Mediensenken

Mediensenken sind die Pipelineobjekte, die Mediendaten empfangen. Eine Mediensenke ist das Ziel für einen oder mehrere Medienstreams. Mediensenken fallen in zwei allgemeine Kategorien:

  • Ein Renderer ist eine Mediensenke, die Daten für die Wiedergabe darstellt. Der erweiterte Videorenderer (EVR) zeigt Videoframes an, und der Audiorenderer gibt Audiostreams über den Sound Karte oder ein anderes Audiogerät wieder.

  • Eine Archivsenke ist eine Mediensenke, die Daten in eine Datei oder einen anderen Speicher schreibt.

Der Standard Unterschied zwischen ihnen besteht darin, dass eine Archivsenke die Daten nicht mit einer festen Wiedergaberate nutzt. Stattdessen werden die empfangenen Daten so schnell wie möglich geschrieben.

Mediensenken machen die IMFMediaSink-Schnittstelle verfügbar. Jede Mediensenke enthält eine oder mehrere Streamsenken. Jede Streamsenke empfängt die Daten von einem Stream. Streamsenken machen die IMFStreamSink-Schnittstelle verfügbar. In der Regel erstellt eine Anwendung Mediensenken nicht direkt. Stattdessen erstellt die Anwendung mindestens ein Aktivierungsobjekt, das die Mediensitzung zum Erstellen der Senke verwendet. Alle anderen Vorgänge in der Senke werden von der Mediensitzung verarbeitet, und die Anwendung ruft keine Methoden für die Mediensenke oder eine der Streamsenken 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.

Streamsenken

Eine Mediensenke kann über eine feste Anzahl von Streamsenken verfügen oder das Hinzufügen und Entfernen von Streamsenken unterstützen. Wenn eine feste Anzahl von Streamsenken vorhanden ist, gibt die IMFMediaSink::GetCharacteristics-Methode das flag MEDIASINK_FIXED_STREAMS zurück. Andernfalls können Sie Streamsenken hinzufügen und entfernen. Um eine neue Streamsenke hinzuzufügen, rufen Sie IMFMediaSink::AddStreamSink auf. Um eine Streamsenke zu entfernen, rufen Sie IMFMediaSink::RemoveStreamSink auf. Das flag MEDIASINK_FIXED_STREAMS gibt an, dass die Mediensenke diese beiden Methoden nicht unterstützt. (Es kann eine andere Möglichkeit unterstützen, die Anzahl der Streams zu konfigurieren, z. B. durch Festlegen von Initialisierungsparametern beim Erstellen der Senke.) Die Liste der Streamsenken ist sortiert. Um sie nach Indexwert aufzulisten, rufen Sie die IMFMediaSink::GetStreamSinkByIndex-Methode auf.

Streamsenken verfügen auch über Bezeichner. Streambezeichner sind innerhalb der Mediensenke eindeutig, müssen aber nicht aufeinander folgen. Abhängig von der Mediensenke können die Streambezeichner eine Bedeutung haben, die sich auf den Inhalt bezieht. Beispielsweise könnte eine Archivsenke die Streambezeichner in den Dateiheader schreiben. Andernfalls sind sie beliebig. Um eine Streamsenke anhand ihres Bezeichners abzurufen, rufen Sie IMFMediaSink::GetStreamSinkById auf.

Präsentationsuhr

Die Rate, mit der eine Mediensenke Stichproben verbraucht, wird durch die Präsentationsuhr gesteuert. Die Mediensitzung wählt die Präsentationsuhr aus und legt sie auf der Mediensenke fest, indem die IMFMediaSink::SetPresentationClock-Methode der Mediensenke aufgerufen wird. Die Präsentationsuhr muss auf der Mediensenke festgelegt werden, bevor das Streaming beginnen kann. Für jede Mediensenke ist eine Präsentationsuhr erforderlich. Die Mediensenke verwendet die Präsentationsuhr für zwei Zwecke:

  • Zum Empfangen von Benachrichtigungen, wenn das Streaming gestartet oder beendet wird. 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, ruft sie den Zeitstempel aus dem Beispiel ab und versucht, das Beispiel zu dieser Präsentationszeit zu rendern.

