Vergleich von MFTs und DMOs

Media Foundation-Transformationen (MFTs) sind eine Weiterentwicklung des Transformationsmodells, das erstmals mit DirectX Media Objects (DMOs) eingeführt wurde. In diesem Thema werden die Standard Möglichkeiten zusammengefasst, in denen sich MFTs von DMOs unterscheiden. Lesen Sie dieses Thema, wenn Sie bereits mit den DMO-Schnittstellen vertraut sind oder wenn Sie ein vorhandenes DMO in ein MFT konvertieren möchten.

Dieses Thema enthält folgende Abschnitte:

Anzahl von Streams

Ein DMO verfügt über eine feste Anzahl von Streams, während ein MFT eine dynamische Anzahl von Streams unterstützen kann. Der Client kann Eingabestreams hinzufügen, und MFT kann während der Verarbeitung neue Ausgabestreams hinzufügen. MFTs sind jedoch nicht erforderlich, um dynamische Datenströme zu unterstützen. Ein MFT kann genau wie ein DMO über eine feste Anzahl von Streams verfügen.

Die folgenden Methoden werden verwendet, um dynamische Datenströme in einem MFT zu unterstützen:

Darüber hinaus definiert die IMFTransform::P rocessOutput-Methode das Verhalten zum Hinzufügen oder Entfernen von Ausgabedatenströmen.

Da DMOs über feste Datenströme verfügen, werden die Streams in einem DMO mithilfe von nullbasierten Indexwerten identifiziert. MFTs hingegen verwenden Streambezeichner, die nicht unbedingt Indexwerten entsprechen. Dies liegt daran, dass sich die Anzahl der Streams in einem MFT ändern kann. Beispielsweise kann Stream 0 entfernt werden, sodass Stream 1 als erster Stream beibehalten wird. Ein MFT mit einer festen Anzahl von Streams sollte jedoch dieselbe Konvention wie DMOs einhalten und Indexwerte für Streambezeichner verwenden.

Formatverhandlung

MFTs verwenden die IMFMediaType-Schnittstelle , um Medientypen zu beschreiben. Andernfalls funktioniert die Formataushandlung mit MFTs nach den gleichen Grundprinzipien wie bei DMOs. In der folgenden Tabelle sind die Formataushandlungsmethoden für DMOs und die entsprechenden Methoden für MFTs aufgeführt.

DMO-Methode MFT-Methode
IMediaObject::GetInputCurrentType IMFTransform::GetInputCurrentType
IMediaObject::GetInputMaxLatency IMFTransform::GetInputStreamInfo
IMediaObject::GetInputSizeInfo IMFTransform::GetInputStreamInfo
IMediaObject::GetInputType IMFTransform::GetInputAvailableType
IMediaObject::GetOutputCurrentType IMFTransform::GetOutputCurrentType
IMediaObject::GetOutputSizeInfo IMFTransform::GetOutputStreamInfo
IMediaObject::GetOutputType IMFTransform::GetOutputAvailableType

 

Streaming

Wie DMOs verarbeiten MFTs Daten über Aufrufe von ProcessInput - und ProcessOutput-Methoden . Hier sind die wichtigsten Unterschiede zwischen DMO- und MFT-Prozessen beim Streamen von Daten aufgeführt.

Zuordnen von Ressourcen

MFTs verfügen nicht über die Methoden IMediaObject::AllocateStreamingResources und IMediaObject::FreeStreamingResources , die mit DMOs verwendet werden. Um die Zuordnung und Zuordnung von Ressourcen effizient zu behandeln, kann ein MFT auf die folgenden Meldungen in der IMFTransform::P rocessMessage-Methode reagieren:

Darüber hinaus kann der Client den Start und das Ende eines Datenstroms signalisieren, indem er ProcessMessage mit den folgenden Meldungen aufruft:

Diese beiden Nachrichten weisen keine genaue DMO-Entsprechung auf.

Verarbeiten von Daten

MFTs verwenden Medienbeispiele, um Eingabe- und Ausgabedaten zu enthalten. Medienbeispiele machen die IMFSample-Schnittstelle verfügbar und enthalten die folgenden Daten:

  • Zeitstempel und Dauer.
  • Attribute, die Pro-Stichproben-Informationen enthalten. Eine Liste der Attribute finden Sie unter Beispielattribute.
  • 0 oder mehr Medienpuffer. Jeder Medienpuffer macht die IMFMediaBuffer-Schnittstelle verfügbar.

Die IMFMediaBuffer-Schnittstelle ähnelt der DMO IMediaBuffer-Schnittstelle . Um auf den zugrunde liegenden Speicherpuffer zuzugreifen, rufen Sie IMFMediaBuffer::Lock auf. Diese Methode entspricht ungefähr IMediaBuffer::GetBufferAndLength für DMOs.

