将MPEG4视频样本推送到解码器-如何使用CBaseOutputPin::DeliverNewSegment()

Pushing MPEG4 video samples to decoder - How to use CBaseOutputPin::DeliverNewSegment()?

本文关键字:CBaseOutputPin 何使用 DeliverNewSegment 解码器 视频 MPEG4 样本      更新时间:2023-10-16

我写了自己的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