📄 hxsm.cpp
字号:
for (i = m_pASMSourceInfo->Begin(); i != m_pASMSourceInfo->End(); ++i)
{
pASMSourceInfo = (ASMSourceInfo*)(*i);
if (pASMSourceInfo->m_ulLastSetDelivery == 0xffffffff)
{
pASMSourceInfo->m_ulLastSetDelivery = pASMSourceInfo->m_ulSubscribedBw;
}
// if ANY of the sources are fast start then we are in
// fast start mode. We may wish to re-visit this decision!
// this comment is for you Rahul!
if (pASMSourceInfo && pASMSourceInfo->m_pSource)
{
bFastStart = bFastStart | pASMSourceInfo->m_pSource->m_bFastStart;
}
ulNumBehindSources += pASMSourceInfo->m_bBehind ? 1 : 0;
ulNumSlightlyBehindSources += pASMSourceInfo->m_bSlightlyBehind ? 1 : 0;
lAggregateBandwidthUsage += pASMSourceInfo->GetBandwidth();
if (!pASMSourceInfo->GetBandwidth())
lAggregateBandwidthUsage += pASMSourceInfo->m_ulSubscribedBw;
else
bAllZeroBw = FALSE;
ulMaxNeededBW += pASMSourceInfo->m_ulMaxSubscribedBw;
}
// so if we are in fast start, let's check to see if we don't want to be in
// fast start!
double maxPossibleAccelRatio = 0.;
if (ulMaxNeededBW > 0.)
{
maxPossibleAccelRatio = (double) m_ulOriginalHighestBandwidthAvail / (double) ulMaxNeededBW;
}
for (i = m_pASMSourceInfo->Begin(); i != m_pASMSourceInfo->End(); ++i)
{
pASMSourceInfo = (ASMSourceInfo*)(*i);
// I could check here for pASMSourceInfo->m_pSource->m_bFastStart, but really
// does it matter?
if (pASMSourceInfo && pASMSourceInfo->m_pSource)
{
pASMSourceInfo->m_pSource->SetMaxPossibleAccelRatio(maxPossibleAccelRatio);
}
// turn this stuff of if we are on modem. *sigh* It probably sort of works on
// modems too. This value makes it work on ISDN, that's ok by me, but if people
// don't like it, I can change it.
if (maxPossibleAccelRatio < 1.5 ||
(m_ulOriginalHighestBandwidthAvail < 110000)) // it now works on DSL or higher
{
bFastStart = FALSE;
if (pASMSourceInfo->m_pSource->m_bFastStart)
{
DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,"(%p)ASM %d - Leaving TurboPlay", pASMSourceInfo->m_pSource, __LINE__));
pASMSourceInfo->m_pSource->LeaveFastStart(TP_OFF_BY_NOTENOUGHBW);
}
}
// Are we currently asking for less than max? Is so Disable!
//
// XXX HP I am not sure the following logic is valid, it's possible
// pASMSourceInfo->m_ulSubscribedBw < pASMSourceInfo->m_ulMaxSubscribedBw because the
// master rulebook defines so even though we have plenty of bandwidth(i.e. maxPossibleAccelRatio > 1.5)
// If it's really the case that the source doesn't subscribe to its max. bandwidth because
// we don't have enough bandwidth, then maxPossibleAccelRatio < 1.5 and we should left faststart
// already
/*
if (pASMSourceInfo && pASMSourceInfo->GetBandwidth() && pASMSourceInfo->m_ulMaxSubscribedBw != pASMSourceInfo->m_ulSubscribedBw
&& pASMSourceInfo->m_pSource->m_bFastStart)
{
DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,"ASM %d - Leaving TurboPlay", __LINE__));
DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,"%d %d %d", pASMSourceInfo->m_ulMaxSubscribedBw, pASMSourceInfo->GetBandwidth(),pASMSourceInfo->m_ulSubscribedBw));
pASMSourceInfo->m_pSource->LeaveFastStart();
}
*/
}
if (m_bPipeFull == TRUE)
{
/*
* Adjust the highest available bandwidth because we have found
* the maximum bandwidth that the pipe can handle. We do this
* so that sources that get added in the future will have
* some information about the max. bandwidth that exists. This
* value is aggresive because a source will want to consume everything
* it can and fall back if it goes over the top.
*/
HX_ASSERT(lAggregateBandwidthUsage >= 100);
if (lAggregateBandwidthUsage < 100)
{
/*
* Please have at *least* 100bps before attempting to
* run the RealPlayer.
*/
lAggregateBandwidthUsage = 100;
}
m_ulHighestBandwidthAvail = (UINT32)(lAggregateBandwidthUsage);
m_ulPeakUsedBandwidth = (UINT32)(lAggregateBandwidthUsage);
m_bInitialHighBwAvail = FALSE;
m_bPipeFull = FALSE;
}
if (m_State == REDIST)
{
m_State = REDO_ACCEL;
m_ulOfferToRecalc = m_ulHighestBandwidthAvail;
Recalc();
return;
}
if ((m_State == REDO_ACCEL) || (m_State == INIT_REDIST))
{
UINT32 ulBigValue;
if ((m_bInitialHighBwAvail) || (m_State == REDO_ACCEL))
{
ulBigValue = m_ulPeakUsedBandwidth;
if (bFastStart && (m_State == INIT_REDIST))
{
ulBigValue = m_ulMaxAccelBitRate;
}
else if ((INT32)ulBigValue > lAggregateBandwidthUsage)
{
ulBigValue = lAggregateBandwidthUsage;
}
}
else
{
/*
* If your state is REDO_ACCEL & we have an imperical value
* then maybe we should use this (ABU) instead of the above,
* but this value may not be completely up to date?
*/
ulBigValue = lAggregateBandwidthUsage;
}
HX_ASSERT(ulBigValue > 0); // Rahul's Crazy, This won't ever happen!
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)(ulBigValue));
if ((HXR_OK == pASMSourceInfo->m_pSource->
QueryInterface(IID_IHXThinnableSource, (void **)&pThin)))
{
if ((ulNewValue > (pASMSourceInfo->m_ulLastSetDelivery * 1.02)) ||
(ulNewValue < (pASMSourceInfo->m_ulLastSetDelivery * 0.98)) ||
(pASMSourceInfo->m_bAdjustBandwidth && pASMSourceInfo->m_pSource->IsLive()))
{
BOOL bFastStart = FALSE;
if (pASMSourceInfo && pASMSourceInfo->m_pSource)
{
bFastStart = pASMSourceInfo->m_pSource->m_bFastStart;
}
if (bFastStart)
{
if (ulNewValue > (pASMSourceInfo->m_ulMaxSubscribedBw * m_fAccelerationFactor))
{
ulNewValue = (UINT32)
(pASMSourceInfo->m_ulMaxSubscribedBw * m_fAccelerationFactor);
}
// if the server says to cap the value, we cap the value!
if (pASMSourceInfo && pASMSourceInfo->m_pSource && ulNewValue > pASMSourceInfo->m_pSource->m_ulMaxBandwidth * 1000 )
{
ulNewValue = pASMSourceInfo->m_pSource->m_ulMaxBandwidth * 1000;
}
// if the value is greater is than the pipe set it to a
// little less than the pipe!
if (ulNewValue > m_ulOriginalHighestBandwidthAvail)
{
ulNewValue = m_ulOriginalHighestBandwidthAvail;
}
}
else
{
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);
}
}
pASMSourceInfo->m_bAdjustBandwidth = FALSE;
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 ((ulNewValue < ulSourceBandwidth) && (ulSourceBandwidth > 10))
{
pASMSourceInfo->m_pSource->EnterBufferedPlay();
}
if (ulNewValue >= ulSourceBandwidth)
{
pASMSourceInfo->m_pSource->LeaveBufferedPlay();
}
if ((ulNewValue >= pASMSourceInfo->m_ulLastSetDelivery) &&
(!pASMSourceInfo->m_bMayBeAccelerated) &&
(!pASMSourceInfo->m_bTryToUpShift))
{
goto dont_actually_set_the_rate;
}
if (ulNewValue > m_ulResistanceBitRate && !bFastStart)
{
UINT32 ulActualResistanceBitRate = m_ulResistanceBitRate;
if (ulActualResistanceBitRate < ulAggregateUsed)
{
ulActualResistanceBitRate = (UINT32)
(ulAggregateUsed * 1.05);
}
if (ulNewValue > ulActualResistanceBitRate)
{
ulNewValue = ulActualResistanceBitRate;
}
}
if(pASMSourceInfo->m_bTryToUpShift)
{
pASMSourceInfo->m_bTryToUpShift=FALSE;
//XXXRA why not check for ulNewValue < ((UINT32)(ulSourceBandwidth * 1.15)
// before assignment.
ulNewValue = (UINT32)(ulSourceBandwidth * 1.15);
}
pASMSourceInfo->m_ulLastSetDelivery = 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));
}
DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s, "(%p)Redist: Tranmission Rate to %d", pASMSourceInfo->m_pSource, ulActualRate));
if (m_bEnableSDB)
{
pThin->SetDeliveryBandwidth(ulActualRate, 0);
}
if (bFastStart)
{
pASMSourceInfo->m_pSource->m_turboPlayStats.ulAcceleratedBW = ulActualRate;
}
}
}
dont_actually_set_the_rate:
HX_RELEASE(pThin);
}
m_State = HX_NONE;
return;
}
if (m_State == CHILL_BUFFERING)
{
m_ulOfferToRecalc = lAggregateBandwidthUsage;
#ifdef MOREDEBUG
DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,
"CHILL to Recalc() %d", m_ulOfferToRecalc));
#endif
m_State = HX_NONE;
Recalc();
}
if ((ulNumBehindSources) ||
((lAggregateBandwidthUsage > ((INT32)m_ulMaxAccelBitRate + 100)) &&
(bAllZeroBw)))
{
if ((lAggregateBandwidthUsage > (INT32)m_ulMaxAccelBitRate) &&
(bAllZeroBw))
{
lAggregateBandwidthUsage = m_ulMaxAccelBitRate;
}
// XXXRA change m_ulNumReportsSinceUpShift to m_lNumReportsSinceUpShift
m_ulNumReportsSinceUpShift = -2;
UINT32 ulLow = (UINT32)(m_ulLastStableBandwidth * 0.90);
UINT32 ulHigh = (UINT32)(m_ulLastStableBandwidth * 1.10);
/*
* XXXSMP Maybe we don't want to use stable point when the aggregate
* detected is more then the stable point?
*/
if ((lAggregateBandwidthUsage > (INT32)ulLow) &&
(lAggregateBandwidthUsage < (INT32)ulHigh))
{
/*
* If we are close to the last stable bandwidth, then let's
* try that one again.
*/
lAggregateBandwidthUsage = m_ulLastStableBandwidth;
#ifdef MOREDEBUG
DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,
"Used Stable Point %d", m_ulLastStableBandwidth));
#endif
m_ulLastStableBandwidth = 0;
m_ulUpShiftTestPointScaleFactor = MAX(1500,
(UINT32)(m_ulUpShiftTestPointScaleFactor * 0.85));
}
if (m_State != CONGESTION)
{
for (i = m_pASMSourceInfo->Begin(); i != m_pASMSourceInfo->End(); ++i)
{
pASMSourceInfo = (ASMSourceInfo*)(*i);
UINT32 ulSourceBandwidth = pASMSourceInfo->m_ulSubscribedBw;
UINT32 ulNewValue =
(UINT32)(
(float)ulSourceBandwidth /
(float)ulAggregateUsed *
(float)lAggregateBandwidthUsage * 0.97);
if (ulNewValue < (pASMSourceInfo->m_ulSubscribedBw))
{
// Attempt ASM Switching to reduce bandwidth usage.
m_State = CONGESTION;
m_ulOfferToRecalc = (UINT32)
(lAggregateBandwidthUsage * 0.97);
#ifdef MOREDEBUG
DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,
"CONGESTION to Recalc() %d", m_ulOfferToRecalc));
#endif
// once again, if we are in start start mode we need to
// turn it off. It may be off already, but I just want to
// make sure.
if (pASMSourceInfo->m_pSource->m_bFastStart)
{
DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,"(%p)ASM %d - Leaving TurboPlay", pASMSourceInfo->m_pSource, __LINE__));
pASMSourceInfo->m_pSource->LeaveFastStart(TP_OFF_BY_NETCONGESTION);
}
Recalc();
return;
}
}
m_State = CONGESTION;
RecalcAccel();
return;
} //m_State != CONGESTION
else
{
BOOL bLossBehind = FALSE;
m_State = HX_NONE;
UINT32 ulTotalBandwidth = 0;
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)lAggregateBandwidthUsage * 0.70);
if (ulNewValue < ulSourceBandwidth)
{
/* Can't be conservative, so go use what we need */
ulNewValue =
(UINT32)(
(float)ulSourceBandwidth /
(float)ulAggregateUsed *
(float)lAggregateBandwidthUsage * 0.97);
// once again, if we are in start start mode we need to
// turn it off. It may be off already, but I just want to
// make sure.
if (pASMSourceInfo->m_pSource->m_bFastStart)
{
DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,"(%p)ASM %d - Leaving TurboPlay", pASMSourceInfo->m_pSource, __LINE__));
pASMSourceInfo->m_pSource->LeaveFastStart(TP_OFF_BY_NETCONGESTION);
}
}
if (pASMSourceInfo->m_bLossBehind &&
(ulNewValue < ulSourceBandwidth))
{
DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s,
"(%p)No Loss Reduce: Will Force BP", pASMSourceInfo->m_pSource));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -