Mediensenken

Mediensenken sind die Pipelineobjekte, die Mediendaten empfangen. Ein Mediensenken ist das Ziel für einen oder mehrere Mediendatenströme. Mediensenken fallen in zwei allgemeine Kategorien:

  • Ein Renderer ist ein Mediensenken, das Daten für die Wiedergabe anzeigt. Der erweiterte Videorenderer (EVR) zeigt Videoframes an, und der Audiorenderer gibt Audiostreams über die Soundkarte oder ein anderes Audiogerät ab.

  • Ein Archivsenken ist ein Mediensenken , das Daten in eine Datei oder einen anderen Speicher schreibt.

Der Hauptunterschied zwischen ihnen besteht darin, dass ein Archivsenken die Daten nicht mit einer festen Wiedergaberate nutzt. Stattdessen schreibt er die Daten, die er so schnell wie möglich empfängt.

Mediensenken stellen die IMFMediaSink-Schnittstelle zur Verfügung. Jede Mediensenke enthält eine oder mehrere Datenstromsenken. Jede Datensenken empfängt die Daten aus einem Datenstrom. Stream-Sinks machen die IMFStreamSink-Schnittstelle verfügbar. In der Regel erstellt eine Anwendung keine Mediensenken direkt. Stattdessen erstellt die Anwendung ein oder mehrere Aktivierungsobjekte, die die Mediensitzung zum Erstellen der Spüle verwendet. Alle anderen Vorgänge auf der Spüle werden von der Mediensitzung behandelt, und die Anwendung ruft keine Methoden für die Mediensenke oder eines der Datenstromsenken auf. Weitere Informationen zu Aktivierungsobjekten finden Sie unter Aktivierungsobjekte.

Sie sollten den Rest dieses Themas lesen, wenn Sie eine benutzerdefinierte Mediensenke schreiben oder eine Mediensenke direkt ohne die Mediensitzung verwenden möchten.

Stream-Sinks

Ein Mediensenken kann eine feste Anzahl von Datenstromsenken aufweisen, oder es kann das Hinzufügen und Entfernen von Datenstromsenken unterstützen. Wenn eine feste Anzahl von Datenstromsenken vorhanden ist, gibt die IMFMediaSink::GetCharacteristics-Methode das MEDIASINK_FIXED_STREAMS Flag zurück. Andernfalls können Sie Stream-Sinks hinzufügen und entfernen. Um einen neuen Stream-Sink hinzuzufügen, rufen Sie IMFMediaSink::AddStreamSink auf. Rufen Sie IMFMediaSink::RemoveStreamSink auf, um einen Datenstromsenken zu entfernen. Das MEDIASINK_FIXED_STREAMS Flag gibt an, dass die Mediensenke diese beiden Methoden nicht unterstützt. (Es kann eine andere Möglichkeit unterstützen, die Anzahl der Datenströme zu konfigurieren, z. B. durch Festlegen von Initialisierungsparametern, wenn die Spüle erstellt wird.) Die Liste der Stream-Sinken wird sortiert. Rufen Sie die IMFMediaSink::GetStreamSinkByIndex-Methode auf, um sie nach Indexwert aufzuzählen.

Stream-Sinks weisen auch Bezeichner auf. Datenstrombezeichner sind innerhalb der Mediensenken eindeutig, müssen jedoch nicht aufeinander folgen. Je nach Mediensenken haben die Datenstrombezeichner möglicherweise eine gewisse Bedeutung, die sich auf den Inhalt bezieht. Beispielsweise kann ein Archivsenken die Datenstrombezeichner in den Dateiheader schreiben. Andernfalls sind sie beliebig. Rufen Sie IMFMediaSink::GetStreamSinkById auf, um einen Datenstromsenken anhand seines Bezeichners abzurufen.

Präsentationsuhr

Die Rate, mit der ein Mediensenken Beispiele verbraucht, wird durch die Präsentationsuhr gesteuert. Die Mediensitzung wählt die Präsentationsuhr aus und legt sie auf der Mediensenke fest, indem sie die IMFMediaSink::SetPresentationClock-Methode aufruft. Die Präsentationsuhr muss auf der Mediensenke festgelegt werden, bevor das Streaming beginnen kann. Jede Mediensenke erfordert eine Präsentationsuhr, die ausgeführt werden soll. Die Mediensenke verwendet die Präsentationsuhr für zwei Zwecke:

  • So empfangen Sie Benachrichtigungen beim Starten oder Anhalten des Streamings. Die Mediensenke empfängt diese Benachrichtigungen über die IMFClockStateSink-Schnittstelle , die alle Mediensenken implementieren müssen.

  • Um zu bestimmen, wann beispiele gerendert werden sollen. Wenn die Mediensenke ein neues Beispiel empfängt, wird der Zeitstempel aus dem Beispiel abgerufen und versucht, das Beispiel zu dieser Präsentationszeit zu rendern.

Die Präsentationsuhr leitet die Uhrzeiten von einem anderen Objekt ab, das als Präsentationszeitquelle bezeichnet wird. Präsentationszeitquellen machen die IMFPresentationTimeSource-Schnittstelle verfügbar. Einige Mediensenken haben Zugriff auf eine genaue Uhr, sodass sie diese Schnittstelle verfügbar machen. Dies bedeutet, dass ein Mediensenken Beispiele für eine Zeit planen kann, die von der eigenen Uhr bereitgestellt wird. Die Mediensenke kann jedoch nicht davon ausgehen, dass dies der Fall ist. Es muss immer die Zeit von der Präsentationsuhr verwenden, unabhängig davon, ob die Präsentationsuhr vom Mediensenken selbst oder von einer anderen Uhr gesteuert wird.

Wenn ein Mediensenken keine Übereinstimmungen mit einer anderen Uhr als einer anderen Uhr hat, gibt die GetCharacteristics-Methode das MEDIASINK_CANNOT_MATCH_CLOCK Flag zurück. Wenn dieses Kennzeichen vorhanden ist und die Präsentationsuhr eine andere Präsentationszeitquelle verwendet, ist die Mediensenke wahrscheinlich schlecht ausgeführt. Beispielsweise kann es während der Wiedergabe glitchen.

Eine ratelose Spüle ist ein Mediensenken, das die Zeitstempel für Proben ignoriert und Daten verbraucht, sobald jedes Beispiel eingeht. Ein rateless Media Sink gibt das MEDIASINK_RATELESS Flag aus der GetCharacteristics-Methode zurück. In der Regel gilt dieses Kennzeichen für Archivsenken. Wenn jede Mediensenke in der Pipeline ratelos ist, verwendet die Mediensitzung eine spezielle ratelose Präsentationsuhr. Diese Uhr wird so schnell ausgeführt, wie die Spüle Proben verbrauchen.

Streamformate

Bevor die Mediensenke Beispiele empfangen kann, muss der Client den Medientyp auf den Stream-Sinks festlegen. Rufen Sie die IMFStreamSink::GetMediaTypeHandler-Methode auf, um den Medientyp festzulegen. Diese Methode gibt einen Zeiger auf die IMFMediaTypeHandler-Schnittstelle zurück. Verwenden Sie diese Schnittstelle, um die Liste der bevorzugten Medientypen abzurufen, den aktuellen Medientyp abzurufen und den Medientyp festzulegen.

Rufen Sie ZUM Abrufen der Liste der bevorzugten Medientypen IMFMediaTypeHandler::GetMediaTypeByIndex auf. Die bevorzugten Typen sollten als Hinweis auf den Client verwendet werden. Die Liste kann unvollständig sein oder teilweise Medientypen enthalten. Ein teiler Medientyp ist ein Typ, der nicht über alle Attribute verfügt, die zum Beschreiben eines gültigen Formats erforderlich sind. Ein teiler Videotyp kann beispielsweise den Farbraum und die Bittiefe angeben, aber nicht die Bildbreite oder Höhe. Ein partieller Audiotyp kann das Komprimierungsformat und die Samplerate angeben, aber nicht die Anzahl der Audiokanäle.

Rufen Sie IMFMediaTypeHandler::GetCurrentMediaType auf, um den aktuellen Medientyp des Streamens abzurufen. Wenn ein Datenstromsenken zum ersten Mal erstellt wird, hat er möglicherweise bereits einen Standardmedientyp festgelegt, oder er verfügt über keinen Medientyp, bis der Client einen festlegt.

Um den Medientyp festzulegen, rufen Sie IMFMediaTypeHandler::SetCurrentMediaType auf. Einige Stream-Sinks unterstützen möglicherweise nicht das Ändern des Typs, nachdem festgelegt wurde. Daher ist es hilfreich, Medientypen zu testen, bevor sie festgelegt werden. Rufen Sie IMFMediaTypeHandler::IsMediaTypeSupported auf, um zu testen, ob der Mediensenken einen Medientyp akzeptiert, (ohne den Typ festzulegen).

Datenfluss

Mediensenken verwenden ein Pullmodell, was bedeutet, dass die Daten vom Datenstrom sinken, während sie sie benötigen. Der Client sollte rechtzeitig reagieren, um eine Glitchingsbeschnüpfung zu vermeiden.

