Pregunta

He estado investigando todo el día y no he llegado muy lejos. Estoy en Windows 7, usando DirectX 11. (Mi salida final es ser una trama de video en una textura DX11) Quiero decodificar algunos archivos de video H.264 muy grandes, y la CPU (usando Libav) no lo hace. cortarlo.

He visto las capacidades HWACCEL de Libav usando DXVA2, pero he llegado a un bloqueo de carretera cuando necesito crear un IdirectXVideOdEcoder, que solo se puede crear con una interfaz D3D9. (que no tengo usando dx11)

Cada vez que busqué la documentación de DXVA, no hace referencia a DX11, ¿se eliminó esto en DX10 o 11? (No puedo encontrar ninguna confirmación de esto, ni en ningún lugar que diga que DXVA2 es redundante, posiblemente que DXVA-HD lo haya superado?)

Luego he examinado el SDK de la Fundación Media, ya que parece que se supone que debo usar para DX11 ... pero ninguno de los tipos existe en mis encabezados (los documentos dicen que solo incluyeu003Cd3d11.h> , pero esto no produce nada). También especifican un mínimo de Windows 8 para usarlo.

Creo que para usar MF, necesito el SDK de Windows 8, que ahora incluye todos los libbs/encabezados DirectX.

Entonces, esto deja un espacio con Windows 7 ... ¿es posible obtener una decodificación de video acelerado de hardware? Y si es así, ¿qué API se supone que debo estar usando?

EDITAR: Como otro seguimiento, mi implementación MediaFoundation (y AVF, Android, Magic Leap, etc.) está en mi proyecto de código abiertohttps://github.com/newchromantics/poph264Edit2: pero no sé si es compatible con Win7 :)

¿Fue útil?

Solución

D3D11 presenta una API de video que es básicamente DXVA2 con una interfaz ligeramente alterada arriba. Necesita una buena comprensión de H.264 BitStreams para proceder (¡realmente!). es decir, asegúrese de tener un analizador H.264 a mano para extraer campos de las estructuras SPS y PPS y todas las rebanadas de un marco codificado.

1) Obtenga la instancia ID3D11VIDEDEVICE de su ID3D11Device e ID3D11VideOcontext de su contexto de dispositivo D3D11 inmediato Nota: ¡En Win7, debe crear su dispositivo con el nivel de funciones 9_3 para obtener soporte de video! (En Win8 simplemente funciona)

2) Cree una instancia de ID3D11VideOdEcoder para H.264 Use ID3D11VIDEDEDVICE :: GetVideodeCoderProfileCount, getVideodeCoderProfile, checkVideOdEcoderFormat ... para iterar a través de todos los perfiles compatibles y encontrar uno con GUID D3D11_Decoder_Profile_H264_Vld_NOfgT For H264 sin Guid. Como salida, su mejor apuesta es DXGI_FORMAT_NV12.

3) Decodificación de los marcos individuales ver Soporte de decodificación de video Direct3D 11 en Media Foundation:

  • ID3D11VideOcontext :: decoderBeginFrame (decoder, outputView -> textura de cuadro decodificado)
  • Llenar buffers:
    • D3d11_video_decoder_buffer_picture_parameters
    • D3d11_video_decoder_buffer_inverse_quantization_matrix
    • D3d11_video_decoder_buffer_bitstream
    • D3d11_video_decoder_buffer_slice_control

Los buffers se llenan con las estructuras DXVA2 correspondientes (ver DXVA2.H) La especificación completa de DXVA2 está aquí, lo necesitará para asignar los campos H.264 SPS/PPS en consecuencia.

Ver:

Después:

  • ID3D11VideOcontext :: SubmitBuffers para confirmar todos los buffers llenos
  • ID3D11VideOcontext :: DecoderEndframe para finalizar el marco actual

3) D3D11_Video_Decoder_Buffer_Picture_Parameters Buffer también contiene información sobre todas las referencias de marcos/superficie: ¡debe administrarlos usted mismo, es decir, asegúrese de que las superficies/texturas estén disponibles para la GPU!

Es bastante complicado, verifique FFMPEG y Media Player Classic, ambos tienen soporte DXVA2 (aunque no a través de DX11).

4) Convierte de NV12 a RGB (a), algunas GPU (niveles de características D3D11) permiten usar NV12 como entrada de sombreador, otras no. En caso de que no sea posible usar NV12 directamente, eche un vistazo a las interfaces D3D11VideOprocessor que cuentan con la conversión NV12/YUV420-> RGB para todas las GPU con soporte D3D11.

La conversión podría realizarse en un 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);

Otros consejos

Como seguimiento, actualmente estoy usando MediaFoundation con Windows 7,8 y 10, con DirectX (o solo Windows SDK en el caso de 8+)

Admite muchos menos formatos (o más bien, resoluciones/niveles de perfil), y actualmente no estoy exactamente seguro de si está usando aceleración de hardware o no ...

Pero esta API es compatible, que era la consulta original

¿Cómo utilizo la decodificación de video acelerado de hardware/H.264 con DirectX 11 y Windows 7?

No puedes.

ID3D11VIDEDEVICE es solo avalaible para Windows 8 ID3D11VIDEDEVICE.

ID3D11VideOdecoder es solo avalaible para Windows 8 ID3D11VIDEODECODER.

En Windows 7, solo puede usar DirectX 9 para video acelerado de hardware/H.264. Gracias Microsoft. El buen nuevo, Idirect3D9Ex funciona ... sí ... las otras buenas noticias, el rendimiento de decodificación de GPU es muy bueno usando DirectX9 en Windows 7.

Aquí hay un código fuente para Windows 7 y DirectX 9: MOFO7777, bajo el proyecto H264DXVA2DECODER.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top