⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxbufstate.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	     * 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)
    {
	if (!m_pktInfo.IsEmpty())
	{
	    HXBufferedPktInfo* pPktInfo = 
		(HXBufferedPktInfo*)m_pktInfo.GetHead();

	    llLowTimestamp = pPktInfo->Timestamp();
	}
	else
	{
	    llLowTimestamp = m_llHighestTimeStamp;
	}

	llHighTimestamp = m_llHighestTimeStamp;
	ulBytesBuffered = GetBufferedData();
	

	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);
}

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)
{
    // Subtract off the first live packet timestamp.
    // If not live, then m_llFirstLivePacketTimeStamp is 0.
    llTimestamp -= m_llFirstLivePacketTimestamp;
    // 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();
    
    // 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 + -