Liefern von Beispielen

[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.]

In diesem Artikel wird beschrieben, wie ein Filter ein Beispiel liefert. Es beschreibt sowohl das Pushmodell mit IMemInputPin-Methoden als auch das Pullmodell mit IAsyncReader.

Pushmodell: Bereitstellen eines Beispiels

Der Ausgabepin liefert ein Beispiel, indem die IMemInputPin::Receive-Methode oder die IMemInputPin::ReceiveMultiple-Methode aufgerufen wird, die gleichwertig ist, aber ein Array von Beispielen liefert. Der Eingabenadel kann in Receive (oder ReceiveMultiple) blockiert werden. Wenn der Pin möglicherweise blockiert, sollte die IMemInputPin::ReceiveCanBlock-Methode S_OK zurückgeben. Wenn der Pin garantiert, dass nie blockiert wird, sollte ReceiveCanBlock S_FALSE zurückgeben. Der S_OK Rückgabewerts bedeutet nicht, dass Empfang immer blockiert wird, nur dass dies möglicherweise der Fall ist.

Obwohl Receive blockieren kann, um auf die Verfügbarkeit einer Ressource zu warten, sollte es nicht blockieren, auf weitere Daten aus dem Upstream-Filter zu warten. Dies kann zu einem Deadlock führen, bei dem der Upstream-Filter wartet, bis der Downstreamfilter das Beispiel losgibt. Dies geschieht nicht, da der Downstreamfilter auf den Upstream-Filter wartet. Wenn ein Filter jedoch über mehrere Eingabestifte verfügt, kann ein Pin warten, bis ein anderer Pin Daten empfängt. Dies wird beispielsweise vom AVI Mux-Filter ausgeführt, sodass Audio- und Videodaten miteinander verwebt werden können.

Eine Pin kann ein Beispiel aus verschiedenen Gründen ablehnen:

  • Der Stift wird geleert (siehe Flushing).
  • Der Pin ist nicht verbunden.
  • Der Filter wird beendet.
  • Ein anderer Fehler ist aufgetreten.

Die Receive-Methode sollte im ersten Fall S_FALSE und in den anderen Fällen einen Fehlercode zurückgeben. Der Upstream-Filter sollte das Senden von Beispielen beenden, wenn der Rückgabecode etwas anderes als S_OK ist.

Sie können die ersten drei Fälle als "erwartete" Fehler in dem Sinne betrachten, dass sich der Filter im falschen Zustand befand, um Beispiele zu empfangen. Ein unerwarteter Fehler wäre ein Fehler, der dazu führt, dass die Pin ein Beispiel ablehnt, obwohl sich die Pin im Empfangszustand befindet. Wenn ein Fehler dieses Typs auftritt, sollte der Pin eine Nachverfolgungsbenachrichtigung zum Ende des Datenstroms senden und ein EC_ERRORABORT-Ereignis an den Filter Graph-Manager senden.

In den DirectShow-Basisklassen überprüft die CBaseInputPin::CheckStreaming-Methode auf die allgemeinen Fehlerfälle – geleerte, beendete usw. Die abgeleitete Klasse muss nach Fehlern suchen, die für den Filter spezifisch sind. Im Falle eines Fehlers sendet die CBaseInputPin::Receive-Methode die Benachrichtigung zum Ende des Datenstroms und das EC_ERRORABORT-Ereignis.

Pullmodell: Anfordern eines Beispiels

In der IAsyncReader-Schnittstelle fordert der Eingabenadel Beispiele vom Ausgabenadel an, indem eine der folgenden Methoden aufgerufen wird:

Die Request-Methode ist asynchron. der Eingabenadel ruft IAsyncReader::WaitForNext auf, um zu warten, bis die Anforderung abgeschlossen ist. Die beiden anderen Methoden sind synchron.

Wann Daten übermittelt werden sollen

Ein Filter liefert immer Beispiele, während er sich im Ausführungszustand befindet. In den meisten Fällen liefert ein Filter auch Beispiele, während er angehalten wird. Dadurch kann das Diagramm die Daten auflisten, sodass die Wiedergabe sofort beginnt, wenn Run aufgerufen wird (siehe Filterstatus). Wenn ihr Filter keine Daten angibt, während er angehalten wird, sollte die IMediaFilter::GetState-Methode des Filters VFW_S_CANT_CUE im angehaltenen Zustand zurückgeben. Dieser Rückgabecode signalisiert dem Filterdiagramm, nicht auf Daten aus dem Filter zu warten, bevor der Übergang zum Anhalten abgeschlossen ist. Andernfalls wird die Pause-Methode unbegrenzt blockiert. Beispielcode finden Sie unter CBaseFilter::GetState.

Im Folgenden finden Sie einige Beispiele dafür, wann ein Filter möglicherweise VFW_S_CANT_CUE zurückgeben muss:

  • Livequellen, z. B. Aufzeichnungsfilter, sollten keine Daten senden, während sie angehalten werden. Weitere Informationen finden Sie unter Erstellen von Daten in einem Erfassungsfilter.
  • Ein Splitterfilter kann daten senden, während er angehalten wird, je nach Implementierung. Wenn der Filter separate Threads verwendet, um Daten an jedem Ausgabenadel in die Warteschlange zu stellen, kann er Daten senden, während er angehalten wird. Wenn der Filter jedoch einen einzelnen Thread für jeden Ausgabepin verwendet, blockiert der erste Pin möglicherweise den Thread, wenn er Receive aufruft, was verhindert, dass die anderen Pins Daten senden. In diesem Fall sollten Sie VFW_S_CANT_CUE zurückgeben.
  • Ein Filter kann daten sporadisch übermitteln. Beispielsweise kann es einen benutzerdefinierten Datenstrom analysieren und einige Pakete herausfiltern, während andere gesendet werden. In diesem Fall kann nicht garantiert werden, dass der Filter Daten angibt, während er angehalten wird.

Ein Quellfilter (mit dem Pushmodell) oder ein Parserfilter (mithilfe des Push-/Pullmodells) erstellt einen oder mehrere Streamingthreads, die so schnell wie möglich Beispiele liefern. Nachgeschaltete Filter, z. B. Decoder und Transformationen, senden Daten in der Regel nur, wenn Receive an ihren Eingabepins aufgerufen wird.

Empfangen und Übermitteln von Beispielen