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

📄 hxsm2.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
    UINT32 ulRet = (m_bFixedBwValid) ? m_ulFixedBandwidth : 0;

    if (!ulRet && m_pThresholds)
    {
	ulRet = (UINT32)m_pThresholds[m_ulCurThresh];
    }

    return ulRet;
}

inline
UINT32 ASMStreamInfo2::StreamID() const
{
    return m_ulStreamID;
}

inline
void ASMStreamInfo2::SetStreamOffer(UINT32 ulOffer)
{
    m_ulStreamOffer = ulOffer;
}

void ASMStreamInfo2::SelectBw(BOOL bPerfectPlay,
			      UINT32 ulAltOffer)
{
    if (m_pThresholds)
    {
	if (bPerfectPlay)
	{
	    /*
	     * If we are in perfect play mode, just select the highest bandwidth rule
	     * and don't negotiate any further.
	     */
	    m_ulCurThresh = m_ulMaxEffectiveThreshold;
	    m_ulOffer = CurrentBw();
	}
	else
	{ 
	    UINT32 ulOffer = ulAltOffer;

	    if (m_ulStreamOffer)
	    {
		ulOffer = m_ulStreamOffer - 1;
	    }
	    
	    if (m_ulMaxEffectiveThreshold != 0)
	    {
		for (UINT32 i = 1; i <= m_ulMaxEffectiveThreshold; i++)
		{
		    if ((ulOffer <= m_pThresholds[i]) ||
			(i == m_ulMaxEffectiveThreshold))
		    {
			m_ulOffer = ulOffer;
			m_ulCurThresh = i;
			break;
		    }
		}
	    }
	}

	ComputeResistence(bPerfectPlay);
    }
}

inline
UINT32 ASMStreamInfo2::ResistanceToLower() const
{
    return m_ulResistanceToLower;
}

void ASMStreamInfo2::SelectNextLowerBw()
{
    if (m_ulCurThresh > 0)
    {
	m_ulCurThresh--;

	ComputeResistence(FALSE);
    }
}

inline
UINT32 ASMStreamInfo2::GetLastBw() const
{
    return m_ulLastBw;
}

void ASMStreamInfo2::SubscribeToNewBw(UINT32 ulBw, CHXSimpleList* pSubChanges)
{
    BOOL bTimeStampDelivery = FALSE;
    
    if (m_pRuleGather && m_pNegotiator)
    {
	m_pRuleGather->RuleGather(pSubChanges);
	
	//update the HXASMStream with our new bandwidth
	m_pNegotiator->SetBandwidthUsage(ulBw, bTimeStampDelivery);
	
	m_pRuleGather->RuleGather(0);
    }

    m_ulLastBw = ulBw;
}

void ASMStreamInfo2::SubscribeToChanges(CHXSimpleList* pSubChanges)
{
    if (m_pRuleGather)
    {
	m_pRuleGather->RuleFlush(pSubChanges);
    }
}

void ASMStreamInfo2::ComputeResistence(BOOL bPerfectPlay)
{
    /* NOTE:
     * m_ulCurThresh and m_ulOffer must
     * be valid when this function is called
     */

    if (IsFixedBw() || 
	bPerfectPlay ||
	(m_ulMaxEffectiveThreshold == 0) ||
	(m_ulCurThresh == 1))
    {
	m_ulResistanceToLower = 0xffffffff;
    }
    else
    {
	m_ulResistanceToLower = 
	    (m_ulOffer - (UINT32)m_pThresholds[m_ulCurThresh - 1]) * m_ulOffer;
    }
}

HXSM2::HXSM2() :
    m_lRefCount(0),
    m_ulNumSources(0),
    m_pASMSourceInfo(0),
    m_ulNumStreams(0),
    m_ulOfferToRecalc(0),
    m_ulSelectionBitRate(0),
    m_ulMaxAccelBitRate(0),
    m_ulSustainableBitRate(0),
    m_pSubscriptionVariables(0),
    m_bCheckOnDemandBw(FALSE)
{
    m_pASMSourceInfo = new CHXSimpleList();
}

