window 显示驱动开发-如何查询视频处理功能(三)
D3DDDICAPS_GETPROCAMPRANGE请求类型
UMD 返回指向 DXVADDI_VALUERANGE 结构的指针,该结构包含特定视频流上特定 ProcAmp 控件属性允许的值范围。 Direct3D 运行时在D3DDDIARG_GETCAPS的 pInfo 成员指向的变量中为特定视频流的 ProcAmp 控件属性指定DXVADDI_QUERYPROCAMPINPUT结构。
功能概述
D3DDDICAPS_GETPROCAMPRANGE请求类型允许应用程序查询视频处理器支持的ProcAmp控制参数(亮度、对比度、色相、饱和度)的有效范围,这些参数可用于实时视频处理调整。
关键数据结构
输入结构 (DXVADDI_QUERYPROCAMPINPUT)
typedef struct _DXVADDI_QUERYPROCAMPINPUT {GUID VPGuid; // 视频处理器GUIDDXVADDI_VIDEODESC VideoDesc; // 视频流描述D3DDDIFORMAT RenderTargetFormat; // 渲染目标格式DXVA2_ProcAmpControlProp Prop; // 查询的属性类型
} DXVADDI_QUERYPROCAMPINPUT;
输出结构 (DXVADDI_VALUERANGE)
typedef struct _DXVADDI_VALUERANGE {DXVA2_Fixed32 MinValue; // 最小值(Fixed32格式)DXVA2_Fixed32 MaxValue; // 最大值DXVA2_Fixed32 DefaultValue; // 默认值DXVA2_Fixed32 StepSize; // 步进增量
} DXVADDI_VALUERANGE;
ProcAmp属性枚举 (DXVA2_ProcAmpControlProp)
typedef enum {DXVA2_ProcAmp_Brightness, // 亮度控制DXVA2_ProcAmp_Contrast, // 对比度控制DXVA2_ProcAmp_Hue, // 色相控制DXVA2_ProcAmp_Saturation // 饱和度控制
} DXVA2_ProcAmpControlProp;
驱动程序实现规范
处理逻辑示例
case D3DDDICAPS_GETPROCAMPRANGE: {// 参数验证if (pArgs->DataSize < sizeof(DXVADDI_VALUERANGE)) {pArgs->DataSize = sizeof(DXVADDI_VALUERANGE);return E_INVALIDARG;}// 解析输入参数DXVADDI_QUERYPROCAMPINPUT* pInput = (DXVADDI_QUERYPROCAMPINPUT*)pArgs->pInfo;DXVADDI_VALUERANGE* pRange = (DXVADDI_VALUERANGE*)pArgs->pData;// 根据属性类型填充范围值switch (pInput->Prop) {case DXVA2_ProcAmp_Brightness:pRange->MinValue = DXVA2_Fixed32(-0.5f); // -50%pRange->MaxValue = DXVA2_Fixed32(0.5f); // +50%pRange->DefaultValue = DXVA2_Fixed32(0.0f);pRange->StepSize = DXVA2_Fixed32(0.01f); // 1%步进break;case DXVA2_ProcAmp_Contrast:pRange->MinValue = DXVA2_Fixed32(0.5f); // 50%pRange->MaxValue = DXVA2_Fixed32(2.0f); // 200%pRange->DefaultValue = DXVA2_Fixed32(1.0f);pRange->StepSize = DXVA2_Fixed32(0.02f); // 2%步进break;// 其他属性处理...}pArgs->DataSize = sizeof(DXVADDI_VALUERANGE);return S_OK;
}
Fixed32格式处理
转换方法示例
// Float转Fixed32
DXVA2_Fixed32 FloatToFixed(float f) {DXVA2_Fixed32 fixed;fixed.value = (short)(f * (1 << 16));fixed.fraction = (unsigned short)((f - fixed.value) * 65536.0f);return fixed;
}// Fixed32转Float
float FixedToFloat(DXVA2_Fixed32 fixed) {return fixed.value + (fixed.fraction / 65536.0f);
}
高级实现策略
动态范围调整
根据视频内容动态调整有效范围:
// HDR视频的特殊范围
if (pInput->VideoDesc.SampleExtendedFormat.VideoPrimaries == DXVA2_VideoPrimaries_BT2020) {pRange->MaxValue = FloatToFixed(4.0f); // HDR允许更高对比度
}
硬件限制检测
// 检测硬件是否支持精细调节
if (!HardwareSupportFineTuning()) {pRange->StepSize = FloatToFixed(0.05f); // 使用较大步进
}
错误处理规范
不支持属性
if (!(GetProcAmpCaps() & (1 << pInput->Prop))) {return DXVA2_E_UNSUPPORTED_PROP;
}
无效视频格式
if (!IsFormatSupported(pInput->RenderTargetFormat)) {return DXVA2_E_UNSUPPORTED_FORMAT;
}
实际应用示例
运行时查询代码
// 准备查询参数
DXVADDI_QUERYPROCAMPINPUT input = {DXVA2_VideoProcProgressiveDevice, // 目标处理器{ /* 视频描述 */ }, // DXVADDI_VIDEODESCD3DDDIFMT_NV12, // 渲染目标格式DXVA2_ProcAmp_Brightness // 查询亮度范围
};DXVADDI_VALUERANGE range;
D3DDDIARG_GETCAPS args = {D3DDDICAPS_GETPROCAMPRANGE,&input,&range,sizeof(DXVADDI_VALUERANGE)
};// 执行查询
if (SUCCEEDED(pDevice->GetCaps(&args))) {float minBrightness = FixedToFloat(range.MinValue);float maxBrightness = FixedToFloat(range.MaxValue);// 配置UI滑块范围...
}
此机制使应用程序能够:
- 准确了解可调整参数范围
- 提供合理的用户界面控制
- 确保参数设置的有效性
- 适应不同硬件的特性差异
驱动程序实现时应根据实际硬件能力返回精确的范围值,并考虑视频内容的特性对参数范围的潜在影响。