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 检测的主要内容,如果未能解决你的问题,请参考以下文章
为啥执行某些命令后 Pexpect 会间歇性挂起(未检测到 EOF)?