Написание пользовательского push-фильтра DirectShow RTSP / RTP Source - отметка времени данных, поступающих из живых источников

Я пишу собственный исходный push-фильтр DirectShow, который должен получать данные RTP с видеосервера и передавать их в средство визуализации. Я написал класс CVideoPushPin, который наследуется от классов CSourceStream и CVideoReceiverThread, являющихся оболочкой для потока, получающего RTP-пакеты от видеосервера. Поток получателя по существу делает три вещи:

получает необработанные RTP-пакеты и собирает некоторые данные, необходимые для отчетов приемника

собирает кадры, копирует их в буфер и сохраняет информацию о них в очередь из 256 элементов, которая определяется следующим образом:

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;
};

каждый полученный кадр помечается текущим временем потока

p->StreamTime(refTime);
REFERENCE_TIME rt = refTime.GetUnits();

Проблема в том, что я не уверен, как мне установить временные метки для каждого MediaSample в методе FillBuffer. Я пробовал несколько способов, но воспроизведение либо останавливается, либо идет слишком медленно. В настоящее время метод FillBuffer выглядит следующим образом:

   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);
    }

В этом случае я заметил, что количество элементов в очереди увеличивается очень быстро (по какой-то причине метод FillBuffer не может извлекать данные достаточно быстро), и в результате увеличивается задержка при воспроизведении видео. Кто-нибудь есть идеи, как я должен делать отметки времени при получении данных из живых источников?

Ответы на вопрос(1)

Ваш ответ на вопрос