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

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. #if defined(HELIX_FEATURE_MEDIAMARKER)
  36. // include
  37. #include "hxtypes.h"
  38. #include "hxcom.h"
  39. #include "hxresult.h"
  40. #include "hxengin.h"
  41. #include "hxcore.h"
  42. #include "hxgroup.h"
  43. #include "hxmmrkr.h"
  44. // pncont
  45. #include "hxslist.h"
  46. #include "hxmap.h"
  47. // rmacore
  48. #include "hxplay.h"
  49. #include "hxcleng.h"
  50. #include "mediamrk.h"
  51. // pndebug
  52. #include "hxheap.h"
  53. #ifdef _DEBUG
  54. #undef HX_THIS_FILE             
  55. static const char HX_THIS_FILE[] = __FILE__;
  56. #endif
  57. CMarkerInfo::CMarkerInfo(IHXBuffer* pURLStr,
  58.                          IHXBuffer* pNameStr,
  59.                          UINT32      ulTime,
  60.                          IHXValues* pOtherParams)
  61. {
  62.     m_pURLStr      = pURLStr;
  63.     m_pNameStr     = pNameStr;
  64.     m_ulTime       = ulTime;
  65.     m_pOtherParams = pOtherParams;
  66.     if (m_pURLStr)      m_pURLStr->AddRef();
  67.     if (m_pNameStr)     m_pNameStr->AddRef();
  68.     if (m_pOtherParams) m_pOtherParams->AddRef();
  69. }
  70. CMarkerInfo::~CMarkerInfo()
  71. {
  72.     HX_RELEASE(m_pURLStr);
  73.     HX_RELEASE(m_pNameStr);
  74.     HX_RELEASE(m_pOtherParams);
  75. }
  76. CHXMediaMarkerManager::CHXMediaMarkerManager(HXPlayer* pPlayer)
  77. {
  78.     m_lRefCount   = 0;
  79.     m_pPlayer     = pPlayer;
  80.     m_pMarkerList = NULL;
  81.     m_pSinkList   = NULL;
  82.     if (m_pPlayer)
  83.     {
  84.         m_pPlayer->AddRef();
  85.     }
  86. }
  87. CHXMediaMarkerManager::~CHXMediaMarkerManager()
  88. {
  89.     Close();
  90. }
  91. STDMETHODIMP CHXMediaMarkerManager::QueryInterface(REFIID riid, void** ppvObj)
  92. {
  93.     HX_RESULT retVal = HXR_OK;
  94.     if (ppvObj)
  95.     {
  96.         QInterfaceList qiList[] =
  97.             {
  98.                 { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXMediaMarkerManager*)this },
  99.                 { GET_IIDHANDLE(IID_IHXMediaMarkerManager), (IHXMediaMarkerManager*)this },
  100.             };
  101.         
  102.         retVal = ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  103.     }
  104.     else
  105.     {
  106.         retVal = HXR_FAIL;
  107.     }
  108.     return retVal;
  109. }
  110. STDMETHODIMP_(ULONG32) CHXMediaMarkerManager::AddRef()
  111. {
  112.     return InterlockedIncrement(&m_lRefCount);
  113. }
  114. STDMETHODIMP_(ULONG32) CHXMediaMarkerManager::Release()
  115. {
  116.     if (InterlockedDecrement(&m_lRefCount) > 0)
  117.     {
  118.         return m_lRefCount;
  119.     }
  120.     delete this;
  121.     return 0;
  122. }
  123. STDMETHODIMP CHXMediaMarkerManager::Close()
  124. {
  125.     HX_RESULT retVal = HXR_OK;
  126.     HX_RELEASE(m_pPlayer);
  127.     ClearMarkerList();
  128.     ClearSinkList();
  129.     return retVal;
  130. }
  131. STDMETHODIMP CHXMediaMarkerManager::AddMediaMarkerSink(IHXMediaMarkerSink* pSink)
  132. {
  133.     HX_RESULT retVal = HXR_FAIL;
  134.     if (pSink)
  135.     {
  136.         // Do we have a list?
  137.         if (!m_pSinkList)
  138.         {
  139.             m_pSinkList = new CHXSimpleList();
  140.         }
  141.         if (m_pSinkList)
  142.         {
  143.             // Make sure this sink is not already on the list
  144.             if (!WasSinkAdded(pSink))
  145.             {
  146.                 // AddRef before we put it on the list
  147.                 pSink->AddRef();
  148.                 // Now put this sink on the tail of the list
  149.                 m_pSinkList->AddTail((void*) pSink);
  150.                 // Clear the return value
  151.                 retVal = HXR_OK;
  152.             }
  153.         }
  154.     }
  155.     return retVal;
  156. }
  157. STDMETHODIMP CHXMediaMarkerManager::RemoveMediaMarkerSink(IHXMediaMarkerSink* pSink)
  158. {
  159.     HX_RESULT retVal = HXR_OK;
  160.     if (pSink)
  161.     {
  162.         if (m_pSinkList)
  163.         {
  164.             LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  165.             while (pos)
  166.             {
  167.                 IHXMediaMarkerSink* pListSink =
  168.                     (IHXMediaMarkerSink*) m_pSinkList->GetAt(pos);
  169.                 if (pListSink == pSink)
  170.                 {
  171.                     m_pSinkList->RemoveAt(pos);
  172.                     HX_RELEASE(pListSink);
  173.                     break;
  174.                 }
  175.                 m_pSinkList->GetNext(pos);
  176.             }
  177.         }
  178.     }
  179.     else
  180.     {
  181.         retVal = HXR_FAIL;
  182.     }
  183.     return retVal;
  184. }
  185. STDMETHODIMP CHXMediaMarkerManager::AddMediaMarkerSinkFilter(IHXMediaMarkerSink* pSink,
  186.                                                               IHXValues*          pFilter)
  187. {
  188.     HX_RESULT retVal = HXR_NOTIMPL;
  189.     return retVal;
  190. }
  191. STDMETHODIMP CHXMediaMarkerManager::ResolveMarker(IHXBuffer* pURLStr,
  192.                                                    IHXBuffer* pMarkerNameStr,
  193.                                                    UINT32      ulTime,
  194.                                                    IHXValues* pOtherMarkerParams)
  195. {
  196.     HX_RESULT retVal = HXR_FAIL;
  197.     if (pURLStr && pMarkerNameStr)
  198.     {
  199.         // Create a CMarkerInfo struct
  200.         CMarkerInfo* pInfo = new CMarkerInfo(pURLStr, pMarkerNameStr,
  201.                                              ulTime, pOtherMarkerParams);
  202.         if (pInfo)
  203.         {
  204.             // Add the marker to all our data structures. This method
  205.             // will fail if an identical marker is already present
  206.             retVal = AddMarkerInfo(pInfo);
  207.             if (SUCCEEDED(retVal))
  208.             {
  209.                 // Now we need to broadcast this marker to
  210.                 // all the sinks who haven't filtered this
  211.                 // marker out. 
  212.                 BroadcastMarkerToSinks(pInfo);
  213.             }
  214.             else
  215.             {
  216.                 HX_DELETE(pInfo);
  217.             }
  218.         }
  219.     }
  220.     return retVal;
  221. }
  222. STDMETHODIMP_(BOOL) CHXMediaMarkerManager::IsMarkerResolved(IHXBuffer* pURLStr,
  223.                                                              IHXBuffer* pMarkerNameStr)
  224. {
  225.     HX_RESULT retVal = HXR_NOTIMPL;
  226.     return retVal;
  227. }
  228. STDMETHODIMP CHXMediaMarkerManager::GetFirstMarker(IHXMediaMarkerSink* pSink,
  229.                                                     REF(IHXBuffer*)     rpURLStr,
  230.                                                     REF(IHXBuffer*)     rpMarkerNameStr,
  231.                                                     REF(UINT32)          rulTime,
  232.                                                     REF(IHXValues*)     rpOtherMarkerParams)
  233. {
  234.     HX_RESULT retVal = HXR_NOTIMPL;
  235.     return retVal;
  236. }
  237. STDMETHODIMP CHXMediaMarkerManager::GetNextMarker(IHXMediaMarkerSink* pSink,
  238.                                                    REF(IHXBuffer*)     rpURLStr,
  239.                                                    REF(IHXBuffer*)     rpMarkerNameStr,
  240.                                                    REF(UINT32)          rulTime,
  241.                                                    REF(IHXValues*)     rpOtherMarkerParams)
  242. {
  243.     HX_RESULT retVal = HXR_NOTIMPL;
  244.     return retVal;
  245. }
  246. void CHXMediaMarkerManager::ClearMarkerList()
  247. {
  248.     if (m_pMarkerList)
  249.     {
  250.         // Run through the list, freeing the marker objects
  251.         LISTPOSITION pos = m_pMarkerList->GetHeadPosition();
  252.         while (pos)
  253.         {
  254.             CMarkerInfo* pInfo = (CMarkerInfo*) m_pMarkerList->GetNext(pos);
  255.             HX_DELETE(pInfo);
  256.         }
  257.         m_pMarkerList->RemoveAll();
  258.         HX_DELETE(m_pMarkerList);
  259.     }
  260. }
  261. void CHXMediaMarkerManager::ClearSinkList()
  262. {
  263.     if (m_pSinkList)
  264.     {
  265.         // Run through the list, releasing the sinks
  266.         LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  267.         while (pos)
  268.         {
  269.             IHXMediaMarkerSink* pSink = (IHXMediaMarkerSink*) m_pSinkList->GetNext(pos);
  270.             HX_RELEASE(pSink);
  271.         }
  272.         m_pSinkList->RemoveAll();
  273.         HX_DELETE(m_pSinkList);
  274.     }
  275. }
  276. BOOL CHXMediaMarkerManager::WasSinkAdded(IHXMediaMarkerSink* pSink)
  277. {
  278.     BOOL bRet = FALSE;
  279.     if (m_pSinkList)
  280.     {
  281.         LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  282.         while (pos)
  283.         {
  284.             IHXMediaMarkerSink* pListSink =
  285.                 (IHXMediaMarkerSink*) m_pSinkList->GetNext(pos);
  286.             if (pListSink == pSink)
  287.             {
  288.                 bRet = TRUE;
  289.                 break;
  290.             }
  291.         }
  292.     }
  293.     return bRet;
  294. }
  295. HX_RESULT CHXMediaMarkerManager::AddMarkerInfo(CMarkerInfo* pInfo)
  296. {
  297.     HX_RESULT retVal = HXR_FAIL;
  298.     if (pInfo)
  299.     {
  300.         // First we add the marker to the master list
  301.         //
  302.         // Do we have a master list yet?
  303.         if (!m_pMarkerList)
  304.         {
  305.             // We don't - create one
  306.             m_pMarkerList = new CHXSimpleList();
  307.         }
  308.         if (m_pMarkerList)
  309.         {
  310.             // This master list will be sorted in increasing time. Therefore,
  311.             // since we expect most datatypes to add markers in increasing
  312.             // time, then we search the list from the TAIL for the right
  313.             // place to insert.
  314.             LISTPOSITION pos = m_pMarkerList->GetTailPosition();
  315.             while (pos)
  316.             {
  317.                 CMarkerInfo* pLInfo = (CMarkerInfo*) m_pMarkerList->GetAt(pos);
  318.                 if (pLInfo && pLInfo->m_ulTime <= pInfo->m_ulTime)
  319.                 {
  320.                     if (!AreMarkersIdentical(pLInfo, pInfo))
  321.                     {
  322.                         // Time of the list marker is either less
  323.                         // than or equal to ours, but we know they
  324.                         // are not the same marker, so we can safely
  325.                         // add our marker after the list marker.
  326.                         m_pMarkerList->InsertAfter(pos, (void*) pInfo);
  327.                         // We DID add the marker, so clear the return value
  328.                         retVal = HXR_OK;
  329.                     }
  330.                     // Whether we added or not, we are bustin' outta here.
  331.                     break;
  332.                 }
  333.                 m_pMarkerList->GetPrev(pos);
  334.             }
  335.             // If we haven't already inserted this marker, then
  336.             // add it at the head and clear the return value
  337.             if (FAILED(retVal))
  338.             {
  339.                 m_pMarkerList->AddHead((void*) pInfo);
  340.                 retVal = HXR_OK;
  341.             }
  342.             // XXXMEH - TODO - Add this marker to any additional
  343.             // data structures we will keep
  344.         }
  345.     }
  346.     return retVal;
  347. }
  348. BOOL CHXMediaMarkerManager::AreMarkersIdentical(CMarkerInfo* pInfo1, CMarkerInfo* pInfo2)
  349. {
  350.     BOOL bRet = FALSE;
  351.     if (pInfo1 && pInfo2)
  352.     {
  353.         // Check url
  354.         if (pInfo1->m_pURLStr && pInfo2->m_pURLStr &&
  355.             !strcmp((const char*) pInfo1->m_pURLStr->GetBuffer(),
  356.                     (const char*) pInfo2->m_pURLStr->GetBuffer()))
  357.         {
  358.             // Check marker name
  359.             if (pInfo1->m_pNameStr && pInfo2->m_pNameStr &&
  360.                 !strcmp((const char*) pInfo1->m_pNameStr->GetBuffer(),
  361.                         (const char*) pInfo2->m_pNameStr->GetBuffer()))
  362.             {
  363.                 // Check time
  364.                 if (pInfo1->m_ulTime == pInfo2->m_ulTime)
  365.                 {
  366.                     bRet = TRUE;
  367.                 }
  368.             }
  369.         }
  370.     }
  371.     return bRet;
  372. }
  373. void CHXMediaMarkerManager::BroadcastMarkerToSinks(CMarkerInfo* pInfo)
  374. {
  375.     if (pInfo && m_pSinkList)
  376.     {
  377.         // Loop through the list of marker sinks
  378.         LISTPOSITION pos = m_pSinkList->GetHeadPosition();
  379.         while (pos)
  380.         {
  381.             // Get the marker sink and check whether this
  382.             // marker should be passed to this sink
  383.             IHXMediaMarkerSink* pSink =
  384.                 (IHXMediaMarkerSink*) m_pSinkList->GetNext(pos);
  385.             if (SinkWantsThisMarker(pSink, pInfo))
  386.             {
  387.                 // This sink DOES want to be notified of this marker,
  388.                 // so call IHXMediaMarkerSink::MarkerResolved()
  389.                 pSink->MarkerResolved(pInfo->m_pURLStr,
  390.                                       pInfo->m_pNameStr,
  391.                                       pInfo->m_ulTime,
  392.                                       pInfo->m_pOtherParams);
  393.             }
  394.         }
  395.     }
  396. }
  397. BOOL CHXMediaMarkerManager::SinkWantsThisMarker(IHXMediaMarkerSink* pSink,
  398.                                                  CMarkerInfo*         pInfo)
  399. {
  400.     BOOL bRet = TRUE;
  401.     return bRet;
  402. }
  403. #endif /* #if defined(HELIX_FEATURE_MEDIAMARKER) */