DirectShow, capture Still Image

admin

Administrator
Staff member
i'm not experienced in Windows programming, i try to capture a Still Image from a WebCam using DirectShow. I wrote a small application based on CommandCam.cpp, which can be found here:

<a href="http://batchloaf.wordpress.com/commandcam/" rel="nofollow">http://batchloaf.wordpress.com/commandcam/</a>

I basically added the code that can be found here:

<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd318622(v=vs.85).aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/windows/desktop/dd318622(v=vs.85).aspx</a>

But the call to pBuilder->FindPin(pCap, PINDIR_OUTPUT, &amp;PIN_CATEGORY_STILL, ... fails and i can't get the Pin for the Still Image.

I doubt that because using other Webcam programs i can get a Still Image from my Microsoft LifeCam Studio.

I wonder what i am doing wrong? I tried placing the call in different places in the application but it never succeeded.

Thanks for any hints,
Torsten.

The relevant part of the code is this:
// Get video input device name
hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&amp;pPropBag));
VariantInit(&amp;var);
hr = pPropBag->Read(L"FriendlyName", &amp;var, 0);
fprintf(stderr, "Capture device: %ls\n", var.bstrVal);
VariantClear(&amp;var);

Code:
// Create capture filter and add to graph
hr = pMoniker-&gt;BindToObject(0, 0, IID_IBaseFilter, (void**)&amp;pCap);
if (hr != S_OK) exit_message("Could not create capture filter", 1);

// Add capture filter to graph
hr = pGraph-&gt;AddFilter(pCap, L"Capture Filter");
if (hr != S_OK) exit_message("Could not add capture filter to graph", 1);

// Create sample grabber filter
hr = CoCreateInstance(CLSID_SampleGrabber, NULL,
    CLSCTX_INPROC_SERVER, IID_IBaseFilter,
    (void**)&amp;pSampleGrabberFilter);
if (hr != S_OK)
    exit_message("Could not create Sample Grabber filter", 1);

// Query the ISampleGrabber interface of the sample grabber filter
hr = pSampleGrabberFilter-&gt;QueryInterface(
        DexterLib::IID_ISampleGrabber, (void**)&amp;pSampleGrabber);
if (hr != S_OK)
    exit_message("Could not get ISampleGrabber interface to sample grabber filter", 1);

// Enable sample buffering in the sample grabber filter
hr = pSampleGrabber-&gt;SetBufferSamples(TRUE);
if (hr != S_OK)
    exit_message("Could not enable sample buffering in the sample grabber", 1);

// Set media type in sample grabber filter
AM_MEDIA_TYPE mt;
ZeroMemory(&amp;mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = pSampleGrabber-&gt;SetMediaType((DexterLib::_AMMediaType *)&amp;mt);
if (hr != S_OK)
    exit_message("Could not set media type in sample grabber", 1);

// Add sample grabber filter to filter graph
hr = pGraph-&gt;AddFilter(pSampleGrabberFilter, L"SampleGrab");
if (hr != S_OK)
    exit_message("Could not add Sample Grabber to filter graph", 1);

// Create Null Renderer filter
hr = CoCreateInstance(CLSID_NullRenderer, NULL,
    CLSCTX_INPROC_SERVER, IID_IBaseFilter,
    (void**)&amp;pNullRenderer);
if (hr != S_OK)
    exit_message("Could not create Null Renderer filter", 1);

// Add Null Renderer filter to filter graph
hr = pGraph-&gt;AddFilter(pNullRenderer, L"NullRender");
if (hr != S_OK)
    exit_message("Could not add Null Renderer to filter graph", 1);

// Connect up the filter graph's capture stream
hr = pBuilder-&gt;RenderStream(
    &amp;PIN_CATEGORY_CAPTURE, &amp;MEDIATYPE_Video,
    pCap,  pSampleGrabberFilter, pNullRenderer);
if (hr != S_OK)
    exit_message("Could not render capture video stream", 1);


hr = pBuilder-&gt;RenderStream(
        &amp;PIN_CATEGORY_PREVIEW, &amp;MEDIATYPE_Video,
        pCap, NULL, NULL);
if (hr != S_OK &amp;&amp; hr != VFW_S_NOPREVIEWPIN)
    exit_message("Could not render preview video stream", 1);

// Get media control interfaces to graph builder object
hr = pGraph-&gt;QueryInterface(IID_IMediaControl,
                (void**)&amp;pMediaControl);
if (hr != S_OK) exit_message("Could not get media control interface", 1);

// Run graph
while(1)
{
    hr = pMediaControl-&gt;Run();

    // Hopefully, the return value was S_OK or S_FALSE
    if (hr == S_OK) break; // graph is now running
    if (hr == S_FALSE) continue; // graph still preparing to run

    // If the Run function returned something else,
    // there must be a problem
    fprintf(stderr, "Error: %u\n", hr);
    exit_message("Could not run filter graph", 1);
}

Sleep(2000);

// get the StillImage Pin
hr = pCap-&gt;QueryInterface(IID_IAMVideoControl, (void**)&amp;pAMVidControl);
if (hr != S_OK) exit_message("Could not get IAMVideoControl", 1);

hr = pBuilder-&gt;FindPin(pCap, PINDIR_OUTPUT, &amp;PIN_CATEGORY_STILL, NULL, FALSE, 0, &amp;pPin);
if (hr != S_OK)
        exit_message("Could not get Pin of category StillImage", 1);

hr = pAMVidControl-&gt;SetMode(pPin, VideoControlFlag_Trigger);
if (hr != S_OK) exit_message("Could set mode VideoControlFlag_Trigger", 1);