concat: adjust running time offsets on events
authorMathieu Duponchelle <mathieu@centricular.com>
Tue, 11 May 2021 19:16:01 +0000 (21:16 +0200)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 14 May 2021 12:53:20 +0000 (12:53 +0000)
When concat adjusts the base of the segments it forwards
downstream, it needs to also adjust the running time offsets,
as GstPad does when an offset is set by the application on a pad.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/819>

plugins/elements/gstconcat.c

index 9b732fe..b1156a5 100644 (file)
@@ -524,28 +524,28 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
   GstConcat *self = GST_CONCAT (parent);
   GstConcatPad *spad = GST_CONCAT_PAD_CAST (pad);
   gboolean ret = TRUE;
+  gboolean adjust_base;
 
   GST_LOG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
 
+  g_mutex_lock (&self->lock);
+  adjust_base = self->adjust_base;
+  g_mutex_unlock (&self->lock);
+
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_STREAM_START:{
       if (!gst_concat_pad_wait (spad, self)) {
         ret = FALSE;
-        gst_event_unref (event);
-      } else {
-        ret = gst_pad_event_default (pad, parent, event);
+        gst_event_replace (&event, NULL);
       }
       break;
     }
     case GST_EVENT_SEGMENT:{
-      gboolean adjust_base;
-
       /* Drop segment event, we create our own one */
       gst_event_copy_segment (event, &spad->segment);
-      gst_event_unref (event);
+      gst_event_replace (&event, NULL);
 
       g_mutex_lock (&self->lock);
-      adjust_base = self->adjust_base;
       if (self->format == GST_FORMAT_UNDEFINED) {
         if (spad->segment.format != GST_FORMAT_TIME
             && spad->segment.format != GST_FORMAT_BYTES) {
@@ -574,7 +574,6 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
         ret = FALSE;
       } else {
         GstSegment segment = spad->segment;
-        GstEvent *topush;
 
         g_mutex_lock (&self->lock);
 
@@ -608,17 +607,15 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
             }
           }
         }
-        topush = gst_event_new_segment (&segment);
-        gst_event_set_seqnum (topush, gst_event_get_seqnum (event));
+        event = gst_event_new_segment (&segment);
+        gst_event_set_seqnum (event, gst_event_get_seqnum (event));
 
         g_mutex_unlock (&self->lock);
-
-        gst_pad_push_event (self->srcpad, topush);
       }
       break;
     }
     case GST_EVENT_EOS:{
-      gst_event_unref (event);
+      gst_event_replace (&event, NULL);
 
       if (!gst_concat_pad_wait (spad, self)) {
         ret = FALSE;
@@ -633,7 +630,7 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
         gst_concat_notify_active_pad (self);
 
         if (!next) {
-          gst_pad_push_event (self->srcpad, gst_event_new_eos ());
+          event = gst_event_new_eos ();
         } else {
           gst_element_post_message (GST_ELEMENT_CAST (self),
               gst_message_new_duration_changed (GST_OBJECT_CAST (self)));
@@ -652,10 +649,8 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
         forward = TRUE;
       g_mutex_unlock (&self->lock);
 
-      if (forward)
-        ret = gst_pad_event_default (pad, parent, event);
-      else
-        gst_event_unref (event);
+      if (!forward)
+        gst_event_replace (&event, NULL);
       break;
     }
     case GST_EVENT_FLUSH_STOP:{
@@ -680,24 +675,36 @@ gst_concat_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
           self->current_start_offset = 0;
           self->last_stop = GST_CLOCK_TIME_NONE;
         }
-        ret = gst_pad_event_default (pad, parent, event);
       } else {
-        gst_event_unref (event);
+        gst_event_replace (&event, NULL);
       }
       break;
     }
     default:{
       /* Wait for other serialized events before forwarding */
       if (GST_EVENT_IS_SERIALIZED (event) && !gst_concat_pad_wait (spad, self)) {
-        gst_event_unref (event);
+        gst_event_replace (&event, NULL);
         ret = FALSE;
-      } else {
-        ret = gst_pad_event_default (pad, parent, event);
       }
       break;
     }
   }
 
