在DirectShow中,媒体样本有两个与时间相关的属性:时间戳和媒体时间。我的应用程序需要寻找视频中的特定帧,因此需要媒体时间。但是,看起来大多数解码器过滤器都没有传递这些信息。
我有一个看起来像这样的DirectShow图:
[File Source (Async.)] -> [AVI Splitter] -> [<Video decoder>] -> [My filter]
我尝试过以下视频解码器:
在这四个中,只有ffdshow解码器生成具有媒体时间的样本。其他三个只设置时间戳,但将媒体时间留空。这看起来很奇怪,因为他们从AVI分离器获得的每个样本都正确设置了媒体时间。
有人知道为什么会这样吗?即使应用程序不断跳过视频,是否有一种解决方法可以使媒体时间可靠地工作?
编辑(回应kidjan):
我们假设我想阅读视频帧#100。使用25fps文件,此帧距视频4秒。使用过滤器图形的IMediaSeeking界面,我寻求到那个位置。在内部,该搜索请求被转发到分离器滤波器(示例中的AVI分离器)。但是,有两个潜在的问题:
在这些情况下,如果解码器过滤器设置样本的媒体时间,将会很有帮助。这样,我就知道我收到了哪一帧。
我的问题归结为基本上:
如何在DirectShow图中获取特定的视频帧(按编号)?
答案 0 :(得分:0)
我很困惑 - 你不需要媒体时间来“......寻找视频中的特定帧”。为什么不用时间戳去寻求?此外,搜索通常由源过滤器处理,下游过滤器实际上不必做太多。我有一个看起来像的过滤器图:
[实施IMediaSeeking的自定义源过滤器] - &gt; [解码器滤波器] - &gt; [渲染]
......并且所有的搜寻都是用时间戳而不是媒体时间进行的。所以我不确定你为什么要使用媒体时间而不是时间戳。
您使用的是IMediaSeeking吗?
答案 1 :(得分:0)
并非所有解码器都遵循DirectShow的所有规则,因此丢失媒体时间是您必须承担的事情之一。如果你只使用AVI文件,那么在使用IMediaSeeking时只需要依赖分割器的准确性,并适当地使用IMediaControl的Stop()和Pause()来确保任何缓存的帧被解除,你就拥有了所需的帧。使用AVI文件,您可以从其标题中获得真实的帧速率,并在使用媒体时间失败时计算正确的搜索时间。
但对于非AVI文件,可能没有恒定的帧速率,并且使用媒体时间进行搜索在那里没有意义。