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

📄 hxbufstate.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: hxbufstate.cpp,v 1.5.4.4 2004/07/09 02:05:57 hubbe Exp $ *  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. *  * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks.  You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL.  Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. *  * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. *  * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. *  * Technology Compatibility Kit Test Suite(s) Location: *    http://www.helixcommunity.org/content/tck *  * Contributor(s): *  * ***** END LICENSE BLOCK ***** */#include "hxbufstate.h"#include "hxassert.h"class HXBufferedPktInfo{public:    HXBufferedPktInfo(INT64 llTimestamp, UINT32 ulSize);    INT64 Timestamp() const { return m_llTimestamp;}    UINT32 Size() const { return m_ulSize;}private:    INT64 m_llTimestamp;    UINT32 m_ulSize;};inlineHXBufferedPktInfo::HXBufferedPktInfo(INT64 llTimestamp, 				     UINT32 ulSize) :    m_llTimestamp(llTimestamp),    m_ulSize(ulSize){}HXBufferingState::HXBufferingState() :    m_ulPreroll(0)    , m_ulPredata(0)    , m_ulMinimumPrerollInMs(0)    , m_ulMinimumPreroll(0)    , m_ulMinimumBufferingInMs(0)    , m_ulMinimumBuffering(0)    , m_ulRemainingToBufferInMs(0)    , m_ulRemainingToBuffer(0)    , m_ulCurrentBufferingInMs(0)    , m_ulCurrentBuffering(0)    , m_bIsFirstPacket(TRUE)    , m_preDataAtStart(FALSE)    , m_prerollAtStart(FALSE)    , m_preDataAfterSeek(FALSE)    , m_prerollAfterSeek(FALSE)    , m_llLowestTimeStamp(0)    , m_llHighestTimeStamp(0)    , m_llLowestTimestampAtTransport(0)    , m_llHighestTimestampAtTransport(0)    , m_ulNumBytesAtTransport(0)    , m_bDoneAtTransport(FALSE)    , m_ulTSRollOver(0)    , m_ulLastPacketTimeStamp(0)    , m_ulAvgBandwidth(0)    , m_pASMProps(NULL)    , m_bCurrentTimeSet(FALSE)    , m_llCurrentPlaybackTime(0)    , m_ulBufferedData(0)    , m_ulLastTimeSync(0)    , m_llFirstLivePacketTimestamp(0)    , m_ulTimeSyncRollOver(0){}HXBufferingState::~HXBufferingState(){    HX_RELEASE(m_pASMProps);    ClearPktInfo();}void HXBufferingState::OnStreamHeader(UINT32 ulPreroll,				      UINT32 ulPredata,				      BOOL preDataAtStart,				      BOOL preDataAfterSeek,				      BOOL prerollAtStart,				      BOOL prerollAfterSeek,				      ULONG32 ulAvgBitRate){    m_ulPreroll = ulPreroll;    m_ulPredata = ulPredata;    m_preDataAtStart = preDataAtStart;    m_preDataAfterSeek = preDataAfterSeek;    m_prerollAtStart = prerollAtStart;    m_prerollAfterSeek = prerollAfterSeek;    m_ulAvgBandwidth = ulAvgBitRate;}void HXBufferingState::OnStream(IUnknown* pStream){    HX_RELEASE(m_pASMProps);    if (pStream)    {	pStream->QueryInterface(IID_IHXASMProps, (void**) &m_pASMProps);    }}void HXBufferingState::Init(ULONG32 ulPerfectPlayTime){    SetMinPrerollInMs(m_ulPreroll, m_ulPreroll + ulPerfectPlayTime);    SetMinPreroll();}void HXBufferingState::SetMinimumPreroll(UINT32 ulSourcePreroll, 					 UINT32 ulInitialAudioPreroll,					 UINT32 ulPerfectPlayTime,					 BOOL   bIsRebuffering){    UINT32 ulMinimumPreroll = m_ulPreroll;        ulMinimumPreroll += ulInitialAudioPreroll;        if (ulMinimumPreroll < ulSourcePreroll)    {	ulMinimumPreroll = ulSourcePreroll;    }        SetMinPrerollInMs(ulMinimumPreroll, 		      ulMinimumPreroll + ulPerfectPlayTime);    m_ulCurrentBufferingInMs = 0;    /* If we have received at lest one packet for this stream,     * mark the lowest timestamp to be the     * last packet timstamp to reset buffering calculations     */    if (bIsRebuffering && !m_bIsFirstPacket)    {	m_bIsFirstPacket = TRUE;	m_llLowestTimeStamp = 	    CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 + CAST_TO_INT64 (m_ulLastPacketTimeStamp);    }        UpdateMinPredata();}void HXBufferingState::Stop(){    m_ulRemainingToBufferInMs = 0;    m_ulRemainingToBuffer = 0;}void HXBufferingState::Reset(BOOL bIsSeeking, UINT32 ulSeekTime){    m_ulRemainingToBufferInMs = m_ulMinimumBufferingInMs;    m_ulRemainingToBuffer = m_ulMinimumBuffering;    m_ulCurrentBufferingInMs = 0;    m_ulCurrentBuffering = 0;    m_ulTSRollOver = 0;    m_ulLastPacketTimeStamp = 0;    m_bIsFirstPacket = TRUE;    ClearPktInfo();    m_bCurrentTimeSet = FALSE;    if (bIsSeeking)    {	m_llLowestTimeStamp = CAST_TO_INT64 ulSeekTime;	m_llHighestTimeStamp = CAST_TO_INT64 ulSeekTime;    }}void HXBufferingState::GetRemainToBuffer(REF(UINT32) ulRemainToBufferInMs,					 REF(UINT32) ulRemainToBuffer){    ulRemainToBufferInMs = m_ulRemainingToBufferInMs;    ulRemainToBuffer = m_ulRemainingToBuffer;}UINT16 HXBufferingState::GetPercentDone(BOOL bIsSeekPerformed){    UINT16  uTotalPercentDone = 100;    UINT16  uPreDataPercentDone = 100;    UINT16  uPrerollPercentDone = 100;    BOOL bHasPreroll;    BOOL bHasPredata;    BOOL bNeedsData = FALSE;    if (!bIsSeekPerformed)    {	// start/rebuffer mode	bHasPreroll = m_prerollAtStart;	bHasPredata = m_preDataAtStart;    }    else    {	// seek mode	bHasPreroll = m_prerollAfterSeek;	bHasPredata = m_preDataAfterSeek;    }    // satisfy the preroll (by default + pre-set)    if (!bHasPredata || bHasPreroll)    {	// percent done on preroll	if (m_ulMinimumBufferingInMs)	{	    uPrerollPercentDone =		((m_ulMinimumBufferingInMs-m_ulRemainingToBufferInMs ) * 100) /				m_ulMinimumBufferingInMs;	}		uTotalPercentDone = uPrerollPercentDone;	bNeedsData = (m_ulRemainingToBufferInMs > 0);    }    // satisfy the predata    if (bHasPredata)    {	// percent done on predata	if (m_ulMinimumBuffering)	{	    uPreDataPercentDone = 		((m_ulMinimumBuffering - m_ulRemainingToBuffer ) * 100) /				m_ulMinimumBuffering;	}		uTotalPercentDone = uPreDataPercentDone;	bNeedsData = (m_ulRemainingToBuffer > 0);    }    if (bHasPredata && bHasPreroll)    {	uTotalPercentDone = (uPrerollPercentDone + uPreDataPercentDone) / 2;    }    else if ((bIsSeekPerformed) &&	     (uTotalPercentDone == 100) &&	     (bNeedsData))    {	uTotalPercentDone = 99;    }    return uTotalPercentDone;}void HXBufferingState::UpdatePreroll(ULONG32 ulPreroll){    UINT32 ulExtraPrerollInMs   = m_ulMinimumPrerollInMs - m_ulPreroll;    UINT32 ulExtraBufferingInMs = m_ulMinimumBufferingInMs - m_ulPreroll;        SetPreroll(ulPreroll);    SetMinPrerollInMs(ulPreroll + ulExtraPrerollInMs,		      ulPreroll + ulExtraBufferingInMs);    SetMinPreroll();    // Notice that we don't call ClearCurrentBufferingInMs()    // or ClearCurrentBuffering(). This allows us to count    // any data we have already received as part of the    // new preroll    CalcRemainingToBufferInMs();    CalcRemainingToBuffer();}INT64 HXBufferingState::CreateINT64Timestamp(UINT32 ulTime){    return CAST_TO_INT64 (m_ulTSRollOver) * CAST_TO_INT64 MAX_UINT32 + CAST_TO_INT64 ulTime;}INT64 HXBufferingState::CreateINT64Timesync(UINT32 ulTime){    return CAST_TO_INT64 (m_ulTimeSyncRollOver) * CAST_TO_INT64 MAX_UINT32 + CAST_TO_INT64 ulTime;}void HXBufferingState::OnPacket(UINT32 ulTimestamp, UINT32 ulPacketSize,				UINT32 ulElapsedTime,				BOOL bIsLive, BOOL bIsBufferedPlayMode){    //  0xFA .. 0xFF [roll over] (0x01)    if (m_ulLastPacketTimeStamp > ulTimestamp &&	((m_ulLastPacketTimeStamp - ulTimestamp) > MAX_TIMESTAMP_GAP))    {	m_ulTSRollOver++;    }        INT64 llActualTimeStamp = CreateINT64Timestamp(ulTimestamp);    m_ulLastPacketTimeStamp = ulTimestamp;    if (m_bIsFirstPacket)    {	/* Only if we are live,  store the first packet timestemp	 * as the lowest timestamp. In any other case, we consider	 * the lowest ts to be 0 OR the Seek time.	 * This is to fix the post-seek buffering where we should not	 * account any packets < seek ts towards buffering completion.	 */	if (bIsLive)	{	    m_llLowestTimeStamp = CAST_TO_INT64 ulTimestamp;            m_llFirstLivePacketTimestamp = m_llLowestTimeStamp;        }	m_llHighestTimeStamp = CAST_TO_INT64 ulTimestamp;	m_bIsFirstPacket = FALSE;    }    // Add this packet to our packet info statistics    AddPktInfo(llActualTimeStamp, ulPacketSize);    // data based preroll    if (DataBasedPreroll())    {	m_ulCurrentBuffering += ulPacketSize;    	if (bIsBufferedPlayMode)	{	    /* 	     * We wait to have at least 1 second worth of data	     * before doing any calculations. This may need some	     * tweaking.	     */	    if ((m_ulRemainingToBuffer != 0) &&		(m_ulCurrentBuffering >= m_ulAvgBandwidth / 8))	    {		/* 		 * Highly unlikely, but may happen from a server on the 		 * local machine.		 */		if (ulElapsedTime == 0)		{		    if (m_ulCurrentBuffering >= m_ulMinimumPreroll)		    {			m_ulRemainingToBuffer = 0;		    }		}		else		{		    UINT32 ulDenom = ulElapsedTime * m_ulAvgBandwidth / 8000;		    		    /* Sanity check - may be 0 only when bandwidth		     * is really low 		     */		    ulDenom = ulDenom > 0 ? ulDenom : 1;		    		    CalcRemainingToBuffer(ulDenom);		}	    }	}	else	{	    /* bIsBufferedPlayMode == FALSE */	    if (m_ulRemainingToBuffer)	    {		CalcRemainingToBuffer();	    }	}    }    if (llActualTimeStamp >= m_llHighestTimeStamp)    {	m_llHighestTimeStamp = llActualTimeStamp;    } }void HXBufferingState::UpdateBufferingInMs(INT64 llRefLowTimestamp,					   INT64 llHighTimestamp, 					   BOOL bIsBufferedPlayMode,					   BOOL bIsTimestampDelivery,					   UINT32 ulElapsedTime){    UpdateCurrentBufferingInMs(llRefLowTimestamp, llHighTimestamp);    if (bIsBufferedPlayMode)    {	/* We handle time stamp delivered streams differently	 * in case of BUffered/PerfectPlay. This is because	 * server sends timestamp delivered stream based	 * on the timestamps on the packet and pretty	 * much streams in realtime. 	 * So even if we are on LAN and streaming a RealText	 * file, we will get packets in realtime even though	 * we have enough bandwidth available	 * 	 * For timestamp delivered streams, we just fulfill 	 * preroll.	 */	if (bIsTimestampDelivery &&	    m_ulCurrentBufferingInMs > m_ulMinimumPrerollInMs)	{	    m_ulRemainingToBufferInMs = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -