I am writing my own DirectShow direct source filter, which should receive RTP data from a video server and click it on a visualization tool. I wrote the CVideoPushPin class, which inherits the CSourceStream class and CVideoReceiverThread, which is the wrapper for the stream that receives RTP packets from the video server. The receiver stream essentially performs three functions:
- receives raw RTP packets and collects some data needed for recipient reports
collects frames, copies them to the buffer and saves information about them in the 256 element queue, which is defined as follows:
struct queue_elem {
char *start;
int length;
REFERENCE_TIME recvTime;
};
struct data {
struct queue_elem queue[QUEUE_LENGTH];
int qWrIdx;
int qRdIdx;
HANDLE mutex;
};
each received frame has a time stamp with the current flow time
p->StreamTime(refTime);
REFERENCE_TIME rt = refTime.GetUnits();
, , MediaSample FillBuffer. , .
FillBuffer :
REFERENCE_TIME thisFrameStartTime, thisFrameEndTime;
if(noOfFrames >= 4)
{
currentQe = m_myData.queue[m_myData.qRdIdx++];
if(m_myData.qRdIdx >= QUEUE_LENGTH)
{
m_myData.qRdIdx = 0;
}
nextQe = m_myData.queue[m_myData.qRdIdx];
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);
}
, ( - FillBuffer ), . - , ?