audioencoder: also adjust sample count upon discont to avoid ts overflow
authorMark Nauwelaerts <mnauw@users.sourceforge.net>
Tue, 8 Aug 2017 18:35:25 +0000 (20:35 +0200)
committerMark Nauwelaerts <mnauw@users.sourceforge.net>
Wed, 9 Aug 2017 07:32:55 +0000 (09:32 +0200)
Only adjusting the base_ts might lead to a negative ts and as such integer
overflow into a huge timestamp which then propagates into the granulepos
and so on.  Instead, resync to incoming buffer timestamp using both base_ts
and sample count rather than only base_ts.

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

gst-libs/gst/audio/gstaudioencoder.c

index 5c3b97bae2c0e6c562469c75eb37fd9ed700b7b4..182d6a549649d4e44eb239766a80b930889840eb 100644 (file)
@@ -1325,7 +1325,18 @@ gst_audio_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
     }
     if (discont) {
       /* now re-sync ts */
-      priv->base_ts += diff;
+      GstClockTime shift =
+          gst_util_uint64_scale (gst_adapter_available (priv->adapter),
+          GST_SECOND, ctx->info.rate * ctx->info.bpf);
+
+      if (G_UNLIKELY (shift > GST_BUFFER_TIMESTAMP (buffer))) {
+        /* ERROR */
+        goto wrong_time;
+      }
+      /* arrange for newly added samples to come out with the ts
+       * of the incoming buffer that adds these */
+      priv->base_ts = GST_BUFFER_TIMESTAMP (buffer) - shift;
+      priv->samples = 0;
       gst_audio_encoder_set_base_gp (enc);
       priv->discont |= discont;
     }
@@ -1362,6 +1373,14 @@ wrong_buffer:
     ret = GST_FLOW_ERROR;
     goto done;
   }
+wrong_time:
+  {
+    GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
+        ("buffer going too far back in time"));
+    gst_buffer_unref (buffer);
+    ret = GST_FLOW_ERROR;
+    goto done;
+  }
 }
 
 static gboolean