#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) |
| 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 }
1.5.2