本文共 5568 字,大约阅读时间需要 18 分钟。
参考文章:
AX文件的一个对外接口DllRegisterServer,由外部调用,比如注册AX的时候:regsvr32 xxx.ax
通常情况下,我们的filter可能注册在”Direct Show”目录下,那么直接调用 // Creates registry entries for the DLL STDAPIDllRegisterServer() { return AMovieDllRegisterServer2(TRUE); } AMovieDllRegisterServer2在DX的帮助文档内的说明如下: The AMovieDllRegisterServer2 函数为g_Templates 数组中的每个组件创建注册入口. 然而这个函数有一些限制,首先,它给每个filter分配“DirectShow Filters”分类(CLSID_LegacyAmFilterCategory), 但是不是每个filter都属于这个分类. 比如Capture filters and compression filters,有他们自己的分类.
第二,如果你的fitler支持一个硬件设备,你可能需要去注册两个增加AMovieDLLRegisterServer2 没有处理的信息pieces,: the medium and the pin category. A medium defines a method of communication in a hardware device, such as a bus. The pin category defines the function of a pin. For information on mediums, see KSPIN_MEDIUM in the Microsoft Windows Driver Development Kit (DDK). For a list of pin categories, see Pin Property Set.
如果我们的引擎需要注册到DirectShow之外的目录,又该如何做? // 注册Filter到Video Compressor REGFILTER2 rf2FilterReg = { 1, // Version 1 (no pin mediums or pin category). MERIT_NORMAL, // Merit. 1, // Number of pins. &sudPins // Pointer to pin information. }; //为DLL创建注册入口 STDAPI DllRegisterServer(void) { HRESULT hr = E_FAIL; IFilterMapper2 *pFM2 = NULL; hr = AMovieDllRegisterServer2(TRUE); // 这个还是要调用的 if (FAILED(hr)) return hr; hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper2, (void **)&pFM2); if (FAILED(hr)) return hr; hr = pFM2->RegisterFilter(CLSID_SomeFilter, // Filter CLSID. g_wszName, // Filter name. NULL, // Device moniker. &CLSID_VideoCompressorCategory, // Video compressor category. g_wszName, // Instance data. &rf2FilterReg // Pointer to filter information. ); pFM2->Release(); return hr; } 注销Filter 注销DirectShow内的引擎 // Removes registry entries for the DLL STDAPI DllUnregisterServer() { return AMovieDllRegisterServer2(FALSE); } 注销指定目录下的引擎 // 注销Video Compressor下的引擎 // Removes registry entries for the DLL STDAPI DllUnregisterServer() { HRESULT hr = E_FAIL; IFilterMapper2* pFM2 = NULL; hr = AMovieDllRegisterServer2(FALSE); if (FAILED(hr)) return hr; hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper2, (void **)&pFM2); if (FAILED(hr)) return hr; hr = pFM2->UnregisterFilter(&CLSID_VideoCompressorCategory, g_wszName, CLSID_SomeFilter); pFM2->Release(); return hr; } 给Filter起个名字 // Pin的type分为Major Type 和 Subtype // 比如,Major Type = Video, Subtype = MPEG-2 const AMOVIESETUP_MEDIATYPE sudPinTypes = { &MEDIATYPE_NULL, // Major type &MEDIASUBTYPE_NULL // Subtype }; const AMOVIESETUP_PIN psudPins[] = { // 定义Input Pin的信息 { L"Input", // String pin name FALSE, // Is it rendered FALSE, // Is it an output FALSE, // Allowed none FALSE, // Allowed many &CLSID_NULL, // Connects to filter 0 // Connects to pin 1, // Number of types &sudPinTypes }, // The pin details { L"Output", // String pin name FALSE, // Is it rendered TRUE, // Is it an output FALSE, // Allowed none FALSE, // Allowed many &CLSID_NULL, // Connects to filter 0, // Connects to pin 1, // Number of types &sudPinTypes // The pin details } }; // Declare filter information const AMOVIESETUP_FILTER sudFilter = { &CLSID_MPKiller, // Filter CLSID L"HQ MP Killer", // Filter name 0x8800000, // Its merit 2, // Number of pins psudPins // Pin details }; // declare a global array of CFactoryTemplate class instances, named g_Templates. Each // CFactoryTemplate class contains registry information for one filter. Several filters can // reside in a single DLL; simply include additional CFactoryTemplate entries. You can // also declare other COM objects, such as property pages // 在同一个DLL或者AX内,可以有多个引擎,比如系统目录下的quartz.dll。 // 所以,如果有多个引擎,相应的数组的大小就是引擎的个数。 CFactoryTemplateg_Templates[] = { { L"HQ MP Killer", &CLSID_MPKiller, CImplement::CreateInstance, NULL, &sudFilter } }; int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); // 有几个引擎 允许Filter应用 // CreateInstance 是CFactory的一个接口,在Filter内部实现它 CUnknown* WINAPI CImplement::CreateInstance( LPUNKNOWN pUnk, HRESULT *pHr) { CImplement *pFilter = new CImplement (); if (!pFilter) { *pHr = E_OUTOFMEMORY; } return pFilter; } Filter的Merit Graph 会使用“傻子”机制联接不同的filter,这就要通过filter的merit值的高低进行“傻子”联接。 该联接要使用IFilterMapper2::EnumMatchingFilters方法。 Merit: enum { MERIT_PREFERRED = 0x800000, MERIT_NORMAL = 0x600000, MERIT_UNLIKELY = 0x400000, MERIT_DO_NOT_USE = 0x200000, MERIT_SW_COMPRESSOR = 0x100000, MERIT_HW_COMPRESSOR = 0x100050 }; <= MERIT_DO_NOT_USE的Merit的Filter,系统是不会去“傻子”联接的。当然Merit值可以是任意值,而不一定是枚举出来的。 确定Filter的用途 不同的Filter有不同的用途,可以选择不同的基类,实现不同的方法。详见DirectX 文档。Filter的种类,在内进行了详细的描述root\DirectShow\DirectShow Reference\Constants and GUIDs\Filter Categories。 添加属性页 CFactoryTemplateg_Templates[2] = { { g_wszArcIPCam, // Name &CLSID_ArcIPCam, // CLSID CArcIPCam::CreateInstance, // Method to create an instance of MyComponent NULL, // Initialization function &sudArcIPCamSourceFilter // Set-up information (for filters) }, { // 这些数据,为属性页准备 g_wszArcIPCamProperty, &CLSID_ArcIPCamProperty, CArcIPCamProperty::CreateInstance } }; class CArcIPCam : public xxx, public IArcIPCam, public ISpecifyPropertyPages { private: // Constructor is private because you have to use CreateInstance CArcIPCam(IUnknown *pUnk, HRESULT *phr); ~CArcIPCam(); CArcIPCamPin *m_pPin; public: static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr); DECLARE_IUNKNOWN; // Property Page--- STDMETHODIMP GetClassID(CLSID *pClsid); // Basic COM - used here to reveal our property interface. STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); // return our property pages STDMETHODIMP GetPages(CAUUID * pPages); } 这三个函数必须实现。转载地址:http://vwyob.baihongyu.com/