liveMedia/rtcp_from_spec.c File Reference

#include "rtcp_from_spec.h"

Include dependency graph for rtcp_from_spec.c:

Go to the source code of this file.

Functions

double rtcp_interval (int members, int senders, double rtcp_bw, int we_sent, double avg_rtcp_size, int initial)
void OnExpire (event e, int members, int senders, double rtcp_bw, int we_sent, double *avg_rtcp_size, int *initial, time_tp tc, time_tp *tp, int *pmembers)
void OnReceive (packet p, event e, int *members, int *pmembers, int *senders, double *avg_rtcp_size, double *tp, double tc, double tn)


Function Documentation

void OnExpire ( event  e,
int  members,
int  senders,
double  rtcp_bw,
int  we_sent,
double *  avg_rtcp_size,
int *  initial,
time_tp  tc,
time_tp tp,
int *  pmembers 
)

Definition at line 154 of file rtcp_from_spec.c.

References EVENT_BYE, EVENT_REPORT, exit, rtcp_interval(), Schedule(), SendBYEPacket(), SendRTCPReport(), SentPacketSize(), and TypeOfEvent().

Referenced by RTCPInstance::onExpire1().

00164    {
00165        /* This function is responsible for deciding whether to send
00166         * an RTCP report or BYE packet now, or to reschedule transmission.
00167         * It is also responsible for updating the pmembers, initial, tp,
00168         * and avg_rtcp_size state variables. This function should be called
00169         * upon expiration of the event timer used by Schedule(). */
00170 
00171        double t;     /* Interval */
00172        double tn;    /* Next transmit time */
00173 
00174        /* In the case of a BYE, we use "unconditional reconsideration" to
00175         * reschedule the transmission of the BYE if necessary */
00176 
00177        if (TypeOfEvent(e) == EVENT_BYE) {
00178            t = rtcp_interval(members,
00179                              senders,
00180                              rtcp_bw,
00181                              we_sent,
00182                              *avg_rtcp_size,
00183                              *initial);
00184            tn = *tp + t;
00185            if (tn <= tc) {
00186                SendBYEPacket(e);
00187                exit(1);
00188            } else {
00189                Schedule(tn, e);
00190            }
00191 
00192        } else if (TypeOfEvent(e) == EVENT_REPORT) {
00193            t = rtcp_interval(members,
00194                              senders,
00195                              rtcp_bw,
00196                              we_sent,
00197                              *avg_rtcp_size,
00198                              *initial);
00199            tn = *tp + t;
00200 
00201            if (tn <= tc) {
00202                SendRTCPReport(e);
00203                *avg_rtcp_size = (1./16.)*SentPacketSize(e) +
00204                    (15./16.)*(*avg_rtcp_size);
00205                *tp = tc;
00206 
00207                /* We must redraw the interval. Don't reuse the
00208                   one computed above, since its not actually
00209                   distributed the same, as we are conditioned
00210                   on it being small enough to cause a packet to
00211                   be sent */
00212 
00213                t = rtcp_interval(members,
00214                                  senders,
00215                                  rtcp_bw,
00216                                  we_sent,
00217                                  *avg_rtcp_size,
00218                                  *initial);
00219 
00220                Schedule(t+tc,e);
00221                *initial = 0;
00222            } else {
00223                Schedule(tn, e);
00224            }
00225            *pmembers = members;
00226        }
00227    }

void OnReceive ( packet  p,
event  e,
int *  members,
int *  pmembers,
int *  senders,
double *  avg_rtcp_size,
double *  tp,
double  tc,
double  tn 
)

Definition at line 230 of file rtcp_from_spec.c.

References AddMember(), AddSender(), EVENT_BYE, EVENT_REPORT, FALSE, NewMember(), NewSender(), PACKET_BYE, PACKET_RTCP_REPORT, PACKET_RTP, PacketType(), ReceivedPacketSize(), RemoveMember(), RemoveSender(), Reschedule(), and TypeOfEvent().

00239    {
00240        /* What we do depends on whether we have left the group, and
00241         * are waiting to send a BYE (TypeOfEvent(e) == EVENT_BYE) or
00242         * an RTCP report. p represents the packet that was just received. */
00243 
00244        if (PacketType(p) == PACKET_RTCP_REPORT) {
00245            if (NewMember(p) && (TypeOfEvent(e) == EVENT_REPORT)) {
00246                AddMember(p);
00247                *members += 1;
00248            }
00249            *avg_rtcp_size = (1./16.)*ReceivedPacketSize(p) +
00250                (15./16.)*(*avg_rtcp_size);
00251        } else if (PacketType(p) == PACKET_RTP) {
00252            if (NewMember(p) && (TypeOfEvent(e) == EVENT_REPORT)) {
00253                AddMember(p);
00254                *members += 1;
00255            }
00256            if (NewSender(p) && (TypeOfEvent(e) == EVENT_REPORT)) {
00257                AddSender(p);
00258                *senders += 1;
00259            }
00260        } else if (PacketType(p) == PACKET_BYE) {
00261            *avg_rtcp_size = (1./16.)*ReceivedPacketSize(p) +
00262                (15./16.)*(*avg_rtcp_size);
00263 
00264            if (TypeOfEvent(e) == EVENT_REPORT) {
00265                if (NewSender(p) == FALSE) {
00266                    RemoveSender(p);
00267                    *senders -= 1;
00268                }
00269 
00270                if (NewMember(p) == FALSE) {
00271                    RemoveMember(p);
00272                    *members -= 1;
00273                }
00274 
00275                if(*members < *pmembers) {
00276                    tn = tc + (((double) *members)/(*pmembers))*(tn - tc);
00277                    *tp = tc - (((double) *members)/(*pmembers))*(tc - *tp);
00278 
00279                    /* Reschedule the next report for time tn */
00280 
00281                    Reschedule(tn, e);
00282                    *pmembers = *members;
00283                }
00284 
00285            } else if (TypeOfEvent(e) == EVENT_BYE) {
00286                *members += 1;
00287            }
00288        }
00289    }

double rtcp_interval ( int  members,
int  senders,
double  rtcp_bw,
int  we_sent,
double  avg_rtcp_size,
int  initial 
)

Definition at line 69 of file rtcp_from_spec.c.

References drand48.

Referenced by OnExpire().

00075    {
00076        /*
00077         * Minimum average time between RTCP packets from this site (in
00078         * seconds).  This time prevents the reports from `clumping' when
00079         * sessions are small and the law of large numbers isn't helping
00080         * to smooth out the traffic.  It also keeps the report interval
00081         * from becoming ridiculously small during transient outages like
00082         * a network partition.
00083         */
00084        double const RTCP_MIN_TIME = 5.;
00085        /*
00086         * Fraction of the RTCP bandwidth to be shared among active
00087         * senders.  (This fraction was chosen so that in a typical
00088         * session with one or two active senders, the computed report
00089         * time would be roughly equal to the minimum report time so that
00090         * we don't unnecessarily slow down receiver reports.) The
00091         * receiver fraction must be 1 - the sender fraction.
00092         */
00093        double const RTCP_SENDER_BW_FRACTION = 0.25;
00094        double const RTCP_RCVR_BW_FRACTION = (1-RTCP_SENDER_BW_FRACTION);
00095        /*
00096         * To compensate for "unconditional reconsideration" converging to a
00097         * value below the intended average.
00098         */
00099        double const COMPENSATION = 2.71828 - 1.5;
00100 
00101        double t;                   /* interval */
00102        double rtcp_min_time = RTCP_MIN_TIME;
00103        int n;                      /* no. of members for computation */
00104 
00105        /*
00106         * Very first call at application start-up uses half the min
00107         * delay for quicker notification while still allowing some time
00108         * before reporting for randomization and to learn about other
00109         * sources so the report interval will converge to the correct
00110         * interval more quickly.
00111         */
00112        if (initial) {
00113            rtcp_min_time /= 2;
00114        }
00115 
00116        /*
00117         * If there were active senders, give them at least a minimum
00118         * share of the RTCP bandwidth.  Otherwise all participants share
00119         * the RTCP bandwidth equally.
00120         */
00121        n = members;
00122        if (senders > 0 && senders < members * RTCP_SENDER_BW_FRACTION) {
00123            if (we_sent) {
00124                rtcp_bw *= RTCP_SENDER_BW_FRACTION;
00125                n = senders;
00126            } else {
00127                rtcp_bw *= RTCP_RCVR_BW_FRACTION;
00128                n -= senders;
00129            }
00130        }
00131 
00132        /*
00133         * The effective number of sites times the average packet size is
00134         * the total number of octets sent when each site sends a report.
00135         * Dividing this by the effective bandwidth gives the time
00136         * interval over which those packets must be sent in order to
00137         * meet the bandwidth target, with a minimum enforced.  In that
00138         * time interval we send one report so this time is also our
00139         * average time between reports.
00140         */
00141        t = avg_rtcp_size * n / rtcp_bw;
00142        if (t < rtcp_min_time) t = rtcp_min_time;
00143 
00144        /*
00145         * To avoid traffic bursts from unintended synchronization with
00146         * other sites, we then pick our actual next report interval as a
00147         * random number uniformly distributed between 0.5*t and 1.5*t.
00148         */
00149        t = t * (drand48() + 0.5);
00150        t = t / COMPENSATION;
00151        return t;
00152    }


Generated on Mon Apr 29 13:30:35 2013 for live by  doxygen 1.5.2