Add even more of the source
This should be about everything needed to build so far?
This commit is contained in:
parent
af3619d4fa
commit
849723c9cf
547 changed files with 149239 additions and 0 deletions
179
Server.tproj/RTPOverbufferWindow.cpp
Normal file
179
Server.tproj/RTPOverbufferWindow.cpp
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: RTPOverbufferWindow.cpp
|
||||
|
||||
Contains: Implementation of the class
|
||||
|
||||
Written By: Denis Serenyi
|
||||
|
||||
*/
|
||||
|
||||
#include "RTPOverbufferWindow.h"
|
||||
#include "OSMemory.h"
|
||||
#include "MyAssert.h"
|
||||
|
||||
RTPOverbufferWindow::RTPOverbufferWindow(UInt32 inSendInterval, UInt32 inInitialWindowSize, UInt32 inMaxSendAheadTimeInSec,
|
||||
Float32 inOverbufferRate)
|
||||
: fWindowSize(inInitialWindowSize),
|
||||
fBytesSentSinceLastReport(0),
|
||||
fSendInterval(inSendInterval),
|
||||
fBytesDuringLastSecond(0),
|
||||
fLastSecondStart(-1),
|
||||
fBytesDuringPreviousSecond(0),
|
||||
fPreviousSecondStart(-1),
|
||||
fBytesDuringBucket(0),
|
||||
fBucketBegin(0),
|
||||
fBucketTimeAhead(0),
|
||||
fPreviousBucketTimeAhead(0),
|
||||
fMaxSendAheadTime(inMaxSendAheadTimeInSec * 1000),
|
||||
fWriteBurstBeginning(false),
|
||||
fOverbufferingEnabled(true),
|
||||
fOverbufferRate(inOverbufferRate),
|
||||
fSendAheadDurationInMsec(1000),
|
||||
fOverbufferWindowBegin(-1)
|
||||
{
|
||||
if (fSendInterval == 0)
|
||||
{
|
||||
fOverbufferingEnabled = false;
|
||||
fSendInterval = 200;
|
||||
}
|
||||
|
||||
if(fOverbufferRate < 1.0)
|
||||
fOverbufferRate = 1.0;
|
||||
|
||||
}
|
||||
|
||||
SInt64 RTPOverbufferWindow::CheckTransmitTime(const SInt64& inTransmitTime, const SInt64& inCurrentTime, SInt32 inPacketSize)
|
||||
{
|
||||
// if this is the beginning of a bucket interval, roll over figures from last time.
|
||||
// accumulate statistics over the period of a second
|
||||
if (inCurrentTime - fBucketBegin > fSendInterval)
|
||||
{
|
||||
fPreviousBucketBegin = fBucketBegin;
|
||||
fBucketBegin = inCurrentTime;
|
||||
if (fPreviousBucketBegin == 0)
|
||||
fPreviousBucketBegin = fBucketBegin - fSendInterval;
|
||||
fBytesDuringBucket = 0;
|
||||
if (inCurrentTime - fLastSecondStart > 1000)
|
||||
{
|
||||
fBytesDuringPreviousSecond = fBytesDuringLastSecond;
|
||||
fBytesDuringLastSecond = 0;
|
||||
fPreviousSecondStart = fLastSecondStart;
|
||||
fLastSecondStart = inCurrentTime;
|
||||
}
|
||||
|
||||
fPreviousBucketTimeAhead = fBucketTimeAhead;
|
||||
}
|
||||
|
||||
if (fOverbufferWindowBegin == -1)
|
||||
fOverbufferWindowBegin = inCurrentTime;
|
||||
|
||||
if ((inTransmitTime <= inCurrentTime + fSendInterval) ||
|
||||
(fOverbufferingEnabled && (inTransmitTime <= inCurrentTime + fSendInterval + fSendAheadDurationInMsec)))
|
||||
{
|
||||
//
|
||||
// If this happens, this packet needs to be sent regardless of overbuffering
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!fOverbufferingEnabled || (fWindowSize == 0))
|
||||
return inTransmitTime;
|
||||
|
||||
// if the client is running low on memory, wait a while for it to be freed up
|
||||
// there's nothing magic bout these numbers, we're just trying to be conservative
|
||||
if ((fWindowSize != -1) && (inPacketSize * 5 > fWindowSize - fBytesSentSinceLastReport))
|
||||
{
|
||||
return inCurrentTime + (fSendInterval * 5); // client reports don't come that often
|
||||
}
|
||||
|
||||
// if we're far enough ahead, then wait until it's time to send more packets
|
||||
if (inTransmitTime - inCurrentTime > fMaxSendAheadTime)
|
||||
return inTransmitTime - fMaxSendAheadTime + fSendInterval;
|
||||
|
||||
// during the first second just send packets normally
|
||||
// if (fPreviousSecondStart == -1)
|
||||
// return inCurrentTime + fSendInterval;
|
||||
|
||||
// now figure if we want to send this packet during this bucket. We have two limitations.
|
||||
// First we scale up bitrate slowly, so we should only try and send a little more than we
|
||||
// sent recently (averaged over a second or two). However, we always try and send at
|
||||
// least the current bitrate and never more than double.
|
||||
// SInt32 currentBitRate = fBytesDuringBucket * 1000 / (inCurrentTime - fPreviousBucketBegin);
|
||||
// SInt32 averageBitRate = (fBytesDuringPreviousSecond + fBytesDuringLastSecond) * 1000 / (inCurrentTime - fPreviousSecondStart);
|
||||
// SInt32 averageBitRate = fBytesDuringPreviousSecond * 1000 / (fLastSecondStart - fPreviousSecondStart);
|
||||
fBucketTimeAhead = inTransmitTime - inCurrentTime;
|
||||
// printf("Current br = %d, average br = %d (cta = %qd, pta = %qd)\n", currentBitRate, averageBitRate, currentTimeAhead, fPreviousBucketTimeAhead);
|
||||
|
||||
// always try and stay as far ahead as we were before
|
||||
if (fBucketTimeAhead < fPreviousBucketTimeAhead)
|
||||
return -1;
|
||||
|
||||
// but don't send at more that double the bitrate (for any given time we should only get further
|
||||
// ahead by that amount of time)
|
||||
//printf("cta - pta = %qd, ct - pbb = %qd\n", fBucketTimeAhead - fPreviousBucketTimeAhead, SInt64((inCurrentTime - fPreviousBucketBegin) * (fOverbufferRate - 1.0)));
|
||||
if (fBucketTimeAhead - fPreviousBucketTimeAhead > ((inCurrentTime - fPreviousBucketBegin) * (fOverbufferRate - 1.0)))
|
||||
{
|
||||
fBucketTimeAhead = fPreviousBucketTimeAhead + SInt64((inCurrentTime - fPreviousBucketBegin) * (fOverbufferRate - 1.0));
|
||||
return inCurrentTime + fSendInterval; // this will get us to the next bucket
|
||||
}
|
||||
|
||||
// don't send more than 10% over the average bitrate for the previous second
|
||||
// if (currentBitRate > averageBitRate * 11 / 10)
|
||||
// return inCurrentTime + fSendInterval; // this will get us to the next bucket
|
||||
|
||||
return -1; // send this packet
|
||||
}
|
||||
|
||||
void RTPOverbufferWindow::ResetOverBufferWindow()
|
||||
{
|
||||
fBytesDuringLastSecond = 0;
|
||||
fLastSecondStart = -1;
|
||||
fBytesDuringPreviousSecond = 0;
|
||||
fPreviousSecondStart = -1;
|
||||
fBytesDuringBucket = 0;
|
||||
fBucketBegin = 0;
|
||||
fBucketTimeAhead = 0;
|
||||
fPreviousBucketTimeAhead = 0;
|
||||
fOverbufferWindowBegin = -1;
|
||||
}
|
||||
|
||||
void RTPOverbufferWindow::AddPacketToWindow(SInt32 inPacketSize)
|
||||
{
|
||||
fBytesDuringBucket += inPacketSize;
|
||||
fBytesDuringLastSecond += inPacketSize;
|
||||
fBytesSentSinceLastReport += inPacketSize;
|
||||
}
|
||||
|
||||
void RTPOverbufferWindow::EmptyOutWindow(const SInt64& inCurrentTime)
|
||||
{
|
||||
// no longer needed
|
||||
}
|
||||
|
||||
void RTPOverbufferWindow::SetWindowSize(UInt32 inWindowSizeInBytes)
|
||||
{
|
||||
fWindowSize = inWindowSizeInBytes;
|
||||
fBytesSentSinceLastReport = 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue