0

我编写了自己的 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()?为什么我需要它?

因为我想我确实需要它,因为它阻止了我的视频流无法流畅地解码......

我用谷歌搜索,但没有运气。任何帮助将不胜感激。谢谢。

更新

在方法videoPin->DeliverNewSegment(tStart, tStop, dRate)参数dRate是:

应处理此段的速率,以原始速率的百分比表示。

因此,如果不是1.0我把100.0流按预期的那样流动,但在某些帧之间会有一些延迟。但这是迄今为止最好的!

4

1 回答 1

1

我不相信 NewSegment 会导致您看到的问题。NewSegment 用于您在单个数据包中推送的数据跨越开始时间或停止时间的情况,它允许解码器仅传送到停止时间。在这种情况下,您可以在流式传输开始时调用 NewSegment (0, MAX_LONGLONG, 1) 一次,它应该没问题。

如果您发现问题,那么也许您应该检查解码器输出的延迟(将时间戳与当前流时间进行比较)。

G

于 2011-06-21T17:47:24.363 回答