rtpjitterbuffer: increment accepted packets after loss
authorWim Taymans <wtaymans@redhat.com>
Fri, 9 May 2014 16:01:28 +0000 (18:01 +0200)
committerWim Taymans <wtaymans@redhat.com>
Fri, 9 May 2014 16:10:32 +0000 (18:10 +0200)
When we detect a lost packet, expect packets with higher
seqnum on the input.

Also update the unit test.

Fixes https://bugzilla.gnome.org/show_bug.cgi?id=729524

gst/rtpmanager/gstrtpjitterbuffer.c
tests/check/elements/rtpjitterbuffer.c

index 97fea62..9e45492 100644 (file)
@@ -2758,7 +2758,7 @@ do_lost_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
 {
   GstRtpJitterBufferPrivate *priv = jitterbuffer->priv;
   GstClockTime duration, timestamp;
-  guint seqnum, lost_packets, num_rtx_retry;
+  guint seqnum, lost_packets, num_rtx_retry, next_in_seqnum;
   gboolean late, head;
   GstEvent *event;
   RTPJitterBufferItem *item;
@@ -2782,6 +2782,12 @@ do_lost_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
   priv->num_late += lost_packets;
   priv->num_rtx_failed += num_rtx_retry;
 
+  next_in_seqnum = (seqnum + lost_packets) & 0xffff;
+
+  /* we now only accept seqnum bigger than this */
+  if (gst_rtp_buffer_compare_seqnum (priv->next_in_seqnum, next_in_seqnum) > 0)
+    priv->next_in_seqnum = next_in_seqnum;
+
   /* create paket lost event */
   event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
       gst_structure_new ("GstRTPPacketLost",
index be5c146..31999ef 100644 (file)
@@ -1409,6 +1409,7 @@ GST_START_TEST (test_gap_exceeds_latency)
   guint32 last_rtp = 0;
   const GstStructure *s = NULL;
   guint32 seqnum = 0;
+  gint i;
 
   setup_testharness (&data);
   g_object_set (data.jitter_buffer, "do-retransmission", TRUE, NULL);
@@ -1506,8 +1507,61 @@ GST_START_TEST (test_gap_exceeds_latency)
   in_buf = generate_test_buffer (last_ts * GST_MSECOND, TRUE, 15, last_rtp);
   g_assert_cmpint (gst_pad_push (data.test_src_pad, in_buf), ==, GST_FLOW_OK);
 
-  /* Wait for data to be pushed, it won't be at this time due to an off by one error. */
-  out_buf = g_async_queue_pop (data.buf_queue);
+  /* Wait for data to be pushed. */
+  while (g_async_queue_length (data.buf_queue) < 1) {
+    if (gst_test_clock_peek_next_pending_id (GST_TEST_CLOCK (data.clock), &id)) {
+      GstClockTime t = gst_clock_id_get_time (id);
+      if (t > gst_clock_get_time (data.clock)) {
+        gst_test_clock_set_time (GST_TEST_CLOCK (data.clock), t);
+      }
+      tid = gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (data.clock));
+      gst_clock_id_unref (id);
+      gst_clock_id_unref (tid);
+    }
+  }
+
+  out_event = g_async_queue_pop (data.sink_event_queue);
+  s = gst_event_get_structure (out_event);
+  g_assert (gst_structure_get_uint (s, "seqnum", &seqnum));
+  g_assert_cmpint (seqnum, ==, 3);
+  gst_event_unref (out_event);
+
+  out_event = g_async_queue_pop (data.sink_event_queue);
+  s = gst_event_get_structure (out_event);
+  g_assert (gst_structure_get_uint (s, "seqnum", &seqnum));
+  g_assert_cmpint (seqnum, ==, 7);
+  gst_event_unref (out_event);
+
+  /* 8 */
+  for (i = 8; i <= 16; i++) {
+    out_buf = g_async_queue_pop (data.buf_queue);
+    GST_DEBUG ("pop %d", i);
+    gst_buffer_unref (out_buf);
+  }
+
+  do {
+    out_event = g_async_queue_try_pop (data.sink_event_queue);
+    if (!out_event) {
+      if (gst_test_clock_peek_next_pending_id (GST_TEST_CLOCK (data.clock),
+              &id)) {
+
+        GstClockTime t = gst_clock_id_get_time (id);
+        if (t > gst_clock_get_time (data.clock)) {
+          gst_test_clock_set_time (GST_TEST_CLOCK (data.clock), t);
+        }
+        tid =
+            gst_test_clock_process_next_clock_id (GST_TEST_CLOCK (data.clock));
+        gst_clock_id_unref (id);
+        gst_clock_id_unref (tid);
+      }
+    }
+  } while (!out_event);
+
+  /* and lost of 17 */
+  s = gst_event_get_structure (out_event);
+  g_assert (gst_structure_get_uint (s, "seqnum", &seqnum));
+  g_assert_cmpint (seqnum, ==, 17);
+  gst_event_unref (out_event);
 
   destroy_testharness (&data);
 }