Comparação de MFTs e DMOs
As MFTs (transformações do Media Foundation) são uma evolução do modelo de transformação introduzido pela primeira vez com DMOs (Objetos de Mídia) do DirectX. Este tópico resume as main maneiras pelas quais os MFTs diferem dos DMOs. Leia este tópico se você já estiver familiarizado com as interfaces DMO ou se quiser converter um DMO existente em um MFT.
Este tópico contém as seguintes seções:
- Número de fluxos
- Formatar Negociação
- Streaming
- Diferenças diversas
- Sinalizadores
- Códigos de Erro
- Criando objetos DMO/MFT híbridos
- Tópicos relacionados
Número de fluxos
Um DMO tem um número fixo de fluxos, enquanto um MFT pode dar suporte a 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, os MFTs não são necessários para dar suporte a fluxos dinâmicos. Um MFT pode ter um número fixo de fluxos, assim como um DMO.
Os métodos a seguir são usados para dar suporte a fluxos dinâmicos em um MFT:
- IMFTransform::AddInputStreams
- IMFTransform::D eleteInputStream
- IMFTransform::GetStreamIDs
- IMFTransform::GetStreamLimits
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. Os MFTs, por outro lado, usam identificadores de fluxo que não correspondem necessariamente aos 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, um MFT com um número fixo de fluxos deve observar a mesma convenção que DMOs e usar valores de índice para identificadores de fluxo.
Formatar Negociação
Os MFTs usam a interface IMFMediaType para descrever tipos de mídia. Caso contrário, a negociação de formato com MFTs funciona nos 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.
Streaming
Assim como os DMOs, os MFTs processam dados por meio de chamadas para os métodos ProcessInput e ProcessOutput . Aqui estão as principais diferenças entre os processos de DMO e MFT ao transmitir dados.
Alocando recursos
Os MFTs não têm os métodos IMediaObject::AllocateStreamingResources e IMediaObject::FreeStreamingResources usados com DMOs. Para lidar com alocação e desalocação de recursos com eficiência, um 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.
Processando dados
Os MFTs usam exemplos de mídia para armazenar dados de entrada e saída. Exemplos de mídia expõem a interface IMFSample 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 a interface IMFMediaBuffer .
A interface IMFMediaBuffer é semelhante à interface IMediaBuffer do DMO. Para acessar o buffer de memória subjacente, chame IMFMediaBuffer::Lock. Esse método é aproximadamente equivalente a IMediaBuffer::GetBufferAndLength para DMOs.
Para dados de vídeo descompactados, um buffer de mídia também pode dar suporte à interface IMF2DBuffer . Um MFT que processa vídeo descompactado (como entrada ou saída) deve estar preparado para usar a interface IMF2DBuffer se o buffer o expor. Para obter mais informações, consulte Buffers de vídeo descompactados.
A Media Foundation fornece algumas implementações padrão do IMFMediaBuffer, portanto, geralmente não é necessário escrever sua própria implementação. Para criar um buffer DMO de um buffer do Media Foundation, chame MFCreateLegacyMediaBufferOnMFMediaBuffer.
Liberando
Os MFTs não têm um método Flush . Para liberar um MFT, chame IMFTransform::P rocessMessage com a mensagem MFT_MESSAGE_COMMAND_FLUSH .
Descontinuidades de fluxo
Os MFTs não têm um método Descontinuidade . Para sinalizar uma descontinuidade em um fluxo, defina o atributo MFSampleExtension_Discontinuity no exemplo de entrada.
Diferenças diversas
Aqui estão algumas diferenças secundárias adicionais entre MFTs e DMOs.
Não há equivalentes de MFT para os seguintes métodos DMO:
Os MFTs não são necessários para dar suporte à agregação.
Os MFTs dão suporte a uma operação chamada esvaziamento. A finalidade da drenagem é processar todos os dados que permanecem no MF, sem fornecer mais dados de entrada para o MFT (por exemplo, no final do fluxo). Para drenar um MFT, chame IMFTransform::P rocessMessage com a mensagem MFT_MESSAGE_COMMAND_DRAIN . Para obter mais informações, consulte Modelo de processamento MFT básico.
Os MFTs podem ter atributos, incluindo atributos por fluxo. Use os seguintes métodos para obter os atributos de um MFT:
Os MFTs podem processar eventos. Para enviar um evento para um MFT, chame IMFTransform::P rocessEvent. Um MFT pode enviar um evento para o cliente por meio do método ProcessOutput . Para obter mais informações, consulte Modelo de processamento MFT básico.
Flags
As tabelas a seguir listam os vários sinalizadores DMO e seus equivalentes de 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.
Sinalizador DMO | Sinalizador MFT |
---|---|
DMO_INPUT_DATA_BUFFERF_SYNCPOINT | Nenhum sinalizador equivalente. Em vez disso, defina o atributo MFSampleExtension_CleanPoint no exemplo. |
DMO_INPUT_DATA_BUFFERF_TIME | Nenhum sinalizador equivalente. Em vez disso, chame IMFSample::SetSampleTime no exemplo. |
DMO_INPUT_DATA_BUFFERF_TIMELENGTH | Nenhum sinalizador 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.
Sinalizador DMO | Sinalizador 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.
Sinalizador DMO | Sinalizador MFT |
---|---|
DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT | Nenhum sinalizador equivalente. Em vez disso, marcar para o atributo MFSampleExtension_CleanPoint no exemplo. |
DMO_OUTPUT_DATA_BUFFERF_TIME | Nenhum sinalizador equivalente. Em vez disso, chame IMFSample::GetSampleTime no exemplo. |
DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH | Nenhum sinalizador equivalente. Em vez disso, chame IMFSample::GetSampleDuration no exemplo. |
DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE | MFT_OUTPUT_DATA_BUFFER_INCOMPLETE |
Nenhum sinalizador equivalente. | MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE |
Nenhum sinalizador equivalente. | MFT_OUTPUT_DATA_BUFFER_STREAM_END |
Nenhum sinalizador equivalente. | MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE |
Sinalizadores GetInputStatus
DMOs: _DMO_INPUT_STATUS_FLAGS enumeração.
MFTs: _MFT_INPUT_STATUS_FLAGS enumeração.
Sinalizador DMO | Sinalizador 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.
Sinalizador DMO | Sinalizador MFT |
---|---|
Nenhum sinalizador equivalente. | MFT_OUTPUT_STATUS_SAMPLE_READY |
Sinalizadores GetInputStreamInfo
DMOs: _DMO_INPUT_STREAM_INFO_FLAGS enumeração.
MFTs: _MFT_INPUT_STREAM_INFO_FLAGS enumeração.
Sinalizador DMO | Sinalizador 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 |
Nenhum sinalizador equivalente. | MFT_INPUT_STREAM_DOES_NOT_ADDREF |
Nenhum sinalizador equivalente. | MFT_INPUT_STREAM_REMOVABLE |
Nenhum sinalizador equivalente. | MFT_INPUT_STREAM_OPTIONAL |
Sinalizadores GetOutputStreamInfo
DMOs: _DMO_OUTPUT_STREAM_INFO_FLAGS enumeração.
MFTs: _MFT_OUTPUT_STREAM_INFO_FLAGS enumeração.
Sinalizador DMO | Sinalizador 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 |
Nenhum sinalizador equivalente. | MFT_OUTPUT_STREAM_PROVIDES_SAMPLES |
Nenhum sinalizador equivalente. | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES |
Nenhum sinalizador equivalente. | MFT_OUTPUT_STREAM_LAZY_READ |
Nenhum sinalizador equivalente. | MFT_OUTPUT_STREAM_REMOVABLE |
Sinalizadores SetInputType/SetOutputType
DMOs: _DMO_SET_TYPE_FLAGS enumeração.
MFTs: _MFT_SET_TYPE_FLAGS enumeração.
Sinalizador DMO | Sinalizador MFT |
---|---|
DMO_SET_TYPEF_TEST_ONLY | MFT_SET_TYPE_TEST_ONLY |
DMO_SET_TYPEF_CLEAR | Nenhum sinalizador 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 dos métodos IMediaObject e os códigos de erro MFT dos 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 principal para DMOs (Objetos de Mídia) DirectX. É possível criar objetos que expõem ambas as interfaces. No entanto, isso pode levar a colisões de nomenclatura, pois as interfaces têm alguns métodos que compartilham o mesmo nome. Você pode resolver esse problema de duas maneiras:
Solução 1: inclua a seguinte linha na parte superior de qualquer arquivo .cpp que contenha funções MFT:
#define MFT_UNIQUE_METHOD_NAMES
Isso altera a declaração da interface IMFTransform para que a maioria dos nomes de método seja prefixada com "MFT". Assim, IMFTransform::P rocessInput torna-se IMFTransform::MFTProcessInput, enquanto IMediaObject::P rocessInput mantém seu nome original. Essa técnica será 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 de ProcessInput da seguinte maneira:
CMyHybridObject::IMFTransform::ProcessInput(...)
Declare a versão DMO de ProcessInput da seguinte maneira:
CMyHybridObject::IMediaObject::ProcessInput(...)
Se você fizer uma chamada interna para um método dentro do objeto , poderá usar essa sintaxe, mas isso substituirá a status virtual do método . Uma maneira melhor de fazer chamadas de dentro do objeto é a seguinte:
hr = ((IMediaObject*)this)->ProcessInput(...)
Dessa forma, se você derivar outra classe do método 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.
Tópicos relacionados