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

📄 hxsm.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		    ulNewValue = ulSourceBandwidth;
		}

		if ((HXR_OK == pASMSourceInfo->m_pSource->
		    QueryInterface(IID_IHXThinnableSource, (void **)&pThin)))
		{
		    if (ulNewValue < (pASMSourceInfo->m_ulLastSetDelivery))
		    {
			DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,
			    "(%p)Congestion: Slow Tranmission Rate to %d %p", pASMSourceInfo->m_pSource,
			    ulNewValue, pASMSourceInfo));

			if (pASMSourceInfo->m_bLossBehind)
			{
			    pASMSourceInfo->m_ulIncomingBandwidth = ulNewValue;
			    bLossBehind = TRUE;
			}

			if (pASMSourceInfo->m_ulRateBeforeDeAccel)
			{
			    pASMSourceInfo->m_ulRateBeforeDeAccel = ulNewValue;
			    /*
			     * Reset the core's acceleration status. 
			     */

			    IHXWatermarkBufferControl* pWMBufCtl = NULL;
			    
			    pASMSourceInfo->m_pSource->
				QueryInterface(IID_IHXWatermarkBufferControl,
					       (void**)&pWMBufCtl);

			    if (pWMBufCtl)
			    {
				pWMBufCtl->ClearChillState();
				pWMBufCtl->Release();
				pWMBufCtl = NULL;
			    }
			    pASMSourceInfo->m_bMayBeAccelerated = TRUE;
			    pASMSourceInfo->m_bPendingChill	= FALSE;
			}

			if ((ulNewValue < ulSourceBandwidth) && (ulSourceBandwidth > 10))
			{
			    pASMSourceInfo->m_pSource->EnterBufferedPlay();
			}

			pASMSourceInfo->m_ulLastSetDelivery = ulNewValue;
		        ulTotalBandwidth += ulNewValue;
			UINT32 ulActualRate = ulNewValue;

			/*
			 * Always keep TCP traffic faster then needed
			 * (but keep it quiet so the rest of the algorithm doesn't
			 * find out :-)
			 */
			if (pASMSourceInfo->m_TransportType == TNG_TCP)
			{
			    ulActualRate = MAX(ulActualRate,
				(UINT32)(ulSourceBandwidth * 1.10));
			}
                        // In low heap mode, do not change the delivery bw.
			// NOTE: There is concern that this is not 
			// satisfactory as a truly long term solution since
			// bw rate control is regarded by some as critical
			// for limited resource platforms.

#if !defined(HELIX_CONFIG_LOW_HEAP_STREAMING)
			pThin->SetDeliveryBandwidth(ulActualRate, 0);
