다음을 통해 공유


창 모드 사용

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

메모

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

 

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

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

IVideoWindow 대한 쿼리

재생을 시작하기 전에 IVideoWindow 인터페이스에 대해 Filter Graph Manager를 쿼리합니다.

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

부모 창 설정

부모 창을 설정하려면 애플리케이션 창에 대한 핸들을 사용하여 IVideoWindow::put_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);  

메모

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

 

비디오 렌더링