Revert "WIP: rtpjitterbuffer: Add RFC7273 media clock handling"
[platform/upstream/gst-plugins-good.git] / gst / rtpmanager / rtpjitterbuffer.c
1 /* GStreamer
2  * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
3  *
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.
8  *
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.
13  *
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., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 #include <string.h>
20 #include <stdlib.h>
21
22 #include <gst/rtp/gstrtpbuffer.h>
23 #include <gst/rtp/gstrtcpbuffer.h>
24
25 #include "rtpjitterbuffer.h"
26
27 GST_DEBUG_CATEGORY_STATIC (rtp_jitter_buffer_debug);
28 #define GST_CAT_DEFAULT rtp_jitter_buffer_debug
29
30 #define MAX_WINDOW      RTP_JITTER_BUFFER_MAX_WINDOW
31 #define MAX_TIME        (2 * GST_SECOND)
32
33 /* signals and args */
34 enum
35 {
36   LAST_SIGNAL
37 };
38
39 enum
40 {
41   PROP_0
42 };
43
44 /* GObject vmethods */
45 static void rtp_jitter_buffer_finalize (GObject * object);
46
47 GType
48 rtp_jitter_buffer_mode_get_type (void)
49 {
50   static GType jitter_buffer_mode_type = 0;
51   static const GEnumValue jitter_buffer_modes[] = {
52     {RTP_JITTER_BUFFER_MODE_NONE, "Only use RTP timestamps", "none"},
53     {RTP_JITTER_BUFFER_MODE_SLAVE, "Slave receiver to sender clock", "slave"},
54     {RTP_JITTER_BUFFER_MODE_BUFFER, "Do low/high watermark buffering",
55         "buffer"},
56     {RTP_JITTER_BUFFER_MODE_SYNCED, "Synchronized sender and receiver clocks",
57         "synced"},
58     {0, NULL, NULL},
59   };
60
61   if (!jitter_buffer_mode_type) {
62     jitter_buffer_mode_type =
63         g_enum_register_static ("RTPJitterBufferMode", jitter_buffer_modes);
64   }
65   return jitter_buffer_mode_type;
66 }
67
68 /* static guint rtp_jitter_buffer_signals[LAST_SIGNAL] = { 0 }; */
69
70 G_DEFINE_TYPE (RTPJitterBuffer, rtp_jitter_buffer, G_TYPE_OBJECT);
71
72 static void
73 rtp_jitter_buffer_class_init (RTPJitterBufferClass * klass)
74 {
75   GObjectClass *gobject_class;
76
77   gobject_class = (GObjectClass *) klass;
78
79   gobject_class->finalize = rtp_jitter_buffer_finalize;
80
81   GST_DEBUG_CATEGORY_INIT (rtp_jitter_buffer_debug, "rtpjitterbuffer", 0,
82       "RTP Jitter Buffer");
83 }
84
85 static void
86 rtp_jitter_buffer_init (RTPJitterBuffer * jbuf)
87 {
88   jbuf->packets = g_queue_new ();
89   jbuf->mode = RTP_JITTER_BUFFER_MODE_SLAVE;
90
91   rtp_jitter_buffer_reset_skew (jbuf);
92 }
93
94 static void
95 rtp_jitter_buffer_finalize (GObject * object)
96 {
97   RTPJitterBuffer *jbuf;
98
99   jbuf = RTP_JITTER_BUFFER_CAST (object);
100
101   g_queue_free (jbuf->packets);
102
103   G_OBJECT_CLASS (rtp_jitter_buffer_parent_class)->finalize (object);
104 }
105
106 /**
107  * rtp_jitter_buffer_new:
108  *
109  * Create an #RTPJitterBuffer.
110  *
111  * Returns: a new #RTPJitterBuffer. Use g_object_unref() after usage.
112  */
113 RTPJitterBuffer *
114 rtp_jitter_buffer_new (void)
115 {
116   RTPJitterBuffer *jbuf;
117
118   jbuf = g_object_new (RTP_TYPE_JITTER_BUFFER, NULL);
119
120   return jbuf;
121 }
122
123 /**
124  * rtp_jitter_buffer_get_mode:
125  * @jbuf: an #RTPJitterBuffer
126  *
127  * Get the current jitterbuffer mode.
128  *
129  * Returns: the current jitterbuffer mode.
130  */
131 RTPJitterBufferMode
132 rtp_jitter_buffer_get_mode (RTPJitterBuffer * jbuf)
133 {
134   return jbuf->mode;
135 }
136
137 /**
138  * rtp_jitter_buffer_set_mode:
139  * @jbuf: an #RTPJitterBuffer
140  * @mode: a #RTPJitterBufferMode
141  *
142  * Set the buffering and clock slaving algorithm used in the @jbuf.
143  */
144 void
145 rtp_jitter_buffer_set_mode (RTPJitterBuffer * jbuf, RTPJitterBufferMode mode)
146 {
147   jbuf->mode = mode;
148 }
149
150 GstClockTime
151 rtp_jitter_buffer_get_delay (RTPJitterBuffer * jbuf)
152 {
153   return jbuf->delay;
154 }
155
156 void
157 rtp_jitter_buffer_set_delay (RTPJitterBuffer * jbuf, GstClockTime delay)
158 {
159   jbuf->delay = delay;
160   jbuf->low_level = (delay * 15) / 100;
161   /* the high level is at 90% in order to release packets before we fill up the
162    * buffer up to the latency */
163   jbuf->high_level = (delay * 90) / 100;
164
165   GST_DEBUG ("delay %" GST_TIME_FORMAT ", min %" GST_TIME_FORMAT ", max %"
166       GST_TIME_FORMAT, GST_TIME_ARGS (jbuf->delay),
167       GST_TIME_ARGS (jbuf->low_level), GST_TIME_ARGS (jbuf->high_level));
168 }
169
170 /**
171  * rtp_jitter_buffer_set_clock_rate:
172  * @jbuf: an #RTPJitterBuffer
173  * @clock_rate: the new clock rate
174  *
175  * Set the clock rate in the jitterbuffer.
176  */
177 void
178 rtp_jitter_buffer_set_clock_rate (RTPJitterBuffer * jbuf, guint32 clock_rate)
179 {
180   if (jbuf->clock_rate != clock_rate) {
181     GST_DEBUG ("Clock rate changed from %" G_GUINT32_FORMAT " to %"
182         G_GUINT32_FORMAT, jbuf->clock_rate, clock_rate);
183     jbuf->clock_rate = clock_rate;
184     rtp_jitter_buffer_reset_skew (jbuf);
185   }
186 }
187
188 /**
189  * rtp_jitter_buffer_get_clock_rate:
190  * @jbuf: an #RTPJitterBuffer
191  *
192  * Get the currently configure clock rate in @jbuf.
193  *
194  * Returns: the current clock-rate
195  */
196 guint32
197 rtp_jitter_buffer_get_clock_rate (RTPJitterBuffer * jbuf)
198 {
199   return jbuf->clock_rate;
200 }
201
202 /**
203  * rtp_jitter_buffer_reset_skew:
204  * @jbuf: an #RTPJitterBuffer
205  *
206  * Reset the skew calculations in @jbuf.
207  */
208 void
209 rtp_jitter_buffer_reset_skew (RTPJitterBuffer * jbuf)
210 {
211   jbuf->base_time = -1;
212   jbuf->base_rtptime = -1;
213   jbuf->base_extrtp = -1;
214   jbuf->ext_rtptime = -1;
215   jbuf->last_rtptime = -1;
216   jbuf->window_pos = 0;
217   jbuf->window_filling = TRUE;
218   jbuf->window_min = 0;
219   jbuf->skew = 0;
220   jbuf->prev_send_diff = -1;
221   jbuf->prev_out_time = -1;
222   jbuf->need_resync = TRUE;
223   GST_DEBUG ("reset skew correction");
224 }
225
226 /**
227  * rtp_jitter_buffer_disable_buffering:
228  * @jbuf: an #RTPJitterBuffer
229  * @disabled: the new state
230  *
231  * Enable or disable buffering on @jbuf.
232  */
233 void
234 rtp_jitter_buffer_disable_buffering (RTPJitterBuffer * jbuf, gboolean disabled)
235 {
236   jbuf->buffering_disabled = disabled;
237 }
238
239 static void
240 rtp_jitter_buffer_resync (RTPJitterBuffer * jbuf, GstClockTime time,
241     GstClockTime gstrtptime, guint64 ext_rtptime, gboolean reset_skew)
242 {
243   jbuf->base_time = time;
244   jbuf->base_rtptime = gstrtptime;
245   jbuf->base_extrtp = ext_rtptime;
246   jbuf->prev_out_time = -1;
247   jbuf->prev_send_diff = -1;
248   if (reset_skew) {
249     jbuf->window_filling = TRUE;
250     jbuf->window_pos = 0;
251     jbuf->window_min = 0;
252     jbuf->window_size = 0;
253     jbuf->skew = 0;
254   }
255   jbuf->need_resync = FALSE;
256 }
257
258 static guint64
259 get_buffer_level (RTPJitterBuffer * jbuf)
260 {
261   RTPJitterBufferItem *high_buf = NULL, *low_buf = NULL;
262   guint64 level;
263
264   /* first buffer with timestamp */
265   high_buf = (RTPJitterBufferItem *) g_queue_peek_tail_link (jbuf->packets);
266   while (high_buf) {
267     if (high_buf->dts != -1 || high_buf->pts != -1)
268       break;
269
270     high_buf = (RTPJitterBufferItem *) g_list_previous (high_buf);
271   }
272
273   low_buf = (RTPJitterBufferItem *) g_queue_peek_head_link (jbuf->packets);
274   while (low_buf) {
275     if (low_buf->dts != -1 || low_buf->pts != -1)
276       break;
277
278     low_buf = (RTPJitterBufferItem *) g_list_next (low_buf);
279   }
280
281   if (!high_buf || !low_buf || high_buf == low_buf) {
282     level = 0;
283   } else {
284     guint64 high_ts, low_ts;
285
286     high_ts = high_buf->dts != -1 ? high_buf->dts : high_buf->pts;
287     low_ts = low_buf->dts != -1 ? low_buf->dts : low_buf->pts;
288
289     if (high_ts > low_ts)
290       level = high_ts - low_ts;
291     else
292       level = 0;
293
294     GST_LOG_OBJECT (jbuf,
295         "low %" GST_TIME_FORMAT " high %" GST_TIME_FORMAT " level %"
296         G_GUINT64_FORMAT, GST_TIME_ARGS (low_ts), GST_TIME_ARGS (high_ts),
297         level);
298   }
299   return level;
300 }
301
302 static void
303 update_buffer_level (RTPJitterBuffer * jbuf, gint * percent)
304 {
305   gboolean post = FALSE;
306   guint64 level;
307
308   level = get_buffer_level (jbuf);
309   GST_DEBUG ("buffer level %" GST_TIME_FORMAT, GST_TIME_ARGS (level));
310
311   if (jbuf->buffering_disabled) {
312     GST_DEBUG ("buffering is disabled");
313     level = jbuf->high_level;
314   }
315
316   if (jbuf->buffering) {
317     post = TRUE;
318     if (level >= jbuf->high_level) {
319       GST_DEBUG ("buffering finished");
320       jbuf->buffering = FALSE;
321     }
322   } else {
323     if (level < jbuf->low_level) {
324       GST_DEBUG ("buffering started");
325       jbuf->buffering = TRUE;
326       post = TRUE;
327     }
328   }
329   if (post) {
330     gint perc;
331
332     if (jbuf->buffering && (jbuf->high_level != 0)) {
333       perc = (level * 100 / jbuf->high_level);
334       perc = MIN (perc, 100);
335     } else {
336       perc = 100;
337     }
338
339     if (percent)
340       *percent = perc;
341
342     GST_DEBUG ("buffering %d", perc);
343   }
344 }
345
346 /* For the clock skew we use a windowed low point averaging algorithm as can be
347  * found in Fober, Orlarey and Letz, 2005, "Real Time Clock Skew Estimation
348  * over Network Delays":
349  * http://www.grame.fr/Ressources/pub/TR-050601.pdf
350  * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.102.1546
351  *
352  * The idea is that the jitter is composed of:
353  *
354  *  J = N + n
355  *
356  *   N   : a constant network delay.
357  *   n   : random added noise. The noise is concentrated around 0
358  *
359  * In the receiver we can track the elapsed time at the sender with:
360  *
361  *  send_diff(i) = (Tsi - Ts0);
362  *
363  *   Tsi : The time at the sender at packet i
364  *   Ts0 : The time at the sender at the first packet
365  *
366  * This is the difference between the RTP timestamp in the first received packet
367  * and the current packet.
368  *
369  * At the receiver we have to deal with the jitter introduced by the network.
370  *
371  *  recv_diff(i) = (Tri - Tr0)
372  *
373  *   Tri : The time at the receiver at packet i
374  *   Tr0 : The time at the receiver at the first packet
375  *
376  * Both of these values contain a jitter Ji, a jitter for packet i, so we can
377  * write:
378  *
379  *  recv_diff(i) = (Cri + D + ni) - (Cr0 + D + n0))
380  *
381  *    Cri    : The time of the clock at the receiver for packet i
382  *    D + ni : The jitter when receiving packet i
383  *
384  * We see that the network delay is irrelevant here as we can elliminate D:
385  *
386  *  recv_diff(i) = (Cri + ni) - (Cr0 + n0))
387  *
388  * The drift is now expressed as:
389  *
390  *  Drift(i) = recv_diff(i) - send_diff(i);
391  *
392  * We now keep the W latest values of Drift and find the minimum (this is the
393  * one with the lowest network jitter and thus the one which is least affected
394  * by it). We average this lowest value to smooth out the resulting network skew.
395  *
396  * Both the window and the weighting used for averaging influence the accuracy
397  * of the drift estimation. Finding the correct parameters turns out to be a
398  * compromise between accuracy and inertia.
399  *
400  * We use a 2 second window or up to 512 data points, which is statistically big
401  * enough to catch spikes (FIXME, detect spikes).
402  * We also use a rather large weighting factor (125) to smoothly adapt. During
403  * startup, when filling the window, we use a parabolic weighting factor, the
404  * more the window is filled, the faster we move to the detected possible skew.
405  *
406  * Returns: @time adjusted with the clock skew.
407  */
408 static GstClockTime
409 calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time)
410 {
411   guint64 ext_rtptime;
412   guint64 send_diff, recv_diff;
413   gint64 delta;
414   gint64 old;
415   gint pos, i;
416   GstClockTime gstrtptime, out_time;
417   guint64 slope;
418
419   ext_rtptime = gst_rtp_buffer_ext_timestamp (&jbuf->ext_rtptime, rtptime);
420
421   if (jbuf->last_rtptime != -1 && ext_rtptime == jbuf->last_rtptime)
422     return jbuf->prev_out_time;
423
424   gstrtptime =
425       gst_util_uint64_scale_int (ext_rtptime, GST_SECOND, jbuf->clock_rate);
426
427   /* keep track of the last extended rtptime */
428   jbuf->last_rtptime = ext_rtptime;
429
430   send_diff = 0;
431   if (G_LIKELY (jbuf->base_rtptime != -1)) {
432     /* check elapsed time in RTP units */
433     if (G_LIKELY (gstrtptime >= jbuf->base_rtptime)) {
434       send_diff = gstrtptime - jbuf->base_rtptime;
435     } else {
436       /* elapsed time at sender, timestamps can go backwards and thus be
437        * smaller than our base time, schedule to take a new base time in
438        * that case. */
439       GST_WARNING ("backward timestamps at server, schedule resync");
440       jbuf->need_resync = TRUE;
441       send_diff = 0;
442     }
443   }
444
445   /* need resync, lock on to time and gstrtptime if we can, otherwise we
446    * do with the previous values */
447   if (G_UNLIKELY (jbuf->need_resync && time != -1)) {
448     GST_INFO ("resync to time %" GST_TIME_FORMAT ", rtptime %"
449         GST_TIME_FORMAT, GST_TIME_ARGS (time), GST_TIME_ARGS (gstrtptime));
450     rtp_jitter_buffer_resync (jbuf, time, gstrtptime, ext_rtptime, FALSE);
451     send_diff = 0;
452   }
453
454   GST_DEBUG ("extrtp %" G_GUINT64_FORMAT ", gstrtp %" GST_TIME_FORMAT ", base %"
455       GST_TIME_FORMAT ", send_diff %" GST_TIME_FORMAT, ext_rtptime,
456       GST_TIME_ARGS (gstrtptime), GST_TIME_ARGS (jbuf->base_rtptime),
457       GST_TIME_ARGS (send_diff));
458
459   /* we don't have an arrival timestamp so we can't do skew detection. we
460    * should still apply a timestamp based on RTP timestamp and base_time */
461   if (time == -1 || jbuf->base_time == -1)
462     goto no_skew;
463
464   /* elapsed time at receiver, includes the jitter */
465   recv_diff = time - jbuf->base_time;
466
467   /* measure the diff */
468   delta = ((gint64) recv_diff) - ((gint64) send_diff);
469
470   /* measure the slope, this gives a rought estimate between the sender speed
471    * and the receiver speed. This should be approximately 8, higher values
472    * indicate a burst (especially when the connection starts) */
473   if (recv_diff > 0)
474     slope = (send_diff * 8) / recv_diff;
475   else
476     slope = 8;
477
478   GST_DEBUG ("time %" GST_TIME_FORMAT ", base %" GST_TIME_FORMAT ", recv_diff %"
479       GST_TIME_FORMAT ", slope %" G_GUINT64_FORMAT, GST_TIME_ARGS (time),
480       GST_TIME_ARGS (jbuf->base_time), GST_TIME_ARGS (recv_diff), slope);
481
482   /* if the difference between the sender timeline and the receiver timeline
483    * changed too quickly we have to resync because the server likely restarted
484    * its timestamps. */
485   if (ABS (delta - jbuf->skew) > GST_SECOND) {
486     GST_WARNING ("delta - skew: %" GST_TIME_FORMAT " too big, reset skew",
487         GST_TIME_ARGS (ABS (delta - jbuf->skew)));
488     rtp_jitter_buffer_resync (jbuf, time, gstrtptime, ext_rtptime, TRUE);
489     send_diff = 0;
490     delta = 0;
491   }
492
493   pos = jbuf->window_pos;
494
495   if (G_UNLIKELY (jbuf->window_filling)) {
496     /* we are filling the window */
497     GST_DEBUG ("filling %d, delta %" G_GINT64_FORMAT, pos, delta);
498     jbuf->window[pos++] = delta;
499     /* calc the min delta we observed */
500     if (G_UNLIKELY (pos == 1 || delta < jbuf->window_min))
501       jbuf->window_min = delta;
502
503     if (G_UNLIKELY (send_diff >= MAX_TIME || pos >= MAX_WINDOW)) {
504       jbuf->window_size = pos;
505
506       /* window filled */
507       GST_DEBUG ("min %" G_GINT64_FORMAT, jbuf->window_min);
508
509       /* the skew is now the min */
510       jbuf->skew = jbuf->window_min;
511       jbuf->window_filling = FALSE;
512     } else {
513       gint perc_time, perc_window, perc;
514
515       /* figure out how much we filled the window, this depends on the amount of
516        * time we have or the max number of points we keep. */
517       perc_time = send_diff * 100 / MAX_TIME;
518       perc_window = pos * 100 / MAX_WINDOW;
519       perc = MAX (perc_time, perc_window);
520
521       /* make a parabolic function, the closer we get to the MAX, the more value
522        * we give to the scaling factor of the new value */
523       perc = perc * perc;
524
525       /* quickly go to the min value when we are filling up, slowly when we are
526        * just starting because we're not sure it's a good value yet. */
527       jbuf->skew =
528           (perc * jbuf->window_min + ((10000 - perc) * jbuf->skew)) / 10000;
529       jbuf->window_size = pos + 1;
530     }
531   } else {
532     /* pick old value and store new value. We keep the previous value in order
533      * to quickly check if the min of the window changed */
534     old = jbuf->window[pos];
535     jbuf->window[pos++] = delta;
536
537     if (G_UNLIKELY (delta <= jbuf->window_min)) {
538       /* if the new value we inserted is smaller or equal to the current min,
539        * it becomes the new min */
540       jbuf->window_min = delta;
541     } else if (G_UNLIKELY (old == jbuf->window_min)) {
542       gint64 min = G_MAXINT64;
543
544       /* if we removed the old min, we have to find a new min */
545       for (i = 0; i < jbuf->window_size; i++) {
546         /* we found another value equal to the old min, we can stop searching now */
547         if (jbuf->window[i] == old) {
548           min = old;
549           break;
550         }
551         if (jbuf->window[i] < min)
552           min = jbuf->window[i];
553       }
554       jbuf->window_min = min;
555     }
556     /* average the min values */
557     jbuf->skew = (jbuf->window_min + (124 * jbuf->skew)) / 125;
558     GST_DEBUG ("delta %" G_GINT64_FORMAT ", new min: %" G_GINT64_FORMAT,
559         delta, jbuf->window_min);
560   }
561   /* wrap around in the window */
562   if (G_UNLIKELY (pos >= jbuf->window_size))
563     pos = 0;
564   jbuf->window_pos = pos;
565
566 no_skew:
567   /* the output time is defined as the base timestamp plus the RTP time
568    * adjusted for the clock skew .*/
569   if (jbuf->base_time != -1) {
570     out_time = jbuf->base_time + send_diff;
571     /* skew can be negative and we don't want to make invalid timestamps */
572     if (jbuf->skew < 0 && out_time < -jbuf->skew) {
573       out_time = 0;
574     } else {
575       out_time += jbuf->skew;
576     }
577     /* check if timestamps are not going backwards, we can only check this if we
578      * have a previous out time and a previous send_diff */
579     if (G_LIKELY (jbuf->prev_out_time != -1 && jbuf->prev_send_diff != -1)) {
580       /* now check for backwards timestamps */
581       if (G_UNLIKELY (
582               /* if the server timestamps went up and the out_time backwards */
583               (send_diff > jbuf->prev_send_diff
584                   && out_time < jbuf->prev_out_time) ||
585               /* if the server timestamps went backwards and the out_time forwards */
586               (send_diff < jbuf->prev_send_diff
587                   && out_time > jbuf->prev_out_time) ||
588               /* if the server timestamps did not change */
589               send_diff == jbuf->prev_send_diff)) {
590         GST_DEBUG ("backwards timestamps, using previous time");
591         out_time = jbuf->prev_out_time;
592       }
593     }
594     if (time != -1 && out_time + jbuf->delay < time) {
595       /* if we are going to produce a timestamp that is later than the input
596        * timestamp, we need to reset the jitterbuffer. Likely the server paused
597        * temporarily */
598       GST_DEBUG ("out %" GST_TIME_FORMAT " + %" G_GUINT64_FORMAT " < time %"
599           GST_TIME_FORMAT ", reset jitterbuffer", GST_TIME_ARGS (out_time),
600           jbuf->delay, GST_TIME_ARGS (time));
601       rtp_jitter_buffer_resync (jbuf, time, gstrtptime, ext_rtptime, TRUE);
602       out_time = time;
603       send_diff = 0;
604     }
605   } else
606     out_time = -1;
607
608   jbuf->prev_out_time = out_time;
609   jbuf->prev_send_diff = send_diff;
610
611   GST_DEBUG ("skew %" G_GINT64_FORMAT ", out %" GST_TIME_FORMAT,
612       jbuf->skew, GST_TIME_ARGS (out_time));
613
614   return out_time;
615 }
616
617 static void
618 queue_do_insert (RTPJitterBuffer * jbuf, GList * list, GList * item)
619 {
620   GQueue *queue = jbuf->packets;
621
622   /* It's more likely that the packet was inserted at the tail of the queue */
623   if (G_LIKELY (list)) {
624     item->prev = list;
625     item->next = list->next;
626     list->next = item;
627   } else {
628     item->prev = NULL;
629     item->next = queue->head;
630     queue->head = item;
631   }
632   if (item->next)
633     item->next->prev = item;
634   else
635     queue->tail = item;
636   queue->length++;
637 }
638
639 /**
640  * rtp_jitter_buffer_insert:
641  * @jbuf: an #RTPJitterBuffer
642  * @item: an #RTPJitterBufferItem to insert
643  * @head: TRUE when the head element changed.
644  * @percent: the buffering percent after insertion
645  *
646  * Inserts @item into the packet queue of @jbuf. The sequence number of the
647  * packet will be used to sort the packets. This function takes ownerhip of
648  * @buf when the function returns %TRUE.
649  *
650  * When @head is %TRUE, the new packet was added at the head of the queue and
651  * will be available with the next call to rtp_jitter_buffer_pop() and
652  * rtp_jitter_buffer_peek().
653  *
654  * Returns: %FALSE if a packet with the same number already existed.
655  */
656 gboolean
657 rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, RTPJitterBufferItem * item,
658     gboolean * head, gint * percent)
659 {
660   GList *list, *event = NULL;
661   guint32 rtptime;
662   guint16 seqnum;
663   GstClockTime dts;
664
665   g_return_val_if_fail (jbuf != NULL, FALSE);
666   g_return_val_if_fail (item != NULL, FALSE);
667
668   list = jbuf->packets->tail;
669
670   /* no seqnum, simply append then */
671   if (item->seqnum == -1)
672     goto append;
673
674   seqnum = item->seqnum;
675
676   /* loop the list to skip strictly larger seqnum buffers */
677   for (; list; list = g_list_previous (list)) {
678     guint16 qseq;
679     gint gap;
680     RTPJitterBufferItem *qitem = (RTPJitterBufferItem *) list;
681
682     if (qitem->seqnum == -1) {
683       /* keep a pointer to the first consecutive event if not already
684        * set. we will insert the packet after the event if we can't find
685        * a packet with lower sequence number before the event. */
686       if (event == NULL)
687         event = list;
688       continue;
689     }
690
691     qseq = qitem->seqnum;
692
693     /* compare the new seqnum to the one in the buffer */
694     gap = gst_rtp_buffer_compare_seqnum (seqnum, qseq);
695
696     /* we hit a packet with the same seqnum, notify a duplicate */
697     if (G_UNLIKELY (gap == 0))
698       goto duplicate;
699
700     /* seqnum > qseq, we can stop looking */
701     if (G_LIKELY (gap < 0))
702       break;
703
704     /* if we've found a packet with greater sequence number, cleanup the
705      * event pointer as the packet will be inserted before the event */
706     event = NULL;
707   }
708
709   /* if event is set it means that packets before the event had smaller
710    * sequence number, so we will insert our packet after the event */
711   if (event)
712     list = event;
713
714   dts = item->dts;
715   if (item->rtptime == -1)
716     goto append;
717
718   rtptime = item->rtptime;
719
720   /* rtp time jumps are checked for during skew calculation, but bypassed
721    * in other mode, so mind those here and reset jb if needed.
722    * Only reset if valid input time, which is likely for UDP input
723    * where we expect this might happen due to async thread effects
724    * (in seek and state change cycles), but not so much for TCP input */
725   if (GST_CLOCK_TIME_IS_VALID (dts) &&
726       jbuf->mode != RTP_JITTER_BUFFER_MODE_SLAVE &&
727       jbuf->base_time != -1 && jbuf->last_rtptime != -1) {
728     GstClockTime ext_rtptime = jbuf->ext_rtptime;
729
730     ext_rtptime = gst_rtp_buffer_ext_timestamp (&ext_rtptime, rtptime);
731     if (ext_rtptime > jbuf->last_rtptime + 3 * jbuf->clock_rate ||
732         ext_rtptime + 3 * jbuf->clock_rate < jbuf->last_rtptime) {
733       /* reset even if we don't have valid incoming time;
734        * still better than producing possibly very bogus output timestamp */
735       GST_WARNING ("rtp delta too big, reset skew");
736       rtp_jitter_buffer_reset_skew (jbuf);
737     }
738   }
739
740   switch (jbuf->mode) {
741     case RTP_JITTER_BUFFER_MODE_NONE:
742     case RTP_JITTER_BUFFER_MODE_BUFFER:
743       /* send 0 as the first timestamp and -1 for the other ones. This will
744        * interpolate them from the RTP timestamps with a 0 origin. In buffering
745        * mode we will adjust the outgoing timestamps according to the amount of
746        * time we spent buffering. */
747       if (jbuf->base_time == -1)
748         dts = 0;
749       else
750         dts = -1;
751       break;
752     case RTP_JITTER_BUFFER_MODE_SYNCED:
753       /* synchronized clocks, take first timestamp as base, use RTP timestamps
754        * to interpolate */
755       if (jbuf->base_time != -1)
756         dts = -1;
757       break;
758     case RTP_JITTER_BUFFER_MODE_SLAVE:
759     default:
760       break;
761   }
762   /* do skew calculation by measuring the difference between rtptime and the
763    * receive dts, this function will return the skew corrected rtptime. */
764   item->pts = calculate_skew (jbuf, rtptime, dts);
765
766 append:
767   queue_do_insert (jbuf, list, (GList *) item);
768
769   /* buffering mode, update buffer stats */
770   if (jbuf->mode == RTP_JITTER_BUFFER_MODE_BUFFER)
771     update_buffer_level (jbuf, percent);
772   else if (percent)
773     *percent = -1;
774
775   /* head was changed when we did not find a previous packet, we set the return
776    * flag when requested. */
777   if (G_LIKELY (head))
778     *head = (list == NULL);
779
780   return TRUE;
781
782   /* ERRORS */
783 duplicate:
784   {
785     GST_WARNING ("duplicate packet %d found", (gint) seqnum);
786     return FALSE;
787   }
788 }
789
790 /**
791  * rtp_jitter_buffer_pop:
792  * @jbuf: an #RTPJitterBuffer
793  * @percent: the buffering percent
794  *
795  * Pops the oldest buffer from the packet queue of @jbuf. The popped buffer will
796  * have its timestamp adjusted with the incomming running_time and the detected
797  * clock skew.
798  *
799  * Returns: a #GstBuffer or %NULL when there was no packet in the queue.
800  */
801 RTPJitterBufferItem *
802 rtp_jitter_buffer_pop (RTPJitterBuffer * jbuf, gint * percent)
803 {
804   GList *item = NULL;
805   GQueue *queue;
806
807   g_return_val_if_fail (jbuf != NULL, NULL);
808
809   queue = jbuf->packets;
810
811   item = queue->head;
812   if (item) {
813     queue->head = item->next;
814     if (queue->head)
815       queue->head->prev = NULL;
816     else
817       queue->tail = NULL;
818     queue->length--;
819   }
820
821   /* buffering mode, update buffer stats */
822   if (jbuf->mode == RTP_JITTER_BUFFER_MODE_BUFFER)
823     update_buffer_level (jbuf, percent);
824   else if (percent)
825     *percent = -1;
826
827   return (RTPJitterBufferItem *) item;
828 }
829
830 /**
831  * rtp_jitter_buffer_peek:
832  * @jbuf: an #RTPJitterBuffer
833  *
834  * Peek the oldest buffer from the packet queue of @jbuf.
835  *
836  * See rtp_jitter_buffer_insert() to check when an older packet was
837  * added.
838  *
839  * Returns: a #GstBuffer or %NULL when there was no packet in the queue.
840  */
841 RTPJitterBufferItem *
842 rtp_jitter_buffer_peek (RTPJitterBuffer * jbuf)
843 {
844   g_return_val_if_fail (jbuf != NULL, NULL);
845
846   return (RTPJitterBufferItem *) jbuf->packets->head;
847 }
848
849 /**
850  * rtp_jitter_buffer_flush:
851  * @jbuf: an #RTPJitterBuffer
852  * @free_func: function to free each item
853  * @user_data: user data passed to @free_func
854  *
855  * Flush all packets from the jitterbuffer.
856  */
857 void
858 rtp_jitter_buffer_flush (RTPJitterBuffer * jbuf, GFunc free_func,
859     gpointer user_data)
860 {
861   GList *item;
862
863   g_return_if_fail (jbuf != NULL);
864   g_return_if_fail (free_func != NULL);
865
866   while ((item = g_queue_pop_head_link (jbuf->packets)))
867     free_func ((RTPJitterBufferItem *) item, user_data);
868 }
869
870 /**
871  * rtp_jitter_buffer_is_buffering:
872  * @jbuf: an #RTPJitterBuffer
873  *
874  * Check if @jbuf is buffering currently. Users of the jitterbuffer should not
875  * pop packets while in buffering mode.
876  *
877  * Returns: the buffering state of @jbuf
878  */
879 gboolean
880 rtp_jitter_buffer_is_buffering (RTPJitterBuffer * jbuf)
881 {
882   return jbuf->buffering && !jbuf->buffering_disabled;
883 }
884
885 /**
886  * rtp_jitter_buffer_set_buffering:
887  * @jbuf: an #RTPJitterBuffer
888  * @buffering: the new buffering state
889  *
890  * Forces @jbuf to go into the buffering state.
891  */
892 void
893 rtp_jitter_buffer_set_buffering (RTPJitterBuffer * jbuf, gboolean buffering)
894 {
895   jbuf->buffering = buffering;
896 }
897
898 /**
899  * rtp_jitter_buffer_get_percent:
900  * @jbuf: an #RTPJitterBuffer
901  *
902  * Get the buffering percent of the jitterbuffer.
903  *
904  * Returns: the buffering percent
905  */
906 gint
907 rtp_jitter_buffer_get_percent (RTPJitterBuffer * jbuf)
908 {
909   gint percent;
910   guint64 level;
911
912   if (G_UNLIKELY (jbuf->high_level == 0))
913     return 100;
914
915   if (G_UNLIKELY (jbuf->buffering_disabled))
916     return 100;
917
918   level = get_buffer_level (jbuf);
919   percent = (level * 100 / jbuf->high_level);
920   percent = MIN (percent, 100);
921
922   return percent;
923 }
924
925 /**
926  * rtp_jitter_buffer_num_packets:
927  * @jbuf: an #RTPJitterBuffer
928  *
929  * Get the number of packets currently in "jbuf.
930  *
931  * Returns: The number of packets in @jbuf.
932  */
933 guint
934 rtp_jitter_buffer_num_packets (RTPJitterBuffer * jbuf)
935 {
936   g_return_val_if_fail (jbuf != NULL, 0);
937
938   return jbuf->packets->length;
939 }
940
941 /**
942  * rtp_jitter_buffer_get_ts_diff:
943  * @jbuf: an #RTPJitterBuffer
944  *
945  * Get the difference between the timestamps of first and last packet in the
946  * jitterbuffer.
947  *
948  * Returns: The difference expressed in the timestamp units of the packets.
949  */
950 guint32
951 rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer * jbuf)
952 {
953   guint64 high_ts, low_ts;
954   RTPJitterBufferItem *high_buf, *low_buf;
955   guint32 result;
956
957   g_return_val_if_fail (jbuf != NULL, 0);
958
959   high_buf = (RTPJitterBufferItem *) g_queue_peek_head_link (jbuf->packets);
960   low_buf = (RTPJitterBufferItem *) g_queue_peek_tail_link (jbuf->packets);
961
962   if (!high_buf || !low_buf || high_buf == low_buf)
963     return 0;
964
965   high_ts = high_buf->rtptime;
966   low_ts = low_buf->rtptime;
967
968   /* it needs to work if ts wraps */
969   if (high_ts >= low_ts) {
970     result = (guint32) (high_ts - low_ts);
971   } else {
972     result = (guint32) (high_ts + G_MAXUINT32 + 1 - low_ts);
973   }
974   return result;
975 }
976
977 /**
978  * rtp_jitter_buffer_get_sync:
979  * @jbuf: an #RTPJitterBuffer
980  * @rtptime: result RTP time
981  * @timestamp: result GStreamer timestamp
982  * @clock_rate: clock-rate of @rtptime
983  * @last_rtptime: last seen rtptime.
984  *
985  * Calculates the relation between the RTP timestamp and the GStreamer timestamp
986  * used for constructing timestamps.
987  *
988  * For extended RTP timestamp @rtptime with a clock-rate of @clock_rate,
989  * the GStreamer timestamp is currently @timestamp.
990  *
991  * The last seen extended RTP timestamp with clock-rate @clock-rate is returned in
992  * @last_rtptime.
993  */
994 void
995 rtp_jitter_buffer_get_sync (RTPJitterBuffer * jbuf, guint64 * rtptime,
996     guint64 * timestamp, guint32 * clock_rate, guint64 * last_rtptime)
997 {
998   if (rtptime)
999     *rtptime = jbuf->base_extrtp;
1000   if (timestamp)
1001     *timestamp = jbuf->base_time + jbuf->skew;
1002   if (clock_rate)
1003     *clock_rate = jbuf->clock_rate;
1004   if (last_rtptime)
1005     *last_rtptime = jbuf->last_rtptime;
1006 }