📄 buffmgr.cpp
字号:
if (!pPacket) { return HXR_INVALID_PARAMETER; } if (pPacket->IsLost() && !(pPacket->GetASMFlags() & HX_ASM_DROPPED_PKT)) { // Ignore all lost packets that aren't dropped packets return hr; } ulStreamNum = pPacket->GetStreamNumber(); if (!m_pStreamInfoTable->Lookup(ulStreamNum, (void*&)pStreamInfo)) { return HXR_INVALID_PARAMETER; } pThisStreamInfo = pStreamInfo; pBuffer = pPacket->GetBuffer(); if (pBuffer) { ulBufferSize = pBuffer->GetSize(); } HX_RELEASE(pBuffer); ulBufferTime = pPacket->GetTime(); /* Set Buffering start time for all streams */ if (m_bBufferStartTimeToBeSet) { m_bBufferStartTimeToBeSet = FALSE; m_ulBufferingStartTime = ulCurrentTime; } ulElapsedTime = GetElapsedTime(ulCurrentTime); BOOL bIsBufferedPlayMode = (m_bPerfectPlay || m_bBufferedPlay || (m_bLocalPlayback && !m_pParent->IsLive())); pStreamInfo->BufferingState().OnPacket(ulBufferTime, ulBufferSize, ulElapsedTime, m_pParent->IsLive(), bIsBufferedPlayMode); llActualTimeStamp = pStreamInfo->BufferingState().CreateINT64Timestamp(ulBufferTime); // time based preroll by default UpdateHighestTimestamps(llActualTimeStamp, pStreamInfo); INT64 llLowRefTS = pThisStreamInfo->BufferingState().LowTS(); // adjust each stream preroll based on the hightest time stamp for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i) { pStreamInfo = (STREAM_INFO*) (*i); BOOL bIsTimestampDelivery = FALSE; if (pStreamInfo->m_pStream && pStreamInfo->m_pStream->IsTimeStampDelivery()) { bIsTimestampDelivery = TRUE; } pStreamInfo->BufferingState().UpdateBufferingInMs(llLowRefTS, m_llHighestTimeStamp, bIsBufferedPlayMode, bIsTimestampDelivery, ulElapsedTime); } return hr;}HX_RESULTCBufferManager::GetStatus(REF(UINT16) uStatusCode, REF(IHXBuffer*) pStatusDesc, REF(UINT16) uPercentDone){ STREAM_INFO* pStreamInfo = NULL; CHXMapLongToObj::Iterator i; uStatusCode = HX_STATUS_READY; pStatusDesc = NULL; uPercentDone = 0; // collect from each streams for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i) { pStreamInfo = (STREAM_INFO*) (*i); uPercentDone += pStreamInfo->BufferingState().GetPercentDone(m_bIsSeekPerformed); } // average them uPercentDone = uPercentDone / m_pStreamInfoTable->GetCount(); if (uPercentDone >= 100) { uPercentDone = 100; m_state = BUFFMGR_READY; } else { uStatusCode = HX_STATUS_BUFFERING; }// DEBUG_OUT(m_pParent->m_pPlayer, DOL_GENERIC, (s,// "BuffMgr::GetStatus: %p Status: %s uPercentDone: %lu ", this, // (uStatusCode == HX_STATUS_BUFFERING ? "HX_STATUS_BUFFERING" : "HX_STATUS_READY" ),// uPercentDone)); return HXR_OK;}HX_RESULTCBufferManager::GetRemainToBuffer(REF(UINT32) ulRemainToBufferInMs, REF(UINT32) ulRemainToBuffer){ STREAM_INFO* pStreamInfo = NULL; ulRemainToBufferInMs = 0; ulRemainToBuffer = 0; CHXMapLongToObj::Iterator i; // caculate each stream for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i) { pStreamInfo = (STREAM_INFO*) (*i); BOOL bHasPreroll = pStreamInfo->BufferingState().HasPreroll(m_bIsSeekPerformed); BOOL bHasPredata = pStreamInfo->BufferingState().HasPredata(m_bIsSeekPerformed); UINT32 ulRemainInMs; UINT32 ulRemain; pStreamInfo->BufferingState().GetRemainToBuffer(ulRemainInMs, ulRemain); // satisfy the preroll (by default + pre-set) if ((!bHasPredata || bHasPreroll) && (ulRemainToBufferInMs < ulRemainInMs)) { ulRemainToBufferInMs = ulRemainInMs; } // satisfy the predata if (bHasPredata) { ulRemainToBuffer += ulRemain; } } return HXR_OK;}HX_RESULT CBufferManager::GetMaximumPreroll(REF(UINT32) ulMaximumPrerollInMs){ STREAM_INFO* pStreamInfo = NULL; CHXMapLongToObj::Iterator i; ulMaximumPrerollInMs = 0; // get max. preroll among the streams for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i) { pStreamInfo = (STREAM_INFO*) (*i); UINT32 ulMinPrerollInMs = pStreamInfo->BufferingState().GetMinPrerollInMs(); if (ulMaximumPrerollInMs < ulMinPrerollInMs) { ulMaximumPrerollInMs = ulMinPrerollInMs; } } return HXR_OK;}HX_RESULTCBufferManager::GetExcessBufferInfo(REF(UINT32) ulRemainToBufferInMs, REF(UINT32) ulRemainToBuffer, REF(UINT32) ulExcessBufferInMs, REF(UINT32) ulExcessBuffer, REF(BOOL) bValidInfo, REF(UINT32) ulActualExcessBufferInMs, REF(UINT32) ulActualExcessBuffer){ STREAM_INFO* pStreamInfo = NULL; INT64 llTheLowestTS = 0; INT64 llTheHighestTS = 0; BOOL bIsFirst = TRUE; STREAM_INFO* pNonEmptyStreamInfo = NULL; ulRemainToBufferInMs = 0; ulRemainToBuffer = 0; ulExcessBufferInMs = 0; ulExcessBuffer = 0; bValidInfo = FALSE; ulActualExcessBufferInMs= 0; ulActualExcessBuffer = 0; CHXMapLongToObj::Iterator i; /* * - Update transport stats for each stream. * - Find the lowest and highest timestamps across all streams * - Keep track of the stream with the lowest timestamp and is * buffering data */ for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i) { pStreamInfo = (STREAM_INFO*) (*i); INT64 llLowestTimestampAtTransport = 0; INT64 llHighestTimestampAtTransport = 0; ULONG32 ulNumBytesAtTransport = 0; BOOL bDoneAtTransport = FALSE; m_pParent->GetCurrentBuffering(pStreamInfo->m_uStreamNumber, llLowestTimestampAtTransport, llHighestTimestampAtTransport, ulNumBytesAtTransport, bDoneAtTransport); pStreamInfo->BufferingState().UpdateTransportStats( llLowestTimestampAtTransport, llHighestTimestampAtTransport, ulNumBytesAtTransport, bDoneAtTransport); if (ulNumBytesAtTransport > 0) { if (bIsFirst) { bIsFirst = FALSE; llTheLowestTS = llLowestTimestampAtTransport; llTheHighestTS = llHighestTimestampAtTransport; pNonEmptyStreamInfo = pStreamInfo; } else { if (llTheLowestTS > llLowestTimestampAtTransport) { llTheLowestTS = llLowestTimestampAtTransport; /* This is the stream with the lowest timestamp */ pNonEmptyStreamInfo = pStreamInfo; } if (llTheHighestTS < llHighestTimestampAtTransport) { llTheHighestTS = llHighestTimestampAtTransport; } } } } /* If none of the streams have any data buffered at the transport layer, * return. */ if (!pNonEmptyStreamInfo) { return HXR_OK; } for (i = m_pStreamInfoTable->Begin(); i != m_pStreamInfoTable->End(); ++i) { pStreamInfo = (STREAM_INFO*) (*i); UINT32 ulExcessForThisStreamInMs = 0; UINT32 ulExcessForThisStream = 0; pStreamInfo->BufferingState().GetExcessBufferInfo(llTheLowestTS, llTheHighestTS, m_bIsSeekPerformed, ulRemainToBufferInMs, ulRemainToBuffer, ulExcessBufferInMs, ulExcessBuffer, ulExcessForThisStreamInMs, ulExcessForThisStream); /* Update Actual Values Regardless of Preroll / PreData */ ulActualExcessBuffer += ulExcessForThisStream; if (ulActualExcessBufferInMs < ulExcessForThisStreamInMs) { ulActualExcessBufferInMs = ulExcessForThisStreamInMs; } } bValidInfo = TRUE; if (ulRemainToBufferInMs >= ulExcessBufferInMs) { ulRemainToBufferInMs -= ulExcessBufferInMs; ulExcessBufferInMs = 0; } else { ulExcessBufferInMs -= ulRemainToBufferInMs; ulRemainToBufferInMs = 0; } if (ulRemainToBuffer > 0) { ulExcessBuffer = 0; } return HXR_OK;}void CBufferManager::EnterBufferedPlay(void){#if !defined(HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES) if (!m_bBufferedPlay && !m_bPerfectPlay) { m_bBufferedPlay = TRUE; UINT32 ulRemainToBufferInMs = 0; UINT32 ulRemainToBuffer = 0; GetRemainToBuffer(ulRemainToBufferInMs, ulRemainToBuffer); /* If we are not done with buffering yet, update the buffering * calc now! */ if (ulRemainToBufferInMs > 0 || ulRemainToBuffer > 0) { UpdateMinimumPreroll(FALSE); } else { m_bBufferCalcToBeChanged = TRUE; } }#endif // (HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES)}void CBufferManager::LeaveBufferedPlay(void){#if !defined(HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES) if (m_bBufferedPlay) { m_bBufferCalcToBeChanged = TRUE; m_bBufferedPlay = FALSE; }#endif // (HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES)}UINT32 CBufferManager::GetElapsedTime(UINT32 ulCurrentTime){ UINT32 ulElapsedTime = CALCULATE_ELAPSED_TICKS(m_ulBufferingStartTime, ulCurrentTime); if (m_ulTotalPauseTime > 0) { HX_ASSERT(ulElapsedTime >= m_ulTotalPauseTime); ulElapsedTime = ulElapsedTime > m_ulTotalPauseTime ? ulElapsedTime - m_ulTotalPauseTime : 0; } return ulElapsedTime;}void CBufferManager::UpdateHighestTimestamps(INT64 llActualTimeStamp, STREAM_INFO* pStreamInfo){ // we apply the highest packet time-stamp to every stream // to solve infinite buffering if (m_llHighestTimeStamp < llActualTimeStamp) { m_llHighestTimeStamp = llActualTimeStamp; }}void CBufferManager::SetPerfectPlay(BOOL bPerfectPlay){ m_bPerfectPlay = bPerfectPlay; if (m_pParent->IsLive()) { m_bPerfectPlay = FALSE; m_bBufferedPlay = FALSE; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -