我正在編寫自定義DirectShow源推送過濾器,它應該從視頻服務器接收RTP數據並將它們推送到呈現器。我編寫了一個CVideoPushPin類,該類繼承自CSourceStream和CVideoReceiverThread類,它是從視頻服務器接收RTP包的線程的包裝。接收器線程基本上做三兩件事:編寫自定義DirectShow RTSP/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();
問題是我不知道我該如何設置FillBuffer方法中每個MediaSample的時間戳。我嘗試了幾種方法,但播放停止或速度太慢。 目前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方法不能拔出數據速度不夠快),其結果是播放視頻時延遲時間增加。有沒有人有一個想法,當從實時來源接收數據時,我應該如何做時間戳?
傑蘭特, 感謝您的輸入。我做了一些C在我的代碼中出現了一些問題,然而,視頻在我運行之後就凍結了。在日誌文件中,我注意到FillBuffer方法只被調用了兩次。第一次調用時,流時間爲3633950000,frameStartTime爲3635700000,frameEndTime爲3635703600.第二次,流時間爲3634370000,frameStartTime爲3635703600,frameEndTime爲3635707200.因此,如果我理解正確,渲染器應等待流時間到達第一幀的時間戳,然後平穩運行,但不幸的是,它不會發生。 – mkurek 2010-02-11 13:58:18