Directshow RenderStream returns E_INVALIDARG

I am working on a video capture program under windows that takes frames from the webcam and saves each frame as a bitmap. I followed the documentation on MSDN about Video Capture and Sample Grabber, so I've written the following code in C++:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "qedit.h"
#include "Streams.h"

#include <control.h>
#include <assert.h>

#pragma comment(lib, "strmiids")

void DisplayDeviceInformation(IEnumMoniker* pEnum)
{
    IMoniker* pMoniker = NULL;
    
    while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
    {
        IPropertyBag* pPropBag;
        IMediaEventEx* pEvent = NULL;

        HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
        if (FAILED(hr))
        {
            pMoniker->Release();
            continue;
        }

        VARIANT var;
        VariantInit(&var);

        // Get description or friendly name.
        hr = pPropBag->Read(L"Description", &var, 0);
        if (FAILED(hr))
        {
            hr = pPropBag->Read(L"FriendlyName", &var, 0);
        }
        if (SUCCEEDED(hr))
        {
            VariantClear(&var);
        }

        hr = pPropBag->Write(L"FriendlyName", &var);

        // WaveInID applies only to audio capture devices.
        hr = pPropBag->Read(L"WaveInID", &var, 0);
        if (SUCCEEDED(hr))
        {
            VariantClear(&var);
        }

        hr = pPropBag->Read(L"DevicePath", &var, 0);
        if (SUCCEEDED(hr))
        {
            // The device path is not intended for display.
            VariantClear(&var);
        }

        IGraphBuilder* m_pGraph = NULL; //Filter Graph
        ICaptureGraphBuilder2* pBuild = NULL; //Capture graph

        IBaseFilter* pSampleGrabberFilter = NULL; //Sample Grabber filter
        ISampleGrabber* pSampleGrabber = NULL; //Sample Grabber

        IBaseFilter* pCap = NULL; //Capture filter
        IBaseFilter* pMux = NULL; //Mux filter

        IMediaControl* pControl; //Media control

        IEnumPins* pEnumPins = NULL;
        IPin* pPin = NULL;

        REFERENCE_TIME rtStart = 0, rtStop = 500000000; //Stop start values
        const WORD wStartCookie = 1, wStopCookie = 2;

        hr = InitCaptureGraphBuilder(&m_pGraph, &pBuild); //Build Filter graph and capture graph

        hr = m_pGraph->QueryInterface(IID_PPV_ARGS(&pEvent)); //Query the Media Event

        hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap); //Create capture filter

        hr = m_pGraph->AddFilter(pCap, L"Capture Filter"); //Add capture filter to filter graph

        hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pSampleGrabberFilter)); //Create sample grabber filter

        hr = pSampleGrabberFilter->QueryInterface(IID_PPV_ARGS(&pSampleGrabber));

        hr = m_pGraph->AddFilter(pSampleGrabberFilter, L"Sample Grabber"); //Add the sample grabber filter

        AM_MEDIA_TYPE mt;
        ZeroMemory(&mt, sizeof(mt));
        mt.majortype = MEDIATYPE_Video;
        mt.subtype = MEDIASUBTYPE_RGB24;

        hr = pSampleGrabber->SetMediaType(&mt);
        if (FAILED(hr))
        {
            return;
        }

        hr = pCap->EnumPins(&pEnumPins);

        while (S_OK == pEnumPins->Next(1, &pPin, NULL))
        {
            hr = ConnectFilters(m_pGraph, pPin, pSampleGrabberFilter);
            SafeRelease(&pPin);
            if (SUCCEEDED(hr))
            {
                break;
            }
        }

        //kapcsold össze a sample grabbert a capture filterrel + rakj be egy render streamet

        hr = pBuild->SetOutputFileName(&MEDIASUBTYPE_Avi, L"C:\\sdfd.avi", &pMux, NULL); //Set capture graph output file name

        hr = pBuild->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap, &rtStart, &rtStop, wStartCookie, wStopCookie); //Control stream assembly

        hr = m_pGraph->QueryInterface(IID_IMediaControl, (LPVOID*)&pControl); // Query control interface

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

        hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap,
            NULL, pMux);

        hr = pControl->Run(); // run stream

        long cbBuffer;
        hr = pSampleGrabber->GetCurrentBuffer(&cbBuffer, NULL);

        char a;
        Sleep(8000);
        // Release the mux filter.
        pMux->Release();
        pPropBag->Release();
    }
    pMoniker->Release();
}

void main()
{
    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (SUCCEEDED(hr))
    {
        IEnumMoniker* pEnum;

        hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum);
        if (SUCCEEDED(hr))
        {
            DisplayDeviceInformation(pEnum);
            pEnum->Release();
        }
        CoUninitialize();
    }
}


Neither does RenderStream and GetCurrentBuffer seem to work, although I've initialized all relevant filters. What is wrong with this code?
Maybe you should check if the Reads on L42 and L48 fail (i.e., add an else to the ifs and don't just continue with normal processing).
Topic archived. No new replies allowed.