Microsoft Direct3D 运行时调用用户模式显示驱动程序的 VideoProcessBeginFrame 和 VideoProcessEndFrame 函数,以指示用户模式显示驱动程序可以处理视频帧的这些函数调用之间的时间段。 在用户模式显示驱动程序可以处理任何视频帧之前,Microsoft Direct3D 运行时必须调用用户模式显示驱动程序的 SetVideoProcessRenderTarget 函数来设置用于视频处理的呈现目标图面。 但是,对 SetVideoProcessRenderTarget 的调用只能在开始帧和结束帧时间段之外发生。
设置用于视频处理的呈现目标图面后,用户模式显示驱动程序可以接收对其 VideoProcessBlt 函数的调用,以处理开始帧和结束帧时间段之间的视频帧。
视频处理生命周期管理
1. 帧处理准备阶段 (VideoProcessBeginFrame)
调用时机:
- 开始处理新视频帧之前
- 必须在任何视频处理操作前调用
函数原型:
HRESULT VideoProcessBeginFrame(HANDLE hVideoProcess, // 视频处理器句柄D3DDDIARG_VIDEOPROCESSBEGINFRAME* pBeginFrame // 帧开始参数
);
关键数据结构:
typedef struct _D3DDDIARG_VIDEOPROCESSBEGINFRAME {UINT Reserved; // 保留字段
} D3DDDIARG_VIDEOPROCESSBEGINFRAME;
驱动程序实现要点:
初始化硬件状态:
ResetVideoProcessorState(hVideoProcess);
分配临时资源:
AllocateFrameBuffers(hVideoProcess);
启动处理流水线:
StartVideoProcessingPipeline(hVideoProcess);
2. 渲染目标设置 (SetVideoProcessRenderTarget)
调用约束:
- 必须在VideoProcessBeginFrame和VideoProcessEndFrame之外调用
- 每帧只需设置一次(除非目标变更)
函数原型:
HRESULT SetVideoProcessRenderTarget(HANDLE hVideoProcess, // 视频处理器句柄D3DDDIARG_SETVIDEOPROCESSRENDERTARGET* pRenderTarget // 目标参数
);
数据结构:
typedef struct _D3DDDIARG_SETVIDEOPROCESSRENDERTARGET {D3DDDI_HANDLE hRenderTarget; // 渲染目标表面句柄UINT SubResourceIndex; // 子资源索引
} D3DDDIARG_SETVIDEOPROCESSRENDERTARGET;
实现示例:
HRESULT SetVideoProcessRenderTarget(...) {// 验证目标表面格式if (!CheckRenderTargetFormat(pRenderTarget->hRenderTarget)) {return DXVA2_E_UNSUPPORTED_FORMAT;}// 绑定到硬件处理器BindRenderTargetToProcessor(hVideoProcess,pRenderTarget->hRenderTarget,pRenderTarget->SubResourceIndex);return S_OK;
}
3. 视频处理执行 (VideoProcessBlt)
核心处理阶段:
- 在BeginFrame和EndFrame之间调用
- 执行实际的视频帧处理
函数原型:
HRESULT VideoProcessBlt(HANDLE hVideoProcess, // 视频处理器句柄D3DDDIARG_VIDEOPROCESSBLT* pBlt // 处理参数
);
关键数据结构:
typedef struct _D3DDDIARG_VIDEOPROCESSBLT {D3DDDI_HANDLE hRenderTarget; // 目标表面(应与Set调用一致)DXVA2_VideoProcessBltParams BltParams; // 处理参数DXVA2_VideoSample Samples[16]; // 输入样本数组UINT NumSamples; // 有效样本数
} D3DDDIARG_VIDEOPROCESSBLT;
处理流程示例:
HRESULT VideoProcessBlt(...) {// 1. 验证状态if (!IsRenderTargetSet(hVideoProcess)) {return DXVA2_E_RENDERTARGETNOTSET;}// 2. 上传样本数据for (UINT i = 0; i < pBlt->NumSamples; i++) {UploadVideoSample(pBlt->Samples[i]);}// 3. 配置处理参数ConfigureBltParameters(pBlt->BltParams);// 4. 执行硬件加速处理ExecuteVideoProcessing(hVideoProcess);return S_OK;
}
4. 帧处理结束 (VideoProcessEndFrame)
资源清理阶段:
- 完成所有处理操作
- 释放临时资源
函数原型
HRESULT VideoProcessEndFrame(HANDLE hVideoProcess // 视频处理器句柄
);
实现要点:
HRESULT VideoProcessEndFrame(HANDLE hVideoProcess) {// 1. 等待处理完成WaitForProcessingCompletion(hVideoProcess);// 2. 释放临时资源ReleaseFrameBuffers(hVideoProcess);// 3. 更新参考帧UpdateReferenceFrames(hVideoProcess);return S_OK;
}
高级处理技术
多流混合处理
// 配置多个输入流
for (UINT i = 0; i < pBlt->NumSamples; i++) {if (pBlt->Samples[i].SampleFormat.SampleFormat == DXVA2_SampleSubStream) {ProcessSubStream(pBlt->Samples[i]);} else {ProcessMainStream(pBlt->Samples[i]);}
}
HDR元数据处理
// 应用HDR元数据
if (pBlt->BltParams.ExtendedFormat.VideoPrimaries == DXVA2_VideoPrimaries_BT2020) {ApplyHDRMetadata(pBlt->BltParams.ColorInfo);
}
错误处理规范
状态验证
if (!IsBeginFrameCalled(hVideoProcess)) {return DXVA2_E_NOT_INITIALIZED;
}
表面验证
if (pBlt->hRenderTarget != GetCurrentRenderTarget(hVideoProcess)) {return DXVA2_E_WRONG_RENDERTARGET;
}
性能优化
异步处理模式
// 使用D3D查询实现异步
IDirect3DQuery9* pQuery;
pDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pQuery);VideoProcessBlt(...);pQuery->Issue(D3DISSUE_END);
while(S_FALSE == pQuery->GetData(NULL, 0, D3DGETDATA_FLUSH));
批处理优化
// 合并多个Blt操作
if (CanBatchProcess()) {ExecuteBatchProcessing(hVideoProcess);
}
实际应用示例
完整处理流程
// 1. 开始帧处理
pDevice->VideoProcessBeginFrame(hVP, &beginFrame);// 2. 设置渲染目标(必须在Begin/End之外)
D3DDDIARG_SETVIDEOPROCESSRENDERTARGET rt = {hRT, 0};
pDevice->SetVideoProcessRenderTarget(hVP, &rt);// 3. 执行处理(可多次调用)
D3DDDIARG_VIDEOPROCESSBLT blt = { /* 配置参数 */ };
pDevice->VideoProcessBlt(hVP, &blt);// 4. 结束帧处理
pDevice->VideoProcessEndFrame(hVP);
此处理流程确保:
- 严格的资源生命周期管理
- 高效的硬件加速处理
- 灵活的多流混合能力
- 可靠的错误处理机制