Soy*_*ham 13 directx directx-11 h.264 hardware-acceleration dxva
我一整天都在研究,并没有走得太远.我在Windows 7上,使用directx 11.(我的最终输出是DX11纹理上的视频帧)我想解码一些非常大的H.264视频文件,而CPU(使用libav)则没有剪了它.
我已经看过了使用DXVA2的libav的hwaccel功能,但是当我需要创建一个IDirectXVideoDecoder时,它只能用一个D3D9接口来创建.(我没有使用DX11)
每当我查看DXVA文档时,它都没有引用DX11,是在DX10或11中删除了吗?(无法找到任何关于此的确认,也没有任何说明DXVA2是多余的,可能是它被DXVA-HD超越了吗?)
然后我查看了媒体基础SDK,因为它看起来像我应该用于DX11 ...但我的标题中没有类型(文档说只是包括,但这没有产生任何东西).他们还指定了最少的窗口8来使用它.
我相信使用MF我需要windows 8 SDK,它现在包含所有directx libs/headers.
因此,这与Windows 7存在差距...是否有可能获得硬件加速视频解码?如果是的话,我应该使用哪种API?
小智 22
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)各帧的解码见Media Foundation中的支持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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13305 次 |
| 最近记录: |