You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用ID3D11VideoContext::GetDecoderBuffer()实现DirectX11 H.264解码

DirectX11 H.264解码问题解答

一、无需手动解析NALU的便捷参数获取方法

Windows平台没有和Mac的CMVideoFormatDescriptionCreateFromH264ParameterSets完全对应的直接API,但可以借助**Media Foundation(MF)**的组件来避免手动解析H.264的NALU(参数集SPS/PPS),步骤如下:

  • 初始化Media Foundation:调用MFInitialize(MF_INIT_FLAG_VIDEO_ONLY)。
  • 创建媒体类型:使用MFCreateMediaType获取IMFMediaType指针。
  • 设置媒体类型属性:
    • 设置主类型为MFMediaType_Video,子类型为MFVideoFormat_H264。
    • 用MFSetAttributeBlob将SPS、PPS数据分别传入MF_MT_H264_SPS和MF_MT_H264_PPS属性。
  • 提取解码所需参数:通过IMFMediaType的属性查询接口(如MFGetAttributeBlob、MFGetAttributeUINT32),直接获取profile_idc、level_idc、图像分辨率等关键参数,无需手动解析NALU的RBSP格式。

如果需要更直接的DXVA参数映射,也可以使用MF的H.264解码器变换(IMFTransform),将媒体类型传入后,通过查询解码器的输出格式或内部状态,间接获取适配DXVA 2.0的参数结构。

二、解码器缓冲区的正确填充方法

DirectX11视频解码确实复用DXVA 2.0的数据结构,你的猜测是正确的,以下是各缓冲区的填充细节:

1. D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS

调用GetDecoderBuffer时,需要将DXVA_PictureParameters指针的地址强制转换为void**传入,具体代码逻辑如下:

DXVA_PictureParameters* picParams = nullptr;
UINT32 bufferSize = 0;

// 获取参数缓冲区
hr = pVideoContext->GetDecoderBuffer(pDecoder, D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS, (void**)&picParams, &bufferSize);
if (SUCCEEDED(hr))
{
    // 填充通用字段
    picParams->wDecodedPictureIndex = 你的解码帧索引;
    picParams->wCurrentPictureIndex = 当前帧索引;
    picParams->bPicStructure = 帧结构类型(如DXVA_PicStruct_Frame);
    
    // 填充H.264特有的参数
    DXVA_PicParams_H264& h264Params = picParams->PicParamsH264;
    h264Params.wProfileIDC = 从MF获取的profile_idc;
    h264Params.wLevelIDC = 从MF获取的level_idc;
    h264Params.wSeqParameterSetID = SPS的ID;
    h264Params.wPicParameterSetID = PPS的ID;
    // 其他H.264参数如帧大小、参考帧数量等按需填充
}

2. 其他缓冲区填充

  • D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX:对应DXVA_Qmatrix结构体,将H.264 PPS中的量化矩阵数据填充到Qmatrix4x4或Qmatrix8x8成员中(取决于profile)。
  • D3D11_VIDEO_DECODER_BUFFER_BITSTREAM:直接填入H.264的字节流数据(包含NALU起始码或按Annex B格式组织的码流),注意缓冲区大小要匹配码流长度。
  • D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL:对应DXVA_Slice_H264结构体,需要为每个切片填充起始偏移、长度、切片类型等信息。如果是单切片帧,只需填充一个切片控制结构即可;多切片帧则需要逐个添加。

内容的提问来源于stack exchange,提问作者luckybroma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 07:25:39