2017-08-30 224 views
3

我有一个图端点是SampleGrabber其中我使用回调函数获取所有帧的未压缩数据。ISampleGrabberFilter一次一个步骤的步骤

在我的顶级界面代码中,我希望有一个函数ReadNextFrame()它获取图中下一帧的数据(直到它到达文件末尾)。

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

我注意到有一个IVideoFrameStep接口,这是理想的我想要的。但似乎这个接口不与样品采集卡兼容,它的文件说:实现微软 下精确到帧的追求的DirectShow必须实现AM_KSPROPSETID_FrameStep属性集, 这是在配合使用IVideoFrameStep

解码器接口。

我试着将它连接到我的图形,但IVideoFrameStep :: CanStep()函数返回给我假的意思是我无法用样品采集卡使用。

所以我的问题是:有没有一种简单和性能方面很好的解决方案,所以我可以有我的图表,以保持目前的状态,然后做出一个机架前用样品采集卡得到的数据?

回答

2

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

要使用样品采集卡可以实现更简单的方法,它没有任何特殊要求由一个得到所有帧一次。

  1. 让你的过滤器图表运行;这将是有意义的,从图中删除时钟 - 看到IMediaFilter::SetSyncSource(NULL)
  2. 有在感兴趣位置的样品采集卡与SampleCB回调
  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 
} 
+0

感谢您的评论,罗马。你所建议的想法似乎是非常好的,并且工作起来,但从设计角度看,我不能那样做。问题是我的函数ReadNextFrame()应该在单个函数调用中完成并返回一个值。如果我在SampleCB代码中等待事件,这意味着它将成为活动线程,并且我的函数将无法完成。 – mbaros

+0

您的顶级'ReadNextFrame'可能会等待'SampleCB'设置的事件。一旦同步,'ReadNextFrame'将复制回调准备的数据,并设置另一个事件释放回调等待并继续获取下一帧。 'ReadNextFrame'又有一个数据副本返回给调用者。 –

+0

能否请你解释一下如何做#4有点详细?非常感谢你。 – mbaros