본문스크랩 DirectShow 비디오 윈도우 셋팅


특정위도우에 비디오 재생을 하는 방법에 대해 설명하겠습니다.

비디오파일을 나타낼때, filter graph는 video renderer filter가 포함되어 있어야 합니다.
비디오는 압축되지 않은 데이터를 비디오 데이터를 입력 받고 윈도우에 스크린 나타는것을 나타냅니다.


달리지정하지않으면, 비디오 재생 윈도우는 타이틀바와 테두리가 있는 최상위 윈도우입니다.
어플리케이션에서 만든 특정윈도우에서 비디오가 나타나기를 원할것입니다.
어플리케이션 윈도우의 자식 비디오 윈도우에 나타나게 만들것입니다.

윈도우의 위치, 스타일 지정한 비디오 윈도우의 프로퍼티를 세팅해서 만들수 있습니다.
Filter Graph Manager의 IVideoWindow 인터페이스로 이걸 할수 있습니다.

첫번째로 filter graph manager의 인스턴스를 만들고, IGraphBuilder::RenderFile 메소드를 호출하여 filter graph를 생성합니다.

그리고, 재생을 시작하기전에 비디오 윈도우의 프로퍼티를 다음과 같이 세팅합니다.


1. 비디오 재생 윈도우를 원하는 부모윈도우에 붙입니다.
이것을 하기 위해, IVideoWindow::put_Owner 메소드를 호출하여 부모윈도우의 핸들을 넘깁니다.
이 메소드는 OAHWND 타입의 변수 하나를 받는다. 그래서 이 타입으로 핸들을 캐스팅합니다.

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


2. 비디오 윈도우의 스타일을 차일드 윈도우로 바꿉니다.
이것을 하기위하여, IVideoWindow::put_WindowStyle 메소드를 호출하고 스타일 플래그 조합을 넘깁니다.
WS_CHILD 윈도우는 윈도우가 자식윈도우를 갖는것이고 WS_CLIPSIBLINGS 플래그는 다른 자식윈도우의 클라이언트 영역에 그려지는것을 막습니다.

pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);


3. IVideoWindow::SetWindowPosition 메소드를 호출해서 비디오 윈도우의 위치를 세팅합니다.
이 메소드는 윈도우의 왼쪽 끝, 위쪽 끝, 길이와 높이의 장치 장표를 지정합니다.
예제 프로그램은 부모 윈도우 전체에 채우기 위해 비디오 윈도우를 늘립니다.

RECT grc;
GetClientRect(g_hwnd, &grc);
pVidWind->SetWindowPosition(0, 0, grc.right, grc.bottom);

GetClientRect 함수는 RECT 구조체를 윈도우의 클라이언트 영역의 좌표로 채웁니다.
좌표는 클라이언트 영역의 upper-left 코너와 관련이 있어서, left와 top은 0이고 right와 bottom은 width와 height로 정의 되어있습니다.

어플리케이션 종료 전에 비디오 윈도우의 visibility를 false로 세팅해야 합니다.
다른 방법으로, 스크린에 비디오 이미지가 남아있고, 사용자가 그것을 없앨수 없습니다.
그러므로, 오너를 NULL로 리셋합니다.
다르게 윈도우에 다른 윈도우에 메세지를 보내서 에러의 원인이 될수 있습니다.

HRESULT hr = pVidWin->put_Visible(OAFALSE);
hr = pVidWin-put_Owner(NULL);

예제소스

#############################################
***** Header *****
#############################################


void CleanUp();
void PlayFile();


IGraphBuilder *m_pGraph;
IMediaControl *m_pMediaControl;
IVideoWindow *m_pVidWin;

afx_msg void OnButton2();//Video Window Play
afx_msg void OnButton3();//Video Window End


#############################################
***** Cpp *****
#############################################

/////////////////////////////
//Setting the Video Window
/////////////////////////////
void CDShowTestDlg::PlayFile()
{
m_pGraph = NULL;
m_pMediaControl = NULL;
m_pVidWin = NULL;

CoInitialize(NULL);

CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void**)&m_pGraph);

m_pGraph->QueryInterface(IID_IMediaControl, (void**)&m_pMediaControl);
m_pGraph->QueryInterface(IID_IVideoWindow, (void**)&m_pVidWin);

//The RenderFile method builds a filter graph that renders the specified file.
m_pGraph->RenderFile(L"D:\\exam.wmv", NULL);


//The put_Owner method specifies a parent window for the video window.
m_pVidWin->put_Owner((OAHWND)(GetDlgItem(IDC_STATIC1)->m_hWnd));
//The put_WindowStyle method sets the window styles on the video window.
m_pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);

RECT grc;
GetDlgItem(IDC_STATIC1)->GetClientRect(&grc);
//The SetWindowPosition method sets the position of the video window.
m_pVidWin->SetWindowPosition(0, 0, grc.right, grc.bottom);


//The Run method runs all the filters in the filter graph.
//While the graph is running, data moves through the graph and is rendered.
m_pMediaControl->Run();
}

/////////////////////////////
//Setting the Video Window
/////////////////////////////
void CDShowTestDlg::CleanUp()
{
//The put_Visible method shows or hides the video window.
m_pVidWin->put_Visible(OAFALSE);
//Reset the owner to NULL before releasing the Filter Graph Manager.
m_pVidWin->put_Owner(NULL);


m_pMediaControl->Release();
m_pVidWin->Release();
m_pGraph->Release();
}

////////////////////////////////////
//Setting the Video Window
//Video Window Play
//////////////////////////////////////
void CDShowTestDlg::OnButton2()
{
// TODO: Add your control notification handler code here
PlayFile();

}

///////////////////////////////
//Setting the Video Window
//Video Window End
//////////////////////////////
void CDShowTestDlg::OnButton3()
{
// TODO: Add your control notification handler code here
CleanUp();

CoUninitialize();
}


by Redef(http://redef.tistory.com)

 


답글 남기기

이메일 주소는 공개되지 않습니다.