gpt4 book ai didi

directx - 如何在 directx 11 和 windows 7 中使用硬件加速视频/H.264 解码?

转载 作者:行者123 更新时间:2023-12-01 18:52:16 93 4
gpt4 key购买 nike

我研究了一整天,但还没有取得多大进展。我在 Windows 7 上,使用 directx 11。(我的最终输出是 DX11 纹理上的视频帧)我想解码一些非常大的 H.264 视频文件,但 CPU(使用 libav)无法处理它。

我已经使用 DXVA2 查看了 libav 的 hwaccel 功能,但是当我需要创建只能使用 D3D9 接口(interface)创建的 IDirectXVideoDecoder 时遇到了障碍。 (我没有使用 DX11)

每当我查找 DXVA 文档时,它都没有引用 DX11,这是在 DX10 或 11 中删除的吗? (找不到任何对此的确认,也没有任何地方说 DXVA2 是多余的,可能它已被 DXVA-HD 取代?)

然后我研究了媒体基础 SDK,因为它看起来像是我应该用于 DX11 的...但是我的 header 中不存在任何类型(文档说只包含 ,但这不会产生任何结果)。他们还指定至少在 Windows 8 上使用它。

我相信要使用 MF,我需要 Windows 8 SDK,它现在包含所有 directx 库/ header 。

所以这与Windows 7留下了差距...是否有可能获得硬件加速视频解码?如果是这样,我应该使用哪个 API?

编辑:作为另一个后续行动,我的 MediaFoundation(以及 AVF、android、magic Leap 等)实现位于我的开源项目中 https://github.com/NewChromantics/PopH264Edit2:但我不知道它是否支持win7:)

最佳答案

D3D11 具有一个视频 api,它基本上是 DXVA2,上面的界面略有改变。您需要充分了解 h.264 比特流才能继续(真的!)。即确保您手头有一个 h.264 解析器来提取 SPS 和 PPS 结构的字段以及编码帧的所有切片。

1) 从您的 ID3D11Device 获取 ID3D11VideoDevice 实例,并从直接 D3D11 设备上下文获取 ID3D11VideoContext注意:在 Win7 上,您必须创建功能级别为 9_3 的设备才能获得视频支持! (在Win8下就可以了)

2) 创建h.264的ID3D11VideoDecoder实例使用 ID3D11VideoDevice::GetVideoDecoderProfileCount、GetVideoDecoderProfile、CheckVideoDecodeRFormat...迭代所有支持的配置文件,并找到一个 GUID D3D11_DECODER_PROFILE_H264_VLD_NOFGT 的配置文件适用于没有胶片颗粒的 h264。作为 OutputFormat,您最好的选择是 DXGI_FORMAT_NV12。

3) 各个帧的解码参见 Supporting Direct3D 11 Video Decoding in Media Foundation :

  • ID3D11VideoContext::DecoderBeginFrame(解码器,outputView -> 解码帧纹理)
  • 填充缓冲区:
    • D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS
    • D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX
    • D3D11_VIDEO_DECODER_BUFFER_BITSTREAM
    • D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL

缓冲区填充有相应的 DXVA2 结构(参见 dxva2.h)完整的 DXVA2 规范在这里,您需要它来相应地映射 h.264 sps/pps 字段。

参见:

然后:

  • ID3D11VideoContext::SubmitBuffers 提交所有已填充的缓冲区
  • ID3D11VideoContext::DecoderEndFrame 完成当前帧

3) D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS 缓冲区还包含所有引用帧/表面的信息- 您需要自己管理它们,即确保表面/纹理可供 GPU 使用!

这很复杂,检查一下 ffmpeg 和 Media Player Classic,它们都有 DXVA2(尽管不是通过 DX11)支持。

4) 从 NV12 转换为 RGB(A),某些 GPU(D3D11 功能级别)允许使用 NV12 作为着色器输入,有些则不允许。如果无法直接使用 NV12,请查看 D3D11VideoProcessor 接口(interface),该接口(interface)可为所有支持 D3D11 的 GPU 提供 NV12/YUV420->RGB 转换功能。

可以通过如下代码执行转换:

// 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);

关于directx - 如何在 directx 11 和 windows 7 中使用硬件加速视频/H.264 解码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19846770/

93 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com