1 / 38

DirectShow Multimedia Programming

DirectShow Multimedia Programming. 한국외국어대학교 정보통신공학과 조 정 원 mailto:sweop@hanmail.net 지도교수 : 홍진표 교수님. Introduction. MS 에서 제공하는 DirectX 패키지는 DirectX 프로그램을 실행하기 위한 ‘ run-time environment ’ 와 DirectX 프로그램을 개발하기 위한 SDK 로 구성됨 . DirectX 기술에는 윈도우 멀티미디어를 다루는 기술은 DirectShow 가 포함되어 있음 .

luther
Télécharger la présentation

DirectShow Multimedia Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. DirectShow Multimedia Programming 한국외국어대학교 정보통신공학과 조 정 원 mailto:sweop@hanmail.net 지도교수 : 홍진표 교수님

  2. Introduction • MS에서 제공하는 DirectX 패키지는 DirectX프로그램을 실행하기 위한 ‘run-time environment’와 DirectX 프로그램을 개발하기 위한 SDK로 구성됨. • DirectX 기술에는 윈도우 멀티미디어를 다루는 기술은 DirectShow가 포함되어 있음. • DirectX 실행환경은 대부분 윈도우에 기본적으로 설치되어 있음. • 윈도우 미디어 플레이어는 DirectShow를 포함한 DirectX 기술을 사용하는 대표적인 프로그램.

  3. Definition • 클라이언트에서 멀티미디어 파일 재생을 목적으로 한 프레임워크(framework). • 재생에 필요한 모든 기능들을 필터(Filter)라는 단위로 쪼개고 이를 서로 조합하여 사용하는 방식을 취함.

  4. DirectShow System Overview [그림1] 다이렉트쇼의 프레임워크

  5. DirectShow 등장배경 (1) • DirectShow 의 모체는 비디오 캡쳐의 주요 기술인 VfW(Video for Windows). • 비디어 캡쳐 기술은 처음에 단순히 비디오 편집을 위해 입력된 영상을 파일에 저장하는 것을 목적으로 하였지만, PC에서 멀티미디어에 대한 요구가 점점 늘어나면서 단순 저장보다는 화상회의 같은 다양한 애플리케이션 형태로 발전함. • MS는 벤더들이 독자적으로 확장한 VfW 기술을 흡수하고 흩어져 있는 각종 멀티미디어 기술을 통합하는 기술을 발표 => DirectShow

  6. DirectShow 등장배경 (2) [표1] 멀티미디어 데이터의 특징

  7. DirectShow 등장배경 (2) [표2] 멀티미디어 데이터의 처리 방안

  8. DirectShow 컴포넌트 구조 (1) • DirectShow는 ‘필터(filter)’라는 구조의 컴포넌트를 도입하고 이들을 조합하여 다양한 멀티미디어 환경에 대응할 수 있도록 설계됨. • 필터는 MS의 COM(Component Object Model) 기술을 기반으로 제작되며, 이에 따라 생성된 객체(object)는 독립된 COM 객체로 취급됨. • DirectShow 자체는 사용자 모드 기술이므로 ‘DirectShow 가 보여주는 필터는 모두 사용자 모드의 필터’ 로 커널 모드의 하드웨어를 DirectShow 에서 사용하기 위해서는 특별한 형태의 사용자 모드 필터가 필요하다. • 커널 모드의 하드웨어와 통신할 수 있는 특별한 DirectShow 필터는 “Hardware Wrapper Filter”

  9. DirectShow 컴포넌트 구조 (2) • DirectShow는 필터를 조합하여 미디어를 재생. • 필터 그래프(Filter Graph)는 필터들을 적절한 순서대로 조합하여 생성한 결과. • DirectShow의 미디어 재생 기능에 있어서 최소 단위의 시스템이 바로 필터라는 컴포넌트 단위. • 필터는 종류별로 묶어 분류하고 이에 GUID(Globally Unique Identifier)를 붙여서 구별한 것. • DirectShow의 필터는 입력값으로 들어온 데이터 스트림을 사용자가 필요한 대로 가공, 변경하여 출력.

  10. 인터넷 DirectShow 소스 필터 변환 필터 렌더 필터 파일 시스템 사용자 모드 커널 모드 스트림 클래스 TV 튜너 기존의 VFW 캡쳐 장치 아날로그 비디오 크로스바 사운드 카드 WDM 캡쳐 장치 Source Filter • 필터그래프의 성격을 결정하는 중요한 필터. • 사용자 모드의 파일 시스템이나 인터넷 입력, 커널 모드의 다양한 하드웨어 입력, CD롬이나 DVD롬 등의 입력을 처리. • 얼마나 다양한 입력을 처리할 수 있느냐는 얼마나 많은 소스 필터를 보유하는지에 따라.

  11. Transform Filter • 소스 필터로부터 입력된 데이터를 다양한 형태로 변화시키는 역할. • 적용될 수 있는 영역은 멀티미디어 데이터 압축 및 해제, 형식 변환, 데이터 수정 등. • 얼마나 다양한 포맷을 처리할 수 있느냐는 얼마나 많은 변환 필터를 보유하는냐에 따라. DirectShow DirectShow 코덱 필터 기존의 VFW VCM/ACM 코덱 소스 필터 변환 필터 렌더 필터 사용자 모드 커널 모드 스트림 클래스 하드웨어 코덱 장치 WDM 코덱 장치

  12. 인터넷 DirectShow 소스 필터 변환 필터 렌더 필터 파일 시스템 사용자 모드 커널 모드 스트림 클래스 DirectDraw DirectSound WDM 캡쳐 장치 비디오 카드 사운드 카드 Render Filter • 최종 출력을 어떤 형태로 처리할것인지 결정짓는 필터 • 최종 출력을 파일로 저장할 수도 있고 화면에 출력할 수도 있고 또는 네트워크에 있는 다른 소스 필터로 최종 출력을 전송할 수도 있다.

  13. DirectShow 제어 • DirectShow는 다수의 컴포넌트 객체가 서로 상호 작용하여 동작하는 구조로 이루어져 있기 때문에 Single-Thread로는 동작하기 어려우며 대개 Multi-Thread로 동작하게 된다. Multi-Thread 환경에서의 Deadlock를 피하기 위해 모든 제어 동작을 항상 “upstream order”로만 수행하도록 규정함. • 제어를 담당하는 컴포넌트는 “Filter graph manager”. • Filter graph manager가 filter graph의 제어를 독점하면 DirectShow의 작동 원칙을 일일이 설명할 필요가 없을 뿐만 아니라 잘못 사용함으로써 발생할 수 있는 치명적인 오류를 방지함.

  14. Filter Graph Manager (1) [표3] 필터그래프매니저의 역할

  15. Filter Graph Manager (2) • 필터 그래프에 제어 명령이 내려지면 해당 필터에 명령을 전달하고 상태를 주시한다. 이벤트 등을 통해 상태 변화가 전달되면 다시 필요한 필터에 상태 변화를 전달하고 필요한 작업을 수행하도록 한다. 필터 그래프 매니저 분배작업 [그림] 필터그래프매니저의 상태/제어 정보 분배

  16. 필터그래프매니저 필터그래프 제어 멀티미디어 스트림 DirectShow의 데이터 흐름 구조 (1) • DirectShow에서는 제어와 데이터 흐름이 분리. • 멀티미디어 데이터가 흐를 수 있는 전용물길을 만들어 주고 제어를 분리하여 필요할 때만 물길에 영향을 미칠 수 있게 함으로써 효율적.. • 제어는 필터그래프 매니저에서 담당하며 멀티미디어 데이터는 필터그래프 내에서만 흐른다. 필터그래프매니저는 이러한 데이터 흐름을 제어할 뿐이지 스트림이 흘러가는 방향을 변경할 수는 없다. 이렇게 멀티미디어 스트림의 물길이 정해짐에 따라 굳이 데이터를 복사하여 전달할 필요 없이 직접 전달할 수 있음.

  17. DirectShow의 데이터 흐름 구조 (2) • 버퍼 공유 : 멀티미디어 스트림의 물길이 정해짐에 따라 굳이 데이터를 복사하여 전달할 필요 없이 직접 전달할 수 있게 한다. 멀티미디어 데이터는 크기가 크기 때문에, 복사하는 횟수를 줄일수록 성능을 향상 시킬 수 있다. DirectShow는 ‘Buffer Negotiation”이라는 과정을 통해 가능하면 최대한 버퍼를 공유해 불필요한 복사 연산을 줄이도록 설계되었다. • 많은 리소스와 CPU 성능을 절약할 수 있음.

  18. DirectX SDK 경로 설정 • 비주얼 C++통합 환경에서 Tool>Option 메뉴를 누르면 옵션 대화상자가 나타난다. • 위의 두 그림과 같이 Directions 탭의 ‘Include files’, ‘Library files’와 관련된 설정에 반드시 DirectX SDK 경로가 포함되어 있어야 한다.

  19. 개발에 필요한 파일 • DirectShow Application을 개발할 때는 DirectShow base class를 사용하는것이 권장 되지 않음. • strmbase.lib 파일을 사용하는 경우는 매우 드물지만 필터 개발에는 꼭 필요한 라이브러리다. [표4] DirectShow Application 개발에 필요한 파일

  20. HRESULT와 매크로 (1) • COM 기술에서 대부분의 함수는 HRESULT라는 자료형을 리턴. • ‘WinError.h’헤더 파일에 부호 있는 32비트 자료형으로 정의  typedef LONG HRESULT; • HRESULT 자료형에는 상위 비트부터 플래그가 여러 개 있음. • 함수 호출의 성패 여부를 알아내는 방법 • 최상위 비트(MSB)에 플래그가 위치. • 이 비트가 0이면 성공, 1이면 실패를 의미. • 성패 여부는 2의 배수 방식에 따라 부호 검사만으로 알아냄. #define SUCCEEDED(Status)((HRESULT)(Status) >= 0) #define FAILED(Status)((HRESULT)(Status) < 0)

  21. HRESULT와 매크로 (2) [표5] 자주 사용되는 HRESULT값 및 코드 값

  22. HRESULT와 매크로 (3) • 대부분 미리 정해놓은 HRESULT 값을 사용. • S_FALSE는 성공한 코드이며, SUCCEEDED()매크로는 TRUE를 리턴하므로 주의! • 문서나 헤더에서는 HRESULT값을 16진수로 표기. • 이처럼 HRESULT값은 단순히 성공과 실패를 구분할 뿐만 아니라 서로 다른 값으로서 단순히 실패를 나타낼 수 있으며, 매개변수가 틀렸음을 의미하거나 메모리 부족등 상세한 의미를 전달하기도 한다.

  23. HRESULT와 매크로 (4) • 매크로 JIF()와 LIF() • DShowApp 위저드가 생성하는 소스 코드 중에 ‘Auxiliary.h’헤더 파일에 정의되어 있음. • 오류가 발생했을 때 오류 내용을 디버그 창에 표시하는 역할. • 매크로를 사용하기 전에 반드시 ‘HRESULT hr;’이라는 코드가 있어야 함. • JIF()는 HRESULT 값을 바로 리턴하여 함수를 종료하고 LIF()는 그렇지 않다는 차이점이 있음. #define JIF(x) if (FAILED(hr=(x))) \ {TRACE(TEXT("FAILED(0x%x) in ") TEXT(#x) TEXT("\n"), hr); return hr;} #define LIF(x) if (FAILED(hr=(x))) \ {TRACE(TEXT("FAILED(0x%x) in ") TEXT(#x) TEXT("\n"), hr); }

  24. HRESULT와 매크로 (5) • 매크로 SAFE_RELEASE() • ‘Auxiliary.h’헤더 파일에 정의되어 있음. • 아래와 같이 그 변수가 NULL이 아닐 때만 Release()함수를 호출하고 변수를 NULL로 초기화하는 역할 수행. • 중복되는 코드를 방지하기 위한 것 #define SAFE_RELEASE(x) {if (x) x->Release(); x=NULL;}

  25. 필터 그래프 구현 • 필터 그래프를 구성하기 위한 그래프 빌더는 아래와 같이 COM 인스턴스를 생성해 만듬. • IGraphBuilder 인터페이스의 메소드 중 가장 중요한것이 RenderFile() 함수 • 호출하면 인텔리전트 커넥트 기능을 이용하여 자동으로 필터 그래프를 생성. CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **) &pGB); 지정된 CLSID와 관련된 객체 생성 객체의 CLSID (plug-in component) 객체가 집합의 부분으로 생성되는지.. 코드가 수행되는 context : server 필터 그래프 매니저의 인터페이스 ID 반환되는 필터 그래프 매니저 객체

  26. RenderFile() : MPEG-1 파일 입력시 MPEG 오디오 압축 해제 변환필터 오디오 Renderer 필터 CLSID_CMPEGAudioCodec CLSID_AudioRenderer 화일 소스 필터 MPEG stream splitter 변환필터 CLSID_AsyncReader CLSID_MPEG1Splitter MPEG 비디오 압축 해제 변환필터 비디오 Renderer 필터 CLSID_CMPEGVideoCodec CLSID_VideoRenderer

  27. COM Interface [표4] 동영상 재생에 사용되는 DirectShow용 COM Interface

  28. 인터페이스 포인터 선언 IGraphBuilder *pGB = NULL; IMediaSeeking *pMS = NULL; IMediaControl *pMC = NULL; IMediaEventEx *pME = NULL; IBasicVideo *pBV = NULL; IVideoWindow *pVW = NULL; FILTER_STATE g_psCurrent=State_Stopped; BOOL g_bAudioOnly=FALSE;

  29. Initialize 초기화하고 필터그래프로 쿼리하여 COM Interface의 pointer를 얻어오는 부분 HRESULT CMPlayerDlg::InitDirectShow(void) //모든 COM함수를 초기화하는 함수 { HRESULT hr = S_OK; JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGB)); JIF(pGB->QueryInterface(IID_IMediaControl, (void **)&pMC)); JIF(pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS)); JIF(pGB->QueryInterface(IID_IBasicVideo, (void **)&pBV)); JIF(pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW)); JIF(pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME)); return S_OK; CLEANUP: FreeDirectShow(); return(hr); }

  30. Release HRESULT CMPlayerDlg::FreeDirectShow(void) { HRESULT hr=S_OK; StopMedia(); if(pVW) { /* 창을 감춘 후 부모 창 설정을 해제 */ hr = pVW->put_Visible(OAFALSE); /* 비디오의 잔상을 없애기 위해 사용 */ hr = pVW->put_Owner(NULL); /* 새로운 비디오 창을 생성하려고 시도 */ } /* 필터 그래프 매니저를 제거하여 필터그래프의 누적 방지 */ SAFE_RELEASE(pMC); SAFE_RELEASE(pMS); SAFE_RELEASE(pVW); SAFE_RELEASE(pBV); SAFE_RELEASE(pME); SAFE_RELEASE(pGB); return hr; }

  31. BOOL CMPlayerDlg::OnFileopen() { // TODO: Add your control notification handler code here HRESULT hr = S_OK; char szFilter[]="Media File(*.mpeg)|*.mpg|Avi(For DivX)(*.avi)|*.avi|ASF(Media Format)|*.asf|*.*|*.*|"; CString strTemp; CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter); if(dlg.DoModal() == IDOK) { strTemp=dlg.GetPathName(); } delete dlg; int a; a = strlen(strTemp); char* m_szFileName = new char[a]; strcpy(m_szFileName,strTemp); int nCurrentState = g_psCurrent; ResetDirectShow(); //혹시나 뭔가가 잘못되었을까봐... hr = PrepareMedia(m_szFileName); //렌더링하는 부분 if (FAILED(hr)) { Say(TEXT("File failed to render!")); m_ButtonPlay.EnableWindow(FALSE); MessageBeep(0); return hr; } else { m_ButtonPlay.EnableWindow(TRUE); } if (nCurrentState == State_Running) { OnPlay(); } else { OnStop(); } return 0; } Fileopen(MFC파일 열기 대화 상자Vs GetOpenFileName() API 함수)

  32. 미디어 파일 널 렌더링 (1) HRESULT CMPlayerDlg::PrepareMedia(LPTSTR lpszMovie) { HRESULT hr = S_OK; WCHAR wFile[MAX_PATH]; Say(TEXT("Loading...")); #ifndef UNICODE /* 1바이트 문자열을 2바이트 문자열로 변환 */ MultiByteToWideChar(CP_ACP, 0, lpszMovie, -1, wFile, MAX_PATH); #else lstrcpy(wFile, lpszMovie); #endif // 미디어 파일 널 렌더링 hr = pGB->RenderFile(wFile, NULL); ……….. Say(TEXT("Ready")); return hr; }

  33. 미디어 파일 널 렌더링 (2) • 필터그래프 매니저는 CLSID_FilterGraph로 정의된 COM 컴포넌트 안에 들어있음. • 이것을 원료로 사용하여 원래 용도인 필터그래프매니저 인터페이스(IGraphBuilder)를 요청하면 됨. • 인터페이스 포인터는 애플리케이션 클래스의 멤버 변수로 정의된 IGraphBuilder 인터페이스 포인터, pGB로 받아옴. • 필터그래프매니저 인터페이스는 다른 함수에서 인터페이스를 물어볼 때(QueryInterface()함수) 사용하므로 멤버 변수로 저장. • 주의: CocreateInstance() API() 함수를 사용하여 필터 그래프 매니저를 생성하면, 새로운 필터그래프 매니저는 그 전과 완전히 다른 COM 객체가 됨.

  34. OnPlay HRESULT RunMedia() { HRESULT hr=S_OK; if (!pMC) return S_OK; // Start playback hr = pMC->Run(); /* IMediaControl 인터페이스의 Run()함수를 호출 */ …….. // Remember play state g_psCurrent = State_Running; return hr; } 이 함수를 쓰기 전에 우리는 IMediaControl 인터페이스 포인터를 선언하고 QueryInterface()함수를 사용하여 필요한 용도(IID_IMediaControl)를 제시한 후, 유효한 IMediaControl 인터페이스 포인터 값을 얻어온 것이다.

  35. OnStop HRESULT StopMedia() { HRESULT hr=S_OK; if (!pMC) return S_OK; if (g_psCurrent == State_Stopped) return hr; // Stop playback hr = pMC->Stop(); ……. // Remember play state g_psCurrent = State_Stopped; return hr; }

  36. OnPause HRESULT PauseMedia(void) { HRESULT hr=S_OK; if (!pMC) return S_OK; // Play/pause if(g_psCurrent != State_Running) return S_OK; hr = pMC->Pause(); if (FAILED(hr)) { RetailOutput(TEXT("\r\n*** Failed(%08lx) in Pause()!\r\n"), hr); return hr; } else RetailOutput(TEXT("*** Media is Paused.\r\n")); // Remember play state g_psCurrent = State_Paused; return hr; }

  37. 필터그래프의 세 가지 상태 • 이 내용은 Directshow 애플리케이션을 배울 때는 자세히 알 필요가 없지만, 필터를 개발할 때는 매우 중요하다! • 추후 미디어 검색, 비디오 창 설정, 이벤트 처리등에 대해 자세히 알아봐야 한다!

  38. Reference • DirecthShow 멀티미디어 프로그래밍, 한빛미디어 • MSDN

More Related