📄 hxbufstate.cpp
字号:
} else if ((m_ulRemainingToBufferInMs != 0) && (m_ulCurrentBufferingInMs >= 1000)) { /* * Highly unlikely, but may happen from a * server on the local machine. */ if (ulElapsedTime == 0) { if (m_ulCurrentBufferingInMs >= m_ulMinimumPrerollInMs) { m_ulRemainingToBufferInMs = 0; } } else { CalcRemainingToBufferInMs(ulElapsedTime); } } } else { /* bIsBufferedPlayMode == FALSE */ if (m_ulRemainingToBufferInMs) { CalcRemainingToBufferInMs(); } }}void HXBufferingState::UpdateTransportStats(INT64 llLowTSAtTransport, INT64 llHighTSAtTransport, ULONG32 ulBytesAtTransport, BOOL bDoneAtTransport){ m_llLowestTimestampAtTransport = llLowTSAtTransport; m_llHighestTimestampAtTransport = llHighTSAtTransport; m_ulNumBytesAtTransport = ulBytesAtTransport; m_bDoneAtTransport = bDoneAtTransport;}HX_RESULT HXBufferingState::GetBufferingStats(REF(INT64) llLowTimestamp, REF(INT64) llHighTimestamp, REF(UINT32) ulBytesBuffered, BOOL bUseTransportStats){ HX_RESULT res = HXR_NO_DATA; if (!m_bIsFirstPacket) { // Note: GetBufferedData() MUST be called first because // it is the one responsible for pruning the list ulBytesBuffered = GetBufferedData(); if (!m_pktInfo.IsEmpty()) { HXBufferedPktInfo* pPktInfo = (HXBufferedPktInfo*)m_pktInfo.GetHead(); llLowTimestamp = pPktInfo->Timestamp(); } else { llLowTimestamp = m_llHighestTimeStamp; } llHighTimestamp = m_llHighestTimeStamp; if (bUseTransportStats) { if (m_llHighestTimestampAtTransport > llHighTimestamp) { llHighTimestamp = m_llHighestTimestampAtTransport; } ulBytesBuffered += m_ulNumBytesAtTransport; } res = HXR_OK; } return res;}void HXBufferingState::GetExcessBufferInfo(INT64 llTheLowestTS, INT64 llTheHighestTS, BOOL bIsSeekPerformed, REF(UINT32) ulRemainToBufferInMs, REF(UINT32) ulRemainToBuffer, REF(UINT32) ulExcessBufferInMs, REF(UINT32) ulExcessBuffer, REF(UINT32) ulExcessForThisStreamInMs, REF(UINT32) ulExcessForThisStream){ UINT32 ulCurBufInMs = 0; UINT32 ulRemainForThisStreamInMs = 0; UINT32 ulRemainForThisStream = 0; ulExcessForThisStreamInMs = 0; ulExcessForThisStream = 0; if (m_ulNumBytesAtTransport > 0) { HX_ASSERT((llTheHighestTS - m_llLowestTimestampAtTransport) < MAX_TIMESTAMP_GAP); ulCurBufInMs = INT64_TO_UINT32(llTheHighestTS - m_llLowestTimestampAtTransport); } else { HX_ASSERT((llTheHighestTS - llTheLowestTS) < MAX_TIMESTAMP_GAP); ulCurBufInMs = INT64_TO_UINT32(llTheHighestTS - llTheLowestTS); } if (ulCurBufInMs <= m_ulMinimumBufferingInMs) { ulRemainForThisStreamInMs = m_ulMinimumBufferingInMs - ulCurBufInMs; } else { ulExcessForThisStreamInMs = ulCurBufInMs - m_ulMinimumBufferingInMs; } if (m_ulNumBytesAtTransport <= m_ulMinimumBuffering) { ulRemainForThisStream = m_ulMinimumBuffering - m_ulNumBytesAtTransport; } else { ulExcessForThisStream = m_ulNumBytesAtTransport - m_ulMinimumBuffering; } BOOL bHasPreroll = HasPreroll(bIsSeekPerformed); BOOL bHasPredata = HasPredata(bIsSeekPerformed); // satisfy the preroll (by default + pre-set) if (!bHasPredata || bHasPreroll) { if (ulRemainToBufferInMs < ulRemainForThisStreamInMs) { ulRemainToBufferInMs = ulRemainForThisStreamInMs; } if (ulExcessBufferInMs < ulExcessForThisStreamInMs) { ulExcessBufferInMs = ulExcessForThisStreamInMs; } } // satisfy the predata if (bHasPredata) { ulRemainToBuffer += ulRemainForThisStream; ulExcessBuffer += ulExcessForThisStream; }}void HXBufferingState::OnTimeSync(UINT32 ulCurrentTime){ // 0xFA .. 0xFF [roll over] (0x01) if (m_ulLastTimeSync > ulCurrentTime && ((m_ulLastTimeSync - ulCurrentTime) > MAX_TIMESTAMP_GAP)) { m_ulTimeSyncRollOver++; } m_ulLastTimeSync = ulCurrentTime; m_llCurrentPlaybackTime = CreateINT64Timesync(ulCurrentTime); // Add back the first live packet timestamp. // If not live, then m_llFirstLivePacketTimeStamp is 0. m_llCurrentPlaybackTime += m_llFirstLivePacketTimestamp; m_bCurrentTimeSet = TRUE;}void HXBufferingState::SetMinPrerollInMs(ULONG32 ulMinPrerollInMs, ULONG32 ulMinBufferingInMs){ m_ulMinimumPrerollInMs = ulMinPrerollInMs; m_ulMinimumBufferingInMs = ulMinBufferingInMs; m_ulRemainingToBufferInMs = m_ulMinimumBufferingInMs;}void HXBufferingState::SetMinPreroll(){ SetMinPreroll(MsToBytes(m_ulMinimumPrerollInMs, m_ulAvgBandwidth), m_ulAvgBandwidth);}void HXBufferingState::SetMinPreroll(UINT32 ulMinimumPredata, UINT32 ulBandwidth){ HX_ASSERT(m_ulMinimumPrerollInMs >= m_ulPreroll); UINT32 ulExtraBufferingInMs = m_ulMinimumPrerollInMs - m_ulPreroll; /* Get current bandiwidth from asm */ m_ulMinimumPreroll = (ulMinimumPredata + MsToBytes(ulExtraBufferingInMs, ulBandwidth)); // There is no buffered or perfect play with MIN_HEAP on.#if defined(HELIX_CONFIG_MIN_PCM_PUSHDOWN_BYTES) m_ulMinimumBuffering = m_ulMinimumPreroll;#else ulExtraBufferingInMs = m_ulMinimumBufferingInMs - m_ulPreroll; m_ulMinimumBuffering = (ulMinimumPredata + MsToBytes(ulExtraBufferingInMs, ulBandwidth));#endif m_ulRemainingToBuffer = m_ulMinimumBuffering; m_ulCurrentBuffering = 0;}void HXBufferingState::UpdateMinPredata(){ UINT32 ulMinimumPredata = m_ulPredata; UINT32 ulBandwidth = m_ulAvgBandwidth; #if defined(HELIX_FEATURE_ASM) // no ASMProps in AutoConfig HX_ASSERT(m_pASMProps); if (m_pASMProps) { UINT32 ulTmp; if (HXR_OK == m_pASMProps->GetPreData(ulTmp)) { ulMinimumPredata = ulTmp; } if (HXR_OK == m_pASMProps->GetBandwidth(ulTmp)) { ulBandwidth = ulTmp; } }#endif /* HELIX_FEATURE_ASM */ SetMinPreroll(ulMinimumPredata, ulBandwidth);}void HXBufferingState::UpdateCurrentBufferingInMs(INT64 llLowestTimeStamp, INT64 llHighestTimeStamp){ INT64 llLowTimestamp = m_llLowestTimeStamp; if (m_bIsFirstPacket) { /* use the reference stream's lowest timestamp for calculation */ llLowTimestamp = llLowestTimeStamp; } if (llHighestTimeStamp > llLowTimestamp) { // if the stream has been continuesly playing for 49 days // we will set m_ulCurrentBufferingInMs to MAX_UINT32 if (llHighestTimeStamp - llLowTimestamp > MAX_UINT32) { m_ulCurrentBufferingInMs = MAX_UINT32; } else { m_ulCurrentBufferingInMs = INT64_TO_UINT32(llHighestTimeStamp - llLowTimestamp); } }}ULONG32 HXBufferingState::MsToBytes(ULONG32 ulValueInMs, ULONG32 ulBw) const{ return (ulValueInMs * (ulBw / 8)) / 1000;}void HXBufferingState::CalcRemainingToBufferInMs(){ m_ulRemainingToBufferInMs = CalcRemaining(m_ulMinimumBufferingInMs, m_ulCurrentBufferingInMs, 0, 0);}void HXBufferingState::CalcRemainingToBufferInMs(ULONG32 ulElapsedTime){ m_ulRemainingToBufferInMs = CalcRemaining(m_ulMinimumBufferingInMs, m_ulCurrentBufferingInMs, m_ulMinimumPrerollInMs, ulElapsedTime);}void HXBufferingState::CalcRemainingToBuffer(){ m_ulRemainingToBuffer = CalcRemaining(m_ulMinimumBuffering, m_ulCurrentBuffering, 0, 0);}void HXBufferingState::CalcRemainingToBuffer(ULONG32 ulDenom){ m_ulRemainingToBuffer = CalcRemaining(m_ulMinimumBuffering, m_ulCurrentBuffering, m_ulMinimumPreroll, ulDenom);}UINT32 HXBufferingState::CalcRemaining(UINT32 ulMinimumBuffering, UINT32 ulCurrentBuffering, UINT32 ulMinimumPreroll, UINT32 ulDenom) const{ UINT32 ulRemainingToBuffer = 0; if (ulMinimumBuffering > ulCurrentBuffering) { ulRemainingToBuffer = ulMinimumBuffering - ulCurrentBuffering; } if (ulDenom) { UINT32 ulBufferWhilePlaying = ulRemainingToBuffer; /* * Buffers during playback = X*X/Y + X*(X/Y)^2 + X*(X/Y)^3 + .... * = X*X/Y (1 + X/Y + (X/Y)^2 + ....) * * = X*X/Y ( 1 / (1 - X/Y)) IFF X/Y < 1 i.e. X < Y * * ELSE We have enough data... Satisfy preroll */ /* Add a fudge factor of 10% */ ulDenom = (UINT32) (ulDenom * 1.10); if (ulCurrentBuffering < ulDenom) { double x = ulCurrentBuffering; double y = ulDenom; ulBufferWhilePlaying = (UINT32) (((x * x) / y) * (1. / (1. - x / y))); } if (ulBufferWhilePlaying < ulRemainingToBuffer) { ulRemainingToBuffer -= ulBufferWhilePlaying; } else if (ulCurrentBuffering >= ulMinimumPreroll) { ulRemainingToBuffer = 0; } } return ulRemainingToBuffer;}void HXBufferingState::SetAvgBWToASMBw(){ UINT32 ulBandwidth = 0; if (m_pASMProps && m_pASMProps->GetBandwidth(ulBandwidth) == HXR_OK) { m_ulAvgBandwidth = ulBandwidth; }}void HXBufferingState::ClearPktInfo(){ m_ulBufferedData = 0; while(!m_pktInfo.IsEmpty()) { HXBufferedPktInfo* pInfo = (HXBufferedPktInfo*)m_pktInfo.RemoveHead(); delete pInfo; }}void HXBufferingState::AddPktInfo(INT64 llTimestamp, UINT32 ulPacketSize){ // Create the HXBufferedPktInfo class HXBufferedPktInfo* pPktInfo = new HXBufferedPktInfo(llTimestamp, ulPacketSize); if (pPktInfo) { m_pktInfo.AddTail(pPktInfo); m_ulBufferedData += ulPacketSize; } // purge the old packet info data // this keeps the list short and prevents the Symbian // allocator from freaking out (void)GetBufferedData();}UINT32 HXBufferingState::GetBufferedData(){ BOOL bDone = m_pktInfo.IsEmpty() || !m_bCurrentTimeSet; // Remove all packet info that is past due // and subtract their sizes from our buffering total while(!bDone) { HXBufferedPktInfo* pPktInfo = (HXBufferedPktInfo*)m_pktInfo.GetHead(); if (pPktInfo->Timestamp() <= m_llCurrentPlaybackTime) { m_ulBufferedData -= pPktInfo->Size(); m_pktInfo.RemoveHead(); delete pPktInfo; bDone = m_pktInfo.IsEmpty(); } else { bDone = TRUE; } } return m_ulBufferedData;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -