DirectShow - 如何确定流是否有效(C ++)

时间:2013-06-11 17:07:53

标签: c++ directshow

我的任务是修复医疗应用程序中的错误,其中包括可以从口内摄像机捕获快照。它使用DirectShow SampleGrabber执行此任务。我必须制作免责声明,我没有使用DirectShow,因此我正努力让自己快速上手。我基本了解各种组件如何协同工作。

无论如何,bug本身看似微不足道,但我无法找到解决方法。由于该系统的模块化特性,预览窗口是SampleGrabber创建的单独图形的一部分(这是一个很长的故事,但这是由于遗留代码支持以前的设备)。当相机处于活动状态时,我们可以拍摄快照,一切都很愉快。当相机关闭时,SampleGrabber会占用一个暗框,但是当释放在预览模块中创建的IAMStreamConfig界面时,DirectShow会崩溃(访问冲突)。看起来由于某种原因,SampleGrabber图形以某种方式破坏了预览模块中内置的图形。由于这个应用程序的性质,我不能在这里显示任何来源,但基本上这就是我想要实现的目标:

我需要能够检测相机是否实际开启。我遇到的问题是,当插入相机(USB)时,它似乎看起来像系统一样并返回视频流,只是流不包含真实数据。当我使用GetState方法检查捕获过滤器的状态时,它声称它正在运行;当我检查视频格式属性时,它返回正确的属性。在我看来,相机上的按钮只是打开/关闭相机传感器本身,但设备仍然在相机关闭时返回空白流。但是有些东西必须是不同的,因为它不会因传感器实际打开并返回实时视频而崩溃。

有人知道如何确定流是空白还是有实时视频? IE,是否有任何暴露的接口或方法我可以调用来确定这个?我查看了MSDN的DirectShow文档中的所有各种接口,但未能找到一种方法。

4 个答案:

答案 0 :(得分:1)

在源过滤器(或您有权访问的最早过滤器)后连接的过滤器中,检查IMediaSample功能收到的receive()

HRESULT Receive(IMediaSample *pSample);

答案 1 :(得分:1)

如果您使用的是ISampleGrabber,则应使用ISampleGrabber::SetCallback

设置其回调函数
HRESULT SetCallback(
  ISampleGrabberCB *pCallback,
  long WhichMethodToCallback
);

这要求您实现类扩展ISampleGrabberCB。之后,您可以在功能SampleCB

中查看收到的样本
HRESULT SampleCB(
  double SampleTime,
  IMediaSample *pSample
);

答案 2 :(得分:1)

没有通用的方法来判断相机是否已连接或流是否为空白。您通常会遇到以下情况之一:

  1. 当相机关闭时,您停止接收任何样本
  2. 您会收到所有像素归零的样本,或完全蓝色图片或某种
  3. 有些相机有信号丢失通知,但它是特定型号以及通知方法。

    因此,在第一种情况下,您只是停止调用回调。要覆盖第二个,你需要检查框架是否完全填充纯色。当您捕获原始视频(未压缩)时,这是一件相当简单的事情。

答案 3 :(得分:1)

如果您不希望调用样本采集器的回调函数,那么您可以考虑在样本采集器和源过滤器之间(或者在源过滤器之后)添加一个特殊的transform filter,以及此变换过滤器用于检查输入样本是否已损坏并阻止那些损坏的样本。这基本上要求您实现自己的Transform()函数:

HRESULT CRleFilter::Transform(IMediaSample *pSource, IMediaSample *pDest)