Darwin-Streaming-Server/Server.tproj/RTPBandwidthTracker.h
Darren VanBuren 849723c9cf Add even more of the source
This should be about everything needed to build so far?
2017-03-07 17:14:16 -08:00

173 lines
7.3 KiB
C++

/*
*
* @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: RTPBandwidthTracker.h
Contains: Uses Karns Algorithm to measure round trip times. This also
tracks the current window size based on input from the caller.
ref:
Improving Round-Trip Time Estimates in Reliable Transport Protocols, ACM SIGCOMM, ???
Congestion Avoidance and Control - Van Jacobson, November 1988 -- Preoceedings of SIGCOMM '88
Internetworking with TCP/IP Comer and Stevens, Chap 14, prentice hall 1991
*/
#ifndef __RTP_BANDWIDTH_TRACKER_H__
#define __RTP_BANDWIDTH_TRACKER_H__
#include "OSHeaders.h"
class RTPBandwidthTracker
{
public:
RTPBandwidthTracker(Bool16 inUseSlowStart)
: fRunningAverageMSecs(0),
fRunningMeanDevationMSecs(0),
fCurRetransmitTimeout( kMinRetransmitIntervalMSecs ),
fUnadjustedRTO( kMinRetransmitIntervalMSecs ),
fCongestionWindow(kMaximumSegmentSize),
fSlowStartThreshold(0),
fSlowStartByteCount(0),
fClientWindow(0),
fBytesInList(0),
fAckTimeout(kMinAckTimeout),
fUseSlowStart(inUseSlowStart),
fMaxCongestionWindowSize(0),
fMinCongestionWindowSize(1000000),
fMaxRTO(0),
fMinRTO(24000),
fTotalCongestionWindowSize(0),
fTotalRTO(0),
fNumStatsSamples(0)
{}
~RTPBandwidthTracker() {}
//
// Initialization - give the client's window size.
void SetWindowSize(SInt32 clientWindowSize);
//
// Each RTT sample you get, let the tracker know what it is
// so it can keep a good running average.
void AddToRTTEstimate( SInt32 rttSampleMSecs );
//
// Before sending new data, let the tracker know
// how much data you are sending so it can adjust the window.
void FillWindow(UInt32 inNumBytes)
{ fBytesInList += inNumBytes; fIsRetransmitting = false; }
//
// When data is acked, let the tracker know how much
// data was acked so it can adjust the window
void EmptyWindow(UInt32 inNumBytes, Bool16 updateBytesInList = true);
//
// When retransmitting a packet, call this function so
// the tracker can adjust the window sizes and back off.
void AdjustWindowForRetransmit();
//
// ACCESSORS
const Bool16 ReadyForAckProcessing() { return (fClientWindow > 0 && fCongestionWindow > 0); } // see RTPBandwidthTracker::EmptyWindow for requirements
const Bool16 IsFlowControlled() { return ( (SInt32)fBytesInList >= fCongestionWindow ); }
const SInt32 ClientWindowSize() { return fClientWindow; }
const UInt32 BytesInList() { return fBytesInList; }
const SInt32 CongestionWindow() { return fCongestionWindow; }
const SInt32 SlowStartThreshold() { return fSlowStartThreshold; }
const SInt32 RunningAverageMSecs() { return fRunningAverageMSecs / 8; } // fRunningAverageMSecs is stored scaled up 8x
const SInt32 RunningMeanDevationMSecs() { return fRunningMeanDevationMSecs/ 4; } // fRunningMeanDevationMSecs is stored scaled up 4x
const SInt32 CurRetransmitTimeout() { return fCurRetransmitTimeout; }
const SInt32 GetCurrentBandwidthInBps()
{ return (fUnadjustedRTO > 0) ? (fCongestionWindow * 1000) / fUnadjustedRTO : 0; }
inline const UInt32 RecommendedClientAckTimeout() { return fAckTimeout; }
void UpdateAckTimeout(UInt32 bitsSentInInterval, SInt64 intervalLengthInMsec);
void UpdateStats();
//
// Stats
SInt32 GetMaxCongestionWindowSize() { return fMaxCongestionWindowSize; }
SInt32 GetMinCongestionWindowSize() { return fMinCongestionWindowSize; }
SInt32 GetAvgCongestionWindowSize() { return (SInt32)(fTotalCongestionWindowSize / (SInt64)fNumStatsSamples); }
SInt32 GetMaxRTO() { return fMaxRTO; }
SInt32 GetMinRTO() { return fMinRTO; }
SInt32 GetAvgRTO() { return (SInt32)(fTotalRTO / (SInt64)fNumStatsSamples); }
enum
{
kMaximumSegmentSize = 1466, // enet - just a guess!
//
// Our algorithm for telling the client what the ack timeout
// is currently not too sophisticated. This could probably be made
// better. During slow start, we just use 20, and afterwards, just use 100
kMinAckTimeout = 20,
kMaxAckTimeout = 100
};
private:
//
// For computing the round-trip estimate using Karn's algorithm
SInt32 fRunningAverageMSecs;
SInt32 fRunningMeanDevationMSecs;
SInt32 fCurRetransmitTimeout;
SInt32 fUnadjustedRTO;
//
// Tracking our window sizes
SInt64 fLastCongestionAdjust;
SInt32 fCongestionWindow; // implentation of VJ congestion avoidance
SInt32 fSlowStartThreshold; // point at which we stop adding to the window for each ack, and add to the window for each window full of acks
SInt32 fSlowStartByteCount; // counts window a full of acks when past ss thresh
SInt32 fClientWindow; // max window size based on client UDP buffer
UInt32 fBytesInList; // how many unacked bytes on this stream
UInt32 fAckTimeout;
Bool16 fUseSlowStart;
Bool16 fIsRetransmitting; // are we in the re-transmit 'state' ( started resending, but have yet to send 'new' data
//
// Stats
SInt32 fMaxCongestionWindowSize;
SInt32 fMinCongestionWindowSize;
SInt32 fMaxRTO;
SInt32 fMinRTO;
SInt64 fTotalCongestionWindowSize;
SInt64 fTotalRTO;
SInt32 fNumStatsSamples;
enum
{
kMinRetransmitIntervalMSecs = 600,
kMaxRetransmitIntervalMSecs = 24000
};
};
#endif // __RTP_BANDWIDTH_TRACKER_H__