+  if (event) {
+    g_mutex_lock (&self->lock);
+    if (self->adjust_base && self->format == GST_FORMAT_TIME) {
+      gint64 offset;
+
+      event = gst_event_make_writable (event);
+      offset = gst_event_get_running_time_offset (event);
+      offset += self->current_start_offset;
+
+      gst_event_set_running_time_offset (event, offset);
+    }
+    g_mutex_unlock (&self->lock);
+    ret = gst_pad_event_default (pad, parent, event);
+  }
+
   return ret;
 }
 
@@ -729,13 +736,12 @@ gst_concat_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
 {
   GstConcat *self = GST_CONCAT (parent);
   gboolean ret = TRUE;
+  GstPad *sinkpad = NULL;
 
   GST_LOG_OBJECT (pad, "received event %" GST_PTR_FORMAT, event);
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_SEEK:{
-      GstPad *sinkpad = NULL;
-
       g_mutex_lock (&self->lock);
       if ((sinkpad = self->current_sinkpad))
         gst_object_ref (sinkpad);
@@ -744,20 +750,13 @@ gst_concat_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
         sinkpad = gst_object_ref (self->sinkpads->data);
       }
       g_mutex_unlock (&self->lock);
-      if (sinkpad) {
-        ret = gst_pad_push_event (sinkpad, event);
-        gst_object_unref (sinkpad);
-      } else {
-        gst_event_unref (event);
+      if (!sinkpad) {
+        gst_event_replace (&event, NULL);
         ret = FALSE;
       }
       break;
     }
     case GST_EVENT_QOS:{
-      GstQOSType type;
-      GstClockTimeDiff diff;
-      GstClockTime timestamp;
-      gdouble proportion;
       GstPad *sinkpad = NULL;
 
       g_mutex_lock (&self->lock);
@@ -765,21 +764,9 @@ gst_concat_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
         gst_object_ref (sinkpad);
       g_mutex_unlock (&self->lock);
 
-      if (sinkpad) {
-        gst_event_parse_qos (event, &type, &proportion, &diff, &timestamp);
-        gst_event_unref (event);
 
-        if (timestamp != GST_CLOCK_TIME_NONE
-            && timestamp > self->current_start_offset) {
-          timestamp -= self->current_start_offset;
-          event = gst_event_new_qos (type, proportion, diff, timestamp);
-          ret = gst_pad_push_event (self->current_sinkpad, event);
-        } else {
-          ret = FALSE;
-        }
-        gst_object_unref (sinkpad);
-      } else {
-        gst_event_unref (event);
+      if (!sinkpad) {
+        gst_event_replace (&event, NULL);
         ret = FALSE;
       }
       break;
@@ -793,15 +780,34 @@ gst_concat_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
             "resetting start offset to 0 after flushing with reset_time = TRUE");
         self->current_start_offset = 0;
       }
-
-      ret = gst_pad_event_default (pad, parent, event);
       break;
     }
     default:
-      ret = gst_pad_event_default (pad, parent, event);
       break;
   }
 
+  if (event) {
+    g_mutex_lock (&self->lock);
+    if (self->adjust_base && self->format == GST_FORMAT_TIME) {
+      gint64 offset;
+
+      event = gst_event_make_writable (event);
+      offset = gst_event_get_running_time_offset (event);
+      offset -= self->current_start_offset;
+
+      gst_event_set_running_time_offset (event, offset);
+    }
+    g_mutex_unlock (&self->lock);
+
+    if (sinkpad)
+      ret = gst_pad_push_event (sinkpad, event);
+    else
+      ret = gst_pad_event_default (pad, parent, event);
+  }
+
+  if (sinkpad)
+    gst_object_unref (sinkpad);
+
   return ret;
 }