啟用 DirectX 視訊加速
[與此頁面相關聯的功能 Windows Media Format 11 SDK是舊版功能。 來源讀取器和接收寫入器已取代它。 來源讀取器和接收寫入器已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用來源讀取器和接收寫入器,而不是Windows Media Format 11 SDK。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]
本節說明如何在自訂播放程式中播放串流內容時啟用 Microsoft® DirectX® 影片加速。
背景
DirectX 影片加速 (DirectX VA) 是 2D 解碼作業硬體加速的 API 規格。 它可讓軟體解碼器將特定 CPU 密集作業卸載至圖形卡進行處理。 對於終端使用者而言,這可讓高位元速率視訊,例如在配備 DirectX VA 相容圖形卡的舊電腦上進行全螢幕 DVD 播放。
從 Windows Media Format 9 系列 SDK 開始,DMO 包裝函式篩選器支援 DirectX VA。 這表示,針對本機播放,應用程式可以使用 WM ASF 讀取器篩選器播放 Windows 媒體型內容,如果圖形卡支援它,則會自動叫用 DirectX VA 硬體加速。 不過,WM ASF 讀取器篩選不支援串流內容的播放。 因此,如果您想要在自訂播放程式中播放串流內容時支援 DirectX VA,您必須使用替代機制,這是從 Windows Media 9 系列開始Windows 媒體播放機所使用的替代機制。
因為Windows 媒體播放機是在開發 QASF 篩選器之前設計,所以Windows 媒體播放機根據 Windows 媒體格式 SDK 有自己的來源篩選器,可用來播放 Windows 媒體型內容。 WMP Windows Media 來源篩選會將解壓縮的資料直接傳遞給音訊和視訊轉譯器。 相反地,WM ASF 讀取器會將壓縮的內容傳遞至 Windows Media 解碼器 DirectX 媒體物件 (DMO) ,這些物件裝載于 DMO 包裝函式內。 下圖說明 WM ASF 讀取器與 WMP Windows 媒體來源篩選器之間的差異。
若要啟用串流內容的 DirectX VA,您必須建立自訂來源篩選準則,就像上圖中的一樣。 基本上,此篩選會使用 Windows 媒體格式 SDK 來具現化 WM Reader 物件、解壓縮範例,並在其輸出釘選上下游傳送它們。 此討論假設您已建立來源篩選,現在已準備好實作 DirectX VA 支援。
若要啟用 DirectX VA,來源篩選的基本工作是提供視訊轉譯器和 WMV 解碼器 DMO 與它們需要交涉 DirectX VA 連線的介面。 來源篩選不會參與這些交涉。 串流啟動之後,來源篩選可以執行的唯一 DirectX VA 相關工作是在 WMV 解碼器將時間戳記傳遞給影片轉譯器之前修改影片範例上的時間戳記。 執行這項操作的主要原因是提供超出標準 DirectShow® 介面啟用的自訂時程表控制項。
已定義三個介面,以啟用 Windows 媒體格式 SDK、播放機的來源篩選、Windows Media 視訊解碼器 DMO 和重迭混音器或視訊混合轉譯器之間的必要通訊。 下表說明這些介面。
介面 | 描述 |
---|---|
IWMCodecAMVideoAccelerator | 由 Windows Media 解碼器 DMO 公開,並由媒體播放機的來源篩選器呼叫,以設定啟用 DirectX VA 進行 Windows 媒體視訊內容解碼所需的各種連線。 |
IWMPlayerTimestampHook | 在玩家的來源篩選上實作。 它可讓篩選準則在下游傳遞影片範例之前修改影片範例上的時間戳記。 |
IWMReaderAccelerator | 在 WM Reader 物件上實作。 播放程式來源篩選會呼叫它,以從解碼器 DMO 取得介面。 |
已啟用 DirectX VA 的播放作業順序
本節說明已啟用 DirectX VA 的播放程式及其來源篩選的執行時間作業一般順序。 本節中參考的元件如下:
- 協力廠商媒體播放機,稱為播放機。
- 由播放機具現化的自訂來源篩選,會使用 Windows 媒體格式 SDK 解壓縮 Windows 媒體型內容。
- 播放程式來源篩選的視訊輸出釘選,稱為輸出釘選。
- DirectShow 影片播放篩選圖形,稱為圖形。
- 影片混合轉譯器,稱為 VMR。
- Windows Media Format SDK 非同步讀取器物件,稱為讀取器。
- Windows 媒體視訊解碼器 DirectX 媒體物件,稱為解碼器 DMO。
作業順序如下:
- 玩家會具現化其來源篩選和讀取器物件。 讀取器會建立視訊解碼器 DMO,並在其上設定壓縮) 輸入類型 (。 這必須在播放程式嘗試設定其視訊播放圖形之前發生,因為 SDK 和解碼器 DMO 必須參與與圖形的交涉程式,而且 DMO 必須知道步驟 9 期間的輸入格式。
- 播放程式會呼叫 IGraphBuilder::Render,並提供視訊來源篩選的輸出釘選。 此時,DirectShow 篩選圖形管理員會嘗試將 VMR 連線到播放機的視訊來源篩選。
- 篩選圖形管理員會在播放程式視訊來源篩選的輸出釘選上呼叫 IPin::Connect 。
步驟 4 到 10 發生在 IPin::Connect內。
來源篩選器會從讀取器的IWMReaderAccelerator::GetCodecInterface方法取得IWMCodecAMVideoAccelerator介面。 如果編解碼器不支援 DirectX VA, 則對 GetCodecInterface 的呼叫可能會失敗。 在此情況下,交涉會如往常一樣繼續進行,而不需要 DirectX VA 支援。
來源篩選會透過IWMCodecAMVideoAccelerator::SetAcceleratorInterface,從傳遞至連線至解碼器 DMO 的PIN 傳遞 IAMVideoAccelerator指標。
然後,來源篩選會將 IPin::Connect 作業的其餘部分委派給 CBaseOutputPin::Connect 方法。 SDK 的格式列舉會像今天一樣繼續進行。 如果編解碼器針對所連線的內容支援 DirectX VA,編解碼器 DMO 會先呈現這些 DirectX VA 子類型,再支援 YUV 和 RGB 類型。 如果有 DirectX VA 支援,則會在 DirectX VA 子類型的內容中嘗試步驟 7 到 11。 下列程式碼片段示範如何識別 DirectX VA 媒體子類型。
bool IsDXVASubtype( AM_MEDIA_TYPE * pmt ) { // All DXVA types have the same last 3 DWORDs. // guidDXVA is the base GUID for all DXVA subtypes. GUID guidDXVA = { 0x00000000, 0xa0c7, 0x11d3, { 0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5 } }; unsigned long const * plguid; unsigned long const * plguidDXVA; plguid = (unsigned long const *)&pmt->subtype; plguidDXVA = (unsigned long *)&guidDXVA; if( ( plguid[1] == plguidDXVA[1] ) && ( plguid[2] == plguidDXVA[2] ) && ( plguid[3] == plguidDXVA[3] ) ) { return true; } return false; }
CBaseOutputPin::Connect實作會在步驟 3 期間呼叫IPin::CompleteConnect。 如果考慮 DirectX VA 子類型,則會嘗試 DirectX VA 交涉。 輸出針腳會呼叫 IWMCodecAMVideoAccelerator::NegotiateConnection,並將目前的輸出媒體類型傳遞給它。
解碼器 DMO 會透過 IAMVideoAccelerator 介面執行與 VMR 的必要交涉,並傳回兩者已同意的視訊子類型 GUID。 輸出針腳會將在此程式期間收到的所有 IAMVideoAcceleratorNotify 呼叫委派給解碼器 DMO 的 IAMVideoAcceleratorNotify 介面,也可以透過 IWMReaderAccelerator::GetCodecInterface 方法取得。
如果NegotiateConnection成功,輸出針腳會使用IWMPlayerTimestampHook介面呼叫IWMCodecAMVideoAccelerator::SetPlayerNotify。 此勾點可讓來源篩選在將時間戳記傳遞給轉譯器之前,先更新樣本上的時間戳記。
來源篩選會呼叫 IWMReaderAccelerator::Notify 與交涉媒體類型。 這可讓讀取器更新其內部變數,並認可至 DirectX VA。 這是編解碼器或讀取器可以失敗的最後一個位置。 如果上述任何步驟失敗,來源篩選應該會返回步驟 3,並嘗試讀取器列舉的下一個類型。
播放隨即啟動。 如果連接輸出類型為 DirectX VA,讀取器會忽略解碼器 DMO 的輸出緩衝區。
發生 IPin::D isconnect時,來源篩選會以Null呼叫IWMCodecAMVideoAccelerator::SetAcceleratorInterface。 這會中斷編解碼器與轉譯器之間的 DirectX VA 連線。
相關主題