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