[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayer、IMFMediaEngine,以及媒體基礎架構中的音訊/視訊擷取 取代。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 MediaPlayer、IMFMediaEngine 和 音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]
如同任何 DirectShow 應用程式,DVD 播放應用程式一開始會建置篩選圖形。 DirectShow 提供下列用於 DVD 播放的元件:
- DVD 圖形構建器。 建構篩選圖形的協助程序物件。 它會公開 IDvdGraphBuilder 介面。
- DVD 導覽器 過濾器。 用於處理 DVD 播放、導覽以及其他命令的 DirectShow 過濾器。
DVD 播放也需要 MPEG-2 譯碼器。 硬體和軟體 MPEG-2 譯碼器可從第三方取得。 首先,建立 DVD Graph Builder 對象的實例。
IDvdGraphBuilder *pBuild = NULL;
hr = CoCreateInstance(CLSID_DvdGraphBuilder, NULL,
CLSCTX_INPROC_SERVER, IID_IDvdGraphBuilder, (void **)&pBuild);
此時,您可以先選取並設定影片轉譯器,再建置圖形的其餘部分。 下一節會詳細說明這個選擇性步驟。 如果您省略此步驟,DVD 圖形產生器會選取預設轉譯器。 接下來,呼叫 IDvdGraphBuilder::RenderDvdVideoVolume 方法來建置圖形。
AM_DVD_RENDERSTATUS buildStatus;
hr = pBuild->RenderDvdVideoVolume(L"Z:\\video_ts", 0, &buildStatus);
第一個參數是包含 DVD 檔案的目錄名稱。 在 DVD 光碟上,這些檔案位於名為 VIDEO_TS 的目錄中。 如果第一個參數是 NULL,則 DVD 圖形產生器會使用包含 DVD 磁碟區的第一個磁碟驅動器。
第二個參數包含各種選擇性旗標,可用來選擇譯碼器類型(硬體或軟體)和其他選項。
第三個參數是接收狀態資訊的 AM_DVD_RENDERSTATUS 結構。 如果 RenderDvdVideoVolume 方法傳回S_FALSE,則表示呼叫部分成功(或部分失敗,如果您是悲觀者)。 例如,方法可能無法轉譯子圖片數據流,即使其他數據流已成功轉譯也一樣。 如果 RenderDvdVideoVolume 方法傳回錯誤碼或值S_FALSE,您可以檢查 AM_DVD_RENDERSTATUS 結構,以取得錯誤的詳細數據。
接下來,呼叫 IDvdGraphBuilder::GetFiltergraph,以取得 Filter Graph 管理員的指標。 這個方法會傳回 Filter Graph Manager IGraphBuilder 介面的指標。
IGraphBuilder *pGraph = NULL;
hr = pBuild->GetFiltergraph(&m_pGraph);
使用 IDvdGraphBuilder:GetDvdInterface 方法來擷取 DVD 相關的介面,包括下列項目:
- IDvdControl2。 控制播放和 DVD 命令
- IDvdInfo2。 傳回 DVD 導覽器目前狀態的相關信息。
- IAMLine21Decoder。 控制隱藏式字幕顯示。 隱藏式字幕顯示預設啟用。 若要停用此功能,請使用 AM_L21_CCSTATE_Off 旗標呼叫 IAMLine21Decoder::SetServiceState。
- IBasicAudio。 控制音訊音量和平衡。
例如,下列程式代碼會傳回 IDvdControl2 介面。
IDvdControl2 *pDvdControl = NULL;
hr = pBuild->GetDvdInterface(IID_IDvdControl2, (void**)&pDvdControl);
建置 DVD 播放篩選圖形的建議方式是讓 DVD Graph Builder 物件自動為您執行。 此方法會在下方和 DVD 範例應用程式中示範。 如果您需要手動建置 DVD 篩選圖形,您可以遵循 DirectShow 檔中討論的圖形建置基本規則來執行此動作。 一般而言,您不應該手動新增、移除、連接或中斷 DVD 圖形產生器所建立圖表中的個別篩選,因為這樣做可能會混淆清除程序代碼。
設定影片轉譯器
DirectShow 提供數個視訊轉譯器篩選。 在建置圖形之前,您可以選擇偏好的視訊轉譯器。 選擇繪圖器,方法是呼叫 IDvdGraphBuilder::GetDvdInterface,並請求該繪圖器特定的介面以選擇它。
- 重疊混音器篩選:IDDrawExclModeVideo。
- 影片混合轉譯器 7 (VMR-7): IVMRFilterConfig。
- 影片混合轉譯器 9 (VMR-9): IVMRFilterConfig9。
- 增強式視訊轉譯器 (EVR):IEVRFilterConfig。
如果您在建置篩選圖形之前要求上述任何介面,DVD 圖形產生器會建立對應的視訊轉譯器。 稍後,當您建置圖形時,DVD 圖形產生器會嘗試使用該轉譯器。 但是,如果無法使用您選取的轉譯器來建置圖形,它可能會切換至另一個轉譯器。 例如,您的 MPEG-2 譯碼器可能與 VMR 篩選器不相容,在此情況下,DVD 圖形產生器會預設為重疊混音器。
這些介面也可讓您在渲染器連接到解碼器之前配置渲染器。 例如,您可以將 VMR 設定為使用無視窗模式,而不是預設的視窗模式。 如需影片轉譯器的詳細資訊,請參閱在 DirectShow 中 關於視訊轉譯的主題。
在 Windows XP 和更新版本上,DVD 圖形產生器一律使用 視訊混合轉譯器 7 (VMR-7),除非:
- 呼叫端查詢只在 重疊混音器中找到的介面,例如 IMixerPinConfig2。 這會傳送一個提示給 DVD 圖形產生器,表明應用程式想使用疊加混音器,而不是 VMR。 Windows Media Player 也有一個對話框選項,可強制使用覆疊混合器。
- 已安裝的譯碼器與 VMR 不相容。 在圖形建置期間,會使用新的 IAMDecoderCaps 介面來檢查譯碼器的 VMR 支援。 如果不存在,DVD 圖形建立器會使用覆疊混合器。
- 使用硬體譯碼器時,譯碼器無法連線到 Video Port Manager (VPM)。 如果硬體譯碼器無法使用 VPM,則它無法使用 VMR,因此 DVD 圖形產生器接著會嘗試使用重迭混音器來建置圖形。
- 已知顯示卡的資源和/或功能不足,無法支援 VMR,但在驅動程式中未正確回報。 (部分已知案例被 DVD 圖形產生器特別排除。
- 譯碼器與 VMR 之間的連線因任何原因而失敗,通常是因為缺少 VRAM 來建立必要的表面。 在這些情況下,DVD 圖表建構器會停用 VMR,並嘗試使用重疊混音器來構建圖形。
視窗模式
在視窗模式中(覆蓋混音器或 VMR),渲染器會建立自己的視訊視窗。 若要將這個視窗設為應用程式視窗的子視窗,請使用應用程式的句柄來呼叫 IVideoWindow::put_Owner。 另外請呼叫 IVideoWindow::put_WindowStyle,在呈像器的影片視窗上設定 WS_CHILD 和 WS_CLIPSIBLINGS 風格。 若要從轉譯器的影片視窗取得滑鼠訊息,請使用應用程式視窗的控制代碼呼叫 IVideoWindow::put_MessageDrain。 這個方法會設定「訊息清空」— 影片視窗會將它接收的任何滑鼠訊息轉送至訊息清空視窗。
pVideoWindow->put_Owner((OAHWND)hwnd);
pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
pVideoWindow->put_MessageDrain((OAHWND)hwnd) ;
訊息流失會讓選取 DVD 菜單按鈕變得有點複雜。 假設視訊視窗未填滿應用程式的整個工作區,某些滑鼠事件會落在視訊視窗外。 當您從視訊窗口 內的 取得滑鼠事件時,您應該處理它以進行 DVD 功能表導航。 不應處理來自 外部 視訊視窗的滑鼠事件。 在訊息排放的情況下,無法區分這兩者。 此外,來自視訊視窗的滑鼠事件的座標會相對於視訊視窗的客戶區,但來自視訊視窗外部的滑鼠事件相對於應用程式的客戶區。
無視窗模式
無視窗模式可以完全避免滑鼠訊息的問題。 您不需要清空訊息,因為 VMR (或 EVR) 不會在無視窗模式中建立自己的視窗。 相反地,它會直接在您的應用程式視窗上繪製。 如果目的地矩形小於應用程式工作區,則 DVD 導覽器會在計算 DVD 按鈕位置時將此納入考慮。 因此,當您收到滑鼠訊息時,您可以將座標直接傳遞至 DVD 導覽器,如功能表導覽一節中所述。
相關主題