Share via


Übersicht über Datenfluss in DirectShow

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde durch MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation ersetzt. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code nach Möglichkeit MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet. Microsoft schlägt vor, vorhandenen Code, der die Legacy-APIs verwendet, um nach Möglichkeit die neuen APIs zu verwenden.]

Dieser Abschnitt bietet eine umfassende Übersicht über die Funktionsweise des Datenflusses in DirectShow. Details finden Sie in anderen Abschnitten der Dokumentation.

Daten werden in Puffern gespeichert, die einfach Arrays von Bytes sind. Jeder Puffer wird von einem COM-Objekt namens Medienbeispiel umschlossen, das die IMediaSample-Schnittstelle implementiert. Beispiele werden von einem anderen Objekttyp erstellt, der als Zuteilung bezeichnet wird und die IMemAllocator-Schnittstelle implementiert. Für jede Pinverbindung wird ein Zuteilungsgeber zugewiesen, obwohl zwei oder mehr Pinverbindungen denselben Zuordnungsator verwenden können. Die folgende Abbildung veranschaulicht diesen Vorgang.

Puffer, Beispiele und Zuteilungen

Jeder Zuteilungsgeber erstellt einen Pool mit Medienbeispielen und weist die Puffer für jedes Beispiel zu. Wenn ein Filter einen Puffer mit Daten füllen muss, fordert er ein Beispiel vom Zuteilungsgeber an, indem er IMemAllocator::GetBuffer aufruft. Wenn der Zuweisungsgeber über Beispiele verfügt, die derzeit nicht von einem anderen Filter verwendet werden, gibt die GetBuffer-Methode sofort mit einem Zeiger auf das Beispiel zurück. Wenn alle Beispiele des Zuweisungsgebers verwendet werden, blockiert die -Methode, bis ein Beispiel verfügbar ist. Wenn die Methode ein Beispiel zurückgibt, legt der Filter Daten in den Puffer, legt die entsprechenden Flags für das Beispiel fest (in der Regel einschließlich eines Zeitstempels), und sendet das Beispiel nachgeschaltet.

Wenn ein Rendererfilter ein Beispiel empfängt, überprüft er den Zeitstempel und hält an dem Beispiel fest, bis die Referenzuhr des Filterdiagramms angibt, dass die Daten gerendert werden sollen. Nachdem der Filter die Daten gerendert hat, wird das Beispiel freigegeben. Das Beispiel wird erst wieder in den Pool der Zuteilungsbeispiele zurückgegeben, bis die Referenzanzahl des Beispiels 0 ist, was bedeutet, dass jeder Filter das Beispiel freigegeben hat. Die folgende Abbildung veranschaulicht diesen Vorgang.

Decoder wartet auf ein kostenloses Medienbeispiel

Der Upstream-Filter kann vor dem Renderer ausgeführt werden, d. h. er füllt Puffer schneller, als der Renderer sie verbraucht. Trotzdem werden Die Beispiele nicht frühzeitig gerendert, da der Renderer jedes element bis zu seiner Präsentationszeit enthält. Darüber hinaus überschreibt der Upstream-Filter Puffer nicht versehentlich, da GetSample nur Beispiele zurückgibt, die sonst nicht verwendet werden. Die Menge, mit der der Upstream-Filter im Voraus ausgeführt werden kann, wird durch die Anzahl der Stichproben im Pool des Zuteilungsgebers bestimmt.

Das vorherige Diagramm zeigt nur einen Zuweisungsator, aber in der Regel gibt es mehrere Zuteilungen pro Stream. Wenn der Renderer also ein Beispiel freigibt, kann dies eine kaskadierende Wirkung haben. Das folgende Diagramm zeigt eine Situation, in der ein Decoder einen komprimierten Videoframe enthält, während er wartet, bis der Renderer ein Beispiel freigibt. Ein Parserfilter wartet auch darauf, dass der Decoder ein Beispiel freigibt.

zwei Filter, die auf Beispiele warten

Wenn der Renderer sein Beispiel freigibt, wird der ausstehende Aufruf von GetBuffer des Decoders zurückgegeben. Der Decoder kann dann den komprimierten Videoframe decodieren und das enthaltene Beispiel freigeben, wodurch die Blockierung des ausstehenden GetBuffer-Aufrufs des Parsers aufgehoben wird.

Datenfluss im Filterdiagramm