步驟 5:新增視訊功能

[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音訊/視訊擷取取代。 這些功能已針對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;
    }
}

針對視 訊混合轉譯器篩選器 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::D isplayModeChanged

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

針對 VMR-7,呼叫 IVMRWindowlessControl::D isplayModeChanged

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

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

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

DirectShow 中的音訊/視訊播放

DirectShow 播放範例

使用 DirectShow EVR 篩選器

使用視訊混合轉譯器