Hardware MFTs

Observação

Este tópico se aplica ao Windows 7 ou posterior.

 

Este tópico descreve como escrever uma MFT (transformação do Media Foundation) que atua como um proxy para um codificador de hardware, decodificador ou DSP (processador de sinal digital).

Importante

Se um codec de hardware usar o driver de classe multimídia AVStream, ele não exigirá um MFT personalizado. O Media Foundation fornece um proxy AVStream para essa finalidade. As informações neste tópico se aplicam somente no caso especial em que o codec de hardware não usa a AVStream. Para obter mais informações, consulte Suporte a codec de hardware no AVStream.

 

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

Introdução

Qualquer codec de hardware que não seja baseado no AVStream deve fornecer seu próprio MFT para atuar como um proxy para o driver. Um codec de hardware pode incorporar vários blocos funcionais distintos:

  • Codificador
  • Decodificador
  • Conversão de escala/formato de quadro

Cada uma dessas funções deve ser gerenciada por um MFT separado. Um MFT de hardware nunca deve atuar como um "transcodificador" de várias finalidades. Em vez disso, coloque as funções de codificação em um codificador MFT e decodificando funções em um MFT decodificador. Se o hardware oferecer conversões de escala e formato de quadro, coloque essas funções em um processador de vídeo separado, registrado na categoria MFT_CATEGORY_VIDEO_PROCESSOR . Se o hardware não oferecer suporte ao dimensionamento de quadros ou à conversão de formato, o Media Foundation fornecerá um processador de vídeo de software.

Os MFTs de hardware têm os seguintes requisitos gerais:

Atributos MFT de hardware

Um MFT de hardware deve implementar os seguintes métodos relacionados aos atributos:

Quando o MFT é criado pela primeira vez, ele deve definir os seguintes atributos em seu próprio repositório de atributos global (ou seja, o repositório de atributos retornado por GetAttributes):

Atributo Descrição
MF_TRANSFORM_ASYNC Deve ser definido como TRUE. Indica que o MFT executa o processamento assíncrono.
MFT_ENUM_HARDWARE_URL_Attribute Contém o link simbólico para o dispositivo de hardware.
O carregador de topologia usa a presença desse atributo para testar se um MFT representa um dispositivo de hardware.
MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE Deve ser definido como TRUE. Indica que o MFT dá suporte a alterações de formato dinâmico.

 

Sequência de handshake de hardware

Se dois MFTs representarem o mesmo dispositivo físico, eles poderão trocar dados dentro do hardware, por exemplo, em um barramento de hardware. Não é necessário copiar os dados para a memória do sistema e, em seguida, voltar para o dispositivo.

No diagrama a seguir, os MFTs rotulados como "A" e "B" representam blocos funcionais dentro do mesmo hardware. Por exemplo, em um cenário de transcodificação, "A" pode representar um decodificador de hardware e "B" pode representar um codificador de hardware. O fluxo de dados entre "A" e "B" ocorre dentro do hardware. O MFT rotulado como "C" é um MFT de software. O fluxo de dados de "B" para "C" usa memória do sistema.

diagrama mostrando caixas rotuladas como a a c e um codec de hardware: um aponta para b e o codec, o codec aponta para b e b aponta para c

Para estabelecer uma conexão de hardware, os dois MFTs de hardware devem usar um canal de comunicação privado. Essa conexão é estabelecida durante a negociação de formato, antes que os tipos de mídia sejam definidos e antes da primeira chamada para ProcessInput. O processo de conexão funciona da seguinte maneira:

  1. O carregador de topologia verifica os dois MFTs quanto à presença do atributo MFT_ENUM_HARDWARE_URL_Attribute . Observe que ele não examina o valor desse atributo.

  2. Se MFT_ENUM_HARDWARE_URL_Attribute estiver presente em ambos os MFTs, o carregador de topologia fará o seguinte:

    1. O carregador de topologia chama IMFTransform::GetOutputStreamAttributes no upstream MFT (A). Esse método retorna um ponteiro IMFAttributes . Deixe esse ponteiro ser indicado como pUpstream.
    2. O carregador de topologia chama IMFTransform::GetInputStreamAttributes no MFT downstream (B). Essa chamada também retorna um ponteiro IMFAttributes . Deixe esse ponteiro ser indicado como pDownstream.
    3. O carregador de topologia define o atributo MFT_CONNECTED_STREAM_ATTRIBUTE em pDownstream chamando IMFAttributes::SetUnknown. O valor do atributo é o ponteiro pUpstream .
    4. O carregador de topologia define o atributo MFT_CONNECTED_TO_HW_STREAM como TRUE em pDownstream e pUpstream.
  3. Neste ponto, o MFT downstream tem um ponteiro para o repositório de atributos do upstream MFT, conforme mostrado no diagrama a seguir.

    diagrama com cada mfts apontando para seu fluxo, cada fluxo apontando para seu repositório e o repositório de entrada com uma linha tracejada para o repositório de saída

    Observação

    Para maior clareza, esse diagrama mostra os fluxos e os armazenamentos de atributos como objetos distintos, mas isso não é necessário para a implementação.

     

  4. O MFT downstream usa o ponteiro IMFAttributes para estabelecer um canal de comunicação privado com o upstream MFT. Como o canal é privado, o mecanismo exato é definido pela implementação. Por exemplo, o MFT pode consultar uma interface COM privada.

