Pergunta

Eu tenho pesquisado o dia todo e não cheguei muito longe. Estou no Windows 7, usando o DirectX 11. (Minha saída final é ser um quadro de vídeo em uma textura DX11) Quero decodificar alguns arquivos de vídeo H.264 muito grandes, e a CPU (usando libav) não corte Isso.

Eu observei os recursos do Hwaccel do Libav usando o DXVA2, mas bati em um bloqueio quando preciso criar um IDirectXVideODecoder, que só pode ser criado com uma interface D3D9. (que eu não tenho usando DX11)

Sempre que procurei documentação DXVA, ele não faz referência ao DX11, foi removido no DX10 ou 11? (Não é possível encontrar nenhuma confirmação disso, nem em qualquer lugar que diga que o DXVA2 é redundante, possivelmente que foi superdominado pelo DXVA-HD?)

Então eu olhei para o SDK da Media Foundation, pois se parece com o que devo usar para o DX11 ... mas nenhum dos tipos existe nos meus cabeçalhos (os documentos dizem para incluir apenasu003Cd3d11.h> , mas isso não gera nada). Eles também especificam um mínimo de Windows 8 para usá -lo.

Acredito que use o MF, preciso do Windows 8 SDK, que agora inclui todos os Libs/cabeçalhos do DirectX.

Então, isso deixa uma lacuna com o Windows 7 ... É possível obter decodificação de vídeo acelerada de hardware? E se sim, qual API eu devo estar usando?

Editar: Como outro acompanhamento, minha implementação de mediafoundation (e AVF, Android, Magic Leap, etc. etc.) está no meu projeto de código abertohttps://github.com/newchromantics/poph264Edit2: Mas não sei se ele suporta Win7 :)

Foi útil?

Solução

O D3D11 apresenta uma API de vídeo que é basicamente DXVA2 com uma interface ligeiramente alterada acima. Você precisa de um bom entendimento dos transportes H.264 para prosseguir (realmente!). ou seja, certifique -se de ter um analisador H.264 à mão para extrair campos das estruturas SPS e PPS e todas as fatias de um quadro codificado.

1) Obtenha a instância ID3D11VideODEVICE do seu ID3D11Device e ID3D11Videocontext do seu dispositivo D3D11 imediato Nota: No Win7, você deve criar seu dispositivo com o recurso Nível 9_3 para obter suporte ao vídeo! (No Win8, ele apenas funciona)

2) Crie uma instância ID3D11VideODecoder para H.264 Use ID3D11VideODevice :: getVideOdecoderProfileCount, GetVideOdecoderProfile, checkVideodecoder_PROFIDA 4 FIMPIDANTENTENTENTENTENTENTENTENTENTENTENTENTENTENTENTEM4 DO FILDATH4 DO FILDA40 Encontre -se com Diretores D3D1D1_DED4 Como outputFormat, sua melhor aposta é dxgi_format_nv12.

3) Decodificação dos quadros individuais veja Suportando Direct3D 11 Decoding de vídeo na Media Foundation:

  • Id3d11videocontext :: decoderbeginframe (decodificador, outputView -> textura do quadro decodificado)
  • Preencha os buffers:
    • D3d11_video_decoder_buffer_picture_parameters
    • D3d11_video_decoder_buffer_inverse_quantization_matrix
    • D3d11_video_decoder_buffer_bittream
    • D3d11_video_decoder_buffer_slice_control

Os buffers são preenchidos com as estruturas DXVA2 correspondentes (consulte DXVA2.H) A especificação DXVA2 completa está aqui, você precisará para mapear os campos H.264 SPS/PPS de acordo.

Ver:

Então:

  • ID3D11VideoContext :: submmitbuffers para cometer todos os buffers preenchidos
  • ID3D11VideoContext :: decoderendframe para terminar o quadro atual

3) D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS Buffer também contém informações sobre todas as referências quadros/superfície - você precisa gerenciá -las você mesmo, ou seja, verifique se as superfícies/texturas estão disponíveis para a GPU!

É bastante complicado, verifique o FFMPEG e o Media Player Classic, ambos têm suporte ao DXVA2 (embora não via DX11).

4) Converter de NV12 para RGB (A), algumas GPUs (níveis de características D3D11) permitem usar o NV12 como entrada do shader, outros não. Caso não seja possível usar o NV12 diretamente, dê uma olhada nas interfaces D3D11VideOprocessor que apresentam conversão NV12/YUV420-> RGB para todas as GPUs com suporte D3D11.

A conversão pode ser realizada em código como este:

// Setup ID3D11Video*
ID3D11VideoProcessor * d3dVideoProc = ...;
ID3D11VideoDevice    * d3dVideoDevice = ...;
ID3D11VideoProcessorEnumerator * d3dVideoProcEnum = ...;


ID3D11Texture2D * srcTextureNV12Fmt = ...;
ID3D11Texture2D * dstTextureRGBFmt = ...;

// Use Video Processor

// Create views for VideoProc In/Output
ID3D11VideoProcessorInputView * videoProcInputView;
ID3D11VideoProcessorOutputView * videoProcOutputView;

{

    D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC inputViewDesc = { 0 };
    inputViewDesc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
    inputViewDesc.Texture2D.ArraySlice = arraySliceIdx;
    inputViewDesc.Texture2D.MipSlice = 0;
    hr = d3dVideoDevice->CreateVideoProcessorInputView(srcTextureNV12Fmt, d3dVideoProcEnum, &inputViewDesc, &videoProcInputView);
}


{
    D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputViewDesc = { D3D11_VPOV_DIMENSION_TEXTURE2D };
    outputViewDesc.Texture2D.MipSlice = 0;
    hr = d3dVideoDevice->CreateVideoProcessorOutputView(dstTextureRGBFmt, d3dVideoProcEnum, &outputViewDesc, &videoProcOutputView);
}


// Setup streams
D3D11_VIDEO_PROCESSOR_STREAM streams = { 0 };
streams.Enable = TRUE;
streams.pInputSurface = videoProcInputView.get();

RECT srcRect = { /* source rectangle in pixels*/ };
RECT dstRect = { /* destination rectangle in pixels*/ };

// Perform VideoProc Blit Operation (with color conversion)
hr = videoCtx_->VideoProcessorBlt(d3dVideoProc, videoProcOutputView.get(), 0, 1, &streams);

Outras dicas

Como acompanhamento, atualmente estou usando o MediaFoundation com o Windows 7,8 e 10, com o DirectX (ou apenas o Windows SDK no caso de 8+)

Ele suporta muito menos formatos (ou melhor, resoluções/níveis de perfil) e, atualmente, não tenho certeza se está usando aceleração de hardware ou não ...

Mas esta API é compatível, que foi a consulta original

Como uso o hardware acelerado em vídeo/h.264 Decodificação com o DirectX 11 e o Windows 7?

Você não pode.

ID3D11VideODODEVICE SOMENTE ALENTE PARA WINDONES 8 ID3D11VideODODEVICE.

ID3D11VideODecoder é ATALIALIBLE para Windows 8 ID3D11VideODecoder.

No Windows 7, você pode usar o DirectX 9 para vídeo acelerado de hardware/H.264. Obrigado Microsoft. O bom novo, o IDirect3D9Ex funciona ... sim ... as outras boas notícias, o desempenho de decodificação da GPU é muito bom usando o DirectX9 no Windows 7.

Aqui está um código -fonte para o Windows 7 e DirectX 9: MOFO7777, no projeto H264DXVA2Decoder.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top