HXSM2::~HXSM2()
{
    if (m_pASMSourceInfo)
    {
	while(!m_pASMSourceInfo->IsEmpty())
	{
	    ASMSourceInfo2* pSrc = 
		(ASMSourceInfo2*)m_pASMSourceInfo->RemoveHead();

	    delete pSrc;
	}

	delete m_pASMSourceInfo;
    }
}

STDMETHODIMP HXSM2::QueryInterface(THIS_ REFIID ID, void** ppInterfaceObj)
{
	QInterfaceList qiList[] =
	{
		{ GET_IIDHANDLE(IID_IUnknown), this },
		{ GET_IIDHANDLE(IID_IHXBandwidthManager), (IHXBandwidthManager*) this },
	};	
    return QIFind(qiList, QILISTSIZE(qiList), ID, ppInterfaceObj);
}

STDMETHODIMP_(UINT32) HXSM2::AddRef(THIS)
{
    return InterlockedIncrement(&m_lRefCount);
}

STDMETHODIMP_(UINT32) HXSM2::Release(THIS)
{
    if (InterlockedDecrement(&m_lRefCount) > 0)
    {
	return m_lRefCount;
    }

    delete this;
    return 0;
}

/*
 *	IHXBandwidthManager methods
 */
STDMETHODIMP HXSM2::RegisterSource(THIS_
				   HXSource* pSource,
				   IUnknown* pUnknown)
{
    HX_RESULT res = HXR_OK;

    IHXSourceBandwidthInfo* pSBI;
    IHXPreferences* pPreferences = NULL;
    IHXBuffer* pBuffer = 0;
    ASMSourceInfo2* pASMSourceInfo = NULL;

    if (HXR_OK == pSource->QueryInterface(IID_IHXSourceBandwidthInfo, 
            (void **)&pSBI))
    {
        pASMSourceInfo = new ASMSourceInfo2(pSource);

        m_ulNumSources++;
        m_ulNumStreams += pASMSourceInfo->StreamCount();

        m_pASMSourceInfo->AddTail((void *)pASMSourceInfo);

        HX_RELEASE(pSBI);
    }
    else
    {
        return HXR_OK;
    }

    /*
     * This variable tells us the highest amount of bandwidth that we
     * believe is useable.  If we stream thin, then the highest value
     * that the pipe can support would be the aggregate bandwidth of
     * the sources.  Barring any thinning, this would be the bandwidth
     * from prefs (unless we can determine it through fast buffering or
     * another transport feature).  This value is used when starting sources
     * as a initial guess for bandwidth (to set subscriptions).
     */
    if (m_ulSelectionBitRate == 0)
    {
        pUnknown->QueryInterface(IID_IHXPreferences, (void **)&pPreferences);

        UINT32 ulTemp = 0;
        UINT32 ulConnectionBw = 10485760; /* wild guess */

        /* Get initial bandwidth guess from Prefs */
        if ((HXR_OK == ReadPrefINT32(pPreferences, "Bandwidth", ulTemp)) &&
            (ulTemp > 0))
        {
            ulConnectionBw = ulTemp;
        }

        /*
         * m_ulSustainableBitRate refers to the max bitrate that we believe is
         * sustainable over the connection. The client should never ask
         * the server to send bits faster than this rate because it could
         * cause congestion collapse.
         *
         * m_ulSelectionBitRate refers to the highest bitrate stream that we'll
         * ever try to play. Note that people can choose to pick values
         * where m_ulSelectionBitRate > m_ulSustainableBitRate. This may
	 * cause rebuffers because the delivery will be capped at 
	 * m_ulSustainableBitRate. Why would someone do that? They may accept
	 * rebuffers if it means they get a higher quality presentation.
         */
        
        /* See if we have a sustainable bandwidth factor */
        if (HXR_OK == ReadPrefINT32(pPreferences, "SustainableBwFactor", 
                                    ulTemp))
        {
            /* clamp value to 0 <= ulTemp <= 100 range */
            if (ulTemp > 100)
            {
                ulTemp = 100;
            }
            
            /* Apply factor */
            m_ulSustainableBitRate = 
                (((ulConnectionBw / 100) * ulTemp) + 
                 (((ulConnectionBw % 100) * ulTemp) / 100));
        }
        else
        {
            m_ulSustainableBitRate = ulConnectionBw;
        }
        

        /* See if we have a selection bandwidth factor */
        if (HXR_OK == ReadPrefINT32(pPreferences, "SelectionBwFactor", 
                                    ulTemp))
        {
            /* clamp value to 0 <= ulTemp <= 200 range */
            if (ulTemp > 200)
            {
                ulTemp = 200;
            }
            
            /* Apply factor */
            m_ulSelectionBitRate  = 
                (((m_ulSustainableBitRate / 100) * ulTemp) + 
                 (((m_ulSustainableBitRate % 100) * ulTemp) / 100));
        }
        else
        {
            m_ulSelectionBitRate = m_ulSustainableBitRate; 
        }

        /* Get MaxBandwidth from Prefs */
        if (HXR_OK != ReadPrefINT32(pPreferences, "MaxBandwidth", 
                                    m_ulMaxAccelBitRate))
        {
            /* 
             * Failed to get the MaxBandwidth preference. 
             * Use m_ulSelectionBitRate value instead.
             */
            m_ulMaxAccelBitRate = m_ulSelectionBitRate;
        }

        /* 
         * Get preference that controls whether we report
         * "not enough bandwidth" conditions for on-demand clips
         */
        ReadPrefBOOL(pPreferences, "CheckOnDemandBw", m_bCheckOnDemandBw);

        HX_RELEASE(pPreferences);
    }

    return res;
}

