www.pudn.com > streamrtp.rar > rtcpinterval.c


/*-------------------------------------------------------------------------
 * rtcpinterval.c - rtcpinitinterval, rtcpinterval
 *-------------------------------------------------------------------------
 */

#include 
#include 
#include 
#include 

/*------------------------------------------------------------------------
 * rtcpinitinterval - compute initial rtcp interval
 *------------------------------------------------------------------------
 */
double
rtcpinitinterval(struct session *sp)
{
	return rtcpinterval(1, 0, sp->sn_bw * RTCP_BWFRAC, FALSE, 0, &sp->sn_avgrtcp, TRUE);
}

/*------------------------------------------------------------------------
 * rtcpinterval - compute seconds until next RTCP cycle.
 * Code from RFC 1889.
 *------------------------------------------------------------------------
 */
double
rtcpinterval(int members,
	     int senders,
	     double rtcp_bw,
	     int we_sent,
	     int packet_size,
	     int *avg_rtcp_size,
	     int initial)
{
	/*
	 * 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 interval from
	 * becoming ridiculously small during transient outages like a
	 * network partition.
	 */
	double const RTCP_MIN_TIME = 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_SENDER_BW_FRACTION = 0.25;
	double const RTCP_RCVR_BW_FRACTION = (1-RTCP_SENDER_BW_FRACTION);
	/*
	 * Gain (smoothing constant) for the low-pass filter that
	 * estimates the average RTCP packet size (see Cadzow reference).
	 */
	double const RTCP_SIZE_GAIN = (1./16.);
  
	double t;                   /* interval */
	double rtcp_min_time = RTCP_MIN_TIME;
	int n;                      /* no. of members for computation */
  
	/*
	 * 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 octets 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;
		*avg_rtcp_size = 128;
	}
  
	/*
	 * If there were active senders, give them at least a minimum
	 * share of the RTCP bandwidth.  Otherwise all participants share
	 * the RTCP bandwidth equally.
	 */
	n = members;
	if (senders > 0 && senders < members * RTCP_SENDER_BW_FRACTION) {
		if (we_sent) {
			rtcp_bw *= RTCP_SENDER_BW_FRACTION;
			n = senders;
		} else {
			rtcp_bw *= RTCP_RCVR_BW_FRACTION;
			n -= senders;
		}
	}
  
	/*
	 * Update the average size estimate by the size of the report
	 * packet we just sent.
	 */
	*avg_rtcp_size += (packet_size - *avg_rtcp_size)*RTCP_SIZE_GAIN;
  
	/*
	 * 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 = (*avg_rtcp_size) * n / rtcp_bw;
	if (t < rtcp_min_time) t = rtcp_min_time;
  
	/*
	 * To avoid traffic bursts from unintended synchronization with
	 * other sites, we then pick our actual next report interval as a
	 * random number uniformly distributed between 0.5*t and 1.5*t.
	 */

	return t * (drand48() + 0.5);
}