ISampleGrabberFilter一次一个步骤的步骤
问题描述:
我有一个图端点是SampleGrabber其中我使用回调函数获取所有帧的未压缩数据。ISampleGrabberFilter一次一个步骤的步骤
在我的顶级界面代码中,我希望有一个函数ReadNextFrame()它获取图中下一帧的数据(直到它到达文件末尾)。
性能方面的错误实现是将nextFrameIndex传递给grabberCB类,以指定此时我想要的帧。所以我的回调函数会跳过所有其他帧,只会选择一个我想要的。这是昂贵的,因为图必须遍历整个文件来拾取单个帧数据。
我注意到有一个IVideoFrameStep接口,这是理想的我想要的。但似乎这个接口不与样品采集卡兼容,它的文件说:实现微软 下精确到帧的追求的DirectShow必须实现AM_KSPROPSETID_FrameStep属性集, 这是在配合使用IVideoFrameStep
解码器接口。
我试着将它连接到我的图形,但IVideoFrameStep :: CanStep()函数返回给我假的意思是我无法用样品采集卡使用。
所以我的问题是:有没有一种简单和性能方面很好的解决方案,所以我可以有我的图表,以保持目前的状态,然后做出一个机架前用样品采集卡得到的数据?
答
您发现IVideoFrameStep
有一定要求的工作和它背后的想法是,整个过滤器图确实状态转换,运行,暂停播放恰好是一帧。
要使用样品采集卡可以实现更简单的方法,它没有任何特殊要求由一个得到所有帧一次。
- 让你的过滤器图表运行;这将是有意义的,从图中删除时钟 - 看到
IMediaFilter::SetSyncSource(NULL)
- 有在感兴趣位置的样品采集卡与
SampleCB
回调 - 一旦你有你
SampleCB
执行,做你的数据的事情,表明帧可用性更高运行图级别的代码 - 虽然里面
SampleCB
和#3以上操作后,不从方法返回,而是陷入等待一个事件,这是表明你已经准备好继续 - 高层次的应用代码将处理一帧,并设置从#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
}
感谢您的评论,罗马。你所建议的想法似乎是非常好的,并且工作起来,但从设计角度看,我不能那样做。问题是我的函数ReadNextFrame()应该在单个函数调用中完成并返回一个值。如果我在SampleCB代码中等待事件,这意味着它将成为活动线程,并且我的函数将无法完成。 – mbaros
您的顶级'ReadNextFrame'可能会等待'SampleCB'设置的事件。一旦同步,'ReadNextFrame'将复制回调准备的数据,并设置另一个事件释放回调等待并继续获取下一帧。 'ReadNextFrame'又有一个数据副本返回给调用者。 –
能否请你解释一下如何做#4有点详细?非常感谢你。 – mbaros