Partilhar via


Comparação de MFTs e DMOs

As transformações Media Foundation (MFTs) são uma evolução do modelo de transformação introduzido pela primeira vez com DirectX Media Objects (DMOs). Este tópico resume as principais maneiras pelas quais as MFTs diferem das DMOs. Leia este tópico se já estiver familiarizado com as interfaces DMO ou se quiser converter um DMO existente em MFT.

Este tópico contém as seguintes seções:

Número de fluxos

Um DMO tem um número fixo de fluxos, enquanto um MFT pode suportar um número dinâmico de fluxos. O cliente pode adicionar fluxos de entrada e o MFT pode adicionar novos fluxos de saída durante o processamento. No entanto, MFTs não são necessárias para suportar fluxos dinâmicos. Um MFT pode ter um número fixo de fluxos, assim como um DMO.

Os seguintes métodos são usados para dar suporte a fluxos dinâmicos em um MFT:

Além disso, o método IMFTransform::P rocessOutput define o comportamento para adicionar ou remover fluxos de saída.

Como os DMOs têm fluxos fixos, os fluxos em um DMO são identificados usando valores de índice baseados em zero. MFTs, por outro lado, usam identificadores de fluxo que não correspondem necessariamente a valores de índice. Isso ocorre porque o número de fluxos em um MFT pode mudar. Por exemplo, o fluxo 0 pode ser removido, deixando o fluxo 1 como o primeiro fluxo. No entanto, uma MFT com um número fixo de fluxos deve observar a mesma convenção que os DMOs e usar valores de índice para identificadores de fluxo.

Negociação de Formatos

MFTs usam o IMFMediaType interface para descrever tipos de mídia. Caso contrário, a negociação de formato com MFTs funciona com os mesmos princípios básicos que com DMOs. A tabela a seguir lista os métodos de negociação de formato para DMOs e os métodos correspondentes para MFTs.

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

 

Transmissão

Como DMOs, MFTs processam dados por meio de chamadas para ProcessInput e métodos de ProcessOutput. Aqui estão as principais diferenças entre os processos DMO e MFT ao transmitir dados.

Alocação de recursos

MFTs não têm o IMediaObject::AllocateStreamingResources e IMediaObject::FreeStreamingResources métodos usados com DMOs. Para lidar com a alocação e desalocação de recursos de forma eficiente, uma MFT pode responder às seguintes mensagens no método IMFTransform::P rocessMessage:

Além disso, o cliente pode sinalizar o início e o fim de um fluxo chamando ProcessMessage com as seguintes mensagens:

Essas duas mensagens não têm equivalente DMO exato.

Processamento de dados

MFTs usam amostras de mídia para armazenar dados de entrada e saída. Exemplos de mídia expõem a interfaceIMFSample e contêm os seguintes dados:

  • Carimbo de data/hora e duração.
  • Atributos que contêm informações por exemplo. Para obter uma lista de atributos, consulte Atributos de exemplo.
  • Zero ou mais buffers de mídia. Cada buffer de mídia expõe o interface de IMFMediaBuffer.

A interface IMFMediaBuffer é semelhante à interface DMO IMediaBuffer. Para acessar o buffer de memória subjacente, chame IMFMediaBuffer::Lock. Este método é aproximadamente equivalente a IMediaBuffer::GetBufferAndLength para DMOs.

Para dados de vídeo não compactados, um buffer de mídia também pode suportar a interfaceIMF2DBuffer. Uma MFT que processa vídeo não comprimido (como entrada ou saída) deve estar preparada para usar a interface IMF2DBuffer se o buffer expô-la. Para obter mais informações, consulte Buffers de vídeo não compactados.

Media Foundation fornece algumas implementações padrão de IMFMediaBuffer, portanto, geralmente não é necessário escrever sua própria implementação. Para criar um buffer DMO a partir de um buffer do Media Foundation, chame MFCreateLegacyMediaBufferOnMFMediaBuffer.

Rubor

MFTs não têm um Flush método. Para liberar uma MFT, chame IMFTransform::P rocessMessage com a mensagem MFT_MESSAGE_COMMAND_FLUSH.

Descontinuidades de fluxo

MFTs não têm um Descontinuidade método. Para sinalizar uma descontinuidade em um fluxo, defina o atributo MFSampleExtension_Discontinuity na amostra de entrada.

Diferenças diversas

Aqui estão algumas pequenas diferenças adicionais entre MFTs e DMOs.

Bandeiras

As tabelas a seguir listam os vários sinalizadores DMO e seus equivalentes MFT. Sempre que um sinalizador DMO é mapeado diretamente para um sinalizador MFT, ambos os sinalizadores têm o mesmo valor numérico. No entanto, alguns sinalizadores DMO não têm equivalentes MFT exatos e vice-versa.

Sinalizadores ProcessInput

DMOs: _DMO_INPUT_DATA_BUFFER_FLAGS enumeração.

MFTs: Nenhuma enumeração equivalente.

Bandeira DMO Bandeira MFT
DMO_INPUT_DATA_BUFFERF_SYNCPOINT Nenhuma bandeira equivalente. Em vez disso, defina o atributo MFSampleExtension_CleanPoint no exemplo.
DMO_INPUT_DATA_BUFFERF_TIME Nenhuma bandeira equivalente. Em vez disso, chame IMFSample::SetSampleTime no exemplo.
DMO_INPUT_DATA_BUFFERF_TIMELENGTH Nenhuma bandeira equivalente. Em vez disso, chame IMFSample::SetSampleDuration no exemplo.

 

Sinalizadores ProcessOutput

DMOs: _DMO_PROCESS_OUTPUT_FLAGS enumeração.

MFTs: _MFT_PROCESS_OUTPUT_FLAGS enumeração.

Bandeira DMO Bandeira MFT
DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER MFT_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER

 

DMOs: _DMO_OUTPUT_DATA_BUFFER_FLAGS enumeração.

MFTs: _MFT_OUTPUT_DATA_BUFFER_FLAGS enumeração.

Bandeira DMO Bandeira MFT
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT Nenhuma bandeira equivalente. Em vez disso, verifique o atributo MFSampleExtension_CleanPoint no exemplo.
DMO_OUTPUT_DATA_BUFFERF_TIME Nenhuma bandeira equivalente. Em vez disso, chame IMFSample::GetSampleTime no exemplo.
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH Nenhuma bandeira equivalente. Em vez disso, chame IMFSample::GetSampleDuration no exemplo.
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
Nenhuma bandeira equivalente. MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
Nenhuma bandeira equivalente. MFT_OUTPUT_DATA_BUFFER_STREAM_END
Nenhuma bandeira equivalente. MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE

 

Sinalizadores GetInputStatus

DMOs: _DMO_INPUT_STATUS_FLAGS enumeração.

MFTs: _MFT_INPUT_STATUS_FLAGS enumeração.

Bandeira DMO Bandeira MFT
DMO_INPUT_STATUSF_ACCEPT_DATA MFT_INPUT_STATUS_ACCEPT_DATA

 

Sinalizadores GetOutputStatus

DMOs: Nenhuma enumeração equivalente.

MFTs: _MFT_OUTPUT_STATUS_FLAGS enumeração.

Bandeira DMO Bandeira MFT
Nenhuma bandeira equivalente. MFT_OUTPUT_STATUS_SAMPLE_READY

 

Sinalizadores GetInputStreamInfo

DMOs: _DMO_INPUT_STREAM_INFO_FLAGS enumeração.

MFTs: _MFT_INPUT_STREAM_INFO_FLAGS enumeração.

Bandeira DMO Bandeira 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
Nenhuma bandeira equivalente. MFT_INPUT_STREAM_DOES_NOT_ADDREF
Nenhuma bandeira equivalente. MFT_INPUT_STREAM_REMOVABLE
Nenhuma bandeira equivalente. MFT_INPUT_STREAM_OPTIONAL

 

Sinalizadores GetOutputStreamInfo

DMOs: _DMO_OUTPUT_STREAM_INFO_FLAGS enumeração.

MFTs: _MFT_OUTPUT_STREAM_INFO_FLAGS enumeração.

Bandeira DMO Bandeira 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
Nenhuma bandeira equivalente. MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
Nenhuma bandeira equivalente. MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
Nenhuma bandeira equivalente. MFT_OUTPUT_STREAM_LAZY_READ
Nenhuma bandeira equivalente. MFT_OUTPUT_STREAM_REMOVABLE

 

Sinalizadores SetInputType/SetOutputType

DMOs: _DMO_SET_TYPE_FLAGS enumeração.

MFTs: _MFT_SET_TYPE_FLAGS enumeração.

Bandeira DMO Bandeira MFT
DMO_SET_TYPEF_TEST_ONLY MFT_SET_TYPE_TEST_ONLY
DMO_SET_TYPEF_CLEAR Nenhuma bandeira equivalente. Em vez disso, defina o tipo de mídia como NULL para limpar o tipo de mídia.

 

Códigos de erro

A tabela a seguir mostra como mapear códigos de erro DMO para códigos de erro MFT. Um objeto MFT/DMO híbrido deve retornar os códigos de erro DMO de métodos IMediaObject e os códigos de erro MFT de métodos IMFTransform. Os códigos de erro DMO são definidos no arquivo de cabeçalho MediaErr.h. Os códigos de erro MFT são definidos no arquivo de cabeçalho mferror.h.

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

 

Criando objetos DMO/MFT híbridos

A interface IMFTransform é vagamente baseada em IMediaObject, que é a interface primária para DirectX Media Objects (DMOs). É possível criar objetos que expõem ambas as interfaces. No entanto, isso pode levar a colisões de nomenclatura, porque as interfaces têm alguns métodos que compartilham o mesmo nome. Pode resolver este problema de duas formas:

Solução 1: Inclua a seguinte linha na parte superior de qualquer ficheiro .cpp que contenha funções MFT:

#define MFT_UNIQUE_METHOD_NAMES

Isso altera a declaração do IMFTransform interface para que a maioria dos nomes de método são prefixados com "MFT". Assim, IMFTransform::P rocessInput torna-se IMFTransform::MFTProcessInput, enquanto IMediaObject::P rocessInput mantém seu nome original. Essa técnica é mais útil se você estiver convertendo um DMO existente em um DMO/MFT híbrido. Você pode adicionar os novos métodos MFT sem alterar os métodos DMO.

Solução 2: Use a sintaxe C++ para desambiguar nomes herdados de mais de uma interface. Por exemplo, declare a versão MFT do ProcessInput da seguinte maneira:

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

Declare a versão DMO do ProcessInput assim:

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

Se você fizer uma chamada interna para um método dentro do objeto, poderá usar essa sintaxe, mas isso substituirá o status virtual do método. Uma maneira melhor de fazer chamadas de dentro do objeto é o seguinte:

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

Dessa forma, se você derivar outra classe de CMyHybridObject e substituir o método CMyHybridObject::IMediaObject::P rocessInput, o método virtual correto será chamado. As interfaces DMO estão documentadas na documentação do SDK do DirectShow.

Media Foundation transforma