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

DirectShow - how to determine if stream is valid (C++)

本文关键字:有效 c++ 是否 何确定 DirectShow      更新时间:2023-10-16

我的任务是修复医疗应用程序中的一个bug,该bug可以从口腔内摄像机捕获快照。它使用DirectShow SampleGrabber来完成这个任务。我必须作出免责声明,我没有与DirectShow工作,所以我正试图加快速度,因为我去。我基本上了解各个组件是如何协同工作的。

无论如何,这个bug本身似乎是微不足道的,但我不能找出一个解决方案。由于该系统的模块化特性,预览窗口是一个独立图形的一部分,而不是由SampleGrabber创建的图形(这是一个很长的故事,但这是由于遗留代码支持以前的设备)。当相机是活跃的,我们可以拍快照,一切都是快乐的。当相机关闭时,SampleGrabber拍摄暗帧,但DirectShow在释放预览模块中创建的IAMStreamConfig接口时崩溃(访问冲突)。似乎出于某种原因,SampleGrabber图形以某种方式破坏了预览模块中内置的图形。由于这个应用程序的性质,我不能在这里显示任何源代码,但实际上这是我想要完成的:

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

有没有人知道我如何确定流是空白的还是有直播视频?IE,是否有任何暴露的接口或方法,我可以调用来确定这一点?我已经浏览了MSDN的DirectShow文档中的所有各种接口,但还没有找到一种方法来做到这一点。

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

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

在源过滤器(或您可以访问的最早的过滤器)之后连接的过滤器中,检查它通过receive()函数接收的IMediaSample:

HRESULT Receive(IMediaSample *pSample);

如果你正在使用ISampleGrabber,那么你应该使用ISampleGrabber::SetCallback来设置它的回调函数

HRESULT SetCallback(
  ISampleGrabberCB *pCallback,
  long WhichMethodToCallback
);

这需要你实现一个类extends ISampleGrabberCB。之后,您可以在函数SampleCB

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

没有通用的方法来判断相机是否连接或者流是否为空白。您通常有以下场景之一:

  1. 当相机关闭时,您将停止接收任何样本
  2. 你会收到所有像素都归零的样本,或者是全蓝色的图片,或者是这样的

一些相机有信号丢失通知,但它是特定于型号和通知方法。

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