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

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