window 显示驱动开发-提供视频解码功能(二)

D3DDDICAPS_GETDECODEGUIDCOUNT和D3DDDICAPS_GETDECODEGUIDS请求类型

以下子主题列出了可能的请求类型及其关联的视频解码功能。

Direct3D 运行时调用 GetCaps 来请求 GUID 的数量,然后再次调用 GetCaps ,并请求支持的 GUID 列表。 UMD 返回以下列表中的数字和 GUID 列表,它支持视频加速 (VA) 解码。 D3DDDIARG_GETCAPS。对于这两种请求类型,pInfo 成员均为 NULL。

复制代码
DEFINE_GUID(DXVADDI_ModeMPEG2_MoComp, 0xe6a9f44b, 0x61b0, 0x4563,0x9e,0xa4,0x63,0xd2,0xa3,0xc6,0xfe,0x66);
DEFINE_GUID(DXVADDI_ModeMPEG2_IDCT,   0xbf22ad00, 0x03ea, 0x4690,0x80,0x77,0x47,0x33,0x46,0x20,0x9b,0x7e);
DEFINE_GUID(DXVADDI_ModeMPEG2_VLD,    0xee27417f, 0x5e28, 0x4e65,0xbe,0xea,0x1d,0x26,0xb5,0x08,0xad,0xc9);

