From 3971f8b86cd79d327e2c0b389e284784823b1da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 12 Nov 2024 11:01:03 +0200 Subject: [PATCH] mpegtsmux: Don't time out in live mode if no timestamped next buffer is available 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: --- .../gst/mpegtsmux/gstbasetsmux.c | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c b/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c index 0a52836e55..be6dda826b 100644 --- a/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c +++ b/subprojects/gst-plugins-bad/gst/mpegtsmux/gstbasetsmux.c @@ -2629,7 +2629,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; @@ -2664,8 +2665,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); @@ -2704,7 +2708,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 */ @@ -2778,6 +2782,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 @@ -3028,7 +3047,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;