Compartir a través de


Comparación de MFT y DMO

Las transformaciones de Media Foundation (MFT) son una evolución del modelo de transformación introducido por primera vez con objetos multimedia (DPO) de DirectX. En este tema se resumen las principales formas en que las MMV difieren de las DMV. Lea este tema si ya está familiarizado con las interfaces DMO o si desea convertir un DMO existente en un MFT.

Este tema contiene las siguientes secciones:

Número de secuencias

Un DMO tiene un número fijo de secuencias, mientras que un MFT puede admitir un número dinámico de secuencias. El cliente puede agregar flujos de entrada y MFT puede agregar nuevos flujos de salida durante el procesamiento. Sin embargo, no es necesario que las MFP admitan secuencias dinámicas. Un MFT puede tener un número fijo de secuencias, al igual que un DMO.

Los métodos siguientes se usan para admitir flujos dinámicos en un MFT:

Además, el método IMFTransform::P rocessOutput define el comportamiento para agregar o quitar flujos de salida.

Dado que las DPO tienen secuencias fijas, las secuencias de un DMO se identifican mediante valores de índice de base cero. Por otro lado, las MFP usan identificadores de flujo que no se corresponden necesariamente con los valores de índice. Esto se debe a que el número de secuencias de un MFT podría cambiar. Por ejemplo, la secuencia 0 podría quitarse, dejando la secuencia 1 como la primera secuencia. Sin embargo, un MFT con un número fijo de secuencias debe observar la misma convención que las DPO y usar valores de índice para identificadores de flujo.

Negociación de formato

Las MFT usan la interfaz IMFMediaType para describir los tipos de medios. De lo contrario, la negociación de formato con TMV funciona con los mismos principios básicos que con las DPO. En la tabla siguiente se enumeran los métodos de negociación de formato para las DMV y los métodos correspondientes para las MMV.

Método DMO Método MFT
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

Al igual que las DMV, las TMV procesan los datos a través de llamadas a los métodos ProcessInput y ProcessOutput . Estas son las principales diferencias entre los procesos DMO y MFT al transmitir datos.

Asignación de recursos

Las MMV no tienen los métodos IMediaObject::AllocateStreamingResources e IMediaObject::FreeStreamingResources usados con DMO. Para controlar la asignación y desasignación de recursos de forma eficaz, un MFT puede responder a los siguientes mensajes en el método IMFTransform::P rocessMessage :

Además, el cliente puede indicar el inicio y el final de una secuencia llamando a ProcessMessage con los siguientes mensajes:

Estos dos mensajes no tienen un equivalente exacto de DMO.

Procesamiento de datos

Las MFP usan ejemplos multimedia para contener datos de entrada y salida. Los ejemplos multimedia exponen la interfaz IMFSample y contienen los datos siguientes:

  • Marca de tiempo y duración.
  • Atributos que contienen información por ejemplo. Para obtener una lista de atributos, vea Atributos de ejemplo.
  • Cero o más búferes multimedia. Cada búfer multimedia expone la interfaz IMFMediaBuffer .

La interfaz IMFMediaBuffer es similar a la interfaz IMediaBuffer de DMO. Para acceder al búfer de memoria subyacente, llame a IMFMediaBuffer::Lock. Este método es aproximadamente equivalente a IMediaBuffer::GetBufferAndLength para DMO.

En el caso de los datos de vídeo sin comprimir, un búfer multimedia también podría admitir la interfaz IMF2DBuffer . Un MFT que procese vídeo sin comprimir (ya sea como entrada o salida) debe estar preparado para usar la interfaz IMF2DBuffer si el búfer lo expone. Para obtener más información, vea Búferes de vídeo sin comprimir.

Media Foundation proporciona algunas implementaciones estándar de IMFMediaBuffer, por lo que generalmente no es necesario escribir su propia implementación. Para crear un búfer DMO desde un búfer de Media Foundation, llame a MFCreateLegacyMediaBufferOnMFMediaBuffer.

Lavado

Las MFT no tienen un método Flush . Para vaciar un MFT, llame a IMFTransform::P rocessMessage con el mensaje MFT_MESSAGE_COMMAND_FLUSH .

Discontinuidades de flujo

Las TMF no tienen un método discontinuidad . Para indicar una discontinuidad en una secuencia, establezca el atributo MFSampleExtension_Discontinuity en el ejemplo de entrada.

Diferencias diversas

Estas son algunas diferencias menores adicionales entre las MMV y las DMV.

Marcas

En las tablas siguientes se enumeran las distintas marcas DMO y sus equivalentes de MFT. Cada vez que una marca DMO se asigna directamente a una marca MFT, ambas marcas tienen el mismo valor numérico. Sin embargo, algunas marcas DMO no tienen equivalentes de MFT exactos y viceversa.

Marcas ProcessInput

DPO: enumeración _DMO_INPUT_DATA_BUFFER_FLAGS .

MFT: no hay ninguna enumeración equivalente.

Marca DMO Marca MFT
DMO_INPUT_DATA_BUFFERF_SYNCPOINT No hay ninguna marca equivalente. En su lugar, establezca el atributo MFSampleExtension_CleanPoint en el ejemplo.
DMO_INPUT_DATA_BUFFERF_TIME No hay ninguna marca equivalente. En su lugar, llame a IMFSample::SetSampleTime en el ejemplo.
DMO_INPUT_DATA_BUFFERF_TIMELENGTH No hay ninguna marca equivalente. En su lugar, llame a IMFSample::SetSampleDuration en el ejemplo.

 

Marcas ProcessOutput

