DirectShow 解码器减少媒体时间

发布于 2024-10-10 01:58:48 字数 1073 浏览 0 评论 0原文

在 DirectShow 中,媒体样本有两个与时间相关的属性:时间戳和媒体时间。我的应用程序需要寻找视频中的特定帧,因此需要媒体时间。然而,看起来大多数解码器过滤器不会传递此信息。

我有一个看起来像这样的 DirectShow 图表:

[File Source (Async.)] -> [AVI Splitter] -> [<Video decoder>] -> [My filter]

我尝试了以下视频解码器:

  • DMO Wrapper Filter with Mpeg4s Decoder DMO(这是我机器上 MPEG-4 的默认设置)
  • Xvid MPEG-4 Video Decoder
  • MainConcept(演示) MPEG-4视频解码器
  • ffdshow 视频解码器(ffdshow 试用)

在这四个解码器中,只有 ffdshow 解码器生成带有媒体时间的样本。其他三个只设置时间戳,但将媒体时间留空。这看起来很奇怪,因为他们从 AVI 分配器获得的每个样本都正确设置了媒体时间。

有谁知道为什么会发生这种情况?即使应用程序不断地跳过视频,是否有一种解决方法可以使媒体时间可靠地工作?

编辑(回应kidjan):

假设我想读取视频帧#100。对于 25fps 文件,该帧位于视频中 4 秒。使用过滤器图的 IMediaSeeking 界面,我寻找该位置。在内部,该查找请求被转发到分离器过滤器(示例中的 AVI 分离器)。然而,存在两个潜在的问题:

  • 根据视频格式,我无法确定分离器是否能够精确地寻找帧 #100。它可能会到达第 95 帧,我必须读取 5 帧才能获得正确的帧。
  • 分离器可能是帧精确的,但由于 DirectShow 的异步特性,解码器过滤器产生的下一帧可能是搜索之前的残留物。如果解码器过滤器使用线程,它可以在查找操作之后传送该帧。

在这些情况下,如果解码器过滤器设置样本的媒体时间将会很有帮助。这样,我就可以确定我收到的是哪个帧。

我的问题基本上归结为:
如何抓取 DirectShow 图表中的特定视频帧(按编号)?

In DirectShow, a media sample has two time-related properties: its time stamp and its media time. My application needs to seek to specific frames within a video and thus requires the media time. As it seems, however, most decoder filters do not pass on this information.

I have a DirectShow graph that looks like this:

[File Source (Async.)] -> [AVI Splitter] -> [<Video decoder>] -> [My filter]

I have tried the following video decoders:

  • DMO Wrapper Filter with Mpeg4s Decoder DMO (that's the default for MPEG-4 on my machine)
  • Xvid MPEG-4 Video Decoder
  • MainConcept (Demo) MPEG-4 Video Decoder
  • ffdshow Video Decoder (ffdshow tryouts)

Of these four, only the ffdshow decoder produces samples with media time. The other three only set the time stamp, but leave the media time empty. This seems strange as each sample they get from the AVI splitter has its media time set correctly.

Does anybody know why this happens? Is there a workaround for getting the media time that works reliably even when the application continually jumps through the video?

Edit (in response to kidjan):

Let's assume I want to read video frame #100. With a 25fps file, this frame is 4 seconds into the video. Using the filter graph's IMediaSeeking interface, I seek to that position. Internally, this seek request is forwarded to the splitter filter (the AVI splitter in the example). However, there are two potential problems:

  • Depending on the video format, I cannot be sure that the splitter will be able to seek precisely to frame #100. It may arrive at frame #95 instead and I will have to read 5 frames before getting the correct frame.
  • The splitter may be frame-accurate, but due to the asynchronous nature of DirectShow the next frame yielded by the decoder filter may be a relict from before the seeking. If the decoder filter uses threading, it may deliver that frame after the seek action.

In these cases, it would be helpful if the decoder filter set the samples' media time. This way, I would know for certain which frame I receive.

What my question boils down to is basically:
How can I grab a specific video frame (by number) within a DirectShow graph?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空宴 2024-10-17 01:58:48

并非所有解码器都遵循 DirectShow 的所有规则,因此丢失媒体时间是您必须忍受的事情之一。如果您只处理 AVI 文件,则在使用 IMediaSeeking 时只需依赖拆分器的准确性,并适当地使用 IMediaControl 的 Stop() 和 Pause() 来确保消除任何缓存的帧,并且您已经获得了所需的帧。使用 AVI 文件,您可以从其标头获取真实的帧速率,并在使用媒体时间失败时计算正确的寻道时间。

但对于非 AVI 文件,可能没有恒定的帧速率,并且使用媒体时间进行搜索没有意义。

Not all decoders follow all the rules of DirectShow, so losing media times is one of the things you'll have to bear with. If you're only working with AVI files, just rely on accuracy of the splitter when using IMediaSeeking and use Stop() and Pause() of IMediaControl appropriately to ensure any cached frames are dismissed and you've got the frame you need. With AVI file you can get true frame rate from its header and calculate correct seek times if using media times fails.

But for non-AVI files there may be no constant framerate and using media times for seeking doesn't make sense there.

傲性难收 2024-10-17 01:58:48

我很困惑 - 您不需要需要媒体时间来“......寻找视频中的特定帧”。为什么不使用时间戳来进行查找呢?此外,查找通常由源过滤器处理,下游过滤器实际上不需要做太多事情。我有一个过滤器图,如下所示:

[自定义源过滤器实现 IMediaSeeking] -> [解码器过滤器]-> [渲染器]

...所有的查找都是通过时间戳而不是媒体时间进行的。所以我不确定为什么你想使用媒体时间而不是时间戳。

您使用 IMediaSeeking 吗?

I'm confused--you do not need media times to "...seek to specific frames within a video." Why not use the time stamp to do seeking? Also, seeking is typically handled by the source filter, and downstream filters really don't have to do much. I have a filter graph that looks like:

[Custom source filter implementing IMediaSeeking] -> [Decoder filter] -> [Renderer]

...and all of the seeking happens with time stamps and not media times. So I'm not sure why you want to use media times instead of time stamps.

Are you using IMediaSeeking?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文