DirectShow 的 eof 检测

Posted

技术标签:

【中文标题】DirectShow 的 eof 检测【英文标题】:eof detection for DirectShow 【发布时间】:2008-11-27 23:29:30 【问题描述】:

有没有办法检测 DirectShow 过滤器图已到达其文件的末尾?在文件末尾,我的意思是带有 SampleGrabber 过滤器的过滤器图将永远不会收到另一个 SampleCB 调用。

以下是一些不起作用的东西:

相信IMediaDet::get_StreamLength(人们常说视频中的帧数比实际存在的帧数多) 信任IMediaSeeking::GetDuration(与IMediaDet一致,+/-一帧) 使用IMediaControl::GetState(即使文件中的所有帧都已处理完毕,过滤图仍会运行)

背景:

我正在处理视频,并且我有一个使用 SampleGrabber 创建过滤器图的类。每当调用SampleGrabber::SampleCB 时,我都会用互斥锁阻止它,这样我就可以在拉模式下运行过滤器图。当我准备好另一帧时,我在我的主线程中取消阻塞互斥锁并等待SampleGrabber::SampleCB 向我发送一个它已经完成的信号。对于某些视频,IMediaDet::get_StreamLength 告诉我视频的帧数比实际存在的多。一旦我提取了最后一帧并请求了一个比实际存在的帧多的帧,主线程就会永远阻塞,因为SampleGrabber::SampleCB 将永远不会被再次调用。我希望能够检测到何时永远不会为文件源调用 SampleGrabber::SampleCB。像 Windows Media Player 这样的应用程序能够以某种方式做到这一点,因为 GUI 报告视频在最后一个真实帧之后已经结束,所以显然有办法做到这一点。

编辑:

我正在使用WaitForSingleObject 来实现主线程阻塞。到目前为止,我一直在使用的解决方法是按照 Greg 的建议:有一个有限的超时。不幸的是,这有点棘手。等待失败的原因有很多,例如真正的 eof、网络文件系统速度慢、网络连接丢失、解码器速度慢等。

【问题讨论】:

【参考方案1】:

也许使用IMediaEventEx 接口?其中一个事件代码是 EC_COMPLETE,记录为“来自特定流的所有数据都已呈现。”

【讨论】:

【参考方案2】:

假设主线程在WaitForSingleObject 上阻塞,你能不指定等待的超时时间吗?那么如果等待返回是因为它已经超时而不是因为它收到了一个信号,你就会知道它是最后一帧。

【讨论】:

这就是我迄今为止一直在做的事情。不幸的是,等待失败的原因有很多(真正的 eof、网络文件系统速度慢、网络连接丢失、解码器速度慢等)。 是的,确实如此 - 不幸的是,这是我找到的最佳解决方案,因为正如您还发现的那样,IMediaDet 永远不会完全返回正确的信息,特别是如果在图表(我最近也做了很多帧抓取)。

以上是关于DirectShow 的 eof 检测的主要内容,如果未能解决你的问题,请参考以下文章

SSL SYSCALL 错误:检测到 EOF

Eclipse:CSV 解析标准输入时未检测到 EOF

为啥执行某些命令后 Pexpect 会间歇性挂起(未检测到 EOF)?

psycopg2.errors.ConnectionFailure:SSL SYSCALL 错误:检测到 EOF

如何在awk中检测EOF?

检测全屏 Direct3D 应用程序