Freigeben über


Erstellen des Recompression Graph

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation abgelöst. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code mediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, so umgeschrieben wird, dass nach Möglichkeit die neuen APIs verwendet werden.]

Ein typisches Filterdiagramm für die AVI-Dateirekomprimierung sieht wie folgt aus:

Avi-Rekomprimierungsdiagramm

Der AVI-Splitterfilter ruft Daten aus dem Dateiquellenfilter (Async) ab und analysiert sie in Video- und Audiostreams. Der Video-Dekomprimierer decodiert das komprimierte Video, wo es vom Videokompressor erneut komprimiert wird. Die Auswahl der Dekomprimierungselemente hängt von der Quelldatei ab. Sie wird automatisch von Intelligent Connect verarbeitet. Die Anwendung muss den Kompressor auswählen, in der Regel, indem dem Benutzer eine Liste angezeigt wird. (Siehe Auswählen eines Komprimierungsfilters.)

Das komprimierte Video wechselt dann zum AVI-Mux-Filter. Der Audiodatenstrom in diesem Beispiel ist nicht komprimiert, sodass er direkt vom AVI-Splitter zum AVI-Mux wechselt. Die AVI Mux stellt die beiden Streams ineinander, und der Dateischreiberfilter schreibt die Ausgabe auf den Datenträger. Beachten Sie, dass der AVI-Mux auch dann erforderlich ist, wenn die Originaldatei keinen Audiodatenstrom aufweist.

Die einfachste Möglichkeit zum Erstellen dieses Filtergraphen ist die Verwendung des Capture Graph Builder, einer DirectShow-Komponente zum Erstellen von Erfassungsgraphen und anderen benutzerdefinierten Filtergraphen.

Rufen Sie zunächst CoCreateInstance auf, um den Capture Graph Builder zu erstellen:

ICaptureGraphBuilder2 *pBuild = NULL;
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, 
                        NULL, CLSCTX_INPROC_SERVER,
    IID_ICaptureGraphBuilder2, (void **)&pBuild);

Verwenden Sie dann den Capture Graph Builder, um das Filterdiagramm zu erstellen:

  1. Erstellen Sie den Renderingabschnitt des Graphen, der den AVI Mux-Filter und den File Writer enthält.
  2. Fügen Sie dem Diagramm den Quellfilter und den Komprimierungsfilter hinzu.
  3. Verbinden Sie den Quellfilter mit dem MUX-Filter. Der Capture Graph Builder fügt alle Splitter- und Decoderfilter ein, die zum Analysieren der Quelldatei erforderlich sind. Es kann auch die Video- und Audiostreams über Komprimierungsfilter weiterleiten.

In den folgenden Abschnitten werden die einzelnen Schritte erläutert.

Erstellen des Renderingabschnitts

Rufen Sie zum Erstellen des Renderingabschnitts des Graphen die ICaptureGraphBuilder2::SetOutputFileName-Methode auf. Diese Methode verwendet Eingabeparameter, die den Medienuntertyp für die Ausgabe und den Namen der Ausgabedatei angeben. Sie gibt Zeiger auf den MUX-Filter und den Dateischreiber zurück. Der MUX-Filter wird für die nächste Phase der Grapherstellung benötigt. Der Zeiger auf den Dateiwriter ist für dieses Beispiel nicht erforderlich, sodass dieser Parameter NULL sein kann:

IBaseFilter *pMux = NULL;
hr = pBuild->SetOutputFileName(
        &MEDIASUBTYPE_Avi, // File type. 
        wszOutputFile,     // File name, as a wide-character string.
        &pMux,             // Receives a pointer to the multiplexer.
        NULL);             // Receives a pointer to the file writer. 

Wenn die Methode zurückgibt, verfügt der MUX-Filter über eine ausstehende Verweisanzahl. Stellen Sie daher sicher, dass Sie den Zeiger später freigeben.

Das folgende Diagramm zeigt das Filterdiagramm an dieser Stelle.

Renderingabschnitt des Filterdiagramms

Der MUX-Filter macht zwei Schnittstellen zum Steuern des AVI-Formats verfügbar:

Hinzufügen der Quell- und Komprimierungsfilter

