Suporte ao DXVA 2.0 no Media Foundation
Este tópico descreve como dar suporte à Aceleração de Vídeo DirectX (DXVA) 2.0 em uma MFT (transformação do Media Foundation) usando o Microsoft Direct3D 9 Especificamente, ele descreve a comunicação entre o decodificador e o renderizador de vídeo, que é mediado pelo carregador de topologia. Este tópico não descreve como implementar a decodificação DXVA.
No restante deste tópico, o termo decodificador refere-se ao decodificador MFT, que recebe vídeo compactado e gera vídeo descompactado. O termo dispositivo de decodificador refere-se a um acelerador de vídeo de hardware implementado pelo driver gráfico.
Dica
Para obter informações sobre a decodificação de vídeo do Microsoft Direct3D 11, consulte Suporte à decodificação de vídeo direct3D 11 no Media Foundation.
Observação
Os aplicativos da Windows Store devem usar o Direct3D 11.
Estas são as etapas básicas que um decodificador deve executar para dar suporte ao DXVA 2.0 no Media Foundation:
- Abra um identificador para o dispositivo Direct3D 9.
- Localize uma configuração de decodificador DXVA.
- Alocar buffers descompactados.
- Decodificar quadros.
Essas etapas são descritas mais detalhadamente no restante deste tópico.
Abrindo um identificador de dispositivo Direct3D
O MFT usa o gerenciador de dispositivos Do Microsoft Direct3D para obter um identificador para o dispositivo Direct3D 9. Para abrir o identificador do dispositivo, execute as seguintes etapas:
- Exponha o atributo MF_SA_D3D_AWARE com o valor TRUE. O carregador de topologia consulta esse atributo chamando IMFTransform::GetAttributes. Definir o atributo como TRUE notifica o carregador de topologia de que o MFT dá suporte a DXVA.
- Quando a negociação de formato começa, o carregador de topologia chama IMFTransform::P rocessMessage com a mensagem MFT_MESSAGE_SET_D3D_MANAGER . O parâmetro ulParam é um ponteiro IUnknown para o gerenciador de dispositivos Direct3D do renderizador de vídeo. Consulte esse ponteiro para a interface IDirect3DDeviceManager9 .
- Chame IDirect3DDeviceManager9::OpenDeviceHandle para obter um identificador para o dispositivo Direct3D do renderizador.
- Chame IDirect3DDeviceManager9::GetVideoService e passe o identificador do dispositivo. Esse método retorna um ponteiro para a interface IDirectXVideoDecoderService .
- Armazene em cache os ponteiros e o identificador do dispositivo.
Localizando uma configuração do decodificador
O MFT deve encontrar uma configuração compatível para o dispositivo decodificador DXVA. Execute as seguintes etapas dentro do método IMFTransform::SetInputType depois de validar o tipo de entrada:
Chame IDirectXVideoDecoderService::GetDecoderDeviceGuids. Esse método retorna uma matriz de GUIDs de dispositivo de decodificador.
Execute um loop pela matriz de GUIDs do decodificador para localizar os que o decodificador dá suporte. Por exemplo, para um decodificador MPEG-2, você procuraria DXVA2_ModeMPEG2_MOCOMP, DXVA2_ModeMPEG2_IDCT ou DXVA2_ModeMPEG2_VLD.
Quando encontrar um GUID de dispositivo de decodificador candidato, passe o GUID para o método IDirectXVideoDecoderService::GetDecoderRenderTargets . Esse método retorna uma matriz de formatos de destino de renderização, especificados como valores D3DFORMAT .
Execute um loop pelos formatos de destino de renderização e procure um formato compatível com o decodificador.
Chame IDirectXVideoDecoderService::GetDecoderConfigurations. Passe o mesmo GUID do dispositivo de decodificador, juntamente com uma estrutura de DXVA2_VideoDesc que descreve o formato de saída proposto. O método retorna uma matriz de estruturas DXVA2_ConfigPictureDecode . Cada estrutura descreve uma configuração possível para o dispositivo decodificador. Procure uma configuração compatível com o decodificador.
Armazene o formato e a configuração de destino de renderização.
No método IMFTransform::GetOutputAvailableType , retorne um formato de vídeo descompactado, com base no formato de destino de renderização proposto.
No método IMFTransform::SetOutputType, marcar o tipo de mídia em relação ao formato de destino de renderização.
Fallback para Decodificação de Software
Se o MFT não conseguir encontrar uma configuração DXVA (por exemplo, se o driver gráfico não tiver os recursos corretos), ele deverá retornar o código de erro MF_E_UNSUPPORTED_D3D_TYPE dos métodos SetInputType e SetOutputType . O carregador de topologia responderá enviando a mensagem MFT_MESSAGE_SET_D3D_MANAGER com o valor NULL para o parâmetro ulParam . O MFT deve liberar seu ponteiro para a interface IDirect3DDeviceManager9 . O carregador de topologia renegociará o tipo de mídia e o MFT poderá usar a decodificação de software.
Alocando buffers descompactados
No DXVA 2.0, o decodificador é responsável por alocar superfícies Direct3D a serem usadas como buffers de vídeo descompactados. O decodificador deve alocar três superfícies para o EVR usar para desinterlacização. Esse número foi corrigido, pois o Media Foundation não fornece uma maneira de o EVR especificar quantas superfícies o driver gráfico requer para desinterlacização. Três superfícies devem ser suficientes para qualquer driver.
No método IMFTransform::GetOutputStreamInfo , defina o sinalizador MFT_OUTPUT_STREAM_PROVIDES_SAMPLES na estrutura MFT_OUTPUT_STREAM_INFO . Esse sinalizador notifica a Sessão de Mídia de que o MFT aloca seus próprios exemplos de saída.
Para criar as superfícies, chame IDirectXVideoAccelerationService::CreateSurface. (A interface IDirectXVideoDecoderService herda esse método de IDirectXVideoAccelerationService.) Você pode fazer isso em SetInputType, depois de localizar o formato de destino de renderização.
Para cada superfície, chame MFCreateVideoSampleFromSurface para criar um exemplo de mídia para manter a superfície. O método retorna um ponteiro para a interface IMFSample .
Decodificação
Para criar o dispositivo decodificador, chame IDirectXVideoDecoderService::CreateVideoDecoder. O método retorna um ponteiro para a interface IDirectXVideoDecoder do dispositivo decodificador.
A decodificação deve ocorrer dentro do método IMFTransform::P rocessOutput . Em cada quadro, chame IDirect3DDeviceManager9::TestDevice para testar o identificador do dispositivo. Se o dispositivo tiver sido alterado, o método retornará DXVA2_E_NEW_VIDEO_DEVICE. Se isso ocorrer, faça o seguinte:
- Feche o identificador do dispositivo chamando IDirect3DDeviceManager9::CloseDeviceHandle.
- Libere os ponteiros IDirectXVideoDecoderService e IDirectXVideoDecoder .
- Abra um novo identificador de dispositivo.
- Negocie uma nova configuração de decodificador, conforme descrito em "Localizando uma configuração de decodificador" anteriormente nesta página.
- Crie um novo dispositivo de decodificador.
Supondo que o identificador do dispositivo seja válido, o processo de decodificação funciona da seguinte maneira:
- Obtenha uma superfície disponível que não está em uso no momento. (Inicialmente, todas as superfícies estão disponíveis.)
- Consulte o exemplo de mídia para a interface IMFTrackedSample .
- Chame IMFTrackedSample::SetAllocator e forneça um ponteiro para a interface IMFAsyncCallback , implementada pelo decodificador. Quando o renderizador de vídeo liberar o exemplo, o retorno de chamada do decodificador será invocado.
- Chame IDirectXVideoDecoder::BeginFrame.
- Faça o seguinte uma ou mais vezes:
- Chame IDirectXVideoDecoder::GetBuffer para obter um buffer de decodificador DXVA.
- Preencha o buffer.
- Chame IDirectXVideoDecoder::ReleaseBuffer.
- Chame IDirectXVideoDecoder::Execute para executar as operações de decodificação no quadro.
A DXVA 2.0 usa as mesmas estruturas de dados que a DXVA 1.0 para operações de decodificação. Para o conjunto original de perfis DXVA (para H.261, H.263 e MPEG-2), essas estruturas de dados são descritas na especificação DXVA 1.0.
Dentro de cada par de chamadas BeginFrame/Execute , você pode chamar GetBuffer várias vezes, mas apenas uma vez para cada tipo de buffer DXVA. Se você chamá-lo duas vezes com o mesmo tipo de buffer, substituirá os dados.
Use o retorno de chamada do método SetAllocator (etapa 3) para acompanhar quais amostras estão disponíveis no momento e quais estão em uso.
Tópicos relacionados