window 显示驱动开发-如何查询视频处理功能(五)

D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT和D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS请求类型

UMD 返回它支持的特定视频处理模式的数字和子流格式列表。 Direct3D 运行时在 D3DDDIARG_GETCAPS的 pInfo 成员指向的变量中为视频处理器模式指定DXVADDI_VIDEOPROCESSORINPUT结构。 UMD 在 D3DDDIARG_GETCAPS pData 成员指定的 D3DDDIFORMAT 类型值数组中返回它支持的子流格式。

功能概述

这两个请求类型用于查询特定视频处理器模式支持的处理子流格式:

D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT

  • 查询支持的处理子流格式数量

D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS

  • 获取具体的处理子流格式列表

关键数据结构

输入结构 (DXVADDI_VIDEOPROCESSORINPUT)

typedef struct _DXVADDI_VIDEOPROCESSORINPUT {
    GUID VPGuid;                   // 视频处理器GUID
    DXVADDI_VIDEODESC VideoDesc;   // 主视频流描述
    D3DDDIFORMAT SubStreamFormat;  // 保留字段(查询时设为0)
} DXVADDI_VIDEOPROCESSORINPUT;

查询流程实现

1. 查询子流格式数量 (D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT)
运行时调用示例:

DXVADDI_VIDEOPROCESSORINPUT input = {
    DXVA2_VideoProcProgressiveDevice, // 处理器GUID
    {1920, 1080, D3DDDIFMT_NV12, ...}, // 主视频描述
    0                               // 查询时设为0
};

D3DDDIARG_GETCAPS args = {
    D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT,
    &input,
    &formatCount,                 // 接收格式数量
    sizeof(UINT)
};

HRESULT hr = pDevice->GetCaps(&args);

UMD实现要点:

case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT: {
    DXVADDI_VIDEOPROCESSORINPUT* pInput = 
        (DXVADDI_VIDEOPROCESSORINPUT*)pArgs->pInfo;
    
    UINT count = GetSupportedSubStreamFormatCount(
        pInput->VPGuid, 
        &pInput->VideoDesc);
    
    *(UINT*)pArgs->pData = count;
    pArgs->DataSize = sizeof(UINT);
    return S_OK;
}

2. 查询子流格式列表 (D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS)
运行时调用示例:

std::vector formats(formatCount);

D3DDDIARG_GETCAPS args = {
    D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS,
    &input,                       // 相同的输入结构
    formats.data(),
    formatCount * sizeof(D3DDDIFORMAT)
};

HRESULT hr = pDevice->GetCaps(&args);

UMD实现要点:

case D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS: {
    DXVADDI_VIDEOPROCESSORINPUT* pInput = 
        (DXVADDI_VIDEOPROCESSORINPUT*)pArgs->pInfo;
    
    UINT count = GetSupportedSubStreamFormatCount(
        pInput->VPGuid, 
        &pInput->VideoDesc);
    
    if (pArgs->DataSize < count * sizeof(D3DDDIFORMAT)) {
        pArgs->DataSize = count * sizeof(D3DDDIFORMAT);
        return E_INVALIDARG;
    }
    
    GetSupportedSubStreamFormats(
        pInput->VPGuid, 
        &pInput->VideoDesc,
        (D3DDDIFORMAT*)pArgs->pData);
    
    pArgs->DataSize = count * sizeof(D3DDDIFORMAT);
    return S_OK;
}

典型支持的处理子流格式

格式值 常量定义 适用场景
50 D3DDDIFMT_NV12 标准子流处理
87 D3DDDIFMT_A8R8G8B8 图形叠加层
89 D3DDDIFMT_A8 Alpha通道数据
100 D3DDDIFMT_P010 HDR子流处理
300 D3DDDIFMT_AYUV 高质量子流

高级实现策略

动态格式支持

UINT GetSupportedSubStreamFormatCount(GUID VPGuid, DXVADDI_VIDEODESC* pDesc)
{
    // 4K视频特殊处理
    if (pDesc->SampleWidth >= 3840) {
        return 3; // 限制高分辨率下的格式选择
    }
    return 5; // 标准格式数量
}

格式兼容性检查

void GetSupportedSubStreamFormats(GUID VPGuid, DXVADDI_VIDEODESC* pDesc, 
                               D3DDDIFORMAT* pFormats)
{
    // 确保子流格式与主视频格式兼容
    if (pDesc->SampleFormat == D3DDDIFMT_P010) {
        pFormats[0] = D3DDDIFMT_P010; // 保持位深一致
        pFormats[1] = D3DDDIFMT_A8;
        // ...
    }
}

错误处理规范

无效GUID处理

if (!IsSupportedVPGuid(((DXVADDI_VIDEOPROCESSORINPUT*)pArgs->pInfo)->VPGuid)) {
    return DXVA2_E_UNSUPPORTED_DEVICE;
}

格式不支持

if (IsHDRContent(pDesc) && !SupportHDRFormats(VPGuid)) {
    return DXVA2_E_UNSUPPORTED_FORMAT;
}

实际应用示例

运行时完整查询流程

此查询机制使应用程序能够:

// 1. 准备查询参数
DXVADDI_VIDEOPROCESSORINPUT input = {
    DXVA2_VideoProcProgressiveDevice,
    {3840, 2160, D3DDDIFMT_P010, ...}, // 4K HDR主视频
    0
};

// 2. 查询子流格式数量
UINT subFormatCount = 0;
D3DDDIARG_GETCAPS args = {
    D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATCOUNT,
    &input, &subFormatCount, sizeof(UINT)
};
pDevice->GetCaps(&args);

// 3. 获取子流格式列表
std::vector subFormats(subFormatCount);
args.Type = D3DDDICAPS_GETVIDEOPROCESSORRTSUBSTREAMFORMATS;
args.pData = subFormats.data();
args.DataSize = subFormatCount * sizeof(D3DDDIFORMAT);
pDevice->GetCaps(&args);

// 4. 选择最佳子流格式
D3DDDIFORMAT selectedSubFormat = SelectSubStreamFormat(
    subFormats, 
    MAIN_VIDEO_FORMAT);
  1. 了解视频处理器对辅助流数据的处理能力
  2. 实现复杂的视频混合场景
  3. 支持字幕、水印等叠加内容
  4. 优化多流视频处理流水线

你可能感兴趣的:(windows图形显示驱动开发,音视频)