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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: vdclback.cpp,v 1.1.36.1 2004/07/09 01:55:25 hubbe 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.  *         Class Implementation for CQTVideoRenderer::CVideoSchedulerCallback
  51.  */
  52. #include "hxtypes.h"
  53. #include "hxwintyp.h"
  54. #include "hxresult.h"
  55. #include "hxcom.h"
  56. #include "hxevent.h"
  57. #include "hxcomm.h"
  58. #include "hxengin.h"
  59. #include "hxerror.h"
  60. #include "hxtick.h"
  61. #include "hxassert.h"
  62. #include "timeval.h"
  63. #include "vdclback.h"
  64. CVideoSchedulerCallback::CVideoSchedulerCallback
  65. (
  66.     FP_CALLBACK pFunc,
  67.     void* cookie,
  68.     IUnknown* pIUnknown,
  69.     BOOL bUseOptimizedScheduler
  70. )
  71.     : m_lRefCount(0) 
  72.     , m_pScheduler(NULL)
  73.     , m_pFunc(pFunc)
  74.     , m_pOptimizedScheduler(NULL)
  75.     , m_bPendingCallback(FALSE)
  76.     , m_bInCallback(FALSE)
  77.     , m_PendingHandle(0)
  78.     , m_bIsInterruptSafe(bUseOptimizedScheduler)
  79.     , m_cookie(cookie)
  80. {
  81.     if (bUseOptimizedScheduler)
  82.     {
  83.         if (HXR_OK != pIUnknown->QueryInterface(IID_IHXOptimizedScheduler, 
  84. (void **) &m_pOptimizedScheduler))
  85.         {
  86.          // just for good luck
  87.     m_pOptimizedScheduler = NULL;
  88. }
  89.     }
  90.     if (m_pOptimizedScheduler == NULL)
  91.     {
  92. if (HXR_OK != pIUnknown->QueryInterface(IID_IHXScheduler, 
  93. (void **) &m_pScheduler))
  94. {
  95.     m_pScheduler = NULL;
  96. }
  97.     }
  98. }
  99. STDMETHODIMP
  100. CVideoSchedulerCallback::Close()
  101. {
  102.     // the optimized scheduler has presidence so we check it first
  103.     if (m_bPendingCallback && m_pOptimizedScheduler)
  104.     {
  105. m_pOptimizedScheduler->Remove(m_PendingHandle);
  106. m_bPendingCallback = FALSE;
  107. m_PendingHandle = 0;
  108.     }
  109.     HX_RELEASE(m_pOptimizedScheduler);
  110.     if (m_bPendingCallback && m_pScheduler)
  111.     {
  112. m_pScheduler->Remove(m_PendingHandle);
  113. m_bPendingCallback = FALSE;
  114. m_PendingHandle = 0;
  115.     }
  116.     HX_RELEASE(m_pScheduler);
  117.     return HXR_OK;
  118. }
  119. CVideoSchedulerCallback::~CVideoSchedulerCallback()
  120. {
  121.     Close();
  122. }
  123. STDMETHODIMP
  124. CVideoSchedulerCallback::ScheduleCallback
  125. (
  126.     UINT32 ulRelativeTime, 
  127.     UINT32 ulTicksTime
  128. )
  129. {
  130.     // this new callback is going to take presidence over the
  131.     // current one so remove it.
  132.     if (m_pOptimizedScheduler != NULL || m_pScheduler != NULL)
  133.     {
  134. IHXCallback* pCallback = NULL;
  135. if (HXR_OK == QueryInterface(IID_IHXCallback, (void**)&pCallback))
  136. {
  137.     HXTimeval lTime;
  138.     // Always use the optimized scheduler if we have one
  139.     if (m_pOptimizedScheduler != NULL)
  140.     {
  141. lTime = m_pOptimizedScheduler->GetCurrentSchedulerTime();
  142.     }
  143.     else
  144.     {
  145. lTime = m_pScheduler->GetCurrentSchedulerTime();
  146.     }
  147.     UINT32 ulCurrentTime = HX_GET_BETTERTICKCOUNT();
  148.     // if ulTicksTime is in the future, add the difference to lTime,
  149.     // if it's in the past, don't add anything to lTime so we schedule
  150.     // an imediate callback.
  151.     if (ulCurrentTime < ulTicksTime)
  152.     {
  153. UINT32 ulTimeDiff = CALCULATE_ELAPSED_TICKS(ulCurrentTime,
  154.     ulTicksTime);
  155. lTime.tv_usec += ulTimeDiff * MILLISECOND;
  156. if (lTime.tv_usec >= SECOND)
  157. {
  158.     lTime.tv_sec += lTime.tv_usec / SECOND;
  159.     lTime.tv_usec %= SECOND;
  160. }
  161.     }
  162.     
  163.     // we want to do the right thing here and remove a callback before we schedule a new one
  164.     // but we should never do that.
  165.     HX_ASSERT(!m_bPendingCallback);
  166.     if (m_bPendingCallback)
  167.     {
  168. // Always use the optimized scheduler if we have one
  169. if (m_pOptimizedScheduler != NULL)
  170. {
  171.     m_pOptimizedScheduler->Remove(m_PendingHandle);
  172. }
  173. else if (m_pScheduler)
  174. {
  175.     m_pScheduler->Remove(m_PendingHandle);
  176. }
  177.     }
  178.     
  179.     m_bPendingCallback = TRUE;
  180.     // Always use the optimized scheduler if we have one
  181.     if (m_pOptimizedScheduler != NULL)
  182.     {
  183.         m_PendingHandle = m_pOptimizedScheduler->AbsoluteEnter(pCallback, lTime);
  184.     }
  185.     else
  186.     {
  187.         m_PendingHandle = m_pScheduler->AbsoluteEnter(pCallback, lTime);
  188.     }
  189. }
  190. HX_RELEASE(pCallback);
  191.     }
  192.     return HXR_OK;
  193. }
  194. STDMETHODIMP
  195. CVideoSchedulerCallback::Func(void)
  196. {
  197.     m_bInCallback = TRUE;
  198.     if (m_pFunc != NULL )
  199.     {
  200. HX_ASSERT(m_bPendingCallback);
  201. HXTimeval lTime;
  202. // Always use the optimized scheduler if we have one
  203. if (m_pOptimizedScheduler != NULL)
  204. {
  205.     lTime = m_pOptimizedScheduler->GetCurrentSchedulerTime();
  206. }
  207. else
  208. {
  209.     lTime = m_pScheduler->GetCurrentSchedulerTime();
  210. }
  211. m_PendingHandle = 0;
  212. m_bPendingCallback = FALSE;
  213. m_pFunc(m_cookie);
  214.     }
  215.     m_bInCallback = FALSE;
  216.     return HXR_OK;
  217. }
  218. STDMETHODIMP_(BOOL)
  219. CVideoSchedulerCallback::ShouldKickStartScheduler()
  220. {
  221.     return !(m_bPendingCallback || (!m_bPendingCallback && m_bInCallback));
  222. }
  223. /////////////////////////////////////////////////////////////////////////
  224. //  Method:
  225. //      IUnknown::QueryInterface
  226. //  Purpose:
  227. //      Implement this to export the interfaces supported by your 
  228. //      object.
  229. //
  230. STDMETHODIMP 
  231. CVideoSchedulerCallback::QueryInterface
  232. (
  233.     REFIID riid, 
  234.     void** ppvObj
  235. )
  236. {
  237.     if (IsEqualIID(riid, IID_IUnknown))
  238.     {
  239. AddRef();
  240. *ppvObj = this;
  241. return HXR_OK;
  242.     }
  243.     else if (IsEqualIID(riid, IID_IHXCallback))
  244.     {
  245. AddRef();
  246. *ppvObj = (IHXCallback*)this;
  247. return HXR_OK;
  248.     }
  249.     else if (IsEqualIID(riid, IID_IHXInterruptSafe))
  250.     {
  251. AddRef();
  252. *ppvObj = (IHXInterruptSafe*)this;
  253. return HXR_OK;
  254.     }
  255.     *ppvObj = NULL;
  256.     return HXR_NOINTERFACE;
  257. }
  258. /////////////////////////////////////////////////////////////////////////
  259. //  Method:
  260. //      IUnknown::AddRef
  261. //  Purpose:
  262. //      Everyone usually implements this the same... feel free to use
  263. //      this implementation.
  264. //
  265. STDMETHODIMP_(ULONG32) 
  266. CVideoSchedulerCallback::AddRef()
  267. {
  268.     return InterlockedIncrement(&m_lRefCount);
  269. }
  270. /////////////////////////////////////////////////////////////////////////
  271. //  Method:
  272. //      IUnknown::Release
  273. //  Purpose:
  274. //      Everyone usually implements this the same... feel free to use
  275. //      this implementation.
  276. //
  277. STDMETHODIMP_(ULONG32)
  278. CVideoSchedulerCallback::Release()
  279. {
  280.     if (InterlockedDecrement(&m_lRefCount) > 0)
  281.     {
  282. return m_lRefCount;
  283.     }
  284.     delete this;
  285.     return 0;
  286. }
  287. STDMETHODIMP_(BOOL)
  288. CVideoSchedulerCallback::IsInterruptSafe()
  289. {
  290.     return m_bIsInterruptSafe;
  291. }