DirectShow: SampleGrabber and Null Render

1.8k Views Asked by At

I want to create a Filter Graph that allows me to take image samples from a (webcam) video stream that should not be rendered.

I have already created a Filter Graph that allows me to preview my webcam video stream and take image samples from it. So I only need not to render the video stream.

From what I'm was able to understand, I should use a NullFilter to deal with the video stream output but I got no success using it...

Here is what I have so far:

IGraphBuilder           *pGraph;
ICaptureGraphBuilder2   *pBuild;
IMediaControl           *pControl;
IMediaEvent             *pEvent;
IMoniker                *pVideoSel; 
IBaseFilter             *pVCap;
IBaseFilter             *pGrabberFilter;
IBaseFilter             *pNullRenderer;
ISampleGrabber          *pGrabber;
IVideoWindow            *pVidWin;

Filter Graph initialization:

Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

// COM library initialization
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);    // same as CoInitialize but for all the threads

// Create the Capture Graph Builder.
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild );

// Create the Filter Graph Manager.
hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC, IID_IGraphBuilder, (void**)&pGraph);
// Initialize the Filter Graph  for the Capture Graph Builder to use.
pBuild->SetFiltergraph(pGraph);

// Attach the graph control
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
// Attach the graph events
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

Add Camera:

HRESULT hr;

//Device binding with connection
hr = pVideoSel->BindToObject(0, 0, IID_IBaseFilter, (void**)&pVCap);

// Add the Device Filter to the Graph
hr = pGraph->AddFilter(pVCap, L"Video Capture");

//Creates Grabber Filter and adds it to the Filter Graph
//Once connected, Grabber Filter will capture still images
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGrabberFilter));

hr = pGraph->AddFilter(pGrabberFilter, L"Sample Grabber");
hr = pGrabberFilter->QueryInterface(IID_PPV_ARGS(&pGrabber));

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

//Channels the camera output to GrabberFilter
hr = pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pVCap, pGrabberFilter, NULL);

hr = pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);

pVidWin->put_Owner((OAHWND)hWnd);       // We own the window now
pVidWin->put_WindowStyle(WS_CHILD);     // you are now a child

pVidWin->SetWindowPosition(img_position.left, img_position.top, rc.right, rc.bottom);

pControl->Run();

Then I'm able to get my image samples with:

long pBufferSize = 0;               // pBuffer size
long Size = 0;
hr = mydata1->pGrabber->GetCurrentBuffer(&Size, NULL);
if (FAILED(hr))
    return 0;
else if (Size != pBufferSize) {
    pBufferSize = Size;
    if (pBuffer != 0)
        delete[] pBuffer;
    pBuffer = new unsigned char[pBufferSize];
}
hr = mydata1->pGrabber->GetCurrentBuffer(&pBufferSize, (long*)pBuffer);

.

To remove the video stream rendering I tried to remove:

hr = pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pVCap, pGrabberFilter, NULL);

hr = pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);

pVidWin->put_Owner((OAHWND)hWnd);       // We own the window now
pVidWin->put_WindowStyle(WS_CHILD);     // you are now a child

pVidWin->SetWindowPosition(img_position.left, img_position.top, rc.right, rc.bottom);

and add this:

GUID majorType = MEDIATYPE_Video;
hr = Main_graph->pBuild->RenderStream (NULL, &majorType, pVCap, NULL, pGrabberFilter);
hr = Main_graph->pBuild->RenderStream (NULL, &majorType, pGrabber, NULL, pNullRenderer);

But when I try to mydata1->pGrabber->GetCurrentBuffer(&pBufferSize, (long*)pBuffer); it failed...

Any ideas of what am I doing wrong?

0

There are 0 best solutions below