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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: recordctl.cpp,v 1.8.20.1 2004/07/09 02:05:58 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. #include "recordctl.h"
  50. #include "ihxpckts.h"
  51. #include "hxrecord.h"
  52. #include "hxheap.h"
  53. #ifdef _DEBUG
  54. #undef HX_THIS_FILE             
  55. static const char HX_THIS_FILE[] = __FILE__;
  56. #endif
  57. HXRecordControl::HXRecordControl(IUnknown* pUnkPlayer, IUnknown* pUnkSource) :
  58.     m_lRefCount(0),
  59.     m_pRecordSource(NULL),
  60.     m_pRecordService(NULL),
  61.     m_bCanGetPackets(FALSE)
  62. {
  63.     SPIHXRecordManager spRecordManager = pUnkPlayer;
  64.     if(spRecordManager.IsValid())
  65. spRecordManager->GetRecordService(m_pRecordService);
  66.     if(m_pRecordService)
  67. m_pRecordService->CreateRecordSource(pUnkSource, m_pRecordSource);
  68.     if(m_pRecordSource)
  69.     {
  70. if(m_pRecordSource->SetFormatResponse(this) == HXR_OK)
  71.     m_bCanGetPackets = TRUE;
  72.     }
  73. }
  74. HXRecordControl::~HXRecordControl()
  75. {
  76.     Cleanup();
  77. }
  78. STDMETHODIMP 
  79. HXRecordControl::QueryInterface(REFIID riid, void** ppvObj)
  80. {
  81.     QInterfaceList qiList[] =
  82.         {
  83.             { GET_IIDHANDLE(IID_IHXFormatResponse), (IHXFormatResponse*)this },
  84.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXFormatResponse*)this },
  85.         };
  86.     
  87.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  88. }
  89. STDMETHODIMP_(ULONG32) 
  90. HXRecordControl::AddRef()
  91. {
  92.     return InterlockedIncrement(&m_lRefCount);
  93. }
  94. STDMETHODIMP_(ULONG32) 
  95. HXRecordControl::Release()
  96. {
  97.     if (InterlockedDecrement(&m_lRefCount) > 0)
  98.     {
  99. return m_lRefCount;
  100.     }
  101.     delete this;
  102.     return 0;
  103. }
  104. void
  105. HXRecordControl::Cleanup()
  106. {
  107.     for(UINT16 nStream = 0; nStream < m_PendingGetPackets.GetSize(); nStream++)
  108.     {
  109. IHXPacket* pPacket = (IHXPacket*)m_PendingGetPackets.GetAt(nStream);
  110. m_PendingGetPackets.SetAt(nStream, NULL);
  111. HX_RELEASE(pPacket);
  112.     }
  113.     if(m_pRecordService)
  114. m_pRecordService->CloseRecordSource(m_pRecordSource);
  115.     HX_RELEASE(m_pRecordService);
  116.     HX_RELEASE(m_pRecordSource);
  117.     while(!m_PendingPutPackets.IsEmpty())
  118.     {
  119. PendingPutPacket* pPutPacket = (PendingPutPacket*)m_PendingPutPackets.RemoveHead();
  120. HX_ASSERT(pPutPacket);
  121. HX_RELEASE(pPutPacket->pPacket);
  122. HX_DELETE(pPutPacket);
  123.     }
  124. }
  125. STDMETHODIMP
  126. HXRecordControl::PacketReady(HX_RESULT status, IHXPacket* pPacket)
  127. {
  128.     if(pPacket)
  129.     {
  130. pPacket->AddRef();
  131. if(pPacket->GetStreamNumber() < m_PendingGetPackets.GetSize())
  132.     HX_ASSERT(!m_PendingGetPackets.GetAt(pPacket->GetStreamNumber()));
  133. m_PendingGetPackets.SetAt(pPacket->GetStreamNumber(), pPacket);
  134.     }
  135.     return HXR_OK;
  136. }
  137. HX_RESULT
  138. HXRecordControl::Seek(ULONG32 seekTime)
  139. {
  140.     if(!m_pRecordSource)
  141. return HXR_NOT_INITIALIZED;
  142.     HX_RESULT nResult = HXR_FAILED;
  143.     if(m_bCanGetPackets)
  144.     {
  145. nResult = m_pRecordSource->Seek(seekTime);
  146. if(nResult == HXR_OK)
  147. {
  148.     for(UINT16 nStream = 0; nStream < m_PendingGetPackets.GetSize(); nStream++)
  149.     {
  150. IHXPacket* pPacket = (IHXPacket*)m_PendingGetPackets.GetAt(nStream);
  151. m_PendingGetPackets.SetAt(nStream, NULL);
  152. HX_RELEASE(pPacket);
  153. // If seek succeeded the first GetPacket() for each stream should not fail. 
  154. // In case of metafiles though no packets should be send to renderers again.
  155. // Therefore GetPacket() fails in case of metafiles. SB.
  156. m_pRecordSource->GetPacket(nStream);
  157.     }
  158. }
  159.     }
  160.     if(nResult != HXR_OK)
  161.     {
  162. m_pRecordSource->Flush();
  163. for(UINT16 nStream = 0; nStream < m_PendingGetPackets.GetSize(); nStream++)
  164. {
  165.     IHXPacket* pPacket = (IHXPacket*)m_PendingGetPackets.GetAt(nStream);
  166.     m_PendingGetPackets.SetAt(nStream, NULL);
  167.     HX_RELEASE(pPacket);
  168. }
  169.     }
  170.     return nResult;
  171. }
  172. HX_RESULT
  173. HXRecordControl::GetPacket(UINT16 usStreamNumber, IHXPacket*& pPacket)
  174. {
  175.     pPacket = NULL;
  176.     if(!m_pRecordSource || !m_bCanGetPackets)
  177. return HXR_FAILED;
  178.     if (m_PendingGetPackets.IsEmpty())
  179.         return HXR_NO_DATA;
  180.     
  181.     HX_RESULT nResult = HXR_OK;
  182.     pPacket = (IHXPacket*)m_PendingGetPackets.GetAt(usStreamNumber);
  183.     if(!pPacket)
  184.     {
  185. nResult = m_pRecordSource->GetPacket(usStreamNumber);
  186. if(nResult == HXR_OK)
  187. {
  188.     pPacket = (IHXPacket*)m_PendingGetPackets.GetAt(usStreamNumber);
  189.     if(!pPacket)
  190. nResult = HXR_WOULD_BLOCK;
  191. }
  192.     }
  193.     m_PendingGetPackets.SetAt(usStreamNumber, NULL);
  194.     return nResult;
  195. }
  196. HX_RESULT
  197. HXRecordControl::OnFileHeader(IHXValues* pValues)
  198. {
  199.     UINT32 nStreamCount = 0;
  200.     if(pValues)
  201. pValues->GetPropertyULONG32("StreamCount", nStreamCount);
  202.     if(nStreamCount)
  203.     {
  204. m_PendingGetPackets.SetSize(nStreamCount);
  205. for(UINT16 nStream = 0; nStream < nStreamCount; nStream++)
  206.     m_PendingGetPackets.SetAt(nStream, NULL);
  207.     }
  208.     HX_RESULT nResult = HXR_FAILED;
  209.     if(m_pRecordSource)
  210. nResult = m_pRecordSource->OnFileHeader(pValues);
  211.     if(nResult != HXR_OK && nResult != HXR_RECORD)
  212. Cleanup();
  213.     return nResult;
  214. }
  215. HX_RESULT
  216. HXRecordControl::OnStreamHeader(IHXValues* pValues)
  217. {
  218.     HX_RESULT nResult = HXR_FAILED;
  219.     if(m_pRecordSource)
  220. nResult = m_pRecordSource->OnStreamHeader(pValues);
  221.     if(nResult != HXR_OK && nResult != HXR_RECORD)
  222. Cleanup();
  223.     return nResult;
  224. }
  225. HX_RESULT
  226. HXRecordControl::OnPacket(IHXPacket* pPacket, INT32 nTimeOffset)
  227. {
  228.     HX_RESULT nResult = HXR_FAILED;
  229.     if(pPacket && m_pRecordSource)
  230.     {
  231. if(m_PendingPutPackets.GetCount())
  232.     nResult = HXR_RETRY;
  233. else
  234.     nResult = m_pRecordSource->OnPacket(pPacket, nTimeOffset);
  235. if(nResult == HXR_RETRY)
  236. {
  237.     PendingPutPacket* pPutPacket = new PendingPutPacket;
  238.     if(!pPutPacket)
  239. return HXR_OUTOFMEMORY;
  240.     pPutPacket->pPacket = pPacket;
  241.     pPutPacket->pPacket->AddRef();
  242.     pPutPacket->nTimeOffset = nTimeOffset;
  243.     m_PendingPutPackets.AddTail(pPutPacket);
  244.     nResult = HXR_OK;
  245. }
  246.     }
  247.     if(nResult != HXR_OK)
  248. Cleanup();
  249.     return nResult;
  250. }
  251. BOOL
  252. HXRecordControl::CanAcceptPackets()
  253. {
  254.     if(!m_pRecordSource)
  255. return FALSE;
  256.     while(!m_PendingPutPackets.IsEmpty())
  257.     {
  258. PendingPutPacket* pPutPacket = (PendingPutPacket*)m_PendingPutPackets.GetHead();
  259. HX_ASSERT(pPutPacket);
  260. if(m_pRecordSource->OnPacket(pPutPacket->pPacket, pPutPacket->nTimeOffset) == HXR_RETRY)
  261.     return FALSE;
  262. HX_RELEASE(pPutPacket->pPacket);
  263. HX_DELETE(pPutPacket);
  264. m_PendingPutPackets.RemoveHead();
  265.     }
  266.     return TRUE;
  267. }
  268. void
  269. HXRecordControl::SetSource(IUnknown* pUnkSource)
  270. {
  271.     if(m_pRecordSource)
  272. m_pRecordSource->SetSource(pUnkSource);
  273. }
  274. void
  275. HXRecordControl::OnEndOfPackets()
  276. {
  277.     if(m_pRecordSource)
  278. m_pRecordSource->OnEndOfPackets();
  279. }