창 모드 사용

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

참고

레거시 비디오 렌더러 필터 는 항상 창 모드를 사용합니다. VMR-7 및 VMR-9 필터는 기본적으로 창 모드를 사용하지만 창 없는 모드도 지원합니다.

 

창 모드에서 비디오 렌더러는 비디오 프레임을 그리는 자체 창을 만듭니다. 달리 지정하지 않는 한 이 창은 자체 테두리와 제목 표시줄이 있는 최상위 창입니다. 그러나 대부분의 경우 비디오가 애플리케이션 UI에 통합되도록 비디오 창을 애플리케이션 창에 연결합니다. 이 경우 다음 단계를 수행해야 합니다.

  1. IVideoWindow에 대한 쿼리입니다.
  2. 부모 창을 설정합니다.
  3. 새 창 스타일을 설정합니다.
  4. 소유자 창 내부에 비디오 창을 배치합니다.
  5. WM_MOVE 메시지의 비디오 창에 알립니다.

IVideoWindow에 대한 쿼리

재생을 시작하기 전에 IVideoWindow 인터페이스에 대한 필터 그래프 관리자를 쿼리합니다.

IVideoWindow *pVidWin = NULL;
pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);

부모 창 설정

부모 창을 설정하려면 애플리케이션 창에 대한 핸들 을 사용하여 IVideoWindow::p ut_Owner 메서드를 호출합니다. 이 메서드는 OAHWND 형식의 변수를 사용하므로 핸들을 다음 형식으로 캐스팅합니다.

pVidWin->put_Owner((OAHWND)hwnd);

새 창 스타일 설정

IVideoWindow::p ut_WindowStyle 메서드를 호출하여 비디오 창의 스타일을 변경합니다.

pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);

WS_CHILD 플래그는 창을 자식 창으로 설정하고 WS_CLIPSIBLINGS 플래그는 창이 다른 자식 창의 클라이언트 영역 내에서 그리는 것을 방지합니다.

비디오 창 배치

애플리케이션 창의 클라이언트 영역을 기준으로 비디오의 위치를 설정하려면 IVideoWindow::SetWindowPosition 메서드를 호출합니다. 이 메서드는 비디오 창의 왼쪽 가장자리, 위쪽 가장자리, 너비 및 높이를 지정하는 사각형을 사용합니다. 예를 들어 다음 코드는 부모 창의 전체 클라이언트 영역에 맞게 비디오 창을 늘립니다.

RECT rc;
GetClientRect(hwnd, &rc);
pVidWin->SetWindowPosition(0, 0, rc.right, rc.bottom);

비디오의 네이티브 크기를 얻으려면 필터 그래프 관리자에서 IBasicVideo::GetVideoSize 메서드를 호출합니다. 이 정보를 사용하여 비디오 크기를 조정하고 올바른 가로 세로 비율을 유지할 수 있습니다.

WM_MOVE 메시지에 응답

최상의 성능을 위해 그래프가 일시 중지되는 동안 창이 이동할 때마다 비디오 렌더러에 알려야 합니다. IVideoWindow::NotifyOwnerMessage 메서드를 호출하여 WM_MOVE 메시지를 전달합니다.

// (Inside your WindowProc)
case WM_MOVE:
    pVidWin->NotifyOwnerMessage((OAHWND)hWnd, msg, wParam, lParam);
    break;

렌더러가 하드웨어 오버레이를 사용하는 경우 이 알림은 렌더러가 오버레이 위치를 업데이트하도록 합니다. (VMR-9는 오버레이를 사용하지 않으므로 VMR-9를 사용하는 경우 이 메서드를 호출할 필요가 없습니다.)

정리

애플리케이션이 종료되기 전에 그래프를 중지하고 비디오 창의 소유자를 NULL로 다시 설정합니다. 그렇지 않으면 창 메시지가 잘못된 창으로 전송되어 오류가 발생할 수 있습니다. 또한 비디오 창을 숨기거나 화면의 비디오 이미지 깜박임이 일시적으로 표시될 수 있습니다.

pControl->Stop(); 
pVidWin->put_Visible(OAFALSE);
pVidWin->put_Owner(NULL);  

참고

비디오 창의 부모가 기본 애플리케이션 창의 자식인 경우(즉, 비디오 창이 자식인 경우) Intelligent Connect 중에 필터 그래프 관리자가 비디오 렌더러를 추가하도록 하는 대신 CoCreateInstance를 사용하여 비디오 창을 만들고 그래프에 추가해야 합니다. 이렇게 하면 비디오 창과 자식 창이 동시에 다시 그려집니다. 그렇지 않으면 자식 창이 비디오 창 위에 그려질 수 있습니다.

 

비디오 렌더링