c++ - ISampleGrabberFilter 一次一帧

标签 c++ winapi directshow samplegrabber

我有一个图形终点,它是一个 SampleGrabber,我在其中使用回调函数获取所有帧的未压缩数据。

在我的顶层接口(interface)代码中,我想要一个函数 ReadNextFrame(),它获取图中下一帧的数据(直到它到达文件末尾)。

性能方面的错误实现是将 nextFrameIndex 传递给 grabberCB 类,指定此时我想要的帧。所以我的回调函数会跳过所有其他帧,只选择我想要的帧。这是代价高昂的,因为图表必须遍历整个文件以选择单个帧数据。

我注意到有一个 IVideoFrameStep 界面,这正是我想要的。但是这个接口(interface)似乎与 Sample Grabber 不兼容,它的文档说:

Decoders that implement frame-accurate seeking under Microsoft DirectShow must implement the AM_KSPROPSETID_FrameStep property set, which is used in conjunction with the IVideoFrameStep interface.

我试图将它连接到我的图表,但 IVideoFrameStep::CanStep() 函数为我返回了 false,这意味着我不能将它与 Sample Grabber 一起使用。

所以我的问题是:是否有一个简单且性能好的解决方案,这样我就可以让我的图表保持当前状态,然后向前制作一个帧并使用 Sample Grabber 获取数据?

最佳答案

您发现 IVideoFrameStep 有特定的工作要求,其背后的想法是整个过滤器图进行状态转换、运行和暂停播放一帧。

要使用 Sample Grabber 一次获取所有帧,您可以实现一种更简单的方法,该方法没有任何特殊要求。

  1. 让你的过滤图运行起来;从图中删除时钟是有意义的 - 请参阅 IMediaFilter::SetSyncSource(NULL)
  2. 在感兴趣的位置有一个带有 SampleCB 回调的 Sample Grabber
  3. 一旦您执行了SampleCB,就可以对数据进行处理,并向运行该图的更高级别代码指示帧可用性
  4. 虽然 SampleCB 和上面的#3 已完成,但不要从该方法返回,而是陷入等待事件,这表明您已准备好继续
  5. 高级应用程序代码将处理一个帧并设置上面#4 中的事件,允许 SampleCB 退出并进一步获取新帧;使用您从上面的 #3 重复的新框架。

也就是说,您的 SampleCB 等待锁定整个管道,在所需时间内保留其状态,让您以方便的速度逐帧处理。

SampleCB 的伪代码是(带有手动设置/重置事件):

data m_Data;
event m_DataAvailability;
event m_NextFrameRequest;

void SampleCB(Frame)
{
  m_Data = Frame.GetData();
  m_DataAvailability.Set();
  m_NextFrameRequest.WaitFor(); // Sleeping here until signaled to continue
  m_NextFrameRequest.Reset();
}

data ReadNextFrame()
{
  m_DataAvailability.WaitFor();
  data Data = m_Data;
  m_DataAvailability.Reset(); // Current data processed, we need next portion
  m_NextFrameRequest.Set(); // Indicate that we allow next callback call
  return Data; // Make captured frame available
}

关于c++ - ISampleGrabberFilter 一次一帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45962088/

相关文章:

c++ - 通过不同的父类从同一个基类进行多重继承真的是个问题吗?

c++ - 为什么我不能从 lambda 返回初始值设定项列表

c++ - 在类的成员函数定义中使用 (::)

c# - 锁定文件不被除我以外的任何人更改?

delphi - GlobalFree - 不兼容的类型 : 'NativeUInt' and 'PWideChar'

c++ - 访问钩子(Hook)程序中的钩子(Hook)

c# - 将DirectShow与OpenCV结合

audio - 使用 DirectShow 确定音频文件的长度

c++ - C/C++ 程序是在 CPU 上运行还是在内核上运行?

c# - QueryInterface 在 C# 上因 E_NOINTERFACE 而失败