다음을 통해 공유


5단계: 비디오 기능 추가

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드가 DirectShow 대신 Media Foundation에서 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]

이 항목은 DirectShow의 오디오/비디오 재생 자습서의 5단계입니다. 전체 코드는 DirectShow 재생 예제 항목에 나와 있습니다.

비디오가 올바르게 표시되도록 하려면 애플리케이션이 다음과 같이 WM_PAINT, WM_SIZEWM_DISPLAYCHANGE 메시지에 응답해야 합니다.

WM_PAINT 메시지 처리

애플리케이션이 WM_PAINT 메시지를 받으면 비디오 렌더러가 마지막 비디오 프레임을 다시 그려야 할 수 있습니다. EVR( Enhanced Video Renderer ) 필터의 경우 IMFVideoDisplayControl::RepaintVideo를 호출합니다.

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

VMR-9(비디오 혼합 렌더러 필터 9)의 경우 IVMRWindowlessControl9::RepaintVideo를 호출합니다.

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

VMR-7(비디오 혼합 렌더러 필터 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 필터 사용

비디오 믹싱 렌더러 사용