Die Präsentationsuhr leitet ihre 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 eine Mediensenke Stichproben für eine Zeit planen kann, die von ihrer eigenen Uhr bereitgestellt wird. Die Mediensenke kann jedoch nicht davon ausgehen, dass dies der Fall ist. Es muss immer die Zeit der Präsentationsuhr verwenden, unabhängig davon, ob die Präsentationsuhr von der Mediensenke selbst oder von einer anderen Uhr gesteuert wird.

Wenn eine Mediensenke die Raten einer anderen Uhr als der eigenen nicht abgleichen kann, gibt die GetCharacteristics-Methode das flag MEDIASINK_CANNOT_MATCH_CLOCK zurück. Wenn dieses Flag vorhanden ist und die Präsentationsuhr eine andere Quelle für die Präsentationszeit verwendet, ist die Mediensenke wahrscheinlich schlecht. Beispielsweise kann es während der Wiedergabe zu einer Störung kommen.

Eine ratenlose Senke ist eine Mediensenke, die die Zeitstempel für Stichproben ignoriert und Daten verbraucht, sobald jede Stichprobe eintrifft. Eine ratelose Mediensenke gibt das MEDIASINK_RATELESS-Flag der GetCharacteristics-Methode zurück. In der Regel gilt dieses Flag für Archivsenken. Wenn jede Mediensenke in der Pipeline ratenlos ist, verwendet die Mediensitzung eine spezielle taktlose Präsentation. Diese Uhr wird so schnell ausgeführt, wie die Senken Beispiele verbrauchen.

Streamformate

Bevor die Mediensenke Beispiele empfangen kann, muss der Client den Medientyp für die Streamsenken festlegen. Um den Medientyp festzulegen, rufen Sie die IMFStreamSink::GetMediaTypeHandler-Methode der Streamsenke auf. 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.

Um die Liste der bevorzugten Medientypen abzurufen, rufen Sie IMFMediaTypeHandler::GetMediaTypeByIndex auf. Die bevorzugten Typen sollten als Hinweis für den Client verwendet werden. Die Liste ist möglicherweise unvollständig oder enthält teilweise Medientypen. Ein partieller Medientyp ist ein Medientyp, der nicht alle Attribute aufweist, die zum Beschreiben eines gültigen Formats erforderlich sind. Beispielsweise kann ein partieller Videotyp den Farbraum und die Bittiefe angeben, aber nicht die Bildbreite oder -höhe. Ein partieller Audiotyp kann das Komprimierungsformat und die Abtastrate angeben, aber nicht die Anzahl der Audiokanäle.

Um den aktuellen Medientyp der Streamsenke abzurufen, rufen Sie IMFMediaTypeHandler::GetCurrentMediaType auf. Wenn eine Streamsenke zum ersten Mal erstellt wird, ist möglicherweise bereits ein Standardmedientyp festgelegt, oder es gibt keinen Medientyp, bis der Client einen festlegt.

Um den Medientyp festzulegen, rufen Sie IMFMediaTypeHandler::SetCurrentMediaType auf. Einige Streamsenken unterstützen möglicherweise keine Änderung des Typs, nachdem festgelegt wurde. Daher ist es hilfreich, Medientypen zu testen, bevor Sie sie festlegen. Um zu testen, ob die Mediensenke einen Medientyp akzeptiert (ohne den Typ festzulegen), rufen Sie IMFMediaTypeHandler::IsMediaTypeSupported auf.

Datenfluss

Mediensenken verwenden ein Pullmodell. Dies bedeutet, dass der Stream Die Anforderungsdaten nach Bedarf absenkt. Der Client sollte rechtzeitig reagieren, um Störungen zu vermeiden.

