简体   繁体   English

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

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

I have been tasked with fixing a bug in a medical application that, among other things, can capture snapshots from intra-oral video cameras. 我的任务是修复医疗应用程序中的一个错误,该错误除其他外,可以从口内摄像机捕获快照。 It uses a DirectShow SampleGrabber for this task. 它使用DirectShow SampleGrabber来完成此任务。 I must make the disclaimer that I have not worked with DirectShow so I'm trying to get up to speed as I go. 我必须声明我没有与DirectShow合作过,因此我在努力提高自己的速度。 I understand basically how the various components work together. 我基本上了解各种组件如何协同工作。

Anyway the bug itself is seemingly trivial but I can't figure out a workaround. 无论如何,该错误本身看似微不足道,但我无法解决。 Due to the modular nature of this system, the preview window is part of a separate graph than the one created by SampleGrabber (it's a long story but this is due to legacy code to support previous devices). 由于该系统的模块化性质,预览窗口是一个单独的图形的一部分,而不是SampleGrabber创建的图形(这是一个很长的故事,但这是由于支持先前设备的旧代码所致)。 When the camera is active we can take snapshots and everything is happy. 当相机处于活动状态时,我们可以拍摄快照,一切都很好。 When the camera is turned off, the SampleGrabber takes a dark frame but DirectShow is crashing when releasing the IAMStreamConfig interface created in the preview module (access violation). 关闭相机电源后,SampleGrabber会显示暗框,但释放在预览模块中创建的IAMStreamConfig接口时,DirectShow会崩溃(访问冲突)。 It seems like for some reason the SampleGrabber graph is somehow corrupting the graph built in the preview module. 由于某种原因,SampleGrabber图似乎以某种方式破坏了预览模块中内置的图。 Due to the nature of this application, I cannot show any source here, but essentially here's what I want to accomplish: 由于此应用程序的性质,我无法在此处显示任何源,但是本质上这是我想要完成的工作:

I need to be able to detect if the camera is actually on or not. 我需要能够检测相机是否真正打开。 The problem I'm having is that when the camera is plugged in (USB), it seems to look to the system like it is on and returning a video stream, it's just that the stream contains no real data. 我遇到的问题是,当插入相机(USB)时,它看起来像是在打开系统并返回视频流,只是该流不包含实际数据。 When I check the state of the capture filter with the GetState method, it claims it is running; 当我使用GetState方法检查捕获过滤器的状态时,它声称它正在运行。 also when I check the video format properties it returns the correct properties. 另外,当我检查视频格式属性时,它会返回正确的属性。 It seems to me like the button on the camera simply turns on/off the camera sensor itself, but the device is still returning a blank stream when the camera is off. 在我看来,相机上的按钮只是打开/关闭相机传感器本身,但是当相机关闭时,设备仍在返回空白流。 Something must be different though, because it doesn't crash with the sensor is actually on and returning live video. 不过必须有所不同,因为它不会因传感器实际打开并返回实时视频而崩溃。

Does anybody have an idea of how I could determine if the stream is blank or has live video? 有人知道我如何确定视频流是空白还是有实时视频? IE, are there any exposed interfaces or methods I could call to determine this? IE,我可以调用任何公开的接口或方法来确定这一点吗? I have looked through all of the various interfaces in MSDN's DirectShow documentation but haven't been able to find a way to do this. 我已经仔细阅读了MSDN的DirectShow文档中的所有各种接口,但是还没有找到实现此目的的方法。

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

HRESULT Receive(IMediaSample *pSample);

In case you're using ISampleGrabber, then you should set its call back function by using ISampleGrabber::SetCallback 如果您使用的是ISampleGrabber,则应该使用ISampleGrabber :: SetCallback设置其回调函数。

HRESULT SetCallback(
  ISampleGrabberCB *pCallback,
  long WhichMethodToCallback
);

This requires you to implement a class extends ISampleGrabberCB . 这要求您实现扩展ISampleGrabberCB的类。 After that, you can check your received sample in function SampleCB 之后,您可以在函数SampleCB中检查收到的样本

HRESULT SampleCB(
  double SampleTime,
  IMediaSample *pSample
);

There is no universal way to tell whether camera is connected or whether the stream is blank or not. 没有通用的方法可以判断是否已连接摄像机或流是否为空白。 You typically have one of the following scenarios: 您通常具有以下情况之一:

  1. you stop receiving any samples when camera is off 关闭相机后,您将停止接收任何样本
  2. you receive samples with all pixels zeroed out or, fully blue picture or a sort of this 您会收到所有像素归零的样本,或者全蓝色图片或类似的图片

Some cameras have signal loss notification, but it's model specific as well as notification method. 有些摄像机具有信号丢失通知,但它是特定于型号以及通知方法的。

So in first case you just stop having callback called. 因此,在第一种情况下,您只需停止调用回调。 And to cover the second one you need to check the frame whether it's filled with solid color entirely. 要覆盖第二个框架,您需要检查框架是否完全填充有纯色。 When you capture raw video (uncompressed) this is a fairly simple thing to do. 当您捕获原始视频(未压缩)时,这是一件相当简单的事情。

If you don't want the callback function of your sample grabber be called, then you may consider adding a special transform filter between the sample grabber and the source filter (or right after the source filter), and what this transform filter does it to check whether the input sample is corrupted and block those corrupted sample. 如果您不希望调用示例采集器的回调函数,则可以考虑在示例采集器和源过滤之间(或紧接在源过滤器之后)添加一个特殊的转换过滤器,以及该转换过滤器的作用检查输入样本是否已损坏,并阻止这些损坏的样本。 This basically requires you to implement your own Transform() function: 这基本上需要您实现自己的Transform()函数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM