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
- Formato de Negociação
- Streaming
- Diferenças diversas
- Bandeiras
- Códigos de erro
- Criação de objetos híbridos DMO/MFT
- Tópicos relacionados
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:
- 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. 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.
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.
Não há equivalentes MFT para os seguintes métodos DMO:
MFTs não são necessários para suportar a agregação.
MFTs suportam uma operação chamada drenagem. O objetivo da drenagem é processar quaisquer dados que permaneçam no MF, sem fornecer mais dados de entrada para o MFT (por exemplo, no final do fluxo). Para drenar uma MFT, chame IMFTransform::P rocessMessage com a mensagem MFT_MESSAGE_COMMAND_DRAIN. Para obter mais informações, consulte Basic MFT Processing Model.
MFTs podem ter atributos, incluindo atributos por fluxo. Use os seguintes métodos para obter os atributos de um MFT:
MFTs podem processar eventos. Para enviar um evento para uma MFT, ligue IMFTransform::P rocessEvent. Uma MFT pode enviar um evento para o cliente através do métodoProcessOutput. Para obter mais informações, consulte Basic MFT Processing Model.
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.
Tópicos relacionados