微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用directx 11和Windows 7的硬件加速视频/ H.264解码?

我一直在研究,没有得到很多.我在 windows 7上,使用directx 11.(我的最终输出一个视频到DX11纹理的帧)
我想解码一些非常大的H.264视频文件,而cpu(使用libav)不会被剪切.

我使用DXVA2查看了libav的hwaccel功能,但是当我需要创建一个只能使用D3D9接口创建的IDirectXVideoDecoder时,打了一个路障. (我没有使用DX11)

每当我查看DXVA文档时,它都不参考DX11,DX10或11中是否已被删除? (找不到任何确认信息,也不知道DXVA2是多余的,可能是DXVA-HD超越了吗?)

然后我看了媒体基础SDK,看起来像我应该用于DX11 …但是没有一个类型存在于我的头文件(文档说只是包含,但这不产生任何东西).他们还指定使用最少的Windows 8.

我相信使用MF我需要Windows 8 SDK,现在包括所有的directx库/标题.

所以这与Windows 7保持一个空白…是否可以获得硬件加速视频解码?如果是,我应该使用哪个API?

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(decode,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字段.

看到:

> About DXVA 2.0
> https://software.intel.com/sites/default/files/m/b/4/7/DXVA_H264.pdf

然后:

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

3)D3D11_VIDEO_DECODER_BUFFER_PICTURE_ParaMETERS缓冲区还包含所有参考帧/表面上的信息
– 您需要自己管理,即确保GPU /表面可用.

这是相当复杂的,检查ffmpeg和媒体播放器经典,他们都有DXVA2(虽然不通过DX11)的支持.

4)从NV12转换为RGB(A),某些GPU(D3D11功能级别)允许使用NV12作为着色器输入,有些则不使用.如果无法直接使用NV12,请查看所有具有D3D11支持的GPU的D3D11VideoProcessor接口,它们具有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,&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(),1,&streams);

原文地址:https://www.jb51.cc/windows/363851.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