DirectShow Capturing funktioniert nicht



  • Hallo,

    ich will mit DirectShow eine AVI-Datei aufnehmen. Ich habe mich durch die DirectShow-API von MSDN gelesen und habe folgenden Quelltext herausbekommen:

    #include <Windows.h>
    #include <DShow.h>
    #pragma warning(disable:4995)
    #pragma warning(disable:4996)
    #define SAFE_RELEASE(x) {if ((x)) (x)->Release(); (x) = NULL;}
    
    HRESULT InitFilterGraphs(IGraphBuilder** ppGraph, ICaptureGraphBuilder2** ppCapture)
    {
    	IGraphBuilder* pGraph;
    	ICaptureGraphBuilder2* pCapture;
    
    	if (FAILED(CoInitialize(NULL)))
    		return E_FAIL;
    
    	if (FAILED(CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**) &pCapture)))
    		return E_FAIL;
    
    	if (FAILED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**) &pGraph)))
    	{
    		pCapture->Release();
    		return E_FAIL;
    	}
    
    	pCapture->SetFiltergraph(pGraph);
    	*ppGraph	= pGraph;
    	*ppCapture	= pCapture;
    
    	return S_OK;
    }
    
    HRESULT EnumVideoDevices(IEnumMoniker** ppMoniker)
    {
    	ICreateDevEnum* pDevEnum;
    	HRESULT hr = E_FAIL;
    
    	if (SUCCEEDED(CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum))))
    	{
    		hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, ppMoniker, 0);
    
    		if (hr == S_FALSE)
    			hr = VFW_E_NOT_FOUND;
    
    		pDevEnum->Release();
    	}
    
    	return hr;
    }
    
    HRESULT DisplayVideoDevices(IEnumMoniker* pEnumMoniker, IGraphBuilder* pGraph, IBaseFilter** ppCap)
    {
    	IMoniker* pMoniker;
    	while (pEnumMoniker->Next(1, &pMoniker, NULL) == S_OK)
    	{
    		IPropertyBag* pPropBag;
    		if (FAILED(pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag))))
    		{
    			pMoniker->Release();
    			continue;
    		}
    
    		VARIANT var;
    		VariantInit(&var);
    
    		if (FAILED(pPropBag->Read(L"Description", &var, 0)))
    			if (FAILED(pPropBag->Read(L"FriendlyName", &var, 0)))
    				return E_FAIL;
    
    		IBaseFilter* pCap;
    		if (SUCCEEDED(pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**) &pCap)))
    			if (FAILED(pGraph->AddFilter(pCap, L"Capture Filter")))
    				return E_FAIL;
    
    		*ppCap = pCap;
    
    		/*char text[256] = "";
    		sprintf(text, "%S", var.bstrVal);
    		MessageBox(NULL, text, "Info", MB_ICONINFORMATION);*/
    		VariantClear(&var);
    		pMoniker->Release();
    		pPropBag->Release();
    		break;
    	}
    
    	return S_OK;
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	IGraphBuilder* pGraph;
    	ICaptureGraphBuilder2* pCapture;
    	IBaseFilter* pCap;
    	IMediaControl* pControl;
    	IMediaEvent* pEvent;
    
    	if (FAILED(InitFilterGraphs(&pGraph, &pCapture)))
    		goto end;
    
    	if (FAILED(pGraph->QueryInterface(IID_IMediaControl, (void**) &pControl)))
    		goto end;
    
    	if (FAILED(pGraph->QueryInterface(IID_IMediaEvent, (void**) &pEvent)))
    		goto end;
    
    	IEnumMoniker* pEnumMoniker;
    	if (SUCCEEDED(EnumVideoDevices(&pEnumMoniker)))
    	{
    		DisplayVideoDevices(pEnumMoniker, pGraph, &pCap);
    		pEnumMoniker->Release();
    	}
    	else goto end;
    
    	IBaseFilter* pMux;
    	if (FAILED(pCapture->SetOutputFileName(&MEDIASUBTYPE_Avi, L"C:\\Test.avi", &pMux, NULL)))
    		goto end;
    
    	if (FAILED(pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pCap, NULL, pMux)))
    		goto end;
    
    	pMux->Release();
    
    	// start recording
    	pControl->Run();
    
    	while (!(GetAsyncKeyState(VK_ESCAPE) & 0x8000)) {}
    
    	pControl->Stop();
    end:
    	SAFE_RELEASE(pGraph);
    	SAFE_RELEASE(pControl);
    	SAFE_RELEASE(pEvent);
    	CoUninitialize();
    }
    

    Fehler gibt es keine, jedoch ist die entsprechende Datei nicht auf der Festplatte, d.h. irgendwie muss das Speichern nicht funktioniert haben. Ich habe diesen Forenbeitrag gefunden und dort scheint alles zu funktionieren... Was läuft bei mir falsch bzw. was habe ich falsch gemacht/vergessen?

    Vielen Dank im Voraus!



  • goto? Ohne jetzt beleidigend klingen zu wollen, aber... Spinnst du?

    Sicher, dass es keine Fehler gibt? Hast du alle HRESULTS ausgewertet, die du zurückbekommst? Könnte es daran liegen, dass du Admin Rechte brauchst, um auf C:\ zu schreiben? Ist etwas schwierig, bei DirectShow so auf Anhieb zu sagen, warum was nicht geht.



  • Mechanics schrieb:

    goto? Ohne jetzt beleidigend klingen zu wollen, aber... Spinnst du?

    Vollpfosten! GOTO Keller und bleib dort!



  • 1. Danke schonmal, denn es lag tatsächich am Laufwerk.
    2. Als ich C++ gelernt habe, wurde mir auch die Problematik und Unschönheit von 'goto' erklärt. Als ich dann mir immer wieder Beispielcodes von MSDN anguckte, habe ich 'goto' immer wieder gefunden (z.B. siehe hier), deshalb dachte ich es wäre in manchen Fällen ganz praktisch...
    3. Beleidigungen kann man sich sparen und auf Nicht-Profis Rücksicht nehmen!


Anmelden zum Antworten