Filter 만들기 예제 (MS Visual Studio)
|
AppWizard의 C++ 프로젝트에서 Win32 Dynamic-Link Library를 선택하고 새로운 프로젝트를 만든다. |
] | |
Project메뉴에서 Insert Project into Workspace선택해서 DirectX SDK sample내에 있는 BaseClasses Project를 선택해서 Workspace에 포함시킨다. 다른 프로젝트를 사용하기전에 미리 BaseClasses빌드한다. |
|
빌드환경을 DirectShow를 이용가능하도록 맞춘다.1. DirectX SDK 디렉토리 설정.2. 헤더파일 dshow.h 라이브러리 파일 strmiids.lib quartz.lib strmbase.lib 를 프로젝트에 포함시킴.3. Calling Convention을 __stdcall로 통일하면, 보다 편하고 안정적이다.4. Setting 메뉴의 Link 에 있는 Entry-point Symbol을 DllEntryPoint@12로 한다. DllEntryPoint는 BaseClasses에 구현되어 있는 함수이다. 이러면 DllMain에 Dll을 초기화 하기위한 구현을 할 필요가 없다. |
|
빌드환경을 DirectShow를 이용가능하도록 맞춘다.1. DirectX SDK 디렉토리 설정.2. 헤더파일 dshow.h 라이브러리 파일 strmiids.lib quartz.lib strmbase.lib 를 프로젝트에 포함시킴.3. Calling Convention을 __stdcall로 통일하면, 보다 편하고 안정적이다.4. Setting 메뉴의 Link 에 있는 Entry-point Symbol을 DllEntryPoint@12로 한다. DllEntryPoint는 BaseClasses에 구현되어 있는 함수이다. 이러면 DllMain에 Dll을 초기화 하기위한 구현을 할 필요가 없다. |
Self-Registration 함수 구현DllRegisterServer와 DllUnRegisterServer를 구현하면 쉽게 시스템 레지스트리에 등록시킬수 있다. BaseClasses Project에 있는 AMovieDllRegisterServer2함수를 이용하면, 쉽게 구현가능하다. 예제 STDAPI DllRegisterServer() { return AMovieDllRegisterServer2(TRUE); } // DllRegisterServer
// // DllUnregisterServer // STDAPI DllUnregisterServer() { return AMovieDllRegisterServer2(FALSE); } // DllUnregisterServer |
Filter 구현1.GUID 생성 유틸리티를 통해서, GUID를 생성후에 DEFINE_GUID매크로를 이용해서 GUID를 정의한다. 2.CTransFormFilter를 상속받은 C++클래스를 정의한다. Override로 구현해야할 함수는 아래와 같다. // Overrides protected: // Transform operation, which this filter does virtual HRESULT Transform(IMediaSample *pIn, IMediaSample *pOut); // check if you can support mtIn virtual HRESULT CheckInputType(const CMediaType *pmtIn); // check if you can support the transform from this input to this output virtual HRESULT CheckTransform(const CMediaType *pmtIn, const CMediaType *pmtOut); // call the SetProperties function with appropriate arguments virtual HRESULT DecideBufferSize(IMemAllocator *pAllocator, ALLOCATOR_PROPERTIES *pProperties); // override to suggest OUTPUT pin media types virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType); 각함수의 기능은 앞에서 설명했다. 자세한 정의는 MSDN을 참고한다. |
CFactoryTemplate 값을 초기화한다. (예제 하나하나의 전달인자의 값은 MSDN을 참고한다.)const AMOVIESETUP_MEDIATYPE sudPinTypes = { &MEDIATYPE_NULL, // Major CLSID &MEDIASUBTYPE_NULL // Minor type };
const AMOVIESETUP_PIN psudPins[] = { { L”Input”, // Pin’s string name FALSE, // Is it rendered FALSE, // Is it an output FALSE, // Allowed none FALSE, // Allowed many &CLSID_NULL, // Connects to filter L”Output”, // Connects to pin 1, // Number of types &sudPinTypes // Pin type information }, { L”Output”, // Pin’s string name FALSE, // Is it rendered TRUE, // Is it an output FALSE, // Allowed none FALSE, // Allowed many &CLSID_NULL, // Connects to filter L”Input”, // Connects to pin 1, // Number of types &sudPinTypes // Pin type information }, };
const AMOVIESETUP_FILTER sudAa = { &CLSID_L544_Aa, // CLSID of filter L”aa Filter”, // Filter’s name MERIT_DO_NOT_USE, // Filter merit 2, // Number of pins psudPins // Pin information };
// // Object creation template // CFactoryTemplate g_Templates[] = { { L”aa Filter”, &CLSID_L544_Aa, CAaFilter::CreateInstance, NULL, &sudAa }, }; |
CreateInstance 구현새로운 COM 객체를 생성하기 위한 함수이다. 구현예는 아래와 같다. CreateInstance(LPUNKNOWN punk, HRESULT *phr) { ASSERT(phr);
CContrast *pNewObject = new IUnknown(NAME(“Filter”), punk, phr); if (pNewObject == NULL) { if (phr) *phr = E_OUTOFMEMORY; }
return pNewObject; } |
CTransformFilter::Transform 구현하기 Transform(IMediaSample *pIn, IMediaSample *pOut) 이 함수의 전달인자로 입력버퍼와 출력 버퍼가 넘어온다.IMediaSample의 GetPointer Method를 통해서 입출력 버퍼의 비트스트림 포인터를 얻을수 있다. 이 비트스트림 포인터 가 참조하는 메모리에서 영상을 읽고 처리해서 출력 비트스트림 포인터 내보내면 된다.
예제 Transform(IMediaSample *pIn, IMediaSample *pOut) { BYTE *pSourceBuffer, *pDestBuffer; pIn->GetPointer(pSourceBuffer); pOut->GetPointer(pDestBuffer); for(int i = 0; i < pIn->GetActualDataLength(); i++){ *pOut = }
return NO_ERROR; } // Transform |
[출처] Filter 만들기 예제 (MS Visual Studio) |작성자 semigifn