#endif
		    }
		    else
		    {
		        ulTotalBandwidth +=
			    pASMSourceInfo->m_ulLastSetDelivery;
		    }
		}
		HX_RELEASE(pThin);
	    }
	    if (bLossBehind)
	    {
		m_ulNumReportsSinceUpShift = -10;
		m_ulResistanceBitRate = MAX(15000, ulTotalBandwidth);
		DEBUG_OUT(m_pEM, DOL_TRANSPORT, 
		    (s, "Resistance Move %d", m_ulResistanceBitRate));
	    }
	}
    }
    else if (!ulNumSlightlyBehindSources)
    {
	INT32 lAccelTestPoint;
	double dRFactor = 1.05;

	if ((INT32)m_ulUpShiftBandwidthAvail > lAggregateBandwidthUsage)
	{
	    lAccelTestPoint = (INT32) 
		((m_ulUpShiftBandwidthAvail - lAggregateBandwidthUsage)
		* ((float)m_ulUpShiftTestPointScaleFactor / 10000.0)
		    + lAggregateBandwidthUsage);
	}
	else
	{
	    lAccelTestPoint = lAggregateBandwidthUsage;
	}

	UINT32 ulAccelTestPoint =
	    (lAccelTestPoint > 0) ? (UINT32)lAccelTestPoint : 0;
	BOOL bResistanceLimited = FALSE;
	BOOL bWentHigherThanResistanceRate = FALSE;

	if (ulAccelTestPoint > m_ulMaxAccelBitRate)
	{
	    ulAccelTestPoint = m_ulMaxAccelBitRate;
	}
	
	if (ulAccelTestPoint > m_ulResistanceBitRate)
	{
	    UINT32 ulActualResistanceBitRate = m_ulResistanceBitRate;

	    if (ulActualResistanceBitRate < ulAggregateUsed)
	    {
		ulActualResistanceBitRate = (UINT32)(ulAggregateUsed * 1.05);
	    }

	    UINT32 ulOldAccelTestPoint = ulAccelTestPoint;
	    if (ulAccelTestPoint > ulActualResistanceBitRate)
	    {
		UINT32 bHowManyReports =
		    (ulActualResistanceBitRate <
		      ulTotalMaxSubscribedBw) ? 5 : 10;

		if (m_ulUpShiftPastResistanceCount > bHowManyReports)
		{
		    bWentHigherThanResistanceRate = TRUE;

		    if ((m_ulOriginalResistanceBitRate >
		        ulActualResistanceBitRate) &&
			(ulActualResistanceBitRate < ulTotalMaxSubscribedBw))
		    {
			dRFactor = (ulActualResistanceBitRate +
			    ((m_ulOriginalResistanceBitRate -
			    ulActualResistanceBitRate) * 0.10)) /
			    (double)ulActualResistanceBitRate;
			if (dRFactor < 1.01)
			{
			    dRFactor = 1.01;
			}
#ifdef MOREDEBUG
		        DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,
			    "Resistance Accel Factor %0.2f", dRFactor));
#endif
		    }
		    else
		    {
			dRFactor = 1.01;
		    }
 		    ulAccelTestPoint = (UINT32)(ulActualResistanceBitRate *
		        dRFactor);
		}
		else
		{
		    ulAccelTestPoint = ulActualResistanceBitRate;
		}
		if (ulOldAccelTestPoint < ulAccelTestPoint)
		{
		    ulAccelTestPoint = ulOldAccelTestPoint;
		}
		else
		{
		    bResistanceLimited = TRUE;
		}
	    }
	}

	if ((m_ulNumReportsSinceUpShift >= 2) &&
		((INT32)m_ulHighestBandwidthAvail < lAggregateBandwidthUsage))
	{
	    m_ulHighestBandwidthAvail = lAggregateBandwidthUsage;
	    m_ulPeakUsedBandwidth = lAggregateBandwidthUsage;
	    m_bInitialHighBwAvail = FALSE;
	}

	DEBUG_OUT(m_pEM, DOL_TRANSPORT_EXTENDED,
	    (s, "UP Bw Report: Num=%d, Avail=%d, CurrentBw=%d, TestPoint=%d", 
	    m_ulNumReportsSinceUpShift, m_ulUpShiftBandwidthAvail,
	    lAggregateBandwidthUsage, ulAccelTestPoint));

	BOOL bDidChange = FALSE;
	BOOL bBrokeMax = FALSE;
	if ((m_ulNumReportsSinceUpShift >= 2) &&
	    (INT32) (ulAccelTestPoint) > lAggregateBandwidthUsage)
	{
	    m_ulLastStableBandwidth = lAggregateBandwidthUsage;
	    for (i = m_pASMSourceInfo->Begin(); i != m_pASMSourceInfo->End(); ++i)
	    {
		pASMSourceInfo = (ASMSourceInfo*)(*i);

		IHXThinnableSource* pThin = 0;
		UINT32 ulSourceBandwidth = pASMSourceInfo->m_ulSubscribedBw;

		UINT32 ulNewValue = 
			(UINT32)(
			(float)ulSourceBandwidth /
			(float)ulAggregateUsed *
			(float)ulAccelTestPoint);

		if (ulNewValue > (pASMSourceInfo->m_ulMaxSubscribedBw * 4))
		{
		    ulNewValue = (UINT32) 
			(pASMSourceInfo->m_ulMaxSubscribedBw * 4);
		}

		/*
		 * Live streams get capped at 107% of Max to prevent 
		 * unneeded bandwidht modulation.
		 */
		if ((pASMSourceInfo->m_pSource->IsLive()) &&
		   (ulNewValue >
			(pASMSourceInfo->m_ulMaxSubscribedBw * 1.07)))
		{
		    ulNewValue = (UINT32)
			(pASMSourceInfo->m_ulMaxSubscribedBw * 1.07);
		}

		if ((ulNewValue > (pASMSourceInfo->m_ulMaxSubscribedBw)) &&
		    (ulNewValue > (ulSourceBandwidth * 3)) &&
		    (pASMSourceInfo->m_ulLastSetDelivery <
			pASMSourceInfo->m_ulMaxSubscribedBw))
		{
		    /*
		     * If we are already accelerating 3x subscribed bandwidth
		     * and we are about to upshift beyond the max possible
		     * bandwidth, then let's stop and take a breather just
		     * above the max subscription.  This prevents us from
		     * buffering huge amounts of the crappy low bw stream.
		     */
		    UINT32 ulTemp;
		    ulTemp = (UINT32) 
			(pASMSourceInfo->m_ulMaxSubscribedBw * 1.10);
		    ulNewValue = MIN(ulTemp, ulNewValue);
		}

		if (pASMSourceInfo->m_ulLastSetDelivery >
			pASMSourceInfo->m_ulMaxSubscribedBw)
		{
		    bBrokeMax = TRUE;
		}

		if (pASMSourceInfo->m_bMayBeAccelerated &&
		   (HXR_OK == pASMSourceInfo->m_pSource->
		    QueryInterface(IID_IHXThinnableSource, (void **)&pThin)))
		{
		    double Factor;

		    if (bResistanceLimited)
		    {
			Factor = 1.005;
		    }
		    else if (pASMSourceInfo->m_pSource->IsLive())
		    {
			Factor = 1.01;
		    }
		    else
		    {
			Factor = 1.05;
		    }

		    if ((ulNewValue > (pASMSourceInfo->m_ulLastSetDelivery * Factor)) && 
			pASMSourceInfo->m_bSourceAccelAllowed)
		    {
			DEBUG_OUT(m_pEM, DOL_TRANSPORT, 
			(s, "(%p)Accelerating: NewTransmissionRate=%d", pASMSourceInfo->m_pSource, ulNewValue));

			m_ulUpShiftPastResistanceCount = 0;

			if (ulNewValue > ulSourceBandwidth)
			{
			    pASMSourceInfo->m_pSource->LeaveBufferedPlay();
			}

			bDidChange = TRUE;

			/*
			 * WHOA!  If this is a timestamp delivered source
			 * i.e. 5.0 thinning, then the imperical Getbandwidth()
			 * will never reach the rate that we set, so we help
			 * it along a bit (just a bit of a nudge, eh?).
			 */
			if (pASMSourceInfo->m_bTimeStampDelivery)
			{
			    pASMSourceInfo->m_ulIncomingBandwidth = ulNewValue;
			}
			m_ulNumReportsSinceUpShift = 0;
			pASMSourceInfo->m_bInvalidUpReport = TRUE;
			m_bDidOfferUpShiftToRecalc = FALSE;
			pThin->SetDeliveryBandwidth(
			    (pASMSourceInfo->m_ulLastSetDelivery = ulNewValue), 0);
		    }
		}
		HX_RELEASE(pThin);
	    }
	}
	if ((bDidChange == TRUE) && (bWentHigherThanResistanceRate))
	{
	    m_ulResistanceBitRate = (UINT32)(m_ulResistanceBitRate * dRFactor);
	    DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,
	        "Went over ResistanceBitRate %d", m_ulResistanceBitRate));
	}
	if (((bDidChange == FALSE) &&
	    (m_ulNumReportsSinceUpShift > NUM_REPORTS_NEEDED_TO_UPSHIFT) ||
	    (bBrokeMax == TRUE)) && (m_bDidOfferUpShiftToRecalc == FALSE))
	{
	    m_State = HX_NONE;
	    m_bDidOfferUpShiftToRecalc = TRUE;
	    m_ulOfferToRecalc = lAggregateBandwidthUsage;

#ifdef MOREDEBUG
	    DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,
			"Upshift Offer to Recalc() %d", m_ulOfferToRecalc));
