我整天都在研究,但还没有走得太远。我在Windows 7上使用DirectX11。(我的最终输出是在DX11纹理上的视频框架)我想解码一些非常大的H.264视频文件,而CPU(使用Libav)则没有剪了它。

我使用DXVA2查看了Libav的Hwaccel功能,但是当我需要创建一个IDIRECTXVIDEODECODER时,撞到了路障,只能使用D3D9接口创建它。 (我没有使用DX11)

每当我查找DXVA文档时,它都不引用DX11,这是否在DX10或11中删除? (找不到任何确认,也找不到DXVA2是多余的任何地方,可能是DXVA-HD超级成功的?)

然后,我研究了媒体基金会SDK,看起来像我应该用于DX11 ...但是我的标题中都不存在类型(文档说的只是包括u003Cd3d11.h>,但这一无所获)。他们还指定了最少的Windows 8使用它。

我相信要使用MF,我需要Windows 8 SDK,现在包括所有DirectX LIB/标头。

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

编辑:作为另一项后续,我的开源项目中的MediaFoundation(以及AVF,Android,Magic Leap等)实现https://github.com/newchromantics/poph264edit2:但是我不知道它是否支持win7 :)

有帮助吗?

解决方案

D3D11具有视频API,基本上是DXVA2,上面的接口略有变化。您需要很好地了解H.264 bitstreams才能进行(真的!)。即,确保您手头有H.264解析器来提取SPS和PPS结构的字段以及编码框架的所有切片。

1)从您的ID3D11DEVICE获得ID3D11VIDED11D11D11D11D11D11VIDEOCONTEXT,从您的即时D3D11设备上下文上下文注意:在Win7上,您必须使用功能级别9_3创建设备才能获得视频支持! (在win8中它起作用)

2)为H.264创建一个ID3D11VIDEODECODER实例,使用ID3D11VIDEDEDEVICE :: GETVIDEDECODERPROFILECOUNT,GetVideOdeCoderProfile,CheckVideEdeCoderFormat ...以通过所有支持的配置文件迭代,并通过所有支持的配置文件进行介绍,并使用GUID D3D11_DECODER_DECODER_PROFIEL__H264。作为OutputFormat,您最好的选择是DXGI_FORMAT_NV12。

3)单个帧的解码 支持Direct3d 11在媒体基金会中的视频解码:

  • ID3D11VIDEOCONTEXT :: DEXODERBEGINFRAME(解码器,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 :: SUBTSBUFFERS提交所有填充的缓冲区
  • ID3D11VIDEOCONTEXT :: DEXODERENDFRAME完成当前帧

3)D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS BUFFER还包含有关所有参考框架/Surface的信息 - 您需要自己管理它们,即确保gpu可以使用表面/纹理!

它非常复杂,检查FFMPEG和媒体播放器经典,他们都有DXVA2(尽管不是通过DX11)的支持。

4)从NV12转换为RGB(A),一些GPU(D3D11功能级别)允许将NV12用作着色器输入,有些则不会。如果不可能直接使用NV12,请查看D3D11VideProcessor界面,这些接口具有NV12/YUV420-> RGB转换,并获得所有GPU,并带有D3D11支持。

转换可以在这样的代码中执行:

// 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解码?

你不能。

ID3D11VIDEDODEVICE仅适用于Windows 8 ID3D11VIDEDODEVICE.

ID3D11VIDEODECODER仅适用于Windows 8 ID3D11VIDEODECODER.

在Windows 7上,您只能将DirectX 9用于硬件加速视频/H.264。谢谢微软。好的新的,IDIRECT3D9EX的工作...是的...其他好消息,使用Windows 7上的DirectX9,GPU解码性能非常好。

这是Windows 7和DirectX 9的源代码: MOFO7777, ,在H264DXVA2DECODER项目下。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top