[C++] ICaptureGraphBuilder2->RenderStream geen beeld?

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Darkvater
  • Registratie: Januari 2001
  • Laatst online: 26-08-2024

Darkvater

oh really?

Topicstarter
Ik zit met een vreemd probleem. Via USB is een capture "kaart" aangesloten. Hiervan wil ik de preview zien, echter heb ik geen beeld, alleen maar een zwart scherm. Als ik de ActiveMovie window verplaats dan is er wel beeld - een soort forced refresh waarbij je updates krijgt als het scherm opnieuw getekend moet worden.

Nou, denk je, het probleem zal wel aan mij liggen, echter:
  • ik heb "precies" dezelfde code in .NET C# en daar doet ie het wel - als ik alles twee keer initialiseer
  • het werkt zonder problemen met een PCI capture kaart die ik hier heb om te testen
  • als ik een debug point zet net na mediacontrol->Run(), en gelijk continue dan heb ik wel beeld en een constante feed van de camera. Een breakpoint op regel 85 dus.
Volgens mij is het een timing issue, maar handmatig pauzeren, etc. helpt allemaal niet.
Heeft iemand hier ervaring mee en hoe is dit op te lossen? De code is hieronder te vinden, echt heel simpel

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
#include <iostream>
#include <comdef.h>
#include <dshow.h>

#pragma comment(lib, "strmbasd.lib")
#pragma comment(lib, "winmm.lib")

IGraphBuilder* gb          = NULL;
ICaptureGraphBuilder2* cgb = NULL;
IBaseFilter* pCap          = NULL;
ICreateDevEnum* pDevEnum   = NULL;
IEnumMoniker* pEnum        = NULL;
IMoniker* pMoniker         = NULL;
IPropertyBag* pPropBag     = NULL;

void init_video() {
    HRESULT res;
    res = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (FAILED(res)) throw "CoInitializeEx failed";

    res = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&gb);
    if (FAILED(res)) throw "FilterGraph CoCreateInstance failed";

    res = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&cgb);
    if (FAILED(res)) throw "CaptureGraphBuilder2 CoCreateInstance failed";

    /* get first capture device */
    res = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pDevEnum);
    if (FAILED(res)) throw "SystemDeviceEnum CoCreateInstance failed";

    res = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
    if (FAILED(res)) throw "VideoInputDeviceCategory CreateClassEnumerator failed";

    res = pEnum->Next(1, &pMoniker, NULL);
    if (FAILED(res)) throw "no capture devices exist on this host";

    VARIANT name; name.vt = VT_BSTR;

    res = pMoniker->BindToStorage(NULL, NULL, IID_IPropertyBag, (void**)&pPropBag);
    if (FAILED(res)) throw "IPropertyBag BindToStorage failed";

    res = pPropBag->Read(L"FriendlyName", &name, NULL);
    if (FAILED(res)) throw "cannot read 'FriendlyName' of capture device";
    std::cout << "Found capture device: '" << std::string(_bstr_t(name.bstrVal)).c_str() << "'" << std::endl;

}

void init_filter()
{
    HRESULT res;

    res = cgb->SetFiltergraph(gb);
    if (FAILED(res)) throw "SetFiltergraph failed";

    res = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pCap);
    if (FAILED(res)) throw "IBaseFilter BindToObject failed";

    res = gb->AddFilter(pCap, L"Video Capture Device");
    if (FAILED(res)) throw "cannot add 'Video Capture Device' filter to GraphBuilder";
}

IMediaControl* get_control() {
    IMediaControl* pControl = NULL;
    HRESULT res = gb->QueryInterface(IID_IMediaControl, (void**)&pControl);
    if (FAILED(res)) throw "IMediaControl QueryInterface failed";
    return pControl;
}

int main() {
    try
    {
        HRESULT res;

        init_video();
        init_filter();
        IMediaControl* pControl = get_control();

        res = pControl->Stop();
        if (FAILED(res)) throw "IMediaControl Stop failed";
        
        res = cgb->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap, NULL, NULL);
        if (FAILED(res)) throw "RenderStream of CVideoRenderer failed";

        res = pControl->Run();
        if (FAILED(res)) throw "IMediaControl Run failed";

    }
    catch (const char* errmsg)
    {
        std::cerr << errmsg << std::endl;
    }

    for (;;) {
        MSG msg;
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        Sleep(1);
    }

    return 0;
}


P.S. RenderStream zegt wel als return VFW_S_NOPREVIEWPIN dus dat het via de Smart Tee Filter gaat die zelf een preview output pin aan vastplakt, maar dat lijkt me geen probleem.

[ Voor 2% gewijzigd door Darkvater op 14-12-2009 11:40 . Reden: VFW_S_NOPREVIEWPIN ]


Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge


Acties:
  • 0 Henk 'm!

  • Darkvater
  • Registratie: Januari 2001
  • Laatst online: 26-08-2024

Darkvater

oh really?

Topicstarter
Een reply op mezelf: Ik heb van alles geprobeerd om het probleem op te lossen en heb iets gevonden wat lijkt te werken. Het is geen oplossing, ik weet zelf niet eens waarom de camera het nu wel doet, maar als ik alle CLSID_AudioCompressorCategory "devices" enumerate - naast CLSID_VideoInputDeviceCategory[1] dan werkt het allemaal wel :?

[1] ik doe nu niet echt een enumerate van CLSID_VideoInputDeviceCategory, ik pak gewoon de eerste, maar door wat code refactoring nu dus wel. Let op: alleen dat maakt geen verschil ik moet echt AudioCompressorCategory enumeraten, AudioInput of VideoCompressor werkt niet.

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
void ds_getDevices(const IID& clsidDeviceClass, monikerList* list = NULL)
{
    ICreateDevEnum* pDevEnum = NULL;
    IEnumMoniker* pEnum      = NULL;

    try
    {
        HRESULT res;

        res = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pDevEnum);
        if (FAILED(res)) throw "SystemDeviceEnum CoCreateInstance failed";

        res = pDevEnum->CreateClassEnumerator(clsidDeviceClass, &pEnum, 0);
        if (FAILED(res)) throw "clsidDeviceClass CreateClassEnumerator failed";

        IMoniker* pMoniker = NULL;
        pEnum->Reset();
        while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
            IPropertyBag* pPropBag = NULL;
            VARIANT name; name.vt = VT_BSTR;

            res = pMoniker->BindToStorage(NULL, NULL, IID_IPropertyBag, (void**)&pPropBag);
            if (FAILED(res)) throw "IPropertyBag BindToStorage failed";

            res = pPropBag->Read(L"FriendlyName", &name, NULL);
            if (FAILED(res)) throw "cannot read 'FriendlyName' of capture device";
            DEBUG(misc, 3, "Found item: '%s'", std::string(_bstr_t(name.bstrVal)).c_str());

            if (list != NULL) list->push_back(pMoniker);
        
            pPropBag->Release();
            pMoniker->Release();
        }
    }
    catch (const char* errmsg)
    {
        error("%s", errmsg);
    }

    if (pEnum != NULL)    pEnum->Release();
    if (pDevEnum != NULL) pDevEnum->Release();
}


ds_getDevices(CLSID_VideoInputDeviceCategory, &list);
ds_getDevices(CLSID_AudioCompressorCategory, NULL); // XXX - nu werkt het?
list[0]->BindToObject(....


Windows Vista? *NEVER* Het waarom - Opera forever!!!
I've seen chickens that were more menacing. Chickens in a coma. On ice. In my fridge