![](/img/trans.png)
[英]How to render to a DirectX11 texture from H.264 NV12 IMFSample output?
[英]How do I use Hardware accelerated video/H.264 decoding with directx 11 and windows 7?
我一整天都在研究,并没有走得太远。 我在 windows 7 上,使用 directx 11。(我的最终输出是将视频帧放到 DX11 纹理上)我想解码一些非常大的 H.264 视频文件,而 CPU(使用 libav)没有剪了它。
我已经使用 DXVA2 查看了 libav 的 hwaccel 功能,但是当我需要创建一个只能使用 D3D9 接口创建的 IDirectXVideoDecoder 时遇到了障碍。 (我没有使用 DX11)
每当我查找 DXVA 文档时,它都没有引用 DX11,这是在 DX10 还是 11 中删除的? (找不到对此的任何确认,也没有任何地方说 DXVA2 是多余的,可能它已被 DXVA-HD 取代?)
然后我查看了媒体基础 SDK,因为它看起来像我应该用于 DX11 的东西......但是我的标题中不存在任何类型(文档说只包含 <d3d11.h>,但是这个什么都不产生)。 他们还指定了最少的 Windows 8 来使用它。
我相信要使用 MF,我需要 Windows 8 SDK,它现在包含所有的 Directx 库/头文件。
所以这与 Windows 7 存在差距......是否有可能获得硬件加速的视频解码? 如果是这样,我应该使用哪个 API?
编辑:作为另一个跟进,我的 MediaFoundation(和 AVF、android、magic jump 等)实现在我的开源项目https://github.com/NewChromantics/PopH264 Edit2:但我不知道它是否支持赢7 :)
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) 单个帧的解码参见在媒体基础中支持 Direct3D 11 视频解码:
缓冲区填充有相应的 DXVA2 结构(请参阅 dxva2.h) 完整的 DXVA2 规范在这里,您需要它来相应地映射 h.264 sps/pps 字段。
看:
然后:
3) D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS 缓冲区还包含有关所有参考帧/表面的信息 - 您需要自己管理它们,即确保表面/纹理可用于 GPU!
这很复杂,检查 ffmpeg 和 Media Player Classic,它们都有 DXVA2(虽然不是通过 DX11)支持。
4) 从 NV12 转换为 RGB(A),一些 GPU(D3D11 功能级别)允许使用 NV12 作为着色器输入,有些则不允许。 如果无法直接使用 NV12,请查看 D3D11VideoProcessor 接口,该接口为所有支持 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);
作为跟进,我目前正在 Windows 7,8 和 10 中使用 MediaFoundation,使用 directx(或者在 8+ 的情况下仅使用 Windows SDK)
它支持的格式少得多(或者更确切地说,分辨率/配置文件级别),目前我不确定它是否使用硬件加速...
但是这个 API 是兼容的,这是原始查询
如何在 Directx 11 和 Windows 7 中使用硬件加速视频/H.264 解码?
你不能。
ID3D11VideoDevice 仅适用于 Windows 8 ID3D11VideoDevice 。
ID3D11VideoDecoder 仅适用于 Windows 8 ID3D11VideoDecoder 。
在 Windows 7 上,您只需将 directx 9 用于硬件加速视频/H.264。 感谢微软。 好消息,IDirect3D9Ex 可以工作......是的......另一个好消息是,在 Windows 7 上使用 DirectX9 的 GPU 解码性能非常好。
这是 Windows 7 和 DirectX 9 的源代码: mofo7777 ,位于 H264Dxva2Decoder 项目下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.