2
votes

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. I must make the disclaimer that I have not worked with DirectShow so I'm trying to get up to speed as I go. 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). 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). It seems like for some reason the SampleGrabber graph is somehow corrupting the graph built in the preview module. 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. When I check the state of the capture filter with the GetState method, it claims it is running; 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? 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.

4

4 Answers

1
votes

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:

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

In the filter you connected after the source filter (or the earliest filter you have access to), check the IMediaSample it receives by the receive() function:

HRESULT Receive(IMediaSample *pSample);
1
votes

In case you're using ISampleGrabber, then you should set its call back function by using ISampleGrabber::SetCallback

HRESULT SetCallback(
  ISampleGrabberCB *pCallback,
  long WhichMethodToCallback
);

This requires you to implement a class extends ISampleGrabberCB. After that, you can check your received sample in function SampleCB

HRESULT SampleCB(
  double SampleTime,
  IMediaSample *pSample
);
1
votes

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.