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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: hxstrm.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 "hlxclib/stdio.h"
  50. #include "hxtypes.h"
  51. #include "hxresult.h"
  52. #include "hxcom.h"
  53. #ifdef _WINDOWS
  54. #include <windows.h>
  55. #endif
  56. #include "ihxpckts.h"
  57. #include "hxfiles.h"
  58. #include "hxengin.h"
  59. #include "hxcore.h"
  60. #include "hxasm.h"
  61. #include "hxgroup.h"
  62. #include "hxplay.h"
  63. #include "hxsmbw.h"
  64. #include "hxprefs.h"
  65. #include "hxslist.h"
  66. #include "hxstring.h"
  67. #include "chxpckts.h"
  68. #include "hxbsrc.h"
  69. #include "hxsrc.h"
  70. #include "hxsmstr.h"
  71. #include "hxstrm.h"
  72. #include "hxstrutl.h"
  73. #include "hxheap.h"
  74. #ifdef _DEBUG
  75. #undef HX_THIS_FILE
  76. static const char HX_THIS_FILE[] = __FILE__;
  77. #endif
  78. HXStream::HXStream() :
  79.      m_lRefCount (0)
  80.     ,m_pSource (NULL)
  81.     ,m_pHeader (NULL)
  82.     ,m_pUnkRenderer(NULL)
  83.     ,m_uStreamNumber(0)
  84.     ,m_ulRegistryID(0)
  85. #if defined(HELIX_FEATURE_ASM)
  86.     ,m_pASMStream(NULL)
  87. #endif /* HELIX_FEATURE_ASM */
  88.     ,m_bPostSeekToBeSent(FALSE)
  89. {
  90. }
  91. HXStream::~HXStream()
  92. {
  93.     if (m_pSource)
  94.     {
  95. m_pSource->Release();
  96.     }
  97.     if (m_pHeader)
  98.     {
  99. m_pHeader->Release();
  100.     }
  101.     if (m_pUnkRenderer)
  102.     {
  103. m_pUnkRenderer->Release();
  104.     }
  105. #if defined(HELIX_FEATURE_ASM)
  106.     HX_RELEASE(m_pASMStream);
  107. #endif /* HELIX_FEATURE_ASM */
  108. }
  109. /////////////////////////////////////////////////////////////////////////
  110. // Method:
  111. // IUnknown::QueryInterface
  112. // Purpose:
  113. // Implement this to export the interfaces supported by your 
  114. // object.
  115. //
  116. STDMETHODIMP HXStream::QueryInterface(REFIID riid, void** ppvObj)
  117. {
  118.     QInterfaceList qiList[] =
  119.         {
  120.             { GET_IIDHANDLE(IID_IHXStream), (IHXStream*)this },
  121.             { GET_IIDHANDLE(IID_IHXRegistryID), (IHXRegistryID*)this },
  122.             { GET_IIDHANDLE(IID_IHXLayoutStream), (IHXLayoutStream*)this },
  123.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXStream*)this },
  124.         };
  125.     
  126.     HX_RESULT res = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  127.     
  128.     // if it succeeded, return immediately...
  129.     if (SUCCEEDED(res))
  130.     {
  131.         return res;
  132.     }
  133.     // ...otherwise proceed
  134.     
  135. #if defined(HELIX_FEATURE_ASM)
  136.     /* Let HXASMStream respond to ASM interface if it wants to. */
  137.     if (m_pASMStream && (HXR_OK == m_pASMStream->QueryInterface(riid, ppvObj)))
  138.     {
  139. return HXR_OK;
  140.     }
  141. #endif /* HELIX_FEATURE_ASM */
  142.     *ppvObj = NULL;
  143.     return HXR_NOINTERFACE;
  144. }
  145. /////////////////////////////////////////////////////////////////////////
  146. // Method:
  147. // IUnknown::AddRef
  148. // Purpose:
  149. // Everyone usually implements this the same... feel free to use
  150. // this implementation.
  151. //
  152. STDMETHODIMP_(ULONG32) HXStream::AddRef()
  153. {
  154.     return InterlockedIncrement(&m_lRefCount);
  155. }
  156. /////////////////////////////////////////////////////////////////////////
  157. // Method:
  158. // IUnknown::Release
  159. // Purpose:
  160. // Everyone usually implements this the same... feel free to use
  161. // this implementation.
  162. //
  163. STDMETHODIMP_(ULONG32) HXStream::Release()
  164. {
  165.     if (InterlockedDecrement(&m_lRefCount) > 0)
  166.     {
  167. return m_lRefCount;
  168.     }
  169.     delete this;
  170.     return 0;
  171. }
  172. /*
  173.  * IHXStream methods
  174.  */
  175. /************************************************************************
  176.  * Method:
  177.  *     IHXStream::GetSource
  178.  * Purpose:
  179.  *     Get the interface to the source object of which the stream is
  180.  *     a part of.
  181.  *
  182.  */
  183. STDMETHODIMP HXStream::GetSource(IHXStreamSource* &pSource)
  184. {
  185.     pSource = m_pSource;
  186.     if (pSource)
  187.     {
  188. pSource->AddRef();
  189.     }
  190.     return HXR_OK;
  191. }
  192. /************************************************************************
  193.  * Method:
  194.  *     IHXStream::GetStreamNumber
  195.  * Purpose:
  196.  *     Get the stream number for this stream relative to the source 
  197.  *     object of which the stream is a part of.
  198.  *
  199.  */
  200. STDMETHODIMP_(UINT16) HXStream::GetStreamNumber(void)
  201. {
  202.     HX_ASSERT(m_pHeader);
  203.     return (UINT16)m_uStreamNumber;
  204. }
  205. /************************************************************************
  206.  * Method:
  207.  *     IHXStream::GetStreamType
  208.  * Purpose:
  209.  *     Get the MIME type for this stream. NOTE: The returned string is
  210.  *     assumed to be valid for the life of the IHXStream from which it
  211.  *     was returned.
  212.  *
  213.  */
  214. STDMETHODIMP_(const char*) HXStream::GetStreamType(void)
  215. {
  216.     HX_ASSERT(m_pHeader);
  217.     IHXBuffer* pMimeTypeBuffer = 0;
  218.     m_pHeader->GetPropertyCString("MimeType",pMimeTypeBuffer);
  219.     HX_ASSERT(pMimeTypeBuffer);
  220.     const char* pMimeTypeString = (const char* )pMimeTypeBuffer->GetBuffer();
  221.     pMimeTypeBuffer->Release();
  222.     return pMimeTypeString;
  223. }
  224. /************************************************************************
  225.  * Method:
  226.  *     IHXStream::GetHeader
  227.  * Purpose:
  228.  *      Get the header for this stream.
  229.  *
  230.  */
  231. STDMETHODIMP_(IHXValues*) HXStream::GetHeader(void)
  232. {
  233.     HX_ASSERT(m_pHeader);
  234.     m_pHeader->AddRef();
  235.     return m_pHeader;
  236. }
  237. /************************************************************************
  238.  * Method:
  239.  *     IHXStream::ReportQualityOfService
  240.  * Purpose:
  241.  *     Call this method to report to the playback context that the 
  242.  *     quality of service for this stream has changed. The unQuality
  243.  *     should be on a scale of 0 to 100, where 100 is the best possible
  244.  *     quality for this stream. Although the transport engine can 
  245.  *     determine lost packets and report these through the user
  246.  *     interface, only the renderer of this stream can determine the 
  247.  *     "real" perceived damage associated with this loss.
  248.  *
  249.  *     NOTE: The playback context may use this value to indicate loss
  250.  *     in quality to the user interface. When the effects of a lost
  251.  *     packet are eliminated the renderer should call this method with
  252.  *     a unQuality of 100.
  253.  *
  254.  */
  255. STDMETHODIMP HXStream::ReportQualityOfService(UINT8 unQuality)
  256. {
  257.     return HXR_NOTIMPL;
  258. }
  259. /************************************************************************
  260.  * Method:
  261.  *     IHXStream::ReportRebufferStatus
  262.  * Purpose:
  263.  *     Call this method to report to the playback context that the
  264.  *     available data has dropped to a critically low level, and that
  265.  *     rebuffering should occur. The renderer should call back into this
  266.  *     interface as it receives additional data packets to indicate the
  267.  *     status of its rebuffering effort.
  268.  *
  269.  *     NOTE: The values of unNeeded and unAvailable are used to indicate
  270.  *     the general status of the rebuffering effort. For example, if a
  271.  *     renderer has "run dry" and needs 5 data packets to play smoothly
  272.  *     again, it should call ReportRebufferStatus() with 5,0 then as
  273.  *     packet arrive it should call again with 5,1; 5,2... and eventually
  274.  *     5,5.
  275.  *
  276.  */
  277. STDMETHODIMP HXStream::ReportRebufferStatus(UINT8 unNeeded, UINT8 unAvailable)
  278. {
  279.     if (m_pSource && m_pHeader)
  280.     {
  281. return m_pSource->ReportRebufferStatus(GetStreamNumber(), 
  282. unNeeded, unAvailable);
  283.     }
  284.     return HXR_OK;
  285. }
  286. STDMETHODIMP
  287. HXStream::SetGranularity (ULONG32 ulGranularity) 
  288. {
  289.     if (m_pSource && m_pHeader)
  290.     {
  291. return m_pSource->SetGranularity(GetStreamNumber(),ulGranularity);
  292.     }
  293.     return HXR_OK;
  294. }
  295. /************************************************************************
  296.  *  Method:
  297.  *    IHXStream::GetRendererCount
  298.  *  Purpose:
  299.  *    Returns the current number of renderer instances supported by
  300.  *    this stream instance.
  301.  */
  302. STDMETHODIMP_(UINT16) HXStream::GetRendererCount()
  303. {
  304.     // In RMA 1.0 there is only one renderer per stream.
  305.     return 1;
  306. }
  307. /************************************************************************
  308.  *  Method:
  309.  *    IHXStream::GetRenderer
  310.  *  Purpose:
  311.  *    Returns the Nth renderer instance supported by this stream.
  312.  */
  313. STDMETHODIMP HXStream::GetRenderer
  314. (
  315.     UINT16 nIndex,
  316.     REF(IUnknown*) pUnknown
  317. )
  318. {
  319.     if (nIndex >= 1)
  320.     {
  321. return HXR_INVALID_PARAMETER;
  322.     }
  323.     pUnknown = m_pUnkRenderer;
  324.     if (pUnknown)
  325.     {
  326. pUnknown->AddRef();
  327. return HXR_OK;
  328.     }
  329.     else
  330.     {
  331. return HXR_FAIL;
  332.     }
  333. }
  334. HX_RESULT    HXStream::Init(HXPlayer* pPlayer, HXSource* pSource, IHXValues* pHeader, 
  335.      IUnknown* pUnkRenderer)
  336. {
  337.     m_pSource     = pSource;
  338.     m_pHeader     = pHeader;
  339.     if (m_pSource)
  340.     {
  341. m_pSource->AddRef();
  342.     }
  343.     if (m_pHeader)
  344.     {
  345. m_pHeader->AddRef();
  346. ULONG32 uStreamNumber = 0;
  347. m_pHeader->GetPropertyULONG32("StreamNumber",uStreamNumber);
  348. m_uStreamNumber = (UINT16) uStreamNumber;
  349.     }
  350. #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
  351.     UINT32 ulSourceID;
  352.     char pStreamEntry[MAX_DISPLAY_NAME]; /* Flawfinder: ignore */
  353.     IHXBuffer* pPropName;
  354.     m_pSource->GetID(ulSourceID);
  355.     m_pSource->m_pRegistry->GetPropName(ulSourceID, pPropName);
  356.     SafeSprintf(pStreamEntry, MAX_DISPLAY_NAME, "%s.Stream%d", pPropName->GetBuffer(), m_uStreamNumber);
  357.     m_ulRegistryID = m_pSource->m_pRegistry->GetId(pStreamEntry);
  358.     HX_ASSERT(m_ulRegistryID);
  359.     pPropName->Release();
  360. #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
  361.     if (pUnkRenderer)
  362.     {
  363. m_pUnkRenderer = pUnkRenderer;
  364. m_pUnkRenderer->AddRef();
  365.     }
  366. #if defined(HELIX_FEATURE_ASM)
  367.     m_pASMStream = new HXASMStream(this, m_pSource);
  368.     if(m_pASMStream)
  369.     {
  370.         m_pASMStream->AddRef();
  371.     }
  372.     else
  373.     {
  374.         return HXR_OUTOFMEMORY;
  375.     }
  376. #endif /* HELIX_FEATURE_ASM */
  377.     return HXR_OK;
  378. }
  379. HX_RESULT
  380. HXStream::SetRenderer(IUnknown* pUnkRenderer)
  381. {
  382.     if (pUnkRenderer && m_pUnkRenderer != pUnkRenderer)
  383.     {
  384. HX_RELEASE(m_pUnkRenderer);
  385. m_pUnkRenderer = pUnkRenderer;
  386. m_pUnkRenderer->AddRef();
  387.     }
  388.     return HXR_OK;
  389. }
  390. /************************************************************************
  391.  * Method:
  392.  *     IHXRegistryID::GetID
  393.  * Purpose:
  394.  *     Get registry ID(hash_key) of the objects(player, source and stream)
  395.  *
  396.  */
  397. STDMETHODIMP
  398. HXStream::GetID(REF(UINT32) /*OUT*/ ulRegistryID)
  399. {
  400.     ulRegistryID = m_ulRegistryID;
  401.    
  402.     return HXR_OK;
  403. }
  404. STDMETHODIMP
  405. HXStream::GetProperties(REF(IHXValues*) pProps)
  406. {
  407.     HX_RESULT     rc = HXR_OK;
  408.     STREAM_INFO*    pStreamInfo = NULL;    
  409.     if (!m_pSource || HXR_OK != m_pSource->GetStreamInfo(m_uStreamNumber, pStreamInfo))
  410.     {
  411. rc = HXR_FAILED;
  412. goto cleanup;
  413.     }
  414.     pProps = pStreamInfo->m_pStreamProps;
  415.     HX_ADDREF(pProps);
  416. cleanup:
  417.     return rc;
  418. }
  419. STDMETHODIMP
  420. HXStream::SetProperties(IHXValues* pProps)
  421. {
  422.     HX_RESULT     rc = HXR_OK;
  423.     UINT32     ulDelay = 0;
  424.     UINT32     ulDuration = 0;
  425.     STREAM_INFO*    pStreamInfo = NULL;
  426.     if (!m_pSource || HXR_OK != m_pSource->GetStreamInfo(m_uStreamNumber, pStreamInfo))
  427.     {
  428. rc = HXR_FAILED;
  429. goto cleanup;
  430.     }
  431.     if (HXR_OK == pProps->GetPropertyULONG32("delay", ulDelay))
  432.     {
  433. m_pSource->UpdateDelay(ulDelay);
  434.     }
  435.     if (HXR_OK == pProps->GetPropertyULONG32("duration", ulDuration))
  436.     {
  437. m_pSource->UpdateDuration(ulDuration);
  438.     }
  439.     HX_RELEASE(pStreamInfo->m_pStreamProps);
  440.     pStreamInfo->m_pStreamProps = pProps;
  441.     HX_ADDREF(pStreamInfo->m_pStreamProps);
  442. cleanup:
  443.     return rc;
  444. }
  445. HX_RESULT
  446. HXStream::ResetASMSource(IHXASMSource* pASMSource)
  447. {
  448.     HX_RESULT hr = HXR_OK;
  449. #if defined(HELIX_FEATURE_ASM)
  450.     if (!m_pASMStream)
  451.     {
  452. hr = HXR_FAILED;
  453. goto cleanup;
  454.     }
  455.     hr = m_pASMStream->ResetASMSource(pASMSource);
  456. cleanup:
  457. #endif /* HELIX_FEATURE_ASM */
  458.     return hr;
  459. }
  460. BOOL
  461. HXStream::IsTimeStampDelivery()
  462. {
  463.     BOOL bTimeStampDelivered = FALSE;
  464. #if defined(HELIX_FEATURE_ASM)
  465.     if (m_pASMStream)
  466.     {
  467. bTimeStampDelivered = m_pASMStream->IsTimeStampDelivery();
  468.     }
  469. #endif /* HELIX_FEATURE_ASM */
  470.     return bTimeStampDelivered;
  471. }
  472. void
  473. HXStream::PostEndTimePacket(IHXPacket* pPacket, BOOL& bSentMe, BOOL& bEndMe)
  474. {
  475.     bSentMe = TRUE;
  476.     bEndMe = TRUE;
  477. #if defined(HELIX_FEATURE_ASM)
  478.     if (!pPacket || !m_pASMStream)
  479.     {
  480. goto cleanup;
  481.     }
  482.     m_pASMStream->PostEndTimePacket(pPacket, bSentMe, bEndMe);
  483. cleanup:
  484. #endif /* HELIX_FEATURE_ASM */
  485.     return;
  486. }
  487.     
  488. void
  489. HXStream::ResetASMRuleState(void)
  490. {
  491. #if defined(HELIX_FEATURE_ASM)
  492.     if (m_pASMStream)
  493.     {
  494. m_pASMStream->ResetASMRuleState();
  495.     }
  496. #endif /* HELIX_FEATURE_ASM */
  497.     return;
  498. }
  499. HXSource*
  500. HXStream::GetHXSource(void)
  501. {
  502.     if (m_pSource)
  503.     {
  504. m_pSource->AddRef(); 
  505.     }
  506.     return m_pSource;
  507. }
  508. BOOL
  509. HXStream::IsSureStream(void)
  510. {
  511.     UINT32 ulThresholds = 0;
  512. #if defined(HELIX_FEATURE_ASM)
  513.     if (m_pASMStream)
  514.     {
  515. ulThresholds = m_pASMStream->GetNumThresholds();
  516. if (ulThresholds > 1)
  517. {
  518.     return TRUE;
  519. }
  520.     }
  521. #endif /* HELIX_FEATURE_ASM */
  522.     return FALSE;
  523. }