将MPEG4视频样本推送到解码器-如何使用CBaseOutputPin::DeliverNewSegment()
Pushing MPEG4 video samples to decoder - How to use CBaseOutputPin::DeliverNewSegment()?
我写了自己的RTSP推送源DirectShow过滤器(CBaseFilter),它对H264非常有效!但是,当我尝试支持MPEG4(MP4V-ES流)时,我偶然发现了一个问题。。。我的流被解码(使用ffdshow视频解码器过滤器,或DivX视频解码器),并完美渲染了整整10秒。画面在15fps时流畅,但在10秒后,fps急剧下降,只有IVOP被解码,PVOP/BVOP被丢弃。。。即使我收到了它们,并按时将它们发送到解码器。
然后我开始摆弄我的代码,我发现我正确地拆包了MPEG4 RTP有效载荷,我正确地将媒体样本发送到解码器,并正确地释放了它们,而且CBaseOutputPin::DecideBufferSize()
完成了它应该完成的工作,我正确调用了IMediaSample::SetTime()
。。。但是,如果我更改这个代码,它会将样本发送到解码器:
hr = videoPin->Deliver(sample);
sample->Release();
使用此代码(注意第一行):
videoPin->DeliverNewSegment(REFERENCE_TIME(start), REFERENCE_TIME(end), 1.0);
hr = videoPin->Deliver(sample);
sample->Release();
视频在10秒及以上都很流畅(fps保持在15),但画面完全混乱。。。像IVOP没有按应有的方式解码,并且在场景的静态部分存在一些伪影。
那么,如何使用CBaseOutputPin::DeliverNewSegment()?我为什么需要它
因为我想我确实需要它,因为它可以阻止我的视频流不能被流畅地解码。。。
我在谷歌上搜索了一下,但运气不好。任何帮助都将不胜感激。Thanx。
更新
在方法videoPin->DeliverNewSegment(tStart, tStop, dRate)
中,参数dRate为:
处理该分段的速率,为原始速率的百分比。
因此,如果不是1.0
,而是100.0
,则流按预期流动,但在某些帧之间有一些延迟。但这是迄今为止最好的!
我不相信NewSegment会导致您看到的问题。NewSegment用于您在单个数据包中推送的数据跨越开始时间或停止时间的情况,并且它允许解码器只在停止时间之前发送。在这种情况下,您可以在流式传输开始时调用NewSegment(0,MAX_LONGLONG,1)一次,它应该很好。
如果您看到问题,那么也许您应该检查解码器输出的延迟(将时间戳与当前流时间进行比较)。
G