📄 hxflsrc.cpp
字号:
if (m_pRecordControl && m_pRecordControl->Seek(seekTime) == HXR_OK && m_bPlayFromRecordControl) { m_pBufferManager->DoSeek(seekTime, TRUE); SeekDone(HXR_OK); } else#endif /* HELIX_FEATURE_RECORDCONTROL */ { m_bSourceEnd = FALSE; m_pBufferManager->DoSeek(seekTime, FALSE); if (HXR_OK != m_pFFObject->Seek(seekTime)) { if (m_nSeeking) { m_nSeeking--; } } } m_llLastFillEndTime = 0; cleanup: return HXR_OK;} HX_RESULT HXFileSource::DoPause(void){ if (m_bPaused) { return HXR_OK; } /* Only if it is an external pause */ if (!m_bSourceEnd && !m_bDelayed && m_pBufferManager) { m_pBufferManager->DoPause(); } m_bPaused = TRUE; return HXR_OK;}HX_RESULT HXFileSource::StartInitialization(void){ m_bFastStartInProgress = TRUE; m_pBufferManager->DoResume(); if (m_pSourceInfo) { m_pSourceInfo->Resumed(); } return HXR_OK;}HX_RESULT HXFileSource::DoResume(void){ HX_RESULT theErr = HXR_OK; m_bFastStartInProgress = FALSE; /* This may happen if a new source is added from SMIL renderer during * initialization of exisitng sources. We will eventually call Resume * on this source once it is initialized in SourceInfo::ProcessIdle */ if (!m_bInitialized || (m_pSourceInfo && !m_pSourceInfo->IsInitialized())) { return HXR_OK; } if (m_bSourceEnd || CanBeResumed()) { m_bResumePending = FALSE; if (!m_bSourceEnd) { m_pBufferManager->DoResume(); } // resume the audio streams if the source is added // while the player is in play mode // CAUTION: this will cause rewind in audio service if (m_bFirstResume && m_pPlayer->IsPlaying() && m_ulDelay <= m_pPlayer->GetInternalCurrentPlayTime()) { ResumeAudioStreams(); } m_bFirstResume = FALSE; m_bPaused = FALSE; if (m_pSourceInfo) { m_pSourceInfo->Resumed(); } if (!m_bSourceEnd) { theErr = FillBuffers(); } } if (!theErr && !m_bIsActive && !m_bDelayed && m_pPlayer->GetInternalCurrentPlayTime() >= m_ulDelay) { AdjustClipBandwidthStats(TRUE); } if (theErr == HXR_AT_END) { SetEndOfClip(); theErr = HXR_OK; } return theErr;}/************************************************************************ * Method: * IHXPendingStatus::GetStatus * Purpose: * Called by the user to get the current pending status from an object */STDMETHODIMPHXFileSource::GetStatus( REF(UINT16) uStatusCode, REF(IHXBuffer*) pStatusDesc, REF(UINT16) ulPercentDone){ HX_RESULT hResult = HXR_OK; IHXPendingStatus* pStatus = NULL; UINT16 buffer = 100; UINT16 statusCode = HX_STATUS_READY; UINT16 percentDone = 0; uStatusCode = HX_STATUS_READY; pStatusDesc = 0; ulPercentDone = 0; if (m_bDelayed) { return HXR_OK; } if (m_bSourceEnd) { if (!IsRebufferDone()) { uStatusCode = HX_STATUS_BUFFERING; ulPercentDone = 99; } else { if (m_bInitialBuffering) { InitialBufferingDone(); } m_ulLastBufferingReturned = 100; uStatusCode = HX_STATUS_READY; } return HXR_OK; } if (m_bInitialized) { if (m_bFirstResume) { uStatusCode = HX_STATUS_INITIALIZING; return HXR_OK; } m_pBufferManager->GetStatus(uStatusCode, pStatusDesc, ulPercentDone); buffer = ulPercentDone; /* We only aggregate buffering from a lower level if we are in a buffering mode. * Reason: Once the initial bufering is done, we go in buffering more ONLY IF the * renderer tells us that it is in a panic state and we run out of packets. */ if (buffer == 100 && !m_bInitialBuffering) { // Rebuffer requested by the Renderer might not be // done yet if (!IsRebufferDone()) { uStatusCode = HX_STATUS_BUFFERING; ulPercentDone = 99; } else { uStatusCode = HX_STATUS_READY; } return HXR_OK; } } if (m_pFFObject) { if (HXR_OK != m_pFFObject->QueryInterface(IID_IHXPendingStatus, (void**)&pStatus)) { goto exit; } if (HXR_OK != pStatus->GetStatus(statusCode, pStatusDesc, percentDone)) { goto exit; } } else if (m_pFileObject) { if (HXR_OK != m_pFileObject->QueryInterface(IID_IHXPendingStatus, (void**)&pStatus)) { goto exit; } if (HXR_OK != pStatus->GetStatus(statusCode, pStatusDesc, percentDone)) { goto exit; } }exit: if (HX_STATUS_CONTACTING == statusCode) { uStatusCode = HX_STATUS_CONTACTING; ulPercentDone = 0; } else if (!m_bInitialized) { uStatusCode = HX_STATUS_INITIALIZING; ulPercentDone = 0; } else if (HX_STATUS_READY == statusCode && 100 == buffer) { uStatusCode = HX_STATUS_READY; ulPercentDone = 0; m_ulLastBufferingReturned = 100; } else { uStatusCode = HX_STATUS_BUFFERING; if (HX_STATUS_READY == statusCode) { ulPercentDone = (UINT16)buffer; } else { ulPercentDone = (UINT16)((buffer + percentDone) * 0.5); } // Do not go back if (ulPercentDone < m_ulLastBufferingReturned && m_ulLastBufferingReturned != 100) { ulPercentDone = (UINT16) m_ulLastBufferingReturned; } else { m_ulLastBufferingReturned = ulPercentDone; } } HX_RELEASE(pStatus); ulPercentDone = ulPercentDone <= 100 ? (UINT16)ulPercentDone : 100; if (m_bInitialBuffering && HX_STATUS_READY == uStatusCode) { InitialBufferingDone(); } /* If we had a delayed start, we do not want to show that we are * in buffering state UNLESS it is really time to give out packets * and we do not have */ if (m_bInitialized && m_ulDelay > 0 && uStatusCode == HX_STATUS_BUFFERING && ulPercentDone < 100) { UINT32 ulCurrentTime = m_pPlayer->GetInternalCurrentPlayTime(); if ((ulCurrentTime + MIN_BUFFERTIME_BEFORE_DELAY) < m_ulDelay) { ulPercentDone = 100; } } return hResult;}UINT16 HXFileSource::GetNumStreams(void){ HX_ASSERT(m_bInitialized); return m_uNumStreams;}HX_RESULT HXFileSource::GetStreamInfo(ULONG32 ulStreamNumber, STREAM_INFO*& theStreamInfo){ HX_RESULT theErr = HXR_OK; STREAM_INFO* lpStreamInfo = 0; if (!mStreamInfoTable->Lookup((LONG32)ulStreamNumber, (void *&)lpStreamInfo)) { theErr = HXR_INVALID_PARAMETER; } theStreamInfo = lpStreamInfo; return theErr;}HX_RESULT HXFileSource::GetEvent(UINT16 usStreamNumber, CHXEvent*& theEvent){ HX_RESULT theErr = HXR_OK; HX_TRACE("HXFileSource::GetEvent"); theEvent = 0; if (!m_bInitialized) { return HXR_NOT_INITIALIZED; } if (mLastError != HXR_OK) { return mLastError; } if (m_bPaused && m_bDelayed) { if (TryResume()) { m_pPlayer->RegisterSourcesDone(); DoResume(); } else { return HXR_NO_DATA; } } STREAM_INFO * lpStreamInfo; if (!mStreamInfoTable->Lookup((LONG32) usStreamNumber, (void *&) lpStreamInfo)) { theErr = HXR_INVALID_PARAMETER; return theErr; }#if defined(HELIX_FEATURE_RECORDCONTROL) if (m_bPlayFromRecordControl && m_pRecordControl) { IHXPacket* pPacket = NULL; HX_ASSERT(m_pRecordControl); theErr = m_pRecordControl->GetPacket(usStreamNumber, pPacket); if(theErr == HXR_OK) { UINT32 streamPreRoll = max(lpStreamInfo->BufferingState().GetMinPrerollInMs(),1000); INT64 llPacketTime = lpStreamInfo->BufferingState().CreateINT64Timestamp(pPacket->GetTime()); theEvent = new CHXEvent(pPacket, GetEventBeginTime(llPacketTime, streamPreRoll)); if(theEvent) theEvent->SetTimeOffset(m_ulStartTime - m_ulDelay); else theErr = HXR_OUTOFMEMORY; if(m_pBufferManager) m_pBufferManager->UpdateCounters(pPacket); HX_RELEASE(pPacket); } else { if(theErr == HXR_NO_DATA && (m_bSourceEnd || lpStreamInfo->m_bSrcStreamDone)) theErr = HXR_AT_END; if(theErr == HXR_NO_DATA) { if (lpStreamInfo->m_unNeeded > 0 && lpStreamInfo->m_unNeeded != lpStreamInfo->m_unAvailable) { // Re-initialize buffering m_pBufferManager->ReBuffer(); FillBuffers(); theErr = HXR_BUFFERING; } } } return theErr; }#endif /* HELIX_FEATURE_RECORDCONTROL */ // get the packet list for this stream CHXEventList * lEventList = &lpStreamInfo->m_EventList; // do we need to fill buffers... if (lEventList->GetNumEvents() == 0) { theErr = FillBuffers(); if (theErr == HXR_AT_END) { SetEndOfClip(); theErr = HXR_OK; } // check if we have packets now... if (!theErr && lEventList->GetNumEvents() == 0) { if (m_bSourceEnd || lpStreamInfo->m_bSrcStreamDone) { return HXR_AT_END; } else { if (lpStreamInfo->m_unNeeded > 0 && lpStreamInfo->m_unNeeded != lpStreamInfo->m_unAvailable) { // Re-initialize buffering m_pBufferManager->ReBuffer(); FillBuffers(); return HXR_BUFFERING; } return HXR_NO_DATA; } } } if (!theErr) { // this event will be deleted by the player... theEvent = lEventList->RemoveHead(); }#ifdef LOSS_HACK if (m_ulLossHack > 0 && ((UINT32) (rand() % 100) < m_ulLossHack) && !theErr && theEvent && !(theEvent->GetPacket())->IsLost()) { GenerateFakeLostPacket(theEvent); /* Update the stats */ if (lpStreamInfo->m_ulReceived > 0) { lpStreamInfo->m_ulReceived--; lpStreamInfo->m_ulLost++; } }#endif /* LOSS_HACK */ return theErr;}void HXFileSource::ReBuffer(){ UINT32 ulRemainToBufferInMs = 0; UINT32 ulRemainToBuffer = 0; m_pBufferManager->GetRemainToBuffer(ulRemainToBufferInMs, ulRemainToBuffer); if ( ulRemainToBufferInMs == 0 && ulRemainToBuffer == 0 ) { m_pBufferManager->ReBuffer(); FillBuffers(); }}BOOL HXFileSource::IsStatisticsReady(void){ return HXR_OK;}HX_RESULT HXFileSource::UpdateRegistry(UINT32 ulRegistryID){ HX_RESULT theErr = HXR_OK;#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY) UINT32 ulRegId = 0; char szRegName[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */ IHXBuffer* pParentName = NULL; STREAM_INFO* pStreamInfo = NULL; CHXMapLongToObj::Iterator ndxStream; m_ulRegistryID = ulRegistryID; if (!m_pStats) { SetupRegistry(); } else { if (m_pSourceInfo && m_pSourceInfo->m_bLeadingSource &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -