Confronto tra MFT e DMO

Le trasformazioni di Media Foundation (MFT) sono un'evoluzione del modello di trasformazione introdotta prima con Oggetti multimediali DirectX (DMO). In questo argomento vengono riepilogati i modi principali in cui le reti MULTIFUNZIONe differiscono da DMO. Leggere questo argomento se si ha già familiarità con le interfacce DMO o se si vuole convertire un DMO esistente in un MFT.

In questo argomento sono incluse le sezioni seguenti:

Numero di flussi

Un DMO ha un numero fisso di flussi, mentre un MFT può supportare un numero di flussi dinamico. Il client può aggiungere flussi di input e MFT può aggiungere nuovi flussi di output durante l'elaborazione. Le MFP non sono tuttavia necessarie per supportare flussi dinamici. Un MFT può avere un numero fisso di flussi, proprio come un DMO.

I metodi seguenti vengono usati per supportare flussi dinamici in un MFT:

Inoltre, il metodo FMTransform::P rocessOutput definisce il comportamento per l'aggiunta o la rimozione di flussi di output.

Poiché i flussi DMO hanno flussi fissi, i flussi in un DMO vengono identificati usando valori di indice in base zero. Le MFT, d'altra parte, usano identificatori di flusso che non corrispondono necessariamente ai valori di indice. Questo è dovuto al fatto che il numero di flussi in un MFT potrebbe cambiare. Ad esempio, il flusso 0 potrebbe essere rimosso, lasciando il flusso 1 come primo flusso. Tuttavia, un MFT con un numero fisso di flussi deve osservare la stessa convenzione degli oggetti DMO e usare i valori di indice per gli identificatori di flusso.

Formattazione negoziazione

Le mft usano l'interfaccia FMMediaType per descrivere i tipi di supporti. In caso contrario, la negoziazione di formato con le reti MULTIFUNZIONe funziona sugli stessi principi di base dei DMO. Nella tabella seguente sono elencati i metodi di negoziazione del formato per i DMO e i metodi corrispondenti per le unità multifunzione.

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

 

Streaming

Come i DMO, le reti MULTIFUNZIONe elaborano i dati tramite chiamate ai metodi ProcessInput e ProcessOutput . Ecco le principali differenze tra i processi DMO e MFT durante lo streaming dei dati.

Allocazione delle risorse

Le reti MULTIFUNZIONe non dispongono dei metodi IMediaObject::AllocateStreamingResources e IMediaObject::FreeStreamingResources usati con dmo. Per gestire l'allocazione e la deallocazione delle risorse in modo efficiente, un MFT può rispondere ai messaggi seguenti nel metodo IMFTransform::P rocessMessage :

Inoltre, il client può segnalare l'inizio e la fine di un flusso chiamando ProcessMessage con i messaggi seguenti:

Questi due messaggi non hanno un equivalente DMO esatto.

Elaborazione dei dati

Le mft usano esempi multimediali per contenere i dati di input e di output. Gli esempi multimediali espongono l'interfaccia IMFSample e contengono i dati seguenti:

  • Timestamp e durata.
  • Attributi che contengono informazioni per esempio. Per un elenco di attributi, vedere Attributi di esempio.
  • Zero o più buffer multimediali. Ogni buffer multimediale espone l'interfaccia FMMediaBuffer .

L'interfaccia IMFMediaBuffer è simile all'interfaccia DMO IMediaBuffer . Per accedere al buffer di memoria sottostante, chiamare FMIMediaBuffer::Lock. Questo metodo è approssimativamente equivalente a IMediaBuffer::GetBufferAndLength per i DMO.

Per i dati video non compressi, un buffer multimediale può supportare anche l'interfaccia FMI2DBuffer . Un MFT che elabora video non compresso (come input o output) deve essere preparato per usare l'interfaccia IMF2DBuffer se il buffer lo espone. Per altre informazioni, vedere Buffer video non compressi.

Media Foundation fornisce alcune implementazioni standard di IMFMediaBuffer, quindi non è in genere necessario scrivere la propria implementazione. Per creare un buffer DMO da un buffer di Media Foundation, chiamare MFCreateLegacyMediaBufferOnMFMediaBuffer.

Flushing

LE MFT non dispongono di un metodo Flush . Per scaricare un MFT, chiamare FMTransform::P rocessMessage con il messaggio di MFT_MESSAGE_COMMAND_FLUSH .

Interruzioni di flusso

LE RETI MULTIFUNZIONE non dispongono di un metodo di discontinuità . Per segnalare una discontinuità in un flusso, impostare l'attributo MFSampleExtension_Discontinuity nell'esempio di input.

Differenze varie

Di seguito sono riportate alcune differenze secondarie aggiuntive tra le unità multifunzione e le unità DMO.

Flags

Le tabelle seguenti elencano i vari flag DMO e i relativi equivalenti MFT. Ogni volta che un flag DMO esegue il mapping direttamente a un flag MFT, entrambi i flag hanno lo stesso valore numerico. Tuttavia, alcuni flag DMO non hanno equivalenti MFT e viceversa.

Flag ProcessInput

DMOs: enumerazione _DMO_INPUT_DATA_BUFFER_FLAGS .

MFT: nessuna enumerazione equivalente.

Flag DMO Flag MFT
DMO_INPUT_DATA_BUFFERF_SYNCPOINT Nessun flag equivalente. Impostare invece l'attributo MFSampleExtension_CleanPoint nell'esempio.
DMO_INPUT_DATA_BUFFERF_TIME Nessun flag equivalente. Chiamare invece IMFSample::SetSampleTime nell'esempio.
DMO_INPUT_DATA_BUFFERF_TIMELENGTH Nessun flag equivalente. Chiamare invece IMFSample::SetSampleDuration nell'esempio.

 

