cpacemkr.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:11k
源码类别:

Symbian

开发平台:

Visual C++

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