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

Symbian

开发平台:

C/C++

  1.     m_pGroupManager->SetCurrentGroup(0);
  2. #else
  3.     HX_DELETE(m_pURL);
  4.     CloseAllRenderers(0);
  5.     m_pURL = new CHXURL(*pURL);
  6.     if( m_pURL )
  7.     {
  8.         theErr = m_pURL->GetLastError();
  9.     }
  10.     else
  11.     {
  12.         theErr = HXR_OUTOFMEMORY;
  13.     }
  14.     if (HXR_OK == theErr)
  15.     {
  16.         pSourceInfo = NewSourceInfo();
  17.         if (pSourceInfo)
  18.         {
  19.             theErr = AddURL(pSourceInfo, TRUE);
  20.         }
  21.         else
  22.         {
  23.             theErr = HXR_OUTOFMEMORY;
  24.         }
  25.     }
  26. #endif /* HELIX_FEATURE_BASICGROUPMGR */
  27.     if (HXR_OK == theErr)
  28.     {
  29.         // At this point, we setup the number of active streams to be the
  30.         // number of sctreams described in the SourceList!
  31.         UpdateSourceActive();
  32.         if (m_bIsFirstBeginPending)
  33.         {
  34.             m_bIsFirstBeginPending = FALSE;
  35.             Begin();
  36.         }
  37.     }
  38.     else
  39.     {
  40.         HX_DELETE(m_pURL);
  41.     }
  42.     return theErr;
  43. };
  44. /************************************************************************
  45.  *  Method:
  46.  *      IHXPlayer::AddURL
  47.  *  Purpose:
  48.  *      Tell the player to add an URL to the current source list.
  49.  */
  50. HX_RESULT HXPlayer::AddURL(SourceInfo*& /*OUT*/ pSourceInfo, BOOL bAltURL)
  51. {
  52.     HX_RESULT   theErr = HXR_OK;
  53.     HXSource*   pSource = NULL;
  54.     theErr = CreateSourceInfo(pSourceInfo, bAltURL);
  55.     if (theErr != HXR_OK)
  56.     {
  57.         goto cleanup;
  58.     }
  59.     pSource = pSourceInfo->m_pSource;
  60.     /* add to the list of sources for this player... */
  61.     if (pSource)
  62.     {
  63.         if (!m_bPartOfNextGroup)
  64.         {
  65. #if defined(HELIX_FEATURE_PREFETCH)
  66.             if (pSourceInfo->m_bPrefetch)
  67.             {
  68.                 if (!m_pPrefetchManager)
  69.                 {
  70.                     m_pPrefetchManager = new PrefetchManager(this);
  71.                 }
  72.                 m_pPrefetchManager->AddSource(pSourceInfo);
  73.                 pSourceInfo->m_pSource->PartOfPrefetchGroup(TRUE);
  74.             }
  75.             else
  76. #endif /* HELIX_FEATURE_PREFETCH */
  77.             {
  78.                 m_pSourceMap->SetAt((void*) pSourceInfo->m_pSource,
  79.                                   (void*) pSourceInfo);
  80.                 if (pSource->GetDelay() >= m_ulCurrentPlayTime &&
  81.                     pSource->GetDelay() - m_ulCurrentPlayTime <= MIN_DELAYBEFORE_START)
  82.                 {
  83.                     pSourceInfo->m_bTobeInitializedBeforeBegin = TRUE;
  84.                     m_uNumSourceToBeInitializedBeforeBegin++;
  85.                 }
  86.                 m_bPlayerWithoutSources = FALSE;
  87.                 m_bSourceMapUpdated = TRUE;
  88.                 m_bForceStatsUpdate = TRUE;
  89.             }
  90.         }
  91.         else
  92.         {
  93.             if (pSource->GetDelay() <= MIN_DELAYBEFORE_START)
  94.             {
  95.                 pSourceInfo->m_bTobeInitializedBeforeBegin = TRUE;
  96.                 /* We will increment the
  97.                  * m_uNumSourceToBeInitializedBeforeBegin value
  98.                  * once we start this next group
  99.                  */
  100.                 //m_uNumSourceToBeInitializedBeforeBegin++;
  101.             }
  102.         }
  103.     }
  104.     /* Are we adding more sources mid presentation ? */
  105.     if (!m_bPartOfNextGroup && !pSourceInfo->m_bPrefetch)
  106.     {
  107.         m_uNumSourcesActive++;
  108.         m_uNumCurrentSourceNotDone++;
  109.     }
  110. cleanup:
  111.     return (theErr);
  112. }
  113. HX_RESULT
  114. HXPlayer::CreateSourceInfo(SourceInfo*& pSourceInfo, BOOL bAltURL)
  115. {
  116.     HX_RESULT   theErr = HXR_OK;
  117.     HXSource*   pSource = NULL;
  118.     if (m_pURL->IsNetworkProtocol())
  119.     {
  120.         theErr = InitializeNetworkDrivers();
  121.         if (!theErr)
  122.         {
  123.             theErr = DoNetworkOpen(pSourceInfo, bAltURL);
  124.         }
  125.     }
  126.     else
  127.     {
  128.         // Only send in URL now.
  129.         theErr = DoFileSystemOpen(pSourceInfo, bAltURL);
  130.     }
  131.     pSource = pSourceInfo->m_pSource;
  132.     if (!theErr && pSource)
  133.     {
  134.         pSourceInfo->m_bInitialized = FALSE;
  135.         if (HXR_OK != pSource->QueryInterface(IID_IHXPendingStatus,
  136.                                             (void**)&(pSourceInfo->m_pStatus)))
  137.         {
  138.             pSourceInfo->m_pStatus = NULL;
  139.         }
  140.     }
  141.     if (HXR_OK != theErr)
  142.     {
  143.         HX_DELETE(pSourceInfo);
  144.     }
  145.     return (theErr);
  146. }
  147. HX_RESULT
  148. HXPlayer::PrepareSourceInfo(IHXValues* pTrack, SourceInfo*& pSourceInfo)
  149. {
  150. #if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
  151.     HX_RESULT       rc = HXR_OK;
  152.     char            szMaxDuration[] = "maxduration";
  153.     char            szIndefiniteDuration[] = "indefiniteduration";
  154.     char            szPrefetchType[] = "PrefetchType";
  155.     char            szPrefetchValue[] = "PrefetchValue";
  156.     char            szSoundLevel[] = "soundLevel";
  157.     char            szAudioDeviceReflushHint[] = "audioDeviceReflushHint";
  158.     char            szPersistentComponentID[] = "PersistentComponentID";
  159.     char            szFill[] = "fill";
  160.     UINT32          ulValue = 0;
  161. #ifdef SEQ_DEPENDENCY
  162.     char            szTrack_hint[] = "track-hint";
  163. #endif
  164.     pSourceInfo->m_bAudioDeviceReflushHint = FALSE;
  165.     pSourceInfo->m_uSoundLevel = 100;
  166.     pSourceInfo->m_bIndefiniteDuration = FALSE;
  167.     pSourceInfo->m_ulMaxDuration = 0;
  168.     pSourceInfo->m_ulPersistentComponentID = MAX_UINT32;
  169.     pSourceInfo->m_ulPersistentComponentSelfID = MAX_UINT32;
  170. #if defined(HELIX_FEATURE_PREFETCH)
  171.     // read prefetch info
  172.     if (HXR_OK == pTrack->GetPropertyULONG32(szPrefetchType, ulValue) && ulValue)
  173.     {
  174.         pSourceInfo->m_bPrefetch = TRUE;
  175.         pSourceInfo->m_prefetchType = (PrefetchType)ulValue;
  176.         if (HXR_OK == pTrack->GetPropertyULONG32(szPrefetchValue, ulValue) && ulValue)
  177.         {
  178.             pSourceInfo->m_ulPrefetchValue = ulValue;
  179.         }
  180.     }
  181. #endif /* HELIX_FEATURE_PREFETCH */
  182.     // read audioDeviceReflushHint
  183.     if (HXR_OK == pTrack->GetPropertyULONG32(szAudioDeviceReflushHint, ulValue) && ulValue)
  184.     {
  185.         pSourceInfo->m_bAudioDeviceReflushHint = TRUE;
  186.     }
  187.     // read soundLevel
  188.     if (HXR_OK == pTrack->GetPropertyULONG32(szSoundLevel, ulValue))
  189.     {
  190.         pSourceInfo->m_uSoundLevel = (UINT16)ulValue;
  191.     }
  192.     if (HXR_OK == pTrack->GetPropertyULONG32(szIndefiniteDuration, ulValue) && ulValue)
  193.     {
  194.         pSourceInfo->m_bIndefiniteDuration = TRUE;
  195.     }
  196.     if (HXR_OK == pTrack->GetPropertyULONG32(szMaxDuration, ulValue))
  197.     {
  198.         pSourceInfo->m_ulMaxDuration = ulValue;
  199.     }
  200.     if (HXR_OK == pTrack->GetPropertyULONG32(szPersistentComponentID, ulValue))
  201.     {
  202.         pSourceInfo->m_ulPersistentComponentID = ulValue;
  203.     }
  204.     if (HXR_OK == pTrack->GetPropertyULONG32(szFill, ulValue))
  205.     {
  206.         pSourceInfo->m_fillType = (FillType)ulValue;
  207.     }
  208. #ifdef SEQ_DEPENDENCY
  209.     IHXBuffer* pDependency = NULL;
  210.     pTrack->GetPropertyCString(szTrack_hint,pDependency);
  211.     if (pDependency && *(pDependency->GetBuffer()))
  212.     {
  213.         pSourceInfo->SetDependency(pDependency);
  214.     }
  215.     HX_RELEASE(pDependency);
  216. #endif /*SEQ_DEPENDENCY*/
  217.     return rc;
  218. #else
  219.     return HXR_NOTIMPL;
  220. #endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
  221. }
  222. /************************************************************************
  223.  *      Method:
  224.  *          IHXPendingStatus::GetStatus
  225.  *      Purpose:
  226.  *          Called by the user to get the current pending status from an object
  227.  */
  228. STDMETHODIMP
  229. HXPlayer::GetStatus
  230. (
  231.     REF(UINT16) uStatusCode,
  232.     REF(IHXBuffer*) pStatusDesc,
  233.     REF(UINT16) ulPercentDone
  234. )
  235. {
  236.     HX_RESULT           hResult = HXR_OK;
  237.     UINT16              statusCode = 0;
  238.     UINT16              percentDone = 0;
  239.     UINT16              totalPercentDone = 0;
  240.     BOOL                bIsContacting = FALSE;
  241.     BOOL                bIsBuffering = FALSE;
  242.     BOOL                bIsReady = FALSE;
  243.     BOOL                bInitializing = FALSE;
  244.     IHXPendingStatus*   pStatus = NULL;
  245.     // initialize(default)
  246.     uStatusCode = HX_STATUS_READY;
  247.     pStatusDesc = NULL;
  248.     ulPercentDone = 0;
  249.     // collect info from all the sources
  250.     CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
  251.     for (; ndxSource != m_pSourceMap->End(); ++ndxSource)
  252.     {
  253.         SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
  254.         pStatus = pSourceInfo->m_pStatus;
  255.         if (pStatus && HXR_OK == pStatus->GetStatus(statusCode, pStatusDesc, percentDone))
  256.         {
  257.             if (HX_STATUS_CONTACTING == statusCode)
  258.             {
  259.                 bIsContacting = TRUE;
  260.                 break;
  261.             }
  262.             else if (HX_STATUS_BUFFERING == statusCode)
  263.             {
  264.                 bIsBuffering = TRUE;
  265.                 totalPercentDone += percentDone;
  266.             }
  267.             else if (HX_STATUS_READY == statusCode)
  268.             {
  269.                 bIsReady = TRUE;
  270.                 totalPercentDone += 100;
  271.             }
  272.             else if (HX_STATUS_INITIALIZING == statusCode)
  273.             {
  274.                 bInitializing = TRUE;
  275.             }
  276.         }
  277.     }
  278.     if (bInitializing)
  279.     {
  280.         uStatusCode = HX_STATUS_INITIALIZING;
  281.         ulPercentDone = 0;
  282.     }
  283.     else if (bIsContacting)
  284.     {
  285.         uStatusCode = HX_STATUS_CONTACTING;
  286.         ulPercentDone = 0;
  287.     }
  288.     else if (bIsBuffering)
  289.     {
  290.         uStatusCode = HX_STATUS_BUFFERING;
  291.         pStatusDesc = NULL;
  292.         ulPercentDone = totalPercentDone / m_pSourceMap->GetCount();
  293.     }
  294.     else if (bIsReady)
  295.     {
  296.         uStatusCode = HX_STATUS_READY;
  297.         pStatusDesc = NULL;
  298.         ulPercentDone = 0;
  299.     }
  300.     return hResult;
  301. }
  302. HX_RESULT
  303. HXPlayer::DoOpenGroup(UINT16 nGroupNumber)
  304. {
  305. #if defined(HELIX_FEATURE_BASICGROUPMGR)
  306.     HX_RESULT   theErr = HXR_OK;
  307.     IHXGroup*   pGroup = 0;
  308.     HX_VERIFY((theErr = m_pGroupManager->GetGroup(nGroupNumber, pGroup)) == HXR_OK);
  309.     if (theErr)
  310.     {
  311.         return theErr;
  312.     }
  313.     if (!m_bPartOfNextGroup)
  314.     {
  315.         m_bInitialized = FALSE; //so that we InitializeRenderers for this group
  316.         m_bIsPresentationClosedToBeSent = FALSE;
  317.         StopAllStreams(END_STOP);
  318.         ResetGroup();
  319.         CloseAllRenderers(m_nCurrentGroup); //kill all currently open renderers
  320.         m_bIsDone   = FALSE;
  321.     }
  322.     // add all the tracks in the group to the player's source list
  323.     UINT16          nTrackCount = pGroup->GetTrackCount();
  324.     IHXValues*      pTrack = NULL;
  325.     IHXPrefetch*    pPrefetch = NULL;
  326.     HX_RESULT       theErrToReturn = HXR_OK;
  327.     for (UINT16 nTrackIndex = 0; nTrackIndex < nTrackCount; nTrackIndex++)
  328.     {
  329.         if ((theErr = pGroup->GetTrack(nTrackIndex,pTrack)) == HXR_OK)
  330.         {
  331.             theErr = OpenTrack(pTrack, nGroupNumber, nTrackIndex);
  332.             if (theErr && !theErrToReturn)
  333.             {
  334.                 theErrToReturn = theErr;
  335.             }
  336.             HX_RELEASE(pTrack);
  337.         }
  338.     }
  339. #if defined(HELIX_FEATURE_PREFETCH)
  340.     if (HXR_OK == pGroup->QueryInterface(IID_IHXPrefetch, (void**)&pPrefetch))
  341.     {
  342.         nTrackCount = pPrefetch->GetPrefetchTrackCount();
  343.         for (UINT16 nTrackIndex = 0; nTrackIndex < nTrackCount; nTrackIndex++)
  344.         {
  345.             if ((theErr = pPrefetch->GetPrefetchTrack(nTrackIndex,pTrack)) == HXR_OK &&
  346.                 pTrack)
  347.             {
  348.                 theErr = OpenTrack(pTrack, nGroupNumber, nTrackIndex);
  349.                 if (theErr && !theErrToReturn)
  350.                 {
  351.                     theErrToReturn = theErr;
  352.                 }
  353.                 HX_RELEASE(pTrack);
  354.             }
  355.         }
  356.     }
  357. #endif /* HELIX_FEATURE_PREFETCH */
  358.     HX_RELEASE(pPrefetch);
  359.     HX_RELEASE(pGroup);
  360.     return theErrToReturn;
  361. #else
  362.     return HXR_NOTIMPL;
  363. #endif /* HELIX_FEATURE_BASICGROUPMGR */
  364. }
  365. HX_RESULT
  366. HXPlayer::DoAltURLOpen(char* pAltURL, BOOL bDefault, SourceInfo* pMainSourceInfo)
  367. {
  368. #if defined(HELIX_FEATURE_ALT_URL)
  369.     HX_RESULT   hr = HXR_OK;
  370.     SourceInfo* pSourceInfo = NULL;
  371.     m_bIsDone   = FALSE;
  372.     ResetActiveRequest();
  373.     HX_DELETE(m_pURL);
  374.     m_pURL = new CHXURL(pAltURL);
  375.     if( m_pURL )
  376.     {
  377.         pAltURL = (char*) m_pURL->GetURL();
  378.         hr = m_pURL->GetLastError();
  379.     }
  380.     else
  381.     {
  382.         hr = HXR_OUTOFMEMORY;
  383.     }
  384.     if (hr)
  385.     {
  386.         HX_DELETE(m_pURL);
  387.         goto cleanup;
  388.     }
  389.     pSourceInfo = NewSourceInfo();
  390.     if (pSourceInfo)
  391.     {
  392.         pSourceInfo->m_uGroupID = pMainSourceInfo->m_uGroupID;
  393.         pSourceInfo->m_uTrackID = pMainSourceInfo->m_uTrackID;
  394.         pSourceInfo->m_bPrefetch = pMainSourceInfo->m_bPrefetch;
  395.         pSourceInfo->m_id = pMainSourceInfo->m_id;
  396.         pSourceInfo->m_bAltURL = TRUE;
  397.         pSourceInfo->m_lastErrorFromMainURL = pMainSourceInfo->m_lastErrorFromMainURL;
  398.         pSourceInfo->m_lastErrorStringFromMainURL = pMainSourceInfo->m_lastErrorStringFromMainURL;
  399.         pSourceInfo->m_ulPersistentComponentID = pMainSourceInfo->m_ulPersistentComponentID;
  400.     }
  401.     else
  402.     {
  403.         hr = HXR_OUTOFMEMORY;
  404.         goto cleanup;
  405.     }
  406.     hr = AddURL(pSourceInfo, TRUE);
  407.     if (HXR_OK == hr && pSourceInfo->m_pSource)
  408.     {
  409.         pSourceInfo->m_pSource->SetAltURLType(bDefault);
  410.     }
  411.     SchedulePlayer();
  412. cleanup:
  413.     return hr;
  414. #else
  415.     return HXR_NOTIMPL;
  416. #endif /* HELIX_FEATURE_ALT_URL */
  417. }
  418. HX_RESULT
  419. HXPlayer::SpawnSourceIfNeeded(SourceInfo* pSourceInfo)
  420. {
  421. #if defined(HELIX_FEATURE_SMIL_REPEAT)
  422.     HX_RESULT   theErr = HXR_OK;
  423.     RepeatInfo* pRepeatInfo = NULL;
  424.     // spawned the source if it is repeated
  425.     if (pSourceInfo->m_pRepeatList                  &&
  426.         !pSourceInfo->m_pPeerSourceInfo             &&
  427.         pSourceInfo->m_pSource->IsInitialized())
  428.     {
  429.         SourceInfo* pPeerSourceInfo = NewSourceInfo();
  430.         if( !pPeerSourceInfo )
  431.         {
  432.             return HXR_OUTOFMEMORY;
  433.         }
  434.         CHXURL*     pURL = m_pURL;
  435.         const char* pszURL = pSourceInfo->m_pSource->GetURL();
  436.         m_pURL = new CHXURL(pszURL);
  437.         if( !m_pURL )
  438.         {
  439.             HX_DELETE(pSourceInfo);
  440.             return HXR_OUTOFMEMORY;
  441.         }
  442.         pPeerSourceInfo->m_curPosition = pSourceInfo->m_curPosition;
  443.         pRepeatInfo = (RepeatInfo*)pSourceInfo->m_pRepeatList->GetAtNext(pPeerSourceInfo->m_curPosition);
  444.         if (pRepeatInfo->ulStart)
  445.         {
  446.             m_pURL->AddOption("Start", pRepeatInfo->ulStart);
  447.         }
  448.         if (pRepeatInfo->ulEnd)
  449.         {
  450.             m_pURL->AddOption("End", pRepeatInfo->ulEnd);
  451.         }
  452.         m_pURL->AddOption("Delay", pRepeatInfo->ulDelay);
  453.         m_pURL->AddOption("Duration", pRepeatInfo->ulDuration);
  454.         pPeerSourceInfo->m_bLeadingSource = FALSE;
  455.         pPeerSourceInfo->m_bRepeatIndefinite = pSourceInfo->m_bRepeatIndefinite;
  456.         pPeerSourceInfo->m_ulRepeatInterval = pSourceInfo->m_ulRepeatInterval;
  457.         pPeerSourceInfo->m_ulMaxDuration = pSourceInfo->m_ulMaxDuration;
  458.         pPeerSourceInfo->m_bTrackStartedToBeSent = pSourceInfo->m_bTrackStartedToBeSent;
  459.         pPeerSourceInfo->m_uGroupID = pSourceInfo->m_uGroupID;
  460.         pPeerSourceInfo->m_uTrackID = pRepeatInfo->uTrackID;
  461.         pPeerSourceInfo->m_ulPersistentComponentID = pSourceInfo->m_ulPersistentComponentID;
  462.         pPeerSourceInfo->m_ulTotalTrackDuration = pSourceInfo->m_ulTotalTrackDuration;
  463.         theErr = CreateSourceInfo(pPeerSourceInfo, FALSE);
  464.         if(pPeerSourceInfo && pPeerSourceInfo->m_pSource)
  465.         {
  466.             pPeerSourceInfo->m_pSource->m_ulOriginalDelay = pSourceInfo->m_pSource->m_ulOriginalDelay;
  467.             pSourceInfo->m_pPeerSourceInfo = pPeerSourceInfo;
  468.             pPeerSourceInfo->m_pPeerSourceInfo = pSourceInfo;
  469.         }
  470.         HX_DELETE(m_pURL);
  471.         m_pURL = pURL;
  472.     }
  473.     return theErr;
  474. #else
  475.     return HXR_NOTIMPL;
  476. #endif /* HELIX_FEATURE_SMIL_REPEAT */
  477. }
  478. HX_RESULT
  479. HXPlayer::SwitchSourceIfNeeded(void)
  480. {
  481. #if defined(HELIX_FEATURE_SMIL_REPEAT)
  482.     // swapping the repeated sources if it's time
  483.     HX_RESULT   theErr = HXR_OK;
  484.     UINT32      ulTotalTrackDuration = 0;
  485.     UINT32      ulPeerSourceDuration = 0;
  486.     UINT32      ulPeerSourceDelay = 0;
  487.     SourceInfo* pSourceInfo = NULL;
  488.     CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
  489.     for (;!theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
  490.     {
  491.         pSourceInfo = (SourceInfo*)(*ndxSource);
  492.         if (!pSourceInfo->m_pPeerSourceInfo ||
  493.             !pSourceInfo->m_pPeerSourceInfo->m_pSource)
  494.         {
  495.             continue;
  496.         }
  497.         ulTotalTrackDuration = pSourceInfo->GetActiveDuration();
  498.         ulPeerSourceDuration = pSourceInfo->m_pPeerSourceInfo->m_pSource->GetDuration();
  499.         ulPeerSourceDelay = pSourceInfo->m_pPeerSourceInfo->m_pSource->GetDelay();
  500.         if (ulTotalTrackDuration > m_ulCurrentPlayTime              &&
  501.             ulPeerSourceDelay > pSourceInfo->m_pSource->GetDelay()  &&
  502.             ulPeerSourceDelay <= m_ulCurrentPlayTime)
  503.         {
  504.             if (ulPeerSourceDuration > ulTotalTrackDuration)
  505.             {
  506.                 pSourceInfo->m_pPeerSourceInfo->UpdateDuration(ulTotalTrackDuration - ulPeerSourceDelay);
  507.             }
  508.             m_pSourceMap->RemoveKey(pSourceInfo->m_pSource);
  509.             if (!pSourceInfo->m_pSource->IsSourceDone())
  510.             {
  511.                 pSourceInfo->m_pSource->SetEndOfClip(TRUE);
  512.             }
  513.             pSourceInfo->m_bDone = TRUE;
  514.             pSourceInfo->m_bRepeatPending = TRUE;
  515.             pSourceInfo->m_pPeerSourceInfo->m_bRepeatPending = FALSE;
  516.             m_pSourceMap->SetAt((void*) pSourceInfo->m_pPeerSourceInfo->m_pSource,
  517.                               (void*) pSourceInfo->m_pPeerSourceInfo);
  518.             m_bSourceMapUpdated = TRUE;
  519.             m_bForceStatsUpdate = TRUE;
  520.             break;
  521.         }
  522.     }
  523.     return theErr;
  524. #else 
  525.     return HXR_NOTIMPL;
  526. #endif /* HELIX_FEATURE_SMIL_REPEAT */
  527. }
  528. HX_RESULT
  529. HXPlayer::OpenTrack(IHXValues* pTrack, UINT16 uGroupID, UINT16 uTrackID)
  530. {
  531. #if defined(HELIX_FEATURE_BASICGROUPMGR)
  532.     HX_RESULT           theErr = HXR_OK;
  533.     IHXBuffer*          pBuffer = NULL;
  534.     IHXBuffer*          pID = NULL;
  535.     SourceInfo*         pSourceInfo = NULL;
  536.     const char*         pURL = NULL;
  537.     char                szID[] = "id";
  538.     char                szUrl[] = "url";
  539.     char                szSrc[] = "src";
  540.     char                szStart[] = "Start";
  541.     char                szEnd[] = "End";
  542.     char                szDelay[] = "Delay";
  543.     char                szDuration[] = "Duration";
  544.     UINT32              ulValue = 0;
  545.     theErr = pTrack->GetPropertyCString(szUrl,pBuffer);
  546.     /*
  547.      * Make sure everyone is setting url property (and not the
  548.      * src property) for consistency.
  549.      */
  550.     /* temp - for now support both "src" & "url" */
  551.     if (theErr)
  552.     {
  553.         theErr = pTrack->GetPropertyCString(szSrc,pBuffer);
  554.     }
  555.     if (theErr)
  556.     {
  557.         theErr = HXR_INVALID_PATH;
  558.         goto cleanup;
  559.     }
  560.     pURL = (const char*)pBuffer->GetBuffer();
  561.     if (!pURL || !*pURL)
  562.     {
  563.         theErr = HXR_INVALID_PATH;
  564.         goto cleanup;
  565.     }
  566.     // Cleanup any url object!
  567.     HX_DELETE(m_pURL);
  568.     m_pURL = new CHXURL(pURL); //parse the url
  569.     if (!m_pURL)
  570.     {
  571.         theErr = HXR_OUTOFMEMORY;
  572.         goto cleanup;
  573.     }
  574.     theErr = m_pURL->GetLastError();
  575.     if (theErr)
  576.     {
  577.         goto cleanup;
  578.     }
  579.     theErr = OpenTrackExt();
  580.     //temp - DoNetworkOpen/DoFSOpen extract these properties from m_pURL
  581.     if (HXR_OK == pTrack->GetPropertyULONG32(szStart,ulValue))
  582.     {
  583.         m_pURL->AddOption(szStart, ulValue);
  584.     }
  585.     //pProperty = NULL;
  586.     if (HXR_OK == pTrack->GetPropertyULONG32(szEnd,ulValue))
  587.     {
  588.         m_pURL->AddOption(szEnd, ulValue);
  589.     }
  590.     if (HXR_OK == pTrack->GetPropertyULONG32(szDelay,ulValue))
  591.     {
  592.         m_pURL->AddOption(szDelay, ulValue);
  593.     }
  594.     if (HXR_OK == pTrack->GetPropertyULONG32(szDuration,ulValue))
  595.     {
  596.         m_pURL->AddOption(szDuration, ulValue);
  597.     }
  598.     pSourceInfo = NewSourceInfo();
  599.     if(pSourceInfo)
  600.     {
  601.         pSourceInfo->m_uGroupID = uGroupID;
  602.         pSourceInfo->m_uTrackID = uTrackID;
  603.         if (HXR_OK == pTrack->GetPropertyCString(szID, pID))
  604.         {
  605.             pSourceInfo->m_id = (const char*)pID->GetBuffer();
  606.         }
  607.         PrepareSourceInfo(pTrack, pSourceInfo);
  608.     }
  609.     else
  610.     {
  611.         theErr = HXR_OUTOFMEMORY;
  612.         goto cleanup;
  613.     }
  614.     theErr = AddURL(pSourceInfo, FALSE);
  615. #if defined(HELIX_FEATURE_NEXTGROUPMGR)
  616.     if (HXR_OK == theErr    &&
  617.         m_bPartOfNextGroup  &&
  618.         pSourceInfo->m_pSource)
  619.     {
  620.         m_pNextGroupManager->AddSource(pSourceInfo);
  621.     }
  622. #endif /* HELIX_FEATURE_NEXTGROUPMGR */
  623. cleanup:
  624.     HX_RELEASE(pBuffer);
  625.     HX_RELEASE(pID);
  626.     return theErr;
  627. #else
  628.     return HXR_NOTIMPL;
  629. #endif /* HELIX_FEATURE_BASICGROUPMGR */
  630. }
  631. HX_RESULT
  632. HXPlayer::OpenTrackExt()
  633. {
  634.     return HXR_OK;
  635. }
  636. /* called from ProcessIdle when done playing current group */
  637. void HXPlayer::PlayNextGroup()
  638. {
  639.     UINT16 uNextGroup = 0;
  640. #if defined(HELIX_FEATURE_BASICGROUPMGR)
  641.     m_pGroupManager->GetNextGroup(uNextGroup);
  642. #else
  643.     uNextGroup = m_nGroupCount;
  644. #endif /* HELIX_FEATURE_BASICGROUPMGR */
  645.     m_nCurrentGroup = uNextGroup;
  646.     if (m_nCurrentGroup >= m_nGroupCount)
  647.     {
  648.         // Stop completely...
  649.         m_bIsPresentationClosedToBeSent = TRUE;
  650.         m_bIsDone = TRUE;
  651.         StopPlayer(END_DURATION);
  652. #if defined(HELIX_FEATURE_VIDEO)
  653.         /*
  654.          * Let the site supplier know that we are done changing the layout.
  655.          */
  656.         if (m_pSiteSupplier && !m_bBeginChangeLayoutTobeCalled)
  657.         {
  658.             m_bBeginChangeLayoutTobeCalled      = TRUE;
  659.             m_pSiteSupplier->DoneChangeLayout();
  660.         }
  661. #endif /* HELIX_FEATURE_VIDEO */
  662.     }
  663.     else
  664.     {
  665.         // build the group's source list
  666.         m_bIsPresentationClosedToBeSent = FALSE;
  667.         StopAllStreams(END_DURATION);
  668.         m_bIsPresentationClosedToBeSent = TRUE;
  669.         ResetGroup();
  670. #if defined(HELIX_FEATURE_BASICGROUPMGR)
  671.         m_pGroupManager->SetCurrentGroup((UINT16) m_nCurrentGroup);
  672. #endif /* HELIX_FEATURE_BASICGROUPMGR */
  673.     }
  674.     m_bForceStatsUpdate = TRUE;
  675. }
  676. /************************************************************************
  677.  *      Method:
  678.  *          HXPlayer::CheckTrackAndSourceOnTrackStarted
  679.  *      Purpose:
  680.  *           Passthrough to allow SourceInfo to call Master TAC manager
  681.  *
  682.  */
  683. BOOL HXPlayer::CheckTrackAndSourceOnTrackStarted(INT32 nGroup,
  684.                                                   INT32 nTrack,
  685.                                                   UINT32 sourceID)
  686. {
  687. #if defined(HELIX_FEATURE_MASTERTAC)
  688.     return (!m_pMasterTAC ?TRUE :m_pMasterTAC->CheckTrackAndSourceOnTrackStarted(nGroup, nTrack, sourceID));
  689. #else
  690.     return TRUE;
  691. #endif /* HELIX_FEATURE_MASTERTAC */
  692. }
  693. /*
  694.  *      IHXRegistryID methods
  695.  */
  696. /************************************************************************
  697.  *      Method:
  698.  *          IHXRegistryID::GetID
  699.  *      Purpose:
  700.  *          Get registry ID(hash_key) of the objects(player, source and stream)
  701.  *
  702.  */
  703. STDMETHODIMP HXPlayer::GetID(REF(UINT32) /*OUT*/ ulRegistryID)
  704. {
  705. #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
  706.     (m_pStats)?(ulRegistryID = m_pStats->m_ulRegistryID):(ulRegistryID = 0);
  707.     return HXR_OK;
  708. #else
  709.     return HXR_NOTIMPL;
  710. #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
  711. }
  712. HX_RESULT HXPlayer::DoNetworkOpen(SourceInfo*& pSourceInfo, BOOL bAltURL)
  713. {
  714. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  715.     HX_RESULT   theErr = HXR_OK;
  716.     HXSource*   pSource = NULL;
  717.     IHXValues*  pURLProperties = NULL;
  718.     IHXBuffer* pBuffer = NULL;
  719.     UINT32      ulRegistryID = 0;
  720.     char*       pszHost = NULL;
  721.     char*       pszResource = NULL;
  722.     const char* pszURL = NULL;
  723.     ULONG32     ulPort = 0;
  724.     IHXBuffer* pszParentName = NULL;
  725.     m_bAllLocalSources = FALSE;
  726. #if defined(HELIX_FEATURE_SMARTERNETWORK)
  727.     if (!m_bPrefTransportInitialized && m_pPreferredTransportManager)
  728.     {
  729.         // re-load proxy/subnet preferences
  730.         m_bPrefTransportInitialized = TRUE;
  731.         if (m_pNetInterfaces)
  732.         {
  733.             m_pNetInterfaces->UpdateNetInterfaces();
  734.         }
  735.         m_pPreferredTransportManager->Initialize();
  736.     }
  737. #endif /* HELIX_FEATURE_SMARTERNETWORK */
  738.     pSource = pSourceInfo->m_pSource = NewNetSource();
  739.     if (!pSource)
  740.     {
  741.         return( HXR_OUTOFMEMORY );
  742.     }
  743.     pSource->AddRef();
  744. #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
  745.     // registry setting
  746.     if (m_pRegistry && m_pStats)
  747.     {
  748.         char        szSourceName[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
  749.         if (m_bPartOfNextGroup &&
  750.             HXR_OK == m_pRegistry->GetPropName(m_ulNextGroupRegistryID, pszParentName))
  751.         {
  752.             SafeSprintf(szSourceName, MAX_DISPLAY_NAME, "%s.Source%ld", pszParentName->GetBuffer(),
  753.                     pSourceInfo->m_uTrackID);
  754.         }
  755.         else if (HXR_OK == m_pRegistry->GetPropName(m_pStats->m_ulRegistryID, pszParentName))
  756.         {
  757.             SafeSprintf(szSourceName, MAX_DISPLAY_NAME, "%s.Source%ld", pszParentName->GetBuffer(),
  758.                     pSourceInfo->m_uTrackID);
  759.         }
  760.         else
  761.         {
  762.             HX_ASSERT(FALSE);
  763.         }
  764.         /* does this ID already exists ? */
  765.         ulRegistryID = m_pRegistry->GetId(szSourceName);
  766.         if (!ulRegistryID)
  767.         {
  768.             ulRegistryID = m_pRegistry->AddComp(szSourceName);
  769.         }
  770.     }
  771. #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
  772.     HX_RELEASE(pszParentName);
  773.     pSource->SetSourceInfo(pSourceInfo);
  774.     pSource->Init(this, ulRegistryID);
  775.     UINT32 ulStart = 0, ulEnd = HX_EOF_TIME, ulDelay = 0, ulDuration = 0;    
  776.     GetTimingFromURL(m_pURL, ulStart, ulEnd, ulDelay, ulDuration);
  777.     if (!(pURLProperties = m_pURL->GetProperties()))
  778.     {
  779.         theErr = HXR_FAILED;
  780.         goto cleanup;
  781.     }
  782.     pURLProperties->GetPropertyULONG32(PROPERTY_PORT, ulPort);
  783.     if (HXR_OK == pURLProperties->GetPropertyBuffer(PROPERTY_HOST, pBuffer))
  784.     {
  785.         pszHost = (char*)pBuffer->GetBuffer();
  786.         pBuffer->Release();
  787.     }
  788.     if (HXR_OK == pURLProperties->GetPropertyBuffer(PROPERTY_RESOURCE, pBuffer))
  789.     {
  790.         pszResource = (char*)pBuffer->GetBuffer();
  791.         pBuffer->Release();
  792.     }
  793.     pszURL = m_pURL->GetURL();
  794.     pSource->SetPlayTimes(ulStart, ulEnd, ulDelay, ulDuration);
  795.     pSource->PartOfNextGroup(m_bPartOfNextGroup);
  796. #if defined(HELIX_FEATURE_PREFETCH)
  797.     if (pSourceInfo->m_bPrefetch)
  798.     {
  799.         pSource->EnterPrefetch(pSourceInfo->m_prefetchType, pSourceInfo->m_ulPrefetchValue);
  800.     }
  801. #endif /* HELIX_FEATURE_PREFETCH */
  802.     theErr = ((HXNetSource*)pSource)->Setup(pszHost, pszResource, (UINT16)ulPort, TRUE, m_pURL, bAltURL);
  803. cleanup:
  804.     HX_RELEASE(pURLProperties);
  805.     // cleanup...
  806.     if(theErr && pSource)
  807.     {
  808.         pSource->DoCleanup();
  809.         HX_RELEASE(pSource);
  810.     }
  811.     return theErr;
  812. #else
  813.     return HXR_NOTIMPL;
  814. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  815. }
  816. HX_RESULT HXPlayer::DoFileSystemOpen(SourceInfo*& pSourceInfo, BOOL bAltURL)
  817. {
  818. #if defined(HELIX_FEATURE_PLAYBACK_LOCAL)
  819.     HX_RESULT   theErr = HXR_OK;
  820.     HXSource*   pSource = NULL;
  821.     IHXValues*  pURLProperties = NULL;
  822.     UINT32      ulRegistryID = 0;
  823.     IHXBuffer* pszParentName = NULL;
  824.     pSource = pSourceInfo->m_pSource = NewFileSource();
  825.     if (!pSource)
  826.     {
  827.         return( HXR_OUTOFMEMORY );
  828.     }
  829.     pSource->AddRef();
  830.     UINT32 ulStart = 0, ulEnd = HX_EOF_TIME, ulDelay = 0, ulDuration = 0;    
  831.     GetTimingFromURL(m_pURL, ulStart, ulEnd, ulDelay, ulDuration);
  832.     if (m_pURL)
  833.     {
  834.         if (!(pURLProperties = m_pURL->GetProperties()))
  835.         {
  836.             theErr = HXR_FAILED;
  837.             goto cleanup;
  838.         }
  839.     }
  840. #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
  841.     // registry setting
  842.     if (m_pRegistry && m_pStats)
  843.     {
  844.         HX_RESULT res    = HXR_OK;
  845.         UINT32    nRegID = 0;
  846.         if(m_bPartOfNextGroup)
  847.             nRegID = m_ulNextGroupRegistryID;
  848.         else
  849.             nRegID = m_pStats->m_ulRegistryID;
  850.         res = m_pRegistry->GetPropName(nRegID, pszParentName);
  851.         if ( HXR_OK == res && pszParentName )
  852.         {
  853.             char        szSourceName[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
  854.             SafeSprintf(szSourceName, MAX_DISPLAY_NAME, "%s.Source%u", pszParentName->GetBuffer(),
  855.                     pSourceInfo->m_uTrackID);
  856.             // does this ID already exist?
  857.             ulRegistryID = m_pRegistry->GetId(szSourceName);
  858.             if ( !ulRegistryID )
  859.             {
  860.                 ulRegistryID = m_pRegistry->AddComp(szSourceName);
  861.             }
  862.             HX_RELEASE(pszParentName);
  863.         }
  864.         else
  865.         {
  866.             HX_ASSERT(FALSE);
  867.         }
  868.     }
  869.     HX_RELEASE(pszParentName);
  870. #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
  871.     pSource->SetSourceInfo(pSourceInfo);
  872.     pSource->Init(this, ulRegistryID);
  873.     pSource->SetPlayTimes(ulStart, ulEnd, ulDelay, ulDuration);
  874.     pSource->PartOfNextGroup(m_bPartOfNextGroup);
  875.     theErr = ((HXFileSource*)pSource)->Setup(m_pURL, bAltURL);
  876. cleanup:
  877.     HX_RELEASE(pURLProperties);
  878.     // cleanup...
  879.     if(theErr && pSource)
  880.     {
  881.         pSource->DoCleanup();
  882.         HX_RELEASE(pSource);
  883.     }
  884.     return theErr;
  885. #else
  886.     return HXR_NOTIMPL;
  887. #endif /* HELIX_FEATURE_PLAYBACK_LOCAL */
  888. }
  889. HX_RESULT
  890. HXPlayer::UnRegisterCurrentSources()
  891. {
  892.     HX_RESULT theErr = HXR_OK;
  893.     
  894.     CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
  895.     for (; !theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
  896.     {
  897.         SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
  898.         theErr = pSourceInfo->UnRegister();
  899.     }
  900.     return theErr;
  901. }
  902. HX_RESULT HXPlayer::InitializeRenderers(void)
  903. {
  904.     HX_RESULT theErr        = HXR_OK;
  905.     HX_RESULT thefinalErr   = HXR_OK;
  906.     SourceInfo*     pSourceInfo = NULL;
  907.     BOOL            bSourceInitialized = TRUE;
  908.     // assume everything will be initialized in this pass...
  909.     BOOL            bAllInitialized = TRUE;
  910.     UINT16 uInitialSourceCount = m_pSourceMap->GetCount();
  911.     CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
  912.     for (; ndxSource != m_pSourceMap->End(); ++ndxSource)
  913.     {
  914.         pSourceInfo = (SourceInfo*)(*ndxSource);
  915.         if (pSourceInfo->m_bInitialized)
  916.             continue;
  917.         theErr = pSourceInfo->InitializeRenderers(bSourceInitialized);
  918.         if (theErr && !thefinalErr)
  919.         {
  920.             thefinalErr = theErr;
  921.         }
  922.         if (!bSourceInitialized)
  923.         {
  924.             bAllInitialized      = FALSE;
  925.         }
  926.         /* Someone added a source during ProcessIdle.
  927.          * Start all over again
  928.          */
  929.         if (uInitialSourceCount != m_pSourceMap->GetCount())
  930.         {
  931.             bAllInitialized = FALSE;
  932.             break;
  933.         }
  934.     }
  935.     if (!thefinalErr && bAllInitialized)
  936.     {
  937.         m_bInitialized = TRUE;
  938.         if (m_pAdviseSink)
  939.         {
  940.             m_pAdviseSink->OnPosLength( m_ulCurrentPlayTime,
  941.                                         m_ulPresentationDuration);
  942.             m_pAdviseSink->OnBegin(m_ulCurrentPlayTime);
  943.         }
  944.     }
  945.     if (!thefinalErr && m_bInitialized && m_pSourceMap->GetCount() == 0)
  946.     {
  947.         m_bPlayerWithoutSources = TRUE;
  948.     }
  949. #if defined(HELIX_FEATURE_PREFETCH)
  950.     if (!thefinalErr && m_bInitialized)
  951.     {
  952.         while (m_pPendingTrackList && m_pPendingTrackList->GetCount() > 0)
  953.         {
  954.             PendingTrackInfo* pPendingTrackInfo =
  955.                         (PendingTrackInfo*) m_pPendingTrackList->RemoveHead();
  956.             theErr = OpenTrack(pPendingTrackInfo->m_pTrack,
  957.                                pPendingTrackInfo->m_uGroupIndex,
  958.                                pPendingTrackInfo->m_uTrackIndex);
  959.             if (theErr && !thefinalErr)
  960.             {
  961.                 thefinalErr = theErr;
  962.             }
  963.             delete pPendingTrackInfo;
  964.         }
  965.         if (thefinalErr)
  966.         {
  967.             ReportError(NULL, thefinalErr, NULL);
  968.         }
  969.     }
  970. #endif /* HELIX_FEATURE_PREFETCH */
  971.     return thefinalErr;
  972. }
  973. // get all packets from event queue and send them to the various renders
  974. HX_RESULT
  975. HXPlayer::ProcessCurrentEvents()
  976. {
  977.     HX_RESULT   theErr  = HXR_OK;
  978.     BOOL        bDone   = FALSE;
  979.     LISTPOSITION listpos = NULL;
  980.     CHXEvent*  pEvent = 0;
  981.     /*
  982.      * check for m_bLiveSeekToBeDone && m_bPaused is so that we do not issue
  983.      * a seek (and start sending packets) before the user has issued a Begin()
  984.      * after Pausing a live stream.
  985.      *
  986.      * Should work for now. Need to be re-visited when Live Pause support
  987.      * is refined in the core.
  988.      *
  989.      * XXXRA
  990.      */
  991.     if (m_bProcessEventsLocked || (m_bLiveSeekToBeDone && m_bPaused))
  992.     {
  993.         return HXR_OK;
  994.     }
  995.     m_bDidWeDeleteAllEvents = FALSE;
  996.     m_bProcessEventsLocked  = TRUE;
  997.     if (m_EventList.GetNumEvents() > 0)
  998.     {
  999.         pEvent = m_EventList.GetHead();
  1000.         listpos = m_EventList.GetHeadPosition();
  1001.     }
  1002.     UINT32  ulEndFillTime = m_ulCurrentPlayTime + m_ulLowestGranularity;
  1003. #ifdef _MACINTOSH
  1004. #define ADDITIONAL_PREDELIVERY_TIME     4000
  1005.         /* on Mac we try to be even farther ahead than the timeline in
  1006.          * packet delivery since the callbacks are not that smooth
  1007.          * and if we are really close to the wire, it results in
  1008.          * unnecccessary re-buffers.
  1009.          */
  1010.         ulEndFillTime += ADDITIONAL_PREDELIVERY_TIME;
  1011. #endif
  1012.     /* If we are in a buffering state, then keep pushing packets
  1013.      * This is required due to ReportRebufferStatus()
  1014.      */
  1015.     if (!m_bIsPlaying && !m_bPaused && pEvent)
  1016.     {
  1017.         UINT32 ulNewEndFillTime = pEvent->GetTimeStartPos() + 1000;
  1018.         ulEndFillTime = ulNewEndFillTime > ulEndFillTime ?
  1019.                         ulNewEndFillTime : ulEndFillTime;
  1020.     }
  1021.     while (!theErr && pEvent && !bDone)
  1022.     {
  1023.         // due?
  1024.         /* Do not hold back any packets for live streams */
  1025. //{FILE* f1 = ::fopen("c:\temp\onpacket.txt", "a+"); ::fprintf(f1, "startPos: %lu endFillTime: %lun", pEvent->GetTimeStartPos(), ulEndFillTime);::fclose(f1);}
  1026.         if (pEvent->GetTimeStartPos() <= ulEndFillTime)
  1027.         {
  1028.             IHXPacket* pPacket = pEvent->GetPacket();
  1029.             /* since packet's time may be different from player's time, send
  1030.              * renderer the offset */
  1031. #if defined(_DEBUG) && defined(DEBUG_LOG_INFO)
  1032.             HXStaticStatLog::StatPrintf("Packet Time: %lun",
  1033.                                         pPacket->GetTime());
  1034. #endif // DEBUG_LOG_INFO
  1035.             BOOL bAtInterrupt = m_pEngine->AtInterruptTime();
  1036.             if (m_bLiveSeekToBeDone && !pEvent->IsPreSeekEvent())
  1037.             {
  1038.                 /* Audio device was earlier seeked  based on the last timesync
  1039.                  * + pause duration. The actual first packet time we get after
  1040.                  * Pause may be different from the seek time. This is because
  1041.                  * at pause time, packets may have been given in advance to
  1042.                  * the renderers due to preroll. Also, they may be stored in
  1043.                  * resend buffer at protocol level. So the only way to kind
  1044.                  * of know what time we should have actually seeked to is based
  1045.                  * on the first packet time. Even this may result in initial
  1046.                  * re-buffering. This is still a hack. We probably need a
  1047.                  * better live pause solution.
  1048.                  */
  1049.                 m_bLiveSeekToBeDone = FALSE;
  1050.                 UINT32 ulCurTime = m_pAudioPlayer->GetCurrentPlayBackTime();
  1051.                 /* make sure we have sent ATLEAST one ontimesync to the renderer.
  1052.                  * otherwise, we cannot rely on the m_ulTimeAfterSeek value since it is based on
  1053.                  * m_ulTimeDiff which only gets set in the first ontimesync call.
  1054.                  * Needed to fix pause during inital buffering of live playback
  1055.                  */
  1056.                 if (!pEvent->m_pRendererInfo->m_bIsFirstTimeSync &&
  1057.                     pPacket->GetTime() > pEvent->m_pRendererInfo->m_pStreamInfo->m_ulTimeAfterSeek)
  1058.                 {
  1059. #if defined(_MACINTOSH) || defined(_MAC_UNIX)
  1060.                     /* Cannot call audio player Seek() at interrupt time. It results
  1061.                      * in audio device Reset() which issues DoImmediate commands
  1062.                      */
  1063.                     if (bAtInterrupt)
  1064.                     {
  1065.                         if (m_pHXPlayerCallback)
  1066.                         {
  1067.                             RemovePendingCallback(m_pHXPlayerCallback);
  1068.                             m_pHXPlayerCallback->CallbackScheduled(
  1069.                             m_pScheduler->RelativeEnter(m_pHXPlayerCallback, 0));
  1070.                         }
  1071.                         bDone = TRUE;
  1072.                         continue;
  1073.                     }
  1074. #endif
  1075.                     UINT32 ulTimeDiff = 0;
  1076.                     ulTimeDiff = pPacket->GetTime() -
  1077.                                  pEvent->m_pRendererInfo->m_pStreamInfo->m_ulTimeAfterSeek;
  1078.                     m_pAudioPlayer->Seek(ulCurTime + ulTimeDiff);
  1079.                 }
  1080.             }
  1081.             if (!bAtInterrupt || pEvent->m_pRendererInfo->m_bInterruptSafe)
  1082.             {
  1083.                 if (!pEvent->IsPreSeekEvent())
  1084.                 {
  1085.                     SendPostSeekIfNecessary(pEvent->m_pRendererInfo);
  1086.                 }
  1087.                 // remove this event from the packet list...
  1088.                 listpos = m_EventList.RemoveAt(listpos);
  1089.                 theErr = SendPacket(pEvent);
  1090.                 /* A renderer may call SetCurrentGroup OR Stop() from within
  1091.                 * OnPacket call. If so, we delete all the pending events
  1092.                 */
  1093.                 if (m_bDidWeDeleteAllEvents)
  1094.                 {
  1095.                     delete pEvent;
  1096.                     bDone = TRUE;
  1097.                     break;
  1098.                 }
  1099.                 HX_ASSERT(pEvent->m_pRendererInfo->m_ulNumberOfPacketsQueued > 0);
  1100.                 pEvent->m_pRendererInfo->m_ulNumberOfPacketsQueued--;
  1101.                 if (pEvent->m_pRendererInfo->m_ulNumberOfPacketsQueued == 0 &&
  1102.                     pEvent->m_pRendererInfo->m_pStreamInfo->m_bSrcInfoStreamDone)
  1103.                 {
  1104.                     SendPostSeekIfNecessary(pEvent->m_pRendererInfo);
  1105.                     pEvent->m_pRendererInfo->m_bOnEndOfPacketSent = TRUE;
  1106.                     pEvent->m_pRendererInfo->m_pRenderer->OnEndofPackets();
  1107.                 }
  1108.                 // cleanup this event...
  1109.                 delete pEvent;
  1110.                 pEvent = NULL;
  1111.                 // and get the next event...
  1112.                 if (m_EventList.GetNumEvents() > 0)
  1113.                 {
  1114.                     pEvent = m_EventList.GetAt(listpos);
  1115.                 }
  1116.             }
  1117.             else
  1118.             {
  1119.                 pEvent = m_EventList.GetAtNext(listpos); //skip over event - *++listpos
  1120.             }
  1121.         }
  1122.         else
  1123.         {
  1124.             bDone = TRUE;
  1125.         }
  1126.     }
  1127.     m_bDidWeDeleteAllEvents = FALSE;
  1128.     m_bProcessEventsLocked  = FALSE;
  1129.     return theErr;
  1130. }
  1131. HX_RESULT HXPlayer::SendPreSeekEvents()
  1132. {
  1133.     HX_RESULT theErr = HXR_OK;
  1134.     LISTPOSITION listpos = m_EventList.GetHeadPosition();
  1135.     while (listpos && (m_EventList.GetNumEvents() != 0))
  1136.     {
  1137.         CHXEvent*  pEvent = m_EventList.GetAt(listpos);
  1138.         BOOL bAtInterrupt = m_pEngine->AtInterruptTime();
  1139.         if (!bAtInterrupt || pEvent->m_pRendererInfo->m_bInterruptSafe)
  1140.         {
  1141.             listpos = m_EventList.RemoveAt(listpos);
  1142.             theErr = SendPacket(pEvent);
  1143.             HX_ASSERT(pEvent->m_pRendererInfo->m_ulNumberOfPacketsQueued > 0);
  1144.             pEvent->m_pRendererInfo->m_ulNumberOfPacketsQueued--;
  1145.             delete pEvent;
  1146.         }
  1147.         else
  1148.         {
  1149.             pEvent->SetPreSeekEvent();
  1150.             m_EventList.GetNext(listpos);
  1151.         }
  1152.     }
  1153.     SendPreSeekEventsExt();
  1154.     CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
  1155.     for (; !theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
  1156.     {
  1157.         SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
  1158.         if (pSourceInfo->m_pSource && pSourceInfo->m_pSource->m_PacketBufferList.GetCount() > 0)
  1159.         {
  1160.             CHXSimpleList* pPacketList = &pSourceInfo->m_pSource->m_PacketBufferList;
  1161.             LISTPOSITION pos = pPacketList->GetHeadPosition();
  1162.             while (pos != NULL)
  1163.             {
  1164.                 CHXEvent* pTempEvent  = (CHXEvent*) pPacketList->GetNext(pos);
  1165.                 pTempEvent->SetPreSeekEvent();
  1166.             }
  1167.         }
  1168.     }
  1169.     return theErr;
  1170. }
  1171. HX_RESULT HXPlayer::DeleteAllEvents()
  1172. {
  1173.     while (m_EventList.GetNumEvents() != 0)
  1174.     {
  1175.         CHXEvent*  pEvent = m_EventList.RemoveHead();
  1176.         /* If these packets belong to a persistent source,
  1177.          * pass them over.
  1178.          */
  1179.         if (pEvent->m_pRendererInfo->m_bIsPersistent)
  1180.         {
  1181.             BOOL bAtInterrupt = m_pEngine->AtInterruptTime();
  1182.             if (!bAtInterrupt || pEvent->m_pRendererInfo->m_bInterruptSafe)
  1183.             {
  1184.                 SendPacket(pEvent);
  1185.             }
  1186.         }
  1187.         delete pEvent;
  1188.     }
  1189.     CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
  1190.     for (; ndxSource != m_pSourceMap->End(); ++ndxSource)
  1191.     {
  1192.         SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
  1193.         if (pSourceInfo->m_pSource)
  1194.         {
  1195.             pSourceInfo->m_pSource->DeleteAllEvents();
  1196.         }
  1197.     }
  1198.     m_bDidWeDeleteAllEvents = TRUE;
  1199.     return HXR_OK;
  1200. }
  1201. HX_RESULT
  1202. HXPlayer::EventReady(HXSource* pSource, CHXEvent* pEvent)
  1203. {
  1204.     HX_RESULT theErr = HXR_OK;
  1205.     SourceInfo*     pSourceInfo = NULL;
  1206.     RendererInfo*   pRendInfo   = NULL;
  1207.     if (!m_pSourceMap->Lookup(pSource, (void*&) pSourceInfo))
  1208.     {
  1209.         HX_ASSERT(FALSE);
  1210.         return HXR_INVALID_PARAMETER;
  1211.     }
  1212.     if (!pSourceInfo->m_pRendererMap->Lookup((pEvent->GetPacket())->GetStreamNumber(), (void*&) pRendInfo))
  1213.     {
  1214.         HX_ASSERT(FALSE);
  1215.         return HXR_INVALID_PARAMETER;
  1216.     }
  1217.     pEvent->m_pRendererInfo = pRendInfo;
  1218.     BOOL bOkToSend = (!m_pEngine->AtInterruptTime() ||
  1219.                       pEvent->m_pRendererInfo->m_bInterruptSafe);
  1220.     if (pEvent->IsPreSeekEvent() && bOkToSend)
  1221.     {
  1222.         SendPacket(pEvent);
  1223.         delete pEvent;
  1224.     }
  1225.     else
  1226.     {
  1227.         m_EventList.InsertEvent(pEvent);
  1228.         pEvent->m_pRendererInfo->m_ulNumberOfPacketsQueued++;
  1229.     }
  1230.     return theErr;
  1231. }
  1232. HX_RESULT HXPlayer::SendPacket(CHXEvent* pEvent)
  1233. {
  1234.     HX_RESULT retVal = pEvent->m_pRendererInfo->m_pRenderer->OnPacket(pEvent->GetPacket(),
  1235.                                                           pEvent->GetTimeOffset());
  1236.     if( retVal == HXR_OUTOFMEMORY )
  1237.     {
  1238.         Report( HXLOG_ERR, retVal, HXR_OK, "Ran out of memory in SendPacket", NULL );
  1239.     }
  1240.     return retVal;
  1241. }
  1242. BOOL
  1243. HXPlayer::AreAllPacketsSent()
  1244. {
  1245.     BOOL bAllSent = TRUE;
  1246.     CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
  1247.     for (; ndxSource != m_pSourceMap->End(); ++ndxSource)
  1248.     {
  1249.         SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
  1250.         if (pSourceInfo->m_pSource && pSourceInfo->m_pSource &&
  1251.             pSourceInfo->m_pSource->m_PacketBufferList.GetCount() > 0)
  1252.         {
  1253.             bAllSent = FALSE;
  1254.             break;
  1255.         }
  1256.     }
  1257.     bAllSent = bAllSent & (m_EventList.GetNumEvents() == 0);
  1258.     return bAllSent;
  1259. }
  1260. void
  1261. HXPlayer::StopAllStreams(EndCode endCode)
  1262. {
  1263.     /* If we do not have access to engine any more, it means it is the final
  1264.      * destruction and everything has been deleted by now
  1265.      */
  1266.     if (!m_pEngine)
  1267.         return;
  1268.     StopAllStreamsExt(endCode);
  1269.     m_bIsDone = TRUE;
  1270.     if (m_bInStop)
  1271.         return;
  1272.     m_bInStop = TRUE;
  1273.     m_bIsPlaying = FALSE;
  1274.     /* stop timeline */
  1275.     m_pAudioPlayer->Stop(TRUE);
  1276.     m_bPendingAudioPause = FALSE;
  1277. #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
  1278.     if (m_pUpdateStatsCallback->m_bIsCallbackPending)
  1279.     {
  1280.         m_pUpdateStatsCallback->m_bIsCallbackPending = FALSE;
  1281.         m_pScheduler->Remove(m_pUpdateStatsCallback->m_PendingHandle);
  1282.         m_pUpdateStatsCallback->m_PendingHandle = 0;
  1283.     }
  1284. #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
  1285.     RemovePendingCallback(m_pHXPlayerCallback);
  1286.     RemovePendingCallback(m_pHXPlayerInterruptCallback);
  1287.     RemovePendingCallback(m_pSetupCallback);
  1288. #if defined(HELIX_FEATURE_AUTHENTICATION)
  1289.     ClearPendingAuthenticationRequests();
  1290. #endif /* HELIX_FEATURE_AUTHENTICATION */
  1291.     m_bCloseAllRenderersPending     = TRUE;
  1292.     CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
  1293.     for (; ndxSource != m_pSourceMap->End(); ++ndxSource)
  1294.     {
  1295.         SourceInfo* pSourceInfo = (SourceInfo *) (*ndxSource);
  1296. //{FILE* f1 = ::fopen("c:\temp\ts.txt", "a+"); ::fprintf(f1, "%p pSourceInfo::Stop, ThreadID: %lun", pSourceInfo, GetCurrentThreadId());::fclose(f1);}
  1297.         pSourceInfo->Stop(endCode);
  1298.         if (pSourceInfo->m_pPeerSourceInfo)
  1299.         {
  1300.             pSourceInfo->m_pPeerSourceInfo->Stop(endCode);
  1301.         }
  1302.     }
  1303.     DeleteAllEvents();
  1304.     if (m_bIsPresentationClosedToBeSent)
  1305.     {
  1306.         m_bIsPresentationClosedToBeSent = FALSE;
  1307.         if (m_pAdviseSink)
  1308.         {
  1309.             m_pAdviseSink->OnStop();
  1310.             m_pAdviseSink->OnPresentationClosed();
  1311.         }
  1312.     }
  1313.     m_bInStop = FALSE;
  1314.     m_bCurrentPresentationClosed    = TRUE;
  1315. }
  1316. HX_RESULT
  1317. HXPlayer::StopAllStreamsExt(EndCode endCode)
  1318. {
  1319.     return HXR_OK;
  1320. }
  1321. HX_RESULT
  1322. HXPlayer::SendPreSeekEventsExt()
  1323. {
  1324.     return HXR_OK;
  1325. }
  1326. SourceInfo*
  1327. HXPlayer::NewSourceInfo(void)
  1328. {
  1329.     return (new SourceInfo(this));
  1330. }
  1331. HXFileSource*
  1332. HXPlayer::NewFileSource(void)
  1333. {
  1334. #if defined(HELIX_FEATURE_PLAYBACK_LOCAL)
  1335.     return (new HXFileSource());
  1336. #else
  1337.     return NULL;
  1338. #endif /* #if defined(HELIX_FEATURE_PLAYBACK_LOCAL) */
  1339. }
  1340. HXNetSource*
  1341. HXPlayer::NewNetSource(void)
  1342. {
  1343. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  1344.     return (new HXNetSource());
  1345. #else
  1346.     return NULL;
  1347. #endif /* #if defined(HELIX_FEATURE_PLAYBACK_NET) */
  1348. }
  1349. void
  1350. HXPlayer::CloseAllRenderers(INT32 nGroupSwitchTo)
  1351. {
  1352.     CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
  1353.     for (; ndxSource != m_pSourceMap->End(); ++ndxSource)
  1354.     {
  1355.         SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
  1356.         if (pSourceInfo->m_pPeerSourceInfo)
  1357.         {
  1358.             pSourceInfo->m_pPeerSourceInfo->CloseRenderers();
  1359.             HX_DELETE(pSourceInfo->m_pPeerSourceInfo);
  1360.         }
  1361.         if (pSourceInfo->CloseRenderers() == HXR_OK)
  1362.         {
  1363.             HX_DELETE(pSourceInfo);
  1364.         }
  1365.     }
  1366.     m_pSourceMap->RemoveAll();
  1367.     m_bSourceMapUpdated = TRUE;
  1368. #if defined(HELIX_FEATURE_NESTEDMETA)
  1369.     if (m_pPersistentComponentManager)
  1370.     {
  1371.         m_pPersistentComponentManager->CloseAllRenderers(nGroupSwitchTo);
  1372.     }
  1373. #else
  1374.     CleanupLayout();
  1375. #endif /* HELIX_FEATURE_NESTEDMETA */
  1376. #ifdef _MACINTOSH
  1377.     unsigned long lastFree = ::TempFreeMem();
  1378.     long deltaFree = 1;
  1379.     long iterationCount = 0;
  1380.     while (deltaFree > 0 && iterationCount < 5)
  1381.     {
  1382.         HXMM_COMPACT();
  1383.         unsigned long curFree = ::TempFreeMem();
  1384.         deltaFree = curFree - lastFree;
  1385.         lastFree = curFree;
  1386.         iterationCount++;
  1387.     }
  1388. #endif
  1389.     m_bCloseAllRenderersPending = FALSE;
  1390. }
  1391. /* Reset the player condition
  1392.  * Remove all sources and re-initialize all variables...
  1393.  */
  1394. void
  1395. HXPlayer::ResetPlayer(void)
  1396. {
  1397.     if (m_pCookies)
  1398.     {
  1399. #if defined(HELIX_FEATURE_COOKIES)
  1400.         m_pCookies->SyncRMCookies(TRUE);
  1401. #endif /* defined(HELIX_FEATURE_COOKIES) */
  1402.     }
  1403.     EmptyBeginList();
  1404.     ResetGroup();
  1405.     if (m_pAltURLs)
  1406.     {
  1407.         m_pAltURLs->RemoveAll();
  1408.     }
  1409. #if defined(HELIX_FEATURE_BASICGROUPMGR)
  1410.     if (m_pGroupManager && m_pGroupManager->GetGroupCount() > 0)
  1411.     {
  1412.         m_pGroupManager->RemoveAllGroup();
  1413.     }
  1414. #endif /* HELIX_FEATURE_BASICGROUPMGR */
  1415. #if defined(HELIX_FEATURE_NEXTGROUPMGR)
  1416.     if (m_pNextGroupManager)
  1417.     {
  1418.         m_pNextGroupManager->Cleanup();
  1419.     }
  1420. #endif /* HELIX_FEATURE_NEXTGROUPMGR */
  1421. #if defined(HELIX_FEATURE_PREFETCH)
  1422.     if (m_pPrefetchManager)
  1423.     {
  1424.         m_pPrefetchManager->Cleanup();
  1425.     }
  1426. #endif /* HELIX_FEATURE_PREFETCH */
  1427. #if defined(HELIX_FEATURE_NESTEDMETA)
  1428.     if (m_pPersistentComponentManager)
  1429.     {
  1430.         m_pPersistentComponentManager->Reset();
  1431.     }
  1432. #endif /* HELIX_FEATURE_NESTEDMETA */
  1433.     m_bSetupLayoutSiteGroup = TRUE;
  1434.     m_bIsDone               = TRUE;
  1435.     m_bIsPresentationDone   = TRUE;
  1436.     m_bPlayerWithoutSources = FALSE;
  1437.     m_bPartOfNextGroup      = FALSE;
  1438.     m_bLastGroup            = FALSE;
  1439.     m_bNextGroupStarted     = FALSE;
  1440.     m_bUserHasCalledBegin   = FALSE;
  1441.     m_bSourceMapUpdated     = FALSE;
  1442.     m_bPrefTransportInitialized = FALSE;
  1443.     m_bAddLayoutSiteGroupCalled = FALSE;
  1444.     if (!m_bDoRedirect && !m_bBeginChangeLayoutTobeCalled)
  1445.     {
  1446.         m_bBeginChangeLayoutTobeCalled = TRUE;
  1447. #if defined(HELIX_FEATURE_VIDEO)
  1448.         if (m_pSiteSupplier)
  1449.         {
  1450.             m_pSiteSupplier->DoneChangeLayout();
  1451.         }
  1452. #endif /* HELIX_FEATURE_VIDEO */
  1453.     }
  1454. #if defined(HELIX_FEATURE_ASM)
  1455.     if (m_pBandwidthMgr)
  1456.     {
  1457.         m_pBandwidthMgr->PresentationDone();
  1458.     }
  1459. #endif /* HELIX_FEATURE_ASM */
  1460.     if (m_bPlayStateNotified && m_pEngine)
  1461.     {
  1462.         m_bPlayStateNotified = FALSE;
  1463.         m_pEngine->NotifyPlayState(m_bPlayStateNotified);
  1464.     }
  1465. #if defined(HELIX_FEATURE_VIDEO)
  1466.     if (m_pSiteManager)
  1467.     {
  1468.         m_pSiteManager->NeedFocus(FALSE);
  1469.     }
  1470. #endif /* HELIX_FEATURE_VIDEO */
  1471. #if defined(HELIX_FEATURE_PLAYBACK_NET) && !defined(_SYMBIAN) && !defined(_OPENWAVE)
  1472.     /* Clean DNS cache */
  1473.     conn::clear_cache();
  1474. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  1475.     /* Compact memory pools now that we are done with a presentation */
  1476. #ifdef _MACINTOSH
  1477.     unsigned long lastFree = ::TempFreeMem();
  1478.     long deltaFree = 1;
  1479.     long iterationCount = 0;
  1480.     while (deltaFree > 0 && iterationCount < 5)
  1481.     {
  1482.         HXMM_COMPACT();
  1483.         unsigned long curFree = ::TempFreeMem();
  1484.         deltaFree = curFree - lastFree;
  1485.         lastFree = curFree;
  1486.         iterationCount++;
  1487.     }
  1488. #endif
  1489. }
  1490. /* Before playing the next group
  1491.  * reset everything ResetPlayer does except .
  1492.  */
  1493. void
  1494. HXPlayer::ResetGroup(void)
  1495. {
  1496.     m_uNumSourcesActive     = 0;
  1497.     m_uNumCurrentSourceNotDone = 0;
  1498.     m_bInitialized          = FALSE;
  1499.     m_bSetupLayoutSiteGroup = TRUE;
  1500.     m_ulCurrentPlayTime     = 0;
  1501. #if defined(_MACINTOSH)
  1502.     m_ulCurrentSystemPlayTime = 0;
  1503. #endif
  1504.     m_ulPresentationDuration  = 0;
  1505.     m_ulTimeBeforeSeek      = 0;
  1506.     m_ulTimeAfterSeek       = 0;
  1507.     m_BufferingReason       = BUFFERING_START_UP;
  1508.     m_bIsDone               = FALSE;
  1509.     m_bPaused               = FALSE;
  1510.     m_bBeginPending         = FALSE;
  1511.     m_bTimelineToBeResumed  = FALSE;
  1512.     m_bIsPlaying            = FALSE;
  1513.     m_bSetupToBeDone        = FALSE;
  1514.     m_bPostSetupToBeDone    = FALSE;
  1515.     /* default DEFAULT_TIMESYNC_GRANULARITY ms timesyncs are
  1516.      * given to renderers
  1517.      */
  1518.     m_ulLowestGranularity   = DEFAULT_TIMESYNC_GRANULARITY;
  1519.     m_bIsFirstBegin         = TRUE;
  1520.     m_bIsLive               = FALSE;
  1521.     m_LastError             = HXR_OK;
  1522.     m_ulMinimumAudioPreroll = 0;
  1523.     m_bInternalPauseResume  = FALSE;
  1524.     m_bInternalReset        = FALSE;
  1525.     m_bContactingDone       = FALSE;
  1526.     m_bIsFirstTimeSync      = TRUE;
  1527.     m_ulFirstTimeSync       = 0;
  1528.     m_ulElapsedPauseTime    = 0;
  1529.     m_ulLiveSeekTime        = 0;
  1530.     m_ulTimeOfPause         = 0;
  1531.     m_bLiveSeekToBeDone     = FALSE;
  1532.     m_bFastStartInProgress  = FALSE;
  1533.     m_ulFSBufferingEndTime  = 0;
  1534.     m_bFSBufferingEnd       = FALSE;
  1535.     m_b100BufferingToBeSent = TRUE;
  1536.     m_uNumSourceToBeInitializedBeforeBegin = 0;
  1537.     m_bAllLocalSources      = TRUE;
  1538.     m_bResumeOnlyAtSystemTime = FALSE;
  1539. #if defined(HELIX_FEATURE_PREFETCH)
  1540.     if (m_pPrefetchManager)
  1541.     {
  1542.         m_pPrefetchManager->Cleanup();
  1543.         HX_DELETE(m_pPrefetchManager);
  1544.     }
  1545. #endif /* HELIX_FEATURE_PREFETCH */
  1546.     HX_RELEASE(m_pCurrentGroup);
  1547.     while (m_pPendingTrackList && m_pPendingTrackList->GetCount() > 0)
  1548.     {
  1549.         PendingTrackInfo* pPendingTrackInfo =
  1550.                     (PendingTrackInfo*) m_pPendingTrackList->RemoveHead();
  1551.         delete pPendingTrackInfo;
  1552.     }
  1553. }
  1554. /************************************************************************
  1555.  *      Method:
  1556.  *              HXPlayer::ReportError
  1557.  *      Purpose:
  1558.  *              The source object reports of any fatal errors.
  1559.  *
  1560.  */
  1561. void
  1562. HXPlayer::ReportError
  1563. (
  1564.     HXSource*  pSource,
  1565.     HX_RESULT   theErr,
  1566.     const char* pUserString
  1567. )
  1568. {
  1569.     SourceInfo* pSourceInfo = NULL;
  1570.     BOOL        bDefault = FALSE;
  1571.     char*       pAltURL = NULL;
  1572.     CHXURL*     pURL = NULL;
  1573.     if (pSource && theErr != HXR_DNR && theErr != HXR_PROXY_DNR)
  1574.     {
  1575.         pURL = pSource->GetCHXURL();
  1576.         // Alt-URL only in network playback mode
  1577.         if (pURL                                                    &&
  1578.             (m_pSourceMap->Lookup(pSource, (void*&)pSourceInfo))
  1579. #if defined(HELIX_FEATURE_NEXTGROUPMGR)
  1580.             || (m_pNextGroupManager                                 &&
  1581.             m_pNextGroupManager->Lookup(pSource, pSourceInfo))
  1582. #endif /* HELIX_FEATURE_NEXTGROUPMGR */
  1583. #if defined(HELIX_FEATURE_PREFETCH)
  1584.             || (m_pPrefetchManager                                  &&
  1585.             m_pPrefetchManager->Lookup(pSource, pSourceInfo))
  1586. #endif /* HELIX_FEATURE_PREFETCH */
  1587.             )
  1588.         {
  1589.             if (pSourceInfo && pSourceInfo->m_bAltURL)
  1590.             {
  1591.                 ResetError();
  1592.                 /* If this error is for the next group, we do not want to
  1593.                  * display the error in the current group playback. Instead,
  1594.                  * pass it to the next group manager (by falling out of this
  1595.                  * if condition) so that it can be displayed when the next
  1596.                  * group is played
  1597.                  */
  1598.                 if (!pSourceInfo->m_pSource ||
  1599.                     (!pSourceInfo->m_pSource->IsPartOfNextGroup() &&
  1600.                      !pSourceInfo->m_pSource->IsPartOfPrefetchGroup()))
  1601.                 {
  1602.                     // return the last error from the main URL instead
  1603.                     Report(HXLOG_ERR, pSourceInfo->m_lastErrorFromMainURL,
  1604.                            HXR_OK, pSourceInfo->m_lastErrorStringFromMainURL, NULL);
  1605.                     goto cleanup;
  1606.                 }
  1607.                 else
  1608.                 {
  1609.                     /* Use the error from the main URL even for the next group */
  1610.                     theErr = pSourceInfo->m_lastErrorFromMainURL;
  1611.                     pUserString = pSourceInfo->m_lastErrorStringFromMainURL;
  1612.                     /* Fall through to report this error to the
  1613.                      * next group manager
  1614.                      */
  1615.                 }
  1616.             }
  1617. #if defined(HELIX_FEATURE_ALT_URL)
  1618.             // switch to Alt-URL when:
  1619.             // * the network playback has succeeded in this session or
  1620.             //   the network playback is in HTTP Cloaking mode
  1621.             //   AND
  1622.             // * the pSource is at SourceMap OR
  1623.             // * the pSource is at the NextGroupManager
  1624.             else if ((theErr != HXR_NOT_AUTHORIZED) &&
  1625.                      !IS_SERVER_ALERT(theErr)       &&
  1626.                      pURL->IsNetworkProtocol()      &&
  1627.                      (pAltURL = pSource->GetAltURL(bDefault)))
  1628.             {
  1629.                 if (!m_pAltURLs)
  1630.                 {
  1631.                     m_pAltURLs  = new CHXSimpleList();
  1632.                 }
  1633.                 if (!m_pAltURLs->Find(pSourceInfo))
  1634.                 {
  1635.                     pSourceInfo->m_lastErrorFromMainURL = theErr;
  1636.                     pSourceInfo->m_lastErrorStringFromMainURL = pUserString;
  1637.                     m_pAltURLs->AddTail(pSourceInfo);
  1638.                 }
  1639.                 goto cleanup;
  1640.             }
  1641. #endif /* HELIX_FEATURE_ALT_URL */
  1642.         }
  1643.     }
  1644. #if defined(HELIX_FEATURE_NEXTGROUPMGR)
  1645.     /* Check if this error is for the next group */
  1646.     if (m_pNextGroupManager &&
  1647.         m_pNextGroupManager->ReportError(pSource, theErr, pUserString))
  1648.     {
  1649.         goto cleanup;
  1650.     }
  1651. #endif /* HELIX_FEATURE_NEXTGROUPMGR */
  1652.     Report(HXLOG_ERR, theErr, HXR_OK, pUserString, NULL);
  1653. cleanup:
  1654.     HX_VECTOR_DELETE(pAltURL);
  1655.     return;
  1656. }
  1657. HX_RESULT HXPlayer::InitializeNetworkDrivers(void)
  1658. {
  1659. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  1660.     if (!m_bNetInitialized)
  1661.     {
  1662. #if defined( _WIN32 ) || defined( _WINDOWS )
  1663.         //  Have we been able to load and initialize the winsock stuff yet?
  1664.         m_bNetInitialized = win_net::IsWinsockAvailable(this);
  1665. #elif defined (_MACINTOSH)
  1666.         m_bNetInitialized = (conn::init_drivers(NULL) == HXR_OK);
  1667. #elif defined(_UNIX) || defined(_SYMBIAN) || defined(__TCS__) || defined(_OPENWAVE)
  1668.         m_bNetInitialized = TRUE;
  1669. #endif
  1670.     }
  1671.     return (m_bNetInitialized) ? HXR_OK : HXR_GENERAL_NONET;
  1672. #else
  1673.     return HXR_NOTIMPL;
  1674. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  1675. }
  1676. void
  1677. HXPlayer::EventOccurred(HXxEvent* pEvent)
  1678. {
  1679.   // Note: Unix player does not go through here.
  1680.   // calls for UNIX go directly from Client Engine to
  1681.   // Site Window class
  1682. #if defined (_MACINTOSH) || defined(_MAC_UNIX)
  1683. //    if (HXMM_RAHUL_CHECK())
  1684. //    {
  1685. //        DebugStr("pEventOccurred SYSTEM Task ENTER;g");
  1686. //    }
  1687. #ifdef _MACINTOSH
  1688.     extern ULONG32         gTIMELINE_MUTEX;
  1689.     InterlockedIncrement(&gTIMELINE_MUTEX);
  1690. #endif
  1691.     if (pEvent->event == nullEvent && m_bIsPlaying)
  1692.     {
  1693.         ULONG32 ulAudioTime = m_pAudioPlayer->GetCurrentPlayBackTime();
  1694.         if ( m_ulCurrentSystemPlayTime != ulAudioTime )
  1695.         {
  1696.             OnTimeSync( ulAudioTime );
  1697.         }
  1698.     }
  1699. #ifdef _MACINTOSH
  1700.     InterlockedDecrement(&gTIMELINE_MUTEX);
  1701. #endif
  1702. //    if (HXMM_RAHUL_CHECK())
  1703. //    {
  1704. //        DebugStr("pEventOccurred SYSTEM Task LEAVE;g");
  1705. //    }
  1706. #endif
  1707. }
  1708. #ifdef _UNIX
  1709. void
  1710. HXPlayer::CollectSelectInfo(INT32* n,
  1711.                              fd_set* readfds,
  1712.                              fd_set* writefds,
  1713.                              fd_set* exceptfds,
  1714.                              struct timeval* tv)
  1715. {
  1716. }
  1717. void
  1718. HXPlayer::ProcessSelect(INT32* n,
  1719.                          fd_set* readfds,
  1720.                          fd_set* writefds,
  1721.                          fd_set* exceptfds,
  1722.                          struct timeval* tv)
  1723. {
  1724. }
  1725. #endif
  1726. void
  1727. HXPlayer::SetGranularity(ULONG32 ulGranularity)
  1728. {
  1729.     if (m_ulLowestGranularity > ulGranularity)
  1730.     {
  1731.         m_ulLowestGranularity = ulGranularity;
  1732.     }
  1733.     /* sanity check */
  1734.     if (m_ulLowestGranularity < MINIMUM_TIMESYNC_GRANULARITY)
  1735.     {
  1736.         m_ulLowestGranularity = MINIMUM_TIMESYNC_GRANULARITY;
  1737.     }
  1738. }
  1739. HX_RESULT
  1740. HXPlayer::SetGranularity(HXSource* pSource, UINT16 uStreamNumber,
  1741.                           UINT32 ulGranularity)
  1742. {
  1743.     SourceInfo*     pSourceInfo = pSource->m_pSourceInfo;
  1744.     RendererInfo*   pRendInfo   = NULL;
  1745.     HX_ASSERT(pSourceInfo);
  1746.     if (!pSourceInfo->m_pRendererMap->Lookup((LONG32) uStreamNumber, (void*&) pRendInfo))
  1747.     {
  1748.         HX_ASSERT(FALSE);
  1749.         return HXR_INVALID_PARAMETER;
  1750.     }
  1751.     pRendInfo->m_ulGranularity  = ulGranularity;
  1752.     /* sanity check */
  1753.     if (pRendInfo->m_ulGranularity < MINIMUM_TIMESYNC_GRANULARITY)
  1754.     {
  1755.         pRendInfo->m_ulGranularity = MINIMUM_TIMESYNC_GRANULARITY;
  1756.     }
  1757.     return HXR_OK;
  1758. }
  1759. /************************************************************************
  1760.  *      Method:
  1761.  *              HXPlayer::ClosePlayer
  1762.  *      Purpose:
  1763.  *              Just adding a lock around calls to Close()
  1764.  *
  1765.  */
  1766. void HXPlayer::ClosePlayer(void)
  1767. {
  1768.     m_bCoreLocked = TRUE;
  1769.     m_pCoreMutex->Lock();
  1770.     Close();
  1771.     m_pCoreMutex->Unlock();
  1772.     m_bCoreLocked = FALSE;
  1773. }
  1774. void
  1775. HXPlayer::AbortPlayer(void)
  1776. {
  1777.     // Stop completely...
  1778.     m_bIsPresentationClosedToBeSent = TRUE;
  1779.     m_bIsDone = TRUE;
  1780.     StopPlayer(END_ABORT);
  1781. #if defined(HELIX_FEATURE_VIDEO)
  1782.     /*
  1783.      * Let the site supplier know that we are done changing the layout.
  1784.      */
  1785.     if (m_pSiteSupplier && !m_bBeginChangeLayoutTobeCalled)
  1786.     {
  1787.         m_bBeginChangeLayoutTobeCalled  = TRUE;
  1788.         m_pSiteSupplier->DoneChangeLayout();
  1789.     }
  1790. #endif /* HELIX_FEATURE_VIDEO */
  1791. }
  1792. void
  1793. HXPlayer::Close()
  1794. {
  1795.     StopPlayer(END_STOP);
  1796.     CloseAllRenderers(m_nCurrentGroup);
  1797. #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
  1798.     if (m_pRegistry)
  1799.     {
  1800.         // delete player stats
  1801.         if (m_pStats && m_pStats->m_ulRegistryID)
  1802.         {
  1803.             m_pRegistry->DeleteById(m_pStats->m_ulRegistryID);
  1804.         }
  1805.         HX_DELETE(m_pStats);
  1806.         // delete repeat stats
  1807.         if (m_ulRepeatedRegistryID)
  1808.         {
  1809.             m_pRegistry->DeleteById(m_ulRepeatedRegistryID);
  1810.             m_ulRepeatedRegistryID = 0;
  1811.         }
  1812.         // delete nextgroup stats
  1813.         if (m_ulNextGroupRegistryID)
  1814.         {
  1815.             m_pRegistry->DeleteById(m_ulNextGroupRegistryID);
  1816.             m_ulNextGroupRegistryID = 0;
  1817.         }
  1818.     }
  1819.     if (m_pUpdateStatsCallback)
  1820.     {
  1821.         if (m_pUpdateStatsCallback->m_bIsCallbackPending)
  1822.         {
  1823.             m_pUpdateStatsCallback->m_bIsCallbackPending = FALSE;
  1824.             m_pScheduler->Remove(m_pUpdateStatsCallback->m_PendingHandle);
  1825.             m_pUpdateStatsCallback->m_PendingHandle = 0;
  1826.         }
  1827.         HX_RELEASE(m_pUpdateStatsCallback);
  1828.     }
  1829. #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
  1830.     if (m_bIsPresentationClosedToBeSent)
  1831.     {
  1832.         m_bIsPresentationClosedToBeSent = FALSE;
  1833.         if (m_pAdviseSink)
  1834.         {
  1835.             m_pAdviseSink->OnStop();
  1836.             m_pAdviseSink->OnPresentationClosed();
  1837.         }
  1838.     }
  1839.     HX_RELEASE (m_pAdviseSink);
  1840.     RemovePendingCallback(m_pHXPlayerCallback);
  1841.     HX_RELEASE(m_pHXPlayerCallback);
  1842.     RemovePendingCallback(m_pHXPlayerInterruptCallback);
  1843.     HX_RELEASE(m_pHXPlayerInterruptCallback);
  1844.     RemovePendingCallback(m_pSetupCallback);
  1845.     HX_RELEASE(m_pSetupCallback);
  1846. #if defined(HELIX_FEATURE_AUTHENTICATION)
  1847.     if (m_pAuthenticationCallback)
  1848.     {
  1849.         ClearPendingAuthenticationRequests();
  1850.         HX_RELEASE(m_pAuthenticationCallback);
  1851.     }
  1852. #endif /* HELIX_FEATURE_AUTHENTICATION */
  1853.     HX_RELEASE(m_pAutheticationValues);
  1854.     HX_RELEASE(m_pRequest);
  1855.     ResetRedirectList();
  1856.     HX_DELETE (m_pRedirectList);
  1857.     HX_DELETE (m_pURL);
  1858.     HX_DELETE (m_pAltURLs);
  1859. #if defined(HELIX_FEATURE_REGISTRY)
  1860.     HX_RELEASE (m_pRegistry);
  1861. #endif /* HELIX_FEATURE_REGISTRY */
  1862.     HX_RELEASE (m_pEngine);
  1863.     HX_RELEASE (m_pClient);
  1864.     HX_RELEASE (m_pScheduler);
  1865.     if (m_pErrorSinkControl)
  1866.     {
  1867. #if defined(HELIX_FEATURE_SINKCONTROL)
  1868.         m_pErrorSinkControl->Close();
  1869. #endif /* HELIX_FEATURE_SINKCONTROL */
  1870.         HX_RELEASE (m_pErrorSinkControl);
  1871.     }
  1872.     HX_RELEASE(m_pClientRequestSink);
  1873. #if defined(HELIX_FEATURE_PREFERENCES)
  1874.     HX_RELEASE (m_pPreferences);
  1875. #endif /* HELIX_FEATURE_PREFERENCES */
  1876. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  1877.     if (m_pHyperNavigate)
  1878.     {
  1879. #if defined(HELIX_FEATURE_HYPER_NAVIGATE)
  1880.         m_pHyperNavigate->Close();
  1881. #endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
  1882.         HX_RELEASE (m_pHyperNavigate);
  1883.     }
  1884. #endif /* HELIX_FEATURE_HYPER_NAVIGATE */
  1885. #if defined(HELIX_FEATURE_BASICGROUPMGR)
  1886.     if (m_pGroupManager)
  1887.     {
  1888.         m_pGroupManager->RemoveSink(this);
  1889. #if defined(HELIX_FEATURE_NESTEDMETA)
  1890.         m_pGroupManager->RemoveSink(m_pPersistentComponentManager);
  1891. #endif /* HELIX_FEATURE_NESTEDMETA */
  1892.         HX_RELEASE(m_pGroupManager);
  1893.     }
  1894. #endif /* HELIX_FEATURE_BASICGROUPMGR */
  1895. #if defined(HELIX_FEATURE_VIDEO)
  1896.     HX_RELEASE (m_pSiteManager);
  1897.     HX_RELEASE (m_pSiteSupplier);
  1898. #endif /* HELIX_FEATURE_VIDEO */
  1899. #if defined(HELIX_FEATURE_AUTOUPGRADE)
  1900.     HX_RELEASE (m_pUpgradeCollection);
  1901. #endif /* HELIX_FEATURE_AUTOUPGRADE */
  1902. #if defined(HELIX_FEATURE_PACKETHOOKMGR)
  1903.     HX_RELEASE (m_pPacketHookManager);
  1904. #endif /* HELIX_FEATURE_PACKETHOOKMGR */
  1905. #if defined(HELIX_FEATURE_SMARTERNETWORK)
  1906.     HX_RELEASE (m_pPreferredTransportManager);
  1907. #endif /* HELIX_FEATURE_SMARTERNETWORK */
  1908.     HX_RELEASE (m_pNetInterfaces);
  1909.     HX_RELEASE (m_pClientViewSource);
  1910.     HX_RELEASE (m_pViewPortManager);
  1911.     HX_RELEASE (m_pClientViewRights);
  1912. #if defined(HELIX_FEATURE_MEDIAMARKER)
  1913.     if (m_pMediaMarkerManager)
  1914.     {
  1915.         m_pMediaMarkerManager->Close();
  1916.         HX_RELEASE(m_pMediaMarkerManager);
  1917.     }
  1918. #endif /* #if defined(HELIX_FEATURE_MEDIAMARKER) */
  1919. #if defined(HELIX_FEATURE_EVENTMANAGER)
  1920.     if (m_pEventManager)
  1921.     {
  1922.         m_pEventManager->Close();
  1923.         HX_RELEASE(m_pEventManager);
  1924.     }
  1925. #endif /* #if defined(HELIX_FEATURE_EVENTMANAGER) */
  1926. #if defined(HELIX_FEATURE_NESTEDMETA)
  1927.     if (m_pPersistentComponentManager)
  1928.     {
  1929.         m_pPersistentComponentManager->Close();
  1930.         HX_RELEASE (m_pPersistentComponentManager);
  1931.     }
  1932. #endif /* HELIX_FEATURE_NESTEDMETA */
  1933. #if defined(HELIX_FEATURE_AUDIO)
  1934.     if (m_pAudioPlayer)
  1935.     {
  1936.         CHXAudioSession* pAudioSession = m_pAudioPlayer->GetOwner();
  1937.         if (pAudioSession)
  1938.         {
  1939.             pAudioSession->CloseAudioPlayer(m_pAudioPlayer);
  1940.         }
  1941.         HX_RELEASE (m_pAudioPlayer);
  1942.     }
  1943. #endif /* HELIX_FEATURE_AUDIO */
  1944.     if (m_pMasterTAC)
  1945.     {
  1946. #if defined(HELIX_FEATURE_MASTERTAC)
  1947.         m_pMasterTAC->Close();
  1948. #endif /* HELIX_FEATURE_MASTERTAC */
  1949.         HX_RELEASE(m_pMasterTAC);
  1950.     }
  1951. #if defined(HELIX_FEATURE_PREFETCH)
  1952.     HX_DELETE(m_pPrefetchManager);
  1953. #endif /* HELIX_FEATURE_PREFETCH */
  1954. #if defined(HELIX_FEATURE_NEXTGROUPMGR)
  1955.     HX_DELETE(m_pNextGroupManager);
  1956. #endif /* HELIX_FEATURE_NEXTGROUPMGR */
  1957. #if defined(HELIX_FEATURE_ASM)
  1958.     if (m_pBandwidthMgr)
  1959.     {
  1960.         m_pBandwidthMgr->PresentationDone();
  1961.         HX_RELEASE(m_pBandwidthMgr);
  1962.     }
  1963. #endif /* HELIX_FEATURE_ASM */
  1964. #if defined(HELIX_FEATURE_ASM)
  1965.     HX_RELEASE(m_pASM);
  1966. #endif /* HELIX_FEATURE_ASM */
  1967.     HX_ASSERT(!m_pPendingTrackList || m_pPendingTrackList->IsEmpty());
  1968.     HX_DELETE(m_pPendingTrackList);
  1969.     if (m_pChildPlayerList)
  1970.     {
  1971.         CHXSimpleList::Iterator i = m_pChildPlayerList->Begin();
  1972.         for (; i != m_pChildPlayerList->End(); ++i)
  1973.         {
  1974.             IHXPlayer* pChildPlayer = (IHXPlayer*)(*i);
  1975.             HX_RELEASE(pChildPlayer);
  1976.         }
  1977.         HX_DELETE(m_pChildPlayerList);
  1978.     }
  1979.     HX_RELEASE(m_pParentPlayer);
  1980. #if defined(HELIX_FEATURE_PLAYBACK_NET)
  1981.     if (m_bNetInitialized)
  1982.     {
  1983.         m_bNetInitialized = FALSE;
  1984. #if defined( _WIN32 ) || defined( _WINDOWS )
  1985.         win_net::ReleaseWinsockUsage(this);
  1986. #endif /* defined( _WIN32 ) || defined( _WINDOWS ) */
  1987.     }
  1988. #endif /* HELIX_FEATURE_PLAYBACK_NET */
  1989. #if defined(_DEBUG) && defined(DEBUG_LOG_INFO)
  1990.      HXStaticStatLog::Close();
  1991. #endif // DEBUG_LOG_INFO
  1992.     HX_RELEASE(m_pPlugin2Handler);
  1993. #if defined(HELIX_FEATURE_RECORDCONTROL)
  1994.     UnloadRecordService();
  1995. #endif /* HELIX_FEATURE_RECORDCONTROL */
  1996.     ResetError();
  1997. }
  1998. void
  1999. HXPlayer::ProcessPendingAuthentication(void)
  2000. {
  2001. #if defined(HELIX_FEATURE_AUTHENTICATION)
  2002.     IHXAuthenticationManager2* pAuthenticationManagerClient2 = NULL;
  2003.     if (HXR_OK == m_pClient->QueryInterface(IID_IHXAuthenticationManager2,
  2004.                              (void**)&pAuthenticationManagerClient2))
  2005.     {
  2006.         HX_ASSERT(pAuthenticationManagerClient2);
  2007.         if (pAuthenticationManagerClient2)
  2008.         {
  2009.             pAuthenticationManagerClient2->HandleAuthenticationRequest2(this, m_pAutheticationValues);
  2010.         }
  2011.         HX_RELEASE(pAuthenticationManagerClient2);
  2012.         return;
  2013.     }
  2014.     // otherwise continue with the old-fashioned authentication manager
  2015.     IHXAuthenticationManager* pAuthenticationManagerClient = NULL;
  2016.     m_pClient->QueryInterface(IID_IHXAuthenticationManager,
  2017.                              (void**)&pAuthenticationManagerClient);
  2018.     HX_ASSERT(pAuthenticationManagerClient);
  2019.     if (pAuthenticationManagerClient)
  2020.     {
  2021.         pAuthenticationManagerClient->HandleAuthenticationRequest(this);
  2022.     }
  2023.     HX_RELEASE(pAuthenticationManagerClient);
  2024. #endif /* HELIX_FEATURE_AUTHENTICATION */
  2025. }
  2026. void
  2027. HXPlayer::ClearPendingAuthenticationRequests(void)
  2028. {
  2029. #if defined(HELIX_FEATURE_AUTHENTICATION)
  2030.     m_AuthenticationRequestsPending.ClearPendingList();
  2031.     RemovePendingCallback(m_pAuthenticationCallback);
  2032.     /* Remove all pending authentication requests TBD */
  2033. #endif /* HELIX_FEATURE_AUTHENTICATION */
  2034. }
  2035. STDMETHODIMP
  2036. HXPlayer::HandleAuthenticationRequest(
  2037.     IHXAuthenticationManagerResponse* pResponse)
  2038. {
  2039. #if defined(HELIX_FEATURE_AUTHENTICATION)
  2040.     return HandleAuthenticationRequest2( pResponse, NULL );
  2041. #else
  2042.     return HXR_NOTIMPL;
  2043. #endif /* HELIX_FEATURE_AUTHENTICATION */
  2044. }
  2045. STDMETHODIMP
  2046. HXPlayer::HandleAuthenticationRequest2(
  2047.     IHXAuthenticationManagerResponse* pResponse, IHXValues* pValues)
  2048. {
  2049. #if defined(HELIX_FEATURE_AUTHENTICATION)
  2050.     IHXValues*                  pHeader = NULL;
  2051.     IHXBuffer*                  pUserName = NULL;
  2052.     IHXBuffer*                  pPassword = NULL;
  2053.     ULONG32                     ulAuthenticationAttempts = 0;
  2054.     HX_RELEASE(m_pAutheticationValues);
  2055.     m_pAutheticationValues = pValues;
  2056.     if (m_pAutheticationValues)
  2057.     {
  2058.         m_pAutheticationValues->AddRef();
  2059.     }
  2060.     /* Username/Password in the url will not work for tracks within
  2061.      * SMIL/RAM files.
  2062.      * This is because the m_pURL points to the last opened track
  2063.      * in the presentation and may not point to the URL for which
  2064.      * the authentication has been requested for.
  2065.      * This is tricky to fix --- post B2 - XXXRA
  2066.      */
  2067.     // Get info about the URL
  2068.     if (m_pURL)
  2069.     {
  2070.         pHeader = m_pURL->GetProperties();
  2071.     }
  2072.     if (pHeader)
  2073.     {
  2074.         // Try to get the username and password from the URL
  2075.         pHeader->GetPropertyBuffer(PROPERTY_USERNAME, pUserName);
  2076.         pHeader->GetPropertyBuffer(PROPERTY_PASSWORD, pPassword);
  2077.         // Try to get the number of times we've tried to authenticate
  2078.         // already based on this name and password
  2079.         HX_RESULT res = pHeader->GetPropertyULONG32("AUTHENTICATION_ATTEMPTS", ulAuthenticationAttempts);
  2080.     }
  2081.     // First check to see if a username and/or password were supplied in the URL.  If they were there is no need to pass
  2082.     // this on to the client to display any UI.
  2083.     // (And in case the wrong name/password were supplied, don't let them try too many times.)
  2084.     if (pUserName && pPassword && (ulAuthenticationAttempts < 3))
  2085.     {
  2086.         if (pHeader)
  2087.         {
  2088.             pHeader->SetPropertyULONG32("AUTHENTICATION_ATTEMPTS", ulAuthenticationAttempts + 1);
  2089.         }
  2090.         pResponse->AuthenticationRequestDone(HXR_OK, (const char*)pUserName->GetBuffer(), (const char*)pPassword->GetBuffer());
  2091.     }
  2092.     else
  2093.     {
  2094. #ifndef _WIN16
  2095.         m_AuthenticationRequestsPending.Add(this, pResponse, pValues);
  2096. #else
  2097.         IHXAuthenticationManager2* pAuthenticationManagerClient2 = NULL;
  2098.         if (HXR_OK == m_pClient->QueryInterface(IID_IHXAuthenticationManager2, (void**)&pAuthenticationManagerClient2))
  2099.         {
  2100.             pAuthenticationManagerClient2->HandleAuthenticationRequest2
  2101.                 (
  2102.                     pResponse, pValues
  2103.                 );
  2104.             HX_RELEASE(pAuthenticationManagerClient2);
  2105.         }
  2106.         else
  2107.         {
  2108.             // if the new authentication manager isn't available, use the old authentication manager.
  2109.             IHXAuthenticationManager* pAuthenticationManagerClient = NULL;
  2110.             m_pClient->QueryInterface
  2111.                 (
  2112.                     IID_IHXAuthenticationManager,
  2113.                     (void**)&pAuthenticationManagerClient
  2114.                 );
  2115.             pAuthenticationManagerClient->HandleAuthenticationRequest
  2116.                 (
  2117.                     pResponse
  2118.                 );
  2119.             HX_RELEASE(pAuthenticationManagerClient);
  2120.         }
  2121. #endif /* _WIN16 */
  2122.     }
  2123.     HX_RELEASE(pUserName);
  2124.     HX_RELEASE(pPassword);
  2125.     HX_RELEASE(pHeader);
  2126. #endif /* HELIX_FEATURE_AUTHENTICATION */
  2127.     return HXR_OK;
  2128. }
  2129. // IHXAuthenticationManagerResponse
  2130. STDMETHODIMP
  2131. HXPlayer::AuthenticationRequestDone
  2132. (
  2133.     HX_RESULT result,
  2134.     const char* user,
  2135.     const char* password
  2136. )
  2137. {
  2138. #if !defined(_WIN16) && defined(HELIX_FEATURE_AUTHENTICATION)
  2139.     return m_AuthenticationRequestsPending.SatisfyPending
  2140.     (
  2141.         result,
  2142.         user,
  2143.         password
  2144.     );
  2145. #else
  2146.     return HXR_NOTIMPL;
  2147. #endif /* _WIN16 */
  2148. }
  2149. /*
  2150.  *      IHXViewSourceCommand::CanViewSouce
  2151.  */
  2152. STDMETHODIMP_(BOOL)
  2153. HXPlayer::CanViewSource(IHXStreamSource* pStream)
  2154. {
  2155. #if defined(HELIX_FEATURE_VIEWSOURCE)
  2156.     BOOL bRet = TRUE;
  2157.     HX_RESULT ret = HXR_OK;
  2158.     if ( m_pClientViewSource == NULL && m_pEngine )
  2159.     {
  2160.         m_pEngine->QueryInterface(IID_IHXClientViewSource,
  2161.             (void**)&m_pClientViewSource);
  2162.     }
  2163.     if ( m_pClientViewSource )
  2164.     {
  2165.         if ( pStream )
  2166.         {
  2167.             bRet = m_pClientViewSource->CanViewSource(pStream);
  2168.         }
  2169.         else
  2170.         {
  2171.             IHXStreamSource* pStrmSource = NULL;
  2172.             if ( GetViewSourceStream(pStrmSource) )
  2173.             {
  2174.                 bRet = m_pClientViewSource->CanViewSource(pStrmSource);
  2175.             }
  2176.             else
  2177.             {
  2178.                 bRet = FALSE;
  2179.             }
  2180.             HX_RELEASE(pStrmSource);
  2181.         }
  2182.     }
  2183.     else
  2184.     {
  2185.         bRet = FALSE;
  2186.     }
  2187.     return bRet;
  2188. #else
  2189.     return FALSE;
  2190. #endif
  2191. }
  2192. /*
  2193.  *      IHXViewSourceCommand::DoViewSouce
  2194.  */
  2195. STDMETHODIMP
  2196. HXPlayer::DoViewSource(IHXStreamSource* pStream)
  2197. {
  2198. #if defined(HELIX_FEATURE_VIEWSOURCE)
  2199.     HX_RESULT ret = HXR_OK;
  2200.     if ( m_pClientViewSource == NULL && m_pEngine )
  2201.     {
  2202.         m_pEngine->QueryInterface(IID_IHXClientViewSource,
  2203.             (void**)&m_pClientViewSource);
  2204.     }
  2205.     if ( m_pClientViewSource )
  2206.     {
  2207.         if ( pStream )
  2208.         {
  2209.             ret = m_pClientViewSource->DoViewSource((IUnknown*)(IHXPlayer*)this, pStream);
  2210.         }
  2211.         else
  2212.         {
  2213.             IHXStreamSource* pStrmSource = NULL;
  2214.             if ( GetViewSourceStream(pStrmSource) )
  2215.             {
  2216.                 ret = m_pClientViewSource->DoViewSource((IUnknown*)(IHXPlayer*)this,
  2217.                     pStrmSource);
  2218.             }
  2219.             else
  2220.             {
  2221.                 // pass null for the stream source -
  2222.                 // will cause a no source error to be shown.
  2223.                 ret = m_pClientViewSource->DoViewSource(
  2224.                     (IUnknown*)(IHXPlayer*)this, NULL);
  2225.             }
  2226.             HX_RELEASE(pStrmSource);
  2227.         }
  2228.     }
  2229.     else
  2230.     {
  2231.         ret = HXR_NOT_INITIALIZED;
  2232.     }
  2233.     return ret;
  2234. #else
  2235.     return HXR_NOTIMPL;
  2236. #endif /* HELIX_FEATURE_AUTHENTICATION */
  2237. }
  2238. /*
  2239.  *      IHXViewSourceCommand::GetViewSourceURL
  2240.  */
  2241. STDMETHODIMP
  2242. HXPlayer::GetViewSourceURL(IHXStreamSource* pStream, IHXViewSourceURLResponse* pResp)
  2243. {
  2244. #if defined(HELIX_FEATURE_VIEWSOURCE)
  2245.     HX_RESULT ret = HXR_OK;
  2246.     if ( m_pClientViewSource == NULL && m_pEngine )
  2247.     {
  2248.         m_pEngine->QueryInterface(IID_IHXClientViewSource,
  2249.             (void**)&m_pClientViewSource);
  2250.     }
  2251.     if ( m_pClientViewSource )
  2252.     {
  2253.         if ( pStream )
  2254.         {
  2255.             ret = m_pClientViewSource->GetViewSourceURL(
  2256.                 (IUnknown*)(IHXPlayer*)this, pStream, pResp);
  2257.         }
  2258.         else
  2259.         {
  2260.             IHXStreamSource* pStrmSource = NULL;
  2261.             if ( GetViewSourceStream(pStrmSource) )
  2262.             {
  2263.                 ret = m_pClientViewSource->GetViewSourceURL(
  2264.                     (IUnknown*)(IHXPlayer*)this, pStrmSource, pResp);
  2265.             }
  2266.             else
  2267.             {
  2268.                 ret = HXR_FAIL;
  2269.             }
  2270.             HX_RELEASE(pStrmSource);
  2271.         }
  2272.     }
  2273.     else
  2274.     {
  2275.         ret = HXR_NOT_INITIALIZED;
  2276.     }
  2277.     return ret;
  2278. #else
  2279.     return HXR_NOTIMPL;
  2280. #endif /* HELIX_FEATURE_VIEWSOURCE */
  2281. }
  2282. BOOL
  2283. HXPlayer::GetViewSourceStream(REF(IHXStreamSource*) pStrmSource)
  2284. {
  2285.     BOOL bRet = FALSE;
  2286. #if defined(HELIX_FEATURE_VIEWSOURCE)
  2287. #if defined(HELIX_FEATURE_NESTEDMETA)
  2288.         HXPersistentComponent* pPersistentComponent = m_pPersistentComponentManager->m_pRootPersistentComponent;
  2289.         // not a persistent playback
  2290.         if (!pPersistentComponent)
  2291.         {
  2292.             HX_ASSERT(m_pSourceMap->GetCount() <= 1);
  2293.             if ( m_pSourceMap->GetCount() > 0 )
  2294.             {
  2295.                 CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
  2296.                 SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
  2297.                 HX_ASSERT(pSourceInfo);
  2298.                 HXSource* pSource = pSourceInfo->m_pSource;
  2299.                 if( pSource )
  2300.                 {
  2301.                     HX_RELEASE(pStrmSource);
  2302.                     if ( SUCCEEDED(pSource->QueryInterface(IID_IHXStreamSource,
  2303.                         (void**)&pStrmSource)) )
  2304.                     {
  2305.                         bRet = TRUE;
  2306.                     }
  2307.                 }
  2308.             }
  2309.         }
  2310.         else
  2311.         {
  2312.             HXSource* pSource = pPersistentComponent->m_pSourceInfo->m_pSource;
  2313.             if ( pSource )
  2314.             {
  2315.                 HX_RELEASE(pStrmSource);
  2316.                 if ( SUCCEEDED(pSource->QueryInterface(IID_IHXStreamSource,
  2317.                     (void**)&pStrmSource)) )
  2318.                 {
  2319.                     bRet = TRUE;
  2320.                 }
  2321.             }
  2322.         }
  2323. #else
  2324.         HX_ASSERT(m_pSourceMap->GetCount() <= 1);
  2325.         if ( m_pSourceMap->GetCount() > 0 )
  2326.         {
  2327.             CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
  2328.             SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
  2329.             HX_ASSERT(pSourceInfo);
  2330.             HXSource* pSource = pSourceInfo->m_pSource;
  2331.             if( pSource )
  2332.             {
  2333.                 HX_RELEASE(pStrmSource);
  2334.                 if ( SUCCEEDED(pSource->QueryInterface(IID_IHXStreamSource,
  2335.                     (void**)&pStrmSource)) )
  2336.                 {
  2337.                     bRet = TRUE;
  2338.                 }
  2339.             }
  2340.         }
  2341. #endif /* HELIX_FEATURE_NESTEDMETA */
  2342. #endif /* HELIX_FEATURE_VIEWSOURCE */
  2343.     return bRet;
  2344. }
  2345. HX_RESULT
  2346. HXPlayer::GetSourceInfo(UINT16 uGroupIndex, UINT16 uTrackIndex, SourceInfo*& pSourceInfo)
  2347. {
  2348. #if defined(HELIX_FEATURE_BASICGROUPMGR)
  2349.     HX_RESULT   hr = HXR_OK;
  2350.     SourceInfo* pTempSourceInfo = NULL;
  2351.     CHXMapPtrToPtr::Iterator ndxSource;
  2352.     pSourceInfo = NULL;
  2353.     if (uGroupIndex != m_nCurrentGroup)
  2354.     {
  2355.         hr = HXR_UNEXPECTED;
  2356.         goto cleanup;
  2357.     }
  2358.     // find the sourceinfo
  2359.     ndxSource = m_pSourceMap->Begin();
  2360.     for (; ndxSource != m_pSourceMap->End(); ++ndxSource)
  2361.     {
  2362.         pTempSourceInfo = (SourceInfo*)(*ndxSource);
  2363.         if (pTempSourceInfo->m_uTrackID == uTrackIndex)
  2364.         {
  2365.             pSourceInfo = pTempSourceInfo;
  2366.             break;
  2367.         }
  2368.     }
  2369.     if (!pSourceInfo)
  2370.     {
  2371.         hr = HXR_FAILED;
  2372.     }
  2373. cleanup:
  2374.     return hr;
  2375. #else
  2376.     return HXR_NOTIMPL;
  2377. #endif /* HELIX_FEATURE_BASICGROUPMGR */
  2378. }
  2379. HX_RESULT
  2380. HXPlayer::CopyRegInfo(UINT32 ulFromRegID, UINT32 ulToRegID)
  2381. {
  2382. #if defined(HELIX_FEATURE_REGISTRY)
  2383.     HX_RESULT       hr = HXR_OK;
  2384.     const char*     pPropName = NULL;
  2385.     ULONG32          ulPropId = 0;
  2386.     UINT32          ulRegId = 0;
  2387.     IHXBuffer*      pFromRegName = NULL;
  2388.     IHXBuffer*      pToRegName = NULL;
  2389.     IHXValues*      pValues = NULL;
  2390.     char            szRegName[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
  2391.     m_pRegistry->GetPropName(ulFromRegID, pFromRegName);
  2392.     m_pRegistry->GetPropName(ulToRegID, pToRegName);
  2393.     // Get the IHXValues under this id.
  2394.     m_pRegistry->GetPropListById(ulFromRegID, pValues);
  2395.     // PT_COMPOSITE without child
  2396.     if (!pValues)
  2397.     {
  2398.         return HXR_OK;
  2399.     }
  2400.     // iterate through the child list
  2401.     hr = pValues->GetFirstPropertyULONG32(pPropName, ulPropId);
  2402.     while (hr == HXR_OK)
  2403.     {
  2404.         HXPropType type = m_pRegistry->GetTypeById(ulPropId);
  2405.         SafeSprintf(szRegName, MAX_DISPLAY_NAME, "%s.%s", pToRegName->GetBuffer(),
  2406.                 pPropName + pFromRegName->GetSize());
  2407.         if (type == PT_COMPOSITE)
  2408.         {
  2409.             ulRegId = m_pRegistry->AddComp(szRegName);
  2410.             CopyRegInfo(ulPropId, ulRegId);
  2411.         }
  2412.         else
  2413.         {
  2414.             switch(type)
  2415.             {
  2416.                 case PT_INTEGER:
  2417.                 {
  2418.                     INT32 val;
  2419.                     if(HXR_OK == m_pRegistry->GetIntById(ulPropId, val))
  2420.                     {
  2421.                         m_pRegistry->AddInt(szRegName, val);
  2422.                     }
  2423.                     break;
  2424.                 }
  2425.                 case PT_STRING:
  2426.                 {
  2427.                     IHXBuffer* pBuffer = NULL;
  2428.                     if(HXR_OK == m_pRegistry->GetStrById(ulPropId,
  2429.                                                        pBuffer))
  2430.                     {
  2431.                         m_pRegistry->AddStr(szRegName, pBuffer);
  2432.                     }
  2433.                     HX_RELEASE(pBuffer);
  2434.                     break;
  2435.                 }
  2436.                 case PT_BUFFER:
  2437.                 {
  2438.                     IHXBuffer* pBuffer = NULL;
  2439.                     if(HXR_OK == m_pRegistry->GetBufById(ulPropId,
  2440.                                                        pBuffer))
  2441.                     {
  2442.                         m_pRegistry->AddBuf(szRegName, pBuffer);
  2443.                     }
  2444.                     HX_RELEASE(pBuffer);
  2445.                     break;
  2446.                 }
  2447.                 default:
  2448.                     break;
  2449.             }
  2450.         }
  2451.         hr = pValues->GetNextPropertyULONG32(pPropName, ulPropId);
  2452.     }
  2453.     HX_RELEASE(pFromRegName);
  2454.     HX_RELEASE(pToRegName);
  2455.     HX_RELEASE(pValues);
  2456. #endif /* HELIX_FEATURE_REGISTRY */
  2457.     return HXR_OK;
  2458. }
  2459. HX_RESULT
  2460. HXPlayer::UpdateTrack(UINT16 uGroupIndex, UINT16 uTrackIndex, IHXValues* pValues)
  2461. {
  2462. #if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
  2463.     HX_RESULT   hr = HXR_OK;
  2464.     UINT16      uCurrentGroup = 0;
  2465.     UINT16      uNewTrackIndex = 0;
  2466.     UINT32      ulParentRegId = 0;
  2467.     SourceInfo* pSourceInfo = NULL;
  2468.     IHXGroup*  pGroup = NULL;
  2469.     if (HXR_OK == pValues->GetPropertyULONG32("TrackIndex", (UINT32&)uNewTrackIndex))
  2470.     {
  2471.         if (uGroupIndex == m_nCurrentGroup &&
  2472.             HXR_OK == GetSourceInfo(uGroupIndex, uTrackIndex, pSourceInfo))
  2473.         {
  2474. #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
  2475.             ulParentRegId = m_pStats->m_ulRegistryID;
  2476. #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
  2477.         }
  2478. #if defined (HELIX_FEATURE_NEXTGROUPMGR)
  2479.         else if (m_bNextGroupStarted                                                &&
  2480.                  m_pNextGroupManager->GetCurrentGroup(uCurrentGroup, pGroup) == HXR_OK  &&
  2481.                  uCurrentGroup == uGroupIndex)
  2482.         {
  2483.             m_pNextGroupManager->GetSource(uTrackIndex, pSourceInfo);
  2484.             ulParentRegId = m_ulNextGroupRegistryID;
  2485.         }
  2486. #endif /* HELIX_FEATURE_NEXTGROUPMGR */
  2487.         if (pSourceInfo)
  2488.         {
  2489.             hr = UpdateSourceInfo(pSourceInfo,
  2490.                                   ulParentRegId,
  2491.                                   uNewTrackIndex);
  2492.         }
  2493.     }
  2494. #if defined(HELIX_FEATURE_NESTEDMETA)
  2495.     m_pPersistentComponentManager->TrackUpdated(uGroupIndex, uTrackIndex, pValues);
  2496. #endif /* HELIX_FEATURE_NESTEDMETA */
  2497.     return hr;
  2498. #else
  2499.     return HXR_NOTIMPL;
  2500. #endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
  2501. }
  2502. HX_RESULT
  2503. HXPlayer::RemoveTrack(UINT16 uGroupIndex, UINT16 uTrackIndex, IHXValues* pValues)
  2504. {
  2505. #if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
  2506.     HX_RESULT   hr = HXR_OK;
  2507.     UINT16      uCurrentGroup = 0;
  2508.     SourceInfo* pSourceInfo = NULL;
  2509.     IHXGroup*  pGroup = NULL;
  2510.     // track removed from the current group
  2511.     if (uGroupIndex == m_nCurrentGroup &&
  2512.         HXR_OK == GetSourceInfo(uGroupIndex, uTrackIndex, pSourceInfo))
  2513.     {
  2514.         // remove source from the current group
  2515.         m_pSourceMap->RemoveKey(pSourceInfo->m_pSource);
  2516.         pSourceInfo->Remove();
  2517.         HX_DELETE(pSourceInfo);
  2518.         AdjustPresentationTime();
  2519.         m_bSourceMapUpdated = TRUE;
  2520.         m_bForceStatsUpdate = TRUE;
  2521.     }
  2522. #if defined(HELIX_FEATURE_NEXTGROUPMGR)
  2523.     // track removed from the next group being prefetched
  2524.     else if (m_bNextGroupStarted                                                    &&
  2525.              m_pNextGroupManager->GetCurrentGroup(uCurrentGroup, pGroup) == HXR_OK  &&
  2526.              uCurrentGroup == uGroupIndex)
  2527.     {
  2528.         if (HXR_OK == m_pNextGroupManager->GetSource(uTrackIndex, pSourceInfo))
  2529.         {
  2530.             m_pNextGroupManager->RemoveSource(pSourceInfo);
  2531.             pSourceInfo->Remove();
  2532.             HX_DELETE(pSourceInfo);
  2533.         }
  2534.     }
  2535. #endif /* HELIX_FEATURE_NEXTGROUPMGR */
  2536.     return hr;
  2537. #else
  2538.     return HXR_NOTIMPL;
  2539. #endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
  2540. }
  2541. HX_RESULT
  2542. HXPlayer::AddPrefetchTrack(UINT16 uGroupIndex,
  2543.                             UINT16 uPrefetchTrackIndex,
  2544.                             IHXValues* pTrack)
  2545. {
  2546. #if defined(HELIX_FEATURE_PREFETCH)
  2547.     HX_RESULT   theErr = HXR_OK;
  2548.     char        szDelay[] = "Delay";
  2549.     UINT32      ulDelay = 0;
  2550.     IHXGroup*   pGroup = NULL;
  2551.     if (m_pGroupManager)
  2552.     {
  2553.         theErr = m_pGroupManager->GetGroup(uGroupIndex, pGroup);
  2554.     }
  2555.     /* Check if a track is added to the group currently played */
  2556.     if (uGroupIndex == m_nCurrentGroup && pGroup == m_pCurrentGroup)
  2557.     {
  2558.         /* If we are not yet initialized, add tracks to the current source
  2559.          * map only if the track is within the fudge factor.
  2560.          *
  2561.          * This is to fix a bug in SMIL file with multiple sources in seq
  2562.          * with outer par.
  2563.          * The expected behavior is to start the first source
  2564.          * in seq and then initialize the remaining sources. Since we were
  2565.          * adding additional tracks to the source map, the player was not
  2566.          * getting initialized until ALL the sources in the seq have been
  2567.          * initialized. This resulted in massive startup delays.
  2568.          */
  2569.         if (!m_bInitialized)
  2570.         {
  2571.             if ((HXR_OK != pTrack->GetPropertyULONG32(szDelay,ulDelay)) ||
  2572.                 (ulDelay <= m_ulCurrentPlayTime + MIN_DELAYBEFORE_START))
  2573.             {
  2574.                 theErr = OpenTrack(pTrack, uGroupIndex, uPrefetchTrackIndex);
  2575.             }
  2576.             else
  2577.             {
  2578.                 if (!m_pPendingTrackList)
  2579.                 {
  2580.                     m_pPendingTrackList = new CHXSimpleList;
  2581.                 }
  2582.                 PendingTrackInfo* pPendingTrackInfo =
  2583.                     new PendingTrackInfo(uGroupIndex, uPrefetchTrackIndex, pTrack);
  2584.                 m_pPendingTrackList->AddTail(pPendingTrackInfo);
  2585.             }
  2586.         }
  2587.         else
  2588.         {
  2589.             theErr = OpenTrack(pTrack, uGroupIndex, uPrefetchTrackIndex);
  2590.         }
  2591.         if (theErr)
  2592.         {
  2593.             ReportError(NULL, theErr, NULL);
  2594.         }
  2595.     }
  2596.     // we don't support prefetch for the next group
  2597.     else
  2598.     {
  2599.         HX_ASSERT(FALSE);
  2600.     }
  2601.     HX_RELEASE(pGroup);
  2602.     return theErr;
  2603. #else
  2604.     return HXR_NOTIMPL;
  2605. #endif /* HELIX_FEATURE_PREFETCH */
  2606. }
  2607. HX_RESULT
  2608. HXPlayer::UpdatePrefetchTrack(UINT16 uGroupIndex,
  2609.                                UINT16 uPrefetchTrackIndex,
  2610.                                IHXValues* pValues)
  2611. {
  2612. #if defined(HELIX_FEATURE_PREFETCH)
  2613.     HX_RESULT   hr = HXR_OK;
  2614.     UINT16      uCurrentGroup = 0;
  2615.     UINT16      uNewTrackIndex = 0;
  2616.     SourceInfo* pSourceInfo = NULL;
  2617.     IHXGroup*  pGroup = NULL;
  2618.     if (!m_pPrefetchManager)
  2619.     {
  2620.         hr = HXR_FAILED;
  2621.         goto cleanup;
  2622.     }
  2623.     if (HXR_OK == pValues->GetPropertyULONG32("TrackIndex", (UINT32&)uNewTrackIndex))
  2624.     {
  2625.         if (uGroupIndex == m_nCurrentGroup &&
  2626.             HXR_OK == m_pPrefetchManager->GetSource(uNewTrackIndex, pSourceInfo))
  2627.         {
  2628.             HX_ASSERT(pSourceInfo->m_uTrackID == uNewTrackIndex);
  2629.         }
  2630. #if defined(HELIX_FEATURE_NEXTGROUPMGR)
  2631.         else if (m_bNextGroupStarted                                                &&
  2632.                  m_pNextGroupManager->GetCurrentGroup(uCurrentGroup, pGroup) == HXR_OK  &&
  2633.                  uCurrentGroup == uGroupIndex)
  2634.         {
  2635.             hr = HXR_NOTIMPL;
  2636.         }
  2637. #endif /* HELIX_FEATURE_NEXTGROUPMGR */
  2638.     }
  2639. cleanup:
  2640.     return hr;
  2641. #else
  2642.     return HXR_NOTIMPL;
  2643. #endif /* HELIX_FEATURE_PREFETCH */
  2644. }
  2645. HX_RESULT
  2646. HXPlayer::RemovePrefetchTrack(UINT16 uGroupIndex,
  2647.                                UINT16 uPrefetchTrackIndex,
  2648.                                IHXValues* pValues)
  2649. {
  2650. #if defined(HELIX_FEATURE_PREFETCH)
  2651.     HX_RESULT   theErr = HXR_OK;
  2652.     SourceInfo* pSourceInfo = NULL;
  2653.     if (m_pPrefetchManager &&
  2654.         m_pPrefetchManager->Lookup(pValues, pSourceInfo))
  2655.     {
  2656.         theErr = m_pPrefetchManager->RemoveSource(pSourceInfo);
  2657.         // cleanup if the prefetch track has not been activated
  2658.         if (pSourceInfo->m_pSource->IsPartOfPrefetchGroup())
  2659.         {
  2660.             pSourceInfo->Remove();
  2661.             HX_DELETE(pSourceInfo);
  2662.         }
  2663.     }
  2664.     return theErr;
  2665. #else
  2666.     return HXR_NOTIMPL;
  2667. #endif /* HELIX_FEATURE_PREFETCH */
  2668. }
  2669. HX_RESULT
  2670. HXPlayer::PrefetchTrackDone(UINT16 uGroupIndex, UINT16 uPrefetchTrackIndex, HX_RESULT status)
  2671. {
  2672. #if defined(HELIX_FEATURE_PREFETCH)
  2673.     IHXGroup*           pGroup = NULL;
  2674.     IHXPrefetchSink*   pPrefetchSink = NULL;
  2675.     if (m_pGroupManager && HXR_OK == m_pGroupManager->GetGroup(uGroupIndex, pGroup))
  2676.     {
  2677.         if (HXR_OK == pGroup->QueryInterface(IID_IHXPrefetchSink, (void**)&pPrefetchSink))
  2678.         {
  2679.             pPrefetchSink->PrefetchTrackDone(uGroupIndex, uPrefetchTrackIndex, status);
  2680.         }
  2681.         HX_RELEASE(pPrefetchSink);
  2682.     }
  2683.     HX_RELEASE(pGroup);
  2684. #endif /* HELIX_FEATURE_PREFETCH */
  2685.     return HXR_OK;
  2686. }
  2687. HX_RESULT
  2688. HXPlayer::BeginTrack(UINT16 uGroupIndex, UINT16 uTrackIndex, IHXValues* pValues)
  2689. {
  2690. #if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
  2691.     HX_RESULT   hr = HXR_OK;
  2692.     SourceInfo* pSourceInfo = NULL;
  2693.     // begin on the current group only
  2694.     if (uGroupIndex == m_nCurrentGroup &&
  2695.         HXR_OK == GetSourceInfo(uGroupIndex, uTrackIndex, pSourceInfo))
  2696.     {
  2697.         hr = pSourceInfo->BeginTrack();
  2698.     }
  2699.     else
  2700.     {
  2701.         hr = HXR_UNEXPECTED;
  2702.     }
  2703.     return hr;
  2704. #else
  2705.     return HXR_NOTIMPL;
  2706. #endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
  2707. }
  2708. HX_RESULT
  2709. HXPlayer::PauseTrack(UINT16 uGroupIndex, UINT16 uTrackIndex, IHXValues* pValues)
  2710. {
  2711. #if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
  2712.     HX_RESULT   hr = HXR_OK;
  2713.     SourceInfo* pSourceInfo = NULL;
  2714.     // pause on the current group only
  2715.     if (uGroupIndex == m_nCurrentGroup &&
  2716.         HXR_OK == GetSourceInfo(uGroupIndex, uTrackIndex, pSourceInfo))
  2717.     {
  2718.         hr = pSourceInfo->PauseTrack();
  2719.     }
  2720.     else
  2721.     {
  2722.         hr = HXR_UNEXPECTED;
  2723.     }
  2724.     return hr;
  2725. #else
  2726.     return HXR_NOTIMPL;
  2727. #endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
  2728. }
  2729. HX_RESULT
  2730. HXPlayer::SeekTrack(UINT16 uGroupIndex, UINT16 uTrackIndex, IHXValues* pValues, UINT32 ulSeekTime)
  2731. {
  2732. #if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
  2733.     HX_RESULT   hr = HXR_OK;
  2734.     SourceInfo* pSourceInfo = NULL;
  2735.     // seek on the current group only
  2736.     if (uGroupIndex == m_nCurrentGroup &&
  2737.         HXR_OK == GetSourceInfo(uGroupIndex, uTrackIndex, pSourceInfo))
  2738.     {
  2739.         hr = pSourceInfo->SeekTrack(ulSeekTime);
  2740.     }
  2741.     else
  2742.     {
  2743.         hr = HXR_UNEXPECTED;
  2744.     }
  2745.     return hr;
  2746. #else
  2747.     return HXR_NOTIMPL;
  2748. #endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
  2749. }
  2750. HX_RESULT
  2751. HXPlayer::StopTrack(UINT16 uGroupIndex, UINT16 uTrackIndex, IHXValues* pValues)
  2752. {
  2753. #if defined(HELIX_FEATURE_ADVANCEDGROUPMGR)
  2754.     HX_RESULT   hr = HXR_OK;
  2755.     SourceInfo* pSourceInfo = NULL;
  2756.     // stop on the current group only
  2757.     if (uGroupIndex == m_nCurrentGroup &&
  2758.         HXR_OK == GetSourceInfo(uGroupIndex, uTrackIndex, pSourceInfo))
  2759.     {
  2760.         hr = pSourceInfo->StopTrack();
  2761.     }
  2762.     else
  2763.     {
  2764.         hr = HXR_UNEXPECTED;
  2765.     }
  2766.     return hr;
  2767. #else
  2768.     return HXR_NOTIMPL;
  2769. #endif /* HELIX_FEATURE_ADVANCEDGROUPMGR */
  2770. }
  2771. HX_RESULT
  2772. HXPlayer::SetSoundLevel(UINT16 uGroupIndex, UINT16 uTrackIndex, UINT16 uSoundLevel, BOOL bReflushAudioDevice)
  2773. {
  2774.     HX_RESULT   hr = HXR_OK;
  2775.     SourceInfo* pSourceInfo = NULL;
  2776.     // set on the current group only