2008-08-26 18 views
14

Ich habe eine DirectShow-Grafik, um MPEG2/4-Filme aus einem Netzwerkstream zu rendern. Wenn ich den Graphen zusammenfüge, indem ich die Pins manuell verbinde, rendert es nicht. Aber wenn ich Render auf dem GraphBuilder aufruft, ist es in Ordnung.Wie kann ich ein DirectShow-Diagramm zurückentwickeln?

Offensichtlich gibt es einige Setup-Schritte, die ich nicht auf einem Filter in dem Diagramm ausführe, das von GraphBuilder ausgeführt wird.

Gibt es eine Möglichkeit, Debug-Ausgabe von GraphBuilder zu sehen, wenn es ein Diagramm zusammenbaut?

Gibt es eine Möglichkeit, ein funktionierendes Diagramm auszugeben, um zu sehen, wie es zusammengesetzt wurde?

Haben Sie noch weitere Ideen, um das Geheimnis der DirectShow-Box zu entwirren?

Danke! -Z

Antwort

13

Sie können das Diagramm, das Sie erstellt haben, mit GraphEdit, einem Tool aus dem DirectShow SDK, ansehen. In GraphEdit, wählen Sie File-> auf Remote-Graph Verbinden ...

Um Ihr Diagramm in der Liste zu finden, haben Sie es in der aktiven Objekttabelle registrieren:

void AddToRot(IUnknown *pUnkGraph, DWORD *pdwRegister) 
{ 
    IMoniker* pMoniker; 
    IRunningObjectTable* pROT; 
    GetRunningObjectTable(0, &pROT); 

    WCHAR wsz[256];  
    swprintf_s(wsz, L"FilterGraph %08p pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); 
    CreateItemMoniker(L"!", wsz, &pMoniker); 

    pROT->Register(0, pUnkGraph, pMoniker, pdwRegister); 

    // Clean up any COM stuff here ... 
} 

nach dem Diagramm zu zerstören Sie sollten es aus dem ROT entfernen, indem Sie IRunningObjectTable :: Revoke aufrufen

0

Ältere Versionen von DirectX, ich glaube 9a, aber nicht 9b hatte einen "Debug-Modus" für dshow. Es würde Protokolle von Debug-Informationen in die Debug-Konsole ausgeben.

So laden Sie eine ältere Version, legen Sie es zum Debuggen. Öffnen Sie dann debugview oder laden Sie graphedt.exe in Visual Studio, um die Debug-Informationen zu sehen.

10

Roman Ryltsov hat ein DirectShow Filter Graph Spy-Tool (http://alax.info/blog/777) erstellt, eine Wrapper-COM-DLL über die FilterGraph-Schnittstelle, die alle Aufrufe von FilterGraph-Methoden protokolliert.

Es wird auch alle erstellten Grafiken in Running Object Table (ROT) hinzufügen, die Sie dann mit Tools wie GraphEdit oder GraphStudio visualisieren können. Sehr nützlich, wenn Sie sehen möchten, wie ein Windows Media Player-Diagramm aussieht.

4

IGraphBuilder :: SetLogFile (siehe http://msdn.microsoft.com/en-us/library/dd390091(v=vs.85).aspx) gibt Ihnen viele nützliche diagnostische Informationen darüber, was während der Erstellung des Diagramms passiert. Übergeben Sie ein Dateihandle (z. B. von CreateFile geöffnet), und übertragen Sie es an DWORD_PTR. Rufen Sie erneut mit NULL auf, um die Protokollierung abzuschließen, bevor Sie das Dateihandle schließen.

Der Code im folgenden Blogpost zum Dumping eines Diagramms gibt Ihnen einige zusätzliche Informationen zur Interpretation der Zahlen in der Protokolldatei.

http://rxwen.blogspot.com/2010/04/directshow-debugging-tips.html

+0

Great! Ich lerne eine neue sehr nützliche Information über DirectShow :-) –

1

Sie müssen:

  1. Registrieren Sie Diagramm, um die "Running Objekte Table" Filter - ROT - Verwenden Sie den Code unten
  2. Verbindung zu Ihrem Filtergraphen mit GraphEdit (File-> Eine Verbindung mit Fern Grafik) oder noch besser - mit GraphEditPlus

Um die Filtergraphen als "anschließbaren" graph, rufen Sie dies mit Ihrem Filtergraphen zu registrieren:

void AddToROT(IUnknown *pUnkGraph, DWORD *pdwRegister) 
{ 
    IMoniker * pMoniker; 
    IRunningObjectTable *pROT; 
    WCHAR wsz[128]; 
    HRESULT hr; 

    if (FAILED(GetRunningObjectTable(0, &pROT))) 
     return; 

    wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); 

    hr = CreateItemMoniker(L"!", wsz, &pMoniker); 
    if (SUCCEEDED(hr)) 
    { 
     hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister); 
     pMoniker->Release(); 
    } 

    pROT->Release(); 
} 

Und das nennen, bevor Sie das Diagramm Mitteilung:

void RemoveFromROT(DWORD pdwRegister) 
{ 
    IRunningObjectTable *pROT; 

    if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) 
    { 
     pROT->Revoke(pdwRegister); 
     pROT->Release(); 
    } 
} 

`