core/base: Only post latency messages if the latency values have actually changed

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

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3282>
This commit is contained in:
Sebastian Dröge 2022-10-27 15:13:36 +03:00 committed by GStreamer Marge Bot
parent 8f286fc388
commit c878d0f68b
6 changed files with 130 additions and 25 deletions

View file

@ -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) {

View file

@ -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)));
}
/**

View file

@ -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_OBJECT_LOCK (enc);
enc->priv->ctx.min_latency = min;
enc->priv->ctx.max_latency = max;
GST_OBJECT_UNLOCK (enc);
GST_LOG_OBJECT (enc, "set to %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
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);
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);
/* 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)));
}
/**

View file

@ -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)));
}
/**

View file

@ -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);

View file

@ -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