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?