Einige Mediensenken unterstützen die Vorrolling. Vorrolling ist der Prozess, daten dem Mediensenken zu geben, bevor die Präsentationsuhr beginnt. Wenn ein Mediensenken die Vorrolling unterstützt, macht die Mediensenke die IMFMediaSinkPreroll-Schnittstelle verfügbar, und die GetCharacteristics-Methode gibt das MEDIASINK_CAN_PREROLL Flag zurück. Vorrolling stellt sicher, dass die Mediensenke bereit ist, das erste Beispiel zu präsentieren, wenn die Präsentationsuhr beginnt. Es wird empfohlen, dass der Client immer vorabrollt, wenn die Mediensenke sie unterstützt, da sie während der Wiedergabe glitching oder Lücken verhindern kann.

Der Datenfluss zu einem Mediensenken funktioniert wie folgt:

  1. Der Client legt die Medientypen und die Präsentationsuhr fest. Die Mediensenke registriert sich selbst mit der Präsentationsuhr, um Benachrichtigungen über Änderungen des Uhrzustands zu erhalten.
  2. Optional fragt der Client nach IMFMediaSinkPreroll. Wenn die Mediensenke diese Schnittstelle verfügbar macht, ruft der Client IMFMediaSinkPreroll::NotifyPreroll auf. Andernfalls springt der Client zu Schritt 5.
  3. Jede Stream-Sink sendet mindestens ein MEStreamSinkRequestSample-Ereignis . Als Reaktion auf jede dieser Ereignisse ruft der Client das nächste Datenbeispiel für diesen Datenstrom ab und ruft IMFStreamSink::P rocessSample auf.
  4. Wenn jeder Stream-Sink genügend Vorabdaten empfängt, sendet es ein MEStreamSinkPrerolled-Ereignis .
  5. Der Client ruft IMFPresentationClock::Start auf, um die Präsentationsuhr zu starten.
  6. Die Präsentationsuhr benachrichtigt die Mediensenken, dass die Uhr gestartet wird, indem SIE IMFClockStateSink::OnClockStart aufrufen.
  7. Um weitere Daten abzurufen, sendet jeder Stream-Sink MEStreamSinkRequestSample-Ereignisse . Als Reaktion auf jede dieser Ereignisse ruft der Client das nächste Beispiel ab und ruft ProcessSample auf. Dieser Schritt wird wiederholt, bis die Präsentation endet.

Die meisten Mediensenken verarbeiten Beispiele asynchron, sodass die Datenstromsenken mehrere Beispielanforderungen gleichzeitig senden können.

Während des Streamings kann der Client JEDERZEIT IMFStreamSink::P laceMarker und IMFStreamSink::Flush aufrufen. Markierungen werden im nächsten Abschnitt beschrieben. Durch das Leeren wird der Datenstromsenken alle Beispiele ablegen, die sie in die Warteschlange gestellt, aber noch nicht gerendert haben.

Marker

Marker bieten eine Möglichkeit für den Client, bestimmte Punkte im Datenstrom anzugeben. Eine Markierung besteht aus den folgenden Informationen:

  • Der Markierungstyp, der als Element der MFSTREAMSINK_MARKER_TYPE-Enumeration definiert ist.
  • Daten, die der Markierung zugeordnet sind. Die Bedeutung der Daten hängt vom Markierungstyp ab. Einige Markierungstypen verfügen nicht über Daten.
  • Optionale Daten für die eigene Verwendung des Clients.

Um eine Markierung zu platzieren, ruft der Client IMFStreamSink::P laceMarker auf. Die Datenstromsenke beendet die Verarbeitung aller Beispiele, die sie vor dem PlaceMarker-Aufruf empfangen hat, und sendet dann ein MEStreamSinkMarker-Ereignis .

