2 * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
3 * Copyright (C) 2015 Kurento (http://kurento.org/)
4 * @author: Miguel ParĂs <mparisdiaz@gmail.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
25 gst_rtp_packet_rate_ctx_reset (RTPPacketRateCtx * ctx, gint32 clock_rate)
27 ctx->clock_rate = clock_rate;
29 ctx->avg_packet_rate = -1;
34 gst_rtp_packet_rate_ctx_update (RTPPacketRateCtx * ctx, guint16 seqnum,
37 guint64 new_ts, diff_ts;
39 gint32 new_packet_rate;
41 if (ctx->clock_rate <= 0) {
42 return ctx->avg_packet_rate;
45 new_ts = ctx->last_ts;
46 gst_rtp_buffer_ext_timestamp (&new_ts, ts);
49 ctx->last_seqnum = seqnum;
50 ctx->last_ts = new_ts;
52 return ctx->avg_packet_rate;
55 diff_seqnum = gst_rtp_buffer_compare_seqnum (ctx->last_seqnum, seqnum);
56 if (diff_seqnum <= 0 || new_ts <= ctx->last_ts) {
57 return ctx->avg_packet_rate;
60 diff_ts = new_ts - ctx->last_ts;
61 diff_ts = gst_util_uint64_scale_int (diff_ts, GST_SECOND, ctx->clock_rate);
62 new_packet_rate = gst_util_uint64_scale (diff_seqnum, GST_SECOND, diff_ts);
64 /* The goal is that higher packet rates "win".
65 * If there's a sudden burst, the average will go up fast,
66 * but it will go down again slowly.
67 * This is useful for bursty cases, where a lot of packets are close
68 * to each other and should allow a higher reorder/dropout there.
69 * Round up the new average.
71 if (ctx->avg_packet_rate > new_packet_rate) {
72 ctx->avg_packet_rate = (7 * ctx->avg_packet_rate + new_packet_rate + 7) / 8;
74 ctx->avg_packet_rate = (ctx->avg_packet_rate + new_packet_rate + 1) / 2;
77 ctx->last_seqnum = seqnum;
78 ctx->last_ts = new_ts;
80 return ctx->avg_packet_rate;
84 gst_rtp_packet_rate_ctx_get (RTPPacketRateCtx * ctx)
86 return ctx->avg_packet_rate;
90 gst_rtp_packet_rate_ctx_get_max_dropout (RTPPacketRateCtx * ctx, gint32 time_ms)
92 if (time_ms <= 0 || !ctx->probed) {
93 return RTP_DEF_DROPOUT;
96 return MAX (RTP_MIN_DROPOUT, ctx->avg_packet_rate * time_ms / 1000);
100 gst_rtp_packet_rate_ctx_get_max_misorder (RTPPacketRateCtx * ctx,
103 if (time_ms <= 0 || !ctx->probed) {
104 return RTP_DEF_MISORDER;
107 return MAX (RTP_MIN_MISORDER, ctx->avg_packet_rate * time_ms / 1000);
111 * rtp_stats_init_defaults:
112 * @stats: an #RTPSessionStats struct
114 * Initialize @stats with its default values.
117 rtp_stats_init_defaults (RTPSessionStats * stats)
119 rtp_stats_set_bandwidths (stats, -1, -1, -1, -1);
120 stats->min_interval = RTP_STATS_MIN_INTERVAL;
121 stats->bye_timeout = RTP_STATS_BYE_TIMEOUT;
122 stats->nacks_dropped = 0;
123 stats->nacks_sent = 0;
124 stats->nacks_received = 0;
128 * rtp_stats_set_bandwidths:
129 * @stats: an #RTPSessionStats struct
130 * @rtp_bw: RTP bandwidth
131 * @rtcp_bw: RTCP bandwidth
132 * @rs: sender RTCP bandwidth
133 * @rr: receiver RTCP bandwidth
135 * Configure the bandwidth parameters in the stats. When an input variable is
136 * set to -1, it will be calculated from the other input variables and from the
140 rtp_stats_set_bandwidths (RTPSessionStats * stats, guint rtp_bw,
141 gdouble rtcp_bw, guint rs, guint rr)
143 GST_DEBUG ("recalc bandwidths: RTP %u, RTCP %f, RS %u, RR %u", rtp_bw,
146 /* when given, sender and receive bandwidth add up to the total
148 if (rs != -1 && rr != -1)
151 /* If rtcp_bw is between 0 and 1, it is a fraction of rtp_bw */
152 if (rtcp_bw > 0.0 && rtcp_bw < 1.0) {
154 rtcp_bw = rtp_bw * rtcp_bw;
159 /* RTCP is 5% of the RTP bandwidth */
160 if (rtp_bw == -1 && rtcp_bw > 1.0)
161 rtp_bw = rtcp_bw * 20;
162 else if (rtp_bw != -1 && rtcp_bw < 0.0)
163 rtcp_bw = rtp_bw / 20;
164 else if (rtp_bw == -1 && rtcp_bw < 0.0) {
165 /* nothing given, take defaults */
166 rtp_bw = RTP_STATS_BANDWIDTH;
167 rtcp_bw = rtp_bw * RTP_STATS_RTCP_FRACTION;
170 stats->bandwidth = rtp_bw;
171 stats->rtcp_bandwidth = rtcp_bw;
173 /* now figure out the fractions */
177 /* both not given, use defaults */
178 rs = stats->rtcp_bandwidth * RTP_STATS_SENDER_FRACTION;
179 rr = stats->rtcp_bandwidth * RTP_STATS_RECEIVER_FRACTION;
181 /* rr known, calculate rs */
182 if (stats->rtcp_bandwidth > rr)
183 rs = stats->rtcp_bandwidth - rr;
187 } else if (rr == -1) {
188 /* rs known, calculate rr */
189 if (stats->rtcp_bandwidth > rs)
190 rr = stats->rtcp_bandwidth - rs;
195 if (stats->rtcp_bandwidth > 0) {
196 stats->sender_fraction = ((gdouble) rs) / ((gdouble) stats->rtcp_bandwidth);
197 stats->receiver_fraction = 1.0 - stats->sender_fraction;
199 /* no RTCP bandwidth, set dummy values */
200 stats->sender_fraction = 0.0;
201 stats->receiver_fraction = 0.0;
203 GST_DEBUG ("bandwidths: RTP %u, RTCP %u, RS %f, RR %f", stats->bandwidth,
204 stats->rtcp_bandwidth, stats->sender_fraction, stats->receiver_fraction);
208 * rtp_stats_calculate_rtcp_interval:
209 * @stats: an #RTPSessionStats struct
210 * @sender: if we are a sender
211 * @profile: RTP profile of this session
212 * @ptp: if this session is a point-to-point session
213 * @first: if this is the first time
215 * Calculate the RTCP interval. The result of this function is the amount of
216 * time to wait (in nanoseconds) before sending a new RTCP message.
218 * Returns: the RTCP interval.
221 rtp_stats_calculate_rtcp_interval (RTPSessionStats * stats, gboolean we_send,
222 GstRTPProfile profile, gboolean ptp, gboolean first)
224 gdouble members, senders, n;
225 gdouble avg_rtcp_size, rtcp_bw;
227 gdouble rtcp_min_time;
229 if (profile == GST_RTP_PROFILE_AVPF || profile == GST_RTP_PROFILE_SAVPF) {
230 /* RFC 4585 3.4d), 3.5.1 */
237 /* Very first call at application start-up uses half the min
238 * delay for quicker notification while still allowing some time
239 * before reporting for randomization and to learn about other
240 * sources so the report interval will converge to the correct
241 * interval more quickly.
243 rtcp_min_time = stats->min_interval;
245 rtcp_min_time /= 2.0;
248 /* Dedicate a fraction of the RTCP bandwidth to senders unless
249 * the number of senders is large enough that their share is
250 * more than that fraction.
252 n = members = stats->active_sources;
253 senders = (gdouble) stats->sender_sources;
254 rtcp_bw = stats->rtcp_bandwidth;
256 if (senders <= members * stats->sender_fraction) {
258 rtcp_bw *= stats->sender_fraction;
261 rtcp_bw *= stats->receiver_fraction;
266 /* no bandwidth for RTCP, return NONE to signal that we don't want to send
268 if (rtcp_bw <= 0.0001)
269 return GST_CLOCK_TIME_NONE;
271 avg_rtcp_size = 8.0 * stats->avg_rtcp_packet_size;
273 * The effective number of sites times the average packet size is
274 * the total number of octets sent when each site sends a report.
275 * Dividing this by the effective bandwidth gives the time
276 * interval over which those packets must be sent in order to
277 * meet the bandwidth target, with a minimum enforced. In that
278 * time interval we send one report so this time is also our
279 * average time between reports.
281 GST_DEBUG ("avg size %f, n %f, rtcp_bw %f", avg_rtcp_size, n, rtcp_bw);
282 interval = avg_rtcp_size * n / rtcp_bw;
283 if (interval < rtcp_min_time)
284 interval = rtcp_min_time;
286 return interval * GST_SECOND;
290 * rtp_stats_add_rtcp_jitter:
291 * @stats: an #RTPSessionStats struct
292 * @interval: an RTCP interval
294 * Apply a random jitter to the @interval. @interval is typically obtained with
295 * rtp_stats_calculate_rtcp_interval().
297 * Returns: the new RTCP interval.
300 rtp_stats_add_rtcp_jitter (RTPSessionStats * stats, GstClockTime interval)
305 * To compensate for "unconditional reconsideration" converging to a
306 * value below the intended average.
308 #define COMPENSATION (2.71828 - 1.5);
310 temp = (interval * g_random_double_range (0.5, 1.5)) / COMPENSATION;
312 return (GstClockTime) temp;
317 * rtp_stats_calculate_bye_interval:
318 * @stats: an #RTPSessionStats struct
320 * Calculate the BYE interval. The result of this function is the amount of
321 * time to wait (in nanoseconds) before sending a BYE message.
323 * Returns: the BYE interval.
326 rtp_stats_calculate_bye_interval (RTPSessionStats * stats)
329 gdouble avg_rtcp_size, rtcp_bw;
331 gdouble rtcp_min_time;
333 /* no interval when we have less than 50 members */
334 if (stats->active_sources < 50)
337 rtcp_min_time = (stats->min_interval) / 2.0;
339 /* Dedicate a fraction of the RTCP bandwidth to senders unless
340 * the number of senders is large enough that their share is
341 * more than that fraction.
343 members = stats->bye_members;
344 rtcp_bw = stats->rtcp_bandwidth * stats->receiver_fraction;
346 /* no bandwidth for RTCP, return NONE to signal that we don't want to send
348 if (rtcp_bw <= 0.0001)
349 return GST_CLOCK_TIME_NONE;
351 avg_rtcp_size = 8.0 * stats->avg_rtcp_packet_size;
353 * The effective number of sites times the average packet size is
354 * the total number of octets sent when each site sends a report.
355 * Dividing this by the effective bandwidth gives the time
356 * interval over which those packets must be sent in order to
357 * meet the bandwidth target, with a minimum enforced. In that
358 * time interval we send one report so this time is also our
359 * average time between reports.
361 interval = avg_rtcp_size * members / rtcp_bw;
362 if (interval < rtcp_min_time)
363 interval = rtcp_min_time;
365 return interval * GST_SECOND;
369 * rtp_stats_get_packets_lost:
370 * @stats: an #RTPSourceStats struct
372 * Calculate the total number of RTP packets lost since beginning of
373 * reception. Packets that arrive late are not considered lost, and
374 * duplicates are not taken into account. Hence, the loss may be negative
375 * if there are duplicates.
377 * Returns: total RTP packets lost.
380 rtp_stats_get_packets_lost (const RTPSourceStats * stats)
383 guint64 extended_max, expected;
385 extended_max = stats->cycles + stats->max_seq;
386 expected = extended_max - stats->base_seq + 1;
387 lost = expected - stats->packets_received;
393 rtp_stats_set_min_interval (RTPSessionStats * stats, gdouble min_interval)
395 stats->min_interval = min_interval;
399 __g_socket_address_equal (GSocketAddress * a, GSocketAddress * b)
401 GInetSocketAddress *ia, *ib;
402 GInetAddress *iaa, *iab;
404 ia = G_INET_SOCKET_ADDRESS (a);
405 ib = G_INET_SOCKET_ADDRESS (b);
407 if (g_inet_socket_address_get_port (ia) !=
408 g_inet_socket_address_get_port (ib))
411 iaa = g_inet_socket_address_get_address (ia);
412 iab = g_inet_socket_address_get_address (ib);
414 return g_inet_address_equal (iaa, iab);
418 __g_socket_address_to_string (GSocketAddress * addr)
420 GInetSocketAddress *ia;
423 ia = G_INET_SOCKET_ADDRESS (addr);
425 tmp = g_inet_address_to_string (g_inet_socket_address_get_address (ia));
426 ret = g_strdup_printf ("%s:%u", tmp, g_inet_socket_address_get_port (ia));