cpacemkr.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:11k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /****************************************************************************
  36.  *  Defines
  37.  */
  38. #define WAIT_TIME_GRANULE 5 // in milliseconds
  39. /****************************************************************************
  40.  *  Includes
  41.  */
  42. #include "hxcom.h"
  43. #include "hxtick.h"
  44. #include "hxassert.h"
  45. #include "hxcomm.h"
  46. #include "hxthread.h"
  47. #include "cpacemkr.h"
  48. #if defined(HELIX_CONFIG_NOSTATICS)
  49. # include "globals/hxglobals.h"
  50. #endif
  51. /****************************************************************************
  52.  *  CVideoPaceMaker             
  53.  */
  54. /****************************************************************************
  55.  *  Statitics
  56.  */
  57. /****************************************************************************
  58.  *  Constructor/Destructor          
  59.  */
  60. CVideoPaceMaker::CVideoPaceMaker(void)
  61.     : m_pThread(NULL)
  62.     , m_pResponse(NULL)
  63.     , m_bActive(FALSE)
  64.     , m_bThreadIdle(FALSE)
  65.     , m_bThreadActive(FALSE)
  66.     , m_bSuspend(FALSE)
  67.     , m_bSuspended(FALSE)
  68.     , m_ulBaseTime(0)
  69.     , m_pEvent(NULL)
  70.     , m_ulInterval(0)
  71.     , m_ulId(0)
  72.     , m_lRefCount(0)
  73. {
  74.     ;
  75. }
  76. CVideoPaceMaker::~CVideoPaceMaker(void)
  77. {
  78.     HX_DELETE(m_pThread);
  79.     HX_RELEASE(m_pResponse);
  80. }
  81. /****************************************************************************
  82.  *  Main Interface               
  83.  */
  84. /****************************************************************************
  85.  *  CVideoPaceMaker::Start               
  86.  */
  87. STDMETHODIMP CVideoPaceMaker::Start(IHXPaceMakerResponse* pResponse,
  88.     LONG32 lPriority,
  89.     ULONG32 ulInterval,
  90.     ULONG32 &ulId)
  91. {
  92.     HX_RESULT retVal = HXR_UNEXPECTED;
  93.     m_bActive = TRUE;
  94.     if ((m_pResponse == NULL) && (m_pThread == NULL))
  95.     {
  96. retVal = HXR_OK;
  97.     }
  98.     if (retVal == HXR_OK)
  99.     {
  100. retVal = HXR_INVALID_PARAMETER;
  101. if (pResponse)
  102. {
  103.     m_pResponse = pResponse;
  104.     pResponse->AddRef();
  105.     retVal = HXR_OK;
  106. }
  107.     }
  108.     if (retVal == HXR_OK)
  109.     {
  110. retVal = HXR_INVALID_PARAMETER;
  111. if (ulInterval != 0)
  112. {
  113.     m_ulInterval = ulInterval;
  114.     retVal = HXR_OK;
  115. }
  116.     }
  117.     if (retVal == HXR_OK)
  118.     {
  119. ulId = m_ulId = GetNextID();
  120. #ifdef THREADS_SUPPORTED        
  121. HXThread::MakeThread(m_pThread);
  122. #else        
  123. HXThread::MakeStubThread(m_pThread);
  124. #endif
  125. retVal = HXR_FAIL;
  126. if (m_pThread)
  127. {
  128.     retVal = HXR_OK;
  129. }
  130.     }
  131. #ifdef THREADS_SUPPORTED        
  132.     if (retVal == HXR_OK)
  133.     {
  134. AddRef();
  135. m_bThreadActive = TRUE;
  136. retVal = m_pThread->CreateThread(ThreadRoutine, 
  137.  (void*) this);
  138. if (FAILED(retVal))
  139. {
  140.     m_bThreadActive = FALSE;
  141.     Release();
  142. }
  143.     }
  144. #endif        
  145.     if (retVal == HXR_OK)
  146.     {
  147. retVal = m_pThread->SetPriority(lPriority);
  148.     }
  149.     if (retVal != HXR_OK)
  150.     {
  151. m_bActive = FALSE;
  152.     }
  153.     return retVal;
  154. }
  155. /****************************************************************************
  156.  *  CVideoPaceMaker::Stop               
  157.  */
  158. STDMETHODIMP CVideoPaceMaker::Stop(void)
  159. {
  160.     HX_RESULT retVal = HXR_UNEXPECTED;
  161.     if (m_bActive)
  162.     {
  163. m_bActive = FALSE;
  164. retVal = HXR_OK;
  165.     }
  166.     return retVal;
  167. }
  168. /****************************************************************************
  169.  *  CVideoPaceMaker::Stop               
  170.  */
  171. STDMETHODIMP CVideoPaceMaker::Suspend(BOOL bSuspend)
  172. {
  173.     HX_RESULT retVal = HXR_UNEXPECTED;
  174.     if ((!(m_bSuspend && bSuspend)) && (bSuspend || m_bSuspend))
  175.     {
  176. m_bSuspend = bSuspend;
  177. retVal = HXR_OK;
  178.     }
  179.     return retVal;
  180. }
  181. HX_RESULT CVideoPaceMaker::Signal(void)
  182. {
  183.     HX_RESULT retVal = HXR_UNEXPECTED;
  184.     if (m_pEvent)
  185.     {
  186. retVal = m_pEvent->SignalEvent();
  187.     }
  188.     return retVal;
  189. }
  190. STDMETHODIMP CVideoPaceMaker::WaitForStop(void)
  191. {
  192.     HX_RESULT retVal = HXR_FAIL;
  193.     HXEvent* pEvent = NULL;
  194. #if defined THREADS_SUPPORTED    
  195.     HXEvent::MakeEvent(pEvent, NULL, TRUE);
  196. #else
  197.     HXEvent::MakeStubEvent(pEvent, NULL, TRUE);
  198. #endif    
  199.     if (pEvent)
  200.     {
  201. retVal = HXR_OK;
  202. while (m_bThreadActive)
  203. {
  204.     pEvent->Wait(WAIT_TIME_GRANULE);
  205. }
  206.     }
  207.     HX_DELETE(pEvent);
  208.     return retVal;
  209. }
  210. STDMETHODIMP CVideoPaceMaker::WaitForSuspend(void)
  211. {
  212.     HX_RESULT retVal = HXR_FAIL;
  213.     HXEvent* pEvent = NULL;
  214. #ifdef THREADS_SUPPORTED    
  215.     HXEvent::MakeEvent(pEvent, NULL, TRUE);
  216. #else
  217.     HXEvent::MakeStubEvent(pEvent, NULL, TRUE);
  218. #endif    
  219.     if (pEvent)
  220.     {
  221. retVal = HXR_OK;
  222. while (m_bThreadActive && (!m_bSuspended))
  223. {
  224.     pEvent->Wait(WAIT_TIME_GRANULE);
  225. }
  226.     }
  227.     HX_DELETE(pEvent);
  228.     return retVal;
  229. }
  230. STDMETHODIMP CVideoPaceMaker::SetPriority(LONG32 lPriority)
  231. {
  232.     HX_RESULT retVal = HXR_UNEXPECTED;
  233.     if (m_pThread)
  234.     {
  235. retVal = m_pThread->SetPriority(lPriority);
  236.     }
  237.     return retVal;
  238. }
  239. STDMETHODIMP CVideoPaceMaker::SetInterval(ULONG32 ulInterval)
  240. {
  241.     m_ulInterval = ulInterval;
  242.     return HXR_OK;
  243. }
  244. /****************************************************************************
  245.  *  Private Methods             
  246.  */
  247. /****************************************************************************
  248.  *  CVideoPaceMaker::OnThreadStart               
  249.  */
  250. void CVideoPaceMaker::OnThreadStart(void)
  251. {
  252.     HX_ASSERT(m_pResponse);
  253.     HX_ASSERT(!m_pEvent);
  254. #ifdef THREADS_SUPPORTED
  255.     HXEvent::MakeEvent(m_pEvent, NULL, TRUE);
  256. #else
  257.     HXEvent::MakeStubEvent(m_pEvent, NULL, TRUE);
  258. #endif    
  259. #ifdef THREADS_SUPPORTED    
  260.     m_pResponse->OnPaceStart(m_ulId);
  261. #endif    
  262. }
  263. /****************************************************************************
  264.  *  CVideoPaceMaker::OnThreadEnd               
  265.  */
  266. void CVideoPaceMaker::OnThreadEnd(void)
  267. {
  268.     HX_ASSERT(m_pResponse);
  269.     HX_DELETE(m_pEvent);
  270. #ifdef THREADS_SUPPORTED    
  271.     m_pResponse->OnPaceEnd(m_ulId);
  272. #endif    
  273.     m_pResponse->Release();
  274.     m_pResponse = NULL;
  275.     m_bThreadActive = FALSE;
  276. }
  277. /****************************************************************************
  278.  *  CVideoPaceMaker::DecoderThreadRoutine               
  279.  */
  280. void* CVideoPaceMaker::ThreadRoutine(void* pArg)
  281. {
  282.     CVideoPaceMaker* pThis = (CVideoPaceMaker*) pArg;
  283.     HX_ASSERT(pThis);
  284.     pThis->OnThreadStart();
  285.     do
  286.     {
  287. pThis->m_bThreadIdle = FALSE;
  288. pThis->m_pResponse->OnPace(pThis->m_ulId);
  289. pThis->m_bThreadIdle = TRUE;
  290. do
  291. {
  292.     if (pThis->m_pEvent->Wait(pThis->m_ulInterval) == HXR_OK)
  293.     {
  294. pThis->m_pEvent->ResetEvent();
  295.     }
  296.     if (pThis->m_bSuspend)
  297.     {
  298. pThis->m_bSuspended = TRUE;
  299.     }
  300.     else
  301.     {
  302. pThis->m_bSuspended = FALSE;
  303.     }
  304. } while (pThis->IsActive() && pThis->IsSuspended());
  305.     } while (pThis->IsActive());
  306.     pThis->OnThreadEnd();
  307.     pThis->Release();
  308.     return NULL;
  309. }
  310. /****************************************************************************
  311. *  IUnknown::AddRef                                            ref:  hxcom.h
  312. *
  313. *  This routine increases the object reference count in a thread safe
  314. *  manner. The reference count is used to manage the lifetime of an object.
  315. *  This method must be explicitly called by the user whenever a new
  316. *  reference to an object is used.
  317. */
  318. STDMETHODIMP_(ULONG32) CVideoPaceMaker::AddRef()
  319. {
  320.     return InterlockedIncrement(&m_lRefCount);
  321. }
  322. /****************************************************************************
  323. *  IUnknown::Release                                           ref:  hxcom.h
  324. *
  325. *  This routine decreases the object reference count in a thread safe
  326. *  manner, and deletes the object if no more references to it exist. It must
  327. *  be called explicitly by the user whenever an object is no longer needed.
  328. */
  329. STDMETHODIMP_(ULONG32) CVideoPaceMaker::Release()
  330. {
  331.     if (InterlockedDecrement(&m_lRefCount) > 0)
  332.     {
  333.         return m_lRefCount;
  334.     }
  335.     
  336.     delete this;
  337.     return 0;
  338. }
  339. /****************************************************************************
  340. *  IUnknown::QueryInterface                                    ref:  hxcom.h
  341. *
  342. *  This routine indicates which interfaces this object supports. If a given
  343. *  interface is supported, the object's reference count is incremented, and
  344. *  a reference to that interface is returned. Otherwise a NULL object and
  345. *  error code are returned. This method is called by other objects to
  346. *  discover the functionality of this object.
  347. */
  348. STDMETHODIMP CVideoPaceMaker::QueryInterface(REFIID riid, void** ppvObj)
  349. {
  350. QInterfaceList qiList[] =
  351. {
  352. { GET_IIDHANDLE(IID_IUnknown), (IUnknown*) this },
  353. { GET_IIDHANDLE(IID_IHXPaceMaker), (IHXPaceMaker*) this },
  354. };
  355.     return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);   
  356. }
  357. LONG32 CVideoPaceMaker::GetNextID()
  358. {
  359. #if defined(HELIX_CONFIG_NOSTATICS)
  360.     const LONG32 zlLastId = 0;
  361.     LONG32& it = HXGlobalInt32::Get(&zlLastId, 0 );
  362.     return InterlockedIncrement(&it);
  363.     
  364. #else
  365.     static LONG32 zlLastId = 0;
  366.     return InterlockedIncrement(&zlLastId);
  367. #endif
  368. }