Für unkomprimierte Videodaten kann ein Medienpuffer auch die IMF2DBuffer-Schnittstelle unterstützen. Ein MFT, das unkomprimierte Videos (als Eingabe oder Ausgabe) verarbeitet, sollte für die Verwendung der IMF2DBuffer-Schnittstelle vorbereitet werden, wenn der Puffer sie verfügbar macht. Weitere Informationen finden Sie unter Unkomprimierte Videopuffer.

Media Foundation stellt einige Standardimplementierungen von IMFMediaBuffer bereit, sodass es in der Regel nicht notwendig ist, eine eigene Implementierung zu schreiben. Um einen DMO-Puffer aus einem Media Foundation-Puffer zu erstellen, rufen Sie MFCreateLegacyMediaBufferOnMFMediaBuffer auf.

Spülung

MFTs verfügen nicht über eine Flush-Methode . Um ein MFT zu leeren, rufen Sie IMFTransform::P rocessMessage mit der MFT_MESSAGE_COMMAND_FLUSH-Nachricht auf.

Stream-Diskontinuitäten

MFTs verfügen nicht über eine Diskontinuitätsmethode . Um eine Diskontinuität in einem Stream zu signalisieren, legen Sie das Attribut MFSampleExtension_Discontinuity für das Eingabebeispiel fest.

Verschiedene Unterschiede

Hier sind einige weitere geringfügige Unterschiede zwischen MFTs und DMOs aufgeführt.

Flags

In den folgenden Tabellen sind die verschiedenen DMO-Flags und ihre MFT-Entsprechungen aufgeführt. Wenn ein DMO-Flag einem MFT-Flag direkt zugeordnet wird, haben beide Flags den gleichen numerischen Wert. Einige DMO-Flags verfügen jedoch nicht über genaue MFT-Entsprechungen und umgekehrt.

ProcessInput-Flags

DMOs: _DMO_INPUT_DATA_BUFFER_FLAGS Enumeration.

MFTs: Keine gleichwertige Enumeration.

DMO-Flag MFT-Flag
DMO_INPUT_DATA_BUFFERF_SYNCPOINT Kein gleichwertiges Flag. Legen Sie stattdessen das MFSampleExtension_CleanPoint-Attribut für das Beispiel fest.
DMO_INPUT_DATA_BUFFERF_TIME Kein gleichwertiges Flag. Rufen Sie stattdessen IMFSample::SetSampleTime für das Beispiel auf.
DMO_INPUT_DATA_BUFFERF_TIMELENGTH Kein gleichwertiges Flag. Rufen Sie stattdessen IMFSample::SetSampleDuration für das Beispiel auf.

 

ProcessOutput-Flags

DMOs: _DMO_PROCESS_OUTPUT_FLAGS Enumeration.

MFTs: _MFT_PROCESS_OUTPUT_FLAGS-Enumeration .

DMO-Flag MFT-Flag
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER

 

DMOs: _DMO_OUTPUT_DATA_BUFFER_FLAGS Enumeration.

MFTs: _MFT_OUTPUT_DATA_BUFFER_FLAGS Enumeration.

DMO-Flag MFT-Flag
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT Kein gleichwertiges Flag. Suchen Sie stattdessen im Beispiel nach dem attribut MFSampleExtension_CleanPoint .
DMO_OUTPUT_DATA_BUFFERF_TIME Kein gleichwertiges Flag. Rufen Sie stattdessen IMFSample::GetSampleTime für das Beispiel auf.
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH Kein gleichwertiges Flag. Rufen Sie stattdessen IMFSample::GetSampleDuration für das Beispiel auf.
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
Kein gleichwertiges Flag. MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
Kein gleichwertiges Flag. MFT_OUTPUT_DATA_BUFFER_STREAM_END
Kein gleichwertiges Flag. MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE

 

GetInputStatus-Flags

DMOs: _DMO_INPUT_STATUS_FLAGS Enumeration.

MFTs: _MFT_INPUT_STATUS_FLAGS Enumeration.

DMO-Flag MFT-Flag
DMO_INPUT_STATUSF_ACCEPT_DATA MFT_INPUT_STATUS_ACCEPT_DATA

 

GetOutputStatus-Flags

DMOs: Keine gleichwertige Enumeration.

MFTs: _MFT_OUTPUT_STATUS_FLAGS Enumeration.

DMO-Flag MFT-Flag
Kein gleichwertiges Flag. MFT_OUTPUT_STATUS_SAMPLE_READY

 

GetInputStreamInfo-Flags

DMOs: _DMO_INPUT_STREAM_INFO_FLAGS Enumeration.

MFTs: _MFT_INPUT_STREAM_INFO_FLAGS-Enumeration .

DMO-Flag MFT-Flag
DMO_INPUT_STREAMF_WHOLE_SAMPLES MFT_INPUT_STREAM_WHOLE_SAMPLES
DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_INPUT_STREAMF_HOLDS_BUFFERS MFT_INPUT_STREAM_HOLDS_BUFFERS
Kein gleichwertiges Flag. MFT_INPUT_STREAM_DOES_NOT_ADDREF
Kein gleichwertiges Flag. MFT_INPUT_STREAM_REMOVABLE
Kein gleichwertiges Flag. MFT_INPUT_STREAM_OPTIONAL

 