STDMETHODIMP HXSM2::RegisterSourcesDone(THIS)
{
    CHXSimpleList::Iterator     i;
    ASMSourceInfo2*    pASMSourceInfo;

    for (i = m_pASMSourceInfo->Begin(); i != m_pASMSourceInfo->End(); ++i)
    {
	pASMSourceInfo = (ASMSourceInfo2*)(*i);
	if (pASMSourceInfo)
	{
	    pASMSourceInfo->LastSetDelivery() = 0;
	}
    }
    
    m_ulOfferToRecalc = m_ulSelectionBitRate;

    if (m_ulOfferToRecalc > m_ulMaxAccelBitRate)
    {
	m_ulOfferToRecalc = m_ulMaxAccelBitRate;
    }

    Recalc();

    return HXR_OK;
}
    
STDMETHODIMP_(BOOL) HXSM2::NotEnoughBandwidth(THIS)
{
    CHXSimpleList::Iterator i;
    ASMSourceInfo2*          pASMSourceInfo;
    UINT32		    ulTotal	= 0;
    BOOL		    bCheckTotal = m_bCheckOnDemandBw;

    for (i = m_pASMSourceInfo->Begin(); i != m_pASMSourceInfo->End(); ++i)
    {
	pASMSourceInfo = (ASMSourceInfo2*)(*i);

	ulTotal += pASMSourceInfo->SubscribeBw();

	if (pASMSourceInfo->IsLive())
	{
	    bCheckTotal = TRUE;
	}
    }

    if (bCheckTotal && ulTotal > m_ulSelectionBitRate)
    {
	return TRUE;
    }
    else
    {
	return FALSE;
    }
}

STDMETHODIMP HXSM2::UnRegisterSource(THIS_
				     HXSource* pSource)
{
    LISTPOSITION		lPos;
    ASMSourceInfo2*             pASMSourceInfo = 0;
    BOOL			bFound = FALSE;

    lPos = m_pASMSourceInfo->GetHeadPosition();

    while (lPos)
    {
	pASMSourceInfo = (ASMSourceInfo2*)m_pASMSourceInfo->GetAt(lPos);
	if (pASMSourceInfo->IsMySource(pSource))
	{
	    m_pASMSourceInfo->RemoveAt(lPos);
	    pASMSourceInfo->Done();
	    bFound  = TRUE;
	    break;
	}
	m_pASMSourceInfo->GetNext(lPos);
    }
    
    if (bFound)
    {
	m_ulNumStreams -= pASMSourceInfo->StreamCount();

	delete pASMSourceInfo;

	m_ulNumSources--;
	
	if (m_ulNumSources > 0)
	{
	    Recalc();
	}
    }

    return HXR_OK;
}