Einige Mediensenken unterstützen die Vorabregistrierung. Die Vorregistrierung ist der Prozess der Bereitstellung von Daten an die Mediensenke, bevor die Präsentationsuhr beginnt. Wenn eine Mediensenke prerolling unterstützt, macht die Mediensenke die IMFMediaSinkPreroll-Schnittstelle verfügbar, und die GetCharacteristics-Methode gibt das flag MEDIASINK_CAN_PREROLL zurück. Durch die Vorabrollung wird sichergestellt, dass die Mediensenke bereit ist, das erste Beispiel zu präsentieren, wenn die Präsentationsuhr beginnt. Es wird empfohlen, dass der Client immer vorab rollt, wenn die Mediensenke dies unterstützt, da es Störungen oder Lücken während der Wiedergabe verhindern kann.

Der Datenfluss zu einer Mediensenke funktioniert wie folgt:

  1. Der Client legt die Medientypen und die Präsentationsuhr fest. Die Mediensenke registriert sich bei der Präsentationsuhr, um Benachrichtigungen über Änderungen des Uhrzustands zu erhalten.
  2. Optional fragt der Client nach IMFMediaSinkPreroll ab. Wenn die Mediensenke diese Schnittstelle verfügbar macht, ruft der Client IMFMediaSinkPreroll::NotifyPreroll auf. Andernfalls überspringt der Client Schritt 5.
  3. Jede Streamsenke sendet mindestens ein MEStreamSinkRequestSample-Ereignis . Als Reaktion auf jedes dieser Ereignisse ruft der Client das nächste Beispiel von Daten für diesen Stream ab und ruft IMFStreamSink::P rocessSample auf.
  4. Wenn jede Streamsenke genügend Prerolldaten empfängt, sendet sie ein MEStreamSinkPrerolled-Ereignis .
  5. Der Client ruft IMFPresentationClock::Start auf, um die Präsentationsuhr zu starten.
  6. Die Präsentationsuhr benachrichtigt die Mediensenke über den Start der Uhr, indem sie IMFClockStateSink::OnClockStart aufruft.
  7. Um weitere Daten abzurufen, sendet jede Streamsenke MEStreamSinkRequestSample-Ereignisse . Als Reaktion auf jedes 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 Proben asynchron, sodass die Streamsenken mehrere Beispielanforderungen gleichzeitig senden können.

Während des Streamings kann der Client jederzeit IMFStreamSink::P laceMarker und IMFStreamSink::Flush aufrufen. Marker werden im nächsten Abschnitt beschrieben. Durch die Leerung wird die Streamsenke alle Beispiele löschen, die in die Warteschlange gestellt, aber noch nicht gerendert wurden.

Marker

Marker bieten dem Client die Möglichkeit, bestimmte Punkte im Stream anzugeben. Ein Marker besteht aus den folgenden Informationen:

  • Der Markertyp, der als Member der MFSTREAMSINK_MARKER_TYPE-Enumeration definiert ist.
  • Dem Marker zugeordnete Daten. Die Bedeutung der Daten hängt vom Markertyp ab. Einige Markertypen verfügen über keine Daten.
  • Optionale Daten für die eigene Verwendung des Clients.

Um einen Marker zu platzieren, ruft der Client IMFStreamSink::P laceMarker auf. Die Streamsenke 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 mit ausstehenden Beispielen, die sie asynchron verarbeiten. Markerereignisse müssen mit der Beispielverarbeitung serialisiert werden, sodass die Mediensenke die Marker in derselben Warteschlange platzieren sollte. 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 die Streamsenke das MEStreamSinkMarker-Ereignis für marker #1 senden, nachdem sie Beispiel #2 verarbeitet hat, und das Ereignis für marker #2, nachdem sie Beispiel #3 verarbeitet hat.

Wenn der Client eine Streamsenke leert, verarbeitet die Streamsenke sofort alle Marker, die sich in der Warteschlange befanden. Es legt den status Code auf E_ABORT für diese Ereignisse fest.

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

  • MFSTREAMSINK_MARKER_TICK: Gibt an, dass im Stream eine Lücke vorhanden ist. Das nächste Beispiel ist eine Diskontinuität.
  • MFSTREAMSINK_MARKER_ENDOFSEGMENT: Gibt das Ende eines Segments oder das Ende eines Datenstroms an. Das nächste Beispiel (falls vorhanden) kann eine Diskontinuität sein.
  • MFSTREAMSINK_MARKER_EVENT: Enthält ein Ereignis. Abhängig vom Ereignistyp und der Implementierung der Mediensenke kann die Mediensenke das Ereignis behandeln oder ignorieren.

