adjustTargetDelay=newTargetDelay;
}
if(adjustedFreeBuffer>maxUsableBufferSizeBytes)
adjustedFreeBuffer=maxUsableBufferSizeBytes;
UInt32freeBytes=fBufferSize-bufferUsage;
if(freeBytes>fBufferSize)
bufferUsage=maxUsableBufferSizeBytes/2;
DEBUG_PRINTF(("ADJUSTINGbufferusageandtargetdelay:
maxUsableBufferSizeBytes=%lu
adjustedFreeBuffer=%lubufferUsage=%luadjustedTargetDelay=%lu\n",maxUsableBufferSizeBytes,
adjustedFreeBuffer,bufferUsage,adjustTargetDelay));
}
DEBUG_PRINTF(("CalculatedmaxUsableBufferSize=%"_U32BITARG_"reported
fBufferSize=%"_U32BITARG_"reportedbufferdelay=%"_U32BITARG_"currentcalculatedbufferUsage=
%"_U32BITARG_"\n",maxUsableBufferSizeBytes,fBufferSize,bufferDelay,bufferUsage));
//bufferDelayshouldreallybethenetworkdelaybecauseifbufferdelaywerereallylargethat
wouldbeok
//itissupposedtobe-1ifnotsupportedorarealvalue.Someclientssend0incorrectly.
//ifbufferdelayissmallthatshouldmeanthebufferisemptyandaunder-runfailure
occurred.
if(bufferDelay==0)
bufferDelay=kUInt32_Max;
doublebufferUsageRatio=static_cast(bufferUsage)/maxUsableBufferSizeBytes;
doublebufferDelayRatio=static_cast(bufferDelay)/adjustTargetDelay;
DEBUG_PRINTF(("bufferUsageRatio=%fbufferDelayRatio=%f\n",bufferUsageRatio,
bufferDelayRatio));
if(!
fStartDoingAdaptation)
{
//ThisisusedtopreventQTSSfromthinninginthebeginningofthestream,whenthebuffering
delayandusageareexpectedtobelowRateadaptationwillstartwhenEITHERofthetwolow
watermarksforthinninghavepassed,ORthemediahasbeenplayingforthetargetbufferingdelay.
Theidealsituationforthecurrentcodeis2xormorebuffersizetotargettime.Sotargettime
convertedtobytesshouldbe50%orlessthebuffersizetoavoidoverrunthisoneisagressiveand
workswellwithNokiawhenallisgoodandthereisextrabandwidthsoitmakesagoodnetworklook
good.
if(bufferUsageRatio>=0.7)//startactiverateadaptwhenclientis70%full
{fStartDoingAdaptation=true;/*qtss_printf("bufferusage\n");*/}
elseif(curTime-fRTPStream.GetSession().GetFirstPlayTime()>=15000)//butdon'twait
longerthan15seconds
{fStartDoingAdaptation=true;}
else//neithercriteriawasmet.//speedupwhilewaitingforthebuffertofill.
{fAdjustTime=kAdjustUpUp;
}
if(fStartDoingAdaptation)
{fNumLargeRTT=0;
fNumSmallRTT=-3;//Delaythefirstrateincrease
}
}
if(fStartDoingAdaptation)
{
SInt32currentQualityLevel=fRTPStream.GetQualityLevel();
if(currentQualityLevel>(fRTPStream.GetNumQualityLevels()*0.75)||currentQualityLevel<1)
{
fRTPStream.SetQualityLevel(20);
}
//newcodeworksgoodforNokiaN93onwifiandokforslowlinks(needssomemorecomparison
testingagainstnonrateadaptcodeandagainstbuild520orearlier)
if(bufferDelay!
=kUInt32_Max)//notsupported
{
DEBUG_PRINTF(("rateadaptisusingdelayratioandbuffersize\n\n"));
//Thebufferingdelayinformationisavailable.
//shouldIspeeduporslowdown?
ADelayRatioof100%isatargetnotaminimumandnotamaximum.
if(bufferDelayRatio<2.0)//allowupto200%
fAdjustTime=kAdjustUpUp;
else
fAdjustTime=kAdjustDown;
if(bufferUsageRatio>=0.7)//ifyouareindangerofbuffer-overflowingbecausethe
buffersizeistoosmallforthemovie,alsoslow
fAdjustTime=kAdjustDown;
elseif(bufferUsageRatio<0.5&&bufferDelayRatio>2.5)//stoppushing.
fAdjustTime=kAdjustDownDown;
elseif(bufferUsageRatio<0.5&&bufferDelayRatio>2.0)//stoppushing.
fAdjustTime=kAdjustDown;
elseif(bufferUsageRatio<0.5&&bufferDelayRatio>0.5)//trytopushuphard.
{fAdjustTime=kAdjustUpUp;
fAdjustSize=kAdjustUp;
}
//shouldIthinorthicken?
if(bufferUsageRatio<0.2&&bufferDelayRatio>2.5)//avoidunderflowsincethe
bandwidthislow.
{fAdjustSize=kAdjustDown;
fAdjustTime=kAdjustUpUp;
}
elseif(bufferUsageRatio<=0.1)//trythickening
{fAdjustSize=kAdjustUpUp;
fAdjustTime=kAdjustUpUp;
}
elseif(bufferUsageRatio<=0.3&&bufferDelayRatio<1.0)//stillindangerofunderflow
fAdjustSize=kNoChange;
elseif(bufferUsageRatio<0.7)//nolongerindangerofunderflow;oktothick
fAdjustSize=kAdjustUp;
else
fAdjustSize=kNoChange;
}
else
{
DEBUG_PRINTF(("rateadaptisusingonlybuffersize\n"));
//Thebufferingdelayisnotavailable;wemakethin/slowdecisionsbasedonjustthe
bufferusagealone
if(bufferUsageRatio>0.9)//needtoslowandthintoavoidoverflow
{
fAdj