flvmux: use the correct timestamp to calculate wait times
authorMichael Olbrich <m.olbrich@pengutronix.de>
Wed, 24 May 2023 14:17:46 +0000 (16:17 +0200)
committerTim-Philipp Müller <tim@centricular.com>
Mon, 29 May 2023 23:52:01 +0000 (00:52 +0100)
Since c0bf793c05cf793aa18a8548cda702625e388115 ("flvmux: Set PTS based on
running time") the timestamp of the output buffer is already in running
time. So using that for 'srcpad->segment.position' does not work correctly
because gst_aggregator_simple_get_next_time() will convert it again with
gst_segment_to_running_time().
This means that the timestamp returned by
gst_aggregator_simple_get_next_time() may be incorrect. For example, if
flvmux is added to a already runinng pipeline then the timestamp is too
small and gst_aggregator_wait_and_check() returns immediately. As a result,
buffers may be muxed in the wrong order.

To fix this, use the PTS of the incoming buffer instead of the outgoing
buffer. Also add the duration as get_next_time() is supposed to return the
timestamp of the next buffer, not the current one.

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

subprojects/gst-plugins-good/gst/flv/gstflvmux.c

index 431cc96..59e39df 100644 (file)
@@ -801,12 +801,6 @@ gst_flv_mux_release_pad (GstElement * element, GstPad * pad)
 static GstFlowReturn
 gst_flv_mux_push (GstFlvMux * mux, GstBuffer * buffer)
 {
-  GstAggregator *agg = GST_AGGREGATOR (mux);
-  GstAggregatorPad *srcpad = GST_AGGREGATOR_PAD (agg->srcpad);
-
-  if (GST_BUFFER_PTS_IS_VALID (buffer))
-    srcpad->segment.position = GST_BUFFER_PTS (buffer);
-
   /* pushing the buffer that rewrites the header will make it no longer be the
    * total output size in bytes, but it doesn't matter at that point */
   mux->byte_count += gst_buffer_get_size (buffer);
@@ -1660,6 +1654,8 @@ gst_flv_mux_write_buffer (GstFlvMux * mux, GstFlvMuxPad * pad,
 {
   GstBuffer *tag;
   GstFlowReturn ret;
+  GstClockTime pts = GST_BUFFER_PTS (buffer);
+  GstClockTime duration = GST_BUFFER_DURATION (buffer);
   GstClockTime dts =
       gst_flv_mux_segment_to_running_time (&GST_AGGREGATOR_PAD (pad)->segment,
       GST_BUFFER_DTS (buffer));
@@ -1678,6 +1674,14 @@ gst_flv_mux_write_buffer (GstFlvMux * mux, GstFlvMuxPad * pad,
   if (ret == GST_FLOW_OK && GST_CLOCK_TIME_IS_VALID (dts))
     pad->last_timestamp = dts;
 
+  if (ret == GST_FLOW_OK && GST_CLOCK_TIME_IS_VALID (pts)) {
+    GstAggregator *agg = GST_AGGREGATOR (mux);
+    GstAggregatorPad *srcpad = GST_AGGREGATOR_PAD (agg->srcpad);
+    srcpad->segment.position = pts;
+    if (GST_CLOCK_TIME_IS_VALID (duration))
+      srcpad->segment.position += duration;
+  }
+
   return ret;
 }