DirectShow 学习(四) 部分Helper Classes类源代码分析(转载)

转载 2007年10月14日 09:58:00

转自http://blog.csdn.net/alvachien/archive/2005/01/13/251847.aspx

CRefTime[reftime.h]CRefTime类维护了REFERENCE_TIME m_time;的成员变量。单位为100ns
另外,几个跟该类相关的宏:
const LONGLONG MILLISECONDS = (1000);            // 10 ^ 3
const LONGLONG NANOSECONDS = (1000000000);       // 10 ^ 9
const 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接口
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.      CCritSecCAutoLock[wxutil.h/wxutil.cpp]CCritSec封装了CRITICAL_SECTION m_CritSec;成员变量,通过函数Lock()和Unlock对该变量进行EnterCriticalSectionLeaveCriticalSection,同时,Constructor和Deconstructor分别调用了InitializeCriticalSectionDeleteCriticalSection函数。
CAutoLock是和CCritSec配合使用的Helper类,它在Constructor中接受一个CCritSec的指针,并对其调用Lock函数,而在Deconstructor调用Unlock函数
4.      CAMSchedule[dsschedule.h/schedule.cpp]派生自 CBaseObject
其实此类就是一个List,Node是类型CAdvisePacket。具体解析略。
5.      CBaseReferenceClock[refclock.h/refclock.cpp]继承了IReferenceClock接口,同时派生自CUnknown、CCritSec。
o        成员变量:
REFERENCE_TIME m_rtPrivateTime;     // Current best estimate of time
DWORD          m_dwPrevSystemTime;  // Last vaule we got from timeGetTime
REFERENCE_TIME m_rtLastGotTime;     // Last time returned by GetTime
REFERENCE_TIME m_rtNextAdvise;      // Time of next advise
UINT           m_TimerResolution;
BOOL           m_bAbort;            // Flag used for thread shutdown
HANDLE         m_hThread;           // Thread handle
CAMSchedule * const m_pSchedule; //
任务列表
// 一个Static函数
static DWORD __stdcall AdviseThreadFunction(LPVOID); // Function used to get there
o        IReferenceClock接口函数:
STDMETHODIMP GetTime(REFERENCE_TIME *pTime);
{
     // 首先调用Lock(),然后rtNow = GetPrivateTime();
     // 判断(rtNow > m_rtLastGotTime),是则m_rtLastGotTime = rtNow;否则设置返回值为S_FALSE
     // 设置返回值 *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
);
{
     //
首先初始化输出变量 *pdwAdviseCookie = 0;
     // 判断 ASSERT(WAIT_TIMEOUT == WaitForSingleObject(HANDLE(hEvent),0));
     // 得到当前绝对时间 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
);
{
     //
同样,首先初始化输出变量
     // *pdwAdviseCookie = m_pSchedule->AddAdvisePacket( StartTime, PeriodTime, HANDLE(hSemaphore), TRUE );
}
STDMETHODIMP Unadvise(DWORD_PTR dwAdviseCookie);
{
     return m_pSchedule->Unadvise(dwAdviseCookie);
}
o        新增加的virtual函数:
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        普通成员函数:
/* 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<CBaseReferenceClock*>(p)->AdviseThread());
}
// Method in which the advise thread runs
HRESULT AdviseThread()
{
     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);
         // DON'T 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();
     //
如果m_hThread存在,设置m_bAbort为TRUE后调用TriggerThread(),
     // 然后等Thread结束:WaitForSingleObject( m_hThread, INFINITE );
     // 关闭Thread的handle::EXECUTE_ASSERT( CloseHandle(m_hThread) );
     // m_hThread = 0;
     // 清除任务列表的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)
{
     //
判断m_pSchedule是否为空,如果为空则直接返回错误
     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,         // Thread parameter
            (DWORD) 0,             // Creation flags
            &ThreadID);            // Thread identifier
        if (m_hThread) SetThreadPriority( m_hThread, THREAD_PRIORITY_TIME_CRITICAL );
        else
返回错误并清除m_pSchedule
     }
}
6.      CAMEvent[wxutil.h/wxutil.cpp]
类似于CCritSec,CAMEvent封装了HANDLE m_hEvent;
o        Construction
CAMEvent(BOOL fManualReset = FALSE);
{m_hEvent = CreateEvent(NULL, fManualReset, FALSE, NULL);}
o        Deconstructor
~CAMEvent(){if (m_hEvent) EXECUTE_ASSERT(CloseHandle(m_hEvent));}
o        成员函数很简洁明了
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[wxutil.h/wxutil.cpp]CAMThread稍微复杂一点,同时也是非常实用的一个辅助类。
o        成员变量:
CAMEvent m_EventSend;
CAMEvent m_EventComplete;
DWORD m_dwParam;
DWORD m_dwReturnVal;
HANDLE m_hThread;
CCritSec m_AccessLock; // locks access by client threads
CCritSec m_WorkerLock; // locks access to shared objects
其中,m_EventSend默认为TRUE,m_hThread初始化为NULL。
o        Deconstrutor只调用了Close函数。
o        新增加的virtual函数:
virtual DWORD ThreadProc() = 0;
o        成员函数:
// start thread running  - error if already running
BOOL Create();
{
     CAutoLock lock(&m_AccessLock);
     if (ThreadExists()) {return FALSE;}
     //
创建Thread,返回创建结果
     m_hThread = CreateThread(NULL, 0, CAMThread::InitialThreadProc, this, 0, &threadid);
}
// signal the thread, and block for a response
DWORD CallWorker(DWORD);
{
     CAutoLock lock(&m_AccessLock);
     //
判断ThreadExists函数
     // 设置参数 m_dwParam = dwParam;     // signal the worker thread: m_EventSend.Set();     // 等待该Thread结束 m_EventComplete.Wait();     / 返回结果 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 otherwise
BOOL ThreadExists(void) const {return (m_hThread != 0); }
HANDLE GetRequestHandle() const { return m_EventSend; };
DWORD GetRequestParam() const { return m_dwParam; };
o        以下这几个成员函数是在继承类的ThreadProc中使用的,通过调用这几个函数,Set/Reset Event来实现线程同步。
// wait for the next request
DWORD GetRequest();{m_EventSend.Wait();return m_dwParam;}
// is there a request?
BOOL CheckRequest(DWORD * pParam);
{
     // if (!m_EventSend.Check())return FALSE;
     //
否则设置*pParam = m_dwParam;
}
// reply to the request
void Reply(DWORD);
{
     m_dwReturnVal = dw;
     m_EventSend.Reset();     m_EventComplete.Set();}

o        static成员函数:
// thread initially runs this. param is actually 'this'. Function
// just gets this and calls ThreadProc
static 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 CoInitializeHelper();
{
  //
通过GetModuleHandle(TEXT("ole32.dll"));来直接调用其中函数CoInitializeEx函数。
}

OpenStack建立实例完整过程源码详细分析(1)

研究和学习OpenStack这么长时间了,一直想写写技术博客的,但是由于工作时间的原因,一直没有做到。现在开始从头整理一下以前看的内容,也是对研究过的内容的一个回顾了!     从接触OpenStac...
  • gaoxingnengjisuan
  • gaoxingnengjisuan
  • 2013年06月19日 23:48
  • 21972

srs代码学习(1)--listen建立过程

srs的服务侦听的建立过程。 以rtmp服务为例 srs服务侦听的建立依靠从上到下的三个类。分别是 SrsServer   SrsStreamListener   SrsTcp...
  • wishfly
  • wishfly
  • 2016年10月24日 17:57
  • 1452

MyBatis架构设计及源代码分析系列(一):MyBatis架构

如果不太熟悉MyBatis使用的请先参见MyBatis官方文档,这对理解其架构设计和源码分析有很大好处。 一、概述 MyBatis并不是一个完整的ORM框架,其官方首页是这么介绍自己 T...
  • wangshfa
  • wangshfa
  • 2015年07月01日 19:02
  • 3513

DirectShow 学习之 CSource类和其一个具体实现例子的源代码分析

1.       CSourceStream类,是CSource类的OutputPin[source.h/source.cpp] 派生自CAMThread和CBaseOutputPin l    ...
  • shejingjing
  • shejingjing
  • 2011年09月13日 15:25
  • 290

IPVS源代码分析---app helper的实现

IPVS的应用是针对象FTP等的多连接协议处理的,由于多连接协议的特殊性,任何以连接为基础进行处理的模块如IPVS,netfilter等都必须对这些协议特别处理, 不过IPVS相对没有netfilte...
  • a_jige
  • a_jige
  • 2014年02月26日 16:04
  • 1258

安卓逆向学习笔记(1) - 反编译classes.dex获取apk的java源代码

在上一篇文章中,我记录了apk的文件结构,其中有一个classes.dex文件。classes.dex是apk的核心文件,其运行在安卓Dalvik虚拟机上。通过查看apk的编译生成过程,我们可以得知:...
  • pengyan0812
  • pengyan0812
  • 2015年01月15日 14:35
  • 12367

安卓逆向学习笔记(1) - 反编译classes.dex获取apk的java源代码

原文地址:http://blog.csdn.net/pengyan0812/article/details/42741101 在上一篇文章安卓逆向学习笔记(0)中,我记录...
  • THMAIL
  • THMAIL
  • 2017年07月03日 09:33
  • 296

HGE 系列教材(7) --- 使用 Helper Classes

字体的使用: 1. 头文件 #include 2. 载入字体 hgeFont* pFont; pFont = new hgeFont("font1.fnt"); // 不要忘记 delet...
  • shizhan1881
  • shizhan1881
  • 2012年08月29日 15:20
  • 453

Java类(classes)的学习

  • 2009年06月15日 17:40
  • 12KB
  • 下载

DirectShow 学习笔记&lt; 一&gt; -- 第一个程序 源代码

  • 2013年08月28日 15:52
  • 528KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DirectShow 学习(四) 部分Helper Classes类源代码分析(转载)
举报原因:
原因补充:

(最多只允许输入30个字)