Die meisten Mediensenken behalten eine Warteschlange aus ausstehenden Beispielen bei, die sie asynchron verarbeiten. Markierungsereignisse müssen mit der Beispielverarbeitung serialisiert werden, sodass die Mediensenken die Markierungen in derselben Warteschlange platzieren sollten. Angenommen, der Client führt die folgenden Methodenaufrufe aus:

  1. ProcessSample (Beispiel #1)
  2. ProcessSample (Beispiel #2)
  3. PlaceMarker (Marker #1)
  4. ProcessSample (Beispiel #3)
  5. PlaceMarker (Marker #2)

In diesem Beispiel muss der Datenstromsenken das MEStreamSinkMarker-Ereignis an Markierung #1 senden, nachdem es Beispiel #2 verarbeitet hat, und das Ereignis für Marker #2 nach dem Prozess des Beispiels #3.

Wenn der Client einen Datenstromsenken löscht, verarbeitet die Stream-Spülung sofort alle Markierungen, die sich in der Warteschlange befinden. Er legt den Statuscode auf E_ABORT für diese Ereignisse fest.

Einige Markierungen enthalten Informationen, die für die Mediensenke relevant sind:

  • MFSTREAMSINK_MARKER_TICK: Gibt an, dass im Datenstrom eine Lücke vorhanden ist. Das nächste Beispiel ist eine Unterbrechung.
  • MFSTREAMSINK_MARKER_ENDOFSEGMENT: Gibt das Ende eines Abschnitts oder des Endes eines Datenstroms an. Das nächste Beispiel (sofern vorhanden) ist möglicherweise eine Unterbrechung.
  • MFSTREAMSINK_MARKER_EVENT: Enthält ein Ereignis. Abhängig vom Ereignistyp und der Implementierung des Mediensenkens werden die Mediensenken möglicherweise das Ereignis behandeln oder ignorieren.

Zustandsänderungen

Ein Mediensenken wird über die IMFClockStateSink-Schnittstelle des Mediensenken über Zustandsänderungen in der Präsentationsuhr benachrichtigt. Wenn der Client die Präsentationsuhr festlegt, ruft die Mediensenke IMFPresentationClock::AddClockStateSink auf, um sich selbst für Benachrichtigungen von der Uhr zu registrieren. In der folgenden Tabelle wird zusammengefasst, wie sich ein Mediensenken als Reaktion auf Änderungen des Uhrzustands verhält.

Änderung des Uhrzustands Beispielverarbeitung Markierungsverarbeitung
OnClockStart Prozessbeispiele, deren Zeitstempel gleich oder höher als die Startzeit der Uhr ist. Senden Sie das MEStreamSinkMarker-Ereignis , wenn alle beispiele empfangen wurden, bevor die Markierung verarbeitet wurde.
OnClockPause Die Mediensenke kann ProcessSample während der Pause fehlschlagen.
Wenn die Mediensenke Beispiele akzeptiert, während sie angehalten werden, muss sie in die Warteschlange gestellt werden, bis die Uhr neu gestartet wird. Verarbeiten Sie keine in die Warteschlange gestellten Beispiele, während sie angehalten wurden.
Wenn in die Warteschlange warteschlangen Beispiele vorhanden sind, platzieren Sie Markierungen in derselben Warteschlange. Senden Sie das Markerereignis, wenn die Uhr neu gestartet wird.
Senden Sie andernfalls das Markierungsereignis sofort.
OnClockRestart Verarbeiten Sie alle Beispiele, die während der Pause in die Warteschlange gestellt wurden, und behandeln Sie dann dasselbe wie OnClockStart. Senden Sie MEStreamSinkMarker-Ereignisse für Warteschlangenmarker (serialisiert mit Beispielverarbeitung), und behandeln Sie dann dasselbe wie OnClockStart.
OnClockStop Alle in die Warteschlange gestellten Beispiele ablegen. Weitere Aufrufe von ProcessSample können fehlschlagen. Senden von Warteschlangenmarkierungsereignissen. Senden Sie bei nachfolgenden Aufrufen von PlaceMarker das Markierungsereignis sofort.

 

Darüber hinaus müssen Stream-Sinken die folgenden Ereignisse senden, wenn sie die Statusübergänge abgeschlossen haben:

Ausführung wird abgeschlossen

Einige Mediensenken erfordern einen zusätzlichen Verarbeitungsschritt, nachdem das letzte Beispiel übermittelt wurde. In der Regel gilt diese Anforderung für Archivsenken, die Kopfzeilen oder Indizes in die Datei schreiben müssen. Wenn eine Mediensenke eine endgültige Verarbeitung erfordert, macht sie die IMFFinalizableMediaSink-Schnittstelle verfügbar.

Nachdem der Client das letzte Beispiel bereitgestellt hat, fragt der Client diese Schnittstelle ab. Wenn die Mediensenke die Schnittstelle unterstützt, ruft der Client IMFFinalizableMediaSink::BeginFinalize auf, um die endgültige Verarbeitung asynchron auszuführen. Diese Methode folgt dem asynchronen Standardmodell von Media Foundation, das in asynchronen Rückrufmethoden beschrieben wird. Die Mediensenke kann davon ausgehen, dass der Client BeginFinalize aufruft. Fehler beim Aufrufen von BeginFinalize kann zu einer falsch erstellten Datei führen.

Herunterfahren

Wenn der Client die Mediensenke verwendet, ruft der Client IMFMediaSink::Shutdown auf. Innerhalb dieser Methode sollte die Mediensenke alle Zirkelbezugsanzahlen unterbrechen. In der Regel gibt es zirkuläre Verweise zwischen dem Mediensenken und den Stream-Spülen.

Wenn Sie das Hilfsobjekt der Ereigniswarteschlange verwenden, um IMFMediaEventGenerator zu implementieren, rufen Sie IMFMediaEventQueue::Shutdown in der Ereigniswarteschlange auf. Diese Methode beendet die Ereigniswarteschlange und signalisiert alle Aufrufer, die derzeit auf ein Ereignis warten.

Nach dem Herunterfahren geben alle Methoden im Mediensenken MF_E_SHUTDOWN zurück, mit Ausnahme von IUnknown-Methoden .

Mediensenkenschnittstellen

In der folgenden Tabelle sind die Standardschnittstellen aufgeführt, die Mediensenken über QueryInterface verfügbar machen können. Mediensenken können auch benutzerdefinierte Schnittstellen verfügbar machen.

Schnittstelle BESCHREIBUNG
IMFMediaSink Die primäre Schnittstelle für Mediensenken. (Erforderlich.)
IMFClockStateSink Wird verwendet, um die Mediensenke zu benachrichtigen, wenn sich der Zustand der Präsentationsuhr ändert. (Erforderlich.)
IMFFinalizableMediaSink Implementieren Sie, ob die Mediensenke einen endgültigen Verarbeitungsschritt ausführen muss. (Optional.)
IMFGetService Implementieren Sie, wenn die Medien sinken alle Dienstschnittstellen verfügbar macht. (Optional.)
IMFMediaEventGenerator Implementieren Sie, ob die Medien sinken Ereignisse sendet. (Optional.)
IMFMediaSinkPreroll Implementieren Sie, wenn die Medien sinken die Preroll-Unterstützung unterstützt. (Optional.)
IMFPresentationTimeSource Implementieren Sie, ob die Medien sinken kann eine Zeitquelle für die Präsentationsuhr bereitstellen können. (Optional.)
IMFQualityAdvise Implementieren Sie, ob die Medien sinken kann die Wiedergabequalität anpassen. (Optional.)

 

Optional kann ein Medien sinken die folgende Schnittstelle als Dienst implementieren.

Dienstschnittstelle BESCHREIBUNG
IMFRateSupport Meldet den Bereich der unterstützten Wiedergaberaten.

 

Weitere Informationen zu Dienstschnittstellen und IMFGetService finden Sie unter Dienstschnittstellen.

Stream-Sinkschnittstellen

Stream-Sinken müssen die folgenden Schnittstellen über QueryInterface verfügbar machen.

Schnittstelle BESCHREIBUNG
IMFStreamSink Die primäre Schnittstelle für Stream-Sinken. (Erforderlich.)
IMFMediaEventGenerator Warteschlangenereignisse. Die IMFStreamSink-Schnittstelle erbt diese Schnittstelle. (Erforderlich.)

 

Derzeit werden keine Dienstschnittstellen für Stream-Sinken definiert.

Stream-Sinkereignisse

In der folgenden Tabelle sind die Ereignisse aufgeführt, die für generische Stream-Sinken definiert sind. Stream-Sinken können auch benutzerdefinierte Ereignisse senden, die hier nicht aufgeführt sind.

Ereignis BESCHREIBUNG
MEStreamSinkFormatChanged Der Medientyp des Stream-Sinks ist nicht mehr gültig. (Optional.)
MEStreamSinkMarker Eine Markierung wurde verarbeitet. (Erforderlich.)
MEStreamSinkPaused Das Stream-Sink hat angehalten. (Erforderlich.)
MEStreamSinkPrerolled Die Vorabrollung ist abgeschlossen. (Optional.)
MEStreamSinkRateChanged Das Stream-Sink hat die Wiedergaberate geändert. (Optional.)
MEStreamSinkRequestSample Ein neues Beispiel wird angefordert. (Erforderlich.)
MEStreamSinkScrubSampleComplete Eine Scrub-Anforderung wurde abgeschlossen. (Optional.)
MEStreamSinkStarted Die Stream-Sink wurde gestartet. (Erforderlich.)
MEStreamSinkStopped Das Stream-Sink wurde beendet. (Erforderlich.)

 

Derzeit werden keine allgemeinen Ereignisse für Medien sinken definiert. Einige Medien sinken möglicherweise benutzerdefinierte Ereignisse.

Media Foundation-Pipeline

Media Foundation-Architektur