1. Some source code analysis of the COM in BaseClasses [Combase.h / Combase.cpp]
o Class CBaseObject is the base class in BaseClasses, which only maintains counting information of M_CObjects. At the same time it only supports the constructor of the input name.
o CunkNown is a base class that implements COM, which inherits supports AGGREGATION from the INONDELEGATIONUnknown interface. At the same time it uses Member as Delegation Unknown Interface: const LPUNKNOWN m_pUnknown; at the same time it maintains the COM Reference Count - volatile LONG m_cRef; it's Constructor is: CUnknown (const TCHAR * pName, LPUNKNOWN pUnk); CUnknown (TCHAR * pName, LPUNKNOWN pUnk , HRESULT * PHR); of course, the Unicode version also has two two constructors that support char types.
O class template definition (really written DirectShow may not be used, mainly its own implementation, will be seen below): Class CFActoryTemplate {public: const wchar * m_name; // Name const clsid * m_clsid; // CLSIDLPFNNEWCOMOBJECT m_lpfnNew; // Create a real function LPFNInitRoutine m_lpfnInit; const AMOVIESETUP_FILTER * m_pAMovieSetup_Filter; BOOL IsClassID (REFCLSID rclsid) const {return (IsEqualCLSID (* m_ClsID, rclsid));} CUnknown * CreateInstance (LPUNKNOWN pUnk, HRESULT * phr) const {checkPointer (phr, NULL); return m_lpfnNew (pUnk, phr);}; where LPFNNewCOMObject and LPFNInitRoutine macro is defined as follows: typedef CUnknown * (CALLBACK * LPFNNewCOMObject) (LPUNKNOWN pUnkOuter, HRESULT * phr); / * a function (can be NULL ) which is called from the DLL entrypoint routine for each factory template: bLoading - TRUE on DLL load, FALSE on DLL unloadrclsid - the m_ClsID of the entry * / typedef void (CALLBACK * LPFNInitRoutine) (BOOL bLoading, const CLSID * rclsid); Amoviesetup_filter defines a slightly complicated point: // PIN on Media TypeTedef regPintypeSamoviesetup_mediatype, * Pamovie SETUP_MEDIATYPE, * FAR LPAMOVIESETUP_MEDIATYPE; typedef REGFILTERPINSAMOVIESETUP_PIN, * PAMOVIESETUP_PIN, * FAR LPAMOVIESETUP_PIN; // Filter real structure definition typedef struct _AMOVIESETUP_FILTER {const CLSID * clsID; const WCHAR * strName; DWORD dwMerit; UINT nPins; const AMOVIESETUP_PIN * lpPin;} AMOVIESETUP_FILTER , * Pamoviesetup_filter, * far lpamoviesetup_filter;
o interfaces implemented Delegation Unknown macros: #define DECLARE_IUNKNOWN / STDMETHODIMP QueryInterface (REFIID riid, void ** ppv) {/ return GetOwner () -> QueryInterface (riid, ppv); /}; / STDMETHODIMP_ (ULONG) AddRef () { / RETURN GETOWNER () -> addRef (); /}; / stdmethodimp_ (ulong) Release () {/ return getowner () -> release (); /}; 2. DirectShow Filter implementation COM self-registration mechanism [dllsetup.h /dllsetup.cpp/dllentry.cpp]
o As a registered COM component, you must support both DLLREGISTERSERVER and DLLUNREGISTERSERVER two export functions. The base class is simply invoked by the AMOVIEDLREGISTERSERVER2 function.
o AmoviedllRegisterServer2 function pseudo code, its parameter FLAG controls the switching of Register and Unregister. (1) Get the current Filter own name, using global variables g_hInit (2) call RegisterAllServers (parameter name Filter and Flag) register all OLE servers (3) by taking IFilterMapper2 or IFilterMapper interfaces to invoke AMovieSetupRegisterFilter2 or AMovieSetupRegisterFilter complete the registration, Note the use of global variables (must be implemented by Filter) extern int g_cTemplates; extern CFactoryTemplate g_Templates []; which, RegisterAllServers call AMovieSetupRegisterServer and AMovieSetupUnregisterServer, these two functions are responsible for registering the Filter as a standard COM component or cancellation, and the AMovieSetupRegisterFilter2 Register the Filter under the Category of DirectShow, the Category supports the Filter's ENUM and other operations.
3. Implementing the mechanism of DllgetClassObject, DllcanunloadNow function [DLLLENTRY.CP] Filter implementation based on BaseClasses generally uses DLLMAIN to initialize information, and the DllgetClassObject and Dllcanunloy DLLASSES have been generated as COM.
o CCLASSFACTORY class is derived from IclassFactory, CBaseObject. Member variable: const CFactoryTemplate * const m_pTemplate; ULONG m_cRef; // count information static int m_cLocked; Constructor: CClassFactory (const CFactoryTemplate *); assignment m_cRef (0), m_pTemplate (pTemplate) IClassFactory interface function: STDMETHODIMP CreateInstance (LPUNKNOWN pUnkOuter, REFIID RIID, VOID ** PV); {// standard support AGGREGATION ClassFactory implementation method, use // cunknown * pobj = m_pTemplate-> CreateInstance (PUNKOUTER, & HR);} stdmethodimp lockserver (Bool Flock); {just according to FLOCK To add m_clocked} o DLLMAIN Function Analysis BaseClasses-based FILTER generally calls DLLLEntryPoint functions directly in Dllmain.
o DllEntryPoint function analysis of several global variables: extern CFactoryTemplate g_Templates []; // User achieve extern int g_cTemplates; // User achieve DWORD g_amPlatform; // VER_PLATFORM_WIN32_WINDOWS etc ... (from GetVersionEx) OSVERSIONINFO g_osInfo; BOOL WINAPI DllEntryPoint (HINSTANCE hInstance , ULONG ulReason, LPVOID pv) {switch (ulReason) {case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls (hInstance); // DLL_THREAD_ATTACH cancel notification message and DLL_THREAD_DETACH DbgInitialise (hInstance); // prepare Debug information g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails g_osInfo.dwOSVersionInfoSize = sizeof (g_osInfo); if (GetVersionEx (& g_osInfo)) {g_amPlatform = g_osInfo.dwPlatformId;} else {DbgLog ((LOG_ERROR, 1, TEXT ( "Failed to get the OS platform, assuming Win95")) ); G_hinst = hinstance; dllinitclasses (true); break; case dll_process_detach: dllinitclasses (false); Break;}} // Call Any Initialization Routinesvoid DllinitClasses (Bool Bloading) {for (i = 0; i
o DllgetClassObject function: The code is relatively simple, as long as the global variable g_templates is traversed. STDAPI DllGetClassObject (REFCLSID rClsID, REFIID riid, void ** pv) {// traverse the array of templates looking for one with this class id for (int i = 0; i
4. DirectShow common structure definition [strMif.h]
o AM_MEDIA_TYPE PIN_DIRECTION well defined structure typedef struct _AMMediaType {GUID majortype; // primary type GUID subtype; // subtype BOOL bFixedSizeSamples; BOOL bTemporalCompression; ULONG lSampleSize; GUID formattype; IUnknown * pUnk; ULONG cbFormat; / * [size_is] * / BYTE * PBFORMAT;} AM_MEDIA_TYPE; TYPEDEF ENUM _PINDIRECTION {PINDIR_INPUT = 0, PINDIR_OUTPUT = PINDIR_INPUT 1} PIN_DIRECTION;
O Other Definition #define max_pin_name 128 # define max_filter_name 128typedef longlong reference_time; typef Double reftime; typef dword_ptr hsemaphore; typef dword_ptr hEvent;
o cmediatype [mtype.h / mtype.cpp] CMEDiatype class Inherited from AM_MEDIA_TYPE, common functions have CreateMediatype, DeleteMediatype, InitMediatype, and FreeMediatype, and CreateAudiomediatype.
5. DirectShow Common DEBUG Macro [wxdebug.h / wxdebug.cpp]
O three types of Assert, respectively, assert, execute_assert, and kassert, Execute_assert and Assert uniquely different are the statement in the non-debug environment. Kassert does not pop up MessageBox but write error information to file and other debugging devices. o DBGLOG is used to display output information.