Hardware MFTs
Observação
Este tópico aplica-se ao Windows 7 ou posterior.
Este tópico descreve como escrever uma transformação do Media Foundation (MFT) que atua como um proxy para um codificador de hardware, decodificador ou processador de sinal digital (DSP).
Importante
Se um codec de hardware usa o driver de classe multimídia AVStream, ele não requer um MFT personalizado. Media Foundation fornece um proxy AVStream para esta finalidade. As informações neste tópico aplicam-se apenas no caso especial em que o codec de hardware não usa 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
- Atributos MFT de hardware
- Sequência de handshake de hardware
- de Processamento de Dados
- Descodificador/Codificador Emparelhado
- Tópicos relacionados
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
- Descodificador
- Dimensionamento de quadros/conversão de formato
Cada uma destas funções deve ser gerida por uma MFT separada. Um MFT de hardware nunca deve atuar como um "transcodificador" multiuso. Em vez disso, coloque funções de codificação em um codificador MFT e funções de decodificação em um decodificador MFT. Se o hardware oferecer dimensionamento de quadros e conversões de formato, coloque essas funções em um processador de vídeo separado, registrado na categoria MFT_CATEGORY_VIDEO_PROCESSOR. Se o hardware não suportar dimensionamento de quadros ou conversão de formato, o Media Foundation fornece um processador de vídeo de software.
As MFTs de hardware têm os seguintes requisitos gerais:
- As MFTs de hardware devem usar o novo modelo de processamento assíncrono, conforme descrito em MFTs assíncronas.
- As MFTs de hardware devem suportar alterações de formato dinâmico, conforme descrito em Dynamic Format Changes.
Atributos MFT de hardware
Uma MFT de hardware deve implementar os seguintes métodos relacionados a atributos:
- IMFTransform::GetAttributes: Retorna um repositório de atributos para atributos MFT globais.
- IMFTransform::GetInputStreamAttributes: Retorna um repositório de atributos para um fluxo de entrada.
- IMFTransform::GetOutputStreamAttributes: Retorna um repositório de atributos para um fluxo de saída.
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 pelo GetAttributes):
Atributo | Descrição |
---|---|
MF_TRANSFORM_ASYNC | Deve ser definido como TRUE. Indica que o MFT executa 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 suporta alterações de formato dinâmico. |
Sequência de Handshake de Hardware
Se duas MFTs representarem o mesmo dispositivo físico, elas poderão trocar dados dentro do hardware — por exemplo, através de um barramento de hardware. Não há necessidade de copiar os dados para a memória do sistema e, em seguida, de volta para o dispositivo.
No diagrama a seguir, as MFTs rotuladas 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 "C" é um software MFT. O fluxo de dados de "B" para "C" usa a memória do sistema.
Para estabelecer uma conexão de hardware, as duas 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:
O carregador de topologia verifica ambas as MFTs quanto à presença do atributo MFT_ENUM_HARDWARE_URL_Attribute. Observe que ele não examina o valor desse atributo.
Se MFT_ENUM_HARDWARE_URL_Attribute estiver presente em ambas as MFTs, o carregador de topologia fará o seguinte:
- O carregador de topologia chama IMFTransform::GetOutputStreamAttributes no MFT upstream (A). Esse método retorna um IMFAttributes ponteiro. Deixe este ponteiro ser indicado pUpstream.
- O carregador de topologia chama IMFTransform::GetInputStreamAttributes no MFT downstream (B). Essa chamada também retorna um ponteiroIMFAttributes. Deixe este ponteiro ser indicado pDownstream.
- O carregador de topologia define o atributo MFT_CONNECTED_STREAM_ATTRIBUTE em pDownstream chamando IMFAttributes::SetUnknown. O valor do atributo é o ponteiro pUpstream.
- O carregador de topologia define o atributo MFT_CONNECTED_TO_HW_STREAM como TRUE em pDownstream e pUpstream.
Neste ponto, o MFT downstream tem um ponteiro para o armazenamento de atributos do MFT upstream, conforme mostrado no diagrama a seguir.
Observação
Para maior clareza, este diagrama mostra os fluxos e os repositórios de atributos como objetos distintos, mas isso não é necessário para a implementação.
A MFT a jusante utiliza o ponteiro deIMFAttributespara estabelecer um canal de comunicação privado com a MFT a montante. 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, a MFT a jusante deve verificar se as duas MFTs compartilham o mesmo dispositivo físico. Caso contrário, eles devem voltar a usar a memória do sistema para o transporte de dados. Isso permite que o MFT funcione corretamente com MFTs de software e outros dispositivos de hardware.
Se o handshake for bem-sucedido e as duas MFTs compartilharem um canal de dados privado, elas 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 de METransformNeedInput; Para obter mais detalhes, consulte a próxima seção neste tópico.
Tratamento de Dados
Quando uma MFT de hardware usa a memória do sistema para o transporte de dados, o processo funciona da seguinte maneira:
- Para solicitar mais entradas, o MFT envia um evento METransformNeedInput.
- O evento METransformNeedInput faz com que o pipeline chame IMFTransform::P rocessInput.
- Quando o MFT tem dados de saída, o MFT envia um METransformHaveOutput evento.
- O evento METransformHaveOutput faz com que o pipeline chame IMFTransform::P rocessOutput.
Para obter detalhes, consulte MFTs assíncronas.
Se o MFT usa um canal de hardware, no entanto, ele não envia esses eventos no ponto de conexão de hardware, porque toda a transferência de dados acontece 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 esta configuração, o processamento de dados ocorreria da seguinte forma:
- "A" envia METransformNeedInput para solicitar dados.
- O pipeline chama ProcessInput em "A".
- "A" e "B" processam os dados no hardware.
- Quando o processamento estiver concluído, "B" enviará um evento METransformHaveOutput.
- O pipeline chama ProcessOutput em "B".
Descodificador/codificador emparelhado
Se um descodificador e um codificador estiverem localizados no mesmo chip de hardware, pode ser preferível utilizá-los em conjunto 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 codec MFTs 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 IMFTransform::GetInputAvailableType método. 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 devem ser sempre emparelhados e não podem interoperar com codecs de software, os MFTs devem 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 Enhanced Video Renderer. Nesse caso, deve ser registado como um descodificador apenas de transcodificação. Consulte Transcode-Only Descodificadores.
Tópicos relacionados
-
Escrevendo um MFT personalizado