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
- Negociación de formato
- Streaming
- Diferencias diversas
- Marcas
- Códigos de error
- Creación de objetos DMO/MFT híbridos
- Temas relacionados
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:
- IMFTransform::AddInputStreams
- IMFTransform::D eleteInputStream
- IMFTransform::GetStreamIDs
- IMFTransform::GetStreamLimits
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.
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.
No hay equivalentes de MFT para los métodos DMO siguientes:
Las MFT no son necesarias para admitir la agregación.
Las MFT admiten una operación denominada purga. El propósito de purgar es procesar los datos que permanecen en mf, sin proporcionar más datos de entrada al MFT (por ejemplo, al final de la secuencia). Para purgar un MFT, llame a IMFTransform::P rocessMessage con el mensaje MFT_MESSAGE_COMMAND_DRAIN . Para obtener más información, vea Modelo de procesamiento de MFT básico.
Las MFT pueden tener atributos, incluidos los atributos por secuencia. Use los métodos siguientes para obtener los atributos de un MFT:
Las MFT pueden procesar eventos. Para enviar un evento a un MFT, llame a IMFTransform::P rocessEvent. Un MFT puede enviar un evento al cliente a través del método ProcessOutput . Para obtener más información, vea Modelo de procesamiento de MFT básico.
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.
Temas relacionados