DirectShow DirectShow 샘플 DMO 샘플 DMO 샘플 [목차열람] [주소복사] [슬롯비우기] |
Microsoft DirectX 9.0 |
DMO 샘플은, Microsoft® DirectX® Media Object (DMO)의 샘플이다. MPEG-1 비디오 패킷을 입력으로 해, 출력 스트림을 2 개 생성한다. 최초의 출력 스트림에는, RGB 565 포맷의 비디오 프레임이 포함되어 있다. 각 프레임은 MPEG-1 비디오로부터 취득한 타임 코드를 표시해, 그것이 없는 경우는 아무것도 표시하지 않는다. 2 번째의 출력 스트림은, 타임 코드가 붙은, 옵션의 텍스트 스트림이다.
DMO 샘플은,IMediaObjectImpl 클래스 템플릿을 사용해,IMediaObject 인터페이스를 처리 한다. Active Template Library (ATL)는, 등록, 집합,IUnknown, DLL 엔트리 포인트 등, 다양한 COM 의 상세를 처리한다.
패스
소스 : (SDK 루트) \Samples\C++\DirectShow\DMO\DMOSample
사용자 가이드
이 프로젝트 워크 스페이스에서는, Dmosample.dll 라는 이름의 DLL 를 생성 한다. Regsvr32 유틸리티를 사용해 DLL 를 등록한다. 이 DMO 의 동작을 보려면 , Microsoft® DirectShow® GraphEdit 유틸리티를 사용한다. 다만, MPEG-1 비디오 파일이 필요하다. 다음의 스텝을 실행한다.
그래프를 실행 하면, 타임 코드를 표시하는 [Video] 윈도우가 나타난다.
프로그래밍 정보
DMO 샘플에는, 이하의 소스 파일이 포함되어 있다.
파일 | 설명 |
Dmosample.cpp | 기본적인 COM 기능을 ATL 에 처리하기 위한 코드. |
Resource.h | 리소스 정수를 정의한다. |
Sample.h, Sample.cpp | DMO 를 처리 하는 CSample 클래스를 정의한다. |
State.h, State.cpp | MPEG 데이터로부터 타임 스탬프를 생성하는 헬퍼-클래스인, CStreamState 클래스를 정의한다. |
Stdafx.h, Stdafx.cpp | 컴파일이 끝난 헤더를 생성한다. |
Util.h, Util.cpp | 출력 이미지를 드로잉(Drawing)하기 위한 유틸리티 함수가 포함된다. |
Dmosample.rc | 버전 정보를 사용해 리소스를 정의해, Sample.rgs 파일에 링크한다. |
Sample.rgs | 레지스트리 정보를 사용해 텍스트 리소스를 정의한다. ATL 는 이 리소스를 사용해, DLL 의 등록시에 레지스트리 엔트리를 생성 한다. |
다음의 주의는, 처리에 대해 상세하게 설명하고 있다.
Dmosample.cpp
이 파일에는, ATL 가 DMO 개체를 생성 해 등록하기 위해서 사용하는 개체 맵이 포함된다. 또, export 되는 DLL 함수도 포함된다. 이러한 함수에는, 엔트리 포인트 함수 (DllMain), COM 에 필요한 함수 (DllCanUnloadNow,DllGetClassObject,DllRegisterServer,DllUnregisterServer)가 있다.
ATL COM AppWizard 는, 이 파일에 포함되는 코드의 대부분을 자동 생성한다. 다음의 2 개가 추가된다.
Resource.h
이 헤더 파일로 선언되는 1 개의 정수 IDR_SAMPLE 는, ATL 의 자동 등록 메카니즘으로 사용된다. 정수 IDR_SAMPLE 는, 리소스 파일 Sample.rgs 로 정의되어 리소스 파일 Dmosample.rc 에 의해 임포트 되는 텍스트 리소스를 식별한다. 헤더 파일 Sample.h 에는, 다음의 행이 있다.
DECLARE_REGISTRY_RESOURCEID(IDR_SAMPLE)
이것에 의해, ATL 는 IDR_SAMPLE 리소스에 선언된 등록 정보를 사용할 수 있다.
Sample.h
DEFINE_GUID 매크로는, DMO 의 클래스 식별자 (CLSID)를 선언한다.
CSample 클래스는 다음의 클래스로부터 파생한다.
CSample 는, 커스텀 마샬링을 실행하는 후리스렛드마샤라개체를 모은다. COM 라이브러리가, 샘플 프로세스내의 복수의 thread에 걸쳐 CSample 포인터를 마샬링 하는 경우는, 완전히 같은 포인터가 반환된다. COM 라이브러리가 복수의 프로세스 또는 복수의 머신에 걸쳐 개체를 마샬링 하려고 하면 에러가 발생한다. ATL 는, 후리스렛드마샤라를 집성 하기 위해서 필요한 모든 코드를 추가한다. 이 코드는,FinalConstruct 메서드와 FinalRelease 메서드에 나타난다. COM 맵내의 COM_INTERFACE_ENTRY_AGGREGATE 엔트리는, 후리스렛드마샤라에 IMarshal 인터페이스를 위임한다.
CSample 클래스는, 다음의 멤버 변수를 선언한다.
변수 | 설명 |
m_pUnkMarshaler | 후리스렛드마샤라개체의 포인터. |
m_pBuffer | 입력 버퍼의 포인터. DMO 는 모든 입력을 처리할 때까지, 버퍼의 참조 카운트를 보관 유지한다. |
m_pbData | 입력 버퍼내의 다음의 바이트의 포인터. |
m_cbData | 미처리의 바이트수. |
m_rtFrame | 마지막 출력 프레임의 타임 스탬프. |
m_StreamState | MPEG 데이터를 해석하는, CStreamState 헬퍼-클래스의 인스턴스. |
m_bPicture | DMO 가 출력하는 픽쳐 정보를 가지고 있을지 어떨지를 나타내는, 불형 플래그. |
Sample.cpp
이 파일은, CSample 클래스에 메서드를 처리 한다.
타입의 설정 후, 새로운 타입이 현재의 타입에 일치하지 않는 경우, 메서드는 실패한다. DMO 가 스트리밍중으로 포맷 변경을 처리할 수 없는 경우는, 같은 코드를 포함할 필요가 있다. 실제, 샘플 DMO 는, 한 번에 1 개의 출력 프레임을 생성하므로, 포맷 변경을 용이하게 받아들일 수가 있다.
1. IMediaBuffer::GetBufferAndLength 메서드를 호출해, 입력 데이터의 포인터와 입력 데이터의 사이즈를 얻어온다.
2. 입력 버퍼의 참조 카운트를 보관 유지한다. m_pBuffer 변수는 ATL 스마트 포인터이므로, 이 변수에 값을 설정 하면,IUnknown::AddRef 메서드를 호출하는 효과를 갖는다.
3. 타임 스탬프를 CStreamState 개체에 건네준다. 샘플에 타임 스탬프가 없는 경우는, 값 INVALID_TIME 를 사용한다.
4. Private 헬퍼-메서드인 Process 를 호출해, 데이터를 처리한다.
1. 출력 버퍼가 출력 데이터를 보관 유지하는데 충분한 사이즈인 것을 확인한다. 충분한 사이즈가 없는 경우, 메서드는 에러를 돌려준다.
2. OurFillRect 메서드를 호출해, 배경을 드로잉(Drawing) 해, DrawOurText 메서드를 호출해, 텍스트를 드로잉(Drawing) 한다.
3. 타임 스탬프를 설정한다. 이 프레임에 유효한 타임 스탬프가 있는 경우는, 그것을 사용한다. 없는 경우는, 전의 타임 스탬프를 평균 frame rate로 인크리먼트(increment) 한다.
4. Process 메서드를 다시 호출해, 입력 버퍼에 남아 있으면 모든 데이터를 처리한다. 이것에 의해 출력 데이터가 증가했을 경우는, DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE 플래그를 설정한다.
스트림 1 은 옵션이므로, 호출측은 스트림 1 용의 버퍼를 할당하지 않은 것이 있다. 스트림 1 에 출력 버퍼가 없다고 해도, DMO 는 타임 코드를 텍스트 캐릭터 라인으로서 기입한다. 타임 스탬프와 처리 플래그는 스트림 0 의 것을 참조한다.