2

有没有办法检测 DirectShow filtergraph 已经到达其文件的末尾?在其文件末尾,我的意思是带有 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、慢速网络文件系统、丢失网络连接、慢速解码器等。

4

2 回答 2

3

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

于 2008-11-28T00:12:27.453 回答
1

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

于 2008-11-27T23:39:22.213 回答