有没有办法检测到DirectShow过滤器图已到达其文件的末尾?在其文件的末尾,我的意思是带有SampleGrabber过滤器的过滤器图将永远不会再接收另一个SampleCB调用。
以下是一些不起作用的事情:
IMediaDet::get_StreamLength
(通常说视频中的帧数比实际存在的要多)IMediaSeeking::GetDuration
(与IMediaDet一致,+ / - 一帧)IMediaControl::GetState
(即使已从文件中处理了所有帧,过滤器图仍保持运行)背景
我正在进行视频处理,我有一个用SampleGrabber创建过滤器图的类。每当调用SampleGrabber::SampleCB
时,我用互斥锁阻止它,这样我就可以在拉模式下运行filtergraph。当我准备好另一帧时,我在主线程中取消阻塞互斥锁并等待SampleGrabber::SampleCB
向我发送一个已完成的信号。对于某些视频,IMediaDet::get_StreamLength
告诉我视频的帧数比实际存在的多。一旦我提取了最终帧并请求了一个比实际存在更多的帧,主线程就会永远阻塞,因为SampleGrabber::SampleCB
永远不会被再次调用。我希望能够检测到永远不会为文件源调用SampleGrabber::SampleCB
的时间。像Windows Media Player这样的应用程序能够以某种方式执行此操作,因为GUI报告视频在最后一个实际帧之后已经结束,因此显然有一种方法可以执行此操作。
修改
我正在使用WaitForSingleObject
来实现主线程阻塞。到目前为止我一直在使用的解决方法是做Greg建议的:有一个有限的超时。不幸的是,这有点棘手。等待可能由于诸如真正的eof,网络文件系统速度慢,网络连接丢失,解码器速度慢等原因而失败。
答案 0 :(得分:3)
也许使用IMediaEventEx界面?其中一个事件代码EC_COMPLETE记录为“已呈现来自特定流的所有数据。”
答案 1 :(得分:1)
假设主线程在WaitForSingleObject
上阻塞,你能不指定等待超时?然后,如果等待因为它已经超时而不是因为它已经收到信号而返回,那么你就会知道它是最后一帧。