Zustandsänderungen

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

Änderung des Uhrzustands Beispielverarbeitung Markerverarbeitung
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 der Marker verarbeitet wurde.
OnClockPause Die Mediensenke kann ProcessSample fehlschlagen, während sie angehalten wird.
Wenn die Mediensenke Beispiele akzeptiert, während sie angehalten werden, muss sie sie in die Warteschlange stellen, bis die Uhr neu gestartet wird. Verarbeiten Sie keine Beispiele in der Warteschlange, während sie angehalten werden.
Wenn Beispiele in einer Warteschlange vorhanden sind, platzieren Sie Marker in derselben Warteschlange. Senden Sie das Markerereignis, wenn die Uhr neu gestartet wird.
Andernfalls senden Sie das Markerereignis sofort.
OnClockRestart Verarbeiten Sie alle Beispiele, die während der Pause in die Warteschlange eingereiht wurden, und behandeln Sie dann dasselbe wie OnClockStart. Senden Sie MEStreamSinkMarker-Ereignisse für Marker mit Warteschlange (serialisiert mit der Beispielverarbeitung), und behandeln Sie dann dasselbe wie OnClockStart.
OnClockStop Löschen Sie alle in der Warteschlange befindlichen Beispiele. Weitere Aufrufe von ProcessSample können fehlschlagen. Senden von Markerereignissen in Warteschlange Senden Sie bei nachfolgenden Aufrufen von PlaceMarker das Markerereignis sofort.

 

Darüber hinaus müssen Streamsenken die folgenden Ereignisse senden, wenn sie die Zustandsü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 Header oder Indizes in die Datei schreiben müssen. Wenn eine Mediensenke eine abschließende Verarbeitung erfordert, macht sie die IMFFinalizableMediaSink-Schnittstelle verfügbar.

Nachdem der Client das letzte Beispiel übermittelt 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 unter Asynchrone Rückrufmethoden beschrieben wird. Die Mediensenke kann davon ausgehen, dass der Client BeginFinalize aufruft. Fehler beim Aufrufen von BeginFinalize können zu einer falsch erstellten Datei führen.

Wird heruntergefahren...

Wenn der Client die Mediensenke verwendet, ruft der Client IMFMediaSink::Shutdown auf. Innerhalb dieser Methode sollte die Mediensenke alle Kreisverweisanzahlen unterbrechen. In der Regel gibt es zirkuläre Verweise zwischen der Mediensenke und den Streamsenken.

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

Nach dem Herunterfahren geben alle Methoden auf der Mediensenke MF_E_SHUTDOWN zurück, mit Ausnahme von IUnknown-Methoden .

Schnittstellen für Mediensenken

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, wenn die Mediensenke einen letzten Verarbeitungsschritt ausführen muss. (Optional.)
IMFGetService Implementieren, wenn die Mediensenke Dienstschnittstellen verfügbar macht. (Optional.)
IMFMediaEventGenerator Implementieren, wenn die Mediensenke Ereignisse sendet. (Optional.)
IMFMediaSinkPreroll Implementieren, wenn die Mediensenke preroll unterstützt. (Optional.)
IMFPresentationTimeSource Implementieren, wenn die Mediensenke eine Zeitquelle für die Präsentationsuhr bereitstellen kann. (Optional.)
IMFQualityAdvise Implementieren, ob die Mediensenke die Wiedergabequalität anpassen kann. (Optional.)

 

Optional kann eine Mediensenke 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.

Streamsenkenschnittstellen

Streamsenken müssen die folgenden Schnittstellen über QueryInterface verfügbar machen.

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

 

Derzeit sind keine Dienstschnittstellen für Streamsenken definiert.

Streamsenkeereignisse

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

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

 

Derzeit sind keine allgemeinen Ereignisse für Mediensenken definiert. Einige Mediensenken können benutzerdefinierte Ereignisse senden.

Media Foundation-Pipeline

Media Foundation-Architektur