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

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 "hxcom.h"
  36. #include "hxresult.h"
  37. #include "hxausvc.h"
  38. #include "ihxpckts.h"
  39. #include "hxmap.h"
  40. #include "smiltype.h"
  41. #include "hxgroup.h"
  42. #include "advgroup.h"
  43. #include "hxwintyp.h"
  44. #include "hxengin.h"
  45. #include "hxcore.h"
  46. #include "hxplay.h"
  47. #include "hxbsrc.h"
  48. #include "hxsrc.h"
  49. #include "srcinfo.h"
  50. #include "hxslist.h"
  51. #include "hxtac.h"
  52. #include "hxstrutl.h"
  53. #include "hxheap.h"
  54. #ifdef _DEBUG
  55. #undef HX_THIS_FILE
  56. static const char HX_THIS_FILE[] = __FILE__;
  57. #endif
  58. HXAdvancedTrack::HXAdvancedTrack(HXAdvancedGroup* pHXGroup)
  59.                 :HXBasicTrack(pHXGroup)
  60.                 ,m_pRepeatList(NULL)
  61.                 ,m_uSoundLevel(100)
  62.                 ,m_bInSoundLevelAnimation(FALSE)
  63.                 ,m_ulSoundLevelAnimationTime(0)
  64.                 ,m_ulGranularity(0)
  65. {
  66. }
  67. HXAdvancedTrack::~HXAdvancedTrack(void)
  68. {
  69.     Close();
  70. }
  71. #if defined(HELIX_FEATURE_AUDIOHOOK)
  72. /*
  73.  *  IUnknown methods
  74.  */
  75. STDMETHODIMP HXAdvancedTrack::QueryInterface(REFIID riid, void** ppvObj)
  76. {
  77.     if (HXR_OK == HXBasicTrack::QueryInterface(riid, ppvObj))
  78.     {
  79. return HXR_OK;
  80.     }
  81.     else if (IsEqualIID(riid, IID_IHXAudioHook))
  82.     {
  83.         AddRef();
  84.         *ppvObj = (IHXAudioHook*)this;
  85.         return HXR_OK;
  86.     }
  87.     *ppvObj = NULL;
  88.     return HXR_NOINTERFACE;
  89. }
  90. STDMETHODIMP_(ULONG32) HXAdvancedTrack::AddRef()
  91. {
  92.     return InterlockedIncrement(&m_lRefCount);
  93. }
  94. STDMETHODIMP_(ULONG32) HXAdvancedTrack::Release()
  95. {
  96.     if (InterlockedDecrement(&m_lRefCount) > 0)
  97.     {
  98.         return m_lRefCount;
  99.     }
  100.     delete this;
  101.     return 0;
  102. }
  103. /*
  104.  *  IHXAudioHook methods
  105.  */
  106. /************************************************************************
  107.  *  Method:
  108.  *      IHXAudioHook::OnInit
  109.  *  Purpose:
  110.  *      Audio Services calls OnInit() with the audio data format of the
  111.  *     audio data that will be provided in the OnBuffer() method.
  112.  */
  113. STDMETHODIMP
  114. HXAdvancedTrack::OnInit(HXAudioFormat* /*IN*/ pFormat)
  115. {
  116.     CHXAudioPlayer* pAudioPlayer = NULL;
  117.     
  118.     pAudioPlayer = m_pHXGroup->m_pPlayer->GetAudioPlayer();
  119.     if (pAudioPlayer)
  120.     {
  121. m_ulSoundLevelAnimationTime = pAudioPlayer->GetCurrentPlayBackTime();
  122. m_ulGranularity = pAudioPlayer->GetGranularity();
  123.     }
  124.     return HXR_OK;
  125. }
  126. /************************************************************************
  127.  *  Method:
  128.  *      IHXAudioHook::OnBuffer
  129.  *  Purpose:
  130.  *      Audio Services calls OnBuffer() with audio data packets. The
  131.  *     renderer should not modify the data in the IHXBuffer part of
  132.  *     pAudioInData.  If the renderer wants to write a modified
  133.  *     version of the data back to Audio Services, then it should 
  134.  *     create its own IHXBuffer, modify the data and then associate 
  135.  *     this buffer with the pAudioOutData->pData member.
  136.  */
  137. STDMETHODIMP
  138. HXAdvancedTrack::OnBuffer(HXAudioData* /*IN*/   pAudioInData,
  139.    HXAudioData* /*OUT*/  pAudioOutData)
  140. {
  141.     HX_RESULT rc = HXR_OK;
  142.     if (!m_pHXGroup)
  143.     {
  144. rc = HXR_UNEXPECTED;
  145. goto cleanup;
  146.     }
  147.     m_ulSoundLevelAnimationTime += m_ulGranularity;
  148.     rc = ((HXAdvancedGroup*)m_pHXGroup)->OnSoundLevelAnimation(m_uTrackIndex, m_uSoundLevel, m_ulSoundLevelAnimationTime);
  149. cleanup:
  150.     return rc;
  151. }
  152. #endif /* HELIX_FEATURE_AUDIOHOOK */
  153. /*
  154.  *  IHXTrack methods
  155.  */
  156. /************************************************************************
  157. *  Method:
  158. *     IHXTrack::Begin()
  159. *  Purpose:
  160. *     start the track
  161. */
  162. STDMETHODIMP
  163. HXAdvancedTrack::Begin(void)
  164. {
  165.     HX_RESULT rc = HXR_OK;
  166.     if (!m_pHXGroup)
  167.     {
  168. rc = HXR_UNEXPECTED;
  169. goto cleanup;
  170.     }
  171.     rc = ((HXAdvancedGroup*)m_pHXGroup)->BeginTrack(m_uTrackIndex, m_pValues);
  172. cleanup:
  173.     return rc;
  174. }
  175. /************************************************************************
  176. *  Method:
  177. *     IHXTrack::Pause()
  178. *  Purpose:
  179. *     pause the track
  180. */
  181. STDMETHODIMP
  182. HXAdvancedTrack::Pause(void)
  183. {
  184.     HX_RESULT rc = HXR_OK;
  185.     if (!m_pHXGroup)
  186.     {
  187. rc = HXR_UNEXPECTED;
  188. goto cleanup;
  189.     }
  190.     rc = ((HXAdvancedGroup*)m_pHXGroup)->PauseTrack(m_uTrackIndex, m_pValues);
  191. cleanup:
  192.     return rc;
  193. }
  194. /************************************************************************
  195. *  Method:
  196. *     IHXTrack::Seek()
  197. *  Purpose:
  198. *     seek the track
  199. */
  200. STDMETHODIMP
  201. HXAdvancedTrack::Seek(UINT32 ulSeekTime)
  202. {
  203.     HX_RESULT rc = HXR_OK;
  204.     if (!m_pHXGroup)
  205.     {
  206. rc = HXR_UNEXPECTED;
  207. goto cleanup;
  208.     }
  209.     rc = ((HXAdvancedGroup*)m_pHXGroup)->SeekTrack(m_uTrackIndex, m_pValues, ulSeekTime);
  210. cleanup:
  211.     return rc;
  212. }
  213. /************************************************************************
  214. *  Method:
  215. *     IHXTrack::Stop()
  216. *  Purpose:
  217. *     stop the track
  218. */
  219. STDMETHODIMP
  220. HXAdvancedTrack::Stop(void)
  221. {
  222.     HX_RESULT rc = HXR_OK;
  223.     if (!m_pHXGroup)
  224.     {
  225. rc = HXR_UNEXPECTED;
  226. goto cleanup;
  227.     }
  228.     rc = ((HXAdvancedGroup*)m_pHXGroup)->StopTrack(m_uTrackIndex, m_pValues);
  229. cleanup:
  230.     return rc;
  231. }
  232. /************************************************************************
  233. *  Method:
  234. *     IHXTrack::AddRepeat()
  235. *  Purpose:
  236. *     add repeat tracks
  237. */
  238. STDMETHODIMP
  239. HXAdvancedTrack::AddRepeat(IHXValues* pTrack)
  240. {
  241.     if (!m_pRepeatList)
  242.     {
  243. m_pRepeatList = new CHXSimpleList();
  244.     }
  245.     m_pRepeatList->AddTail(pTrack);
  246.     pTrack->AddRef();
  247.     ((HXAdvancedGroup*)m_pHXGroup)->RepeatTrackAdded(m_uTrackIndex, pTrack);
  248.     return HXR_OK;
  249. }
  250. /************************************************************************
  251.  * Method:
  252.  *     IHXTrack::GetSource
  253.  * Purpose:
  254.  *     Returns the Nth source instance supported by this player.
  255.  */
  256. STDMETHODIMP
  257. HXAdvancedTrack::GetSource(REF(IHXStreamSource*) pStreamSource)
  258. {
  259.     HX_RESULT rc = HXR_OK;
  260.     if (!m_pHXGroup)
  261.     {
  262. rc = HXR_UNEXPECTED;
  263. goto cleanup;
  264.     }
  265.     rc = ((HXAdvancedGroup*)m_pHXGroup)->GetSource(m_uTrackIndex, pStreamSource);
  266. cleanup:
  267.     return rc;
  268. }
  269. /************************************************************************
  270. *  Method:
  271. *     IHXTrack::SetSoundLevel()
  272. *  Purpose:
  273. *     Set Audio Level
  274. */
  275. STDMETHODIMP
  276. HXAdvancedTrack::SetSoundLevel(UINT16 uSoundLevel)
  277. {
  278.     HX_RESULT rc = HXR_OK;
  279.     if (!m_pHXGroup)
  280.     {
  281. rc = HXR_UNEXPECTED;
  282. goto cleanup;
  283.     }
  284.     if (m_uSoundLevel != uSoundLevel)
  285.     {
  286. m_uSoundLevel = uSoundLevel;
  287. rc = ((HXAdvancedGroup*)m_pHXGroup)->SetSoundLevel(m_uTrackIndex, m_uSoundLevel, !m_bInSoundLevelAnimation);
  288.     }
  289. cleanup:
  290.     return rc;
  291. }
  292. /************************************************************************
  293. *  Method:
  294. *     IHXTrack::GetSoundLevel()
  295. *  Purpose:
  296. *     Get Audio Level
  297. */
  298. STDMETHODIMP_(UINT16)
  299. HXAdvancedTrack::GetSoundLevel()
  300. {
  301.     return m_uSoundLevel;
  302. }
  303. /************************************************************************
  304. *  Method:
  305. *     IHXTrack::BeginSoundLevelAnimation()
  306. *  Purpose:
  307. *     notify the start of soundlevel animation
  308. */
  309. STDMETHODIMP
  310. HXAdvancedTrack::BeginSoundLevelAnimation(UINT16 uSoundLevelBeginWith)
  311. {
  312.     HX_RESULT rc = HXR_OK;
  313.     if (!m_pHXGroup)
  314.     {
  315. rc = HXR_UNEXPECTED;
  316. goto cleanup;
  317.     }
  318.     m_uSoundLevel = uSoundLevelBeginWith;
  319.     m_bInSoundLevelAnimation = TRUE;
  320.     rc = ((HXAdvancedGroup*)m_pHXGroup)->BeginSoundLevelAnimation(m_uTrackIndex, m_uSoundLevel);
  321.     
  322. cleanup:
  323.     return rc;
  324. }
  325. /************************************************************************
  326. *  Method:
  327. *     IHXTrack::EndSoundLevelAnimation()
  328. *  Purpose:
  329. *     notify the stop of soundlevel animation
  330. */
  331. STDMETHODIMP
  332. HXAdvancedTrack::EndSoundLevelAnimation(UINT16 uSoundLevelEndWith)
  333. {
  334.     HX_RESULT rc = HXR_OK;
  335.     if (!m_pHXGroup)
  336.     {
  337. rc = HXR_UNEXPECTED;
  338. goto cleanup;
  339.     }
  340.     m_uSoundLevel = uSoundLevelEndWith;
  341.     rc = ((HXAdvancedGroup*)m_pHXGroup)->EndSoundLevelAnimation(m_uTrackIndex, m_uSoundLevel);
  342.     m_bInSoundLevelAnimation = FALSE;
  343. cleanup:
  344.     return rc;
  345. }
  346. void
  347. HXAdvancedTrack::Close(void)
  348. {
  349.     if (m_bInSoundLevelAnimation)
  350.     {
  351. EndSoundLevelAnimation(0);
  352.     }
  353.     if (m_pRepeatList)
  354.     {
  355. CHXSimpleList::Iterator i = m_pRepeatList->Begin();
  356. for (; i != m_pRepeatList->End(); ++i)
  357. {
  358.     IHXValues* pValues = (IHXValues*)*i;
  359.     HX_RELEASE(pValues);
  360. }
  361. HX_DELETE(m_pRepeatList);
  362.     }
  363.     HXBasicTrack::Close();
  364. }
  365. HXAdvancedGroup::HXAdvancedGroup(HXAdvancedGroupManager* pManager)
  366.                 :HXBasicGroup(pManager)
  367.                 ,m_pGroupProperties(NULL)
  368.                 ,m_bPrefetchSinkAdded(FALSE)
  369.                 ,m_pPrefetchTrackMap(NULL)
  370.                 ,m_pPersistentComponentPropertyMap(NULL)
  371.                 ,m_uPrefetchTrackCount(0)
  372.                 ,m_pTrackSinkList(NULL)
  373.                 ,m_pPrefetchSinkList(NULL)
  374. {
  375. }
  376. HXAdvancedGroup::~HXAdvancedGroup(void)
  377. {
  378.     Close();
  379. }
  380. /*
  381.  *  IUnknown methods
  382.  */
  383. STDMETHODIMP HXAdvancedGroup::QueryInterface(REFIID riid, void** ppvObj)
  384. {
  385.     if (HXR_OK == HXBasicGroup::QueryInterface(riid, ppvObj))
  386.     {
  387. return HXR_OK;
  388.     }
  389.     else if (IsEqualIID(riid, IID_IHXGroup2))
  390.     {
  391.         AddRef();
  392.         *ppvObj = (IHXGroup2*)this;
  393.         return HXR_OK;
  394.     }
  395. #if defined(HELIX_FEATURE_PREFETCH)
  396.     else if (IsEqualIID(riid, IID_IHXPrefetch))
  397.     {
  398.         AddRef();
  399.         *ppvObj = (IHXPrefetch*)this;
  400.         return HXR_OK;
  401.     }
  402.     else if (IsEqualIID(riid, IID_IHXPrefetchSink))
  403.     {
  404.         AddRef();
  405.         *ppvObj = (IHXPrefetchSink*)this;
  406.         return HXR_OK;
  407.     }
  408. #endif /* HELIX_FEATURE_PREFETCH */
  409.     *ppvObj = NULL;
  410.     return HXR_NOINTERFACE;
  411. }
  412. STDMETHODIMP_(ULONG32) HXAdvancedGroup::AddRef()
  413. {
  414.     return InterlockedIncrement(&m_lRefCount);
  415. }
  416. STDMETHODIMP_(ULONG32) HXAdvancedGroup::Release()
  417. {
  418.     if (InterlockedDecrement(&m_lRefCount) > 0)
  419.     {
  420.         return m_lRefCount;
  421.     }
  422.     delete this;
  423.     return 0;
  424. }
  425. /*
  426.  *  IHXGroup methods
  427.  */
  428. /************************************************************************
  429. *  Method:
  430. *      IHXGroup::SetGroupProperties
  431. *  Purpose:
  432. * Set any group specific information like Title Author 
  433. * Copyright etc. 
  434. */
  435. STDMETHODIMP
  436. HXAdvancedGroup::SetGroupProperties(IHXValues*  /*IN*/ pProperties)
  437. {
  438.     UINT32  ulDuration = 0;
  439.     if (m_pGroupProperties || !pProperties)
  440.     {
  441. return HXR_UNEXPECTED;
  442.     }
  443.     m_pGroupProperties = pProperties;
  444.     m_pGroupProperties->AddRef();
  445.     // support adjust current group's duration on the fly
  446.     if (m_uGroupIndex == m_pGroupManager->m_uCurrentGroup)
  447.     {
  448. if (HXR_OK == m_pGroupProperties->GetPropertyULONG32("duration", ulDuration))
  449. {
  450.     m_pPlayer->SetPresentationTime(ulDuration);
  451. }
  452.     }
  453.     return HXR_OK;
  454. }
  455. /************************************************************************
  456. *  Method:
  457. *      IHXGroup::GetGroupProperties
  458. *  Purpose:
  459. * Get any group specific information. May return NULL.
  460. */
  461. STDMETHODIMP_(IHXValues*)
  462. HXAdvancedGroup::GetGroupProperties(void)
  463. {
  464.     if (m_pGroupProperties)
  465.     {
  466. m_pGroupProperties->AddRef();
  467.     }
  468.     return m_pGroupProperties;
  469. }
  470. /************************************************************************
  471. *  Method:
  472. *      IHXGroup2::SetPersistentComponentProperties
  473. *  Purpose:
  474. * Set persistent component properties associated with this group
  475. * One group may contain multiple persistent components
  476. */
  477. STDMETHODIMP
  478. HXAdvancedGroup::SetPersistentComponentProperties(UINT32        /*IN*/ ulPersistentComponentID,
  479.           IHXValues* /*IN*/ pProperties)
  480. {
  481.     HX_RESULT rc = HXR_OK;
  482.     IHXValues* pValues = NULL;
  483.     if (!pProperties)
  484.     {
  485. rc = HXR_FAILED;
  486. goto cleanup;
  487.     }
  488.     if (!m_pPersistentComponentPropertyMap)
  489.     {
  490. m_pPersistentComponentPropertyMap = new CHXMapLongToObj;
  491.     }
  492.     if (!m_pPersistentComponentPropertyMap->Lookup(ulPersistentComponentID, 
  493.    (void*&)pValues))
  494.     {
  495. (*m_pPersistentComponentPropertyMap)[ulPersistentComponentID] = pProperties;
  496. pProperties->AddRef();
  497.     }
  498. cleanup:
  499.     return rc;
  500. }
  501. /************************************************************************
  502. *  Method:
  503. *      IHXGroup2::GetPersistentComponentProperties
  504. *  Purpose:
  505. * Get any persistent component specific information associated with 
  506. * the group.
  507. * One group may contain multiple persistent components
  508. */
  509. STDMETHODIMP
  510. HXAdvancedGroup::GetPersistentComponentProperties(UINT32          /*IN*/  ulPersistentComponentID,
  511.           REF(IHXValues*) /*OUT*/ pProperties)
  512. {
  513.     HX_RESULT rc = HXR_OK;
  514.     
  515.     pProperties = NULL;
  516.     if (m_pPersistentComponentPropertyMap &&
  517. m_pPersistentComponentPropertyMap->Lookup(ulPersistentComponentID, (void*&)pProperties))
  518.     {
  519. pProperties->AddRef();
  520.     }
  521.     else
  522.     {
  523. rc = HXR_FAILED;
  524.     }
  525.     return rc;
  526. }
  527. /************************************************************************
  528. *  Method:
  529. *      IHXGroup2::GetTrack2
  530. *  Purpose:
  531. * Get ith track in this group
  532. */
  533. STDMETHODIMP
  534. HXAdvancedGroup::GetTrack2(UINT16 /*IN*/ uTrackIndex,
  535.            REF(IHXValues*) /*OUT*/ pTrack,
  536.            REF(IHXValues*) /*OUT*/ pTrackPropInRequest)
  537. {
  538.     return DoGetTrack(uTrackIndex, pTrack, pTrackPropInRequest);
  539. }
  540. STDMETHODIMP
  541. HXAdvancedGroup::AddTrack(IHXValues* /*IN*/ pTrack)
  542. {
  543.     HX_RESULT   rc = HXR_OK;
  544.     HXAdvancedTrack* pHXTrack = new HXAdvancedTrack(this);
  545.     pHXTrack->AddRef();
  546.     rc = DoAddTrack(pTrack, NULL, pHXTrack);
  547.     if (HXR_OK != rc)
  548.     {
  549.         HX_RELEASE(pHXTrack);
  550.     }
  551.     return rc;
  552. }
  553. /************************************************************************
  554. *  Method:
  555. *      IHXGroup2::AddTrack2
  556. *  Purpose:
  557. * Add Tracks to the group, including the props set in RequestHeader
  558. */
  559. STDMETHODIMP
  560. HXAdvancedGroup::AddTrack2(IHXValues*   /*IN*/ pTrack,
  561.            IHXValues*   /*IN*/ pTrackPropInRequest)
  562. {
  563.     HX_RESULT   rc = HXR_OK;
  564.     HXAdvancedTrack* pHXTrack = new HXAdvancedTrack(this);
  565.     pHXTrack->AddRef();
  566.    
  567.     rc = DoAddTrack(pTrack, pTrackPropInRequest, pHXTrack);
  568.     if (HXR_OK != rc)
  569.     {
  570.         HX_RELEASE(pHXTrack);
  571.     }
  572.     return rc;
  573. }
  574. /************************************************************************
  575. *  Method:
  576. *      IHXGroup::RemoveTrack
  577. *  Purpose:
  578. * Remove an already added track
  579. */
  580. STDMETHODIMP
  581. HXAdvancedGroup::RemoveTrack(UINT16 /*IN*/ uTrackIndex)
  582. {
  583.     HX_RESULT theErr = HXR_OK;
  584.     int i = 0;
  585.     IHXValues* pValues = NULL;
  586.     IHXValues* pValuesInRequest = NULL;
  587.     IHXValues* pUpdateValues = NULL;
  588.     CHXMapLongToObj* pNewTrackMap = NULL;
  589.     HXAdvancedTrack* pHXTrackRemoved = NULL;
  590.     HXAdvancedTrack* pHXTrack = NULL;
  591.     if (!m_pTrackMap->Lookup(uTrackIndex, (void*&)pHXTrackRemoved))
  592.     {
  593. theErr = HXR_UNEXPECTED;
  594. goto cleanup;
  595.     }
  596.     m_pTrackMap->RemoveKey(uTrackIndex);
  597.     pHXTrackRemoved->GetTrackProperties(pValues, pValuesInRequest);
  598.     HX_ASSERT(pValues);
  599.     HX_ASSERT(m_pPlayer);
  600.     if (HXR_OK != m_pPlayer->RemoveTrack(m_uGroupIndex, uTrackIndex, pValues))
  601.     {
  602. theErr = HXR_UNEXPECTED;
  603. goto cleanup;
  604.     }
  605.     if (m_bToNotifyTrack)
  606.     {
  607. theErr = m_pGroupManager->TrackRemoved(m_uGroupIndex, uTrackIndex, pValues);
  608.     }
  609.     // adjust track map index
  610.     pNewTrackMap = new CHXMapLongToObj;
  611.     for (i = 0; i < uTrackIndex; i++)
  612.     {
  613. m_pTrackMap->Lookup(i, (void*&)pHXTrack);
  614. HX_ASSERT(pHXTrack);
  615. (*pNewTrackMap)[i] = pHXTrack;
  616.     }
  617.     for (i = uTrackIndex + 1; i < m_uTrackCount; i++)
  618.     {
  619. m_pTrackMap->Lookup(i, (void*&)pHXTrack);
  620. HX_ASSERT(pHXTrack);
  621. pHXTrack->m_uTrackIndex = i - 1;
  622. (*pNewTrackMap)[i - 1] = pHXTrack;
  623. pUpdateValues = new CHXHeader;
  624. pUpdateValues->AddRef();
  625. pUpdateValues->SetPropertyULONG32("TrackIndex", i - 1);
  626. m_pPlayer->UpdateTrack(m_uGroupIndex, i, pUpdateValues);
  627. HX_RELEASE(pUpdateValues);
  628.     }
  629.     HX_DELETE(m_pTrackMap);
  630.     m_pTrackMap = pNewTrackMap;
  631.     m_uTrackCount--;
  632.     
  633. cleanup:
  634.     HX_RELEASE(pValues);
  635.     HX_RELEASE(pValuesInRequest);
  636.     HX_RELEASE(pHXTrackRemoved);
  637.     return theErr;
  638. }
  639. HX_RESULT
  640. HXAdvancedGroup::BeginTrack(UINT16      /*IN*/ uTrackIndex,
  641.             IHXValues*  /*IN*/ pTrack)
  642. {
  643.     HX_RESULT theErr = HXR_OK;
  644.     HX_ASSERT(m_pPlayer);
  645.     theErr = m_pPlayer->BeginTrack(m_uGroupIndex, uTrackIndex, pTrack);
  646.     if (m_pTrackSinkList)
  647.     {
  648. CHXSimpleList::Iterator ndx = m_pTrackSinkList->Begin();
  649. for (; ndx != m_pTrackSinkList->End(); ++ndx)
  650. {
  651.     IHXTrackSink* pTrackSink = (IHXTrackSink*) (*ndx);
  652.     pTrackSink->BeginDone(m_uGroupIndex, uTrackIndex);
  653. }
  654.     }
  655.     return theErr;
  656. }
  657. HX_RESULT
  658. HXAdvancedGroup::PauseTrack(UINT16      /*IN*/ uTrackIndex,
  659.             IHXValues*  /*IN*/ pTrack)
  660. {
  661.     HX_RESULT theErr = HXR_OK;
  662.     HX_ASSERT(m_pPlayer);
  663.     theErr = m_pPlayer->PauseTrack(m_uGroupIndex, uTrackIndex, pTrack);
  664.     if (m_pTrackSinkList)
  665.     {
  666. CHXSimpleList::Iterator ndx = m_pTrackSinkList->Begin();
  667. for (; ndx != m_pTrackSinkList->End(); ++ndx)
  668. {
  669.     IHXTrackSink* pTrackSink = (IHXTrackSink*) (*ndx);
  670.     pTrackSink->PauseDone(m_uGroupIndex, uTrackIndex);
  671. }
  672.     }
  673.     return theErr;
  674. }
  675. HX_RESULT
  676. HXAdvancedGroup::SeekTrack(UINT16     /*IN*/ uTrackIndex,
  677.            IHXValues*     /*IN*/ pTrack,
  678.            UINT32     /*IN*/ ulSeekTime)
  679. {
  680.     HX_RESULT theErr = HXR_OK;
  681.     HX_ASSERT(m_pPlayer);
  682.     theErr = m_pPlayer->SeekTrack(m_uGroupIndex, uTrackIndex, pTrack, ulSeekTime);
  683.     if (m_pTrackSinkList)
  684.     {
  685. CHXSimpleList::Iterator ndx = m_pTrackSinkList->Begin();
  686. for (; ndx != m_pTrackSinkList->End(); ++ndx)
  687. {
  688.     IHXTrackSink* pTrackSink = (IHXTrackSink*) (*ndx);
  689.     pTrackSink->SeekDone(m_uGroupIndex, uTrackIndex, ulSeekTime);
  690. }
  691.     }
  692.     return theErr;
  693. }
  694. HX_RESULT
  695. HXAdvancedGroup::StopTrack(UINT16 /*IN*/ uTrackIndex,
  696.            IHXValues* /*IN*/ pTrack)
  697. {
  698.     HX_RESULT theErr = HXR_OK;
  699.     HX_ASSERT(m_pPlayer);    
  700.     theErr = m_pPlayer->StopTrack(m_uGroupIndex, uTrackIndex, pTrack);
  701.     if (m_pTrackSinkList)
  702.     {
  703. CHXSimpleList::Iterator ndx = m_pTrackSinkList->Begin();
  704. for (; ndx != m_pTrackSinkList->End(); ++ndx)
  705. {
  706.     IHXTrackSink* pTrackSink = (IHXTrackSink*) (*ndx);
  707.     pTrackSink->StopDone(m_uGroupIndex, uTrackIndex);
  708. }
  709.     }
  710.     return theErr;
  711. }
  712. HX_RESULT
  713. HXAdvancedGroup::GetSource(UINT16 uTrackIndex, 
  714.            IHXStreamSource*& pStreamSource)
  715. {
  716.     SourceInfo* pSourceInfo = NULL;
  717.     pStreamSource = NULL;
  718.     HX_ASSERT(m_pPlayer);
  719.     if (HXR_OK == m_pPlayer->GetSourceInfo(m_uGroupIndex, uTrackIndex, pSourceInfo) && 
  720. pSourceInfo)
  721.     {
  722. return pSourceInfo->m_pSource->QueryInterface(IID_IHXStreamSource, (void**)&pStreamSource);
  723.     }
  724.     return HXR_FAILED;
  725. }
  726. HX_RESULT
  727. HXAdvancedGroup::SetSoundLevel(UINT16 /*IN*/ uTrackIndex,
  728.        UINT16 /*IN*/ uSoundLevel,
  729.        BOOL /*IN*/ bReflushAudioDevice)
  730. {
  731.     HX_RESULT theErr = HXR_OK;
  732.     HX_ASSERT(m_pPlayer);
  733.     theErr = m_pPlayer->SetSoundLevel(m_uGroupIndex, 
  734.       uTrackIndex, 
  735.       uSoundLevel,
  736.       bReflushAudioDevice);
  737.     return theErr;
  738. }
  739. HX_RESULT
  740. HXAdvancedGroup::BeginSoundLevelAnimation(UINT16 uTrackIndex, 
  741.           UINT16 uSoundLevelBeginWith)
  742. {    
  743.     HX_RESULT         rc = HXR_OK;
  744.     CHXAudioPlayer*     pAudioPlayer = NULL;
  745.     HXAdvancedTrack* pHXTrack = NULL;
  746.     HX_ASSERT(m_pPlayer);
  747.     if ((pAudioPlayer = m_pPlayer->GetAudioPlayer()) &&
  748. m_pTrackMap->Lookup(uTrackIndex, (void*&)pHXTrack))
  749.     {     
  750. pAudioPlayer->ActualAddPostMixHook((IHXAudioHook*)pHXTrack, 0, 1);
  751. m_pPlayer->SetSoundLevel(m_uGroupIndex, 
  752.  uTrackIndex, 
  753.  uSoundLevelBeginWith, 
  754.  TRUE);
  755.     }
  756.     return rc;
  757. }
  758. HX_RESULT
  759. HXAdvancedGroup::EndSoundLevelAnimation(UINT16 uTrackIndex, 
  760.         UINT16 uSoundLevelEndWith)
  761. {
  762.     HX_RESULT         theErr = HXR_OK;
  763.     CHXAudioPlayer*     pAudioPlayer = NULL;
  764.     HXAdvancedTrack* pHXTrack = NULL;
  765.     HX_ASSERT(m_pPlayer);
  766.     if ((pAudioPlayer = m_pPlayer->GetAudioPlayer()) &&
  767. m_pTrackMap->Lookup(uTrackIndex, (void*&)pHXTrack))
  768.     {
  769. pAudioPlayer->ActualRemovePostMixHook((IHXAudioHook*)pHXTrack);
  770.     
  771. m_pPlayer->SetSoundLevel(m_uGroupIndex, 
  772.  uTrackIndex, 
  773.  uSoundLevelEndWith, 
  774.  FALSE);
  775.     }
  776.     return theErr;
  777. }
  778. HX_RESULT
  779. HXAdvancedGroup::OnSoundLevelAnimation(UINT16 uTrackIndex, 
  780.                                        UINT16 uSoundLevel, 
  781.                                        UINT32 ulSoundLevelAnimationTime)
  782. {
  783.     HX_RESULT theErr = HXR_OK;
  784.     if (m_pTrackSinkList)
  785.     {
  786. CHXSimpleList::Iterator ndx = m_pTrackSinkList->Begin();
  787. for (; ndx != m_pTrackSinkList->End(); ++ndx)
  788. {
  789.     IHXTrackSink* pTrackSink = (IHXTrackSink*) (*ndx);
  790.     pTrackSink->OnSoundLevelAnimation(m_uGroupIndex, uTrackIndex, ulSoundLevelAnimationTime);
  791. }
  792.     }
  793.     return theErr;
  794. }
  795. void
  796. HXAdvancedGroup::PersistentComponentAdded(UINT16 uTrackIndex)
  797. {
  798.     HXAdvancedTrack*    pPersistentHXTrack = NULL;
  799.     // XXX HP we don't actually remove the track in order
  800.     // to preserve the group/track ID of subsequent sources
  801.     // Need more work on RemoveTrack() so that all the group/
  802.     // track ID get updated across the board(esp. in persistent
  803.     // renderers)!!
  804.     if (m_pTrackMap->Lookup(uTrackIndex, (void*&)pPersistentHXTrack))
  805.     {
  806. pPersistentHXTrack->m_bActive = FALSE;
  807.     }
  808.     return;
  809. }
  810. void
  811. HXAdvancedGroup::PersistentComponentRemoved(UINT16 uTrackIndex)
  812. {
  813.     return;
  814. }
  815. HX_RESULT
  816. HXAdvancedGroup::CurrentGroupSet(void)
  817. {
  818.     HX_RESULT rc = HXR_OK;
  819.     CHXMapLongToObj::Iterator i = m_pTrackMap->Begin();
  820.     for(; i != m_pTrackMap->End(); ++i)
  821.     {
  822. HXAdvancedTrack*    pHXTrack = (HXAdvancedTrack*)(*i);
  823. CHXSimpleList*     pRepeatList = pHXTrack->m_pRepeatList;
  824. if (pRepeatList)
  825. {
  826.     CHXSimpleList::Iterator ndx = pRepeatList->Begin();
  827.     for (; ndx != pRepeatList->End(); ++ndx)
  828.     {
  829. IHXValues* pRepeatTrack = (IHXValues*) (*ndx);
  830. ((HXAdvancedGroupManager*)m_pGroupManager)->RepeatTrackAdded(m_uGroupIndex, 
  831.                                                                              pHXTrack->m_uTrackIndex, 
  832.                                                                              pRepeatTrack);
  833.     }
  834. }
  835.     }
  836.     return rc;
  837. }
  838. HX_RESULT
  839. HXAdvancedGroup::RepeatTrackAdded(UINT16 uTrackIndex, IHXValues* pValues)
  840. {
  841.     HX_RESULT rc = HXR_OK;
  842.     if (m_bToNotifyTrack)
  843.     {
  844. rc = ((HXAdvancedGroupManager*)m_pGroupManager)->RepeatTrackAdded(m_uGroupIndex, 
  845.                                                                           uTrackIndex, 
  846.                                                                           pValues);
  847. HX_ASSERT(rc == HXR_OK);
  848.     }
  849.     return rc;
  850. }
  851. /************************************************************************
  852. *  Method:
  853. *      IHXGroup2::GetIHXTrack
  854. *  Purpose:
  855. * get the IHXTrack object
  856. */
  857. STDMETHODIMP
  858. HXAdvancedGroup::GetIHXTrack(UINT16         /*IN*/  uTrackIndex,
  859.              REF(IHXTrack*) /*OUT*/ pTrack)
  860. {
  861.     HX_RESULT rc = HXR_OK;
  862.     pTrack = NULL;
  863.     if (!m_pTrackMap->Lookup(uTrackIndex, (void*&)pTrack))
  864.     {
  865. rc = HXR_FAILED;
  866. goto cleanup;
  867.     }
  868.     pTrack->AddRef();
  869. cleanup:
  870.     return HXR_OK;
  871. }
  872. /************************************************************************
  873. *  Method:
  874. *      IHXGroup2::AddTrackSink
  875. *  Purpose:
  876. * add advise sink on track
  877. */
  878. STDMETHODIMP
  879. HXAdvancedGroup::AddTrackSink(IHXTrackSink*   /*IN*/  pSink)
  880. {
  881.     if (!pSink)
  882.     {
  883. return HXR_UNEXPECTED;
  884.     }
  885.     if (!m_pTrackSinkList)
  886.     {
  887. m_pTrackSinkList = new CHXSimpleList;
  888.     }
  889.     pSink->AddRef();
  890.     m_pTrackSinkList->AddTail(pSink);
  891.     return HXR_OK;    
  892. }
  893. /************************************************************************
  894. *  Method:
  895. *      IHXGroup2::RemoveTrackSink
  896. *  Purpose:
  897. * remove advise sink on track
  898. */
  899. STDMETHODIMP
  900. HXAdvancedGroup::RemoveTrackSink(IHXTrackSink*   /*IN*/  pSink)
  901. {
  902.     if (!m_pTrackSinkList)
  903.     {
  904. return HXR_UNEXPECTED;
  905.     }
  906.     LISTPOSITION lPosition = m_pTrackSinkList->Find(pSink);
  907.     if (!lPosition)
  908.     {
  909. return HXR_UNEXPECTED;
  910.     }
  911.     m_pTrackSinkList->RemoveAt(lPosition);
  912.     HX_RELEASE(pSink);
  913.     
  914.     return HXR_OK;
  915. }
  916. #if defined(HELIX_FEATURE_PREFETCH)
  917. /************************************************************************
  918. *  Method:
  919. *      IHXPrefetch::AddPrefetchTrack
  920. *  Purpose:
  921. *      adds prefetch track by specifying "PrefetchType" and "PrefetchValue"
  922. *      in pTrack's IHXValues
  923. */
  924. STDMETHODIMP
  925. HXAdvancedGroup::AddPrefetchTrack(IHXValues* /*IN*/  pTrack)
  926. {
  927.     HX_RESULT     rc = HXR_OK;
  928.     UINT16     uPrefetchIndex = 0;
  929.     IHXPrefetch*   pPrefetch = NULL;
  930.     if (!pTrack)
  931.     {
  932. rc = HXR_UNEXPECTED;
  933. goto cleanup;
  934.     }
  935.     uPrefetchIndex = m_uPrefetchTrackCount;
  936.     pTrack->SetPropertyULONG32("GroupIndex", m_uGroupIndex);
  937.     pTrack->SetPropertyULONG32("TrackIndex", uPrefetchIndex);
  938.     // give TLC a first bite on prefetch track
  939.     if (HXR_OK == m_pPlayer->QueryInterface(IID_IHXPrefetch, (void**)&pPrefetch))
  940.     {
  941. rc = pPrefetch->AddPrefetchTrack(pTrack);
  942. if (HXR_OK == rc && !m_bPrefetchSinkAdded)
  943. {
  944.     m_bPrefetchSinkAdded = TRUE;
  945.     pPrefetch->AddPrefetchSink(this);
  946. }
  947. else if (HXR_NOT_SUPPORTED == rc)
  948. {
  949.     rc = m_pPlayer->AddPrefetchTrack(m_uGroupIndex, uPrefetchIndex, pTrack);
  950. }
  951.     }
  952.     else
  953.     {
  954. rc = m_pPlayer->AddPrefetchTrack(m_uGroupIndex, uPrefetchIndex, pTrack);
  955.     }
  956.     if (HXR_OK != rc)
  957.     {
  958. goto cleanup;
  959.     }
  960.     if (!m_pPrefetchTrackMap)
  961.     {
  962. m_pPrefetchTrackMap = new CHXMapLongToObj;
  963.     }
  964.     (*m_pPrefetchTrackMap)[uPrefetchIndex] = pTrack;
  965.     pTrack->AddRef();
  966.     m_uPrefetchTrackCount++;
  967.     if (m_pPrefetchSinkList)
  968.     {
  969. CHXSimpleList::Iterator ndx = m_pPrefetchSinkList->Begin();
  970. for (; ndx != m_pPrefetchSinkList->End(); ++ndx)
  971. {
  972.     IHXPrefetchSink* pPrefetchSink = (IHXPrefetchSink*) (*ndx);
  973.     pPrefetchSink->PrefetchTrackAdded(m_uGroupIndex, uPrefetchIndex, pTrack);
  974. }
  975.     }
  976. cleanup:
  977.     HX_RELEASE(pPrefetch);
  978.     return rc;
  979. }
  980. /************************************************************************
  981. *  Method:
  982. *      IHXPrefetch::RemovePrefetchTrack
  983. *  Purpose:
  984. *      removes prefetched track
  985. */
  986. STDMETHODIMP
  987. HXAdvancedGroup::RemovePrefetchTrack(UINT16 /*IN*/ uTrackIndex)
  988. {
  989.     HX_RESULT rc = HXR_OK;
  990.     int i = 0;
  991.     IHXValues* pTrack = NULL;
  992.     IHXValues* pUpdateValues = NULL;
  993.     CHXMapLongToObj* pNewPrefetchTrackMap = NULL;
  994.     if (!m_pPrefetchTrackMap)
  995.     {
  996. rc = HXR_FAILED;
  997. goto cleanup;
  998.     }
  999.     if (!m_pPrefetchTrackMap->Lookup(uTrackIndex, (void*&)pTrack))
  1000.     {
  1001. rc = HXR_FAILED;
  1002. goto cleanup;
  1003.     }
  1004.     m_pPrefetchTrackMap->RemoveKey(uTrackIndex);
  1005.     if (HXR_OK != m_pPlayer->RemovePrefetchTrack(m_uGroupIndex, uTrackIndex, pTrack))
  1006.     {
  1007. rc = HXR_FAILED;
  1008. goto cleanup;
  1009.     }
  1010.     if (m_pPrefetchSinkList)
  1011.     {
  1012. CHXSimpleList::Iterator ndx = m_pPrefetchSinkList->Begin();
  1013. for (; ndx != m_pPrefetchSinkList->End(); ++ndx)
  1014. {
  1015.     IHXPrefetchSink* pPrefetchSink = (IHXPrefetchSink*) (*ndx);
  1016.     pPrefetchSink->PrefetchTrackRemoved(m_uGroupIndex, uTrackIndex, pTrack);
  1017. }
  1018.     }
  1019.     HX_RELEASE(pTrack);
  1020.     // adjust track map index
  1021.     pNewPrefetchTrackMap = new CHXMapLongToObj;
  1022.     for (i = 0; i < uTrackIndex; i++)
  1023.     {
  1024. pTrack = (IHXValues*)(*m_pPrefetchTrackMap)[i];
  1025. HX_ASSERT(pTrack);
  1026. (*pNewPrefetchTrackMap)[i] = pTrack;
  1027.     }
  1028.     for (i = uTrackIndex + 1; i < m_uPrefetchTrackCount; i++)
  1029.     {
  1030. pTrack = (IHXValues*)(*m_pPrefetchTrackMap)[i];
  1031. HX_ASSERT(pTrack);
  1032. (*pNewPrefetchTrackMap)[i - 1] = pTrack;
  1033. pUpdateValues = new CHXHeader;
  1034. pUpdateValues->AddRef();
  1035. pUpdateValues->SetPropertyULONG32("TrackIndex", i - 1);
  1036. m_pPlayer->UpdatePrefetchTrack(m_uGroupIndex, i, pUpdateValues);
  1037. HX_RELEASE(pUpdateValues);
  1038.     }
  1039.     HX_DELETE(m_pPrefetchTrackMap);
  1040.     m_pPrefetchTrackMap = pNewPrefetchTrackMap;
  1041.     m_uPrefetchTrackCount--;
  1042. cleanup:
  1043.     return rc;
  1044. }
  1045. /************************************************************************
  1046. *  Method:
  1047. *      IHXPrefetch::GetPrefetchTrackCount
  1048. *  Purpose:
  1049. *      get number of prefetch tracks added
  1050. */
  1051. STDMETHODIMP_(UINT16)
  1052. HXAdvancedGroup::GetPrefetchTrackCount()
  1053. {
  1054.     return m_uPrefetchTrackCount;
  1055. }
  1056. /************************************************************************
  1057. *  Method:
  1058. *      IHXPrefetch::GetPrefetchTrack
  1059. *  Purpose:
  1060. *      get prefetch track based on the index
  1061. */
  1062. STDMETHODIMP
  1063. HXAdvancedGroup::GetPrefetchTrack(UINT16            /*IN*/  uTrackIndex,
  1064.           REF(IHXValues*)   /*OUT*/ pTrack)
  1065. {
  1066.     HX_RESULT rc = HXR_OK;
  1067.     pTrack = NULL;
  1068.     if (!m_pPrefetchTrackMap)
  1069.     {
  1070. rc = HXR_FAILED;
  1071. goto cleanup;
  1072.     }
  1073.     if (!m_pPrefetchTrackMap->Lookup(uTrackIndex, (void*&)pTrack))
  1074.     {
  1075. rc = HXR_FAILED;
  1076. goto cleanup;
  1077.     }
  1078. cleanup:
  1079.     return rc;
  1080. }
  1081. /************************************************************************
  1082. *  Method:
  1083. *      IHXPrefetch::AddPrefetchSink
  1084. *  Purpose:
  1085. *      add prefetch sink
  1086. */
  1087. STDMETHODIMP
  1088. HXAdvancedGroup::AddPrefetchSink(IHXPrefetchSink* /*IN*/ pSink)
  1089. {
  1090.     HX_RESULT rc = HXR_OK;
  1091.     if (!pSink)
  1092.     {
  1093. rc = HXR_FAILED;
  1094. goto cleanup;
  1095.     }
  1096.     if (!m_pPrefetchSinkList)
  1097.     {
  1098. m_pPrefetchSinkList = new CHXSimpleList;
  1099.     }
  1100.     m_pPrefetchSinkList->AddTail(pSink);
  1101.     pSink->AddRef();
  1102. cleanup:
  1103.     return rc;
  1104. }
  1105. /************************************************************************
  1106. *  Method:
  1107. *      IHXPrefetch::RemovePrefetchSink
  1108. *  Purpose:
  1109. *      remove prefetch sink
  1110. */
  1111. STDMETHODIMP
  1112. HXAdvancedGroup::RemovePrefetchSink(IHXPrefetchSink* /*IN*/ pSink)
  1113. {
  1114.     HX_RESULT     rc = HXR_OK;
  1115.     LISTPOSITION    lPosition = 0;
  1116.     if (!m_pPrefetchSinkList || !pSink)
  1117.     {
  1118. rc = HXR_FAILED;
  1119. goto cleanup;
  1120.     }
  1121.     lPosition = m_pPrefetchSinkList->Find(pSink);
  1122.     if (!lPosition)
  1123.     {
  1124. rc = HXR_FAILED;
  1125. goto cleanup;
  1126.     }
  1127.     m_pPrefetchSinkList->RemoveAt(lPosition);
  1128.     HX_RELEASE(pSink);
  1129.     
  1130. cleanup:
  1131.     return rc;
  1132. }
  1133. /************************************************************************
  1134. *  Method:
  1135. *     IHXPrefetchSink::PrefetchTrackAdded()
  1136. *  Purpose:
  1137. *     prefetch track is added
  1138. */
  1139. STDMETHODIMP
  1140. HXAdvancedGroup::PrefetchTrackAdded(UINT16      uGroupIndex,
  1141.             UINT16      uTrackIndex,
  1142.             IHXValues*  pTrack)
  1143. {
  1144.     return HXR_OK;
  1145. }
  1146. /************************************************************************
  1147. *  Method:
  1148. *     IHXPrefetchSink::PrefetchTrackRemoved()
  1149. *  Purpose:
  1150. *     prefetch track is removed
  1151. */
  1152. STDMETHODIMP
  1153. HXAdvancedGroup::PrefetchTrackRemoved(UINT16     uGroupIndex,
  1154.               UINT16        uTrackIndex,
  1155.               IHXValues*    pTrack)
  1156. {
  1157.     return HXR_OK;
  1158. }
  1159. /************************************************************************
  1160. *  Method:
  1161. *     IHXPrefetchSink::PrefetchTrackDone()
  1162. *  Purpose:
  1163. *     prefetch track is done
  1164. */
  1165. STDMETHODIMP
  1166. HXAdvancedGroup::PrefetchTrackDone(UINT16 uGroupIndex,
  1167.            UINT16 uTrackIndex,     
  1168.            HX_RESULT status)
  1169. {
  1170.     HX_RESULT rc = HXR_OK;
  1171.     if (m_pPrefetchSinkList)
  1172.     {
  1173. CHXSimpleList::Iterator ndx = m_pPrefetchSinkList->Begin();
  1174. for (; ndx != m_pPrefetchSinkList->End(); ++ndx)
  1175. {
  1176.     IHXPrefetchSink* pPrefetchSink = (IHXPrefetchSink*) (*ndx);
  1177.     pPrefetchSink->PrefetchTrackDone(uGroupIndex, uTrackIndex, status);
  1178. }
  1179.     }
  1180.     return rc;
  1181. }
  1182. #endif /* HELIX_FEATURE_PREFETCH */
  1183. void
  1184. HXAdvancedGroup::Close(void)
  1185. {
  1186.     HXBasicGroup::Close();
  1187.     HX_RELEASE(m_pGroupProperties);
  1188.     IHXPrefetch*   pPrefetch = NULL;
  1189.     CHXMapLongToObj::Iterator i;
  1190.     CHXSimpleList::Iterator j;
  1191.     m_uPrefetchTrackCount = 0;
  1192.     if (m_pTrackSinkList)
  1193.     {
  1194. CHXSimpleList::Iterator ndx = m_pTrackSinkList->Begin();
  1195. for (; ndx != m_pTrackSinkList->End(); ++ndx)
  1196. {
  1197.     IHXTrackSink* pTrackSink = (IHXTrackSink*) (*ndx);
  1198.     HX_RELEASE(pTrackSink);
  1199. }
  1200. HX_DELETE(m_pTrackSinkList);
  1201.     }
  1202. #if defined(HELIX_FEATURE_PREFETCH)
  1203.     if (m_pPrefetchTrackMap)
  1204.     {
  1205. i = m_pPrefetchTrackMap->Begin();
  1206. for(; i != m_pPrefetchTrackMap->End(); ++i)
  1207. {
  1208.     IHXValues* pTrack = (IHXValues*)(*i);
  1209.     HX_RELEASE(pTrack);
  1210. }
  1211. HX_DELETE(m_pPrefetchTrackMap);
  1212.     }
  1213.     if (m_pPrefetchSinkList)
  1214.     {
  1215. j = m_pPrefetchSinkList->Begin();
  1216. for (; j != m_pPrefetchSinkList->End(); ++j)
  1217. {
  1218.     IHXPrefetchSink* pPrefetchSink = (IHXPrefetchSink*) (*j);
  1219.     HX_RELEASE(pPrefetchSink);
  1220. }
  1221. HX_DELETE(m_pPrefetchSinkList);
  1222.     }
  1223.     if (m_bPrefetchSinkAdded)
  1224.     {
  1225. if (HXR_OK == m_pPlayer->QueryInterface(IID_IHXPrefetch, (void**)&pPrefetch))
  1226. {
  1227.     pPrefetch->RemovePrefetchSink(this);
  1228.     m_bPrefetchSinkAdded = FALSE;
  1229. }
  1230. HX_RELEASE(pPrefetch);
  1231.     }
  1232. #endif /* HELIX_FEATURE_PREFETCH */
  1233.     if (m_pPersistentComponentPropertyMap)
  1234.     {
  1235. i = m_pPersistentComponentPropertyMap->Begin();
  1236. for(; i != m_pPersistentComponentPropertyMap->End(); ++i)
  1237. {
  1238.     IHXValues* pValues = (IHXValues*)(*i);
  1239.     HX_RELEASE(pValues);
  1240. }
  1241. HX_DELETE(m_pPersistentComponentPropertyMap);
  1242.     }
  1243. }
  1244. /*HXAdvancedGroupManager*/
  1245. HXAdvancedGroupManager::HXAdvancedGroupManager(HXPlayer* pPlayer)
  1246.                        :HXBasicGroupManager(pPlayer)
  1247.                        ,m_pMasterTAC(NULL)
  1248. {
  1249. }
  1250. HXAdvancedGroupManager::~HXAdvancedGroupManager(void)
  1251. {
  1252.     Close();
  1253. }
  1254. void HXAdvancedGroupManager::SetMasterTAC(HXMasterTAC* pMasterTAC)
  1255. {
  1256.     m_pMasterTAC = pMasterTAC;
  1257.     m_pMasterTAC->AddRef();
  1258. }
  1259. void
  1260. HXAdvancedGroupManager::PersistentComponentAdded(UINT16 uGroupIndex, UINT16 uTrackIndex)
  1261. {
  1262.     HXAdvancedGroup* pGroup = NULL;
  1263.     CHXSimpleList::Iterator ndx;
  1264.     if (HXR_OK == GetGroup(uGroupIndex, (IHXGroup*&)pGroup))
  1265.     {
  1266. pGroup->PersistentComponentAdded(uTrackIndex);
  1267.     }
  1268.     HX_RELEASE(pGroup);
  1269.     return;
  1270. }
  1271. void 
  1272. HXAdvancedGroupManager::PersistentComponentRemoved(UINT16 uGroupIndex, UINT16 uTrackIndex)
  1273. {    
  1274.     HXAdvancedGroup* pGroup = NULL;
  1275.     CHXSimpleList::Iterator ndx;
  1276.     if (HXR_OK == GetGroup(uGroupIndex, (IHXGroup*&)pGroup))
  1277.     {
  1278. pGroup->PersistentComponentRemoved(uTrackIndex);
  1279.     }
  1280.     return;
  1281. }
  1282. /*
  1283.  *  IHXGroupManager methods
  1284.  */
  1285. /************************************************************************
  1286. *  Method:
  1287. *      IHXGroupManager::CreateGroup
  1288. *  Purpose:
  1289. * Create a group
  1290. */
  1291. STDMETHODIMP
  1292. HXAdvancedGroupManager::CreateGroup(REF(IHXGroup*) pGroup)
  1293. {
  1294.     pGroup = new HXAdvancedGroup(this);
  1295.     if (!pGroup)
  1296.     {
  1297. return HXR_OUTOFMEMORY;
  1298.     }
  1299.     
  1300.     pGroup->AddRef();
  1301.     return HXR_OK;
  1302. }
  1303. /************************************************************************
  1304. *  Method:
  1305. *      IHXGroupManager::AddGroup
  1306. *  Purpose:
  1307. * Add a group to the presentation.
  1308. */
  1309. STDMETHODIMP
  1310. HXAdvancedGroupManager::AddGroup(IHXGroup* /*IN*/ pGroup)
  1311. {
  1312.     HX_RESULT         theErr = HXR_OK;
  1313.     UINT16         uInsertGroupAt = 0;
  1314.     UINT32         ulLastGroupInRAM20 = 0;
  1315.     UINT32         ulPersistentComponentID = 0;
  1316.     IHXValues*         pGroupProperties = NULL;
  1317.     HXAdvancedTrack*    pHXTrack = NULL;
  1318.     IHXPersistentComponent* pPersistentComponent = NULL;
  1319.     HXPersistentComponentManager* pPersistentComponentManager = NULL;
  1320.     if (!pGroup)
  1321.     {
  1322. return HXR_UNEXPECTED;
  1323.     }
  1324.     
  1325.     pGroupProperties = ((HXAdvancedGroup*)pGroup)->m_pGroupProperties;
  1326. #if defined(HELIX_FEATURE_NESTEDMETA)
  1327.     if (pGroupProperties)
  1328.     {
  1329. if (HXR_OK != pGroupProperties->GetPropertyULONG32("LastGroupInRAM20", ulLastGroupInRAM20) &&
  1330.     HXR_OK == pGroupProperties->GetPropertyULONG32("PersistentComponentID", ulPersistentComponentID))
  1331. {
  1332.     pPersistentComponentManager = m_pPlayer->m_pPersistentComponentManager;
  1333.     if (HXR_OK == pPersistentComponentManager->GetPersistentComponent(ulPersistentComponentID,
  1334.       pPersistentComponent))
  1335.     {
  1336. ((HXPersistentComponent*)pPersistentComponent)->m_uGroups++;
  1337. uInsertGroupAt = ((HXPersistentComponent*)pPersistentComponent)->m_pSourceInfo->m_uGroupID +
  1338.  ((HXPersistentComponent*)pPersistentComponent)->m_uGroups;
  1339. theErr = InsertGroupAt(uInsertGroupAt, pGroup);
  1340.     }
  1341.     else
  1342.     {
  1343. HX_ASSERT(FALSE);
  1344.     }
  1345. }
  1346. else
  1347. {
  1348.     HX_ASSERT(ulLastGroupInRAM20);
  1349.     InsertGroupAt(m_uGroupCount, pGroup);
  1350. }
  1351.     }
  1352.     else
  1353. #endif /* HELIX_FEATURE_NESTEDMETA */
  1354.     {
  1355. InsertGroupAt(m_uGroupCount, pGroup);
  1356.     }
  1357.     
  1358.     HX_RELEASE(pPersistentComponent);
  1359.     return theErr;
  1360. }
  1361. /************************************************************************
  1362. *  Method:
  1363. *      IHXGroupManager::RemoveGroup
  1364. *  Purpose:
  1365. * Remove an already added group
  1366. */
  1367. STDMETHODIMP
  1368. HXAdvancedGroupManager::RemoveGroup(UINT16  /*IN*/ uGroupIndex)
  1369. {
  1370.     HX_RESULT theErr = HXR_OK;
  1371.     int i = 0;
  1372.     CHXMapLongToObj* pNewGroupMap = NULL;
  1373.     IHXGroup* pHXGroupRemoved = NULL;
  1374.     IHXGroup* pHXGroup = NULL;
  1375.     CHXSimpleList::Iterator ndx;
  1376.     if (!m_pGroupMap->Lookup(uGroupIndex, (void*&)pHXGroupRemoved))
  1377.     {
  1378. theErr = HXR_UNEXPECTED;
  1379. goto cleanup;
  1380.     }
  1381.     m_pGroupMap->RemoveKey(uGroupIndex);
  1382.     // adjust track map index
  1383.     pNewGroupMap = new CHXMapLongToObj;
  1384.     for (i = 0; i < uGroupIndex; i++)
  1385.     {
  1386. m_pGroupMap->Lookup(i, (void*&)pHXGroup);
  1387. HX_ASSERT(pHXGroup);
  1388. (*pNewGroupMap)[i] = pHXGroup;
  1389.     }
  1390.     for (i = uGroupIndex + 1; i < m_uGroupCount; i++)
  1391.     {
  1392. m_pGroupMap->Lookup(i, (void*&)pHXGroup);
  1393. HX_ASSERT(pHXGroup);
  1394. ((HXAdvancedGroup*)pHXGroup)->m_uGroupIndex = i - 1;
  1395. (*pNewGroupMap)[i - 1] = pHXGroup;
  1396.     }
  1397.     HX_DELETE(m_pGroupMap);
  1398.     m_pGroupMap = pNewGroupMap;
  1399.     m_uGroupCount--;
  1400.     
  1401.     ndx = m_pSinkList->Begin();
  1402.     for (; ndx != m_pSinkList->End(); ++ndx)
  1403.     {
  1404. IHXGroupSink* pGroupSink = (IHXGroupSink*) (*ndx);
  1405. pGroupSink->GroupRemoved(uGroupIndex, pHXGroupRemoved);
  1406.     }
  1407. cleanup:
  1408.     HX_RELEASE(pHXGroupRemoved);
  1409.     return theErr;
  1410. }    
  1411. STDMETHODIMP
  1412. HXAdvancedGroupManager::SetCurrentGroup(UINT16 uGroupIndex)
  1413. {
  1414.     HX_RESULT res = HXBasicGroupManager::SetCurrentGroup(uGroupIndex);
  1415. #if defined(HELIX_FEATURE_MASTERTAC)
  1416.     if (SUCCEEDED(res) && m_pMasterTAC)
  1417.     {
  1418.        // check for TAC info from new group
  1419.        m_pMasterTAC->ResetTAC(TRUE, TRUE); // reset status & clear master props
  1420.        m_pMasterTAC->CheckGroupForTACInfo(uGroupIndex);
  1421.     }
  1422. #endif // defined(HELIX_FEATURE_MASTERTAC)
  1423.     return res;
  1424. }
  1425. HX_RESULT     
  1426. HXAdvancedGroupManager::RepeatTrackAdded(UINT16 uGroupIndex, UINT16 uTrackIndex, IHXValues* pTrack)
  1427. {
  1428.     return m_pPlayer->RepeatTrackAdded(uGroupIndex, uTrackIndex, pTrack);
  1429. }
  1430. void
  1431. HXAdvancedGroupManager::Close(void)
  1432. {
  1433.     HX_RELEASE(m_pMasterTAC);
  1434.     HXBasicGroupManager::Close();
  1435. }