共用方式為


步驟 5:新增影片功能

[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngine,以及媒體基礎結構中的音訊/視訊擷取 取代。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 MediaPlayerIMFMediaEngine 音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]

本主題是 DirectShow 中音訊/視訊播放教學課程的步驟 5。 完整的程式代碼會顯示在 DirectShow 播放範例 主題中,

為了確保視訊正確顯示,應用程式必須回應 WM_PAINTWM_SIZEWM_DISPLAYCHANGE 訊息,如下所示。

處理WM_PAINT訊息

當應用程式收到 WM_PAINT 訊息時,視訊轉譯器可能需要重新繪製最後一個視訊畫面。 針對 增強式視訊渲染器 (EVR) 過濾器,呼叫 IMFVideoDisplayControl::RepaintVideo

HRESULT CEVR::Repaint(HWND hwnd, HDC hdc)
{
    if (m_pVideoDisplay)
    {
        return m_pVideoDisplay->RepaintVideo();
    }
    else
    {
        return S_OK;
    }
}

如需 Video Mixing Renderer Filter 9 (VMR-9),請呼叫 IVMRWindowlessControl9::RepaintVideo

HRESULT CVMR9::Repaint(HWND hwnd, HDC hdc)
{
    if (m_pWindowless)
    {
        return m_pWindowless->RepaintVideo(hwnd, hdc);
    }
    else
    {
        return S_OK;
    }
}

針對 視訊混合轉譯器濾鏡 7 (VMR-7),呼叫 IVMRWindowlessControl::RepaintVideo

HRESULT CVMR7::Repaint(HWND hwnd, HDC hdc)
{
    if (m_pWindowless)
    {
        return m_pWindowless->RepaintVideo(hwnd, hdc);
    }
    else
    {
        return S_OK;
    }
}

處理WM_SIZE訊息

如果視訊視窗的大小變更,請通知視訊轉譯器調整視訊大小。 針對EVR,呼叫 IMFVideoDisplayControl::SetVideoPosition

HRESULT CEVR::UpdateVideoWindow(HWND hwnd, const LPRECT prc)
{
    if (m_pVideoDisplay == NULL)
    {
        return S_OK; // no-op
    }

    if (prc)
    {
        return m_pVideoDisplay->SetVideoPosition(NULL, prc);
    }
    else
    {

        RECT rc;
        GetClientRect(hwnd, &rc);
        return m_pVideoDisplay->SetVideoPosition(NULL, &rc);
    }
}

針對 VMR-9,呼叫 IVMRWindowlessControl9::SetVideoPosition

HRESULT CVMR9::UpdateVideoWindow(HWND hwnd, const LPRECT prc)
{
    if (m_pWindowless == NULL)
    {
        return S_OK; // no-op
    }

    if (prc)
    {
        return m_pWindowless->SetVideoPosition(NULL, prc);
    }
    else
    {

        RECT rc;
        GetClientRect(hwnd, &rc);
        return m_pWindowless->SetVideoPosition(NULL, &rc);
    }
}

針對 VMR-7,呼叫 IVMRWindowlessControl::SetVideoPosition

HRESULT CVMR7::UpdateVideoWindow(HWND hwnd, const LPRECT prc)
{
    if (m_pWindowless == NULL)
    {
        return S_OK; // no-op
    }

    if (prc)
    {
        return m_pWindowless->SetVideoPosition(NULL, prc);
    }
    else
    {
        RECT rc;
        GetClientRect(hwnd, &rc);
        return m_pWindowless->SetVideoPosition(NULL, &rc);
    }
}

處理WM_DISPLAYCHANGE訊息

如果顯示模式發生變更,您必須通知 VMR-9 或 VMR-7 濾鏡。 針對 VMR-9,呼叫 IVMRWindowlessControl9::DisplayModeChanged

HRESULT CVMR9::DisplayModeChanged()
{
    if (m_pWindowless)
    {
        return m_pWindowless->DisplayModeChanged();
    }
    else
    {
        return S_OK;
    }
}

針對 VMR-7,呼叫 IVMRWindowlessControl:DisplayModeChanged

HRESULT CVMR7::DisplayModeChanged()
{
    if (m_pWindowless)
    {
        return m_pWindowless->DisplayModeChanged();
    }
    else
    {
        return S_OK;
    }
}

當顯示模式變更時,不需要通知 EVR。

下一步:步驟 6:處理圖形事件

在 DirectShow 中的音訊/視訊播放

DirectShow 播放範例

使用 DirectShow EVR 篩選器

使用影片混合轉譯器