matroskamux: 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.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7872>
This commit is contained in:
Sebastian Dröge 2024-11-12 11:36:38 +02:00 committed by GStreamer Marge Bot
parent 701f563996
commit a391728ad4

View file

@ -271,6 +271,10 @@ gst_matroska_mux_write_simple_tag (const GstTagList * list, const gchar * tag,
static gboolean gst_matroska_mux_tag_list_is_empty (const GstTagList * list); static gboolean gst_matroska_mux_tag_list_is_empty (const GstTagList * list);
static void gst_matroska_mux_write_streams_tags (GstMatroskaMux * mux); static void gst_matroska_mux_write_streams_tags (GstMatroskaMux * mux);
static gboolean gst_matroska_mux_streams_have_tags (GstMatroskaMux * mux); static gboolean gst_matroska_mux_streams_have_tags (GstMatroskaMux * mux);
static gboolean gst_matroska_mux_all_pads_have_codec_id (GstMatroskaMux * mux);
static GstMatroskaMuxPad *gst_matroska_mux_find_best_pad (GstMatroskaMux * mux,
GstClockTime * best_time, gboolean timeout);
/* Cannot use boilerplate macros here because we need the full init function /* Cannot use boilerplate macros here because we need the full init function
* signature with the additional class argument, so we use the right template * signature with the additional class argument, so we use the right template
@ -709,14 +713,20 @@ static GstClockTime
gst_matroska_mux_get_next_time (GstAggregator * agg) gst_matroska_mux_get_next_time (GstAggregator * agg)
{ {
GstMatroskaMux *mux = GST_MATROSKA_MUX (agg); GstMatroskaMux *mux = GST_MATROSKA_MUX (agg);
GstSegment segment; GstMatroskaMuxPad *best = NULL;
GstClockTime next_time; GstClockTime best_time = GST_CLOCK_TIME_NONE;
gst_segment_init (&segment, GST_FORMAT_TIME); if (mux->state == GST_MATROSKA_MUX_STATE_START
next_time = && !gst_matroska_mux_all_pads_have_codec_id (mux))
gst_segment_to_running_time (&segment, GST_FORMAT_TIME, mux->last_pos); return GST_CLOCK_TIME_NONE;
return next_time; best = gst_matroska_mux_find_best_pad (mux, &best_time, TRUE);
// Buffer without timestamps are muxed immediately
if (best && best_time == GST_CLOCK_TIME_NONE)
best_time = 0;
gst_clear_object (&best);
return best_time;
} }
static void static void
@ -4178,10 +4188,11 @@ gst_matroska_mux_clip (GstAggregator * agg, GstAggregatorPad * agg_pad,
} }
static GstMatroskaMuxPad * static GstMatroskaMuxPad *
gst_matroska_mux_find_best_pad (GstMatroskaMux * mux, gboolean timeout) gst_matroska_mux_find_best_pad (GstMatroskaMux * mux, GstClockTime * best_time,
gboolean timeout)
{ {
GstMatroskaMuxPad *best = NULL; GstMatroskaMuxPad *best = NULL;
GstClockTime best_time = GST_CLOCK_TIME_NONE; GstClockTime best_ts = GST_CLOCK_TIME_NONE;
GList *l; GList *l;
GST_OBJECT_LOCK (mux); GST_OBJECT_LOCK (mux);
@ -4194,7 +4205,7 @@ gst_matroska_mux_find_best_pad (GstMatroskaMux * mux, gboolean timeout)
if (!buffer) { if (!buffer) {
if (!timeout && !GST_PAD_IS_EOS (mux_pad)) { if (!timeout && !GST_PAD_IS_EOS (mux_pad)) {
best = NULL; best = NULL;
best_time = GST_CLOCK_TIME_NONE; best_ts = GST_CLOCK_TIME_NONE;
break; break;
} }
continue; continue;
@ -4205,18 +4216,21 @@ gst_matroska_mux_find_best_pad (GstMatroskaMux * mux, gboolean timeout)
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
// GST_CLOCK_TIME_NONE < any other clock time // GST_CLOCK_TIME_NONE < any other clock time
if (best == NULL || !GST_CLOCK_TIME_IS_VALID (timestamp) || (best != NULL if (best == NULL || !GST_CLOCK_TIME_IS_VALID (timestamp) || (best != NULL
&& GST_CLOCK_TIME_IS_VALID (best_time) && timestamp < best_time)) { && GST_CLOCK_TIME_IS_VALID (best_ts) && timestamp < best_ts)) {
best = mux_pad; best = mux_pad;
best_time = timestamp; best_ts = timestamp;
} }
} }
if (best) if (best) {
gst_object_ref (best); gst_object_ref (best);
if (best_time)
*best_time = best_ts;
}
GST_OBJECT_UNLOCK (mux); GST_OBJECT_UNLOCK (mux);
GST_DEBUG_OBJECT (mux, "best pad %s, best time %" GST_TIME_FORMAT, GST_DEBUG_OBJECT (mux, "best pad %s, best time %" GST_TIME_FORMAT,
best ? GST_PAD_NAME (best) : "(nil)", GST_TIME_ARGS (best_time)); best ? GST_PAD_NAME (best) : "(nil)", GST_TIME_ARGS (best_ts));
return best; return best;
} }
@ -4274,7 +4288,7 @@ gst_matroska_mux_aggregate (GstAggregator * agg, gboolean timeout)
GST_DEBUG_OBJECT (mux, "Aggregating (timeout: %d)", timeout); GST_DEBUG_OBJECT (mux, "Aggregating (timeout: %d)", timeout);
best = gst_matroska_mux_find_best_pad (mux, timeout); best = gst_matroska_mux_find_best_pad (mux, NULL, timeout);
/* if there is no best pad, we have reached EOS or timed out without any /* if there is no best pad, we have reached EOS or timed out without any
* buffers */ * buffers */