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);