2 * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
23 * rtp_stats_init_defaults:
24 * @stats: an #RTPSessionStats struct
26 * Initialize @stats with its default values.
29 rtp_stats_init_defaults (RTPSessionStats * stats)
31 rtp_stats_set_bandwidths (stats, -1, -1, -1, -1);
32 stats->min_interval = RTP_STATS_MIN_INTERVAL;
33 stats->bye_timeout = RTP_STATS_BYE_TIMEOUT;
37 * rtp_stats_set_bandwidths:
38 * @stats: an #RTPSessionStats struct
39 * @rtp_bw: RTP bandwidth
40 * @rtcp_bw: RTCP bandwidth
41 * @rs: sender RTCP bandwidth
42 * @rr: receiver RTCP bandwidth
44 * Configure the bandwidth parameters in the stats. When an input variable is
45 * set to -1, it will be calculated from the other input variables and from the
49 rtp_stats_set_bandwidths (RTPSessionStats * stats, guint rtp_bw, guint rtcp_bw,
52 /* when given, sender and receive bandwidth add up to the total
54 if (rs != -1 && rr != -1)
57 /* RTCP is 5% of the RTP bandwidth */
58 if (rtp_bw == -1 && rtcp_bw != -1)
59 rtp_bw = rtcp_bw * 20;
60 else if (rtp_bw != -1 && rtcp_bw == -1)
61 rtcp_bw = rtp_bw / 20;
62 else if (rtp_bw == -1 && rtcp_bw == -1) {
63 /* nothing given, take defaults */
64 rtp_bw = RTP_STATS_BANDWIDTH;
65 rtcp_bw = RTP_STATS_RTCP_BANDWIDTH;
67 stats->bandwidth = rtp_bw;
68 stats->rtcp_bandwidth = rtcp_bw;
70 /* now figure out the fractions */
74 /* both not given, use defaults */
75 rs = stats->rtcp_bandwidth * RTP_STATS_SENDER_FRACTION;
76 rr = stats->rtcp_bandwidth * RTP_STATS_RECEIVER_FRACTION;
78 /* rr known, calculate rs */
79 if (stats->rtcp_bandwidth > rr)
80 rs = stats->rtcp_bandwidth - rr;
84 } else if (rr == -1) {
85 /* rs known, calculate rr */
86 if (stats->rtcp_bandwidth > rs)
87 rr = stats->rtcp_bandwidth - rs;
92 if (stats->rtcp_bandwidth > 0) {
93 stats->sender_fraction = ((gdouble) rs) / ((gdouble) stats->rtcp_bandwidth);
94 stats->receiver_fraction = 1.0 - stats->sender_fraction;
96 /* no RTCP bandwidth, set dummy values */
97 stats->sender_fraction = 0.0;
98 stats->receiver_fraction = 0.0;
100 GST_DEBUG ("bandwidths: RTP %u, RTCP %u, RS %f, RR %f", stats->bandwidth,
101 stats->rtcp_bandwidth, stats->sender_fraction, stats->receiver_fraction);
105 * rtp_stats_calculate_rtcp_interval:
106 * @stats: an #RTPSessionStats struct
107 * @sender: if we are a sender
108 * @first: if this is the first time
110 * Calculate the RTCP interval. The result of this function is the amount of
111 * time to wait (in nanoseconds) before sending a new RTCP message.
113 * Returns: the RTCP interval.
116 rtp_stats_calculate_rtcp_interval (RTPSessionStats * stats, gboolean we_send,
119 gdouble members, senders, n;
120 gdouble avg_rtcp_size, rtcp_bw;
122 gdouble rtcp_min_time;
124 /* Very first call at application start-up uses half the min
125 * delay for quicker notification while still allowing some time
126 * before reporting for randomization and to learn about other
127 * sources so the report interval will converge to the correct
128 * interval more quickly.
130 rtcp_min_time = stats->min_interval;
132 rtcp_min_time /= 2.0;
134 /* Dedicate a fraction of the RTCP bandwidth to senders unless
135 * the number of senders is large enough that their share is
136 * more than that fraction.
138 n = members = stats->active_sources;
139 senders = (gdouble) stats->sender_sources;
140 rtcp_bw = stats->rtcp_bandwidth;
142 if (senders <= members * stats->sender_fraction) {
144 rtcp_bw *= stats->sender_fraction;
147 rtcp_bw *= stats->receiver_fraction;
152 /* no bandwidth for RTCP, return NONE to signal that we don't want to send
154 if (rtcp_bw <= 0.00001)
155 return GST_CLOCK_TIME_NONE;
157 avg_rtcp_size = stats->avg_rtcp_packet_size / 16.0;
159 * The effective number of sites times the average packet size is
160 * the total number of octets sent when each site sends a report.
161 * Dividing this by the effective bandwidth gives the time
162 * interval over which those packets must be sent in order to
163 * meet the bandwidth target, with a minimum enforced. In that
164 * time interval we send one report so this time is also our
165 * average time between reports.
167 interval = avg_rtcp_size * n / rtcp_bw;
168 if (interval < rtcp_min_time)
169 interval = rtcp_min_time;
171 return interval * GST_SECOND;
175 * rtp_stats_add_rtcp_jitter:
176 * @stats: an #RTPSessionStats struct
177 * @interval: an RTCP interval
179 * Apply a random jitter to the @interval. @interval is typically obtained with
180 * rtp_stats_calculate_rtcp_interval().
182 * Returns: the new RTCP interval.
185 rtp_stats_add_rtcp_jitter (RTPSessionStats * stats, GstClockTime interval)
190 * To compensate for "unconditional reconsideration" converging to a
191 * value below the intended average.
193 #define COMPENSATION (2.71828 - 1.5);
195 temp = (interval * g_random_double_range (0.5, 1.5)) / COMPENSATION;
197 return (GstClockTime) temp;
202 * rtp_stats_calculate_bye_interval:
203 * @stats: an #RTPSessionStats struct
205 * Calculate the BYE interval. The result of this function is the amount of
206 * time to wait (in nanoseconds) before sending a BYE message.
208 * Returns: the BYE interval.
211 rtp_stats_calculate_bye_interval (RTPSessionStats * stats)
214 gdouble avg_rtcp_size, rtcp_bw;
216 gdouble rtcp_min_time;
218 /* no interval when we have less than 50 members */
219 if (stats->active_sources < 50)
222 rtcp_min_time = (stats->min_interval) / 2.0;
224 /* Dedicate a fraction of the RTCP bandwidth to senders unless
225 * the number of senders is large enough that their share is
226 * more than that fraction.
228 members = stats->bye_members;
229 rtcp_bw = stats->rtcp_bandwidth * stats->receiver_fraction;
231 /* no bandwidth for RTCP, return NONE to signal that we don't want to send
233 if (rtcp_bw <= 0.0001)
234 return GST_CLOCK_TIME_NONE;
236 avg_rtcp_size = stats->avg_rtcp_packet_size / 16.0;
238 * The effective number of sites times the average packet size is
239 * the total number of octets sent when each site sends a report.
240 * Dividing this by the effective bandwidth gives the time
241 * interval over which those packets must be sent in order to
242 * meet the bandwidth target, with a minimum enforced. In that
243 * time interval we send one report so this time is also our
244 * average time between reports.
246 interval = avg_rtcp_size * members / rtcp_bw;
247 if (interval < rtcp_min_time)
248 interval = rtcp_min_time;
250 return interval * GST_SECOND;