DirectShow的eof检测

时间:2008-11-27 23:29:31

标签: c++ windows deadlock directshow

有没有办法检测到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,网络文件系统速度慢,网络连接丢失,解码器速度慢等原因而失败。

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

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