From: Sebastian Dröge Date: Thu, 27 Oct 2022 12:13:36 +0000 (+0300) Subject: core/base: Only post latency messages if the latency values have actually changed X-Git-Tag: 1.22.0~672 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c878d0f68b4bbe19d0835c2b6e48b52a87f03ad8;p=platform%2Fupstream%2Fgstreamer.git core/base: Only post latency messages if the latency values have actually changed Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1525 Part-of: --- diff --git a/subprojects/gst-plugins-base/gst-libs/gst/app/gstappsrc.c b/subprojects/gst-plugins-base/gst-libs/gst/app/gstappsrc.c index 1fb4674..add6a28 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/app/gstappsrc.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/app/gstappsrc.c @@ -183,6 +183,9 @@ struct _GstAppSrcPrivate guint64 min_latency; guint64 max_latency; + /* Tracks whether the latency message was posted at least once */ + gboolean posted_latency_msg; + gboolean emit_signals; guint min_percent; gboolean handle_segment_change; @@ -1103,6 +1106,7 @@ gst_app_src_stop (GstBaseSrc * bsrc) priv->is_eos = FALSE; priv->flushing = TRUE; priv->started = FALSE; + priv->posted_latency_msg = FALSE; gst_app_src_flush_queued (appsrc, TRUE); g_cond_broadcast (&priv->cond); g_mutex_unlock (&priv->mutex); @@ -2325,6 +2329,10 @@ gst_app_src_set_latencies (GstAppSrc * appsrc, gboolean do_min, guint64 min, priv->max_latency = max; changed = TRUE; } + if (!priv->posted_latency_msg) { + priv->posted_latency_msg = TRUE; + changed = TRUE; + } g_mutex_unlock (&priv->mutex); if (changed) { diff --git a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiodecoder.c b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiodecoder.c index 8b00138..9396a9f 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiodecoder.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiodecoder.c @@ -180,6 +180,8 @@ typedef struct _GstAudioDecoderContext /* MT-protected (with LOCK) */ GstClockTime min_latency; GstClockTime max_latency; + /* Tracks whether the latency message was posted at least once */ + gboolean posted_latency_msg; GstAllocator *allocator; GstAllocationParams params; @@ -555,6 +557,7 @@ gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full) memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx)); gst_audio_info_init (&dec->priv->ctx.info); + dec->priv->ctx.posted_latency_msg = FALSE; GST_OBJECT_UNLOCK (dec); dec->priv->ctx.had_output_data = FALSE; dec->priv->ctx.had_input_data = FALSE; @@ -3391,24 +3394,43 @@ gst_audio_decoder_get_max_errors (GstAudioDecoder * dec) * @min: minimum latency * @max: maximum latency * - * Sets decoder latency. + * Sets decoder latency. If the provided values changed from + * previously provided ones, this will also post a LATENCY message on the bus + * so the pipeline can reconfigure its global latency. */ void gst_audio_decoder_set_latency (GstAudioDecoder * dec, GstClockTime min, GstClockTime max) { + gboolean post_message = FALSE; + g_return_if_fail (GST_IS_AUDIO_DECODER (dec)); g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min)); g_return_if_fail (min <= max); + GST_DEBUG_OBJECT (dec, + "min_latency:%" GST_TIME_FORMAT " max_latency:%" GST_TIME_FORMAT, + GST_TIME_ARGS (min), GST_TIME_ARGS (max)); + GST_OBJECT_LOCK (dec); - dec->priv->ctx.min_latency = min; - dec->priv->ctx.max_latency = max; + if (dec->priv->ctx.min_latency != min) { + dec->priv->ctx.min_latency = min; + post_message = TRUE; + } + if (dec->priv->ctx.max_latency != max) { + dec->priv->ctx.max_latency = max; + post_message = TRUE; + } + if (!dec->priv->ctx.posted_latency_msg) { + dec->priv->ctx.posted_latency_msg = TRUE; + post_message = TRUE; + } GST_OBJECT_UNLOCK (dec); /* post latency message on the bus */ - gst_element_post_message (GST_ELEMENT (dec), - gst_message_new_latency (GST_OBJECT (dec))); + if (post_message) + gst_element_post_message (GST_ELEMENT (dec), + gst_message_new_latency (GST_OBJECT (dec))); } /** diff --git a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioencoder.c b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioencoder.c index a2fa472..f772167 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioencoder.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioencoder.c @@ -171,6 +171,9 @@ typedef struct _GstAudioEncoderContext /* MT-protected (with LOCK) */ GstClockTime min_latency; GstClockTime max_latency; + /* Tracks whether the latency message was posted at least once */ + gboolean posted_latency_msg; + gboolean negotiated; GList *headers; @@ -493,6 +496,7 @@ gst_audio_encoder_reset (GstAudioEncoder * enc, gboolean full) memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx)); gst_audio_info_init (&enc->priv->ctx.info); + enc->priv->ctx.posted_latency_msg = FALSE; GST_OBJECT_UNLOCK (enc); if (enc->priv->upstream_tags) { @@ -2346,27 +2350,43 @@ gst_audio_encoder_get_lookahead (GstAudioEncoder * enc) * @min: minimum latency * @max: maximum latency * - * Sets encoder latency. + * Sets encoder latency. If the provided values changed from + * previously provided ones, this will also post a LATENCY message on the bus + * so the pipeline can reconfigure its global latency. */ void gst_audio_encoder_set_latency (GstAudioEncoder * enc, GstClockTime min, GstClockTime max) { + gboolean post_message = FALSE; + g_return_if_fail (GST_IS_AUDIO_ENCODER (enc)); g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min)); g_return_if_fail (min <= max); + GST_DEBUG_OBJECT (enc, + "min_latency:%" GST_TIME_FORMAT " max_latency:%" GST_TIME_FORMAT, + GST_TIME_ARGS (min), GST_TIME_ARGS (max)); + GST_OBJECT_LOCK (enc); - enc->priv->ctx.min_latency = min; - enc->priv->ctx.max_latency = max; + if (enc->priv->ctx.min_latency != min) { + enc->priv->ctx.min_latency = min; + post_message = TRUE; + } + if (enc->priv->ctx.max_latency != max) { + enc->priv->ctx.max_latency = max; + post_message = TRUE; + } + if (!enc->priv->ctx.posted_latency_msg) { + enc->priv->ctx.posted_latency_msg = TRUE; + post_message = TRUE; + } GST_OBJECT_UNLOCK (enc); - GST_LOG_OBJECT (enc, "set to %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT, - GST_TIME_ARGS (min), GST_TIME_ARGS (max)); - /* post latency message on the bus */ - gst_element_post_message (GST_ELEMENT (enc), - gst_message_new_latency (GST_OBJECT (enc))); + if (post_message) + gst_element_post_message (GST_ELEMENT (enc), + gst_message_new_latency (GST_OBJECT (enc))); } /** diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideoencoder.c b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideoencoder.c index 2f814ad..fcfb15b 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideoencoder.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideoencoder.c @@ -134,6 +134,9 @@ struct _GstVideoEncoderPrivate gint64 min_latency; gint64 max_latency; + /* Tracks whether the latency message was posted at least once */ + gboolean posted_latency_msg; + /* FIXME 2.0: Use a GQueue or similar, see GstVideoCodecFrame::events */ GList *current_frame_events; @@ -512,6 +515,8 @@ gst_video_encoder_reset (GstVideoEncoder * encoder, gboolean hard) priv->dropped = 0; priv->processed = 0; + + priv->posted_latency_msg = FALSE; } else { GList *l; @@ -2853,22 +2858,41 @@ gst_video_encoder_set_output_state (GstVideoEncoder * encoder, GstCaps * caps, * @min_latency: minimum latency * @max_latency: maximum latency * - * Informs baseclass of encoding latency. + * Informs baseclass of encoding latency. If the provided values changed from + * previously provided ones, this will also post a LATENCY message on the bus + * so the pipeline can reconfigure its global latency. */ void gst_video_encoder_set_latency (GstVideoEncoder * encoder, GstClockTime min_latency, GstClockTime max_latency) { + gboolean post_message = FALSE; + g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min_latency)); g_return_if_fail (max_latency >= min_latency); + GST_DEBUG_OBJECT (encoder, + "min_latency:%" GST_TIME_FORMAT " max_latency:%" GST_TIME_FORMAT, + GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); + GST_OBJECT_LOCK (encoder); - encoder->priv->min_latency = min_latency; - encoder->priv->max_latency = max_latency; + if (encoder->priv->min_latency != min_latency) { + encoder->priv->min_latency = min_latency; + post_message = TRUE; + } + if (encoder->priv->max_latency != max_latency) { + encoder->priv->max_latency = max_latency; + post_message = TRUE; + } + if (!encoder->priv->posted_latency_msg) { + encoder->priv->posted_latency_msg = TRUE; + post_message = TRUE; + } GST_OBJECT_UNLOCK (encoder); - gst_element_post_message (GST_ELEMENT_CAST (encoder), - gst_message_new_latency (GST_OBJECT_CAST (encoder))); + if (post_message) + gst_element_post_message (GST_ELEMENT_CAST (encoder), + gst_message_new_latency (GST_OBJECT_CAST (encoder))); } /** diff --git a/subprojects/gstreamer/libs/gst/base/gstaggregator.c b/subprojects/gstreamer/libs/gst/base/gstaggregator.c index 3e7d12a..d51ac56 100644 --- a/subprojects/gstreamer/libs/gst/base/gstaggregator.c +++ b/subprojects/gstreamer/libs/gst/base/gstaggregator.c @@ -384,6 +384,8 @@ struct _GstAggregatorPrivate GstClockTime sub_latency_min; /* protected by src_lock */ GstClockTime sub_latency_max; /* protected by src_lock */ + /* Tracks whether the latency message was posted at least once */ + gboolean posted_latency_msg; GstClockTime upstream_latency_min; /* protected by src_lock */ @@ -1914,6 +1916,7 @@ gst_aggregator_stop (GstAggregator * agg) agg->priv->has_peer_latency = FALSE; agg->priv->peer_latency_live = FALSE; agg->priv->peer_latency_min = agg->priv->peer_latency_max = 0; + agg->priv->posted_latency_msg = FALSE; if (agg->priv->tags) gst_tag_list_unref (agg->priv->tags); @@ -3699,7 +3702,7 @@ gst_aggregator_merge_tags (GstAggregator * self, * * Lets #GstAggregator sub-classes tell the baseclass what their internal * latency is. Will also post a LATENCY message on the bus so the pipeline - * can reconfigure its global latency. + * can reconfigure its global latency if the values changed. */ void gst_aggregator_set_latency (GstAggregator * self, @@ -3720,6 +3723,10 @@ gst_aggregator_set_latency (GstAggregator * self, self->priv->sub_latency_max = max_latency; changed = TRUE; } + if (!self->priv->posted_latency_msg) { + self->priv->posted_latency_msg = TRUE; + changed = TRUE; + } if (changed) SRC_BROADCAST (self); diff --git a/subprojects/gstreamer/libs/gst/base/gstbaseparse.c b/subprojects/gstreamer/libs/gst/base/gstbaseparse.c index e1920a9..4e7c46e 100644 --- a/subprojects/gstreamer/libs/gst/base/gstbaseparse.c +++ b/subprojects/gstreamer/libs/gst/base/gstbaseparse.c @@ -231,6 +231,8 @@ struct _GstBaseParsePrivate guint lead_in, lead_out; GstClockTime lead_in_ts, lead_out_ts; GstClockTime min_latency, max_latency; + /* Tracks whether the latency message was posted at least once */ + gboolean posted_latency_msg; gboolean discont; gboolean flushing; @@ -899,6 +901,7 @@ gst_base_parse_reset (GstBaseParse * parse) parse->priv->detect_buffers_size = 0; parse->priv->segment_seqnum = GST_SEQNUM_INVALID; + parse->priv->posted_latency_msg = FALSE; GST_OBJECT_UNLOCK (parse); } @@ -4081,23 +4084,44 @@ gst_base_parse_set_infer_ts (GstBaseParse * parse, gboolean infer_ts) * @max_latency: maximum parse latency * * Sets the minimum and maximum (which may likely be equal) latency introduced - * by the parsing process. If there is such a latency, which depends on the + * by the parsing process. If there is such a latency, which depends on the * particular parsing of the format, it typically corresponds to 1 frame duration. + * + * If the provided values changed from previously provided ones, this will + * also post a LATENCY message on the bus so the pipeline can reconfigure its + * global latency. */ void gst_base_parse_set_latency (GstBaseParse * parse, GstClockTime min_latency, GstClockTime max_latency) { + gboolean post_message = FALSE; + g_return_if_fail (GST_CLOCK_TIME_IS_VALID (min_latency)); g_return_if_fail (min_latency <= max_latency); - GST_OBJECT_LOCK (parse); - parse->priv->min_latency = min_latency; - parse->priv->max_latency = max_latency; - GST_OBJECT_UNLOCK (parse); GST_INFO_OBJECT (parse, "min/max latency %" GST_TIME_FORMAT ", %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); + + GST_OBJECT_LOCK (parse); + if (parse->priv->min_latency != min_latency) { + parse->priv->min_latency = min_latency; + post_message = TRUE; + } + if (parse->priv->max_latency != max_latency) { + parse->priv->max_latency = max_latency; + post_message = TRUE; + } + if (!parse->priv->posted_latency_msg) { + parse->priv->posted_latency_msg = TRUE; + post_message = TRUE; + } + GST_OBJECT_UNLOCK (parse); + + if (post_message) + gst_element_post_message (GST_ELEMENT_CAST (parse), + gst_message_new_latency (GST_OBJECT_CAST (parse))); } static gboolean