DPO: enumeración _DMO_PROCESS_OUTPUT_FLAGS .

MFT: enumeración _MFT_PROCESS_OUTPUT_FLAGS .

Marca DMO Marca MFT
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER

 

DPO: enumeración _DMO_OUTPUT_DATA_BUFFER_FLAGS .

MFT: enumeración _MFT_OUTPUT_DATA_BUFFER_FLAGS .

Marca DMO Marca MFT
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT No hay ninguna marca equivalente. En su lugar, busque el atributo MFSampleExtension_CleanPoint en el ejemplo.
DMO_OUTPUT_DATA_BUFFERF_TIME No hay ninguna marca equivalente. En su lugar, llame a IMFSample::GetSampleTime en el ejemplo.
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH No hay ninguna marca equivalente. En su lugar, llame a IMFSample::GetSampleDuration en el ejemplo.
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
No hay ninguna marca equivalente. MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
No hay ninguna marca equivalente. MFT_OUTPUT_DATA_BUFFER_STREAM_END
No hay ninguna marca equivalente. MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE

 

GetInputStatus Flags

DPO: enumeración _DMO_INPUT_STATUS_FLAGS .

MFT: enumeración _MFT_INPUT_STATUS_FLAGS .

Marca DMO Marca MFT
DMO_INPUT_STATUSF_ACCEPT_DATA MFT_INPUT_STATUS_ACCEPT_DATA

 

Marcas getOutputStatus

DPO: no hay ninguna enumeración equivalente.

MFT: enumeración _MFT_OUTPUT_STATUS_FLAGS .

Marca DMO Marca MFT
No hay ninguna marca equivalente. MFT_OUTPUT_STATUS_SAMPLE_READY

 

Marcas GetInputStreamInfo

DPO: enumeración _DMO_INPUT_STREAM_INFO_FLAGS .

MFT: enumeración _MFT_INPUT_STREAM_INFO_FLAGS .

Marca DMO Marca 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
No hay ninguna marca equivalente. MFT_INPUT_STREAM_DOES_NOT_ADDREF
No hay ninguna marca equivalente. MFT_INPUT_STREAM_REMOVABLE
No hay ninguna marca equivalente. MFT_INPUT_STREAM_OPTIONAL

 

Marcas GetOutputStreamInfo

DPO: enumeración _DMO_OUTPUT_STREAM_INFO_FLAGS .

MFT: enumeración _MFT_OUTPUT_STREAM_INFO_FLAGS .

Marca DMO Marca 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
No hay ninguna marca equivalente. MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
No hay ninguna marca equivalente. MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
No hay ninguna marca equivalente. MFT_OUTPUT_STREAM_LAZY_READ
No hay ninguna marca equivalente. MFT_OUTPUT_STREAM_REMOVABLE

 

Marcas SetInputType/SetOutputType

DPO: enumeración _DMO_SET_TYPE_FLAGS .

MFT: enumeración _MFT_SET_TYPE_FLAGS .

Marca DMO Marca MFT
DMO_SET_TYPEF_TEST_ONLY MFT_SET_TYPE_TEST_ONLY
DMO_SET_TYPEF_CLEAR No hay ninguna marca equivalente. En su lugar, establezca el tipo de medio en NULL para borrar el tipo de medio.

 

Códigos de error

En la tabla siguiente se muestra cómo asignar códigos de error de DMO a códigos de error de MFT. Un objeto MFT/DMO híbrido debe devolver los códigos de error DMO de los métodos IMediaObject y los códigos de error MFT de los métodos IMFTransform . Los códigos de error de DMO se definen en el archivo de encabezado MediaErr.h. Los códigos de error de MFT se definen en el archivo de encabezado mferror.h.

Código de error de DMO Código de error de 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

 

Creación de objetos DMO/MFT híbridos

La interfaz IMFTransform se basa de forma flexible en IMediaObject, que es la interfaz principal para objetos multimedia (DPO) de DirectX. Es posible crear objetos que expongan ambas interfaces. Sin embargo, esto puede provocar colisiones de nombres, ya que las interfaces tienen algunos métodos que comparten el mismo nombre. Puede resolver este problema de una de estas dos maneras:

Solución 1: incluya la siguiente línea en la parte superior de cualquier archivo .cpp que contenga funciones MFT:

#define MFT_UNIQUE_METHOD_NAMES

Esto cambia la declaración de la interfaz IMFTransform para que la mayoría de los nombres de método estén prefijos con "MFT". Por lo tanto, IMFTransform::P rocessInput se convierte en IMFTransform::MFTProcessInput, mientras que IMediaObject::P rocessInput mantiene su nombre original. Esta técnica es más útil si va a convertir un DMO existente en un DMO/MFT híbrido. Puede agregar los nuevos métodos MFT sin cambiar los métodos DMO.

Solución 2: use la sintaxis de C++ para desambiguar nombres heredados de más de una interfaz. Por ejemplo, declare la versión MFT de ProcessInput de la siguiente manera:

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

Declare la versión DMO de ProcessInput de la siguiente manera:

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

Si realiza una llamada interna a un método dentro del objeto , puede usar esta sintaxis, pero si lo hace, invalidará el estado virtual del método. Una mejor manera de realizar llamadas desde dentro del objeto es la siguiente:

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

De este modo, si deriva otra clase de CMyHybridObject e invalida el método CMyHybridObject::IMediaObject::P rocessInput, se llama al método virtual correcto. Las interfaces DMO se documentan en la documentación del SDK de DirectShow.

Transformaciones de Media Foundation