Durante a etapa 4, o MFT downstream deve verificar se os dois MFTs compartilham o mesmo dispositivo físico. Caso contrário, eles devem voltar a usar a memória do sistema para transporte de dados. Isso permite que o MFT opere corretamente com MFTs de software e outros dispositivos de hardware.

Se o handshake for bem-sucedido e os dois MFTs compartilharem um canal de dados privado, eles não usarão o modelo de processamento de dados padrão (descrito na próxima seção) no ponto de conexão. Especificamente, o MFT downstream não envia eventos METransformNeedInput ; para obter mais detalhes, consulte a próxima seção neste tópico.

Processamento de dados

Quando um MFT de hardware usa memória do sistema para transporte de dados, o processo funciona da seguinte maneira:

  1. Para solicitar mais entrada, o MFT envia um evento METransformNeedInput .
  2. O evento METransformNeedInput faz com que o pipeline chame IMFTransform::P rocessInput.
  3. Quando o MFT tem dados de saída, o MFT envia um evento METransformHaveOutput .
  4. O evento METransformHaveOutput faz com que o pipeline chame IMFTransform::P rocessOutput.

Para obter detalhes, consulte MFTs assíncronos.

No entanto, se o MFT usa um canal de hardware, ele não envia esses eventos no ponto de conexão de hardware, pois toda a transferência de dados ocorre internamente dentro do hardware. Portanto, o pipeline não chama ProcessInput ou ProcessOutput no ponto de conexão.

Por exemplo, considere o primeiro diagrama neste tópico. Dada essa configuração, o processamento de dados ocorreria da seguinte maneira:

  1. "A" envia METransformNeedInput para solicitar dados.
  2. O pipeline chama ProcessInput em "A".
  3. "A" e "B" processam os dados no hardware.
  4. Quando o processamento for concluído, "B" enviará um evento METransformHaveOutput .
  5. O pipeline chama ProcessOutput em "B".

Decodificador/Codificador Emparelhado

Se um decodificador e um codificador estiverem localizados no mesmo chip de hardware, talvez seja preferível usá-los juntos durante a transcodificação. Ou seja, selecionar um deve fazer com que o outro seja selecionado no pipeline de transcodificação. Para garantir que os codecs de hardware correspondentes sejam escolhidos, ambos os MFTs codec devem oferecer um tipo de mídia personalizado. Para criar um tipo de mídia personalizado:

  • Defina o atributo MF_MT_MAJOR_TYPE como MFMediaType_Audio ou MFMediaType_Video, conforme apropriado.
  • Defina o atributo MF_MT_SUBTYPE como um valor guid personalizado.

Outros atributos de tipo são opcionais. O decodificador retorna o tipo personalizado de seu IMFTransform::GetOutputAvailableType e o codificador retorna o tipo personalizado de seu método IMFTransform::GetInputAvailableType . Em ambos os casos, o tipo personalizado deve ser a primeira entrada na lista (dwTypeIndex = 0).

Para trabalhar com codecs de software, o codec também deve retornar pelo menos um formato padrão, como NV12 para vídeo. Os formatos padrão devem aparecer após o tipo personalizado (dwTypeIndex> 0). Se os dois codecs sempre precisarem ser emparelhados e não puderem interoperar com codecs de software, os MFTs deverão retornar apenas o formato personalizado e não retornar nenhum formato padrão.

Observação

Se um decodificador não retornar nenhum formato padrão, ele não poderá ser usado para reprodução com o Renderizador de Vídeo Avançado. Nesse caso, ele deve ser registrado como um decodificador somente de código transcódigo. Confira Decodificadores somente transcodificadores.

 

Escrevendo um MFT personalizado

Implementando um Codec MFT

Transformações do Media Foundation