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);
此處理流程確保:
- 嚴格的資源生命周期管理
- 高效的硬件加速處理
- 靈活的多流混合能力
- 可靠的錯誤處理機制