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
- Formattazione negoziazione
- Streaming
- Differenze varie
- Flag
- Codici errore
- Creazione di oggetti DMO/MFT ibridi
- Argomenti correlati
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:
- FMTransform::AddInputStreams
- FMTransform::D eleteInputStream
- FMTransform::GetStreamIDs
- FMTransform::GetStreamLimits
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.
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.
Non sono disponibili equivalenti MFT per i metodi DMO seguenti:
Le MFP non sono necessarie per supportare l'aggregazione.
Le MFP supportano un'operazione denominata svuotamento. Lo scopo dello svuotamento è quello di elaborare tutti i dati che rimangono nel MF, senza fornire altri dati di input al MFT (ad esempio, alla fine del flusso). Per svuotare un MFT, chiamare IMFTransform::P rocessMessage con il messaggio di MFT_MESSAGE_COMMAND_DRAIN . Per altre informazioni, vedere Modello di elaborazione MFT di base.
Le MFP possono avere attributi, inclusi gli attributi per flusso. Usare i metodi seguenti per ottenere gli attributi da un MFT:
Le MFP possono elaborare gli eventi. Per inviare un evento a un MFT, chiamare IMFTransform::P rocessEvent. Un MFT può inviare un evento al client tramite il metodo ProcessOutput . Per altre informazioni, vedere Modello di elaborazione MFT di base.
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.
Argomenti correlati