Sto scrivendo un filtro push sorgente DirectShow personalizzato che dovrebbe ricevere i dati RTP dal server video e inviarli al renderer. Ho scritto una classe CVideoPushPin che eredita da CSourceStream e CVideoReceiverThread class che è un wrapper per un thread che riceve pacchetti RTP dal server video. Il filo ricevitore fa essenzialmente tre cose:Scrittura personalizzata DirectShow Filtro push RTSP/RTP sorgente - Dati cronografici provenienti da fonti live
- riceve pacchetti RTP prime e raccoglie alcuni dati che è necessario per il ricevitore Reports
assembla telai, li copia nel buffer e memorizza le informazioni su di loro in 256 coda elemento , che è definito come segue:
struct queue_elem { char *start; // Pointer to a frame in a buffer int length; // Lenght of data REFERENCE_TIME recvTime; // Timestamp when the frame was received (stream time) }; struct data { struct queue_elem queue[QUEUE_LENGTH]; int qWrIdx; int qRdIdx; HANDLE mutex; };
ogni frame ricevuto viene timestamped tempo stream corrente
p->StreamTime(refTime); REFERENCE_TIME rt = refTime.GetUnits();
Il problema è che non sono sicuro di come sia necessario impostare i timestamp per ogni MediaSample nel metodo FillBuffer. Ho provato diversi modi, ma la riproduzione si interrompe o è troppo lenta. Attualmente il metodo FillBuffer assomiglia a questo:
REFERENCE_TIME thisFrameStartTime, thisFrameEndTime;
// Make sure if there are at least 4 frames in the buffer
if(noOfFrames >= 4)
{
currentQe = m_myData.queue[m_myData.qRdIdx++]; //Take current frame description
if(m_myData.qRdIdx >= QUEUE_LENGTH)
{
m_myData.qRdIdx = 0;
}
nextQe = m_myData.queue[m_myData.qRdIdx]; //Take next frame description
if(currentQe.length > 0)
{
memcpy(pData, currentQe.start, currentQe.length);
pSample->SetActualDataLength(currentQe.length);
CRefTime refTime;
m_pFilter->StreamTime(refTime);
REFERENCE_TIME rt;
rt = refTime.GetUnits();
pSample->GetTime(&thisFrameStartTime, &thisFrameEndTime);
thisFrameEndTime = thisFrameStartTime + (nextQe.recvTime - currentQe.recvTime);
pSample->SetTime(&thisFrameStartTime, &thisFrameEndTime);
}
}
else
{
pSample->SetActualDataLength(0);
}
In questo caso ho notato che il numero di elementi negli aumenti di coda molto rapidamente (per qualche motivo il metodo FillBuffer non può tirare fuori i dati abbastanza veloce), e il risultato è aumento del ritardo durante la riproduzione di video. Qualcuno ha un'idea di come dovrei fare il timestamping quando ricevo dati da fonti live?
Geraint, Grazie per il vostro input. ho fatto un po 'di c appende il mio codice, tuttavia il video si blocca subito dopo averlo eseguito. Nel file di registro ho notato che il metodo FillBuffer viene chiamato solo due volte.Quando viene chiamato per la prima volta, lo stream time è 3633950000, frameStartTime è 3635700000 e frameEndTime è 3635703600. Per la seconda volta, lo stream time è 3634370000, frameStartTime è 3635703600 e frameEndTime è 3635707200. Quindi, se ho capito bene, il renderer dovrebbe attendere il tempo di flusso per raggiungere il timestamp sul primo fotogramma e quindi eseguire senza intoppi, ma purtroppo non succede. – mkurek