DirectShow Filtergraph initialisieren und starten
-
Hallo.
Ich arbeite zwar nicht an einem Spiel, aber an einer Grafikanwendung - und bin hoffentlich hier richtig.
Also: Ich habe hier einen selbstgeschriebenen DirectShow-Filter (abgeleitet von CTransInPlaceFilter) und baue nun darum eine Anwendung, um ihn unter kontrollierten Bedingungen testen zu können. Diese Anwendung soll ein MPEG-File per DirectX einlesen und dann durch meinen Filter durchleiten (wohin die Daten anschließend gehen, ist mir egal - die wichtigen Sachen spielen sich im Inneren des Filters ab).
Wie geht das am effektivsten?(PS: Ich habe schon versucht, den Graphen über einen IGraphBuilder zusammenzubauen und die Daten per AddSourceFilter()/RenderStream weiterzuleiten, aber außer dem Konstruktor wird keine Methode meines Filters auch nur angesehen)
-
Hast Du Dir schonmal das beigelegte Tool Graphedit angeschaut?!
Da kannst Du auf jeden Fall beliebig Filter zusammenstöpseln. Könnt' mir auch vorstellen, daß das eigentliche Rendering getestet werden kann.
-
Sgt. Nukem schrieb:
Hast Du Dir schonmal das beigelegte Tool Graphedit angeschaut?!
Da kannst Du auf jeden Fall beliebig Filter zusammenstöpseln.Und kann ich da auch ins Innere meines Filters "reinschauen"?
(btw, was muß ich eigentlich machen, um eine selbstgeschriebene Filterklasse dort verwenden zu können?)Könnt' mir auch vorstellen, daß das eigentliche Rendering getestet werden kann.
Das Rendering ist mir ja egal (da ich einen Transform-Filter habe, der die durchgeleiteten Daten lesen und nach "außen" weiterreichen soll).
-
CStoll schrieb:
Sgt. Nukem schrieb:
Hast Du Dir schonmal das beigelegte Tool Graphedit angeschaut?!
Da kannst Du auf jeden Fall beliebig Filter zusammenstöpseln.Und kann ich da auch ins Innere meines Filters "reinschauen"?
(btw, was muß ich eigentlich machen, um eine selbstgeschriebene Filterklasse dort verwenden zu können?)Ich schätze mal, ihn bei Windows "registrieren" (regsvr32.exe)
CStoll schrieb:
Könnt' mir auch vorstellen, daß das eigentliche Rendering getestet werden kann.
Das Rendering ist mir ja egal (da ich einen Transform-Filter habe, der die durchgeleiteten Daten lesen und nach "außen" weiterreichen soll).
Mit "Rendering" ist bei diesen Filterketten meist der komplette Ablauf der gesamten Kette gemeint. Zumindest hab' ich das so gemeint.
-
Sgt. Nukem schrieb:
Ich schätze mal, ihn bei Windows "registrieren" (regsvr32.exe)
Ich wollte eigentlich erst versuchen, den Filter so laufen zu lassen.
Mit "Rendering" ist bei diesen Filterketten meist der komplette Ablauf der gesamten Kette gemeint. Zumindest hab' ich das so gemeint.
Und wie würde das praktisch aussehen? Aktuell habe ich das ungefähr so aufgebaut:
ICaptureGraphBuilder2* pBuilder=...; IGraphBuilder* pGraph=...; pBuilder->SetFiltergraph(pGraph); myFilter* target=...; IBaseFilter* source; pGraph->AddFilter(target,L"mein Filter"); pGraph->AddSourceFilter(L"test.mpg",L"Bildquelle",&source); pBuilder->RenderStream(NULL,MEDIATYPE_Video,source,NULL,target);(das stammt in groben Zügen aus der MSDN bzw. DirectX SDK)
Bis dahin läuft alles ohne Fehlermeldungen ab und sollte eigentlich meinen Filtergraphen zusammensetzen.
a) Wie kann ich an dem Punkt kontrollieren, ob der Graph steht (und wie er aufgebaut ist?
b) Wie kann ich den Filtergraph jetzt dazu bringen, zu starten?
-
Ich bin jetzt einen Schritt weiter gekommen: Ich setze meine Filter über AddFilter() bzw. AddSourceFilter() in den Graph ein, hole mir über EnumPins() die notwendigen Pins und verbinde sie mittels Connect() (das führt zu ca. 200 CheckInputType-Aufrufen, bevor sich die Filter auf einen Medientyp einigen können). Jetzt muß ich es nur noch schaffen, daß dieser fertige Graph auch in Gang gesetzt wird und die Daten durchschaufelt.
PS: Irgendeine Idee, wie ich den Verbindungsaufbau abkürzen könnte?
-
So langsam habe ich alle Möglichkeiten durch, die mir eingefallen sind.
pGraph->Render(pSOut) gibt Fehlercode 0x80040111 (CLASS_E_CLASSENOTAVAILABLE) zurück
pGraph->Render(pFOut) stellt einen Mediatyp für meinen Ausgangspin ein und das war's
pSrc->Run() macht gar nichts
pFlt->Run() macht ebenfalls gar nichts(pGraph ist ein IGraphBuilder, pSrc (IBaseFilter) und pFlt (CTransInPlaceFilter-Derivat) sind die Filter und ohne Fehler-Rückgabe eingebunden, pSOut und pFOut sind jeweils die Ausgangs-Pins von pSrc bzw. pFlt)
Also bleibt eine Frage übrig: Wie kann ich den fertig zusammengebauten Filtergraph starten???
-
IMediaControl::Run
The Run method runs all the filters in the filter graph. While the graph is running, data moves through the graph and is rendered.Syntax
HRESULT Run(void);
-
Ja, das habe ich inzwischen auch schon probiert (in meiner Verzweiflung teste ich jetzt alle Direct-X-Klassen und -Interfaces durch, die eine Run()-Methode (oder was vergleichbares haben) - was hinter den Kulissen tatsächlich passiert, kann ich nicht sehen, aber nach dem Start wird definitiv nicht meine Filter::Transform()-Methode aufgerufen.
(PS: Ja, ich hab's im Debugger durchsteppen lassen, aber der will nicht IN die Methoden der DirectX-Interfaces reinspringen)
-
Kommando zurück - es funktioniert doch
(ich war wohl etwas zu ungeduldig und habe den Versuch schon abgebrochen, bevor die Daten bis zu mir durchgekommen sind).*tief durchatmet*
Ein Problem ist geklärt, auf zum nächsten.
-
CStoll schrieb:
(PS: Ja, ich hab's im Debugger durchsteppen lassen, aber der will nicht IN die Methoden der DirectX-Interfaces reinspringen)
Wahrscheinlich keine Debug-Runtimes installiert bzw. aktiviert.
Die DirectSound-Debug-Symbole sind z.B. auch nicht beim DirectX-SDK dabei, die muß man nachladen und dann aktivieren.

CStoll schrieb:
Kommando zurück - es funktioniert doch
Dann solltest Du vielleicht aus Kulanz nachfolgenden Fragern mit ähnlichen Problemen kurz erklären wo das Problem war und wie Du es letztendlich hinbekommen hast.

-
Sorry, das hatte ich vergessen - mein (Verständnis-)Problem war wohl, daß ich mit dem Debugger das komplette Programm angehalten hatte, während der Filter in einem neuen Arbeitsthread darauf wartete, endlich loslaufen zu können.
(wie ich schonmal sagte: Multithreading ist nicht meine stärkste Seite ;))
...//Graph zusammenbauen IMediaControl* pCont; pGraph->QueryInterface(&pCont); hr=pCont->Run(); if(!SUCCEEDED(hr))// <- BREAK TRACE("Error"); ...(ich stand an der Position BREAK und hab' mich gewundert, warum's nicht weiterging - ein paar Sekunden nachdem ich das Programm reaktiviert hatte, kamen die ersten Wortmeldungen von meinem Filter)