|
|
/*----------------------------------------------------------------------------
* File: RTCPTIME.C * Product: RTP/RTCP implementation * Description: Provides timers related functions for RTCP. * * INTEL Corporation Proprietary Information * This listing is supplied under the terms of a license agreement with * Intel Corporation and may not be copied nor disclosed except in * accordance with the terms of that agreement. * Copyright (c) 1995 Intel Corporation. *--------------------------------------------------------------------------*/
#include "rrcm.h"
/*---------------------------------------------------------------------------
/ Global Variables /--------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
/ External Variables /--------------------------------------------------------------------------*/ extern PRTCP_CONTEXT pRTCPContext; #ifdef _DEBUG
extern char debug_string[]; #endif
/*----------------------------------------------------------------------------
* Function : RTCPxmitInterval * Description: Calculate the RTCP transmission interval * * Input : members: Estimated number of session members including * ourselves. On the initial call, should be 1. * * senders: Number of active senders since last report, known from * construction of receiver reports for this packet. * Includes ourselves if we sent. * * rtcpBw: The target RTCP bandwidth, ie, the total Bw that will * be used by RTCP by all members of this session, in * bytes per seconds. Should be 5% of the session Bw. * * weSent: True if we've sent data during the last two RTCP * intervals. If TRUE, the compound RTCP packet just * sent contained an SR packet. * * packetSize: Size of the RTCP packet just sent, in bytes, including * network encapsulation, eg 28 bytes for UDP over IP. * * *avgRtcpSize: Estimator to RTCP packet size, initialized and * updated by this function for the packet just sent. * * initial: Initial transmission flag. * * Return: Interval time before the next transmission in msec. ---------------------------------------------------------------------------*/ DWORD RTCPxmitInterval (DWORD members, DWORD senders, DWORD rtcpBw, DWORD weSent, DWORD packetSize, int *avgRtcpSize, DWORD initial) { #ifdef ENABLE_FLOATING_POINT
// // Minimum time between RTCP packets from this site in seconds. This time
// // prevents the reports from clumping when sessions are small and the law
// // of large numbers isn't helping to smooth out the traffic. It also keeps
// // the report intervals from becoming ridiculously small during transient
// // outages like a network partition.
// double const RTCP_MinTime = 5.;
//
// // Fraction of the RTCP bandwidth to be shared among active senders. This
// // fraction was chosen so that in a typical session with one or two active
// // senders, the computed report time would be roughly equal to the minimum
// // report time so that we don't unnecessarily slow down receiver reports.
// // The receiver fraction must be 1 - the sender fraction.
// double const RTCP_SenderBwFraction = 0.25;
// double const RTCP_RcvrBwFraction = (1 - RTCP_SenderBwFraction);
//
// // Gain (smoothing constant) for the low-pass filter that estimates the
// // average RTCP packet size.
// double const RTCP_sizeGain = RTCP_SIZE_GAIN;
//
// // Interval
// double t = 0;
// double rtcp_min_time = RTCP_MinTime;
//
// // Number of member for computation
// unsigned int n;
// int tmpSize;
//
// // Random number
// double randNum;
//
// // Very first call at application start-up uses half the min delay for
// // quicker notification while still allowing some time before reporting
// // for randomization and to learn about other sources so the report
// // interval will converge to the correct interval more quickly. The
// // average RTCP size is initialized to 128 octects which is conservative.
// // It assumes everyone else is generating SRs instead of RRs:
// // 20 IP + 8 UDP + 52 SR + 48 SDES CNAME
// if (initial)
// {
// rtcp_min_time /= 2;
// *avgRtcpSize = 128;
// }
//
// // If there were active senders, give them at least a minimum share of the
// // RTCP bandwidth. Otherwise all participants share the RTCP Bw equally.
// n = members;
// if (senders > 0 && (senders < (members * RTCP_SenderBwFraction)))
// {
// if (weSent)
// {
// rtcpBw *= RTCP_SenderBwFraction;
// n = senders;
// }
// else
// {
// rtcpBw *= RTCP_RcvrBwFraction;
// n -= senders;
// }
// }
//
// // Update the average size estimate by the size of the report packet we
// // just sent out.
// tmpSize = packetSize - *avgRtcpSize;
// tmpSize = (int)(tmpSize * RTCP_sizeGain);
// *avgRtcpSize += tmpSize;
//
// // The effective number of sites times the average packet size is the
// // total number of octets sent when each site sends a report. Dividing
// // this by the effective bandwidth gives the time interval over which
// // those packets must be sent in order to meet the bandwidth target,
// // with a minimum enforced. In that time interval we send one report so
// // this time is also our average time between reports.
// t = (*avgRtcpSize) * n / rtcpBw;
//
// if (t < rtcp_min_time)
// t = rtcp_min_time;
//
// // To avoid traffic burst from unintended synchronization with other sites
// // we then pick our actual next report interval as a random number
// // uniformely distributed between 0.5*t and 1.5*t.
//
// // Get a random number between 0 and 1
// // rand() gives a number between 0-32767.
// randNum = RRCMrand() % 32767;
// randNum /= 32767.0;
//
// // return timeout in msec
// return (t * (randNum + 0.5) * 1000);
#else
// Minimum time between RTCP packets from this site in Msec. This time
// prevents the reports from clumping when sessions are small and the law
// of large numbers isn't helping to smooth out the traffic. It also keeps
// the report intervals from becoming ridiculously small during transient
// outages like a network partition.
int RTCP_MinTime = 5000;
// Interval
int t = 0; int rtcp_min_time = RTCP_MinTime;
// Number of member for computation
unsigned int n; int tmpSize;
// Random number
int randNum;
// Very first call at application start-up uses half the min delay for
// quicker notification while still allowing some time before reporting
// for randomization and to learn about other sources so the report
// interval will converge to the correct interval more quickly. The
// average RTCP size is initialized to 128 octects which is conservative.
// It assumes everyone else is generating SRs instead of RRs:
// 20 IP + 8 UDP + 52 SR + 48 SDES CNAME
if (initial) { rtcp_min_time /= 2; *avgRtcpSize = 128; }
// If there were active senders, give them at least a minimum share of the
// RTCP bandwidth. Otherwise all participants share the RTCP Bw equally.
n = members;
// Only a quart of the bandwidth (=> /4). Check above with floatting point
if (senders > 0 && (senders < (members / 4))) { if (weSent) { // Only a quart of the bandwidth for the sender
rtcpBw /= 4; n = senders; } else { // 3/4 of the bandwidth for the receiver
rtcpBw = (3*rtcpBw)/4; n -= senders; } }
// Update the average size estimate by the size of the report packet we
// just sent out.
tmpSize = packetSize - *avgRtcpSize; tmpSize = (tmpSize+8) / 16; *avgRtcpSize += tmpSize;
// The effective number of sites times the average packet size is the
// total number of octets sent when each site sends a report. Dividing
// this by the effective bandwidth gives the time interval over which
// those packets must be sent in order to meet the bandwidth target,
// with a minimum enforced. In that time interval we send one report so
// this time is also our average time between reports.
if (rtcpBw) t = (*avgRtcpSize) * n / rtcpBw;
if (t < rtcp_min_time) t = rtcp_min_time;
// To avoid traffic burst from unintended synchronization with other sites
// we then pick our actual next report interval as a random number
// uniformely distributed between 0.5*t and 1.5*t.
// Get a random number between 0 and 1
// In order to avoid floating point operation, get a number between
// 0 and 1000, i.e. converted in Msec already. Add 500 Msec instead of
// 0.5 to the random number
randNum = RRCMrand() % 1000;
return ((t * (randNum + 500))/1000); #endif
}
// [EOF]
|