The following function returns the time between transmissions of RTCP packets, measured in seconds. It should be called after sending one compound RTCP packet to calculate the delay until the next should be sent. This function should also be called to calculate the delay before sending the first RTCP packet upon startup rather than send the packet immediately. This avoids any burst of RTCP packets if an application is started at many sites simultaneously, for example as a result of a session announcement.
The parameters have the following meaning:
#include <math.h> double rtcp_interval(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); }