70a49c1e7b4bbec69c52040d73f513f653402002
[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., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, 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 /* static guint rtp_jitter_buffer_signals[LAST_SIGNAL] = { 0 }; */
48
49 G_DEFINE_TYPE (RTPJitterBuffer, rtp_jitter_buffer, G_TYPE_OBJECT);
50
51 static void
52 rtp_jitter_buffer_class_init (RTPJitterBufferClass * klass)
53 {
54   GObjectClass *gobject_class;
55
56   gobject_class = (GObjectClass *) klass;
57
58   gobject_class->finalize = rtp_jitter_buffer_finalize;
59
60   GST_DEBUG_CATEGORY_INIT (rtp_jitter_buffer_debug, "rtpjitterbuffer", 0,
61       "RTP Jitter Buffer");
62 }
63
64 static void
65 rtp_jitter_buffer_init (RTPJitterBuffer * jbuf)
66 {
67   jbuf->packets = g_queue_new ();
68
69   rtp_jitter_buffer_reset_skew (jbuf);
70 }
71
72 static void
73 rtp_jitter_buffer_finalize (GObject * object)
74 {
75   RTPJitterBuffer *jbuf;
76
77   jbuf = RTP_JITTER_BUFFER_CAST (object);
78
79   rtp_jitter_buffer_flush (jbuf);
80   g_queue_free (jbuf->packets);
81
82   G_OBJECT_CLASS (rtp_jitter_buffer_parent_class)->finalize (object);
83 }
84
85 /**
86  * rtp_jitter_buffer_new:
87  *
88  * Create an #RTPJitterBuffer.
89  *
90  * Returns: a new #RTPJitterBuffer. Use g_object_unref() after usage.
91  */
92 RTPJitterBuffer *
93 rtp_jitter_buffer_new (void)
94 {
95   RTPJitterBuffer *jbuf;
96
97   jbuf = g_object_new (RTP_TYPE_JITTER_BUFFER, NULL);
98
99   return jbuf;
100 }
101
102 void
103 rtp_jitter_buffer_reset_skew (RTPJitterBuffer * jbuf)
104 {
105   jbuf->base_time = -1;
106   jbuf->base_rtptime = -1;
107   jbuf->ext_rtptime = -1;
108   jbuf->window_pos = 0;
109   jbuf->window_filling = TRUE;
110   jbuf->window_min = 0;
111   jbuf->skew = 0;
112   jbuf->prev_send_diff = -1;
113 }
114
115 /* For the clock skew we use a windowed low point averaging algorithm as can be
116  * found in http://www.grame.fr/pub/TR-050601.pdf. The idea is that the jitter is
117  * composed of:
118  *
119  *  J = N + n
120  *
121  *   N   : a constant network delay.
122  *   n   : random added noise. The noise is concentrated around 0
123  *
124  * In the receiver we can track the elapsed time at the sender with:
125  *
126  *  send_diff(i) = (Tsi - Ts0);
127  *
128  *   Tsi : The time at the sender at packet i
129  *   Ts0 : The time at the sender at the first packet
130  *
131  * This is the difference between the RTP timestamp in the first received packet
132  * and the current packet.
133  *
134  * At the receiver we have to deal with the jitter introduced by the network.
135  *
136  *  recv_diff(i) = (Tri - Tr0)
137  *
138  *   Tri : The time at the receiver at packet i
139  *   Tr0 : The time at the receiver at the first packet
140  *
141  * Both of these values contain a jitter Ji, a jitter for packet i, so we can
142  * write:
143  *
144  *  recv_diff(i) = (Cri + D + ni) - (Cr0 + D + n0))
145  *
146  *    Cri    : The time of the clock at the receiver for packet i
147  *    D + ni : The jitter when receiving packet i
148  *
149  * We see that the network delay is irrelevant here as we can elliminate D:
150  *
151  *  recv_diff(i) = (Cri + ni) - (Cr0 + n0))
152  *
153  * The drift is now expressed as:
154  *
155  *  Drift(i) = recv_diff(i) - send_diff(i);
156  *
157  * We now keep the W latest values of Drift and find the minimum (this is the
158  * one with the lowest network jitter and thus the one which is least affected
159  * by it). We average this lowest value to smooth out the resulting network skew.
160  *
161  * Both the window and the weighting used for averaging influence the accuracy
162  * of the drift estimation. Finding the correct parameters turns out to be a
163  * compromise between accuracy and inertia. 
164  *
165  * We use a 2 second window or up to 512 data points, which is statistically big
166  * enough to catch spikes (FIXME, detect spikes).
167  * We also use a rather large weighting factor (125) to smoothly adapt. During
168  * startup, when filling the window, we use a parabolic weighting factor, the
169  * more the window is filled, the faster we move to the detected possible skew.
170  *
171  * Returns: @time adjusted with the clock skew.
172  */
173 static GstClockTime
174 calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time,
175     guint32 clock_rate)
176 {
177   guint64 ext_rtptime;
178   guint64 send_diff, recv_diff;
179   gint64 delta;
180   gint64 old;
181   gint pos, i;
182   GstClockTime gstrtptime, out_time;
183
184   ext_rtptime = gst_rtp_buffer_ext_timestamp (&jbuf->ext_rtptime, rtptime);
185
186   gstrtptime = gst_util_uint64_scale_int (ext_rtptime, GST_SECOND, clock_rate);
187
188 again:
189   /* first time, lock on to time and gstrtptime */
190   if (jbuf->base_time == -1)
191     jbuf->base_time = time;
192   if (jbuf->base_rtptime == -1)
193     jbuf->base_rtptime = gstrtptime;
194
195   if (gstrtptime >= jbuf->base_rtptime)
196     send_diff = gstrtptime - jbuf->base_rtptime;
197   else {
198     /* elapsed time at sender, timestamps can go backwards and thus be smaller
199      * than our base time, take a new base time in that case. */
200     GST_DEBUG ("backward timestamps at server, taking new base time");
201     jbuf->base_rtptime = gstrtptime;
202     jbuf->base_time = time;
203     send_diff = 0;
204   }
205
206   GST_DEBUG ("extrtp %" G_GUINT64_FORMAT ", gstrtp %" GST_TIME_FORMAT ", base %"
207       GST_TIME_FORMAT ", send_diff %" GST_TIME_FORMAT, ext_rtptime,
208       GST_TIME_ARGS (gstrtptime), GST_TIME_ARGS (jbuf->base_rtptime),
209       GST_TIME_ARGS (send_diff));
210
211   if (jbuf->prev_send_diff != -1 && time != -1) {
212     gint64 delta_diff;
213
214     if (send_diff > jbuf->prev_send_diff)
215       delta_diff = send_diff - jbuf->prev_send_diff;
216     else
217       delta_diff = jbuf->prev_send_diff - send_diff;
218
219     /* server changed rtp timestamps too quickly, reset skew detection and start
220      * again. This value is sortof arbitrary and can be a bad measurement up if
221      * there are many packets missing because then we get a big gap that is
222      * unrelated to a timestamp switch. */
223     if (delta_diff > GST_SECOND) {
224       GST_DEBUG ("delta changed too quickly %" GST_TIME_FORMAT " reset skew",
225           GST_TIME_ARGS (delta_diff));
226       rtp_jitter_buffer_reset_skew (jbuf);
227       goto again;
228     }
229   }
230   jbuf->prev_send_diff = send_diff;
231
232   /* we don't have an arrival timestamp so we can't do skew detection. we
233    * should still apply a timestamp based on RTP timestamp and base_time */
234   if (time == -1)
235     goto no_skew;
236
237   /* elapsed time at receiver, includes the jitter */
238   recv_diff = time - jbuf->base_time;
239
240   GST_DEBUG ("time %" GST_TIME_FORMAT ", base %" GST_TIME_FORMAT ", recv_diff %"
241       GST_TIME_FORMAT, GST_TIME_ARGS (time), GST_TIME_ARGS (jbuf->base_time),
242       GST_TIME_ARGS (recv_diff));
243
244   /* measure the diff */
245   delta = ((gint64) recv_diff) - ((gint64) send_diff);
246
247   pos = jbuf->window_pos;
248
249   if (jbuf->window_filling) {
250     /* we are filling the window */
251     GST_DEBUG ("filling %d, delta %" G_GINT64_FORMAT, pos, delta);
252     jbuf->window[pos++] = delta;
253     /* calc the min delta we observed */
254     if (pos == 1 || delta < jbuf->window_min)
255       jbuf->window_min = delta;
256
257     if (send_diff >= MAX_TIME || pos >= MAX_WINDOW) {
258       jbuf->window_size = pos;
259
260       /* window filled */
261       GST_DEBUG ("min %" G_GINT64_FORMAT, jbuf->window_min);
262
263       /* the skew is now the min */
264       jbuf->skew = jbuf->window_min;
265       jbuf->window_filling = FALSE;
266     } else {
267       gint perc_time, perc_window, perc;
268
269       /* figure out how much we filled the window, this depends on the amount of
270        * time we have or the max number of points we keep. */
271       perc_time = send_diff * 100 / MAX_TIME;
272       perc_window = pos * 100 / MAX_WINDOW;
273       perc = MAX (perc_time, perc_window);
274
275       /* make a parabolic function, the closer we get to the MAX, the more value
276        * we give to the scaling factor of the new value */
277       perc = perc * perc;
278
279       /* quickly go to the min value when we are filling up, slowly when we are
280        * just starting because we're not sure it's a good value yet. */
281       jbuf->skew =
282           (perc * jbuf->window_min + ((10000 - perc) * jbuf->skew)) / 10000;
283       jbuf->window_size = pos + 1;
284     }
285   } else {
286     /* pick old value and store new value. We keep the previous value in order
287      * to quickly check if the min of the window changed */
288     old = jbuf->window[pos];
289     jbuf->window[pos++] = delta;
290
291     if (delta <= jbuf->window_min) {
292       /* if the new value we inserted is smaller or equal to the current min,
293        * it becomes the new min */
294       jbuf->window_min = delta;
295     } else if (old == jbuf->window_min) {
296       gint64 min = G_MAXINT64;
297
298       /* if we removed the old min, we have to find a new min */
299       for (i = 0; i < jbuf->window_size; i++) {
300         /* we found another value equal to the old min, we can stop searching now */
301         if (jbuf->window[i] == old) {
302           min = old;
303           break;
304         }
305         if (jbuf->window[i] < min)
306           min = jbuf->window[i];
307       }
308       jbuf->window_min = min;
309     }
310     /* average the min values */
311     jbuf->skew = (jbuf->window_min + (124 * jbuf->skew)) / 125;
312     GST_DEBUG ("delta %" G_GINT64_FORMAT ", new min: %" G_GINT64_FORMAT,
313         delta, jbuf->window_min);
314   }
315   /* wrap around in the window */
316   if (pos >= jbuf->window_size)
317     pos = 0;
318   jbuf->window_pos = pos;
319
320 no_skew:
321   /* the output time is defined as the base timestamp plus the RTP time
322    * adjusted for the clock skew .*/
323   out_time = jbuf->base_time + send_diff + jbuf->skew;
324
325   GST_DEBUG ("skew %" G_GINT64_FORMAT ", out %" GST_TIME_FORMAT,
326       jbuf->skew, GST_TIME_ARGS (out_time));
327
328   return out_time;
329 }
330
331 /**
332  * rtp_jitter_buffer_insert:
333  * @jbuf: an #RTPJitterBuffer
334  * @buf: a buffer
335  * @time: a running_time when this buffer was received in nanoseconds
336  * @clock_rate: the clock-rate of the payload of @buf
337  * @tail: TRUE when the tail element changed.
338  *
339  * Inserts @buf into the packet queue of @jbuf. The sequence number of the
340  * packet will be used to sort the packets. This function takes ownerhip of
341  * @buf when the function returns %TRUE.
342  * @buf should have writable metadata when calling this function.
343  *
344  * Returns: %FALSE if a packet with the same number already existed.
345  */
346 gboolean
347 rtp_jitter_buffer_insert (RTPJitterBuffer * jbuf, GstBuffer * buf,
348     GstClockTime time, guint32 clock_rate, gboolean * tail)
349 {
350   GList *list;
351   guint32 rtptime;
352   guint16 seqnum;
353
354   g_return_val_if_fail (jbuf != NULL, FALSE);
355   g_return_val_if_fail (buf != NULL, FALSE);
356
357   seqnum = gst_rtp_buffer_get_seq (buf);
358
359   /* loop the list to skip strictly smaller seqnum buffers */
360   for (list = jbuf->packets->head; list; list = g_list_next (list)) {
361     guint16 qseq;
362     gint gap;
363
364     qseq = gst_rtp_buffer_get_seq (GST_BUFFER_CAST (list->data));
365
366     /* compare the new seqnum to the one in the buffer */
367     gap = gst_rtp_buffer_compare_seqnum (seqnum, qseq);
368
369     /* we hit a packet with the same seqnum, notify a duplicate */
370     if (G_UNLIKELY (gap == 0))
371       goto duplicate;
372
373     /* seqnum > qseq, we can stop looking */
374     if (G_LIKELY (gap < 0))
375       break;
376   }
377
378   /* do skew calculation by measuring the difference between rtptime and the
379    * receive time, this function will retimestamp @buf with the skew corrected
380    * running time. */
381   rtptime = gst_rtp_buffer_get_timestamp (buf);
382   time = calculate_skew (jbuf, rtptime, time, clock_rate);
383   GST_BUFFER_TIMESTAMP (buf) = time;
384
385   if (list)
386     g_queue_insert_before (jbuf->packets, list, buf);
387   else
388     g_queue_push_tail (jbuf->packets, buf);
389
390   /* tail was changed when we did not find a previous packet, we set the return
391    * flag when requested. */
392   if (tail)
393     *tail = (list == NULL);
394
395   return TRUE;
396
397   /* ERRORS */
398 duplicate:
399   {
400     GST_WARNING ("duplicate packet %d found", (gint) seqnum);
401     return FALSE;
402   }
403 }
404
405 /**
406  * rtp_jitter_buffer_pop:
407  * @jbuf: an #RTPJitterBuffer
408  *
409  * Pops the oldest buffer from the packet queue of @jbuf. The popped buffer will
410  * have its timestamp adjusted with the incomming running_time and the detected
411  * clock skew.
412  *
413  * Returns: a #GstBuffer or %NULL when there was no packet in the queue.
414  */
415 GstBuffer *
416 rtp_jitter_buffer_pop (RTPJitterBuffer * jbuf)
417 {
418   GstBuffer *buf;
419
420   g_return_val_if_fail (jbuf != NULL, FALSE);
421
422   buf = g_queue_pop_tail (jbuf->packets);
423
424   return buf;
425 }
426
427 /**
428  * rtp_jitter_buffer_peek:
429  * @jbuf: an #RTPJitterBuffer
430  *
431  * Peek the oldest buffer from the packet queue of @jbuf. Register a callback
432  * with rtp_jitter_buffer_set_tail_changed() to be notified when an older packet
433  * was inserted in the queue.
434  *
435  * Returns: a #GstBuffer or %NULL when there was no packet in the queue.
436  */
437 GstBuffer *
438 rtp_jitter_buffer_peek (RTPJitterBuffer * jbuf)
439 {
440   GstBuffer *buf;
441
442   g_return_val_if_fail (jbuf != NULL, FALSE);
443
444   buf = g_queue_peek_tail (jbuf->packets);
445
446   return buf;
447 }
448
449 /**
450  * rtp_jitter_buffer_flush:
451  * @jbuf: an #RTPJitterBuffer
452  *
453  * Flush all packets from the jitterbuffer.
454  */
455 void
456 rtp_jitter_buffer_flush (RTPJitterBuffer * jbuf)
457 {
458   GstBuffer *buffer;
459
460   g_return_if_fail (jbuf != NULL);
461
462   while ((buffer = g_queue_pop_head (jbuf->packets)))
463     gst_buffer_unref (buffer);
464 }
465
466 /**
467  * rtp_jitter_buffer_num_packets:
468  * @jbuf: an #RTPJitterBuffer
469  *
470  * Get the number of packets currently in "jbuf.
471  *
472  * Returns: The number of packets in @jbuf.
473  */
474 guint
475 rtp_jitter_buffer_num_packets (RTPJitterBuffer * jbuf)
476 {
477   g_return_val_if_fail (jbuf != NULL, 0);
478
479   return jbuf->packets->length;
480 }
481
482 /**
483  * rtp_jitter_buffer_get_ts_diff:
484  * @jbuf: an #RTPJitterBuffer
485  *
486  * Get the difference between the timestamps of first and last packet in the
487  * jitterbuffer.
488  *
489  * Returns: The difference expressed in the timestamp units of the packets.
490  */
491 guint32
492 rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer * jbuf)
493 {
494   guint64 high_ts, low_ts;
495   GstBuffer *high_buf, *low_buf;
496   guint32 result;
497
498   g_return_val_if_fail (jbuf != NULL, 0);
499
500   high_buf = g_queue_peek_head (jbuf->packets);
501   low_buf = g_queue_peek_tail (jbuf->packets);
502
503   if (!high_buf || !low_buf || high_buf == low_buf)
504     return 0;
505
506   high_ts = gst_rtp_buffer_get_timestamp (high_buf);
507   low_ts = gst_rtp_buffer_get_timestamp (low_buf);
508
509   /* it needs to work if ts wraps */
510   if (high_ts >= low_ts) {
511     result = (guint32) (high_ts - low_ts);
512   } else {
513     result = (guint32) (high_ts + G_MAXUINT32 + 1 - low_ts);
514   }
515   return result;
516 }