audioaggregator: Don't overwrite already written samples
authorOlivier Crête <olivier.crete@collabora.com>
Thu, 27 May 2021 20:05:04 +0000 (16:05 -0400)
committerOlivier Crête <olivier.crete@collabora.com>
Thu, 27 May 2021 20:33:00 +0000 (16:33 -0400)
On re-sync, don't forget what has already been written. Instead, just
drop any samples that overlap with parts that were already filled.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1180>

gst-libs/gst/audio/gstaudioaggregator.c

index 44fc7c6..22a22d4 100644 (file)
@@ -1674,13 +1674,12 @@ gst_audio_aggregator_fill_buffer (GstAudioAggregator * aagg,
       GST_DEBUG_OBJECT (pad, "Have discont. Expected %"
           G_GUINT64_FORMAT ", got %" G_GUINT64_FORMAT,
           pad->priv->next_offset, start_offset);
-    pad->priv->output_offset = -1;
     pad->priv->next_offset = end_offset;
   } else {
     pad->priv->next_offset += pad->priv->size;
   }
 
-  if (pad->priv->output_offset == -1) {
+  if (pad->priv->output_offset == -1 || discont) {
     GstClockTime start_running_time;
     GstClockTime end_running_time;
     GstClockTime segment_pos;
@@ -1716,7 +1715,6 @@ gst_audio_aggregator_fill_buffer (GstAudioAggregator * aagg,
       /* Outside output segment, drop */
       pad->priv->position = 0;
       pad->priv->size = 0;
-      pad->priv->output_offset = -1;
       GST_DEBUG_OBJECT (pad, "Buffer outside output segment");
       return FALSE;
     }
@@ -1728,14 +1726,16 @@ gst_audio_aggregator_fill_buffer (GstAudioAggregator * aagg,
     if (end_output_offset < aagg->priv->offset) {
       pad->priv->position = 0;
       pad->priv->size = 0;
-      pad->priv->output_offset = -1;
       GST_DEBUG_OBJECT (pad,
           "Buffer before segment or current position: %" G_GUINT64_FORMAT " < %"
           G_GINT64_FORMAT, end_output_offset, aagg->priv->offset);
       return FALSE;
     }
 
-    if (start_output_offset == -1 || start_output_offset < aagg->priv->offset) {
+    if (start_output_offset == -1 ||
+        start_output_offset < aagg->priv->offset ||
+        (pad->priv->output_offset != -1 &&
+            start_output_offset < pad->priv->output_offset)) {
       guint diff;
 
       if (start_output_offset == -1 && end_output_offset < pad->priv->size) {
@@ -1747,6 +1747,9 @@ gst_audio_aggregator_fill_buffer (GstAudioAggregator * aagg,
           diff = aagg->priv->offset - start_output_offset;
         else
           diff = 0;
+      } else if (pad->priv->output_offset != -1 &&
+          start_output_offset < pad->priv->output_offset) {
+        diff = pad->priv->output_offset - start_output_offset;
       } else {
         diff = aagg->priv->offset - start_output_offset;
       }
@@ -1756,7 +1759,6 @@ gst_audio_aggregator_fill_buffer (GstAudioAggregator * aagg,
         /* Empty buffer, drop */
         pad->priv->position = 0;
         pad->priv->size = 0;
-        pad->priv->output_offset = -1;
         GST_DEBUG_OBJECT (pad,
             "Buffer before segment or current position: %" G_GUINT64_FORMAT
             " < %" G_GINT64_FORMAT, end_output_offset, aagg->priv->offset);
@@ -1766,6 +1768,9 @@ gst_audio_aggregator_fill_buffer (GstAudioAggregator * aagg,
 
     if (start_output_offset == -1 || start_output_offset < aagg->priv->offset)
       pad->priv->output_offset = aagg->priv->offset;
+    else if (pad->priv->output_offset != -1)
+      pad->priv->output_offset = MAX (pad->priv->output_offset,
+          start_output_offset);
     else
       pad->priv->output_offset = start_output_offset;