Flag ProcessOutput

DMOs: enumerazione _DMO_PROCESS_OUTPUT_FLAGS .

MFT: enumerazione _MFT_PROCESS_OUTPUT_FLAGS .

Flag DMO Flag MFT
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER

 

DMOs: _DMO_OUTPUT_DATA_BUFFER_FLAGS'enumerazione.

MFT: enumerazione _MFT_OUTPUT_DATA_BUFFER_FLAGS .

Flag DMO Flag MFT
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT Nessun flag equivalente. Controllare invece l'attributo MFSampleExtension_CleanPoint nell'esempio.
DMO_OUTPUT_DATA_BUFFERF_TIME Nessun flag equivalente. Chiamare invece IMFSample::GetSampleTime nell'esempio.
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH Nessun flag equivalente. Chiamare invece IMFSample::GetSampleDuration nell'esempio.
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
Nessun flag equivalente. MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
Nessun flag equivalente. MFT_OUTPUT_DATA_BUFFER_STREAM_END
Nessun flag equivalente. MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE

 

Flag GetInputStatus

DMOs: _DMO_INPUT_STATUS_FLAGS'enumerazione.

MFT: enumerazione _MFT_INPUT_STATUS_FLAGS .

Flag DMO Flag MFT
DMO_INPUT_STATUSF_ACCEPT_DATA MFT_INPUT_STATUS_ACCEPT_DATA

 

Flag GetOutputStatus

DMOs: nessuna enumerazione equivalente.

MFT: _MFT_OUTPUT_STATUS_FLAGS enumerazione.

Flag DMO Flag MFT
Nessun flag equivalente. MFT_OUTPUT_STATUS_SAMPLE_READY

 

Flag GetInputStreamInfo

DMOs: enumerazione _DMO_INPUT_STREAM_INFO_FLAGS .

MFT: _MFT_INPUT_STREAM_INFO_FLAGS'enumerazione.

Flag DMO Flag MFT
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
Nessun flag equivalente. MFT_INPUT_STREAM_DOES_NOT_ADDREF
Nessun flag equivalente. MFT_INPUT_STREAM_REMOVABLE
Nessun flag equivalente. MFT_INPUT_STREAM_OPTIONAL

 

Flag GetOutputStreamInfo

DMOs: _DMO_OUTPUT_STREAM_INFO_FLAGS'enumerazione.

MFT: enumerazione _MFT_OUTPUT_STREAM_INFO_FLAGS .

Flag DMO Flag MFT
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
Nessun flag equivalente. MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
Nessun flag equivalente. MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
Nessun flag equivalente. MFT_OUTPUT_STREAM_LAZY_READ
Nessun flag equivalente. MFT_OUTPUT_STREAM_REMOVABLE

 

Flag SetInputType/SetOutputType

DMOs: _DMO_SET_TYPE_FLAGS'enumerazione.

MFT: enumerazione _MFT_SET_TYPE_FLAGS .

Flag DMO Flag MFT
DMO_SET_TYPEF_TEST_ONLY MFT_SET_TYPE_TEST_ONLY
DMO_SET_TYPEF_CLEAR Nessun flag equivalente. Impostare invece il tipo di supporto su NULL per cancellare il tipo di supporto.

 

Codici errore

Nella tabella seguente viene illustrato come eseguire il mapping dei codici di errore DMO ai codici di errore MFT. Un oggetto MFT/DMO ibrido deve restituire i codici di errore DMO dai metodi IMediaObject e i codici di errore MFT dai metodi IMFTransform . I codici di errore DMO sono definiti nel file di intestazione MediaErr.h. I codici di errore MFT sono definiti nel file di intestazione mferror.h.

Codice di errore DMO Codice di errore MFT
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

 

Creazione di oggetti DMO/MFT ibridi

L'interfaccia IMFTransform è basata liberamente su IMediaObject, ovvero l'interfaccia principale per gli oggetti multimediali DirectX( DMO). È possibile creare oggetti che espongono entrambe le interfacce. Tuttavia, ciò può causare conflitti di denominazione, perché le interfacce hanno alcuni metodi che condividono lo stesso nome. È possibile risolvere questo problema in uno dei due modi seguenti:

Soluzione 1: includere la riga seguente all'inizio di qualsiasi file con estensione cpp che contiene funzioni MFT:

#define MFT_UNIQUE_METHOD_NAMES

Questa modifica la dichiarazione dell'interfaccia IMFTransform in modo che la maggior parte dei nomi dei metodi sia preceduta da "MFT". Di conseguenza , IMFTransform::P rocessInput diventa IMFTransform::MFTProcessInput, mentre IMediaObject::P rocessInput mantiene il nome originale. Questa tecnica è più utile se si converte un DMO esistente in un modello DMO/MFT ibrido. È possibile aggiungere i nuovi metodi MFT senza modificare i metodi DMO.

Soluzione 2: usare la sintassi C++ per disambiguare i nomi ereditati da più interfacce. Ad esempio, dichiarare la versione MFT di ProcessInput come indicato di seguito:

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

Dichiarare la versione DMO di ProcessInput come segue:

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

Se si effettua una chiamata interna a un metodo all'interno dell'oggetto, è possibile usare questa sintassi, ma in questo modo verrà eseguito l'override dello stato virtuale del metodo . Un modo migliore per effettuare chiamate dall'interno dell'oggetto è il seguente:

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

In questo modo, se si deriva un'altra classe da CMyHybridObject ed si esegue l'override del metodo CMyHybridObject::IMediaObject::P rocessInput, viene chiamato il metodo virtuale corretto. Le interfacce DMO sono documentate nella documentazione di DirectShow SDK.

Trasformazioni di Media Foundation