Getting the Image Data
Top  Previous  Next

The Sample Grabber filter provides a way to retrieve samples as they pass through the filter graph. It is a transform filter with one input pin and one output pin. It passes all samples downstream unchanged, so you can insert it into a filter graph without altering the data stream. Your application can then retrieve individual samples from the filter by calling methods on the ISampleGrabber interface. If you want to retrieve samples without rendering the data, connect the Sample Grabber filter to the Null Renderer filter.

Before building the rest of the graph, you should set a media type for the Sample Grabber by calling the SetMediaType method. When the Sample Grabber connects, it will compare this media type against the media type offered by the other filter.

If you want to discard the samples after you are done with them connect the Sample Grabber to the Null Renderer Filter. The sample grabber operates either in buffering mode (makes a copy of each sample before delivering the sample downstream) or in callback mode (invokes an application-defined callback function on each sample).

// Create a Sample Grabber.
IBaseFilter *pGrabberF = NULL;
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pGrabberF);
if (FAILED(hr))
Error( "Failed to create a grabber" );
return FALSE;
hr = pGraph->AddFilter(pGrabberF, L"Sample Grabber");
if (FAILED(hr)
Error( "Failed to add the grabber to graph" );
return FALSE;

// Query the Sample Grabber for the ISampleGrabber interface.
ISampleGrabber *pGrabber;
pGrabberF->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber);

//specify RGB24 uncompressed video

ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = pGrabber->SetMediaType(&mt);

// Activate buffering mode

hr = pGrabber->SetBufferSamples(TRUE);

// Run the graph.

pEvent->WaitForCompletion(INFINITE, &evCode); // Wait till it's done.

// Find the required buffer size.
long cbBuffer = 0;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);

// Allocate the array and call the method a second time to copy the buffer:
char *pBuffer = new char[cbBuffer];
//get the image data
hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);

Note that images DirectShow are converted into standard video types (RGB8, RGB24, YUV411, YUV422, YUV444) . If your work with high-bit depth video formats and want to access original pixel values, use the GetImageData or GetImagePointer methods of IActiveUSB interface.