DirectShow Filter verbinden



  • Hallo,

    wieder mal ein DirectShow Problem, und zwar habe ich im GraphEdit meinen benötigten Filter zusammengebaut(Funktioniert auch). Wenn ich diesen Graphen nun versuche nach zu programmieren, bekomme ich immer einen Programmabsturz. Hier mein Quelltext(Fehler tritt bei der ersten Verwendung eines Filters auf):

    const GUID CAM = {0xbbefb6c7, 0x2fc4, 0x4139, 0xbb8b, 0xa58bba724083};
    	const GUID TEE = {0xCC58E280, 0x8AA1, 0x11D1, 0xB3F1, 0x00AA003761C5};
    	const GUID AVI = {0xCF49D4E0, 0x1115, 0x11CE, 0xB03A, 0x0020AF0BA770};
    	const GUID CCOLOR = {0x1643E180, 0x90F5, 0x11CE, 0x97D5, 0x00AA0055595A};
    	const GUID RENDERER = {0x70E102B0, 0x5556, 0x11Ce, 0x97C0, 0x00AA0055595A};
    
    	IMoniker **devs = GetDevices();
    	ListDevices();	
    
    	//Basis-Filter für jedes Filterobjekt
    	IBaseFilter *logitechCam = NULL;
    	CoCreateInstance(CAM, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&logitechCam);
    	IBaseFilter *smartTee = NULL;
    	CoCreateInstance(TEE, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&smartTee);
    	IBaseFilter *aviDecompressor = NULL;
    	CoCreateInstance(AVI, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&aviDecompressor);
    	IBaseFilter *colorConverter = NULL;
    	CoCreateInstance(CCOLOR, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&colorConverter);
    	IBaseFilter *vidRenderer = NULL;
    	CoCreateInstance(RENDERER, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&vidRenderer);
    
    	//Pins abfragen
    	IPin *capture = NULL;
    	logitechCam->FindPin(TEXT("Capture"), (IPin **)capture);
    
    	IPin *teeInput = NULL;
    	smartTee->FindPin(TEXT("Input"), (IPin **)teeInput);
    
    	IPin *teeCapture = NULL;
    	smartTee->FindPin(TEXT("Capture"), (IPin **)teeCapture);
    
    	IPin *aviIn = NULL;
    	aviDecompressor->FindPin(TEXT("XForm In"), (IPin **)aviIn);
    
    	IPin *aviOut = NULL;
    	aviDecompressor->FindPin(TEXT("XForm Out"), (IPin **)aviOut);
    
    	IPin *colorIn = NULL;
    	colorConverter->FindPin(TEXT("Input"), (IPin **)colorIn);
    
    	IPin *colorOut = NULL;
    	colorConverter->FindPin(TEXT("XForm Out"), (IPin **)colorOut);
    
    	IPin *vidInput = NULL;
    	vidRenderer->FindPin(TEXT("VMR Input0"), (IPin **)vidInput);
    	//GraphManager erstellen
    	IGraphBuilder *graphManager = NULL;
    	IMediaControl *graphControl = NULL;
    	CoCreateInstance(CLSID_FilterGraph , NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&graphManager); 
    
    	//Pins verbinden
    	graphManager->Connect(capture, teeInput);
    	graphManager->Connect(teeCapture, aviIn);
    	graphManager->Connect(aviOut, colorIn);
    	graphManager->Connect(colorOut, vidInput);
    
    	graphManager->AddFilter(logitechCam, TEXT("Logitech HD Webcam C510"));	
    	graphManager->AddFilter(smartTee, TEXT("Smart Tee"));
    	//graphManager->AddFilter(baseFilter, TEXT("HD Webcam C510"));
    	graphManager->AddFilter(aviDecompressor, TEXT("AVI Decompressor"));
    	graphManager->AddFilter(colorConverter, TEXT("Color Space Converter"));
    	graphManager->AddFilter(vidRenderer, TEXT("Video Renderer"));
    	//graphManager->AddFilter(baseFilter, TEXT("Default DirectSound Device"));
    	//graphManager->AddFilter(baseFilter, TEXT("Smart Tee"));
    
    	//Basis-Filter freigeben
    	logitechCam->Release();
    	smartTee->Release();
    	aviDecompressor->Release();
    	colorConverter->Release();
    	vidRenderer->Release();
    
    	graphManager->QueryInterface(IID_IMediaControl, (void **)graphControl);
    	graphControl->Run();
    

    Vllt hat jemand auch eine Idee, wie man die GUID's der Filter als Konstante bekommt(Momentan aus GraphEdit in der zweiten Gruppe die ID's genommen).
    Über ein sehr ausführliches DirectShow Tutorial wäre ich auch sehr dankbar(Noch neu in DirectShow und COM) 😉

    Mit freundlichen Grüßen

    Anon



  • Problem gelöst, habe jedoch ein neues Problem, und zwar möchte ich den Stream meiner Webcam jetzt in einem Fenster darstellen, jedoch sehe ich immer nur kurz ein Fenster, das sich sofort wieder schleißt. Hier der Code:

    #include <Windows.h>
    #include <dshow.h>
    #include <d3d9.h>
    #include <vmr9.h>
    #include <comutil.h>
    #include <stdlib.h>
    #include <InitGuid.h>
    #pragma comment(lib, "strmiids.lib")
    
    /*
    * Funktion zum Ermitteln aller ansprechbaren Devices.
    * Rückgabe VerketteteListe mit den Objekten.
    */
    IMoniker** GetDevices() {
    	IMoniker *dev = NULL;
    	IMoniker **devList = NULL;
    	IEnumMoniker *devs = NULL;
    	ICreateDevEnum *enumDevs = NULL;
    	HRESULT ret = NULL;
    	ULONG fetched = NULL; 
    	int i = 0;
    
    	//COMInitialisieren
    	CoInitialize(NULL);
    
    	//Speicher für DevList anfordern
    	devList = (IMoniker **)malloc(sizeof(IMoniker));
    
    	//EnumListe erstelen für VideoDevices
    	CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&enumDevs);
    
    	//Alles gut ?
    	if(SUCCEEDED(ret)) {
    		//Enumerator für GeräteKlasse erstellen
    		enumDevs->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &devs, 0);
    
    		//Alles gut ?
    		if(SUCCEEDED(ret)) {
    			//Solange noch geräte vorhanden sind 
    			while(devs->Next(1, &dev, &fetched) == S_OK) {				
    				devList = (IMoniker **)realloc(devList, (i + 1) * sizeof(IMoniker));
    				devList[i] = dev;
    				i++;
    			}
    		}
    	}
    
    	//Objekte freigeben
    	enumDevs->Release();
    	devs->Release();		
    
    	return devList;
    }
    
    /*
    * Funktion zur Ausgabe aller ermittelten DeviceNames.
    */
    void ListDevices() {
    	IMoniker **devs = GetDevices();
    	IPropertyBag *propBag;
    	VARIANT deviceName;
    	//Größe des arrays ermitteln
    	int size = sizeof(devs) / sizeof(IMoniker);
    
    	//Ausgabe aller Geräte
    	for(int i = 0; i < size; i++) {
    		devs[i]->BindToStorage(0, 0, IID_IPropertyBag, (void **)&propBag);
    		VariantInit(&deviceName);
    		propBag->Read(TEXT("FriendlyName"), &deviceName, 0); 
    		MessageBox(NULL, deviceName.bstrVal, TEXT("ID Von Device"), 0);
    		VariantClear(&deviceName);
    	}
    
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) {
    	//const GUID CAM = {0xbbefb6c7, 0x2fc4, 0x4139, 0xbb8b, 0xa58bba724083};
    	//const GUID TEE = {0xCC58E280, 0x8AA1, 0x11D1, 0xB3F1, 0x00AA003761C5};
    	//const GUID AVI = {0xCF49D4E0, 0x1115, 0x11CE, 0xB03A, 0x0020AF0BA770};
    	//const GUID CCOLOR = {0x1643E180, 0x90F5, 0x11CE, 0x97D5, 0x00AA0055595A};
    	//const GUID RENDERER = {0x70E102B0, 0x5556, 0x11Ce, 0x97C0, 0x00AA0055595A};
    
    	IMoniker **devs = GetDevices();
    	ListDevices();	
    
    	//Filter für den Stream
    	ICaptureGraphBuilder2 *capGraph = NULL;
    	CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&capGraph);   
    
    	//VideoWindow
    	IVideoWindow *vidWindow = NULL;	
    
    	//Basis-Filter für jedes Filterobjekt
    	IBaseFilter *logitechCam = NULL;
    	devs[0]->BindToObject(0, 0, IID_IBaseFilter, (void **)&logitechCam);
    	//CoCreateInstance(CAM, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&logitechCam);
    	/*IBaseFilter *smartTee = NULL;
    	CoCreateInstance(TEE, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&smartTee);*/
    	IBaseFilter *aviDecompressor = NULL;
    	CoCreateInstance(CLSID_AVIDec, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&aviDecompressor);
    	//IBaseFilter *colorConverter = NULL;
    	/*CoCreateInstance(CCOLOR, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&colorConverter);*/
    	IBaseFilter *vidRenderer = NULL;
    	CoCreateInstance(CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&vidRenderer);
    
    	//Pins abfragen
    	IPin *capture = NULL;
    	logitechCam->FindPin(TEXT("Capture"), (IPin **)capture);
    
    	//IPin *teeInput = NULL;
    	//smartTee->FindPin(TEXT("Input"), (IPin **)teeInput);
    
    	//IPin *teeCapture = NULL;
    	//smartTee->FindPin(TEXT("Capture"), (IPin **)teeCapture);
    
    	IPin *aviIn = NULL;
    	aviDecompressor->FindPin(TEXT("XForm In"), (IPin **)aviIn);
    
    	IPin *aviOut = NULL;
    	aviDecompressor->FindPin(TEXT("XForm Out"), (IPin **)aviOut);
    
    	//IPin *colorIn = NULL;
    	//colorConverter->FindPin(TEXT("Input"), (IPin **)colorIn);
    
    	//IPin *colorOut = NULL;
    	//colorConverter->FindPin(TEXT("XForm Out"), (IPin **)colorOut);
    
    	IPin *vidInput = NULL;
    	vidRenderer->FindPin(TEXT("VMR Input0"), (IPin **)vidInput);
    	//GraphManager erstellen
    	IGraphBuilder *graphManager = NULL;
    	IMediaControl *graphControl = NULL;
    	CoCreateInstance(CLSID_FilterGraph , NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&graphManager); 
    
    	//Pins verbinden
    	//graphManager->Connect(capture, teeInput);
    	//graphManager->Connect(teeCapture, aviIn);
    	//graphManager->Connect(aviOut, colorIn);
    	//graphManager->Connect(colorOut, vidInput);
    
    	graphManager->Connect(capture, aviIn);
    	graphManager->Connect(aviOut, vidInput);
    
    	graphManager->AddFilter(logitechCam, TEXT("Logitech HD Webcam C510"));	
    	//graphManager->AddFilter(smartTee, TEXT("Smart Tee"));
    	//graphManager->AddFilter(baseFilter, TEXT("HD Webcam C510"));
    	graphManager->AddFilter(aviDecompressor, TEXT("AVI Decompressor"));
    	//graphManager->AddFilter(colorConverter, TEXT("Color Space Converter"));
    	graphManager->AddFilter(vidRenderer, TEXT("Video Renderer"));
    	//graphManager->AddFilter(baseFilter, TEXT("Default DirectSound Device"));
    	//graphManager->AddFilter(baseFilter, TEXT("Smart Tee"));	
    
    	graphManager->QueryInterface(IID_IVideoWindow, (void **)&vidWindow);
    
    	vidWindow->put_Visible(OATRUE);
    	vidWindow->put_AutoShow(OATRUE);
    	vidWindow->put_Owner((OAHWND)GetDesktopWindow());
    	vidWindow->SetWindowPosition(50, 50, 400, 400);
    	vidWindow->put_WindowStyle( WS_CHILD | WS_CLIPSIBLINGS);
    
    	vidRenderer->QueryInterface(IID_IVideoWindow, (void **)&vidWindow);
    	graphManager->QueryInterface(IID_IMediaControl, (void **)&graphControl);	
    	capGraph->SetFiltergraph(graphManager);
    	capGraph->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, logitechCam, NULL, vidRenderer);
    
    	graphControl->Run();
    	//vidRenderer->Run(0);
    
    	/*
    	//CaptureGraph erstellen für die Stream Wiedergabe
    	ICaptureGraphBuilder2 *graphBuilder = NULL;
    	CoCreateInstance(CLSID_CaptureGraphBuilder, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&graphBuilder);
    
    	//Graphbuilder für die Filter Erstellung
    	IGraphBuilder *graph = NULL;
    	CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&graph);
    
    	//Mediaevent für die VideoKontrolle
    
    	IMediaEvent *mediaEvent = NULL;
    	graph->QueryInterface(IID_IMediaEvent, (void **)&mediaEvent);
    
    	IMediaControl *mediaControl = NULL;	
    	graph->QueryInterface(IID_IMediaControl, (void **)&mediaControl);		
    
    	IVideoWindow *window = NULL;
    
    	graph->QueryInterface(IID_IVideoWindow, (void **)&window);
    
    	window->put_Owner((OAHWND)GetDesktopWindow());
    	window->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
    
    	//Filter zuordnen
    	graphBuilder->SetFiltergraph(graph);
    
    	//Gerät an Filter binden
    	IBaseFilter *baseFilter = NULL;
    	devs[0]->BindToObject(0, 0, IID_IBaseFilter, (void **)&baseFilter);
    
    	//Filter für die Wiedergabe binden 
    	graph->AddFilter(baseFilter, TEXT("Video Capture"));
    
    	//Stream beginnen 
    	graphBuilder->RenderStream(NULL, NULL, NULL, baseFilter, NULL);
    
    	//Stream laufen lassen.
    	mediaControl->Run();
    	*/
    
    	//Speicher wieder freigeben
    	free(devs);
    
    	//ComUninitialisieren 
    	CoUninitialize();
    
    	return 0;
    }
    

    Mit freundlichen Grüßen

    Anon



  • Schon mal was von nem debugger gehört?
    Rückgabewerte prüfen wäre auch noch was für Dich. 🙄



  • Benutze nen Debugger, und schaue mir dort auch die Rückgabewerte an(Läuft ja auch, jedoch ist es mir unerklärlich, warum das Fenster wieder geschlossen wird. Übrigens sehr hilfreicher Beitrag)



  • Naja, Deine Anwendung beendet sich doch auch. Damit werden eben auch alle Fenster geschlossen, die die Anwendung erstellt hat (in Deinem Fall das Video-Window).



  • Das ist schon richtig, jedoch selbst wenn ich das Return Statement entferne, wird das Fenster geschlossen. Ich müsste als irgendeine Art Nachrichtenschleife oder Callback funktion haben, jedoch wüsste ich jetzt nicht, was man in DirectShow dort nehmen könnte.



  • Problem gelöst (hattes recht mit dem Return) habe jetzt ein Fenster erzeugt, in dem die Daten gecaptured werden.

    Mit freundlichen Grüßen

    Anon



  • Siehst du!


Anmelden zum Antworten