註冊DirectShow Filter資訊 收藏
編寫自己的 DirectShow Filter ,除了編寫實現功能的代碼之外,要使自己的 DLL 稱為一個 Filter ,還有一個重要的工作需要做,那就是註冊資訊。 DirectShow Filter 有兩種資訊註冊,一種是包含 Filter 的 DLL 作為 COM 組件的註冊資訊,一種是註冊 Filter 種類資訊。
當應用程式通過 CoCreateInstane 建立 Filter 的時候,通過第一中註冊資訊定位 DLL 。
第二種資訊註冊後,可以通過系統 裝置列舉程式和 Filter Mapped 定位到 Filter ,這種資訊不是必須註冊,當不註冊時候, Filter 被預設為 CLSID_LegacyAmFilterCategory 類型。
註冊 Filter 種類資訊分一下步驟:
一、聲明 Filter 資訊
view plain copy to clipboard print ? AMOVIESETUP_MEDIATYPE、 AMOVIESETUP_PIN、AMOVIESETUP_FILTER 1.AMOVIESETUP_MEDIATYPE typedef struct { const CLSID *clsMajorType; //主媒體類型 const CLSID *clsMinorType; //子媒體類型,可以使用MEDIASUBTYPE_NULL } REGPINTYPES; typedef REGPINTYPES AMOVIESETUP_MEDIATYPE, * PAMOVIESETUP_MEDIATYPE, * LPAMOVIESETUP_MEDIATYPE; 2.AMOVIESETUP_PIN typedef struct { LPWSTR strName; //已經廢棄,可以填充Output或者是Input,表示pin的類型 BOOL bRendered; //TRUE表示這是Render的Input Pin,其他的都使用FALSE BOOL bOutput; //TRUE表示這是output Pin。 BOOL bZero; //TRUE表示Filter可以包含0個這個pin的執行個體。 BOOL bMany; //TRUE表示Filter可以包含兩個或以上的這個pin的執行個體。 const CLSID *clsConnectsToFilter; //已經廢棄,填充CLSID_NULL const WCHAR *strConnectsToPin; //已經廢棄,填充NULL UINT nMediaTypes; //pin能支援多少中媒體類型 const REGPINTYPES *lpMediaType; // AMOVIESETUP_MEDIATYPE對象,描述媒體類型 } REGFILTERPINS; typedef REGFILTERPINS AMOVIESETUP_PIN, * PAMOVIESETUP_PIN, * LPAMOVIESETUP_PIN; 3.AMOVIESETUP_FILTER typedef struct _AMOVIESETUP_FILTER { const CLSID *clsID; //Filter的CLASSID const WCHAR *strName; //Filter的名字 DWORD dwMerit; // UINT nPins; //lpPin中AMOVIESETUP_PIN對象的個數 const AMOVIESETUP_PIN *lpPin; // AMOVIESETUP_PIN對象指標 } AMOVIESETUP_FILTER, * PAMOVIESETUP_FILTER, * FAR LPAMOVIESETUP_FILTER; AMOVIESETUP_MEDIATYPE、 AMOVIESETUP_PIN、AMOVIESETUP_FILTER 1.AMOVIESETUP_MEDIATYPE typedef struct { const CLSID *clsMajorType;//主媒體類型 const CLSID *clsMinorType;//子媒體類型,可以使用MEDIASUBTYPE_NULL } REGPINTYPES; typedef REGPINTYPES AMOVIESETUP_MEDIATYPE, * PAMOVIESETUP_MEDIATYPE, * LPAMOVIESETUP_MEDIATYPE; 2.AMOVIESETUP_PIN typedef struct { LPWSTR strName;//已經廢棄,可以填充Output或者是Input,表示pin的類型 BOOL bRendered;//TRUE表示這是Render的Input Pin,其他的都使用FALSE BOOL bOutput;//TRUE表示這是output Pin。 BOOL bZero;//TRUE表示Filter可以包含0個這個pin的執行個體。 BOOL bMany;//TRUE表示Filter可以包含兩個或以上的這個pin的執行個體。 const CLSID *clsConnectsToFilter;//已經廢棄,填充CLSID_NULL const WCHAR *strConnectsToPin;//已經廢棄,填充NULL UINT nMediaTypes;//pin能支援多少中媒體類型 const REGPINTYPES *lpMediaType;// AMOVIESETUP_MEDIATYPE對象,描述媒體類型 } REGFILTERPINS; typedef REGFILTERPINS AMOVIESETUP_PIN, * PAMOVIESETUP_PIN, * LPAMOVIESETUP_PIN; 3.AMOVIESETUP_FILTER typedef struct _AMOVIESETUP_FILTER { const CLSID *clsID;//Filter的CLASSID const WCHAR *strName;//Filter的名字 DWORD dwMerit;// UINT nPins;//lpPin中AMOVIESETUP_PIN對象的個數 const AMOVIESETUP_PIN *lpPin;// AMOVIESETUP_PIN對象指標 } AMOVIESETUP_FILTER, * PAMOVIESETUP_FILTER, * FAR LPAMOVIESETUP_FILTER;
二、聲明類工廠
view plain copy to clipboard print ? CFactoryTemplate g_Templates[] = { { L"MyFilter" //Filter名字 , &CLSID_MyFilter//Filter 的CLASSID , CMySourceFilter::CreateInstance//Filter的執行個體化介面 , NULL , &sudBallax }// AMOVIESETUP_FILTER對象 }; int g_cTemplates = sizeof (g_Templates) / sizeof (g_Templates[0]); CFactoryTemplate g_Templates[] = { { L"MyFilter"//Filter名字 , &CLSID_MyFilter//Filter的CLASSID , CMySourceFilter::CreateInstance//Filter的執行個體化介面 , NULL , &sudBallax }// AMOVIESETUP_FILTER對象 }; int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
三、重載 DllRegisterServer
view plain copy to clipboard print ? REGFILTER2 rf2FilterReg = { 1, // Pin使用 AMOVIESETUP_PIN,所以版本為1 MERIT_NORMAL, // Merit. 1, // Number of pins. &sudPins // Pointer to pin information. }; STDAPI DllRegisterServer(void ) { HRESULT hr; IFilterMapper2 *pFM2 = NULL; //此處註冊DLL資訊 hr = AMovieDllRegisterServer2(TRUE); if (FAILED(hr)) return hr; //以下註冊Filter資訊 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; } REGFILTER2 rf2FilterReg = { 1, // Pin使用AMOVIESETUP_PIN,所以版本為1 MERIT_NORMAL, // Merit. 1, // Number of pins. &sudPins // Pointer to pin information. }; STDAPI DllRegisterServer(void) { HRESULT hr; IFilterMapper2 *pFM2 = NULL; //此處註冊DLL資訊 hr = AMovieDllRegisterServer2(TRUE); if (FAILED(hr)) return hr; //以下註冊Filter資訊 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 的函數
view plain copy to clipboard print ? STDAPI DllUnregisterServer() { HRESULT hr; 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; } STDAPI DllUnregisterServer() { HRESULT hr; 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; }
IFilterMapper2 的 RegisterFilter 介面註冊 Filter 資訊,介面的第四個參數決定 Filter 屬於什麼種類,如果使用 CLSID_VideoCompressorCategory ,在 GraphEdit 中看到的 Filter 就在 Video Capture Source 中。