在媒體基礎中支援 DXVA 2.0
本主題描述如何使用 Microsoft Direct3D 9 在 Media Foundation 轉換中支援 DirectX 視訊加速 (DXVA) 2.0 (MFT) 。具體來說,它會描述解碼器與拓撲載入器所媒體的視訊轉譯器之間的通訊。 本主題不會描述如何實作 DXVA 解碼。
在本主題的其餘部分, 解碼器 一詞是指解碼器 MFT,它會接收壓縮的視訊,並輸出未壓縮的視訊。 解碼器裝置一詞是指圖形驅動程式所實作的硬體視訊加速器。
提示
如需 Microsoft Direct3D 11 影片解碼的資訊,請參閱 支援 Media Foundation 中的 Direct3D 11 影片解碼。
注意
Windows 市集應用程式必須使用 Direct3D 11。
以下是解碼器必須在媒體基礎中執行以支援 DXVA 2.0 的基本步驟:
- 開啟 Direct3D 9 裝置的控制碼。
- 尋找 DXVA 解碼器設定。
- 配置未壓縮的緩衝區。
- 解碼畫面格。
本主題的其餘部分會更詳細地說明這些步驟。
開啟 Direct3D 裝置控制碼
MFT 會使用 Microsoft Direct3D 裝置管理員來取得 Direct3D 9 裝置的控制碼。 若要開啟裝置控制碼,請執行下列步驟:
- 使用TRUE值公開MF_SA_D3D_AWARE屬性。 拓撲載入器會呼叫 IMFTransform::GetAttributes來查詢此屬性。 將 屬性設定為 TRUE 會通知拓撲載入器 MFT 支援 DXVA。
- 當格式交涉開始時,拓撲載入器會使用MFT_MESSAGE_SET_D3D_MANAGER訊息呼叫IMFTransform::P rocessMessage。 ulParam參數是影片轉譯器 Direct3D 裝置管理員的IUnknown指標。 查詢 IDirect3DDeviceManager9 介面的這個指標。
- 呼叫 IDirect3DDeviceManager9::OpenDeviceHandle 以取得轉譯器 Direct3D 裝置的控制碼。
- 呼叫 IDirect3DDeviceManager9::GetVideoService 並傳入裝置控制碼。 這個方法會傳回 IDirectXVideoDecoderService 介面的指標。
- 快取指標和裝置控制碼。
尋找解碼器組態
MFT 必須尋找 DXVA 解碼器裝置的相容設定。 在驗證輸入類型之後,在 IMFTransform::SetInputType 方法內執行下列步驟:
呼叫 IDirectXVideoDecoderService::GetDecoderDeviceGuids。 這個方法會傳回解碼器裝置 GUID 的陣列。
迴圈查看解碼器 GUID 的陣列,以尋找解碼器支援的專案。 例如,針對 MPEG-2 解碼器,您會尋找 DXVA2_ModeMPEG2_MOCOMP、 DXVA2_ModeMPEG2_IDCT或 DXVA2_ModeMPEG2_VLD。
當您找到候選解碼器裝置 GUID 時,請將 GUID 傳遞至 IDirectXVideoDecoderService::GetDecoderRenderTargets 方法。 這個方法會傳回轉譯目標格式的陣列,指定為 D3DFORMAT 值。
迴圈查看轉譯目標格式,並尋找解碼器所支援的格式。
呼叫 IDirectXVideoDecoderService::GetDecoderConfigurations。 傳入相同的解碼器裝置 GUID,以及描述建議輸出格式 的DXVA2_VideoDesc 結構。 方法會傳回 DXVA2_ConfigPictureDecode 結構的陣列。 每個結構都會描述解碼器裝置的一個可能設定。 尋找解碼器支援的組態。
儲存轉譯目標格式和組態。
在 IMFTransform::GetOutputAvailableType 方法中,根據建議的轉譯目標格式傳回未壓縮的視訊格式。
在 IMFTransform::SetOutputType 方法中,根據轉譯目標格式檢查媒體類型。
後援軟體解碼
例如,如果 MFT 找不到 DXVA 組態 (,如果圖形驅動程式沒有正確的功能) ,它應該會從SetInputType和SetOutputType方法傳回錯誤碼MF_E_UNSUPPORTED_D3D_TYPE。 拓撲載入器會傳送具有ulParam參數值為Null的MFT_MESSAGE_SET_D3D_MANAGER訊息來回應。 MFT 應該釋放其 IDirect3DDeviceManager9 介面的指標。 拓撲載入器接著會重新交涉媒體類型,而 MFT 可以使用軟體解碼。
配置未壓縮的緩衝區
在 DXVA 2.0 中,解碼器負責配置 Direct3D 表面做為未壓縮的視訊緩衝區。 解碼器應該為 EVR 配置 3 個表面,以用於反交錯。 這個數位是固定的,因為媒體基礎不提供 EVR 指定圖形驅動程式在取消交錯時所需的表面數目。 三個表面應該足以供任何驅動程式使用。
在 IMFTransform::GetOutputStreamInfo 方法中,設定 MFT_OUTPUT_STREAM_INFO 結構中的 MFT_OUTPUT_STREAM_PROVIDES_SAMPLES 旗標。 此旗標會通知媒體會話 MFT 配置自己的輸出範例。
若要建立表面,請呼叫 IDirectXVideoAccelerationService::CreateSurface。 (IDirectXVideoDecoderService 介面會從 IDirectXVideoAccelerationService.) 您可以在 SetInputType中執行這項操作,然後尋找轉譯目標格式。
針對每個表面,呼叫 MFCreateVideoSampleFromSurface 來建立媒體範例來保存表面。 方法會傳回 IMFSample 介面的指標。
解碼
若要建立解碼器裝置,請呼叫 IDirectXVideoDecoderService::CreateVideoDecoder。 方法會傳回解碼器裝置 之 IDirectXVideoDecoder 介面的指標。
解碼應該發生在 IMFTransform::P rocessOutput 方法內。 在每個畫面上,呼叫 IDirect3DDeviceManager9::TestDevice 來測試裝置控制碼。 如果裝置已變更,方法會 傳回DXVA2_E_NEW_VIDEO_DEVICE。 如果發生這種情況,請執行下列動作:
- 呼叫 IDirect3DDeviceManager9::CloseDeviceHandle來關閉裝置控制碼。
- 釋放 IDirectXVideoDecoderService 和 IDirectXVideoDecoder 指標。
- 開啟新的裝置控制碼。
- 交涉新的解碼器組態,如此頁面稍早的「尋找解碼器組態」中所述。
- 建立新的解碼器裝置。
假設裝置控制碼有效,解碼程式的運作方式如下:
- 取得目前未使用的可用表面。 (一開始可以使用所有表面。)
- 查詢 IMFTrackedSample 介面的媒體範例。
- 呼叫 IMFTrackedSample::SetAllocator ,並提供解碼器所實作之 IMFAsyncCallback 介面的指標。 當影片轉譯器釋放範例時,將會叫用解碼器的回呼。
- 呼叫 IDirectXVideoDecoder::BeginFrame。
- 執行下列一或多次:
- 呼叫 IDirectXVideoDecoder::GetBuffer 以取得 DXVA 解碼器緩衝區。
- 填入緩衝區。
- 呼叫 IDirectXVideoDecoder::ReleaseBuffer。
- 呼叫 IDirectXVideoDecoder::Execute 以在畫面上執行解碼作業。
DXVA 2.0 會針對解碼作業使用與 DXVA 1.0 相同的資料結構。 針對 H.261、H.263 和 MPEG-2) 的原始 DXVA 設定檔集 (,這些資料結構會在 DXVA 1.0 規格中說明。
在每對BeginFrame/Execute呼叫內,您可以多次呼叫GetBuffer,但每種類型的 DXVA 緩衝區只能呼叫一次。 如果您使用相同的緩衝區類型呼叫兩次,將會覆寫資料。
使用 SetAllocator 方法的回呼 (步驟 3) ,追蹤目前可用的樣本和使用中。
相關主題