GetOutputStreamInfo-Flags

DMOs: _DMO_OUTPUT_STREAM_INFO_FLAGS Enumeration.

MFTs: _MFT_OUTPUT_STREAM_INFO_FLAGS Enumeration.

DMO-Flag MFT-Flag
DMO_OUTPUT_STREAMF_WHOLE_SAMPLES MFT_OUTPUT_STREAM_WHOLE_SAMPLES
DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
DMO_OUTPUT_STREAMF_DISCARDABLE MFT_OUTPUT_STREAM_DISCARDABLE
DMO_OUTPUT_STREAMF_OPTIONAL MFT_OUTPUT_STREAM_OPTIONAL
Kein entsprechendes Flag. MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
Kein entsprechendes Flag. MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
Kein entsprechendes Flag. MFT_OUTPUT_STREAM_LAZY_READ
Kein entsprechendes Flag. MFT_OUTPUT_STREAM_REMOVABLE

 

SetInputType/SetOutputType-Flags

DMOs: _DMO_SET_TYPE_FLAGS Enumeration.

MFTs: _MFT_SET_TYPE_FLAGS Enumeration.

DMO-Flag MFT-Flag
DMO_SET_TYPEF_TEST_ONLY MFT_SET_TYPE_TEST_ONLY
DMO_SET_TYPEF_CLEAR Kein entsprechendes Flag. Legen Sie stattdessen den Medientyp auf NULL fest, um den Medientyp zu löschen.

 

Fehlercodes

Die folgende Tabelle zeigt, wie Sie DMO-Fehlercodes MFT-Fehlercodes zuordnen. Ein MFT/DMO-Hybridobjekt sollte die DMO-Fehlercodes von IMediaObject-Methoden und die MFT-Fehlercodes von IMFTransform-Methoden zurückgeben. Die DMO-Fehlercodes sind in der Headerdatei MediaErr.h definiert. Die MFT-Fehlercodes sind in der Headerdatei mferror.h definiert.

DMO-Fehlercode MFT-Fehlercode
DMO_E_INVALIDTYPE MF_E_INVALIDTYPE
DMO_E_INVALIDSTREAMINDEX MF_E_INVALIDSTREAMNUMBER
DMO_E_NOTACCEPTING MF_E_NOTACCEPTING
DMO_E_NO_MORE_ITEMS MF_E_NO_MORE_TYPES
DMO_E_TYPE_NOT_ACCEPTED MF_E_INVALIDMEDIATYPE
DMO_E_TYPE_NOT_SET MF_E_TRANSFORM_TYPE_NOT_SET

 

Erstellen von DMO/MFT-Hybridobjekten

Die IMFTransform-Schnittstelle basiert lose auf IMediaObject, der primären Schnittstelle für DirectX Media Objects (DMOs). Es ist möglich, Objekte zu erstellen, die beide Schnittstellen verfügbar machen. Dies kann jedoch zu Benennungskonflikten führen, da die Schnittstellen über einige Methoden verfügen, die denselben Namen verwenden. Sie können dieses Problem auf zwei Arten lösen:

Lösung 1: Fügen Sie die folgende Zeile oben in jede CPP-Datei ein, die MFT-Funktionen enthält:

#define MFT_UNIQUE_METHOD_NAMES

Dadurch wird die Deklaration der IMFTransform-Schnittstelle geändert, sodass den meisten Methodennamen "MFT" vorangestellt wird. Daher wird IMFTransform::P rocessInput zu IMFTransform::MFTProcessInput, während IMediaObject::P rocessInput seinen ursprünglichen Namen behält. Diese Technik ist am nützlichsten, wenn Sie eine vorhandene DMO in eine Hybrid-DMO/MFT konvertieren. Sie können die neuen MFT-Methoden hinzufügen, ohne die DMO-Methoden zu ändern.

Lösung 2: Verwenden Sie die C++-Syntax, um Namen zu trennen, die von mehreren Schnittstellen geerbt werden. Deklarieren Sie beispielsweise die MFT-Version von ProcessInput wie folgt:

CMyHybridObject::IMFTransform::ProcessInput(...)

Deklarieren Sie die DMO-Version von ProcessInput wie folgt:

CMyHybridObject::IMediaObject::ProcessInput(...)

Wenn Sie einen internen Aufruf einer Methode innerhalb des -Objekts vornehmen, können Sie diese Syntax verwenden, aber dadurch wird die virtuelle status der -Methode überschrieben. Eine bessere Möglichkeit, Aufrufe aus dem Objekt zu tätigen, ist folgendes:

hr = ((IMediaObject*)this)->ProcessInput(...)

Wenn Sie eine andere Klasse von CMyHybridObject ableiten und die CMyHybridObject::IMediaObject::P rocessInput-Methode überschreiben, wird die richtige virtuelle Methode aufgerufen. Die DMO-Schnittstellen sind in der DirectShow SDK-Dokumentation dokumentiert.

Media Foundation-Transformationen