#endif


	    Recalc();
	    return;
	}
    }
}

void
ASMStreamInfo::NotifyNewBandwidth()
{
    m_pNegotiator->SetBandwidthUsage(m_ulLastBandwidth,
	m_bTimeStampDelivery);
}

void
ASMStreamInfo::NotifyTimeStampDelivery()
{
    if(m_bTimeStampDelivery)
    {
	m_pASMSourceInfo->m_bTimeStampDelivery = TRUE;
    }
}

UINT32
ASMSourceInfo::GetBandwidth()
{
    return m_ulIncomingBandwidth;
}


void
ASMStreamInfo::SetLastBandwidth(UINT32 ulOffer)
{
    m_ulLastBandwidth = ulOffer;
}

void
ASMStreamInfo::NotifyLimitBandwidth(UINT32 ulRecv)
{
    if(m_pASMSourceInfo->m_bBehind)
    {
	m_pNegotiator->HandleSlowSource(ulRecv);
    }
}

ASMSourceInfo::ASMSourceInfo(HXSource* pSource, HXSM* pHXASM)
    : m_ulLastReportTime(0)
    , m_ulIncomingBandwidth(0)
    , m_ulRateBeforeDeAccel(0)
    , m_lTimeDiffBase(0)
    , m_ulBytesBehind(0)
    , m_lLastBehindTime(0)
    , m_ulLastSetDelivery(0xffffffff)
    , m_ulSubscribedBw(0)
    , m_ulMaxSubscribedBw(0)
    , m_bBehind(FALSE)
    , m_bLossBehind(FALSE)
    , m_bSlightlyBehind(FALSE)
    , m_bTimeStampDelivery(FALSE)
    , m_bPendingChill(FALSE)
    , m_bInvalidUpReport(FALSE)
    , m_bPerfectPlay(FALSE)
    , m_bIsDone(FALSE)
    , m_bMayBeAccelerated(TRUE)
    , m_bTryToUpShift(FALSE)
    , m_bAdjustBandwidth(FALSE)
    , m_ulLowestBandwidthBeforeTimeStamp(0)
    , m_bSourceAccelAllowed(TRUE)
    , m_bSourceDecelAllowed (TRUE)
    , m_bSlidingBwWindowReady(FALSE)
    , m_pMasterRuleBook(0)
    , m_pStreams(0)
    , m_TransportType(TNG_UDP)
    , m_pSource(pSource)
    , m_pSBI(0)
    , THRESHOLD(1000)
    , m_lRefCount(0)
    , m_ulBwDetectionDataCount(0)
    , m_ulBwDetectionDataLen(0)
    , m_ulSlidingWindowLocation(0)
    , m_pBwDetectionData(NULL)
    , m_pHXASM(pHXASM)
{
    m_lOuterThreshold = THRESHOLD;
    IHXValues* pHeader = 0;

    pSource->AddRef();

    if (pSource->m_pFileHeader)
    {
	IHXBuffer* pMasterRuleBook = NULL;
	pSource->m_pFileHeader->
	    GetPropertyCString("ASMRuleBook", pMasterRuleBook);

	if (pMasterRuleBook)
	{
	    m_pMasterRuleBook = new ASMRuleBook
		((const char *)pMasterRuleBook->GetBuffer());
	}

	HX_RELEASE(pMasterRuleBook);
    }
}

ASMSourceInfo::~ASMSourceInfo()
{
    HX_VECTOR_DELETE(m_pBwDetectionData);
    delete[] m_pStreams;
    delete m_pMasterRuleBook;
}


BOOL
ASMSourceInfo::AllocBWDetectionData(UINT32 ulReqSize)
{
    BOOL bOk = TRUE;

    // Our current array is too small
    if (ulReqSize > m_ulBwDetectionDataLen)
    {
	BwDetectionData* pTemp = new 

⌨️ 快捷键说明

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