DEFINE_GUID(DXVADDI_ModeH264_A,  0x1b81be64, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(DXVADDI_ModeH264_B,  0x1b81be65, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(DXVADDI_ModeH264_C,  0x1b81be66, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(DXVADDI_ModeH264_D,  0x1b81be67, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(DXVADDI_ModeH264_E,  0x1b81be68, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(DXVADDI_ModeH264_F,  0x1b81be69, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);

DEFINE_GUID(DXVADDI_ModeWMV8_A,  0x1b81be80, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(DXVADDI_ModeWMV8_B,  0x1b81be81, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);

DEFINE_GUID(DXVADDI_ModeWMV9_A,  0x1b81be90, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(DXVADDI_ModeWMV9_B,  0x1b81be91, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(DXVADDI_ModeWMV9_C,  0x1b81be94, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);

DEFINE_GUID(DXVADDI_ModeVC1_A,   0x1b81beA0, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(DXVADDI_ModeVC1_B,   0x1b81beA1, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(DXVADDI_ModeVC1_C,   0x1b81beA2, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(DXVADDI_ModeVC1_D,   0x1b81beA3, 0xa0c7, 0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);

#define DXVADDI_ModeMPEG2_MOCOMP  DXVADDI_ModeMPEG2_MoComp

#define DXVADDI_ModeWMV8_PostProc  DXVADDI_ModeWMV8_A
#define DXVADDI_ModeWMV8_MoComp  DXVADDI_ModeWMV8_B

#define DXVADDI_ModeWMV9_PostProc  DXVADDI_ModeWMV9_A
#define DXVADDI_ModeWMV9_MoComp  DXVADDI_ModeWMV9_B
#define DXVADDI_ModeWMV9_IDCT  DXVADDI_ModeWMV9_C

#define DXVADDI_ModeVC1_PostProc  DXVADDI_ModeVC1_A
#define DXVADDI_ModeVC1_MoComp  DXVADDI_ModeVC1_B
#define DXVADDI_ModeVC1_IDCT  DXVADDI_ModeVC1_C
#define DXVADDI_ModeVC1_VLD  DXVADDI_ModeVC1_D

#define DXVADDI_ModeH264_MoComp_NoFGT  DXVADDI_ModeH264_A
#define DXVADDI_ModeH264_MoComp_FGT  DXVADDI_ModeH264_B
#define DXVADDI_ModeH264_IDCT_NoFGT  DXVADDI_ModeH264_C
#define DXVADDI_ModeH264_IDCT_FGT  DXVADDI_ModeH264_D
#define DXVADDI_ModeH264_VLD_NoFGT  DXVADDI_ModeH264_E
#define DXVADDI_ModeH264_VLD_FGT  DXVADDI_ModeH264_F

核心查询机制

Direct3D 运行时通过两步流程查询用户模式驱动程序(UMD)支持的视频加速解码GUID:

  1. 查询GUID数量:首先获取支持的GUID总数
  2. 获取GUID列表:然后获取具体的GUID列表

数据结构与参数说明

D3DDDIARG_GETCAPS 结构关键成员

复制代码
typedef struct _D3DDDIARG_GETCAPS {
    D3DDDICAPS_TYPE Type;  // 指定请求类型
    VOID* pInfo;           // 此场景下始终为NULL
    VOID* pData;           // 指向返回数据的缓冲区
    UINT DataSize;         // 缓冲区大小(输入)/返回数据大小(输出)
} D3DDDIARG_GETCAPS;

详细查询流程

第一步:查询支持的GUID数量 (D3DDDICAPS_GETDECODEGUIDCOUNT)

运行时调用

复制代码
D3DDDIARG_GETCAPS getCapsArgs = {};
getCapsArgs.Type = D3DDDICAPS_GETDECODEGUIDCOUNT;
getCapsArgs.pInfo = NULL;
getCapsArgs.pData = &guidCount;  // 指向UINT变量
getCapsArgs.DataSize = sizeof(UINT);

pUMD->GetCaps(&getCapsArgs);

UMD响应要求:

  • 返回支持的视频解码GUID总数
  • 不要求提供pInfo参数
  • 通过pData返回计数值
  • 设置DataSize为实际写入的数据大小

第二步:查询GUID列表 (D3DDDICAPS_GETDECODEGUIDS)

运行时调用:

复制代码
std::vector<GUID> guidList(guidCount);  // 根据前一步的数量预分配

D3DDDIARG_GETCAPS getCapsArgs = {};
getCapsArgs.Type = D3DDDICAPS_GETDECODEGUIDS;
getCapsArgs.pInfo = NULL;
getCapsArgs.pData = guidList.data();
getCapsArgs.DataSize = guidCount * sizeof(GUID);

pUMD->GetCaps(&getCapsArgs);

UMD响应要求:

  • 填充pData缓冲区所有支持的GUID
  • 按连续数组形式排列GUID
  • 设置DataSize为实际写入的数据总字节数
  • 保持GUID顺序一致(推荐按优先级排序)

典型支持的视频解码GUID

UMD可能返回的常见DXVA解码器GUID示例:

GUID 描述
DXVA2_ModeMPEG2_VLD MPEG-2可变长度解码
DXVA2_ModeH264_E H.264硬件加速解码
DXVA2_ModeVC1_D VC-1解码
DXVA2_ModeHEVC_VLD_Main HEVC/H.265主配置解码
DXVA2_ModeVP9_VLD_Profile0 VP9 Profile0解码

错误处理规范

UMD应当处理以下情况:

缓冲区不足:当DataSize小于所需大小时

  • 返回E_INVALIDARG或类似错误码
  • 不修改缓冲区内容

无效参数:

  • 当pData为NULL时返回E_POINTER
  • 当Type不匹配时返回E_INVALIDARG

功能不支持:

  • 若完全不支持视频解码,返回0个GUID

实现示例代码

UMD侧实现伪代码:

复制代码
HRESULT UMD::GetCaps(D3DDDIARG_GETCAPS* pArgs) {
    if (!pArgs) return E_INVALIDARG;
    
    switch (pArgs->Type) {
    case D3DDDICAPS_GETDECODEGUIDCOUNT:
        if (pArgs->DataSize < sizeof(UINT)) return E_INVALIDARG;
        *(UINT*)pArgs->pData = SUPPORTED_GUIDS_COUNT;
        pArgs->DataSize = sizeof(UINT);
        return S_OK;
        
    case D3DDDICAPS_GETDECODEGUIDS: {
        size_t requiredSize = SUPPORTED_GUIDS_COUNT * sizeof(GUID);
        if (pArgs->DataSize < requiredSize) return E_INVALIDARG;
        
        memcpy(pArgs->pData, SUPPORTED_GUIDS_ARRAY, requiredSize);
        pArgs->DataSize = requiredSize;
        return S_OK;
    }
    // ...其他类型处理
    }
}

性能优化建议

  1. 缓存结果:UMD应缓存GUID列表避免重复计算
  2. 静态数据:多数情况下GUID列表是静态不变的
  3. 快速路径:对已知请求类型实现快速返回
  4. 并行安全:确保多线程调用安全性

这种两步查询机制允许运行时先确定所需缓冲区大小,再准确获取完整数据,是DirectX VA中标准的能力发现模式。

相关推荐
A133455514 分钟前
视频特效字幕怎么翻译?保姆级AI字幕与外挂字幕教程
人工智能·音视频
ViiTor_AI13 小时前
从去字幕到 AI 配音:完整视频本地化流程
人工智能·音视频
明德扬16 小时前
多路MIPI摄像头如何同步聚合?一文看懂FPGA视频汇聚方案
fpga开发·音视频
折枝吖18 小时前
音视频开发-PCM 原理与 AI 模块实战
音视频·pcm
HySpark20 小时前
熙瑾·会悟 ASR 实战:Qwen-ASR 漏字导致转写不完整,如何从音频分段到二次校验解决?
音视频·熙瑾会悟
大鹅办公21 小时前
酷狗音乐怎么转换MP3格式?4种方法亲测对比+避坑指南(附FFmpeg命令行教程)
ffmpeg·音视频·音频格式
小妖同学学AI1 天前
AI视频生成难在提示词?这个Claude插件让Seedance 2.0效率翻倍,附超全示例!
人工智能·开源·github·音视频
梦想的旅途21 天前
企业微信视频消息:mp4当图片发送失败
音视频·企业微信
阿童木写作1 天前
跨马翻译:AI图片翻译工具批量处理,跨境电商视频字幕翻译更高效
人工智能·python·音视频
老衲の少女心1 天前
【AI项目】从零构建 AI 视频生成系统:多模型编排的工程实践
人工智能·音视频