Finding out when the samplegrabber is ready in DirectShow

1.8k views Asked by At

I am continuing work on my DirectShow application and am just putting the finishing touches on it. What the program is doing is going through a video file in 1 second intervals and capturing from the samplegrabber the current buffer and processing it before moving on. However, I was noticing that I was getting duplicate images in my tests to which I found out that DirectShow has not incremented through the video in that 1 second interval fast enough. My question is if there is a way to check when DirectShow is ready for me to call the samplegrabber to get the current frame and to process it. At the moment I call sleep for 1 second but there has to be a better method. Thank you in advance for the help.

EDIT

I just tried running a check to see if the video's position is equal to the next position that I would like to grab and process. That decreased the number of duplicate frames but I still see them showing up in chunks.

2

There are 2 answers

3
Ralf On BEST ANSWER

I always let the DS framework handle the processing rate: in the main application thread, configure the sample grabber callback and then when the callback is triggered, you get the media sample as well as sample time: at this point you can process the sample if the appropriate interval i.e. 1 second has elapsed.

What do you mean you call sleep for a second and from where (which thread) do you call it? If you're doing this from inside the callback you are effectively blocking the DirectShow pipeline? Perhaps if you could explain your setup in more detail I could be more helpful.

/// Callback that is triggered per media sample
/// Note this all happens in the DirectShow streaming thread!
STDMETHODIMP SampleCB( double dSampleTime, IMediaSample * pSample )
{
  // check timestamp and if one second has elapsed process sample accordingly
  // else do nothing

  ...

  // Get byte pointer
  BYTE* pbData(NULL);
  HRESULT hr = pSample->GetPointer(&pbData);
  if (FAILED(hr)) 
  {
    return hr;
  }

  ...
}

P.S if you want to process the samples as fast as possible, you can set the sample timestamp to NULL in your callback.

  // set time to NULL to allow for fast rendering since the 
  // the video renderer controls the rendering rate according
  // to the timestamps
  pSample->SetTime(NULL, NULL);
3
Daniel Mošmondor On

Try setting your graph timer to NULL. It will allow to:

  • process the file as fast as possible
  • will relieve you of the issues you have.

Of course, it won't work if you are rendering the file to screen at the same time.