mpegtsmux: Don't time out in live mode if no timestamped next buffer is available
authorSebastian Dröge <sebastian@centricular.com>
Tue, 12 Nov 2024 09:01:03 +0000 (11:01 +0200)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 15 Nov 2024 19:19:32 +0000 (19:19 +0000)
The muxer can only advance the time if it has a timestamped buffer that can be
output, otherwise it will just busy-wait and use up a lot of CPU.

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3912

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

subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c

index c9c4fbca26d2ed40f85b8ab4221f6f1f60202fc0..dafe2d67851f26140f3f18fb264a64f841e5cb63 100644 (file)
@@ -2449,7 +2449,8 @@ beach:
 }
 
 static GstBaseTsMuxPad *
-gst_base_ts_mux_find_best_pad (GstAggregator * aggregator, gboolean timeout)
+gst_base_ts_mux_find_best_pad (GstAggregator * aggregator,
+    GstClockTime * best_time, gboolean timeout)
 {
   GstBaseTsMuxPad *best = NULL;
   GstClockTime best_ts = GST_CLOCK_TIME_NONE;
@@ -2484,8 +2485,11 @@ gst_base_ts_mux_find_best_pad (GstAggregator * aggregator, gboolean timeout)
     gst_buffer_unref (buffer);
   }
 
-  if (best)
+  if (best) {
     gst_object_ref (best);
+    if (best_time)
+      *best_time = best_ts;
+  }
 
   GST_OBJECT_UNLOCK (aggregator);
 
@@ -2524,7 +2528,7 @@ gst_base_ts_mux_aggregate (GstAggregator * agg, gboolean timeout)
 {
   GstBaseTsMux *mux = GST_BASE_TS_MUX (agg);
   GstFlowReturn ret = GST_FLOW_OK;
-  GstBaseTsMuxPad *best = gst_base_ts_mux_find_best_pad (agg, timeout);
+  GstBaseTsMuxPad *best = gst_base_ts_mux_find_best_pad (agg, NULL, timeout);
   GstCaps *caps;
 
   /* set caps on the srcpad if no caps were set yet */
@@ -2598,6 +2602,21 @@ gst_base_ts_mux_stop (GstAggregator * agg)
   return TRUE;
 }
 
+static GstClockTime
+gst_base_ts_mux_get_next_time (GstAggregator * agg)
+{
+  GstBaseTsMuxPad *best = NULL;
+  GstClockTime next_time = GST_CLOCK_TIME_NONE;
+
+  best = gst_base_ts_mux_find_best_pad (agg, &next_time, TRUE);
+  // Buffer without timestamps are muxed immediately
+  if (best && next_time == GST_CLOCK_TIME_NONE)
+    next_time = 0;
+  gst_clear_object (&best);
+
+  return next_time;
+}
+
 /* GObject implementation */
 
 static void
@@ -2842,7 +2861,7 @@ gst_base_ts_mux_class_init (GstBaseTsMuxClass * klass)
   gstagg_class->src_event = gst_base_ts_mux_src_event;
   gstagg_class->start = gst_base_ts_mux_start;
   gstagg_class->stop = gst_base_ts_mux_stop;
-  gstagg_class->get_next_time = gst_aggregator_simple_get_next_time;
+  gstagg_class->get_next_time = gst_base_ts_mux_get_next_time;
 
   klass->create_ts_mux = gst_base_ts_mux_default_create_ts_mux;
   klass->allocate_packet = gst_base_ts_mux_default_allocate_packet;