[MOVED FROM GST-P-FARSIGHT] liveadder : Handle jitter in incoming buffers
authorEdward Hervey <bilboed@bilboed.com>
Wed, 27 Aug 2008 15:16:27 +0000 (17:16 +0200)
committerEdward Hervey <bilboed@bilboed.com>
Tue, 17 Feb 2009 18:29:06 +0000 (19:29 +0100)
Incoming buffers (especially those from an RTP connection) might have slight timestamp jitter. This is normally handled by audiosink (accepting up to 500ms of jitter).
Here we accept a maximum jitter of 10ms. If a buffer is within 10ms of the expected time, we correct its timestamp.

gst/liveadder/liveadder.c

index dd6ffe7..637dbae 100644 (file)
@@ -897,11 +897,16 @@ gst_live_live_adder_chain (GstPad *pad, GstBuffer *buffer)
   GstFlowReturn ret = GST_FLOW_OK;
   GList *item = NULL;
   GstClockTime skip = 0;
+  gint64 drift = 0; /* Positive if new buffer after old buffer */
 
   GST_OBJECT_LOCK (adder);
 
   ret = adder->srcresult;
 
+  GST_DEBUG ("Incoming buffer time:%"GST_TIME_FORMAT" duration:%"GST_TIME_FORMAT,
+            GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)),
+            GST_TIME_ARGS(GST_BUFFER_DURATION(buffer)));
+
   if (ret != GST_FLOW_OK)
   {
     GST_DEBUG_OBJECT (adder, "Passing non-ok result from src: %s",
@@ -942,17 +947,28 @@ gst_live_live_adder_chain (GstPad *pad, GstBuffer *buffer)
   if (padprivate->segment.format != GST_FORMAT_TIME)
     goto invalid_segment;
 
+  buffer = gst_buffer_make_metadata_writable (buffer);
+
+  drift = GST_BUFFER_TIMESTAMP (buffer) - padprivate->expected_timestamp;
+
   /* Just see if we receive invalid timestamp/durations */
   if (GST_CLOCK_TIME_IS_VALID (padprivate->expected_timestamp) &&
       !GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT) &&
-      GST_BUFFER_TIMESTAMP(buffer) != padprivate->expected_timestamp)
+      (drift != 0)) {
     GST_LOG_OBJECT (adder,
         "Timestamp discontinuity without the DISCONT flag set"
-        " (expected %" GST_TIME_FORMAT ", got %" GST_TIME_FORMAT")",
+        " (expected %" GST_TIME_FORMAT ", got %" GST_TIME_FORMAT" drift:%ldms)",
         GST_TIME_ARGS (padprivate->expected_timestamp),
-        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
+                   GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
+                   drift / GST_MSECOND);
+
+    /* We accept drifts of 10ms*/
+    if (ABS(drift) < (10 * GST_MSECOND)) {
+      GST_DEBUG ("Correcting minor drift");
+      GST_BUFFER_TIMESTAMP (buffer) = padprivate->expected_timestamp;
+    }
+  }
 
-  buffer = gst_buffer_make_metadata_writable (buffer);
 
   /* If there is no duration, lets set one */
   if (!GST_BUFFER_DURATION_IS_VALID (buffer)) {
@@ -976,8 +992,10 @@ gst_live_live_adder_chain (GstPad *pad, GstBuffer *buffer)
       adder->bps);
 
   /* buffer can be NULL if it's completely outside of the segment */
-  if (!buffer)
+  if (!buffer) {
+    GST_DEBUG ("Buffer completely outside of configured segment, dropping it");
     goto out;
+  }
 
   /*
    * Make sure all incoming buffers share the same timestamping
@@ -1297,6 +1315,10 @@ gst_live_adder_loop (gpointer data)
   if (newseg_event)
     gst_pad_push_event (adder->srcpad, newseg_event);
 
+  GST_DEBUG ("About to push buffer time:%"GST_TIME_FORMAT" duration:%"GST_TIME_FORMAT,
+            GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buffer)),
+            GST_TIME_ARGS(GST_BUFFER_DURATION(buffer)));
+
   result = gst_pad_push (adder->srcpad, buffer);
   if (result != GST_FLOW_OK)
     goto pause;