📄 hxplay.cpp
字号:
{ SchedulePlayer(); return HXR_OK; } m_pCoreMutex->Lock();#if 0#if defined(_WIN32) && defined(_DEBUG) GetChangesToWorkingSet();#endif#endif m_bCoreLocked = TRUE; HX_RESULT theErr = HXR_OK; BOOL bIsBuffering = FALSE; UINT16 uLowestBuffering = 100; SourceInfo* pSourceInfo = NULL; RendererInfo* pRendInfo = NULL; IHXRenderer* pRenderer = NULL; BOOL bDone = FALSE; BOOL bIsFirst = TRUE; BOOL bReadyToUpgrade = TRUE; BOOL bSuppressErrorReporting = FALSE; UINT32 ulNumStreamsToBeFilled = 0; UINT32 ulLoopEntryTime = 0; UINT16 unStatusCode = 0; UINT16 unPercentDone = 0; IHXBuffer* pStatusDesc = NULL; CHXMapPtrToPtr::Iterator ndxSource; CHXMapLongToObj::Iterator ndxRend; if (m_bIsDone || m_bSetupToBeDone) { goto exitRoutine; }#ifdef _MACINTOSH /* check InternalPause() for details */ if (m_bPendingAudioPause && !m_pEngine->AtInterruptTime()) { m_pAudioPlayer->Pause(); }#endif ndxSource = m_pSourceMap->Begin(); for (;!theErr && ndxSource != m_pSourceMap->End(); ++ndxSource) { pSourceInfo = (SourceInfo*)(*ndxSource); /* Do not call Process source at interrupt time unless * it is initialized. */ if (pSourceInfo->m_pSource && (pSourceInfo->m_pSource->IsInitialized() || !m_pEngine->AtInterruptTime())) { // XXX HP may need to rework if (!pSourceInfo->m_bDone) { theErr = pSourceInfo->m_pSource->ProcessIdle(); if( theErr == HXR_OUTOFMEMORY ) { goto exitRoutine; } } theErr = SpawnSourceIfNeeded(pSourceInfo); if( theErr == HXR_OUTOFMEMORY ) { goto exitRoutine; } else { theErr = HXR_OK; // filter out HXR_NOTIMPL } } if (pSourceInfo->m_pPeerSourceInfo && pSourceInfo->m_pPeerSourceInfo->m_pSource && !pSourceInfo->m_pPeerSourceInfo->m_bDone && (pSourceInfo->m_pPeerSourceInfo->m_pSource->IsInitialized() || !m_pEngine->AtInterruptTime())) { theErr = pSourceInfo->m_pPeerSourceInfo->m_pSource->ProcessIdle(); if( theErr == HXR_OUTOFMEMORY ) { goto exitRoutine; } } }#if defined(HELIX_FEATURE_PREFETCH) if (m_pPrefetchManager && m_pPrefetchManager->GetNumSources() > 0) { m_pPrefetchManager->ProcessIdle(); }#endif /* HELIX_FEATURE_PREFETCH */#if defined(HELIX_FEATURE_NEXTGROUPMGR) if (m_pNextGroupManager->GetNumSources() > 0) { m_pNextGroupManager->ProcessIdle(); }#endif /* HELIX_FEATURE_NEXTGROUPMGR */ // check the status first if (!m_bContactingDone && HXR_OK == GetStatus(unStatusCode, pStatusDesc, unPercentDone)) { if (HX_STATUS_CONTACTING == unStatusCode && pStatusDesc && m_pAdviseSink) { m_pAdviseSink->OnContacting((const char*)pStatusDesc->GetBuffer()); } else if (HX_STATUS_INITIALIZING != unStatusCode) { m_bContactingDone = TRUE; } HX_RELEASE(pStatusDesc); } // initialize renderes if not done yet.. // this involves reading headers from source object // creating the right renderers for each stream and pass this // header to the renderer. if (!m_bInitialized) { /* A temporary hack till we change SMIL fileformat * to send Layout info in Header */ BOOL bIsSmilRenderer = m_bSetupLayoutSiteGroup; theErr = InitializeRenderers();#if defined(HELIX_FEATURE_VIDEO) if (!theErr && m_bInitialized && !m_bPlayerWithoutSources) { SetupLayout(/*!m_bSetupLayoutSiteGroup*/ FALSE); if (bIsSmilRenderer == m_bSetupLayoutSiteGroup && m_pSiteSupplier && !m_bBeginChangeLayoutTobeCalled) { m_bBeginChangeLayoutTobeCalled = TRUE; m_pSiteSupplier->DoneChangeLayout(); } }#endif /* HELIX_FEATURE_VIDEO */ if (!theErr && m_bInitialized) { AdjustPresentationTime(); m_bSetupToBeDone = TRUE; theErr = SetupAudioPlayer(); } } if (m_bPostSetupToBeDone) { m_bPostSetupToBeDone = FALSE; /* Initialize audio services */ if (!theErr && m_bInitialized) { m_bIsPresentationClosedToBeSent = TRUE; if (m_pAdviseSink) { m_pAdviseSink->OnPresentationOpened(); } } if (!theErr && m_bInitialized) { m_ulMinimumAudioPreroll = m_pAudioPlayer->GetInitialPushdown(); SetMinimumPushdown(); } if (!theErr && m_bInitialized && !m_bIsFirstBegin) { CheckSourceRegistration(); ndxSource = m_pSourceMap->Begin(); for (; !theErr && ndxSource != m_pSourceMap->End(); ++ndxSource) { SourceInfo* pSourceInfo = (SourceInfo*) (*ndxSource); HXSource* pSource = pSourceInfo->m_pSource; if (pSource) { theErr = pSource->DoResume(); } else { /* pSource should never be NULL */ HX_ASSERT(FALSE); } } } /* Start Downloading even if we have not been issued a * Begin() command */ if (!theErr && m_bInitialized && m_bIsFirstBegin && !m_bIsDone) { theErr = StartDownload(); } } // if it is still not initialized check error code and return if (theErr || !m_bInitialized) { // my first use of goto..!! goto exitRoutine; } /* try to fill up packets from the various source objects for * different streams so that all of them are upto their preroll * mark... */ UpdateCurrentPlayTime( m_pAudioPlayer->GetCurrentPlayBackTime() ); if (!m_ToBeginRendererList.IsEmpty()) { CheckBeginList(); } while (!theErr && !bDone && m_uNumSourcesActive > 0) { ndxSource = m_pSourceMap->Begin(); for (;!theErr && ndxSource != m_pSourceMap->End(); ++ndxSource) { pSourceInfo = (SourceInfo*)(*ndxSource); theErr = pSourceInfo->ProcessIdle(bIsFirst, ulNumStreamsToBeFilled, bIsBuffering, uLowestBuffering); if (pSourceInfo->m_pPeerSourceInfo) { BOOL tmp_bIsFirst = TRUE; BOOL tmp_bIsBuffering = FALSE; UINT32 tmp_ulNumStreamsToBeFilled = 0; UINT16 tmp_uLowestBuffering = 100; pSourceInfo->m_pPeerSourceInfo->ProcessIdle(tmp_bIsFirst, tmp_ulNumStreamsToBeFilled, tmp_bIsBuffering, tmp_uLowestBuffering); } /* Someone added a source during ProcessIdle. * Start all over again */ if (m_bSourceMapUpdated) { break; } } if (bIsBuffering && !m_bIsPlaying) { if (!ulLoopEntryTime) { ulLoopEntryTime = HX_GET_TICKCOUNT(); } ndxSource = m_pSourceMap->Begin(); for (;!theErr && ndxSource != m_pSourceMap->End(); ++ndxSource) { pSourceInfo = (SourceInfo*)(*ndxSource); ndxRend = pSourceInfo->m_pRendererMap->Begin(); for (;!theErr && ndxRend != pSourceInfo->m_pRendererMap->End(); ++ndxRend) { pRendInfo = (RendererInfo*)(*ndxRend); pRenderer = pRendInfo->m_pRenderer; if((pRendInfo->m_bInterruptSafe || !m_pEngine->AtInterruptTime()) && pRenderer) { pRenderer->OnBuffering(m_BufferingReason, uLowestBuffering); } } } m_b100BufferingToBeSent = TRUE; if (m_pAdviseSink) { m_pAdviseSink->OnBuffering(m_BufferingReason, uLowestBuffering); } // free some CPU time if we stuck in this WHILE loop too long if (!theErr && CALCULATE_ELAPSED_TICKS(ulLoopEntryTime, HX_GET_TICKCOUNT()) >= MAX_LOOP_EXE_TIME) { break; } if (!theErr) { theErr = ProcessCurrentEvents(); } } if (theErr || m_bSourceMapUpdated) { m_bSourceMapUpdated = FALSE; goto exitRoutine; } bIsFirst = FALSE; if (ulNumStreamsToBeFilled == 0) { bDone = TRUE; } } // SPECIAL CASE: // the player received all the packets(m_uNumSourcesActive is 0) and // EndOfPacket() hasn't been sent to the renderer yet, // BUT the renderer still calls ReportRebufferStatus() // we need to make sure the rebuffering is done before calling resume. if (m_uNumSourcesActive == 0) { ndxSource = m_pSourceMap->Begin(); for (;!theErr && ndxSource != m_pSourceMap->End(); ++ndxSource) { pSourceInfo = (SourceInfo*)(*ndxSource); if (!pSourceInfo->IsRebufferDone()) { bIsBuffering = TRUE; break; } } } /* Stop Downloading if we have not been issued a * Begin() command and we are done with Buffering. */ if (!theErr && !bIsBuffering && m_bFastStartInProgress && !m_bIsDone) { theErr = PauseDownload(); } // Process Current Events Due... if (!theErr) { theErr = ProcessCurrentEvents(); } // repeat source specific SwitchSourceIfNeeded(); if (!theErr && !bIsBuffering && (!m_bResumeOnlyAtSystemTime || !m_pEngine->AtInterruptTime())) { theErr = CheckForAudioResume(); } if (!theErr && !m_bLastGroup && !m_bNextGroupStarted && !m_pEngine->AtInterruptTime()) { CheckToStartNextGroup(); } /* Check if live stream has ended */ if (!theErr && m_bInitialized && !m_bPlayerWithoutSources && ((!m_bIsLive && (!m_ulPresentationDuration || (m_ulPresentationDuration < m_ulCurrentPlayTime))) || (m_bIsLive && AreAllPacketsSent())) && m_uNumSourcesActive == 0) { /* If there are any sources that MUST be initialized before playback * begins/stops, we should not end the presentation here. Instead, wait for * the stream headers to come down... */ if ((m_uNumSourceToBeInitializedBeforeBegin > 0) && m_ulPresentationDuration) { InternalPause(); } else if (!m_ulPresentationDuration || (m_ulPresentationDuration < m_ulCurrentPlayTime)) { if (ScheduleOnTimeSync()) { // schedule a system callback to ensure // the renderers receive OnTimeSync() on its duration // AND the clip ends ASAP RemovePendingCallback(m_pHXPlayerCallback); m_pHXPlayerCallback->CallbackScheduled( m_pScheduler->RelativeEnter(m_pHXPlayerCallback, 0)); goto cleanup; } else { m_bIsDone = TRUE; m_pAudioPlayer->DonePlayback(); /* This assert is to find bugs in fileformats which place invalid ts * (ts > m_ulPresentationDuration) on the packets. */ HX_ASSERT(AreAllPacketsSent() == TRUE); } } }exitRoutine:#if defined(HELIX_FEATURE_AUTOUPGRADE) if(m_pUpgradeCollection && m_pUpgradeCollection->GetCount() > 0 && !m_pEngine->AtInterruptTime()) { // Request an upgrade IHXUpgradeHandler* pUpgradeHandler = NULL; if(m_pClient) m_pClient->QueryInterface(IID_IHXUpgradeHandler, (void**)&pUpgradeHandler); if(!pUpgradeHandler) { // In case of clients with no IHXUpgradeHandler support // just remove all the upgrade collectopn components m_pUpgradeCollection->RemoveAll(); theErr = HXR_MISSING_COMPONENTS; } else { // see if we should send an upgrade request only if all the sour
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -