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

C++ DirectShow-如何确定流是否有效(C+;+;),c++,directshow,C++,Directshow,我的任务是修复一个医疗应用程序中的一个bug,该应用程序可以从口腔内摄像机捕获快照。它使用DirectShow SampleGrabber执行此任务。我必须声明我没有与DirectShow合作过,所以我正在努力跟上进度。我基本上了解各个组件是如何协同工作的 不管怎么说,这个bug本身看起来很小,但我想不出一个解决方法。由于该系统的模块化特性,预览窗口是由SampleGrabber创建的图形以外的单独图形的一部分(这是一个很长的故事,但这是由于支持以前设备的遗留代码)。当相机处于活动状态时,我们可

我的任务是修复一个医疗应用程序中的一个bug,该应用程序可以从口腔内摄像机捕获快照。它使用DirectShow SampleGrabber执行此任务。我必须声明我没有与DirectShow合作过,所以我正在努力跟上进度。我基本上了解各个组件是如何协同工作的

不管怎么说,这个bug本身看起来很小,但我想不出一个解决方法。由于该系统的模块化特性,预览窗口是由SampleGrabber创建的图形以外的单独图形的一部分(这是一个很长的故事,但这是由于支持以前设备的遗留代码)。当相机处于活动状态时,我们可以拍摄快照,一切都很愉快。当相机关闭时,SampleGrabber拍摄暗帧,但释放预览模块中创建的IAMStreamConfig界面时DirectShow崩溃(访问冲突)。出于某种原因,SampleGrabber图形似乎在某种程度上破坏预览模块中构建的图形。由于此应用程序的性质,我无法在此处显示任何源代码,但基本上我想实现以下目标:

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


有人知道我如何确定流是空白的还是有实时视频吗?也就是说,我是否可以调用任何公开的接口或方法来确定这一点?我已经查看了MSDN DirectShow文档中的所有接口,但还没有找到实现此目的的方法。

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

HRESULT Receive(IMediaSample *pSample);
HRESULT CRleFilter::Transform(IMediaSample *pSource, IMediaSample *pDest)

在源筛选器(或您有权访问的最早筛选器)之后连接的筛选器中,检查它通过函数接收的:

HRESULT Receive(IMediaSample *pSample);
HRESULT CRleFilter::Transform(IMediaSample *pSource, IMediaSample *pDest)

如果您使用的是ISampleGrabber,那么您应该使用

这要求您实现一个类扩展。之后,您可以在函数中检查收到的样本


如果您使用的是ISampleGrabber,那么您应该使用

这要求您实现一个类扩展。之后,您可以在函数中检查收到的样本


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

  • 相机关闭时,您将停止接收任何样本
  • 您接收到的样本中所有像素都已调零,或者是完全蓝色的图片或类似的图片
  • 一些相机有信号丢失通知,但它是特定于型号的,并且有通知方法


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

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

  • 相机关闭时,您将停止接收任何样本
  • 您接收到的样本中所有像素都已调零,或者是完全蓝色的图片或类似的图片
  • 一些相机有信号丢失通知,但它是特定于型号的,并且有通知方法


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

    < P>如果你不想调用你的样本抓取器的回调函数,那么你可以考虑在样本抓取器和源过滤器之间添加一个特殊的(或者在源过滤器之后)。这个变换过滤器的作用是检查输入样本是否损坏并阻止这些损坏的样本。这基本上要求您实现自己的
    Transform()
    函数:

    HRESULT Receive(IMediaSample *pSample);
    
    HRESULT CRleFilter::Transform(IMediaSample *pSource, IMediaSample *pDest)
    

    如果你不想调用你的样本抓取器的回调函数,那么你可以考虑在样本抓取器和源过滤器之间(或者在源过滤器之后)添加一个特殊的内容,以及这个变换过滤器做什么来检查输入样本是否被破坏并阻止那些被破坏的样本。这基本上要求您实现自己的

    Transform()
    函数:

    HRESULT Receive(IMediaSample *pSample);
    
    HRESULT CRleFilter::Transform(IMediaSample *pSource, IMediaSample *pDest)
    

    在示例抓取器图中,只有两个过滤器是源和抓取器。抓取器是一个IBaseFilter,它似乎是从ISampleGrabber实例实例化的。我在两个对象中都没有看到这个方法的实现。我是否需要查询grabber筛选器上的特定接口?在示例grabber图中,只有两个筛选器是源和grabber。抓取器是一个IBaseFilter,它似乎是从ISampleGrabber实例实例化的。我在两个对象中都没有看到这个方法的实现。我需要在grabber筛选器上查询特定接口吗?啊,好的,我已经这样做了,当我在回调中检查IMediaSample时,例如调用GetActualDataLength(),它会返回一个有效的大小。正如我所怀疑的,它返回的是一个有效但空白的视频流。Arg.@健忘症,例如