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
- Formatverhandlung
- Streaming
- Verschiedene Unterschiede
- Flags
- Fehlercodes
- Erstellen von DMO/MFT-Hybridobjekten
- Zugehörige Themen
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:
- IMFTransform::AddInputStreams
- IMFTransform::D eleteInputStream
- IMFTransform::GetStreamIDs
- IMFTransform::GetStreamLimits
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.
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.
Es gibt keine MFT-Entsprechungen für die folgenden DMO-Methoden:
MFTs sind nicht erforderlich, um die Aggregation zu unterstützen.
MFTs unterstützen einen Vorgang, der als Draining bezeichnet wird. Der Zweck der Entleerung besteht darin, alle Daten zu verarbeiten, die im MF verbleiben, ohne dem MFT weitere Eingabedaten bereitzustellen (z. B. am Ende des Datenstroms). Um eine MFT zu leeren, rufen Sie IMFTransform::P rocessMessage mit der MFT_MESSAGE_COMMAND_DRAIN-Nachricht auf. Weitere Informationen finden Sie unter Grundlegendes MFT-Verarbeitungsmodell.
MFTs können Attribute aufweisen, einschließlich Streamattributen. Verwenden Sie die folgenden Methoden, um die Attribute aus einem MFT abzurufen:
MFTs können Ereignisse verarbeiten. Um ein Ereignis an ein MFT zu senden, rufen Sie IMFTransform::P rocessEvent auf. Ein MFT kann ein Ereignis über die ProcessOutput-Methode an den Client senden. Weitere Informationen finden Sie unter Grundlegendes MFT-Verarbeitungsmodell.
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.
Zugehörige Themen