STDMETHODIMP HXSM2::ChangeAccelerationStatus(THIS_
				HXSource* pSource,
				BOOL	   bMayBeAccelerated,
				BOOL	   bUseAccelerationFactor,
				UINT32	   ulAccelerationFactor)
{

    return HXR_OK;
}

    /* Called by HXPlayer at end of each presentation */
STDMETHODIMP HXSM2::PresentationDone(THIS)
{
    return HXR_OK;
}
    
STDMETHODIMP HXSM2::ChangeBW(THIS_ 
			     UINT32 newBW, HXSource* pSource)
{
    return HXR_OK;
}

void
HXSM2::Recalc()
{
    CHXSimpleList::Iterator     i;
    ASMStreamInfoItr            streamItr(m_pASMSourceInfo);
    ASMSourceInfo2*             pASMSourceInfo;
    ASMStreamInfo2*             pASMStreamInfo;
    INT32			lAggregateBandwidthUsage = 0;
    UINT32			ulSourceCount;
    UINT32			ulStreamCount;
    float			fBiasMean = (float) 0.;

    ulSourceCount = m_pASMSourceInfo->GetCount();
    ulStreamCount = m_ulNumStreams;

    for (i = m_pASMSourceInfo->Begin(); i != m_pASMSourceInfo->End(); ++i)
    {
	pASMSourceInfo = (ASMSourceInfo2*)(*i);

        /* Init these for later */
	pASMSourceInfo->MasterOffer() = 0;
    }

    lAggregateBandwidthUsage = m_ulOfferToRecalc;

    INT32 lCorrectAggregateBandwidthUsage = lAggregateBandwidthUsage;

    /*
     * For each stream that is at a fixed bitrate, remove that bitrate
     * from our available bandwidth.
     */
    for (streamItr.Reset(); streamItr.More(); streamItr.Next())
    {
        INT32 lBias;

	pASMStreamInfo = streamItr.Stream();

	HX_VERIFY(HXR_OK == pASMStreamInfo->GetBiasFactor(lBias));
	fBiasMean += lBias;

	if (pASMStreamInfo->IsFixedBw())
	{
	    lAggregateBandwidthUsage -= pASMStreamInfo->CurrentBw();
	    ulStreamCount--;
	}

	/* Init this for later */
	pASMStreamInfo->SetStreamOffer(0);
    }

    if (ulStreamCount != 0)
    {
        /* At least 1 stream is not fixed bandwidth */

        fBiasMean /= ulStreamCount;
        
        /*
         * Calculate the offer for each source that has a master rulebook
         * defining it's bandwidth division.
         */
        INT32 lNewAggregateBandwidthUsage = lAggregateBandwidthUsage;

        for (streamItr.Reset(); streamItr.More(); streamItr.Next())
        {
            INT32 lBias;
            
            pASMStreamInfo = streamItr.Stream();
            pASMSourceInfo = streamItr.Source();
            
            HX_VERIFY(HXR_OK == pASMStreamInfo->GetBiasFactor(lBias));
            
            if (pASMSourceInfo->HasMasterRuleBook())
            {
                UINT32 ulOffer = 
                    (UINT32)(lAggregateBandwidthUsage / ulStreamCount);
                
                ulOffer += 
                    (UINT32)(((float)lBias - fBiasMean) *
                             ((float)lAggregateBandwidthUsage / 100.0) *
                             (2.0 / ulStreamCount));
                
                pASMSourceInfo->MasterOffer() += ulOffer;
                lNewAggregateBandwidthUsage -= ulOffer;
            }
        }

        lAggregateBandwidthUsage = lNewAggregateBandwidthUsage;
    }

    /*
     * For each source that has a master rule book, evaluate it to find
     * out how much to distribute to each stream.
     */
    for (i = m_pASMSourceInfo->Begin(); i != m_pASMSourceInfo->End(); ++i)
    {
	pASMSourceInfo = (ASMSourceInfo2*)(*i);
	if (pASMSourceInfo->HasMasterRuleBook())
	{
	    pASMSourceInfo->DistributeBw();
	}
    }

    /*
     *  Now go through each of the streams that are not at a
     *  fixed bitrate and try to distribute the rest of the bandwidth.
     */
    UINT32 ulTakenBandwidth = 0;

    for (streamItr.Reset(); streamItr.More(); streamItr.Next())
    {
	pASMStreamInfo = streamItr.Stream();

	if (!pASMStreamInfo->IsFixedBw())
	{
	    INT32 lBias;
	    
	    HX_VERIFY(HXR_OK == pASMStreamInfo->GetBiasFactor(lBias));
	    
	    UINT32 ulAltOffer =
		(UINT32)(lAggregateBandwidthUsage / (float)ulStreamCount);

	    ulAltOffer += (UINT32)(((float)lBias - fBiasMean) *
				   ((float)lAggregateBandwidthUsage / 100.0) *
				   (2.0 / (float)ulStreamCount));

	    pASMStreamInfo->SelectBw(streamItr.Source()->IsPerfectPlay(),
				     ulAltOffer);
	}

	ulTakenBandwidth += pASMStreamInfo->CurrentBw();
    }

    lAggregateBandwidthUsage = lCorrectAggregateBandwidthUsage;

    BOOL bDone = FALSE;
    while (!bDone && (lAggregateBandwidthUsage < (INT32)ulTakenBandwidth))
    {
	/* Resistance is Futile.  You will be Real(tm)lyAssimilated */
	UINT32 ulLowestResistance = 0xffffffff;
	ASMStreamInfo2* pLowestResistanceStream  = 0;

	// Find the stream with the lowest resistence
	for (streamItr.Reset(); streamItr.More(); streamItr.Next())
	{
	    pASMStreamInfo = streamItr.Stream();

	    if (pASMStreamInfo->ResistanceToLower() < ulLowestResistance)
	    {
		ulLowestResistance = pASMStreamInfo->ResistanceToLower();
		pLowestResistanceStream = pASMStreamInfo;
	    }
	}

	if (ulLowestResistance == 0xffffffff)
	{
	    bDone = TRUE;
	}
	else
	{
	    ulTakenBandwidth -= (UINT32)
		pLowestResistanceStream->CurrentBw();

	    pLowestResistanceStream->SelectNextLowerBw();

	    ulTakenBandwidth += (UINT32)
		pLowestResistanceStream->CurrentBw();
	}
    }

    UINT32 ulLeftOverForDropByN = lAggregateBandwidthUsage - ulTakenBandwidth;
    BOOL bForce = FALSE;

    for (streamItr.Reset(); streamItr.More(); streamItr.Next())
    {
	pASMStreamInfo = streamItr.Stream();

	UINT32 ulBw = pASMStreamInfo->CurrentBw();

	if (ulBw == 1)
	{
	    // Hack Alert for DropByN. XXXSMP
	    ulBw = ulLeftOverForDropByN;
	}

	if ((ulBw != pASMStreamInfo->GetLastBw()) &&
	    (pASMStreamInfo->IsFixedBw()))
	{
	    bForce = TRUE;
	}
	
	CHXSimpleList* pSubsChanges = 
	    streamItr.Source()->SubsChanges();

	pASMStreamInfo->SubscribeToNewBw(ulBw, pSubsChanges);
    }

    for (i = m_pASMSourceInfo->Begin(); i != m_pASMSourceInfo->End(); ++i)
    {
	pASMSourceInfo = (ASMSourceInfo2*)(*i);

	pASMSourceInfo->SubscribeToChanges();	
	pASMSourceInfo->SetDeliveryBw(m_ulSustainableBitRate);
    }
}

⌨️ 快捷键说明

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