DirectShow Learning (4) Part of Helper Classes Class Source Code Analysis

xiaoxiao2021-03-06  39

1. CREFTIME Class [Reftime.h] The Creftime class maintains the member variable of Reference_time M_Time; The unit is 100ns. In addition, several macros related to this class: const linelong milliseconds = (1000); // 10 ^ 3const longlong nanoseconds = (1000000000); // 10 ^ 9const longlong units = (nanoseconds / 100); // 10 ^ 7 #define MILLISECONDS_TO_100NS_UNITS (lMs) / Int32x32To64 ((lMs), (UNITS / MILLISECONDS)) inline LONGLONG WINAPI ConvertToMilliseconds (const REFERENCE_TIME & RT) {return (RT / (UNITS / MILLISECONDS));}

2. IBaseReferenceClock Interface IReferenceClock: public IUnknown {public:. // Retrieves the current reference time virtual HRESULT STDMETHODCALLTYPE GetTime (/ * [out] * / REFERENCE_TIME * pTime) = 0; // Creates a one-shot advise request virtual HRESULT. STDMETHODCALLTYPE AdviseTime (/ * [in] * / REFERENCE_TIME baseTime, / * [in] * / REFERENCE_TIME streamTime, / * [in] * / hEVENT hEvent, / * [out] * / DWORD_PTR * pdwAdviseCookie) = 0; // Creates a periodic advise request. virtual HRESULT STDMETHODCALLTYPE AdvisePeriodic (/ * [in] * / REFERENCE_TIME startTime, / * [in] * / REFERENCE_TIME periodTime, / * [in] * / hSEMAPHORE hSemaphore, / * [out] * / DWORD_PTR * pdwAdviseCookie ) = 0; // Removes a pending advise request. Virtual hResult stdmethodcallType unadvise (/ * [in] * / dword_ptr dwadvisecookie) = 0;

3. CCritSec and CAutoLock class [wxutil.h / wxutil.cpp] CCritSec encapsulates CRITICAL_SECTION m_CritSec; member variable, the function performed by LeaveCriticalSection EnterCriticalSection and Lock () and Unlock the variables simultaneously, and the Constructor called respectively Deconstructor InitializeCriticalSection and DeleteCriticalSection function. Cautolock is a Helper class that is used in conjunction with ccritsec, which accepts a ccritsec pointer in the Constructor and calls the Lock function, and calls the UNLock function in the Deconstructor. 4. Camschedule Class [DSSCHEDULE.H / Schedule.cpp] Delivery from CBaseObject In fact, this is a list, node is the type CADVISEPACKET. Specific parsing.

5. CBASEREFERENCECLOCK class [Refclock.h / refClock.cpp] inherits the IReferenceClock interface and is derived from CunkNown, Ccritsec.

o member variables: REFERENCE_TIME m_rtPrivateTime; // Current best estimate of timeDWORD m_dwPrevSystemTime; // Last vaule we got from timeGetTimeREFERENCE_TIME m_rtLastGotTime; // Last time returned by GetTimeREFERENCE_TIME m_rtNextAdvise; // Time of next adviseUINT m_TimerResolution; BOOL m_bAbort; // Flag used For Thread ShutdownHandle M_Hthread; // Thread HandlecamSchedule * const m_pschedule; // Task list // A Static function static dword __stdcall adviSetreadFunction (lpvoid); // function used to get there

o IReferenceClock interface functions: STDMETHODIMP GetTime (REFERENCE_TIME * pTime); {// first call Lock (), then rtNow = GetPrivateTime (); // Analyzing (rtNow> m_rtLastGotTime), is then m_rtLastGotTime = rtNow; otherwise, set the return value of S_FALSE // set the return value * pTime = m_rtLastGotTime;} / * Ask for an async notification that a time has elapsed * / STDMETHODIMP AdviseTime (REFERENCE_TIME baseTime, // base reference time REFERENCE_TIME streamTime, // stream offset time hEVENT hEvent, // advise via this event DWORD_PTR * pdwAdviseCookie // where your cookie goes); {// initialize the first output variable * pdwAdviseCookie = 0; // Analyzing ASSERT (WAIT_TIMEOUT == WaitForSingleObject (HANDLE (hEvent), 0)); // get the current absolute time const REFERENCE_TIME lRefTime = baseTime streamTime; // * pdwAdviseCookie = m_pSchedule-> AddAdvisePacket (lRefTime, 0, HANDLE (hEvent), FALSE);} / * Ask for an asynchronous periodic notification that a time has elapsed * / STDMETHODIMP AdvisePeriodic ( Reference_time StartTime, // Starting At this time REFERENCE_TIME PeriodTime, // time between notifications HSEMAPHORE hSemaphore, // advise via a semaphore DWORD_PTR * pdwAdviseCookie // where your cookie goes); {// Similarly, first initializes the output variable // * pdwAdviseCookie = m_pSchedule-> AddAdvisePacket (StartTime, PeriodTime, HSemaphore, True;} stdmethodimp unadvise; {return m_pschedule-> unadvise (dwadvisecookie);}

o the newly added virtual functions: virtual REFERENCE_TIME GetPrivateTime (); {CAutoLock cObjectLock (this); DWORD dwTime = timeGetTime (); m_rtPrivateTime = Int32x32To64 (UNITS / MILLISECONDS, (DWORD) (dwTime - m_dwPrevSystemTime)); m_dwPrevSystemTime = dwTime; return m_rtPrivateTime;} o Common member functions: / * Provide a method for correcting drift * / STDMETHODIMP SetTimeDelta (const REFERENCE_TIME & timeDelta); {CAutoLock cObjectLock (this); m_rtPrivateTime = timeDelta; if (timeDelta> 5000 && m_pSchedule-> GetAdviseCount ( )> 0) TriggerThread (); return NOERROR;} CAMSchedule * GetSchedule () const {return m_pSchedule;} void TriggerThread () // Wakes thread up Need to do this if {// time to next advise needs reevaluating EXECUTE_ASSERT (.. SetEvent (m_pSchedule-> GetEvent ()));} DWORD __stdcall AdviseThreadFunction (LPVOID p) {return DWORD (reinterpret_cast (p) -> AdviseThread ());} // Method in which the advise thread runsHRESULT Advise Thread () {DWORD dwWait = INFINITE; while (! M_bAbort) {WaitForSingleObject (m_pSchedule-> GetEvent (), dwWait); if (m_bAbort) break; const REFERENCE_TIME rtNow = GetPrivateTime (); m_rtNextAdvise = m_pSchedule-> Advise (10000 rtNow); LONGLONG llWait = m_rtNextAdvise - rtNow; llWait = ConvertToMilliseconds (llWait); // DO NOT replace this with a max !! (The type's of these things is VERY important) dwWait = (llWait> REFERENCE_TIME (UINT_MAX))? UINT_MAX: DWORD (LLWAIT);}}

o Deconstructor: ~ CBaseReferenceClock () {if (m_TimerResolution) timeEndPeriod (m_TimerResolution); m_pSchedule-> DumpLinkedList (); // if m_hThread present, call set to TRUE m_bAbort TriggerThread (), // and the like Thread End: WaitForSingleObject (m_hThread , Infinite); // Close Thread's Handle :: EXECUTE_ASSERT (CloseHandle (m_hthread)); // m_hthread = 0; // Clear the Event Handle: Execute_assert (CloseHandle (M_PsChedule-> getEvent ()))));}

o Constructor: CBaseReferenceClock :: CBaseReferenceClock (TCHAR * pName, LPUNKNOWN pUnk, HRESULT * phr, CAMSchedule * pShed): CUnknown (pName, pUnk), m_rtLastGotTime (0), m_TimerResolution (0), m_bAbort (FALSE), m_pSchedule (pShed? pShed: new CAMSchedule (CreateEvent (NULL, FALSE, FALSE, NULL))), m_hThread (0) {// determines m_pSchedule is empty, if empty directly returns an error TIMECAPS tc; m_TimerResolution = (TIMERR_NOERROR == timeGetDevCaps (& tc ?, sizeof (tc))) tc.wPeriodMin: 1; timeBeginPeriod (m_TimerResolution); / * Initialise our system times - the derived clock should set the right values ​​* / m_dwPrevSystemTime = timeGetTime (); m_rtPrivateTime = (UNITS / MILLISECONDS) * m_dwPrevSystemTime; if (! pShed) {DWORD ThreadID; m_hThread = :: CreateThread (NULL, // Security attributes (DWORD) 0, // Initial stack size AdviseThreadFunction, // Thread start address (LPVOID) this, // Threa d parameter (DWORD) 0, // Creation flags & ThreadID); // Thread identifier if (m_hThread) SetThreadPriority (m_hThread, THREAD_PRIORITY_TIME_CRITICAL); else returns an error and cleared m_pSchedule}} 6 CAMEvent class [wxutil.h / wxutil.cpp]. Similar to ccritsec, Camevent encapsulates Handle M_hevent;

o Construction: Camevent (Bool FmanualRevet = false); {m_hevent = creteEvent (null, fmanualReset, false, null)

o Deconstructor ~ Camevent () {if (m_hevent) Execute_assert (CloseHandle (M_ HEVENT));}

o member function very concise operator HANDLE () const {return m_hEvent;}; void Set () {EXECUTE_ASSERT (SetEvent (m_hEvent));}; BOOL Wait (DWORD dwTimeout = INFINITE) {return (WaitForSingleObject (m_hEvent, dwTimeout) = = WAIT_Object_0);}; void reset () {resetEvent (m_hevent);}; bool check () {return Wait (0);}; 7. Camthread class [wxutil.h / wxutil.cpp] Camthread is slightly complicated, at the same time It is also a very practical auxiliary class.

o member variables: CAMEvent m_EventSend; CAMEvent m_EventComplete; DWORD m_dwParam; DWORD m_dwReturnVal; HANDLE m_hThread; CCritSec m_AccessLock; // locks access by client threadsCCritSec m_WorkerLock; // locks access to shared objects which, m_EventSend default is TRUE, m_hThread initialized to NULL.

o Deconstrutor only calls the Close function.

o Add new Virtual function: Virtual dword threadproc () = 0;

o member function: // start thread running - error if already runningBOOL Create (); {CAutoLock lock (& ​​m_AccessLock); if (ThreadExists ()) {return FALSE;} // Create Thread, returns the result to create m_hThread = CreateThread (NULL, 0, CAMThread :: InitialThreadProc, this, 0, & threadid);} // signal the thread, and block for a responseDWORD CallWorker (DWORD); {CAutoLock lock (& ​​m_AccessLock); // // function setting parameter determining ThreadExists m_dwParam = dwParam ; // signal the worker thread: m_EventSend.Set (); // wait for the end Thread m_EventComplete.Wait (); / return result return m_dwReturnVal;} // accessor thread calls this when done with thread (having told thread to exit) void Close () {HANDLE hThread = (HANDLE) InterlockedExchangePointer (& m_hThread, 0); if (hThread) {WaitForSingleObject (hThread, INFINITE); CloseHandle (hThread);}};. // Return TRUE if the thread exists FALSE otherwiseBOOL ThreadExists (void) const {return (m_hthread! = 0);} handle getRequestHandle () const {return m_eventsend;}; dword get RequestParam () const {return m_dwparam;}; o Wait for several member functions are used in THREADPROC in inherited, by calling these functions, SET / RESET Event to implement thread synchronization. // Wait for the next requestdWord getRequest (); {m_eventsend.wait (); return m_dwparam;} // is the a request? Bool CheckRequest (DWORD * PPARAM); {// if (! m_eventsend.check ()) Return () Return False; / / Otherwise, * pParam = m_dwparam;} // reply to the requestvoid reply (dword); {m_dwreturnval = dw; m_eventsend.reset (); m_eventcomplete.set ();}

. O static member functions: // thread initially runs this param is actually 'this' Function // just gets this and calls ThreadProcstatic DWORD WINAPI InitialThreadProc (LPVOID pv); {HRESULT hrCoInit = CAMThread :: CoInitializeHelper (); CAMThread * pThread. = (CAMThread *) pv; HRESULT hr = pThread-> ThreadProc (); if (SUCCEEDED (hrCoInit)) {CoUninitialize ();} return hr;.} // call CoInitializeEx (COINIT_DISABLE_OLE1DDE) if available S_FALSE means it's not available. Static HRESULT COINTIALIZEHELPER (); {// Passing the function CoinitializeEx function directly by getModuleHandle (Text ("OLE32.DLL"); }Previous Article:

(3) Analysis of CBASEFILTER Class Source Codes

转载请注明原文地址:https://www.9cbs.com/read-69377.html

New Post(0)