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