Der nächste Schritt besteht darin, dem Filterdiagramm die Quell- und Komprimierungsfilter hinzuzufügen. Der Capture Graph Builder erstellt automatisch eine instance des Graphfilter-Managers, wenn Sie SetOutputFileName aufrufen. Rufen Sie einen Zeiger darauf ab, indem Sie die ICaptureGraphBuilder2::GetFiltergraph-Methode aufrufen:

IGraphBuilder *pGraph = NULL;
hr = pBuild->GetFiltergraph(&pGraph);

Rufen Sie nun die IGraphBuilder::AddSourceFilter-Methode auf, um den Async File Source-Filter hinzuzufügen, und die IFilterGraph::AddFilter-Methode , um den Videokompressor hinzuzufügen:

IBaseFilter *pSrc = NULL;
hr = pGraph->AddSourceFilter(wszInputFile, L"Source Filter", &pSrc);
hr = pGraph->AddFilter(pVComp, L"Compressor");

An diesem Punkt sind der Quellfilter und der Komprimierungsfilter nicht mit anderen Elementen im Diagramm verbunden, wie in der folgenden Abbildung gezeigt:

Filterdiagramm mit Quell- und Komprimierungsfiltern

Verbinden der Quelle mit dem Mux

Der letzte Schritt besteht darin, den Quellfilter über den Videokompressor mit dem AVI Mux-Filter zu verbinden. Verwenden Sie die ICaptureGraphBuilder2::RenderStream-Methode , die einen Ausgabepin im Quellfilter mit einem angegebenen Senkenfilter verbindet, optional über einen Komprimierungsfilter.

Die ersten beiden Parameter geben an, welche Pins des Quellfilters verbunden werden sollen, indem eine Pinkategorie und ein Medientyp angegeben werden. Der Filter "Asynchrone Dateiquelle" verfügt nur über einen Ausgabepin, sodass diese Parameter NULL sein sollten. Die nächsten drei Parameter geben den Quellfilter, den Komprimierungsfilter (falls vorhanden) und den Mux-Filter an.

Im folgenden Codebeispiel wird der Videostream über den Videokompressor gerendert:

hr = pBuild->RenderStream(
        NULL,       // Output pin category
        NULL,       // Media type
        pSrc,       // Source filter
        pVComp,     // Compression filter
        pMux);      // Sink filter (the AVI Mux)

Das folgende Diagramm zeigt das bisherige Filterdiagramm.

Gerenderter Videostream

Unter der Annahme, dass die Quelldatei über einen Audiodatenstrom verfügt, hat der AVI-Splitter-Filter einen Ausgabepin für die Audiodaten erstellt. Um diesen Pin zu verbinden, rufen Sie RenderStream erneut auf:

hr = pBuild->RenderStream(NULL, NULL, pSrc, NULL, pMux);

Hier wird kein Komprimierungsfilter angegeben. Der Ausgabepin des Quellfilters ist bereits verbunden, sodass die RenderStream-Methode nach einem nicht verbundenen Ausgabepin im Splitterfilter sucht. Er findet den Audio-Pin und verbindet ihn direkt mit dem MUX-Filter. Wenn die Quelldatei keinen Audiodatenstrom enthält, schlägt der zweite Aufruf von RenderStream fehl. Dieses Verhalten wird erwartet. Das Diagramm ist nach dem ersten Aufruf von RenderStream abgeschlossen, sodass der Fehler im zweiten Aufruf harmlos ist.

In diesem Beispiel ist die Reihenfolge der beiden RenderStream-Aufrufe wichtig. Da der zweite Aufruf keinen Kompressor angibt, werden alle nicht verbundenen Pins vom AVI-Splitter verbunden. Wenn Sie diesen Anruf vor dem anderen tätigen, kann er den Videostream ohne Ihren Videokompressor mit dem AVI Mux verbinden. Daher muss zuerst der spezifischere Aufruf (mit dem Komprimierungsfilter) erfolgen.

In der vorherigen Diskussion wurde davon ausgegangen, dass die Quelldatei eine AVI-Datei ist. Dieses Verfahren funktioniert jedoch auch mit anderen Dateitypen, z. B. MPEG-Dateien. Das resultierende Filterdiagramm ist etwas anders.

Erneutes Komprimieren einer AVI-Datei