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;
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);
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) {
/* 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;
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;
* @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)));
}
/**
/* 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;
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) {
* @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)));
}
/**
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;
priv->dropped = 0;
priv->processed = 0;
+
+ priv->posted_latency_msg = FALSE;
} else {
GList *l;
* @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)));
}
/**
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 */
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);
*
* 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,
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);
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;
parse->priv->detect_buffers_size = 0;
parse->priv->segment_seqnum = GST_SEQNUM_INVALID;
+ parse->priv->posted_latency_msg = FALSE;
GST_OBJECT_UNLOCK (parse);
}
* @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