• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  *
3  * Copyright (C) 2009 Nokia Corporation and its subsidiary(-ies)
4  *               contact: <stefan.kost@nokia.com>
5  * Copyright (C) 2012 Cisco Systems, Inc
6  *               Authors: Kelley Rogers <kelro@cisco.com>
7  *               Havard Graff <hgraff@cisco.com>
8  * Copyright (C) 2013-2016 Pexip AS
9  *               Stian Selnes <stian@pexip>
10  *               Havard Graff <havard@pexip>
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public
23  * License along with this library; if not, write to the
24  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25  * Boston, MA 02110-1301, USA.
26  */
27 
28 #include <gst/check/gstcheck.h>
29 #include <gst/check/gsttestclock.h>
30 #include <gst/check/gstharness.h>
31 #include <gst/rtp/gstrtpbuffer.h>
32 
33 /* For ease of programming we use globals to keep refs for our floating
34  * src and sink pads we create; otherwise we always have to do get_pad,
35  * get_peer, and then remove references in every test function */
36 static GstPad *mysrcpad, *mysinkpad;
37 /* we also have a list of src buffers */
38 static GList *inbuffers = NULL;
39 static gint num_dropped = 0;
40 
41 #define RTP_CAPS_STRING    \
42     "application/x-rtp, "               \
43     "media = (string)audio, "           \
44     "payload = (int) 0, "               \
45     "clock-rate = (int) 8000, "         \
46     "encoding-name = (string)PCMU"
47 
48 #define RTP_FRAME_SIZE 20
49 
50 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
51     GST_PAD_SINK,
52     GST_PAD_ALWAYS,
53     GST_STATIC_CAPS ("application/x-rtp")
54     );
55 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
56     GST_PAD_SRC,
57     GST_PAD_ALWAYS,
58     GST_STATIC_CAPS ("application/x-rtp, "
59         "clock-rate = (int) [ 1, 2147483647 ]")
60     );
61 
62 static void
buffer_dropped(G_GNUC_UNUSED gpointer data,GstMiniObject * obj)63 buffer_dropped (G_GNUC_UNUSED gpointer data, GstMiniObject * obj)
64 {
65   GST_DEBUG ("dropping buffer %p", obj);
66   num_dropped++;
67 }
68 
69 static GstElement *
setup_jitterbuffer(gint num_buffers)70 setup_jitterbuffer (gint num_buffers)
71 {
72   GstElement *jitterbuffer;
73   GstClock *clock;
74   GstBuffer *buffer;
75   GstCaps *caps;
76   /* a 20 sample audio block (2,5 ms) generated with
77    * gst-launch audiotestsrc wave=silence blocksize=40 num-buffers=3 !
78    *    "audio/x-raw,channels=1,rate=8000" ! mulawenc ! rtppcmupay !
79    *     fakesink dump=1
80    */
81   guint8 in[] = {
82     /* first 4 bytes are rtp-header, next 4 bytes are timestamp */
83     0x80, 0x80, 0x1c, 0x24, 0x46, 0xcd, 0xb7, 0x11, 0x3c, 0x3a, 0x7c, 0x5b,
84     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
85     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
86   };
87   GstClockTime ts = G_GUINT64_CONSTANT (0);
88   GstClockTime tso = gst_util_uint64_scale (RTP_FRAME_SIZE, GST_SECOND, 8000);
89   /*guint latency = GST_TIME_AS_MSECONDS (num_buffers * tso); */
90   gint i;
91 
92   GST_DEBUG ("setup_jitterbuffer");
93   jitterbuffer = gst_check_setup_element ("rtpjitterbuffer");
94   /* we need a clock here */
95   clock = gst_system_clock_obtain ();
96   gst_element_set_clock (jitterbuffer, clock);
97   gst_object_unref (clock);
98   /* setup latency */
99   /* latency would be 7 for 3 buffers here, default is 200
100      g_object_set (G_OBJECT (jitterbuffer), "latency", latency, NULL);
101      GST_INFO_OBJECT (jitterbuffer, "set latency to %u ms", latency);
102    */
103 
104   mysrcpad = gst_check_setup_src_pad (jitterbuffer, &srctemplate);
105   mysinkpad = gst_check_setup_sink_pad (jitterbuffer, &sinktemplate);
106   gst_pad_set_active (mysrcpad, TRUE);
107   gst_pad_set_active (mysinkpad, TRUE);
108 
109   /* create n buffers */
110   caps = gst_caps_from_string (RTP_CAPS_STRING);
111   gst_check_setup_events (mysrcpad, jitterbuffer, caps, GST_FORMAT_TIME);
112   gst_caps_unref (caps);
113 
114   for (i = 0; i < num_buffers; i++) {
115     buffer = gst_buffer_new_and_alloc (sizeof (in));
116     gst_buffer_fill (buffer, 0, in, sizeof (in));
117     GST_BUFFER_DTS (buffer) = ts;
118     GST_BUFFER_PTS (buffer) = ts;
119     GST_BUFFER_DURATION (buffer) = tso;
120     gst_mini_object_weak_ref (GST_MINI_OBJECT (buffer), buffer_dropped, NULL);
121     GST_DEBUG ("created buffer: %p", buffer);
122 
123     if (!i)
124       GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
125 
126     inbuffers = g_list_append (inbuffers, buffer);
127 
128     /* hackish way to update the rtp header */
129     in[1] = 0x00;
130     in[3]++;                    /* seqnumber */
131     in[7] += RTP_FRAME_SIZE;    /* inc. timestamp with framesize */
132     ts += tso;
133   }
134   num_dropped = 0;
135 
136   return jitterbuffer;
137 }
138 
139 static GstStateChangeReturn
start_jitterbuffer(GstElement * jitterbuffer)140 start_jitterbuffer (GstElement * jitterbuffer)
141 {
142   GstStateChangeReturn ret;
143   GstClockTime now;
144   GstClock *clock;
145 
146   clock = gst_element_get_clock (jitterbuffer);
147   now = gst_clock_get_time (clock);
148   gst_object_unref (clock);
149 
150   gst_element_set_base_time (jitterbuffer, now);
151   ret = gst_element_set_state (jitterbuffer, GST_STATE_PLAYING);
152 
153   return ret;
154 }
155 
156 static void
cleanup_jitterbuffer(GstElement * jitterbuffer)157 cleanup_jitterbuffer (GstElement * jitterbuffer)
158 {
159   GST_DEBUG ("cleanup_jitterbuffer");
160 
161   g_list_foreach (buffers, (GFunc) gst_mini_object_unref, NULL);
162   g_list_free (buffers);
163   buffers = NULL;
164 
165   g_list_free (inbuffers);
166   inbuffers = NULL;
167 
168   gst_pad_set_active (mysrcpad, FALSE);
169   gst_pad_set_active (mysinkpad, FALSE);
170   gst_element_set_state (jitterbuffer, GST_STATE_NULL);
171   gst_check_teardown_src_pad (jitterbuffer);
172   gst_check_teardown_sink_pad (jitterbuffer);
173   gst_check_teardown_element (jitterbuffer);
174 }
175 
176 static void
check_jitterbuffer_results(gint num_buffers)177 check_jitterbuffer_results (gint num_buffers)
178 {
179   GstBuffer *buffer;
180   GList *node;
181   GstClockTime ts = G_GUINT64_CONSTANT (0);
182   GstClockTime tso = gst_util_uint64_scale (RTP_FRAME_SIZE, GST_SECOND, 8000);
183   GstMapInfo map;
184   guint16 prev_sn = 0, cur_sn;
185   guint32 prev_ts = 0, cur_ts;
186 
187   /* sleep for twice the latency */
188   g_usleep (400 * 1000);
189 
190   GST_INFO ("of %d buffer %d/%d received/dropped", num_buffers,
191       g_list_length (buffers), num_dropped);
192   /* if this fails, not all buffers have been processed */
193   fail_unless_equals_int ((g_list_length (buffers) + num_dropped), num_buffers);
194 
195   /* check the buffer list */
196   fail_unless_equals_int (g_list_length (buffers), num_buffers);
197   for (node = buffers; node; node = g_list_next (node)) {
198     fail_if ((buffer = (GstBuffer *) node->data) == NULL);
199     fail_if (GST_BUFFER_PTS (buffer) != ts);
200     gst_buffer_map (buffer, &map, GST_MAP_READ);
201     cur_sn = ((guint16) map.data[2] << 8) | map.data[3];
202     cur_ts = ((guint32) map.data[4] << 24) | ((guint32) map.data[5] << 16) |
203         ((guint32) map.data[6] << 8) | map.data[7];
204     gst_buffer_unmap (buffer, &map);
205 
206     if (node != buffers) {
207       fail_unless (cur_sn > prev_sn);
208       fail_unless (cur_ts > prev_ts);
209 
210       prev_sn = cur_sn;
211       prev_ts = cur_ts;
212     }
213     ts += tso;
214   }
215 }
216 
GST_START_TEST(test_push_forward_seq)217 GST_START_TEST (test_push_forward_seq)
218 {
219   GstElement *jitterbuffer;
220   const guint num_buffers = 3;
221   GstBuffer *buffer;
222   GList *node;
223 
224   jitterbuffer = setup_jitterbuffer (num_buffers);
225   fail_unless (start_jitterbuffer (jitterbuffer)
226       == GST_STATE_CHANGE_SUCCESS, "could not set to playing");
227 
228   /* push buffers: 0,1,2, */
229   for (node = inbuffers; node; node = g_list_next (node)) {
230     buffer = (GstBuffer *) node->data;
231     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
232   }
233 
234   /* check the buffer list */
235   check_jitterbuffer_results (num_buffers);
236 
237   /* cleanup */
238   cleanup_jitterbuffer (jitterbuffer);
239 }
240 
241 GST_END_TEST;
242 
GST_START_TEST(test_push_backward_seq)243 GST_START_TEST (test_push_backward_seq)
244 {
245   GstElement *jitterbuffer;
246   const guint num_buffers = 4;
247   GstBuffer *buffer;
248   GList *node;
249 
250   jitterbuffer = setup_jitterbuffer (num_buffers);
251   fail_unless (start_jitterbuffer (jitterbuffer)
252       == GST_STATE_CHANGE_SUCCESS, "could not set to playing");
253 
254   /* push buffers: 0,3,2,1 */
255   buffer = (GstBuffer *) inbuffers->data;
256   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
257   for (node = g_list_last (inbuffers); node != inbuffers;
258       node = g_list_previous (node)) {
259     buffer = (GstBuffer *) node->data;
260     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
261   }
262 
263   /* check the buffer list */
264   check_jitterbuffer_results (num_buffers);
265 
266   /* cleanup */
267   cleanup_jitterbuffer (jitterbuffer);
268 }
269 
270 GST_END_TEST;
271 
GST_START_TEST(test_push_unordered)272 GST_START_TEST (test_push_unordered)
273 {
274   GstElement *jitterbuffer;
275   const guint num_buffers = 4;
276   GstBuffer *buffer;
277 
278   jitterbuffer = setup_jitterbuffer (num_buffers);
279   fail_unless (start_jitterbuffer (jitterbuffer)
280       == GST_STATE_CHANGE_SUCCESS, "could not set to playing");
281 
282   /* push buffers; 0,2,1,3 */
283   buffer = (GstBuffer *) inbuffers->data;
284   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
285   buffer = g_list_nth_data (inbuffers, 2);
286   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
287   buffer = g_list_nth_data (inbuffers, 1);
288   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
289   buffer = g_list_nth_data (inbuffers, 3);
290   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
291 
292   /* check the buffer list */
293   check_jitterbuffer_results (num_buffers);
294 
295   /* cleanup */
296   cleanup_jitterbuffer (jitterbuffer);
297 }
298 
299 GST_END_TEST;
300 
301 gboolean is_eos;
302 
303 static gboolean
eos_event_function(G_GNUC_UNUSED GstPad * pad,G_GNUC_UNUSED GstObject * parent,GstEvent * event)304 eos_event_function (G_GNUC_UNUSED GstPad * pad,
305     G_GNUC_UNUSED GstObject * parent, GstEvent * event)
306 {
307   if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
308     g_mutex_lock (&check_mutex);
309     is_eos = TRUE;
310     g_cond_signal (&check_cond);
311     g_mutex_unlock (&check_mutex);
312   }
313   gst_event_unref (event);
314   return TRUE;
315 }
316 
GST_START_TEST(test_push_eos)317 GST_START_TEST (test_push_eos)
318 {
319   GstElement *jitterbuffer;
320   const guint num_buffers = 5;
321   GList *node;
322   GstStructure *stats;
323   guint64 pushed, lost, late, duplicates;
324   int n = 0;
325 
326   is_eos = FALSE;
327 
328   jitterbuffer = setup_jitterbuffer (num_buffers);
329   gst_pad_set_event_function (mysinkpad, eos_event_function);
330 
331   g_object_set (jitterbuffer, "latency", 1, NULL);
332 
333   fail_unless (start_jitterbuffer (jitterbuffer)
334       == GST_STATE_CHANGE_SUCCESS, "could not set to playing");
335 
336   /* push buffers: 0,1,2, */
337   for (node = inbuffers; node; node = g_list_next (node)) {
338     GstBuffer *buffer;
339 
340     /* steal buffer from list */
341     buffer = node->data;
342     node->data = NULL;
343 
344     n++;
345     /* Skip 1 */
346     if (n == 2) {
347       gst_buffer_unref (buffer);
348       continue;
349     }
350     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
351   }
352 
353   gst_pad_push_event (mysrcpad, gst_event_new_eos ());
354 
355   g_mutex_lock (&check_mutex);
356   while (!is_eos)
357     g_cond_wait (&check_cond, &check_mutex);
358   g_mutex_unlock (&check_mutex);
359 
360   fail_unless_equals_int (g_list_length (buffers), num_buffers - 1);
361 
362   /* Verify statistics */
363   g_object_get (jitterbuffer, "stats", &stats, NULL);
364   gst_structure_get (stats, "num-pushed", G_TYPE_UINT64, &pushed,
365       "num-lost", G_TYPE_UINT64, &lost,
366       "num-late", G_TYPE_UINT64, &late,
367       "num-duplicates", G_TYPE_UINT64, &duplicates, NULL);
368   fail_unless_equals_int (pushed, g_list_length (inbuffers) - 1);
369   fail_unless_equals_int (lost, 1);
370   fail_unless_equals_int (late, 0);
371   fail_unless_equals_int (duplicates, 0);
372   gst_structure_free (stats);
373 
374   /* cleanup */
375   cleanup_jitterbuffer (jitterbuffer);
376 }
377 
378 GST_END_TEST;
379 
GST_START_TEST(test_basetime)380 GST_START_TEST (test_basetime)
381 {
382   GstElement *jitterbuffer;
383   const guint num_buffers = 3;
384   GstBuffer *buffer;
385   GList *node;
386   GstClockTime tso = gst_util_uint64_scale (RTP_FRAME_SIZE, GST_SECOND, 8000);
387 
388   jitterbuffer = setup_jitterbuffer (num_buffers);
389   fail_unless (start_jitterbuffer (jitterbuffer)
390       == GST_STATE_CHANGE_SUCCESS, "could not set to playing");
391 
392   /* push buffers: 2,1,0 */
393   for (node = g_list_last (inbuffers); node; node = g_list_previous (node)) {
394     buffer = (GstBuffer *) node->data;
395     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
396   }
397 
398   /* sleep for twice the latency */
399   g_usleep (400 * 1000);
400 
401   /* if this fails, not all buffers have been processed */
402   fail_unless_equals_int ((g_list_length (buffers) + num_dropped), num_buffers);
403 
404   buffer = (GstBuffer *) buffers->data;
405   fail_unless (GST_BUFFER_DTS (buffer) != (num_buffers * tso));
406   fail_unless (GST_BUFFER_PTS (buffer) != (num_buffers * tso));
407 
408   /* cleanup */
409   cleanup_jitterbuffer (jitterbuffer);
410 }
411 
412 GST_END_TEST;
413 
414 static GstCaps *
request_pt_map(G_GNUC_UNUSED GstElement * jitterbuffer,guint pt)415 request_pt_map (G_GNUC_UNUSED GstElement * jitterbuffer, guint pt)
416 {
417   fail_unless (pt == 0);
418 
419   return gst_caps_from_string (RTP_CAPS_STRING);
420 }
421 
GST_START_TEST(test_clear_pt_map)422 GST_START_TEST (test_clear_pt_map)
423 {
424   GstElement *jitterbuffer;
425   const guint num_buffers = 10;
426   gint i;
427   GstBuffer *buffer;
428   GList *node;
429 
430   jitterbuffer = setup_jitterbuffer (num_buffers);
431   fail_unless (start_jitterbuffer (jitterbuffer)
432       == GST_STATE_CHANGE_SUCCESS, "could not set to playing");
433 
434   g_signal_connect (jitterbuffer, "request-pt-map", (GCallback)
435       request_pt_map, NULL);
436 
437   /* push buffers: 0,1,2, */
438   for (node = inbuffers, i = 0; node && i < 3; node = g_list_next (node), i++) {
439     buffer = (GstBuffer *) node->data;
440     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
441   }
442 
443   g_usleep (400 * 1000);
444 
445   g_signal_emit_by_name (jitterbuffer, "clear-pt-map", NULL);
446 
447   for (; node && i < 10; node = g_list_next (node), i++) {
448     buffer = (GstBuffer *) node->data;
449     fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
450   }
451 
452   /* check the buffer list */
453   check_jitterbuffer_results (num_buffers);
454 
455   /* cleanup */
456   cleanup_jitterbuffer (jitterbuffer);
457 }
458 
459 GST_END_TEST;
460 
461 #define TEST_BUF_CLOCK_RATE 8000
462 #define AS_TEST_BUF_RTP_TIME(gst_time) gst_util_uint64_scale_int (TEST_BUF_CLOCK_RATE, gst_time, GST_SECOND)
463 #define TEST_BUF_PT 0
464 #define TEST_BUF_SSRC 0x01BADBAD
465 #define TEST_BUF_MS  20
466 #define TEST_BUF_DURATION (TEST_BUF_MS * GST_MSECOND)
467 #define TEST_BUF_SIZE (64000 * TEST_BUF_MS / 1000)
468 #define TEST_RTP_TS_DURATION AS_TEST_BUF_RTP_TIME (TEST_BUF_DURATION)
469 
470 static GstCaps *
generate_caps(void)471 generate_caps (void)
472 {
473   return gst_caps_new_simple ("application/x-rtp",
474       "media", G_TYPE_STRING, "audio",
475       "clock-rate", G_TYPE_INT, TEST_BUF_CLOCK_RATE,
476       "encoding-name", G_TYPE_STRING, "TEST",
477       "payload", G_TYPE_INT, TEST_BUF_PT,
478       "ssrc", G_TYPE_UINT, TEST_BUF_SSRC, NULL);
479 }
480 
481 static GstBuffer *
generate_test_buffer_full(GstClockTime dts,guint seq_num,guint32 rtp_ts)482 generate_test_buffer_full (GstClockTime dts, guint seq_num, guint32 rtp_ts)
483 {
484   GstBuffer *buf;
485   guint8 *payload;
486   guint i;
487   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
488 
489   buf = gst_rtp_buffer_new_allocate (TEST_BUF_SIZE, 0, 0);
490   GST_BUFFER_DTS (buf) = dts;
491 
492   gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
493   gst_rtp_buffer_set_payload_type (&rtp, TEST_BUF_PT);
494   gst_rtp_buffer_set_seq (&rtp, seq_num);
495   gst_rtp_buffer_set_timestamp (&rtp, rtp_ts);
496   gst_rtp_buffer_set_ssrc (&rtp, TEST_BUF_SSRC);
497 
498   payload = gst_rtp_buffer_get_payload (&rtp);
499   for (i = 0; i < TEST_BUF_SIZE; i++)
500     payload[i] = 0xff;
501 
502   gst_rtp_buffer_unmap (&rtp);
503 
504   return buf;
505 }
506 
507 static GstBuffer *
generate_test_buffer(guint seq_num)508 generate_test_buffer (guint seq_num)
509 {
510   return generate_test_buffer_full (seq_num * TEST_BUF_DURATION,
511       seq_num, seq_num * TEST_RTP_TS_DURATION);
512 }
513 
514 static GstBuffer *
generate_test_buffer_rtx(GstClockTime dts,guint seq_num)515 generate_test_buffer_rtx (GstClockTime dts, guint seq_num)
516 {
517   GstBuffer *buffer = generate_test_buffer_full (dts, seq_num,
518       seq_num * TEST_RTP_TS_DURATION);
519   GST_BUFFER_FLAG_SET (buffer, GST_RTP_BUFFER_FLAG_RETRANSMISSION);
520   return buffer;
521 }
522 
523 static void
push_test_buffer(GstHarness * h,guint seq_num)524 push_test_buffer (GstHarness * h, guint seq_num)
525 {
526   gst_harness_set_time (h, seq_num * TEST_BUF_DURATION);
527   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
528           generate_test_buffer (seq_num)));
529 }
530 
531 static void
push_test_buffer_now(GstHarness * h,guint seqnum,guint32 rtptime,gboolean rtx)532 push_test_buffer_now (GstHarness * h, guint seqnum, guint32 rtptime,
533     gboolean rtx)
534 {
535   GstClockTime now =
536       gst_clock_get_time (GST_ELEMENT_CLOCK (h->element)) -
537       h->element->base_time;
538   GstBuffer *buf = generate_test_buffer_full (now, seqnum, rtptime);
539   if (rtx)
540     GST_BUFFER_FLAG_SET (buf, GST_RTP_BUFFER_FLAG_RETRANSMISSION);
541   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buf));
542 }
543 
544 static gint
get_rtp_seq_num(GstBuffer * buf)545 get_rtp_seq_num (GstBuffer * buf)
546 {
547   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
548   gint seq;
549   gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);
550   seq = gst_rtp_buffer_get_seq (&rtp);
551   gst_rtp_buffer_unmap (&rtp);
552   return seq;
553 }
554 
555 static void
verify_lost_event(GstHarness * h,guint exp_seq,GstClockTime exp_ts,GstClockTime exp_dur)556 verify_lost_event (GstHarness * h, guint exp_seq, GstClockTime exp_ts,
557     GstClockTime exp_dur)
558 {
559   GstEvent *event;
560   const GstStructure *s;
561   const GValue *value;
562   guint seq;
563   GstClockTime ts;
564   GstClockTime dur;
565 
566   event = gst_harness_pull_event (h);
567   fail_unless (event != NULL);
568 
569   s = gst_event_get_structure (event);
570   fail_unless (s != NULL);
571   fail_unless (gst_structure_get_uint (s, "seqnum", &seq));
572 
573   value = gst_structure_get_value (s, "timestamp");
574   fail_unless (value && G_VALUE_HOLDS_UINT64 (value));
575 
576   ts = g_value_get_uint64 (value);
577   value = gst_structure_get_value (s, "duration");
578   fail_unless (value && G_VALUE_HOLDS_UINT64 (value));
579 
580   dur = g_value_get_uint64 (value);
581   fail_unless_equals_int ((guint16) exp_seq, seq);
582   fail_unless_equals_uint64 (exp_ts, ts);
583   fail_unless_equals_uint64 (exp_dur, dur);
584 
585   gst_event_unref (event);
586 }
587 
588 static void
verify_rtx_event(GstHarness * h,guint exp_seq,GstClockTime exp_ts,gint exp_delay,GstClockTime exp_spacing)589 verify_rtx_event (GstHarness * h, guint exp_seq, GstClockTime exp_ts,
590     gint exp_delay, GstClockTime exp_spacing)
591 {
592   GstEvent *event;
593   const GstStructure *s;
594   const GValue *value;
595   guint seq;
596   GstClockTime ts;
597   guint delay;
598   GstClockTime spacing;
599 
600   event = gst_harness_pull_upstream_event (h);
601   fail_unless (event != NULL);
602 
603   s = gst_event_get_structure (event);
604   fail_unless (s != NULL);
605   fail_unless (gst_structure_get_uint (s, "seqnum", &seq));
606 
607   value = gst_structure_get_value (s, "running-time");
608   fail_unless (value && G_VALUE_HOLDS_UINT64 (value));
609 
610   ts = g_value_get_uint64 (value);
611   fail_unless (gst_structure_get_uint (s, "delay", &delay));
612   value = gst_structure_get_value (s, "packet-spacing");
613   fail_unless (value && G_VALUE_HOLDS_UINT64 (value));
614   spacing = g_value_get_uint64 (value);
615   fail_unless_equals_int ((guint16) exp_seq, seq);
616   fail_unless_equals_uint64 (exp_ts, ts);
617   fail_unless_equals_int (exp_delay, delay);
618   fail_unless_equals_uint64 (exp_spacing, spacing);
619 
620   gst_event_unref (event);
621 }
622 
623 static gboolean
verify_jb_stats(GstElement * jb,GstStructure * expected)624 verify_jb_stats (GstElement * jb, GstStructure * expected)
625 {
626   gboolean ret;
627   GstStructure *actual;
628   g_object_get (jb, "stats", &actual, NULL);
629 
630   ret = gst_structure_is_subset (actual, expected);
631 
632   if (!ret) {
633     gchar *e_str = gst_structure_to_string (expected);
634     gchar *a_str = gst_structure_to_string (actual);
635     fail_unless (ret, "%s is not a subset of %s", e_str, a_str);
636     g_free (e_str);
637     g_free (a_str);
638   }
639 
640   gst_structure_free (expected);
641   gst_structure_free (actual);
642 
643   return ret;
644 }
645 
646 static guint
construct_deterministic_initial_state(GstHarness * h,gint latency_ms)647 construct_deterministic_initial_state (GstHarness * h, gint latency_ms)
648 {
649   guint next_seqnum = latency_ms / TEST_BUF_MS + 1;
650   guint seqnum;
651   gint i;
652 
653   g_assert (latency_ms % TEST_BUF_MS == 0);
654 
655   gst_harness_set_src_caps (h, generate_caps ());
656   g_object_set (h->element, "latency", latency_ms, NULL);
657 
658   /* When the first packet arrives in the jitterbuffer, it will create a
659    * timeout for this packet equal to the latency of the jitterbuffer.
660    * This is known as DEADLINE internally, and is meant to allow the stream
661    * to buffer a bit before starting to push it out, to get some ideas about
662    * the nature of the stream. (packetspacing, jitter etc.)
663    *
664    * When writing tests using the test-clock, it it hence important to know
665    * that by simply advancing the clock to this timeout, you are basically
666    * describing a stream that had one initial packet, and then nothing at all
667    * for the duration of the latency (100ms in this test), which is not a very
668    * usual scenario.
669    *
670    * Instead, a pattern used throughout this test-suite, is to keep the buffers
671    * arriving at their optimal time, until the DEADLINE is reached, and that
672    * then becomes the "starting-point" for the test, because at this time
673    * there should now be no waiting timers (unless using rtx) and we have
674    * a "clean" state to craft the test from.
675    */
676 
677   /* Packet 0 arrives at time 0ms, Packet 5 arrives at time 100ms */
678   for (seqnum = 0; seqnum < next_seqnum; seqnum++) {
679     push_test_buffer (h, seqnum);
680     gst_harness_wait_for_clock_id_waits (h, 1, 60);
681   }
682 
683   /* We release the DEADLINE timer for packet 0, verify the time is indeed
684    * @latency_ms (100ms) and pull out all the buffers that have been released,
685    * and verify their PTS and sequence numbers.
686    */
687   gst_harness_crank_single_clock_wait (h);
688   fail_unless_equals_int64 (latency_ms * GST_MSECOND,
689       gst_clock_get_time (GST_ELEMENT_CLOCK (h->element)));
690   for (seqnum = 0; seqnum < next_seqnum; seqnum++) {
691     GstBuffer *buf = gst_harness_pull (h);
692     fail_unless_equals_uint64 (seqnum * TEST_BUF_DURATION,
693         GST_BUFFER_PTS (buf));
694     fail_unless_equals_int (seqnum, get_rtp_seq_num (buf));
695     gst_buffer_unref (buf);
696   }
697 
698   /* drop GstEventStreamStart & GstEventCaps & GstEventSegment */
699   for (i = 0; i < 3; i++)
700     gst_event_unref (gst_harness_pull_event (h));
701 
702   /* drop reconfigure event */
703   gst_event_unref (gst_harness_pull_upstream_event (h));
704 
705   /* Verify that at this point our queues are empty */
706   fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
707   fail_unless_equals_int (0, gst_harness_events_in_queue (h));
708 
709   return next_seqnum;
710 }
711 
GST_START_TEST(test_lost_event)712 GST_START_TEST (test_lost_event)
713 {
714   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
715   GstBuffer *buf;
716   gint latency_ms = 100;
717   guint next_seqnum;
718   guint missing_seqnum;
719 
720   g_object_set (h->element, "do-lost", TRUE, NULL);
721   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
722 
723   /* We will now create a gap in the stream, by skipping one sequence-number,
724    * and push the following packet.
725    */
726   missing_seqnum = next_seqnum;
727   next_seqnum += 1;
728   push_test_buffer (h, next_seqnum);
729 
730   /* This packet (@next_seqnum) will now be held back, awaiting the missing one,
731    * verify that this is the case:
732    */
733   fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
734   fail_unless_equals_int (0, gst_harness_events_in_queue (h));
735 
736   /* The lost-timeout for the missing packet will now be its pts + latency, so
737    * now we will simply crank the clock to advance to this point in time, and
738    * check that we get a lost-event, as well as the last packet we pushed in.
739    */
740   gst_harness_crank_single_clock_wait (h);
741   verify_lost_event (h, missing_seqnum,
742       missing_seqnum * TEST_BUF_DURATION, TEST_BUF_DURATION);
743 
744   buf = gst_harness_pull (h);
745   fail_unless_equals_uint64 (next_seqnum * TEST_BUF_DURATION,
746       GST_BUFFER_PTS (buf));
747   fail_unless_equals_int (next_seqnum, get_rtp_seq_num (buf));
748   gst_buffer_unref (buf);
749 
750   fail_unless (verify_jb_stats (h->element,
751           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
752               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum,
753               "num-lost", G_TYPE_UINT64, (guint64) 1, NULL)));
754 
755   gst_harness_teardown (h);
756 }
757 
758 GST_END_TEST;
759 
GST_START_TEST(test_only_one_lost_event_on_large_gaps)760 GST_START_TEST (test_only_one_lost_event_on_large_gaps)
761 {
762   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
763   GstTestClock *testclock;
764   GstBuffer *out_buf;
765   guint next_seqnum;
766   gint latency_ms = 200;
767   gint num_lost_events = latency_ms / TEST_BUF_MS;
768   gint i;
769 
770   testclock = gst_harness_get_testclock (h);
771   /* Need to set max-misorder-time and max-dropout-time to 0 so the
772    * jitterbuffer does not base them on packet rate calculations.
773    * If it does, out gap is big enough to be considered a new stream and
774    * we wait for a few consecutive packets just to be sure
775    */
776   g_object_set (h->element, "do-lost", TRUE,
777       "max-misorder-time", 0, "max-dropout-time", 0, NULL);
778   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
779 
780   /* move time ahead to just before 10 seconds */
781   gst_harness_set_time (h, 10 * GST_SECOND - 1);
782 
783   /* check that we have no pending waits */
784   fail_unless_equals_int (0, gst_test_clock_peek_id_count (testclock));
785 
786   /* a buffer now arrives perfectly on time */
787   fail_unless_equals_int (GST_FLOW_OK,
788       gst_harness_push (h, generate_test_buffer (500)));
789 
790   /* release the wait, advancing the clock to 10 sec */
791   fail_unless (gst_harness_crank_single_clock_wait (h));
792 
793   /* we should now receive a packet-lost-event for buffers 11 through 489 ... */
794   verify_lost_event (h, next_seqnum,
795       next_seqnum * TEST_BUF_DURATION, TEST_BUF_DURATION * (490 - next_seqnum));
796 
797   /* ... as well as 490 (since at 10 sec 490 is too late) */
798   verify_lost_event (h, 490, 490 * TEST_BUF_DURATION, TEST_BUF_DURATION);
799 
800   /* we get as many lost events as the the number of *
801    * buffers the jitterbuffer is able to wait for */
802   for (i = 1; i < num_lost_events; i++) {
803     fail_unless (gst_harness_crank_single_clock_wait (h));
804     verify_lost_event (h, 490 + i, (490 + i) * TEST_BUF_DURATION,
805         TEST_BUF_DURATION);
806   }
807 
808   /* and then the buffer is released */
809   out_buf = gst_harness_pull (h);
810   fail_unless (GST_BUFFER_FLAG_IS_SET (out_buf, GST_BUFFER_FLAG_DISCONT));
811   fail_unless_equals_int (500, get_rtp_seq_num (out_buf));
812   fail_unless_equals_uint64 (10 * GST_SECOND, GST_BUFFER_PTS (out_buf));
813   gst_buffer_unref (out_buf);
814 
815   fail_unless (verify_jb_stats (h->element,
816           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
817               "num-lost", G_TYPE_UINT64, (guint64) 489, NULL)));
818 
819   gst_object_unref (testclock);
820   gst_harness_teardown (h);
821 }
822 
823 GST_END_TEST;
824 
GST_START_TEST(test_two_lost_one_arrives_in_time)825 GST_START_TEST (test_two_lost_one_arrives_in_time)
826 {
827   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
828   GstTestClock *testclock;
829   GstClockID id;
830   GstBuffer *buf;
831   gint latency_ms = 100;
832   guint next_seqnum;
833   guint first_missing;
834   guint second_missing;
835   guint current_arrived;
836 
837   testclock = gst_harness_get_testclock (h);
838   g_object_set (h->element, "do-lost", TRUE, NULL);
839   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
840 
841   /* hop over 2 packets and make another one (gap of 2) */
842   first_missing = next_seqnum;
843   second_missing = next_seqnum + 1;
844   current_arrived = next_seqnum + 2;
845   push_test_buffer (h, current_arrived);
846 
847   /* verify that the jitterbuffer now wait for the latest moment it can push the
848    * @first_missing packet out.
849    */
850   gst_test_clock_wait_for_next_pending_id (testclock, &id);
851   fail_unless_equals_uint64 (first_missing * TEST_BUF_DURATION +
852       latency_ms * GST_MSECOND, gst_clock_id_get_time (id));
853   gst_clock_id_unref (id);
854 
855   /* let the time expire... */
856   fail_unless (gst_harness_crank_single_clock_wait (h));
857 
858   /* we should now receive a packet-lost-event */
859   verify_lost_event (h, first_missing,
860       first_missing * TEST_BUF_DURATION, TEST_BUF_DURATION);
861 
862   /* @second_missing now arrives just in time */
863   fail_unless_equals_int (GST_FLOW_OK,
864       gst_harness_push (h, generate_test_buffer (second_missing)));
865 
866   /* verify that @second_missing made it through! */
867   buf = gst_harness_pull (h);
868   fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
869   fail_unless_equals_int (second_missing, get_rtp_seq_num (buf));
870   gst_buffer_unref (buf);
871 
872   /* and see that @current_arrived now also is pushed */
873   buf = gst_harness_pull (h);
874   fail_unless (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
875   fail_unless_equals_int (current_arrived, get_rtp_seq_num (buf));
876   gst_buffer_unref (buf);
877 
878   fail_unless (verify_jb_stats (h->element,
879           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
880               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum + 2,
881               "num-lost", G_TYPE_UINT64, (guint64) 1, NULL)));
882 
883   gst_object_unref (testclock);
884   gst_harness_teardown (h);
885 }
886 
887 GST_END_TEST;
888 
GST_START_TEST(test_late_packets_still_makes_lost_events)889 GST_START_TEST (test_late_packets_still_makes_lost_events)
890 {
891   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
892   GstBuffer *out_buf;
893   gint latency_ms = 100;
894   guint next_seqnum;
895   guint seqnum;
896   GstClockTime now;
897 
898   g_object_set (h->element, "do-lost", TRUE, NULL);
899   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
900 
901   /* jump 10 seconds forward in time */
902   now = 10 * GST_SECOND;
903   gst_harness_set_time (h, now);
904 
905   /* push a packet with a gap of 2, that now is very late */
906   seqnum = next_seqnum + 2;
907   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
908           generate_test_buffer_full (now,
909               seqnum, seqnum * TEST_RTP_TS_DURATION)));
910 
911   /* We get one "huge" lost-event accounting for all the missing time */
912   verify_lost_event (h, next_seqnum, 120 * GST_MSECOND, 9860 * GST_MSECOND);
913 
914   /* and the next packet is optimistically expected to be the one
915      just prior to our current packet, so we time that out with a crank */
916   gst_harness_crank_single_clock_wait (h);
917 
918   /* and we verify that indeed this lost event was thought to should
919      have arrived 20ms prior to the packet that actually arrived */
920   verify_lost_event (h, next_seqnum + 1, 9980 * GST_MSECOND, 20 * GST_MSECOND);
921 
922   /* and finally verify that the super-late packet made it through! */
923   out_buf = gst_harness_pull (h);
924   fail_unless (GST_BUFFER_FLAG_IS_SET (out_buf, GST_BUFFER_FLAG_DISCONT));
925   fail_unless_equals_int (seqnum, get_rtp_seq_num (out_buf));
926   gst_buffer_unref (out_buf);
927 
928   fail_unless (verify_jb_stats (h->element,
929           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
930               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum + 1,
931               "num-lost", G_TYPE_UINT64, (guint64) 2, NULL)));
932 
933   gst_harness_teardown (h);
934 }
935 
936 GST_END_TEST;
937 
938 
GST_START_TEST(test_num_late_when_considered_lost_arrives)939 GST_START_TEST (test_num_late_when_considered_lost_arrives)
940 {
941   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
942   gboolean do_lost = __i__ != 0;
943   gint latency_ms = 100;
944   guint next_seqnum;
945 
946   g_object_set (h->element, "do-lost", do_lost, NULL);
947   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
948 
949   /* gap of 1 */
950   push_test_buffer (h, next_seqnum + 1);
951 
952   /* crank to trigger lost-event */
953   gst_harness_crank_single_clock_wait (h);
954 
955   if (do_lost) {
956     /* we should now receive packet-lost-events for the missing packet */
957     verify_lost_event (h, next_seqnum,
958         next_seqnum * TEST_BUF_DURATION, TEST_BUF_DURATION);
959   }
960 
961   /* pull out the pushed packet */
962   gst_buffer_unref (gst_harness_pull (h));
963 
964   /* we have one lost packet in the stats */
965   fail_unless (verify_jb_stats (h->element,
966           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
967               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum + 1,
968               "num-lost", G_TYPE_UINT64, (guint64) 1,
969               "num-late", G_TYPE_UINT64, (guint64) 0, NULL)));
970 
971   /* the missing packet now arrives (too late) */
972   fail_unless_equals_int (GST_FLOW_OK,
973       gst_harness_push (h, generate_test_buffer (next_seqnum)));
974 
975   /* and this increments num-late */
976   fail_unless (verify_jb_stats (h->element,
977           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
978               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum + 1,
979               "num-lost", G_TYPE_UINT64, (guint64) 1,
980               "num-late", G_TYPE_UINT64, (guint64) 1, NULL)));
981 
982   gst_harness_teardown (h);
983 }
984 
985 GST_END_TEST;
986 
GST_START_TEST(test_lost_event_uses_pts)987 GST_START_TEST (test_lost_event_uses_pts)
988 {
989   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
990   GstClockTime now;
991   gint latency_ms = 100;
992   guint next_seqnum;
993   guint lost_seqnum;
994 
995   g_object_set (h->element, "do-lost", TRUE, NULL);
996   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
997 
998   /* hop over 1 packets and make another one (gap of 1), but due to
999      network delays, this packets is also grossly late */
1000   lost_seqnum = next_seqnum;
1001   next_seqnum += 1;
1002 
1003   /* advance the clock to the latest time packet @next_seqnum could arrive */
1004   now = next_seqnum * TEST_BUF_DURATION + latency_ms * GST_MSECOND;
1005   gst_harness_set_time (h, now);
1006   gst_harness_push (h, generate_test_buffer_full (now, next_seqnum,
1007           next_seqnum * TEST_RTP_TS_DURATION));
1008 
1009   /* we should now have received a packet-lost-event for buffer 3 */
1010   verify_lost_event (h, lost_seqnum,
1011       lost_seqnum * TEST_BUF_DURATION, TEST_BUF_DURATION);
1012 
1013   /* and pull out packet 4 */
1014   gst_buffer_unref (gst_harness_pull (h));
1015 
1016   fail_unless (verify_jb_stats (h->element,
1017           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
1018               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum,
1019               "num-lost", G_TYPE_UINT64, (guint64) 1, NULL)));
1020 
1021   gst_harness_teardown (h);
1022 }
1023 
1024 GST_END_TEST;
1025 
GST_START_TEST(test_lost_event_with_backwards_rtptime)1026 GST_START_TEST (test_lost_event_with_backwards_rtptime)
1027 {
1028   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1029   gint latency_ms = 40;
1030 
1031   g_object_set (h->element, "do-lost", TRUE, NULL);
1032   construct_deterministic_initial_state (h, latency_ms);
1033 
1034   /*
1035    * For video using B-frames, an expected sequence
1036    * could be like this:
1037    * (I = I-frame, P = P-frame, B = B-frame)
1038    *               ___   ___   ___   ___   ___
1039    *          ... | 3 | | 4 | | 5 | | 6 | | 7 |
1040    *               –––   –––   –––   –––   –––
1041    * rtptime:       3(I)  5(P)  5(P)  4(B)  6(P)
1042    * arrival(dts):  3     5     5     5     6
1043    *
1044    * Notice here that packet 6 (the B frame) make
1045    * the rtptime go backwards.
1046    *
1047    * But we get this:
1048    *               ___   ___   _ _   ___   ___
1049    *          ... | 3 | | 4 | |   | | 6 | | 7 |
1050    *               –––   –––   - -   –––   –––
1051    * rtptime:       3(I)  5(P)        4(B)  6(P)
1052    * arrival(dts):  3     5           5     6
1053    *
1054    */
1055 
1056   /* seqnum 3 */
1057   push_test_buffer (h, 3);
1058   gst_buffer_unref (gst_harness_pull (h));
1059 
1060   /* seqnum 4, arriving at time 5 with rtptime 5 */
1061   gst_harness_push (h,
1062       generate_test_buffer_full (5 * TEST_BUF_DURATION,
1063           4, 5 * TEST_RTP_TS_DURATION));
1064   gst_buffer_unref (gst_harness_pull (h));
1065 
1066   /* seqnum 6, arriving at time 5 with rtptime 4,
1067      making a gap for missing seqnum 5 */
1068   gst_harness_push (h,
1069       generate_test_buffer_full (5 * TEST_BUF_DURATION,
1070           6, 4 * TEST_RTP_TS_DURATION));
1071 
1072   /* seqnum 7, arriving at time 6 with rtptime 6 */
1073   gst_harness_push (h,
1074       generate_test_buffer_full (6 * TEST_BUF_DURATION,
1075           7, 6 * TEST_RTP_TS_DURATION));
1076 
1077   /* we should now have received a packet-lost-event for seqnum 5,
1078      with time 5 and 0 duration */
1079   gst_harness_crank_single_clock_wait (h);
1080   verify_lost_event (h, 5, 5 * TEST_BUF_DURATION, 0);
1081 
1082   /* and pull out 6 and 7 */
1083   gst_buffer_unref (gst_harness_pull (h));
1084   gst_buffer_unref (gst_harness_pull (h));
1085 
1086   fail_unless (verify_jb_stats (h->element,
1087           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
1088               "num-pushed", G_TYPE_UINT64, (guint64) 7,
1089               "num-lost", G_TYPE_UINT64, (guint64) 1, NULL)));
1090 
1091   gst_harness_teardown (h);
1092 }
1093 
1094 GST_END_TEST;
1095 
GST_START_TEST(test_all_packets_are_timestamped_zero)1096 GST_START_TEST (test_all_packets_are_timestamped_zero)
1097 {
1098   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1099   GstBuffer *out_buf;
1100   gint jb_latency_ms = 100;
1101   gint i, b;
1102 
1103   gst_harness_set_src_caps (h, generate_caps ());
1104   g_object_set (h->element, "do-lost", TRUE, "latency", jb_latency_ms, NULL);
1105 
1106   /* advance the clock with 10 seconds */
1107   gst_harness_set_time (h, 10 * GST_SECOND);
1108 
1109   /* push the first buffer through */
1110   gst_buffer_unref (gst_harness_push_and_pull (h, generate_test_buffer (0)));
1111 
1112   /* push some buffers in, all timestamped 0 */
1113   for (b = 1; b < 3; b++) {
1114     fail_unless_equals_int (GST_FLOW_OK,
1115         gst_harness_push (h,
1116             generate_test_buffer_full (0 * GST_MSECOND, b, 0)));
1117 
1118     /* check for the buffer coming out that was pushed in */
1119     out_buf = gst_harness_pull (h);
1120     fail_unless_equals_uint64 (0, GST_BUFFER_PTS (out_buf));
1121     gst_buffer_unref (out_buf);
1122   }
1123 
1124   /* hop over 2 packets and make another one (gap of 2) */
1125   b = 5;
1126   fail_unless_equals_int (GST_FLOW_OK,
1127       gst_harness_push (h, generate_test_buffer_full (0 * GST_MSECOND, b, 0)));
1128 
1129   /* drop GstEventStreamStart & GstEventCaps & GstEventSegment */
1130   for (i = 0; i < 3; i++)
1131     gst_event_unref (gst_harness_pull_event (h));
1132 
1133   /* we should now receive packet-lost-events for buffer 3 and 4 */
1134   verify_lost_event (h, 3, 0, 0);
1135   verify_lost_event (h, 4, 0, 0);
1136 
1137   /* verify that buffer 5 made it through! */
1138   out_buf = gst_harness_pull (h);
1139   fail_unless (GST_BUFFER_FLAG_IS_SET (out_buf, GST_BUFFER_FLAG_DISCONT));
1140   fail_unless_equals_int (5, get_rtp_seq_num (out_buf));
1141   gst_buffer_unref (out_buf);
1142 
1143   fail_unless (verify_jb_stats (h->element,
1144           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
1145               "num-pushed", G_TYPE_UINT64, (guint64) 4,
1146               "num-lost", G_TYPE_UINT64, (guint64) 2, NULL)));
1147 
1148   gst_harness_teardown (h);
1149 }
1150 
1151 GST_END_TEST;
1152 
GST_START_TEST(test_reorder_of_non_equidistant_packets)1153 GST_START_TEST (test_reorder_of_non_equidistant_packets)
1154 {
1155   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1156   GstTestClock *testclock;
1157   gint latency_ms = 5;
1158   GstClockID pending_id;
1159   GstClockTime time;
1160   gint seq, frame;
1161   gint num_init_frames = 1;
1162   const GstClockTime frame_dur = TEST_BUF_DURATION;
1163   const guint32 frame_rtp_ts_dur = TEST_RTP_TS_DURATION;
1164 
1165   gst_harness_set_src_caps (h, generate_caps ());
1166   testclock = gst_harness_get_testclock (h);
1167   g_object_set (h->element, "do-lost", TRUE, "latency", latency_ms, NULL);
1168 
1169   for (frame = 0, seq = 0; frame < num_init_frames; frame++, seq += 2) {
1170     /* Push a couple of packets with identical timestamp, typical for a video
1171      * stream where one frame generates multiple packets. */
1172     gst_harness_set_time (h, frame * frame_dur);
1173     gst_harness_push (h, generate_test_buffer_full (frame * frame_dur,
1174             seq, frame * frame_rtp_ts_dur));
1175     gst_harness_push (h, generate_test_buffer_full (frame * frame_dur,
1176             seq + 1, frame * frame_rtp_ts_dur));
1177 
1178     if (frame == 0)
1179       /* deadline for buffer 0 expires */
1180       gst_harness_crank_single_clock_wait (h);
1181 
1182     gst_buffer_unref (gst_harness_pull (h));
1183     gst_buffer_unref (gst_harness_pull (h));
1184   }
1185 
1186   /* Finally push the last frame reordered */
1187   gst_harness_set_time (h, frame * frame_dur);
1188   gst_harness_push (h, generate_test_buffer_full (frame * frame_dur,
1189           seq + 1, frame * frame_rtp_ts_dur));
1190 
1191   /* Check the scheduled lost timer. The expected arrival of this packet
1192    * should be assumed to be the same as the last packet received since we
1193    * don't know wether the missing packet belonged to this or previous
1194    * frame. */
1195   gst_test_clock_wait_for_next_pending_id (testclock, &pending_id);
1196   time = gst_clock_id_get_time (pending_id);
1197   fail_unless_equals_int64 (time, frame * frame_dur + latency_ms * GST_MSECOND);
1198   gst_clock_id_unref (pending_id);
1199 
1200   /* And then missing packet arrives just in time */
1201   gst_harness_set_time (h, time - 1);
1202   gst_harness_push (h, generate_test_buffer_full (time - 1, seq,
1203           frame * frame_rtp_ts_dur));
1204 
1205   gst_buffer_unref (gst_harness_pull (h));
1206   gst_buffer_unref (gst_harness_pull (h));
1207 
1208   gst_object_unref (testclock);
1209   gst_harness_teardown (h);
1210 }
1211 
1212 GST_END_TEST;
1213 
GST_START_TEST(test_loss_equidistant_spacing_with_parameter_packets)1214 GST_START_TEST (test_loss_equidistant_spacing_with_parameter_packets)
1215 {
1216   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1217   gint latency_ms = 5;
1218   gint seq, frame;
1219   gint num_init_frames = 10;
1220   gint i;
1221 
1222   gst_harness_set_src_caps (h, generate_caps ());
1223   g_object_set (h->element, "do-lost", TRUE, "latency", latency_ms, NULL);
1224 
1225   /* drop stream-start, caps, segment */
1226   for (i = 0; i < 3; i++)
1227     gst_event_unref (gst_harness_pull_event (h));
1228 
1229   for (frame = 0, seq = 0; frame < num_init_frames; frame++, seq++) {
1230     gst_harness_set_time (h, frame * TEST_BUF_DURATION);
1231     gst_harness_push (h, generate_test_buffer_full (frame * TEST_BUF_DURATION,
1232             seq, frame * TEST_RTP_TS_DURATION));
1233 
1234     if (frame == 0)
1235       /* deadline for buffer 0 expires */
1236       gst_harness_crank_single_clock_wait (h);
1237 
1238     gst_buffer_unref (gst_harness_pull (h));
1239   }
1240 
1241   /* Push three packets with same rtptime, simulating parameter packets +
1242    * frame. This should not disable equidistant mode as it is common for
1243    * certain audio codecs. */
1244   for (i = 0; i < 3; i++) {
1245     gst_harness_set_time (h, frame * TEST_BUF_DURATION);
1246     gst_harness_push (h, generate_test_buffer_full (frame * TEST_BUF_DURATION,
1247             seq++, frame * TEST_RTP_TS_DURATION));
1248     gst_buffer_unref (gst_harness_pull (h));
1249   }
1250   frame++;
1251 
1252   /* Finally push the last packet introducing a gap */
1253   gst_harness_set_time (h, frame * TEST_BUF_DURATION);
1254   gst_harness_push (h, generate_test_buffer_full (frame * TEST_BUF_DURATION,
1255           seq + 1, frame * TEST_RTP_TS_DURATION));
1256 
1257   /* given that the last known PTS (pkt#12) was 200ms and this last PTS (pkt#14) was 220ms,
1258      and our current packet-spacing is 20ms, the lost-event gets a problem here:
1259      If we use our packet-spacing, the last pushed packet (#12) should have
1260      a duration of 20ms, meaning we would expect the missing packet (#13) to
1261      have a PTS of 220ms. However, packet #14 comes in at 220ms, so what is
1262      the best estimation for the missing packet here?
1263 
1264      Given that we want to estimate the most optimistic PTS in order to give
1265      the packet as many chances as possible to arrive, we end up with a PTS
1266      of 220ms and a duration of 0, since that will be the most optimistic
1267      placement given that it has to be before pkt #14.
1268    */
1269 
1270   /* timeout the lost-event */
1271   gst_harness_crank_single_clock_wait (h);
1272   verify_lost_event (h, seq, frame * TEST_BUF_DURATION, 0);
1273 
1274   gst_buffer_unref (gst_harness_pull (h));
1275 
1276   gst_harness_teardown (h);
1277 }
1278 
1279 GST_END_TEST;
1280 
1281 
1282 typedef struct
1283 {
1284   guint gap;
1285   GstClockTime duration[3];
1286 } ThreeLostPackets;
1287 
1288 ThreeLostPackets no_fractional_lost_event_durations_input[] = {
1289   {5, {60 * GST_MSECOND, 20 * GST_MSECOND, 20 * GST_MSECOND}},
1290   {4, {40 * GST_MSECOND, 20 * GST_MSECOND, 20 * GST_MSECOND}},
1291   {3, {20 * GST_MSECOND, 20 * GST_MSECOND, 20 * GST_MSECOND}},
1292   {2, {20 * GST_MSECOND, 20 * GST_MSECOND, 0 * GST_MSECOND}},
1293   {1, {20 * GST_MSECOND, 0 * GST_MSECOND, 0 * GST_MSECOND}},
1294   {0, {0 * GST_MSECOND, 0 * GST_MSECOND, 0 * GST_MSECOND}},
1295 };
1296 
1297 /* This test looks after that fact that when we have equidistant
1298    packetspacing, we try and keep that spacing for the lost events,
1299    so we operate in "whole" packets.
1300 */
GST_START_TEST(test_no_fractional_lost_event_durations)1301 GST_START_TEST (test_no_fractional_lost_event_durations)
1302 {
1303   ThreeLostPackets *ctx = &no_fractional_lost_event_durations_input[__i__];
1304 
1305   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1306   GstClockTime now;
1307   guint latency_ms = 100;
1308   guint16 seqnum, gap_seqnum;
1309   GstClockTime pts;
1310   GstClockTime duration;
1311 
1312   g_object_set (h->element, "do-lost", TRUE, NULL);
1313   seqnum = construct_deterministic_initial_state (h, latency_ms);
1314   gap_seqnum = seqnum + ctx->gap;
1315 
1316   now = gap_seqnum * TEST_BUF_DURATION;
1317   gst_harness_set_time (h, now);
1318   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
1319           generate_test_buffer_full (now,
1320               seqnum + 3, gap_seqnum * TEST_RTP_TS_DURATION)));
1321 
1322   pts = seqnum * TEST_BUF_DURATION;
1323   now = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1324   /* check if the lost-event has expired, if not
1325      crank to move the time ahead */
1326   if (pts + latency_ms * GST_MSECOND > now)
1327     gst_harness_crank_single_clock_wait (h);
1328   duration = ctx->duration[0];
1329   verify_lost_event (h, seqnum, pts, duration);
1330 
1331   seqnum++;
1332   pts += duration;
1333   duration = ctx->duration[1];
1334   now = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1335   if (pts + latency_ms * GST_MSECOND > now)
1336     gst_harness_crank_single_clock_wait (h);
1337   verify_lost_event (h, seqnum, pts, duration);
1338 
1339   seqnum++;
1340   pts += duration;
1341   duration = ctx->duration[2];
1342   now = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1343   if (pts + latency_ms * GST_MSECOND > now)
1344     gst_harness_crank_single_clock_wait (h);
1345   verify_lost_event (h, seqnum, pts, duration);
1346 
1347   /* followed by the buffer */
1348   gst_buffer_unref (gst_harness_pull (h));
1349   /* verify that we have pulled out all waiting buffers and events */
1350   fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
1351   fail_unless_equals_int (0, gst_harness_events_in_queue (h));
1352 
1353   gst_harness_teardown (h);
1354 }
1355 
1356 GST_END_TEST;
1357 
GST_START_TEST(test_late_lost_with_same_pts)1358 GST_START_TEST (test_late_lost_with_same_pts)
1359 {
1360   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1361   GstClockTime dts, now;
1362   guint latency_ms = 40;
1363   guint16 seqnum;
1364   guint rtp_ts;
1365 
1366   g_object_set (h->element, "do-lost", TRUE, NULL);
1367   seqnum = construct_deterministic_initial_state (h, latency_ms);
1368 
1369   dts = seqnum * TEST_BUF_DURATION;
1370   rtp_ts = seqnum * TEST_RTP_TS_DURATION;
1371 
1372   /* set the time on the clock one buffer-length after the
1373      length of the jitterbuffer */
1374   now = dts + latency_ms * GST_MSECOND + TEST_BUF_DURATION;
1375   gst_test_clock_set_time (GST_TEST_CLOCK (GST_ELEMENT_CLOCK (h->element)),
1376       now);
1377 
1378   /* now two buffers arrive, same arrival time (in the past, must
1379      have spent a lot of time from udpsrc to jitterbuffer!),
1380      with the same rtptimestamp (typical of videobuffers),
1381      with a gap in between them */
1382   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
1383           generate_test_buffer_full (dts, seqnum, rtp_ts)));
1384 
1385   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
1386           generate_test_buffer_full (dts, seqnum + 2, rtp_ts)));
1387 
1388   /* the lost event is generated immediately since we are already
1389      too late to wait for anything */
1390   verify_lost_event (h, seqnum + 1, dts, 0);
1391   gst_buffer_unref (gst_harness_pull (h));
1392   gst_buffer_unref (gst_harness_pull (h));
1393 
1394   /* verify that we have pulled out all waiting buffers and events */
1395   fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
1396   fail_unless_equals_int (0, gst_harness_events_in_queue (h));
1397 
1398   gst_harness_teardown (h);
1399 }
1400 
1401 GST_END_TEST;
1402 
1403 static void
gst_test_clock_set_time_and_process(GstTestClock * testclock,GstClockTime time)1404 gst_test_clock_set_time_and_process (GstTestClock * testclock,
1405     GstClockTime time)
1406 {
1407   GstClockID id, tid;
1408   gst_test_clock_wait_for_next_pending_id (testclock, &id);
1409   gst_test_clock_set_time (testclock, time);
1410   tid = gst_test_clock_process_next_clock_id (testclock);
1411   g_assert (tid == id);
1412   gst_clock_id_unref (tid);
1413   gst_clock_id_unref (id);
1414 }
1415 
GST_START_TEST(test_rtx_expected_next)1416 GST_START_TEST (test_rtx_expected_next)
1417 {
1418   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1419   gint latency_ms = 200;
1420   guint next_seqnum;
1421   GstClockTime timeout;
1422   gint rtx_delay_ms;
1423   const GstClockTime rtx_retry_timeout_ms = 40;
1424 
1425   g_object_set (h->element, "do-lost", TRUE, NULL);
1426   g_object_set (h->element, "do-retransmission", TRUE, NULL);
1427   g_object_set (h->element, "rtx-retry-period", 120, NULL);
1428   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
1429 
1430   /* At this point there is already existing a rtx-timer for @next_seqnum,
1431    * that will have a timeout of the expected arrival-time for that seqnum,
1432    * and a delay equal to 2*jitter==0 and 0.5*packet_spacing==10ms */
1433   timeout = next_seqnum * TEST_BUF_DURATION;
1434   rtx_delay_ms = TEST_BUF_MS / 2;
1435 
1436   /* We crank the clock to time-out the next scheduled timer */
1437   gst_harness_crank_single_clock_wait (h);
1438   verify_rtx_event (h, next_seqnum, timeout, rtx_delay_ms, TEST_BUF_DURATION);
1439 
1440   /* now we wait for the next timeout, all following timeouts 40ms in the
1441    * future because this is rtx-retry-timeout */
1442   rtx_delay_ms += rtx_retry_timeout_ms;
1443   gst_harness_crank_single_clock_wait (h);
1444   verify_rtx_event (h, next_seqnum, timeout, rtx_delay_ms, TEST_BUF_DURATION);
1445 
1446   /* And a third time... */
1447   rtx_delay_ms += rtx_retry_timeout_ms;
1448   gst_harness_crank_single_clock_wait (h);
1449   verify_rtx_event (h, next_seqnum, timeout, rtx_delay_ms, TEST_BUF_DURATION);
1450 
1451   /* we should now receive a packet-lost-event for packet @next_seqnum */
1452   gst_harness_crank_single_clock_wait (h);
1453   verify_lost_event (h, next_seqnum, timeout, TEST_BUF_DURATION);
1454 
1455   gst_harness_teardown (h);
1456 }
1457 
1458 GST_END_TEST;
1459 
GST_START_TEST(test_rtx_not_bursting_requests)1460 GST_START_TEST (test_rtx_not_bursting_requests)
1461 {
1462   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1463   gint latency_ms = 200;
1464   guint next_seqnum;
1465   guint missing_seqnum;
1466   GstClockTime now;
1467 
1468   g_object_set (h->element,
1469       "do-lost", TRUE,
1470       "do-retransmission", TRUE,
1471       "rtx-next-seqnum", FALSE, "rtx-max-retries", 3, NULL);
1472 
1473   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
1474   now = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1475 
1476   /* skip a packet and move the time for the next one
1477      quite a bit forward */
1478   missing_seqnum = next_seqnum;
1479   next_seqnum++;
1480   now += 150 * GST_MSECOND;
1481   gst_harness_set_time (h, now);
1482 
1483   push_test_buffer_now (h, next_seqnum, next_seqnum * TEST_RTP_TS_DURATION,
1484       FALSE);
1485 
1486   /* note the delay here is 130. This is because we advanced the clock 150,
1487      and 20 of those were the duration of the missing seqnum, so this
1488      RTX event is in effect 130ms "late" compared to its ideal time */
1489   verify_rtx_event (h, missing_seqnum,
1490       missing_seqnum * TEST_BUF_DURATION, 130, TEST_BUF_DURATION);
1491 
1492   /* verify we have not sent any other rtx events */
1493   fail_unless_equals_int (0, gst_harness_upstream_events_in_queue (h));
1494 
1495   gst_harness_teardown (h);
1496 }
1497 
1498 GST_END_TEST;
1499 
GST_START_TEST(test_rtx_next_seqnum_disabled)1500 GST_START_TEST (test_rtx_next_seqnum_disabled)
1501 {
1502   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1503   gint latency_ms = 200;
1504   guint next_seqnum, missing_seqnum;
1505   GstTestClock *testclock;
1506   GstClockTime timeout, last_rtx_request;
1507   gint rtx_delay_ms;
1508   const GstClockTime rtx_retry_timeout_ms = 40;
1509 
1510   testclock = gst_harness_get_testclock (h);
1511 
1512   g_object_set (h->element, "do-lost", TRUE, NULL);
1513   g_object_set (h->element, "do-retransmission", TRUE, NULL);
1514   g_object_set (h->element, "rtx-retry-period", 120, NULL);
1515   g_object_set (h->element, "rtx-next-seqnum", FALSE, NULL);
1516 
1517   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
1518 
1519   /* When rtx-next-seqnum is disabled there is no existing rtx-timer for
1520    * @next_seqnum until there is a gap and it's missing. */
1521 
1522   /* Check that we have no pending waits */
1523   fail_unless_equals_int (0, gst_test_clock_peek_id_count (testclock));
1524 
1525   /* Push next packet to create a gap and trigger rtx-timers */
1526   missing_seqnum = next_seqnum;
1527   next_seqnum += 1;
1528   push_test_buffer (h, next_seqnum);
1529 
1530   /* Now there should exist a rtx-timer for @next_seqnum, that will have a
1531    * timeout of the expected arrival-time for that seqnum, and a delay equal
1532    * to the elapsed time since the timeout and until now (which is the
1533    * duration of one buffer, 20 ms). */
1534   timeout = missing_seqnum * TEST_BUF_DURATION;
1535   rtx_delay_ms = TEST_BUF_MS;
1536 
1537   /* The first rtx-event is triggered immediately since the timeout + delay is
1538    * less than "now" */
1539   verify_rtx_event (h, missing_seqnum, timeout, rtx_delay_ms,
1540       TEST_BUF_DURATION);
1541   last_rtx_request = gst_clock_get_time (GST_CLOCK (testclock));
1542   fail_unless_equals_int64 (last_rtx_request,
1543       missing_seqnum * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
1544 
1545   /* now we wait for the next timeout, all following timers timeout in 40ms
1546    * increments because this is rtx-retry-timeout */
1547   rtx_delay_ms += rtx_retry_timeout_ms;
1548   gst_harness_crank_single_clock_wait (h);
1549   verify_rtx_event (h, missing_seqnum, timeout, rtx_delay_ms,
1550       TEST_BUF_DURATION);
1551   last_rtx_request = gst_clock_get_time (GST_CLOCK (testclock));
1552   fail_unless_equals_int64 (last_rtx_request,
1553       missing_seqnum * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
1554 
1555   /* And a third time... */
1556   rtx_delay_ms += rtx_retry_timeout_ms;
1557   gst_harness_crank_single_clock_wait (h);
1558   verify_rtx_event (h, missing_seqnum, timeout, rtx_delay_ms,
1559       TEST_BUF_DURATION);
1560   last_rtx_request = gst_clock_get_time (GST_CLOCK (testclock));
1561   fail_unless_equals_int64 (last_rtx_request,
1562       missing_seqnum * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
1563 
1564   /* we should now receive a packet-lost-event for packet @missing_seqnum */
1565   gst_harness_crank_single_clock_wait (h);
1566   verify_lost_event (h, missing_seqnum, timeout, TEST_BUF_DURATION);
1567 
1568   /* Finally pull out the next packet */
1569   gst_buffer_unref (gst_harness_pull (h));
1570 
1571   gst_object_unref (testclock);
1572   gst_harness_teardown (h);
1573 }
1574 
1575 GST_END_TEST;
1576 
GST_START_TEST(test_rtx_two_missing)1577 GST_START_TEST (test_rtx_two_missing)
1578 {
1579   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1580   gint latency_ms = 200;
1581   guint next_seqnum;
1582   GstClockTime last_rtx_request, now;
1583   gint rtx_delay_ms_0 = TEST_BUF_MS / 2;
1584   gint rtx_delay_ms_1 = TEST_BUF_MS;
1585 
1586   g_object_set (h->element, "do-retransmission", TRUE, NULL);
1587   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
1588   fail_unless_equals_int (11, next_seqnum);
1589 
1590   /*
1591    * The expected sequence of buffers is this:
1592    *      ____   ____   ____   ____
1593    * ... | 10 | | 11 | | 12 | | 13 |
1594    *      ––––   ––––   ––––   ––––
1595    *      200ms  220ms  240ms  260ms
1596    *
1597    * But instead we get this:
1598    *      ____    _ _    _ _   ____
1599    * ... | 10 |  |   |  |   | | 13 |
1600    *      ––––    - -    - -   ––––
1601    *      200ms                260ms
1602    *
1603    * Now it is important to note that the next thing that happens is that
1604    * the RTX timeout for packet 11 will happen at time 230ms, so we crank
1605    * the timer thread to advance the time to this:
1606    */
1607   gst_harness_crank_single_clock_wait (h);
1608   verify_rtx_event (h, 11, 11 * TEST_BUF_DURATION,
1609       rtx_delay_ms_0, TEST_BUF_DURATION);
1610   last_rtx_request = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1611   fail_unless_equals_int64 (last_rtx_request,
1612       11 * TEST_BUF_DURATION + rtx_delay_ms_0 * GST_MSECOND);
1613   gst_harness_wait_for_clock_id_waits (h, 1, 60);
1614 
1615   /* The next scheduled RTX for packet 11 is now at 230 + 40 = 270ms,
1616      so the next thing that happens is that buffer 13 arrives in perfect time: */
1617   now = 13 * TEST_BUF_DURATION;
1618   gst_harness_set_time (h, now);
1619   fail_unless_equals_int (GST_FLOW_OK,
1620       gst_harness_push (h,
1621           generate_test_buffer_full (now, 13, 13 * TEST_RTP_TS_DURATION)));
1622 
1623   /*
1624    *
1625    * This will estimate the dts on the two missing packets to:
1626    *      ____   ____
1627    * ... | 11 | | 12 | ...
1628    *      ––––   ––––
1629    *      220ms  240ms
1630    *
1631    * And given their regular interspacing of 20ms, it will schedule two RTX
1632    * timers for them like so:
1633    *
1634    *      ____   ____
1635    * ... | 11 | | 12 | ...
1636    *      ––––   ––––
1637    *      230ms  250ms
1638    *
1639    * There are however two problems, packet 11 we have already sent one RTX for
1640    * and its timeout is currently at 270ms, so we should not tamper with that,
1641    * and as for packet 12, 250ms has already expired, so we now expect to see
1642    * an rtx-event being sent for packet 12 immediately.
1643    *
1644    * Since the current time is 260 ms and packet 12 was expected at 240 ms,
1645    * the delay of the rtx-event is 20 ms.
1646    */
1647   verify_rtx_event (h, 12, 12 * TEST_BUF_DURATION,
1648       rtx_delay_ms_1, TEST_BUF_DURATION);
1649   last_rtx_request = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1650   fail_unless_equals_int64 (last_rtx_request,
1651       12 * TEST_BUF_DURATION + rtx_delay_ms_1 * GST_MSECOND);
1652 
1653   /* and another crank will see the second RTX event being sent for packet 11 */
1654   gst_harness_crank_single_clock_wait (h);
1655   rtx_delay_ms_0 += 40;
1656   verify_rtx_event (h, 11, 11 * TEST_BUF_DURATION,
1657       rtx_delay_ms_0, TEST_BUF_DURATION);
1658   last_rtx_request = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1659   fail_unless_equals_int64 (last_rtx_request,
1660       11 * TEST_BUF_DURATION + rtx_delay_ms_0 * GST_MSECOND);
1661 
1662   gst_harness_teardown (h);
1663 }
1664 
1665 GST_END_TEST;
1666 
GST_START_TEST(test_rtx_buffer_arrives_just_in_time)1667 GST_START_TEST (test_rtx_buffer_arrives_just_in_time)
1668 {
1669   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1670   gint latency_ms = 5 * TEST_BUF_MS;
1671   gint next_seqnum;
1672   GstBuffer *buffer;
1673   GstClockTime now, last_rtx_request;
1674   gint rtx_delay_ms = TEST_BUF_MS / 2;
1675 
1676   g_object_set (h->element, "do-retransmission", TRUE,
1677       "rtx-max-retries", 1, NULL);
1678   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
1679 
1680   /* Crank clock to send retransmission events requesting seqnum 6 which has
1681    * not arrived yet. */
1682   gst_harness_crank_single_clock_wait (h);
1683   verify_rtx_event (h, next_seqnum,
1684       next_seqnum * TEST_BUF_DURATION, rtx_delay_ms, TEST_BUF_DURATION);
1685 
1686   last_rtx_request = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1687   fail_unless_equals_int64 (last_rtx_request,
1688       next_seqnum * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
1689 
1690   /* seqnum 6 arrives just before it times out and is considered lost */
1691   now = 200 * GST_MSECOND;
1692   gst_harness_set_time (h, now);
1693   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
1694           generate_test_buffer_rtx (now, next_seqnum)));
1695   buffer = gst_harness_pull (h);
1696   fail_unless_equals_int (next_seqnum, get_rtp_seq_num (buffer));
1697   gst_buffer_unref (buffer);
1698 
1699   fail_unless (verify_jb_stats (h->element,
1700           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
1701               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum + 1,
1702               "num-lost", G_TYPE_UINT64, (guint64) 0,
1703               "rtx-count", G_TYPE_UINT64, (guint64) 1,
1704               "rtx-success-count", G_TYPE_UINT64, (guint64) 1,
1705               "rtx-per-packet", G_TYPE_DOUBLE, 1.0,
1706               "rtx-rtt", G_TYPE_UINT64, (guint64) (now - last_rtx_request),
1707               NULL)));
1708 
1709   gst_harness_teardown (h);
1710 }
1711 
1712 GST_END_TEST;
1713 
GST_START_TEST(test_rtx_buffer_arrives_too_late)1714 GST_START_TEST (test_rtx_buffer_arrives_too_late)
1715 {
1716   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1717   gint latency_ms = 5 * TEST_BUF_MS;
1718   gint next_seqnum;
1719   GstClockTime now, last_rtx_request;
1720   gint rtx_delay_ms = TEST_BUF_MS / 2;
1721 
1722   g_object_set (h->element, "do-retransmission", TRUE,
1723       "do-lost", TRUE, "rtx-max-retries", 1, NULL);
1724   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
1725 
1726   /* Crank clock to send retransmission events requesting seqnum 6 which has
1727    * not arrived yet. */
1728   gst_harness_crank_single_clock_wait (h);
1729   verify_rtx_event (h, next_seqnum,
1730       next_seqnum * TEST_BUF_DURATION, rtx_delay_ms, TEST_BUF_DURATION);
1731 
1732   last_rtx_request = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1733   fail_unless_equals_int64 (last_rtx_request,
1734       next_seqnum * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
1735 
1736   /* packet @next_seqnum is considered lost */
1737   gst_harness_crank_single_clock_wait (h);
1738   verify_lost_event (h, next_seqnum,
1739       next_seqnum * TEST_BUF_DURATION, TEST_BUF_DURATION);
1740 
1741   /* packet @next_seqnum arrives too late */
1742   now = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1743   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
1744           generate_test_buffer_rtx (now, next_seqnum)));
1745 
1746   fail_unless (verify_jb_stats (h->element,
1747           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
1748               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum,
1749               "num-lost", G_TYPE_UINT64, (guint64) 1,
1750               "num-late", G_TYPE_UINT64, (guint64) 1,
1751               "num-duplicates", G_TYPE_UINT64, (guint64) 0,
1752               "rtx-count", G_TYPE_UINT64, (guint64) 1,
1753               "rtx-success-count", G_TYPE_UINT64, (guint64) 0,
1754               "rtx-per-packet", G_TYPE_DOUBLE, 1.0,
1755               "rtx-rtt", G_TYPE_UINT64, (guint64) (now - last_rtx_request),
1756               NULL)));
1757 
1758   gst_harness_teardown (h);
1759 }
1760 
1761 GST_END_TEST;
1762 
GST_START_TEST(test_rtx_original_buffer_does_not_update_rtx_stats)1763 GST_START_TEST (test_rtx_original_buffer_does_not_update_rtx_stats)
1764 {
1765   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1766   gint latency_ms = 100;
1767   gint next_seqnum;
1768   GstBuffer *buffer;
1769   GstClockTime now, last_rtx_request;
1770   gint rtx_delay_ms = TEST_BUF_MS / 2;
1771 
1772   g_object_set (h->element, "do-retransmission", TRUE,
1773       "rtx-max-retries", 1, NULL);
1774   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
1775   fail_unless_equals_int (6, next_seqnum);
1776 
1777   /* Crank clock to send retransmission events requesting @next_seqnum which has
1778    * not arrived yet. */
1779   gst_harness_crank_single_clock_wait (h);
1780   verify_rtx_event (h, next_seqnum,
1781       next_seqnum * TEST_BUF_DURATION, rtx_delay_ms, TEST_BUF_DURATION);
1782 
1783   last_rtx_request = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1784   fail_unless_equals_int64 (last_rtx_request,
1785       next_seqnum * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
1786 
1787   /* make sure the wait has settled before moving on */
1788   gst_harness_wait_for_clock_id_waits (h, 1, 1);
1789 
1790   /* ORIGINAL seqnum 6 arrives just before it times out and is considered
1791    * lost. */
1792   now = 200 * GST_MSECOND;
1793   gst_harness_set_time (h, now);
1794   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
1795           generate_test_buffer_full (now,
1796               next_seqnum, next_seqnum * TEST_RTP_TS_DURATION)));
1797   buffer = gst_harness_pull (h);
1798   fail_unless_equals_int (next_seqnum, get_rtp_seq_num (buffer));
1799   gst_buffer_unref (buffer);
1800 
1801   /* due to the advance in time, we will now also have sent
1802      an rtx-request for 7 */
1803   next_seqnum++;
1804   verify_rtx_event (h, next_seqnum,
1805       next_seqnum * TEST_BUF_DURATION, 60, TEST_BUF_DURATION);
1806 
1807   /* The original buffer does not count in the RTX stats. */
1808   fail_unless (verify_jb_stats (h->element,
1809           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
1810               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum,
1811               "num-lost", G_TYPE_UINT64, (guint64) 0,
1812               "num-late", G_TYPE_UINT64, (guint64) 0,
1813               "num-duplicates", G_TYPE_UINT64, (guint64) 0,
1814               "rtx-count", G_TYPE_UINT64, (guint64) 2,
1815               "rtx-success-count", G_TYPE_UINT64, (guint64) 0,
1816               "rtx-per-packet", G_TYPE_DOUBLE, 0.0,
1817               "rtx-rtt", G_TYPE_UINT64, (guint64) 0, NULL)));
1818 
1819   /* Now the retransmitted packet arrives and stats should be updated. Note
1820    * that the buffer arrives in time and should not be considered late, but
1821    * a duplicate. */
1822   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
1823           generate_test_buffer_rtx (now, 6)));
1824 
1825   fail_unless (verify_jb_stats (h->element,
1826           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
1827               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum,
1828               "num-lost", G_TYPE_UINT64, (guint64) 0,
1829               "num-late", G_TYPE_UINT64, (guint64) 0,
1830               "num-duplicates", G_TYPE_UINT64, (guint64) 1,
1831               "rtx-count", G_TYPE_UINT64, (guint64) 2,
1832               "rtx-success-count", G_TYPE_UINT64, (guint64) 0,
1833               "rtx-per-packet", G_TYPE_DOUBLE, 1.0,
1834               "rtx-rtt", G_TYPE_UINT64, (guint64) (now - last_rtx_request),
1835               NULL)));
1836 
1837   gst_harness_teardown (h);
1838 }
1839 
1840 GST_END_TEST;
1841 
GST_START_TEST(test_rtx_duplicate_packet_updates_rtx_stats)1842 GST_START_TEST (test_rtx_duplicate_packet_updates_rtx_stats)
1843 {
1844   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1845   gint latency_ms = 100;
1846   gint next_seqnum;
1847   GstClockTime now, rtx_request_6, rtx_request_7;
1848   gint rtx_delay_ms = TEST_BUF_MS / 2;
1849   gint i;
1850 
1851   g_object_set (h->element, "do-retransmission", TRUE, NULL);
1852   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
1853   fail_unless_equals_int (6, next_seqnum);
1854 
1855   /* Push packet 8 so that 6 and 7 is missing */
1856   fail_unless_equals_int (GST_FLOW_OK,
1857       gst_harness_push (h, generate_test_buffer (8)));
1858 
1859   /* Wait for NACKs on 6 and 7 */
1860   gst_harness_crank_single_clock_wait (h);
1861   verify_rtx_event (h, 6, 6 * TEST_BUF_DURATION,
1862       rtx_delay_ms, TEST_BUF_DURATION);
1863   rtx_request_6 = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1864   fail_unless_equals_int64 (rtx_request_6,
1865       6 * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
1866 
1867   gst_harness_crank_single_clock_wait (h);
1868   verify_rtx_event (h,
1869       7, 7 * TEST_BUF_DURATION, rtx_delay_ms, TEST_BUF_DURATION);
1870   rtx_request_7 = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1871   fail_unless_equals_int64 (rtx_request_7,
1872       7 * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
1873 
1874   /* Original packet 7 arrives */
1875   now = 161 * GST_MSECOND;
1876   gst_harness_set_time (h, now);
1877   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
1878           generate_test_buffer_full (now, 7, 7 * TEST_RTP_TS_DURATION)));
1879 
1880   /* We're still waiting for packet 6, so 7 should not be pushed */
1881   gst_harness_wait_for_clock_id_waits (h, 1, 60);
1882   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 0);
1883 
1884   /* The original buffer does not count in the RTX stats. */
1885   fail_unless (verify_jb_stats (h->element,
1886           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
1887               "num-lost", G_TYPE_UINT64, (guint64) 0,
1888               "num-late", G_TYPE_UINT64, (guint64) 0,
1889               "num-duplicates", G_TYPE_UINT64, (guint64) 0,
1890               "rtx-count", G_TYPE_UINT64, (guint64) 2,
1891               "rtx-success-count", G_TYPE_UINT64, (guint64) 0,
1892               "rtx-per-packet", G_TYPE_DOUBLE, 0.0,
1893               "rtx-rtt", G_TYPE_UINT64, (guint64) 0, NULL)));
1894 
1895   /* Push RTX packet 7. Should be dropped as duplicate but update RTX stats. */
1896   now = 162 * GST_MSECOND;
1897   gst_harness_set_time (h, now);
1898   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
1899           generate_test_buffer_rtx (now, 7)));
1900   gst_harness_wait_for_clock_id_waits (h, 1, 60);
1901   fail_unless_equals_int (gst_harness_buffers_in_queue (h), 0);
1902 
1903   /* Check RTX stats with updated num-duplicates and rtx-rtt fields */
1904   fail_unless (verify_jb_stats (h->element,
1905           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
1906               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum,
1907               "num-lost", G_TYPE_UINT64, (guint64) 0,
1908               "num-late", G_TYPE_UINT64, (guint64) 0,
1909               "num-duplicates", G_TYPE_UINT64, (guint64) 1,
1910               "rtx-count", G_TYPE_UINT64, (guint64) 2,
1911               "rtx-success-count", G_TYPE_UINT64, (guint64) 0,
1912               "rtx-per-packet", G_TYPE_DOUBLE, 1.0,
1913               "rtx-rtt", G_TYPE_UINT64, (guint64) (now - rtx_request_7),
1914               NULL)));
1915 
1916   /* RTX packet 6 arrives, both 6, 7 and 8 is ready to be pulled */
1917   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
1918           generate_test_buffer_rtx (now, 6)));
1919 
1920   for (i = 6; i <= 8; i++) {
1921     GstBuffer *buf = gst_harness_pull (h);
1922     fail_unless_equals_int (i, get_rtp_seq_num (buf));
1923     gst_buffer_unref (buf);
1924   }
1925 
1926   /* RTX stats is updated with success count increased. */
1927   fail_unless (verify_jb_stats (h->element,
1928           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
1929               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum + 3,
1930               "num-lost", G_TYPE_UINT64, (guint64) 0,
1931               "num-late", G_TYPE_UINT64, (guint64) 0,
1932               "num-duplicates", G_TYPE_UINT64, (guint64) 1,
1933               "rtx-count", G_TYPE_UINT64, (guint64) 2,
1934               "rtx-success-count", G_TYPE_UINT64, (guint64) 1,
1935               "rtx-per-packet", G_TYPE_DOUBLE, 1.0,
1936               "rtx-rtt", G_TYPE_UINT64, (guint64)
1937               /* Use the rtx-rtt formula. Can be subject to change though. */
1938               ((now - rtx_request_6) + 47 * (now - rtx_request_7)) / 48,
1939               NULL)));
1940 
1941   gst_harness_teardown (h);
1942 }
1943 
1944 GST_END_TEST;
1945 
GST_START_TEST(test_rtx_buffer_arrives_after_lost_updates_rtx_stats)1946 GST_START_TEST (test_rtx_buffer_arrives_after_lost_updates_rtx_stats)
1947 {
1948   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
1949   gint latency_ms = 100;
1950   gint next_seqnum;
1951   GstClockTime now, last_rtx_request;
1952   gint rtx_delay_ms = TEST_BUF_MS / 2;
1953 
1954   g_object_set (h->element, "do-retransmission", TRUE,
1955       "do-lost", TRUE, "rtx-max-retries", 1, NULL);
1956   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
1957 
1958   /* Crank clock to send retransmission events requesting seqnum 6 which has
1959    * not arrived yet. */
1960   gst_harness_crank_single_clock_wait (h);
1961   verify_rtx_event (h, next_seqnum,
1962       next_seqnum * TEST_BUF_DURATION, rtx_delay_ms, TEST_BUF_DURATION);
1963 
1964   last_rtx_request = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1965   fail_unless_equals_int64 (last_rtx_request,
1966       next_seqnum * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
1967 
1968   /* seqnum 6 is considered lost */
1969   gst_harness_crank_single_clock_wait (h);
1970   verify_lost_event (h, next_seqnum,
1971       next_seqnum * TEST_BUF_DURATION, TEST_BUF_DURATION);
1972 
1973   /* seqnum 6 arrives too late */
1974   now = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
1975   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
1976           generate_test_buffer_rtx (now, next_seqnum)));
1977 
1978   fail_unless (verify_jb_stats (h->element,
1979           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
1980               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum,
1981               "num-lost", G_TYPE_UINT64, (guint64) 1,
1982               "num-late", G_TYPE_UINT64, (guint64) 1,
1983               "num-duplicates", G_TYPE_UINT64, (guint64) 0,
1984               "rtx-count", G_TYPE_UINT64, (guint64) 1,
1985               "rtx-success-count", G_TYPE_UINT64, (guint64) 0,
1986               "rtx-per-packet", G_TYPE_DOUBLE, 1.0,
1987               "rtx-rtt", G_TYPE_UINT64, (guint64) (now - last_rtx_request),
1988               NULL)));
1989 
1990   gst_harness_teardown (h);
1991 }
1992 
1993 GST_END_TEST;
1994 
GST_START_TEST(test_rtx_rtt_larger_than_retry_timeout)1995 GST_START_TEST (test_rtx_rtt_larger_than_retry_timeout)
1996 {
1997   /* When RTT is larger than retry period we will send two or more requests
1998    * before receiving any retransmission packets */
1999   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2000   gint latency_ms = 100;
2001   gint next_seqnum;
2002   gint rtx_retry_timeout_ms = 20;
2003   gint rtx_delay_ms = TEST_BUF_MS / 2;
2004   gint rtt = rtx_retry_timeout_ms * GST_MSECOND + 1;
2005   GstClockTime now, first_request, second_request;
2006 
2007   g_object_set (h->element, "do-retransmission", TRUE,
2008       "rtx-retry-timeout", rtx_retry_timeout_ms, NULL);
2009   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
2010 
2011   /* Wait for first NACK on 6 */
2012   gst_harness_crank_single_clock_wait (h);
2013   verify_rtx_event (h, next_seqnum,
2014       next_seqnum * TEST_BUF_DURATION, rtx_delay_ms, TEST_BUF_DURATION);
2015   first_request = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
2016   fail_unless_equals_int64 (first_request,
2017       next_seqnum * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
2018 
2019   /* Packet @next_seqnum + 1 arrives in time (so that we avoid its EXPECTED
2020    * timers to interfer with our test) */
2021   push_test_buffer (h, next_seqnum + 1);
2022 
2023   /* Simulating RTT > rtx-retry-timeout, we send a new NACK before receiving
2024    * the RTX packet. Wait for second NACK on @next_seqnum */
2025   gst_harness_crank_single_clock_wait (h);
2026   rtx_delay_ms += rtx_retry_timeout_ms;
2027   verify_rtx_event (h, next_seqnum,
2028       next_seqnum * TEST_BUF_DURATION, rtx_delay_ms, TEST_BUF_DURATION);
2029   second_request = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
2030   fail_unless_equals_int64 (second_request,
2031       next_seqnum * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
2032 
2033   /* The first retransmitted packet arrives */
2034   now = first_request + rtt;
2035   gst_harness_set_time (h, now);
2036   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
2037           generate_test_buffer_rtx (now, next_seqnum)));
2038 
2039   /* Pull packets @next_seqnum and @next_seqnum + 1 */
2040   gst_buffer_unref (gst_harness_pull (h));
2041   gst_buffer_unref (gst_harness_pull (h));
2042 
2043   /* Stats should be updated. Note that RTT is not updated since we cannot be
2044    * sure whether the RTX packet is in response to the first or second NACK. */
2045   fail_unless (verify_jb_stats (h->element,
2046           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
2047               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum + 2,
2048               "num-lost", G_TYPE_UINT64, (guint64) 0,
2049               "num-late", G_TYPE_UINT64, (guint64) 0,
2050               "num-duplicates", G_TYPE_UINT64, (guint64) 0,
2051               "rtx-count", G_TYPE_UINT64, (guint64) 2,
2052               "rtx-success-count", G_TYPE_UINT64, (guint64) 1,
2053               "rtx-per-packet", G_TYPE_DOUBLE, 2.0,
2054               "rtx-rtt", G_TYPE_UINT64, (guint64) 0, NULL)));
2055 
2056   /* Packet @next_seqnum + 2 arrives in time */
2057   push_test_buffer (h, next_seqnum + 2);
2058   gst_buffer_unref (gst_harness_pull (h));
2059 
2060   /* Now the second retransmitted packet arrives */
2061   now = second_request + rtt;
2062   gst_harness_set_time (h, now);
2063   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
2064           generate_test_buffer_rtx (now, next_seqnum)));
2065 
2066   /* The stats is updated with the correct RTT. */
2067   fail_unless (verify_jb_stats (h->element,
2068           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
2069               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum + 3,
2070               "num-lost", G_TYPE_UINT64, (guint64) 0,
2071               "num-late", G_TYPE_UINT64, (guint64) 0,
2072               "num-duplicates", G_TYPE_UINT64, (guint64) 1,
2073               "rtx-count", G_TYPE_UINT64, (guint64) 2,
2074               "rtx-success-count", G_TYPE_UINT64, (guint64) 1,
2075               "rtx-per-packet", G_TYPE_DOUBLE, 2.0,
2076               "rtx-rtt", G_TYPE_UINT64, (guint64) rtt, NULL)));
2077 
2078   gst_harness_teardown (h);
2079 }
2080 
2081 GST_END_TEST;
2082 
GST_START_TEST(test_rtx_no_request_if_time_past_retry_period)2083 GST_START_TEST (test_rtx_no_request_if_time_past_retry_period)
2084 {
2085   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2086   const gint latency_ms = 200;
2087   const gint retry_period_ms = 120;
2088   GstTestClock *testclock;
2089   GstClockID pending_id;
2090   GstClockTime time;
2091   gint i;
2092 
2093   gst_harness_set_src_caps (h, generate_caps ());
2094   testclock = gst_harness_get_testclock (h);
2095 
2096   g_object_set (h->element, "do-lost", TRUE, NULL);
2097   g_object_set (h->element, "do-retransmission", TRUE, NULL);
2098   g_object_set (h->element, "latency", latency_ms, NULL);
2099   g_object_set (h->element, "rtx-retry-period", retry_period_ms, NULL);
2100 
2101   /* push the first couple of buffers */
2102   push_test_buffer (h, 0);
2103   push_test_buffer (h, 1);
2104 
2105   /* drop reconfigure event */
2106   gst_event_unref (gst_harness_pull_upstream_event (h));
2107   /* drop GstEventStreamStart & GstEventCaps & GstEventSegment */
2108   for (i = 0; i < 3; i++)
2109     gst_event_unref (gst_harness_pull_event (h));
2110 
2111   /* Wait for the first EXPECTED timer to be scheduled */
2112   gst_test_clock_wait_for_next_pending_id (testclock, &pending_id);
2113   time = gst_clock_id_get_time (pending_id);
2114   gst_clock_id_unref (pending_id);
2115   fail_unless_equals_int64 (time, 2 * TEST_BUF_DURATION + 10 * GST_MSECOND);
2116 
2117   /* Let the first EXPECTED timer time out and be sent. However, set the 'now'
2118    * time to be past the retry-period simulating that the jitterbuffer has too
2119    * much to do and is not able to process all timers in real-time. In this
2120    * case the jitterbuffer should not schedule a new EXPECTED timer as that
2121    * would just make matters worse (more unnecessary processing of a request
2122    * that is already too late to be valuable). In practice this typically
2123    * happens for high loss networks with low RTT. */
2124   gst_test_clock_set_time_and_process (testclock,
2125       2 * TEST_BUF_DURATION + retry_period_ms * GST_MSECOND + 1);
2126 
2127   /* Verify the event. It could be argued that this request is already too
2128    * late and unnecessary. However, in order to keep things simple (for now)
2129    * we just keep the already scehduled EXPECTED timer, but refrain from
2130    * scheduled another EXPECTED timer */
2131   verify_rtx_event (h, 2, 2 * TEST_BUF_DURATION, 120, TEST_BUF_DURATION);
2132 
2133   /* "crank" to reach the DEADLINE for packet 0 */
2134   gst_harness_crank_single_clock_wait (h);
2135   gst_buffer_unref (gst_harness_pull (h));
2136   gst_buffer_unref (gst_harness_pull (h));
2137 
2138   fail_unless_equals_int (0, gst_harness_upstream_events_in_queue (h));
2139   fail_unless_equals_int (0, gst_harness_events_in_queue (h));
2140 
2141   /* "crank" to time out the LOST event */
2142   gst_harness_crank_single_clock_wait (h);
2143   verify_lost_event (h, 2, 2 * TEST_BUF_DURATION, TEST_BUF_DURATION);
2144 
2145   gst_object_unref (testclock);
2146   gst_harness_teardown (h);
2147 }
2148 
2149 GST_END_TEST;
2150 
GST_START_TEST(test_rtx_same_delay_and_retry_timeout)2151 GST_START_TEST (test_rtx_same_delay_and_retry_timeout)
2152 {
2153   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2154   gint latency_ms = 5 * TEST_BUF_MS;
2155   gint next_seqnum;
2156   gint rtx_delay_ms = 20;
2157   GstClockTime last_rtx_request;
2158 
2159   g_object_set (h->element, "do-retransmission", TRUE,
2160       "rtx-max-retries", 3, "rtx-delay", rtx_delay_ms,
2161       "rtx-retry-timeout", rtx_delay_ms, NULL);
2162   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
2163 
2164   /* Crank clock to send retransmission events requesting seqnum 6 which has
2165    * not arrived yet. */
2166   gst_harness_crank_single_clock_wait (h);
2167   verify_rtx_event (h, next_seqnum,
2168       next_seqnum * TEST_BUF_DURATION, rtx_delay_ms, TEST_BUF_DURATION);
2169   /* first rtx for packet @next_seqnum should arrive at the right time */
2170   last_rtx_request = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
2171   fail_unless_equals_int64 (last_rtx_request,
2172       next_seqnum * TEST_BUF_DURATION + rtx_delay_ms * GST_MSECOND);
2173 
2174   /* verify we have pulled out all rtx-events */
2175   fail_unless_equals_int (0, gst_harness_upstream_events_in_queue (h));
2176 
2177   /* now crank to get the second attempt at packet @next_seqnum */
2178   gst_harness_crank_single_clock_wait (h);
2179   verify_rtx_event (h, next_seqnum,
2180       next_seqnum * TEST_BUF_DURATION, rtx_delay_ms * 2, TEST_BUF_DURATION);
2181 
2182   /* second rtx for seqnum 6 should arrive at 140 + 20ms */
2183   last_rtx_request = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
2184   fail_unless_equals_int64 (last_rtx_request,
2185       next_seqnum * TEST_BUF_DURATION + rtx_delay_ms * 2 * GST_MSECOND);
2186 
2187   /* verify we have pulled out all rtx-events */
2188   fail_unless_equals_int (0, gst_harness_upstream_events_in_queue (h));
2189 
2190   fail_unless (verify_jb_stats (h->element,
2191           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
2192               "num-pushed", G_TYPE_UINT64, (guint64) next_seqnum,
2193               "num-lost", G_TYPE_UINT64, (guint64) 0,
2194               "rtx-count", G_TYPE_UINT64, (guint64) 2, NULL)));
2195 
2196   gst_harness_teardown (h);
2197 }
2198 
2199 GST_END_TEST;
2200 
GST_START_TEST(test_rtx_with_backwards_rtptime)2201 GST_START_TEST (test_rtx_with_backwards_rtptime)
2202 {
2203   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2204   gint latency_ms = 40;
2205 
2206   g_object_set (h->element, "do-retransmission", TRUE, NULL);
2207   construct_deterministic_initial_state (h, latency_ms);
2208 
2209   /*
2210    * For video using B-frames, an expected sequence
2211    * could be like this:
2212    * (I = I-frame, P = P-frame, B = B-frame)
2213    *               ___   ___   ___
2214    *          ... | 3 | | 4 | | 5 |
2215    *               –––   –––   –––
2216    * rtptime:       3(I)  5(P)  4(B)
2217    * arrival(dts):  3     5     5
2218    *
2219    * Notice here that packet 5 (the B frame) make
2220    * the rtptime go backwards.
2221    */
2222 
2223   /* seqnum 3, arriving at time 3 with rtptime 3 */
2224   push_test_buffer (h, 3);
2225   gst_buffer_unref (gst_harness_pull (h));
2226 
2227   /* seqnum 4, arriving at time 5 with rtptime 5 */
2228   gst_harness_push (h, generate_test_buffer_full (5 * TEST_BUF_DURATION,
2229           4, 5 * TEST_RTP_TS_DURATION));
2230   gst_buffer_unref (gst_harness_pull (h));
2231 
2232   /* seqnum 5, arriving at time 5 with rtptime 4 */
2233   gst_harness_push (h, generate_test_buffer_full (5 * TEST_BUF_DURATION,
2234           5, 4 * TEST_RTP_TS_DURATION));
2235   gst_buffer_unref (gst_harness_pull (h));
2236 
2237   /* crank to time-out the rtx-request for seqnum 6, the point here
2238    * being that the backwards rtptime did not mess up the timeout for
2239    * the rtx event.
2240    *
2241    * Note: the jitterbuffer no longer update early timers, as a result
2242    * we need to advance the clock to the expected point
2243    */
2244   gst_harness_wait_for_clock_id_waits (h, 1, 1);
2245   gst_harness_set_time (h, 6 * TEST_BUF_DURATION + 15 * GST_MSECOND);
2246   gst_harness_crank_single_clock_wait (h);
2247   verify_rtx_event (h, 6, 5 * TEST_BUF_DURATION + 15 * GST_MSECOND,
2248       20, 35 * GST_MSECOND);
2249 
2250   fail_unless (verify_jb_stats (h->element,
2251           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
2252               "num-pushed", G_TYPE_UINT64, (guint64) 6,
2253               "rtx-count", G_TYPE_UINT64, (guint64) 1,
2254               "num-lost", G_TYPE_UINT64, (guint64) 0, NULL)));
2255 
2256   gst_harness_teardown (h);
2257 }
2258 
2259 GST_END_TEST;
2260 
GST_START_TEST(test_rtx_timer_reuse)2261 GST_START_TEST (test_rtx_timer_reuse)
2262 {
2263   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2264   gint latency_ms = 5 * TEST_BUF_MS;
2265   gint rtx_delay_ms = TEST_BUF_MS / 2;
2266   guint next_seqnum;
2267 
2268   g_object_set (h->element, "do-retransmission", TRUE,
2269       "do-lost", TRUE, "rtx-max-retries", 1, NULL);
2270   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
2271 
2272   /* crank to timeout the only rtx-request, and the timer will
2273    * now reschedule as a lost-timer internally */
2274   gst_harness_crank_single_clock_wait (h);
2275   verify_rtx_event (h, next_seqnum,
2276       next_seqnum * TEST_BUF_DURATION, rtx_delay_ms, TEST_BUF_DURATION);
2277 
2278   /* but now buffer 6 arrives, and this should now reuse the lost-timer
2279    * for 6, as an expected-timer for 7 */
2280   fail_unless_equals_int (GST_FLOW_OK,
2281       gst_harness_push (h, generate_test_buffer (next_seqnum)));
2282 
2283   /* now crank to timeout the expected-timer for 7 and verify */
2284   next_seqnum++;
2285   gst_harness_crank_single_clock_wait (h);
2286   verify_rtx_event (h, next_seqnum,
2287       next_seqnum * TEST_BUF_DURATION, rtx_delay_ms, TEST_BUF_DURATION);
2288 
2289   gst_harness_teardown (h);
2290 }
2291 
2292 GST_END_TEST;
2293 
2294 
2295 static void
start_test_rtx_large_packet_spacing(GstHarness * h,gint latency_ms,gint frame_dur_ms,gint rtx_rtt_ms,guint16 * dst_lost_seq,GstClockTime * dst_now)2296 start_test_rtx_large_packet_spacing (GstHarness * h,
2297     gint latency_ms, gint frame_dur_ms, gint rtx_rtt_ms,
2298     guint16 * dst_lost_seq, GstClockTime * dst_now)
2299 {
2300   gint i, seq, frame;
2301   GstBuffer *buffer;
2302   GstClockTime now, lost_packet_time;
2303   GstClockTime frame_dur = frame_dur_ms * GST_MSECOND;
2304 
2305   gst_harness_set_src_caps (h, generate_caps ());
2306   g_object_set (h->element,
2307       "do-lost", TRUE, "latency", latency_ms, "do-retransmission", TRUE, NULL);
2308 
2309   /* Pushing 2 frames @frame_dur_ms ms apart from each other to initialize
2310    * packet_spacing and avg jitter */
2311   for (frame = 0, seq = 0, now = 0; frame < 2;
2312       frame++, seq += 2, now += frame_dur) {
2313     gst_harness_set_time (h, now);
2314     gst_harness_push (h, generate_test_buffer_full (now, seq,
2315             AS_TEST_BUF_RTP_TIME (now)));
2316     gst_harness_push (h, generate_test_buffer_full (now, seq + 1,
2317             AS_TEST_BUF_RTP_TIME (now)));
2318 
2319     if (frame == 0)
2320       /* deadline for buffer 0 expires */
2321       gst_harness_crank_single_clock_wait (h);
2322 
2323     gst_buffer_unref (gst_harness_pull (h));
2324     gst_buffer_unref (gst_harness_pull (h));
2325   }
2326 
2327   /* drop GstEventStreamStart & GstEventCaps & GstEventSegment */
2328   for (i = 0; i < 3; i++)
2329     gst_event_unref (gst_harness_pull_event (h));
2330   /* drop reconfigure event */
2331   gst_event_unref (gst_harness_pull_upstream_event (h));
2332 
2333   /* The first packet (#@seq) of the 3rd frame is lost */
2334   lost_packet_time = now;
2335   gst_harness_set_time (h, now);
2336   gst_harness_push (h, generate_test_buffer_full (now, seq + 1,
2337           AS_TEST_BUF_RTP_TIME (now)));
2338 
2339   /* RTX delay calculated as:
2340    *     MIN(rtx_delay_max, MAX(2*avg_jitter, 0.5 * packet_spacing)).
2341    * Where rtx_delay_max:
2342    *     rtx_delay_max = latency - rtx_rtt.
2343    * We have not used RTX yet, so rtx_rtt = 0, rtx_delay_max = latency.
2344    * Thus we expect the first RTX event to be sent in @latency_ms ms */
2345   gst_harness_crank_single_clock_wait (h);
2346   fail_unless_equals_int64 (now + latency_ms * GST_MSECOND,
2347       gst_clock_get_time (GST_ELEMENT_CLOCK (h->element)));
2348   verify_rtx_event (h, seq, now, latency_ms, frame_dur);
2349   verify_lost_event (h, seq, now, 0);
2350   gst_buffer_unref (gst_harness_pull (h));
2351   now += latency_ms * GST_MSECOND;
2352 
2353   /* Sending lost packet as RTX to initialize rtx_rtt */
2354   now += rtx_rtt_ms * GST_MSECOND;
2355   gst_harness_set_time (h, now);
2356   buffer =
2357       generate_test_buffer_full (now, seq,
2358       AS_TEST_BUF_RTP_TIME (lost_packet_time));
2359   GST_BUFFER_FLAG_SET (buffer, GST_RTP_BUFFER_FLAG_RETRANSMISSION);
2360   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer));
2361 
2362   /* No buffers should be pushed through, as lost packet arrived too late */
2363   fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
2364 
2365   seq += 2;
2366   frame += 1;
2367   now = frame * frame_dur;
2368   gst_harness_set_time (h, now);
2369 
2370   /* The first packet (#@seq) of the 4th frame is lost */
2371   gst_harness_push (h, generate_test_buffer_full (now, seq + 1,
2372           AS_TEST_BUF_RTP_TIME (now)));
2373   *dst_lost_seq = seq;
2374   *dst_now = now;
2375 }
2376 
GST_START_TEST(test_rtx_large_packet_spacing_and_small_rtt)2377 GST_START_TEST (test_rtx_large_packet_spacing_and_small_rtt)
2378 {
2379   GstClockTime now;
2380   guint16 lost_seq;
2381   gint latency_ms = 20;
2382   gint frame_dur_ms = 50;
2383   gint rtx_rtt_ms = 5;
2384   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2385 
2386   start_test_rtx_large_packet_spacing (h, latency_ms, frame_dur_ms, rtx_rtt_ms,
2387       &lost_seq, &now);
2388 
2389   /* With small rtx_rtt, RTX event expected to be sent in
2390      (@latency_ms - @rtx_rtt_ms) ms */
2391   gst_harness_crank_single_clock_wait (h);
2392   fail_unless_equals_int64 (now + (latency_ms - rtx_rtt_ms) * GST_MSECOND,
2393       gst_clock_get_time (GST_ELEMENT_CLOCK (h->element)));
2394   verify_rtx_event (h, lost_seq, now, (latency_ms - rtx_rtt_ms),
2395       frame_dur_ms * GST_MSECOND);
2396 
2397   /* After @latency ms the packet should be considered lost */
2398   gst_harness_crank_single_clock_wait (h);
2399   fail_unless_equals_int64 (now + latency_ms * GST_MSECOND,
2400       gst_clock_get_time (GST_ELEMENT_CLOCK (h->element)));
2401   verify_lost_event (h, lost_seq, now, 0);
2402   gst_buffer_unref (gst_harness_pull (h));
2403 
2404   gst_harness_teardown (h);
2405 }
2406 
2407 GST_END_TEST;
2408 
GST_START_TEST(test_rtx_large_packet_spacing_and_large_rtt)2409 GST_START_TEST (test_rtx_large_packet_spacing_and_large_rtt)
2410 {
2411   GstClockTime now;
2412   guint16 lost_seq;
2413   gint latency_ms = 20;
2414   gint frame_dur_ms = 50;
2415   gint rtx_rtt_ms = 30;
2416   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2417 
2418   start_test_rtx_large_packet_spacing (h, latency_ms, frame_dur_ms, rtx_rtt_ms,
2419       &lost_seq, &now);
2420 
2421   /* With large rtx_rtt, RTX event expected to be sent in @latency_ms ms.
2422      The buffer considered lost. */
2423   gst_harness_crank_single_clock_wait (h);
2424   fail_unless_equals_int64 (now + latency_ms * GST_MSECOND,
2425       gst_clock_get_time (GST_ELEMENT_CLOCK (h->element)));
2426   verify_rtx_event (h, lost_seq, now, latency_ms, frame_dur_ms * GST_MSECOND);
2427   verify_lost_event (h, lost_seq, now, 0);
2428   gst_buffer_unref (gst_harness_pull (h));
2429 
2430   gst_harness_teardown (h);
2431 }
2432 
2433 GST_END_TEST;
2434 
GST_START_TEST(test_rtx_large_packet_spacing_does_not_reset_jitterbuffer)2435 GST_START_TEST (test_rtx_large_packet_spacing_does_not_reset_jitterbuffer)
2436 {
2437   gint latency_ms = 20;
2438   gint frame_dur_ms = 50;
2439   gint rtx_rtt_ms = 5;
2440   gint i, seq;
2441   GstBuffer *buffer;
2442   GstClockTime now, lost_packet_time;
2443   GstClockTime frame_dur = frame_dur_ms * GST_MSECOND;
2444   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2445 
2446   gst_harness_set_src_caps (h, generate_caps ());
2447   g_object_set (h->element,
2448       "do-lost", TRUE, "latency", latency_ms, "do-retransmission", TRUE, NULL);
2449 
2450   /* Pushing 2 frames @frame_dur_ms ms apart from each other to initialize
2451    * packet_spacing and avg jitter */
2452   for (seq = 0, now = 0; seq < 2; ++seq, now += frame_dur) {
2453     gst_harness_set_time (h, now);
2454     gst_harness_push (h, generate_test_buffer_full (now, seq,
2455             AS_TEST_BUF_RTP_TIME (now)));
2456     if (seq == 0)
2457       gst_harness_crank_single_clock_wait (h);
2458     buffer = gst_harness_pull (h);
2459     fail_unless_equals_int64 (now, GST_BUFFER_PTS (buffer));
2460     gst_buffer_unref (buffer);
2461   }
2462 
2463   /* drop GstEventStreamStart & GstEventCaps & GstEventSegment */
2464   for (i = 0; i < 3; i++)
2465     gst_event_unref (gst_harness_pull_event (h));
2466   /* drop reconfigure event */
2467   gst_event_unref (gst_harness_pull_upstream_event (h));
2468 
2469   /* Waiting for the RTX timer of packet #2 to timeout */
2470   lost_packet_time = now;
2471   gst_harness_crank_single_clock_wait (h);
2472   fail_unless_equals_int64 (now + latency_ms * GST_MSECOND,
2473       gst_clock_get_time (GST_ELEMENT_CLOCK (h->element)));
2474   verify_rtx_event (h, seq, now, latency_ms, frame_dur);
2475   verify_lost_event (h, seq, now, frame_dur);
2476   now += latency_ms * GST_MSECOND;
2477 
2478   /* Pushing packet #2 as RTX */
2479   now += rtx_rtt_ms * GST_MSECOND;
2480   gst_harness_set_time (h, now);
2481   buffer =
2482       generate_test_buffer_full (now, seq,
2483       AS_TEST_BUF_RTP_TIME (lost_packet_time));
2484   GST_BUFFER_FLAG_SET (buffer, GST_RTP_BUFFER_FLAG_RETRANSMISSION);
2485   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h, buffer));
2486   fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
2487 
2488   /* Packet #3 should have PTS not affected by clock skew logic */
2489   seq += 1;
2490   now = seq * frame_dur;
2491   gst_harness_set_time (h, now);
2492   gst_harness_push (h, generate_test_buffer_full (now, seq,
2493           AS_TEST_BUF_RTP_TIME (now)));
2494   buffer = gst_harness_pull (h);
2495   fail_unless_equals_int64 (now, GST_BUFFER_PTS (buffer));
2496   gst_buffer_unref (buffer);
2497 
2498   gst_harness_teardown (h);
2499 }
2500 
2501 GST_END_TEST;
2502 
GST_START_TEST(test_minor_reorder_does_not_skew)2503 GST_START_TEST (test_minor_reorder_does_not_skew)
2504 {
2505   gint latency_ms = 20;
2506   gint frame_dur_ms = 50;
2507   guint rtx_min_delay_ms = 110;
2508   gint hickup_ms = 2;
2509   gint i, seq;
2510   GstBuffer *buffer;
2511   GstClockTime now;
2512   GstClockTime frame_dur = frame_dur_ms * GST_MSECOND;
2513   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2514 
2515   gst_harness_set_src_caps (h, generate_caps ());
2516   g_object_set (h->element,
2517       "do-lost", TRUE, "latency", latency_ms, "do-retransmission", TRUE,
2518       "rtx-min-delay", rtx_min_delay_ms, NULL);
2519 
2520   /* Pushing 2 frames @frame_dur_ms ms apart from each other to initialize
2521    * packet_spacing and avg jitter */
2522   for (seq = 0, now = 0; seq < 2; ++seq, now += frame_dur) {
2523     gst_harness_set_time (h, now);
2524     gst_harness_push (h, generate_test_buffer_full (now, seq,
2525             AS_TEST_BUF_RTP_TIME (now)));
2526     if (seq == 0)
2527       gst_harness_crank_single_clock_wait (h);
2528     buffer = gst_harness_pull (h);
2529     fail_unless_equals_int64 (now, GST_BUFFER_PTS (buffer));
2530     gst_buffer_unref (buffer);
2531   }
2532 
2533   /* drop GstEventStreamStart & GstEventCaps & GstEventSegment */
2534   for (i = 0; i < 3; i++)
2535     gst_event_unref (gst_harness_pull_event (h));
2536   /* drop reconfigure event */
2537   gst_event_unref (gst_harness_pull_upstream_event (h));
2538 
2539   /* Pushing packet #4 before #3, shortly after #3 would have arrived normally */
2540   gst_harness_set_time (h, now + hickup_ms * GST_MSECOND);
2541   gst_harness_push (h, generate_test_buffer_full (now + hickup_ms * GST_MSECOND,
2542           seq + 1, AS_TEST_BUF_RTP_TIME (now + frame_dur)));
2543 
2544   /* Pushing packet #3 after #4 when #4 would have normally arrived */
2545   gst_harness_set_time (h, now + frame_dur);
2546   gst_harness_push (h, generate_test_buffer_full (now + frame_dur, seq,
2547           AS_TEST_BUF_RTP_TIME (now)));
2548 
2549   /* Pulling should be retrieving #3 first */
2550   buffer = gst_harness_pull (h);
2551   fail_unless_equals_int64 (now, GST_BUFFER_PTS (buffer));
2552   gst_buffer_unref (buffer);
2553 
2554   /* Pulling should be retrieving #4 second */
2555   buffer = gst_harness_pull (h);
2556   fail_unless_equals_int64 (now + frame_dur, GST_BUFFER_PTS (buffer));
2557   gst_buffer_unref (buffer);
2558 
2559   now += 2 * frame_dur;
2560   seq += 2;
2561 
2562   /* Pushing packet #5 normal again */
2563   gst_harness_set_time (h, now);
2564   gst_harness_push (h, generate_test_buffer_full (now, seq,
2565           AS_TEST_BUF_RTP_TIME (now)));
2566   buffer = gst_harness_pull (h);
2567   fail_unless_equals_int64 (now, GST_BUFFER_PTS (buffer));
2568   gst_buffer_unref (buffer);
2569 
2570   seq++;
2571   now += frame_dur;
2572 
2573   /* Pushing packet #6 half a frame early to trigger clock skew */
2574   gst_harness_set_time (h, now);
2575   gst_harness_push (h, generate_test_buffer_full (now, seq,
2576           AS_TEST_BUF_RTP_TIME (now + frame_dur / 2)));
2577   buffer = gst_harness_pull (h);
2578   fail_unless (now + frame_dur / 2 > GST_BUFFER_PTS (buffer),
2579       "pts should have been adjusted due to clock skew");
2580   gst_buffer_unref (buffer);
2581 
2582   gst_harness_teardown (h);
2583 }
2584 
2585 GST_END_TEST;
2586 
GST_START_TEST(test_deadline_ts_offset)2587 GST_START_TEST (test_deadline_ts_offset)
2588 {
2589   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2590   GstTestClock *testclock;
2591   GstClockID id;
2592   const gint jb_latency_ms = 10;
2593 
2594   gst_harness_set_src_caps (h, generate_caps ());
2595   testclock = gst_harness_get_testclock (h);
2596 
2597   g_object_set (h->element, "latency", jb_latency_ms, NULL);
2598 
2599   /* push the first buffer in */
2600   fail_unless_equals_int (GST_FLOW_OK,
2601       gst_harness_push (h, generate_test_buffer (0)));
2602 
2603   /* wait_next_timeout() syncs on the deadline timer */
2604   gst_test_clock_wait_for_next_pending_id (testclock, &id);
2605   fail_unless_equals_uint64 (jb_latency_ms * GST_MSECOND,
2606       gst_clock_id_get_time (id));
2607   gst_clock_id_unref (id);
2608 
2609   /* add ts-offset while waiting */
2610   g_object_set (h->element, "ts-offset", 20 * GST_MSECOND, NULL);
2611 
2612   gst_test_clock_set_time_and_process (testclock, jb_latency_ms * GST_MSECOND);
2613 
2614   /* wait_next_timeout() syncs on the new deadline timer */
2615   gst_test_clock_wait_for_next_pending_id (testclock, &id);
2616   fail_unless_equals_uint64 ((20 + jb_latency_ms) * GST_MSECOND,
2617       gst_clock_id_get_time (id));
2618   gst_clock_id_unref (id);
2619 
2620   /* now make deadline timer timeout */
2621   gst_test_clock_set_time_and_process (testclock,
2622       (20 + jb_latency_ms) * GST_MSECOND);
2623 
2624   gst_buffer_unref (gst_harness_pull (h));
2625 
2626   gst_object_unref (testclock);
2627   gst_harness_teardown (h);
2628 }
2629 
2630 GST_END_TEST;
2631 
GST_START_TEST(test_big_gap_seqnum)2632 GST_START_TEST (test_big_gap_seqnum)
2633 {
2634   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2635   const gint num_consecutive = 5;
2636   const guint gap = 20000;
2637   gint i;
2638   guint seqnum_org;
2639   GstClockTime dts_base;
2640   guint seqnum_base;
2641   guint32 rtpts_base;
2642   GstClockTime expected_ts;
2643 
2644   g_object_set (h->element, "do-lost", TRUE, "do-retransmission", TRUE, NULL);
2645   seqnum_org = construct_deterministic_initial_state (h, 100);
2646 
2647   /* a sudden jump in sequence-numbers (and rtptime), but packets keep arriving
2648      at the same pace */
2649   dts_base = seqnum_org * TEST_BUF_DURATION;
2650   seqnum_base = seqnum_org + gap;
2651   rtpts_base = seqnum_base * TEST_RTP_TS_DURATION;
2652 
2653   for (i = 0; i < num_consecutive; i++) {
2654     fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
2655             generate_test_buffer_full (dts_base + i * TEST_BUF_DURATION,
2656                 seqnum_base + i, rtpts_base + i * TEST_RTP_TS_DURATION)));
2657   }
2658 
2659   for (i = 0; i < num_consecutive; i++) {
2660     GstBuffer *buf = gst_harness_pull (h);
2661     guint expected_seqnum = seqnum_base + i;
2662     fail_unless_equals_int (expected_seqnum, get_rtp_seq_num (buf));
2663 
2664     expected_ts = dts_base + i * TEST_BUF_DURATION;
2665     fail_unless_equals_int (expected_ts, GST_BUFFER_PTS (buf));
2666     gst_buffer_unref (buf);
2667   }
2668 
2669   fail_unless_equals_int (0, gst_harness_events_in_queue (h));
2670 
2671   gst_harness_teardown (h);
2672 }
2673 
2674 GST_END_TEST;
2675 
GST_START_TEST(test_big_gap_arrival_time)2676 GST_START_TEST (test_big_gap_arrival_time)
2677 {
2678   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2679   const gint num_consecutive = 5;
2680   const guint gap = 20000;
2681   gint i;
2682   guint seqnum_org;
2683   GstClockTime dts_base;
2684   guint seqnum_base;
2685   guint32 rtpts_base;
2686   GstClockTime expected_ts;
2687 
2688   g_object_set (h->element, "do-lost", TRUE, "do-retransmission", TRUE, NULL);
2689   seqnum_org = construct_deterministic_initial_state (h, 100);
2690 
2691   /* packets are being held back on the wire, then continues */
2692   dts_base = (seqnum_org + gap) * TEST_BUF_DURATION;
2693   seqnum_base = seqnum_org;
2694   rtpts_base = seqnum_base * TEST_RTP_TS_DURATION;
2695 
2696   for (i = 0; i < num_consecutive; i++) {
2697     fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
2698             generate_test_buffer_full (dts_base + i * TEST_BUF_DURATION,
2699                 seqnum_base + i, rtpts_base + i * TEST_RTP_TS_DURATION)));
2700   }
2701 
2702   for (i = 0; i < num_consecutive; i++) {
2703     GstBuffer *buf = gst_harness_pull (h);
2704     guint expected_seqnum = seqnum_base + i;
2705     fail_unless_equals_int (expected_seqnum, get_rtp_seq_num (buf));
2706 
2707     expected_ts = dts_base + i * TEST_BUF_DURATION;
2708     fail_unless_equals_int (expected_ts, GST_BUFFER_PTS (buf));
2709     gst_buffer_unref (buf);
2710   }
2711 
2712   fail_unless_equals_int (0, gst_harness_events_in_queue (h));
2713 
2714   gst_harness_teardown (h);
2715 }
2716 
2717 GST_END_TEST;
2718 
2719 typedef struct
2720 {
2721   guint seqnum_offset;
2722   guint late_buffer;
2723 } TestLateArrivalInput;
2724 
2725 static const TestLateArrivalInput
2726     test_considered_lost_packet_in_large_gap_arrives_input[] = {
2727   {0, 1}, {0, 2}, {65535, 1}, {65535, 2}, {65534, 1}, {65534, 2}
2728 };
2729 
GST_START_TEST(test_considered_lost_packet_in_large_gap_arrives)2730 GST_START_TEST (test_considered_lost_packet_in_large_gap_arrives)
2731 {
2732   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2733   GstTestClock *testclock;
2734   GstBuffer *buffer;
2735   gint jb_latency_ms = 20;
2736   const TestLateArrivalInput *test_input =
2737       &test_considered_lost_packet_in_large_gap_arrives_input[__i__];
2738   guint seq_offset = test_input->seqnum_offset;
2739   guint late_buffer = test_input->late_buffer;
2740   gint i;
2741 
2742   gst_harness_set_src_caps (h, generate_caps ());
2743   testclock = gst_harness_get_testclock (h);
2744   g_object_set (h->element, "do-lost", TRUE, "latency", jb_latency_ms, NULL);
2745 
2746   /* first push buffer 0 */
2747   fail_unless_equals_int (GST_FLOW_OK,
2748       gst_harness_push (h, generate_test_buffer_full (0 * TEST_BUF_DURATION,
2749               0 + seq_offset, 0 * TEST_RTP_TS_DURATION)));
2750   fail_unless (gst_harness_crank_single_clock_wait (h));
2751   gst_buffer_unref (gst_harness_pull (h));
2752 
2753   /* drop GstEventStreamStart & GstEventCaps & GstEventSegment */
2754   for (i = 0; i < 3; i++)
2755     gst_event_unref (gst_harness_pull_event (h));
2756 
2757   /* hop over 3 packets, and push buffer 4 (gap of 3) */
2758   gst_harness_set_time (h, 4 * TEST_BUF_DURATION);
2759   fail_unless_equals_int (GST_FLOW_OK,
2760       gst_harness_push (h, generate_test_buffer_full (4 * TEST_BUF_DURATION,
2761               4 + seq_offset, 4 * TEST_RTP_TS_DURATION)));
2762 
2763   /* we get a "bundled" lost-event for the 2 packets now already too late */
2764   verify_lost_event (h, 1 + seq_offset, 1 * TEST_BUF_DURATION,
2765       2 * TEST_BUF_DURATION);
2766 
2767   /* and another one for buffer 3 */
2768   verify_lost_event (h, 3 + seq_offset, 3 * TEST_BUF_DURATION,
2769       1 * TEST_BUF_DURATION);
2770 
2771   /* A late buffer arrives */
2772   fail_unless_equals_int (GST_FLOW_OK,
2773       gst_harness_push (h,
2774           generate_test_buffer_full (late_buffer * TEST_BUF_DURATION,
2775               late_buffer + seq_offset, late_buffer * TEST_RTP_TS_DURATION)));
2776 
2777   /* buffer 4 is pushed as normal */
2778   buffer = gst_harness_pull (h);
2779   fail_unless_equals_int ((4 + seq_offset) & 0xffff, get_rtp_seq_num (buffer));
2780   gst_buffer_unref (buffer);
2781 
2782   /* we have lost 3, and one of them arrived eventually, but too late */
2783   fail_unless (verify_jb_stats (h->element,
2784           gst_structure_new ("application/x-rtp-jitterbuffer-stats",
2785               "num-pushed", G_TYPE_UINT64, (guint64) 2,
2786               "num-lost", G_TYPE_UINT64, (guint64) 3,
2787               "num-late", G_TYPE_UINT64, (guint64) 1, NULL)));
2788 
2789   gst_object_unref (testclock);
2790   gst_harness_teardown (h);
2791 }
2792 
2793 GST_END_TEST;
2794 
GST_START_TEST(test_performance)2795 GST_START_TEST (test_performance)
2796 {
2797   GstHarness *h =
2798       gst_harness_new_parse
2799       ("rtpjitterbuffer do-lost=1 do-retransmission=1 latency=1000");
2800   GTimer *timer = g_timer_new ();
2801   const gdouble test_duration = 2.0;
2802   guint buffers_pushed = 0;
2803   guint buffers_received;
2804 
2805   gst_harness_set_src_caps (h, generate_caps ());
2806   gst_harness_use_systemclock (h);
2807 
2808   while (g_timer_elapsed (timer, NULL) < test_duration) {
2809     /* Simulate 1ms packets */
2810     guint n = buffers_pushed * 2;       // every packet also produces a gap
2811     guint16 seqnum = n & 0xffff;
2812     guint32 rtp_ts = n * 8;
2813     GstClockTime dts = n * GST_MSECOND;
2814     gst_harness_push (h, generate_test_buffer_full (dts, seqnum, rtp_ts));
2815     buffers_pushed++;
2816     g_usleep (G_USEC_PER_SEC / 10000);
2817   }
2818   g_timer_destroy (timer);
2819 
2820   buffers_received = gst_harness_buffers_received (h);
2821   GST_INFO ("Pushed %d, received %d (%.1f%%)", buffers_pushed, buffers_received,
2822       100.0 * buffers_received / buffers_pushed);
2823 
2824   gst_harness_teardown (h);
2825 }
2826 
2827 GST_END_TEST;
2828 
GST_START_TEST(test_fill_queue)2829 GST_START_TEST (test_fill_queue)
2830 {
2831   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2832   const gint num_consecutive = 40000;
2833   GstBuffer *buf;
2834   gint i;
2835 
2836   gst_harness_use_testclock (h);
2837 
2838   gst_harness_set_src_caps (h, generate_caps ());
2839 
2840   gst_harness_play (h);
2841 
2842   gst_harness_push (h, generate_test_buffer (1000));
2843   /* Skip 1001 */
2844   for (i = 2; i < num_consecutive; i++)
2845     gst_harness_push (h, generate_test_buffer (1000 + i));
2846 
2847   buf = gst_harness_pull (h);
2848   fail_unless_equals_int (1000, get_rtp_seq_num (buf));
2849   gst_buffer_unref (buf);
2850   /* 1001 is skipped */
2851   for (i = 2; i < num_consecutive; i++) {
2852     GstBuffer *buf = gst_harness_pull (h);
2853     fail_unless_equals_int (1000 + i, get_rtp_seq_num (buf));
2854     gst_buffer_unref (buf);
2855   }
2856 
2857   gst_harness_teardown (h);
2858 }
2859 
2860 GST_END_TEST;
2861 
2862 typedef struct
2863 {
2864   gint64 dts_skew;
2865   gint16 seqnum_skew;
2866 } RtxSkewCtx;
2867 
2868 static const RtxSkewCtx rtx_does_not_affect_pts_calculation_input[] = {
2869   {0, 0},
2870   {20 * GST_MSECOND, -100},
2871   {20 * GST_MSECOND, 100},
2872   {-10 * GST_MSECOND, 1},
2873   {100 * GST_MSECOND, 0},
2874 };
2875 
GST_START_TEST(test_rtx_does_not_affect_pts_calculation)2876 GST_START_TEST (test_rtx_does_not_affect_pts_calculation)
2877 {
2878   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2879   GstBuffer *buffer;
2880   guint next_seqnum;
2881   guint rtx_seqnum;
2882   GstClockTime now;
2883   const RtxSkewCtx *ctx = &rtx_does_not_affect_pts_calculation_input[__i__];
2884 
2885   /* set up a deterministic state and take the time on the clock */
2886   g_object_set (h->element, "do-retransmission", TRUE, "do-lost", TRUE, NULL);
2887   next_seqnum = construct_deterministic_initial_state (h, 3000);
2888   now = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
2889 
2890   /* push in a "bad" RTX buffer, arriving at various times / seqnums */
2891   rtx_seqnum = next_seqnum + ctx->seqnum_skew;
2892   buffer = generate_test_buffer_full (now + ctx->dts_skew, rtx_seqnum,
2893       rtx_seqnum * TEST_RTP_TS_DURATION);
2894   GST_BUFFER_FLAG_SET (buffer, GST_RTP_BUFFER_FLAG_RETRANSMISSION);
2895   gst_harness_push (h, buffer);
2896 
2897   /* now push in the next regular buffer at its ideal time, and verify the
2898      rogue RTX-buffer did not mess things up */
2899   push_test_buffer (h, next_seqnum);
2900   now = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
2901   buffer = gst_harness_pull (h);
2902   fail_unless_equals_int64 (now, GST_BUFFER_PTS (buffer));
2903 
2904   gst_buffer_unref (buffer);
2905 
2906   gst_harness_teardown (h);
2907 }
2908 
2909 GST_END_TEST;
2910 
GST_START_TEST(test_dont_drop_packet_based_on_skew)2911 GST_START_TEST (test_dont_drop_packet_based_on_skew)
2912 {
2913   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2914   guint base_seqnum;
2915   GstClockTime now;
2916   guint i;
2917 
2918   /* set up a deterministic state and take the time on the clock */
2919   g_object_set (h->element, "do-retransmission", TRUE, "do-lost", TRUE, NULL);
2920   base_seqnum = construct_deterministic_initial_state (h, 20);
2921   now = gst_clock_get_time (GST_ELEMENT_CLOCK (h->element));
2922 
2923   /* and after a delay of 50ms... */
2924   now += GST_MSECOND * 50;
2925   gst_test_clock_set_time (GST_TEST_CLOCK (GST_ELEMENT_CLOCK (h->element)),
2926       now);
2927 
2928   /* ..two more buffers arrive in perfect order */
2929   for (i = 0; i < 2; i++) {
2930     gst_harness_push (h, generate_test_buffer_full (now + i * GST_MSECOND * 20,
2931             base_seqnum + i, (base_seqnum + i) * TEST_RTP_TS_DURATION));
2932   }
2933 
2934   /* verify we did not drop any of them */
2935   for (i = 0; i < 2; i++) {
2936     gst_buffer_unref (gst_harness_pull (h));
2937   }
2938 
2939   gst_harness_teardown (h);
2940 }
2941 
2942 GST_END_TEST;
2943 
2944 static gboolean
check_drop_message(GstMessage * drop_msg,const char * reason_check,guint seqnum_check,guint num_msg)2945 check_drop_message (GstMessage * drop_msg, const char *reason_check,
2946     guint seqnum_check, guint num_msg)
2947 {
2948 
2949   const GstStructure *s = gst_message_get_structure (drop_msg);
2950   const gchar *reason_str;
2951   GstClockTime timestamp;
2952   guint seqnum;
2953   guint num_too_late;
2954   guint num_drop_on_latency;
2955 
2956   guint num_too_late_check = 0;
2957   guint num_drop_on_latency_check = 0;
2958 
2959   /* Check that fields exist */
2960   fail_unless (gst_structure_get_uint (s, "seqnum", &seqnum));
2961   fail_unless (gst_structure_get_uint64 (s, "timestamp", &timestamp));
2962   fail_unless (gst_structure_get_uint (s, "num-too-late", &num_too_late));
2963   fail_unless (gst_structure_get_uint (s, "num-drop-on-latency",
2964           &num_drop_on_latency));
2965   fail_unless (reason_str = gst_structure_get_string (s, "reason"));
2966 
2967   /* Assing what to compare message fields to based on message reason */
2968   if (g_strcmp0 (reason_check, "too-late") == 0) {
2969     num_too_late_check += num_msg;
2970   } else if (g_strcmp0 (reason_check, "drop-on-latency") == 0) {
2971     num_drop_on_latency_check += num_msg;
2972   } else {
2973     return FALSE;
2974   }
2975 
2976   /* Check that fields have correct value */
2977   fail_unless (seqnum == seqnum_check);
2978   fail_unless (g_strcmp0 (reason_str, reason_check) == 0);
2979   fail_unless (num_too_late == num_too_late_check);
2980   fail_unless (num_drop_on_latency == num_drop_on_latency_check);
2981 
2982   return TRUE;
2983 }
2984 
GST_START_TEST(test_drop_messages_too_late)2985 GST_START_TEST (test_drop_messages_too_late)
2986 {
2987   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
2988   gint latency_ms = 100;
2989   guint next_seqnum;
2990   GstBus *bus;
2991   GstMessage *drop_msg;
2992   gboolean have_message = FALSE;
2993 
2994   g_object_set (h->element, "post-drop-messages", TRUE, NULL);
2995   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
2996 
2997   /* Create a bus to get the drop message on */
2998   bus = gst_bus_new ();
2999   gst_element_set_bus (h->element, bus);
3000 
3001   /* Push test buffer resulting in gap of one */
3002   push_test_buffer (h, next_seqnum + 1);
3003 
3004   /* Advance time to trigger timeout of the missing buffer */
3005   gst_harness_crank_single_clock_wait (h);
3006 
3007   /* Pull out and unref pushed buffer */
3008   gst_buffer_unref (gst_harness_pull (h));
3009 
3010   /* Push missing buffer, now arriving "too-late" */
3011   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
3012           generate_test_buffer (next_seqnum)));
3013 
3014   /* Pop the resulting drop message and check its correctness */
3015   while (!have_message &&
3016       (drop_msg = gst_bus_pop_filtered (bus, GST_MESSAGE_ELEMENT)) != NULL) {
3017     if (gst_message_has_name (drop_msg, "drop-msg")) {
3018       fail_unless (check_drop_message (drop_msg, "too-late", next_seqnum, 1));
3019       have_message = TRUE;
3020     }
3021     gst_message_unref (drop_msg);
3022   }
3023   fail_unless (have_message);
3024 
3025   /* Cleanup */
3026   gst_element_set_bus (h->element, NULL);
3027   gst_object_unref (bus);
3028   gst_harness_teardown (h);
3029 }
3030 
3031 GST_END_TEST;
3032 
GST_START_TEST(test_drop_messages_drop_on_latency)3033 GST_START_TEST (test_drop_messages_drop_on_latency)
3034 {
3035   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
3036   gint latency_ms = 20;
3037   guint next_seqnum;
3038   guint first_seqnum;
3039   guint final_seqnum;
3040   GstBus *bus;
3041   GstMessage *drop_msg;
3042   gboolean have_message = FALSE;
3043 
3044   g_object_set (h->element, "post-drop-messages", TRUE, NULL);
3045   g_object_set (h->element, "drop-on-latency", TRUE, NULL);
3046   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
3047 
3048   /* Create a bus to get the drop message on */
3049   bus = gst_bus_new ();
3050   gst_element_set_bus (h->element, bus);
3051 
3052   /* Push 3 buffers in correct seqnum order with initial gap of 1, with the buffers
3053    * arriving simultaneously in harness time. First buffer will wait for gap buffer,
3054    * and the third arriving buffer will trigger the first to be dropped due to
3055    * drop-on-latency.
3056    */
3057   first_seqnum = ++next_seqnum;
3058   final_seqnum = next_seqnum + 2;
3059   for (; next_seqnum <= final_seqnum; next_seqnum++) {
3060     fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
3061             generate_test_buffer_full (next_seqnum * TEST_BUF_DURATION,
3062                 next_seqnum, next_seqnum * TEST_RTP_TS_DURATION)));
3063   }
3064 
3065   /* Pop the resulting drop message and check its correctness */
3066   while (!have_message &&
3067       (drop_msg = gst_bus_pop_filtered (bus, GST_MESSAGE_ELEMENT)) != NULL) {
3068     if (gst_message_has_name (drop_msg, "drop-msg")) {
3069       fail_unless (check_drop_message (drop_msg, "drop-on-latency",
3070               first_seqnum, 1));
3071       have_message = TRUE;
3072     }
3073     gst_message_unref (drop_msg);
3074   }
3075   fail_unless (have_message);
3076 
3077   /* Cleanup */
3078   gst_element_set_bus (h->element, NULL);
3079   gst_object_unref (bus);
3080   gst_buffer_unref (gst_harness_take_all_data_as_buffer (h));
3081   gst_harness_teardown (h);
3082 }
3083 
3084 GST_END_TEST;
3085 
GST_START_TEST(test_drop_messages_interval)3086 GST_START_TEST (test_drop_messages_interval)
3087 {
3088   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
3089   guint latency_ms = 100;
3090   GstClockTime interval = 10;
3091   guint next_seqnum;
3092   guint final_seqnum;
3093   GstBus *bus;
3094   GstMessage *drop_msg;
3095   GstClockTime now;
3096   guint num_late_not_sent = 0;
3097   guint num_sent_msg = 0;
3098 
3099   g_object_set (h->element, "post-drop-messages", TRUE, NULL);
3100   g_object_set (h->element, "drop-messages-interval", interval, NULL);
3101   next_seqnum = construct_deterministic_initial_state (h, latency_ms);
3102 
3103   /* Create a bus to get the drop message on */
3104   bus = gst_bus_new ();
3105   gst_element_set_bus (h->element, bus);
3106 
3107   /* Jump 1 second forward in time */
3108   now = 1 * GST_SECOND;
3109   gst_harness_set_time (h, now);
3110 
3111   /* Push a packet with a gap of 3, that now is very late */
3112   final_seqnum = next_seqnum + 3;
3113 
3114   fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
3115           generate_test_buffer_full (now,
3116               final_seqnum, final_seqnum * TEST_RTP_TS_DURATION)));
3117 
3118   /* Pull and unref pushed buffer */
3119   gst_buffer_unref (gst_harness_pull (h));
3120 
3121   /* The 3 missing packets are now pushed with half the message "interval" between them.
3122    * When arriving they are considered as "too-late". Only the first and third should trigger
3123    * a drop_msg, as the second is dropped during the interval where no new messages will be sent.
3124    * The second should have num-too-late=2, as the "too-late" event that never sent a message
3125    * still increments the count of dropped "too-late" buffers.
3126    */
3127   for (; next_seqnum < final_seqnum; next_seqnum++) {
3128     fail_unless_equals_int (GST_FLOW_OK, gst_harness_push (h,
3129             generate_test_buffer (next_seqnum)));
3130     num_late_not_sent++;
3131 
3132     /* Pop a potential drop message and check its correctness */
3133     while ((drop_msg = gst_bus_pop (bus)) != NULL) {
3134       if (gst_message_has_name (drop_msg, "drop-msg")) {
3135         fail_unless (check_drop_message (drop_msg, "too-late", next_seqnum,
3136                 num_late_not_sent));
3137 
3138         num_late_not_sent = 0;
3139         num_sent_msg++;
3140       }
3141       gst_message_unref (drop_msg);
3142     }
3143     /* Advance time half the minimum interval of sending drop messages */
3144     now += (interval * GST_MSECOND) / 2;
3145     gst_harness_set_time (h, now);
3146   }
3147   /* Exactly two drop messages should have been sent */
3148   fail_unless (num_sent_msg == 2);
3149 
3150   /* Cleanup */
3151   gst_element_set_bus (h->element, NULL);
3152   gst_object_unref (bus);
3153   gst_harness_teardown (h);
3154 }
3155 
3156 GST_END_TEST;
3157 
3158 typedef struct
3159 {
3160   gint seqnum_d;
3161   gint rtptime_d;
3162   gboolean rtx;
3163   gint sleep_us;
3164 } BufferArrayCtx;
3165 
3166 static void
buffer_array_push(GstHarness * h,GArray * array,guint16 seqnum_base,guint32 rtptime_base)3167 buffer_array_push (GstHarness * h, GArray * array,
3168     guint16 seqnum_base, guint32 rtptime_base)
3169 {
3170   guint16 seqnum = seqnum_base;
3171   guint32 rtptime = rtptime_base;
3172   guint i;
3173 
3174   for (i = 0; i < array->len; i++) {
3175     BufferArrayCtx *ctx = &g_array_index (array, BufferArrayCtx, i);
3176     seqnum += ctx->seqnum_d;
3177     rtptime += ctx->rtptime_d;
3178     push_test_buffer_now (h, seqnum, rtptime, ctx->rtx);
3179     g_usleep (ctx->sleep_us);
3180   }
3181 }
3182 
3183 static gint
buffer_array_get_max_seqnum_delta(GArray * array)3184 buffer_array_get_max_seqnum_delta (GArray * array)
3185 {
3186   gint delta = 0;
3187   gint max_delta = 0;
3188   guint i;
3189 
3190   for (i = 0; i < array->len; i++) {
3191     BufferArrayCtx *ctx = &g_array_index (array, BufferArrayCtx, i);
3192     delta += ctx->seqnum_d;
3193     if (delta > max_delta)
3194       max_delta = delta;
3195   }
3196   return max_delta;
3197 }
3198 
3199 static void
buffer_array_append_sequential(GArray * array,guint num_bufs)3200 buffer_array_append_sequential (GArray * array, guint num_bufs)
3201 {
3202   guint i;
3203   for (i = 0; i < num_bufs; i++) {
3204     BufferArrayCtx ctx;
3205     ctx.seqnum_d = 1;
3206     ctx.rtptime_d = TEST_RTP_TS_DURATION;       /* 20ms for 8KHz */
3207     ctx.rtx = FALSE;
3208     ctx.sleep_us = G_USEC_PER_SEC / 1000 * 20;  /* 20ms */
3209     g_array_append_val (array, ctx);
3210   }
3211 }
3212 
3213 static void
buffer_array_append_ctx(GArray * array,BufferArrayCtx * bufs,guint num_bufs)3214 buffer_array_append_ctx (GArray * array, BufferArrayCtx * bufs, guint num_bufs)
3215 {
3216   guint i;
3217   for (i = 0; i < num_bufs; i++) {
3218     g_array_append_val (array, bufs[i]);
3219   }
3220 }
3221 
3222 static gboolean
check_for_stall(GstHarness * h,BufferArrayCtx * bufs,guint num_bufs)3223 check_for_stall (GstHarness * h, BufferArrayCtx * bufs, guint num_bufs)
3224 {
3225   guint latency_ms;
3226   guint initial_bufs;
3227   guint16 base_seqnum = 10000;
3228   guint32 base_rtptime = base_seqnum * TEST_RTP_TS_DURATION;
3229   guint16 max_seqnum;
3230   guint in_queue;
3231   GArray *array;
3232 
3233   gst_harness_use_systemclock (h);
3234   gst_element_set_base_time (h->element,
3235       gst_clock_get_time (GST_ELEMENT_CLOCK (h->element)));
3236   gst_harness_set_src_caps (h, generate_caps ());
3237 
3238   g_object_get (h->element, "latency", &latency_ms, NULL);
3239   initial_bufs = latency_ms / TEST_BUF_MS;
3240 
3241   array = g_array_new (FALSE, FALSE, sizeof (BufferArrayCtx));
3242   buffer_array_append_sequential (array, initial_bufs);
3243   buffer_array_append_ctx (array, bufs, num_bufs);
3244   max_seqnum = base_seqnum + buffer_array_get_max_seqnum_delta (array);
3245   buffer_array_push (h, array, base_seqnum, base_rtptime);
3246   g_array_set_size (array, 0);
3247 
3248   /* sleep a bit to settle things down, then find out
3249      how many buffers have been pushed out */
3250   g_usleep (G_USEC_PER_SEC);
3251   in_queue = gst_harness_buffers_in_queue (h);
3252 
3253   /* push another 50 buffers normally */
3254   buffer_array_append_sequential (array, 50);
3255   base_seqnum = max_seqnum + 1;
3256   base_rtptime = base_seqnum * TEST_RTP_TS_DURATION;
3257   buffer_array_push (h, array, base_seqnum, base_rtptime);
3258   g_array_unref (array);
3259 
3260   {
3261     gint64 start_time = g_get_monotonic_time ();
3262     gint64 timeout_s = 30;
3263     while (gst_harness_buffers_in_queue (h) <= in_queue) {
3264 
3265       gint64 duration_s =
3266           (g_get_monotonic_time () - start_time) / G_USEC_PER_SEC;
3267       if (duration_s > timeout_s)
3268         break;
3269 
3270       g_usleep (G_USEC_PER_SEC / 100);
3271     }
3272   }
3273 
3274 
3275   /* we expect at least some of those buffers to come through */
3276   return gst_harness_buffers_in_queue (h) > in_queue;
3277 }
3278 
GST_START_TEST(test_reset_timers_does_not_stall)3279 GST_START_TEST (test_reset_timers_does_not_stall)
3280 {
3281   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
3282   BufferArrayCtx bufs[] = {
3283     /* *INDENT-OFF* */
3284     { 1, 0, FALSE, 0},
3285     { 2, 0, FALSE, 0},
3286     { 3, 0, FALSE, 0},
3287     { 4, 0, FALSE, 0},
3288     { 5, 0, FALSE, 0},
3289     { 6, 0, FALSE, 0},
3290     { 7, 0, FALSE, 0},
3291     { 8, 0, FALSE, 0},
3292     { 9, 0, FALSE, 0},
3293     {10, 0, FALSE, 0},
3294     /* *INDENT-ON* */
3295   };
3296 
3297   g_object_set (h->element, "latency", 100,
3298       "do-retransmission", TRUE, "do-lost", TRUE, NULL);
3299   g_object_set (h->element, "max-dropout-time", 10, NULL);
3300   fail_unless (check_for_stall (h, bufs, G_N_ELEMENTS (bufs)));
3301   gst_harness_teardown (h);
3302 }
3303 
3304 GST_END_TEST;
3305 
GST_START_TEST(test_multiple_lost_do_not_stall)3306 GST_START_TEST (test_multiple_lost_do_not_stall)
3307 {
3308   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
3309   BufferArrayCtx bufs[] = {
3310     /* *INDENT-OFF* */
3311     { 39,  4960, FALSE,   58},
3312     {-28, -5280, FALSE, 1000},
3313     /* *INDENT-ON* */
3314   };
3315 
3316   g_object_set (h->element, "latency", 200,
3317       "do-retransmission", TRUE, "do-lost", TRUE, NULL);
3318   fail_unless (check_for_stall (h, bufs, G_N_ELEMENTS (bufs)));
3319   gst_harness_teardown (h);
3320 }
3321 
3322 GST_END_TEST;
3323 
GST_START_TEST(test_reset_using_rtx_packets_does_not_stall)3324 GST_START_TEST (test_reset_using_rtx_packets_does_not_stall)
3325 {
3326   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
3327   BufferArrayCtx bufs[] = {
3328     /* *INDENT-OFF* */
3329     {  1,    1 * TEST_RTP_TS_DURATION, FALSE, 2000000},
3330     {  62,  62 * TEST_RTP_TS_DURATION, FALSE, 0},
3331     { -13, -13 * TEST_RTP_TS_DURATION, TRUE, 10000},
3332     {   1,   1 * TEST_RTP_TS_DURATION, TRUE, 0},
3333     {   1,   1 * TEST_RTP_TS_DURATION, TRUE, 0},
3334     {   1,   1 * TEST_RTP_TS_DURATION, TRUE, 0},
3335     {   1,   1 * TEST_RTP_TS_DURATION, TRUE, 0},
3336     {   1,   1 * TEST_RTP_TS_DURATION, TRUE, 0},
3337     /* *INDENT-ON* */
3338   };
3339 
3340   g_object_set (h->element, "latency", 400,
3341       "do-retransmission", TRUE, "do-lost", TRUE, "max-misorder-time", 1, NULL);
3342   fail_unless (check_for_stall (h, bufs, G_N_ELEMENTS (bufs)));
3343   gst_harness_teardown (h);
3344 }
3345 
3346 GST_END_TEST;
3347 
GST_START_TEST(test_gap_using_rtx_does_not_stall)3348 GST_START_TEST (test_gap_using_rtx_does_not_stall)
3349 {
3350   GstHarness *h = gst_harness_new ("rtpjitterbuffer");
3351 
3352   BufferArrayCtx bufs[] = {
3353     /* *INDENT-OFF* */
3354     { 201, -1440, FALSE, 185591 },
3355     { 265,     1, FALSE,      0 },
3356     /* *INDENT-ON* */
3357   };
3358 
3359   g_object_set (h->element, "do-lost", TRUE,
3360       "do-retransmission", TRUE,
3361       "rtx-next-seqnum", FALSE, "rtx-delay-reorder", 0, NULL);
3362 
3363   fail_unless (check_for_stall (h, bufs, G_N_ELEMENTS (bufs)));
3364   gst_harness_teardown (h);
3365 }
3366 
3367 GST_END_TEST;
3368 
3369 static Suite *
rtpjitterbuffer_suite(void)3370 rtpjitterbuffer_suite (void)
3371 {
3372   Suite *s = suite_create ("rtpjitterbuffer");
3373   TCase *tc_chain = tcase_create ("general");
3374 
3375   suite_add_tcase (s, tc_chain);
3376 
3377   tcase_add_test (tc_chain, test_push_forward_seq);
3378   tcase_add_test (tc_chain, test_push_backward_seq);
3379   tcase_add_test (tc_chain, test_push_unordered);
3380   tcase_add_test (tc_chain, test_push_eos);
3381   tcase_add_test (tc_chain, test_basetime);
3382   tcase_add_test (tc_chain, test_clear_pt_map);
3383 
3384   tcase_add_test (tc_chain, test_lost_event);
3385   tcase_add_test (tc_chain, test_only_one_lost_event_on_large_gaps);
3386   tcase_add_test (tc_chain, test_two_lost_one_arrives_in_time);
3387   tcase_add_test (tc_chain, test_late_packets_still_makes_lost_events);
3388   tcase_add_test (tc_chain, test_lost_event_uses_pts);
3389   tcase_add_test (tc_chain, test_lost_event_with_backwards_rtptime);
3390 
3391   tcase_add_test (tc_chain, test_all_packets_are_timestamped_zero);
3392   tcase_add_loop_test (tc_chain, test_num_late_when_considered_lost_arrives, 0,
3393       2);
3394   tcase_add_test (tc_chain, test_reorder_of_non_equidistant_packets);
3395   tcase_add_test (tc_chain,
3396       test_loss_equidistant_spacing_with_parameter_packets);
3397   tcase_add_loop_test (tc_chain, test_no_fractional_lost_event_durations, 0,
3398       G_N_ELEMENTS (no_fractional_lost_event_durations_input));
3399   tcase_add_test (tc_chain, test_late_lost_with_same_pts);
3400 
3401   tcase_add_test (tc_chain, test_rtx_expected_next);
3402   tcase_add_test (tc_chain, test_rtx_not_bursting_requests);
3403 
3404   tcase_add_test (tc_chain, test_rtx_next_seqnum_disabled);
3405   tcase_add_test (tc_chain, test_rtx_two_missing);
3406   tcase_add_test (tc_chain, test_rtx_buffer_arrives_just_in_time);
3407   tcase_add_test (tc_chain, test_rtx_buffer_arrives_too_late);
3408   tcase_add_test (tc_chain, test_rtx_original_buffer_does_not_update_rtx_stats);
3409   tcase_add_test (tc_chain, test_rtx_duplicate_packet_updates_rtx_stats);
3410   tcase_add_test (tc_chain,
3411       test_rtx_buffer_arrives_after_lost_updates_rtx_stats);
3412   tcase_add_test (tc_chain, test_rtx_rtt_larger_than_retry_timeout);
3413   tcase_add_test (tc_chain, test_rtx_no_request_if_time_past_retry_period);
3414   tcase_add_test (tc_chain, test_rtx_same_delay_and_retry_timeout);
3415   tcase_add_test (tc_chain, test_rtx_with_backwards_rtptime);
3416   tcase_add_test (tc_chain, test_rtx_timer_reuse);
3417   tcase_add_test (tc_chain, test_rtx_large_packet_spacing_and_small_rtt);
3418   tcase_add_test (tc_chain, test_rtx_large_packet_spacing_and_large_rtt);
3419   tcase_add_test (tc_chain,
3420       test_rtx_large_packet_spacing_does_not_reset_jitterbuffer);
3421   tcase_add_test (tc_chain, test_minor_reorder_does_not_skew);
3422   tcase_add_loop_test (tc_chain, test_rtx_does_not_affect_pts_calculation, 0,
3423       G_N_ELEMENTS (rtx_does_not_affect_pts_calculation_input));
3424   tcase_add_test (tc_chain, test_dont_drop_packet_based_on_skew);
3425 
3426   tcase_add_test (tc_chain, test_deadline_ts_offset);
3427   tcase_add_test (tc_chain, test_big_gap_seqnum);
3428   tcase_add_test (tc_chain, test_big_gap_arrival_time);
3429   tcase_add_test (tc_chain, test_fill_queue);
3430 
3431   tcase_add_loop_test (tc_chain,
3432       test_considered_lost_packet_in_large_gap_arrives, 0,
3433       G_N_ELEMENTS (test_considered_lost_packet_in_large_gap_arrives_input));
3434 
3435   tcase_add_test (tc_chain, test_performance);
3436 
3437   tcase_add_test (tc_chain, test_drop_messages_too_late);
3438   tcase_add_test (tc_chain, test_drop_messages_drop_on_latency);
3439   tcase_add_test (tc_chain, test_drop_messages_interval);
3440 
3441   tcase_add_test (tc_chain, test_reset_timers_does_not_stall);
3442   tcase_add_test (tc_chain, test_multiple_lost_do_not_stall);
3443   tcase_add_test (tc_chain, test_reset_using_rtx_packets_does_not_stall);
3444   tcase_add_test (tc_chain, test_gap_using_rtx_does_not_stall);
3445 
3446 
3447   return s;
3448 }
3449 
3450 GST_CHECK_MAIN (rtpjitterbuffer);
3451