分享
 
 
 

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

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

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));}

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;

};

CCritSec和CAutoLock类[wxutil.h/wxutil.cpp]

CCritSec封装了CRITICAL_SECTION m_CritSec;成员变量,通过函数Lock()和Unlock对该变量进行EnterCriticalSection和LeaveCriticalSection,同时,Constructor和Deconstructor分别调用了InitializeCriticalSection和DeleteCriticalSection函数。

CAutoLock是和CCritSec配合使用的Helper类,它在Constructor中接受一个CCritSec的指针,并对其调用Lock函数,而在Deconstructor调用Unlock函数。

CAMSchedule类[dsschedule.h/schedule.cpp]

派生自 CBaseObject

其实此类就是一个List,Node是类型CAdvisePacket。具体解析略。

CBaseReferenceClock类[refclock.h/refclock.cpp]

继承了IReferenceClock接口,同时派生自CUnknown、CCritSec。

成员变量:

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

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);

}

新增加的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;

}

普通成员函数:

/* 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);

}

}

Deconstructor:

CBaseReferenceClock::~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()) );

}

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

}

}

CAMEvent类[wxutil.h/wxutil.cpp]

类似于CCritSec,CAMEvent封装了HANDLE m_hEvent;

Construction:

CAMEvent(BOOL fManualReset = FALSE);

{m_hEvent = CreateEvent(NULL, fManualReset, FALSE, NULL);}

Deconstructor

~CAMEvent(){if (m_hEvent) EXECUTE_ASSERT(CloseHandle(m_hEvent));}

成员函数很简洁明了

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); };

CAMThread类[wxutil.h/wxutil.cpp]

CAMThread稍微复杂一点。

成员变量:

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。

Deconstrutor只调用了Close函数。

新增加的virtual函数:

virtual DWORD ThreadProc() = 0;

成员函数:

// 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); }

// 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();

}

HANDLE GetRequestHandle() const { return m_EventSend; };

DWORD GetRequestParam() const { return m_dwParam; };

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函数。

}

下几个部分将结合DirectShow中自带的例子分析CSource、CTransform和Render等类的源代码。

上一篇:学习(三) CBaseFilter类源代码解析

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有