From e68317f070caf533c582c9fe2795e21b75f4747f Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Thu, 5 Dec 2013 14:39:57 +0000 Subject: [PATCH] audiodec/enc: clear reconfigure flag if negotiate succeeds So that it avoids to send an allocation query twice. One from an early call to gst_audio_encoder_negotiate from a subclass, then one from gst_audio_encoder_allocate_output_buffer. Which means that previously gst_audio_encoder_negotiate was not clearing the GST_PAD_FLAG_NEED_RECONFIGURE even on success. Fixes bug https://bugzilla.gnome.org/show_bug.cgi?id=719684 --- gst-libs/gst/audio/gstaudiodecoder.c | 35 +++++++++++++++++++++++++++------ gst-libs/gst/audio/gstaudioencoder.c | 38 ++++++++++++++++++++++++++++-------- 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c index 3102ee5..c806871 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.c +++ b/gst-libs/gst/audio/gstaudiodecoder.c @@ -315,6 +315,7 @@ static gboolean gst_audio_decoder_decide_allocation_default (GstAudioDecoder * static gboolean gst_audio_decoder_propose_allocation_default (GstAudioDecoder * dec, GstQuery * query); static gboolean gst_audio_decoder_negotiate_default (GstAudioDecoder * dec); +static gboolean gst_audio_decoder_negotiate_unlocked (GstAudioDecoder * dec); static GstElementClass *parent_class = NULL; @@ -656,11 +657,25 @@ no_decide_allocation: } } +static gboolean +gst_audio_decoder_negotiate_unlocked (GstAudioDecoder * dec) +{ + GstAudioDecoderClass *klass = GST_AUDIO_DECODER_GET_CLASS (dec); + gboolean ret = TRUE; + + if (G_LIKELY (klass->negotiate)) + ret = klass->negotiate (dec); + + return ret; +} + /** * gst_audio_decoder_negotiate: * @dec: a #GstAudioDecoder * - * Negotiate with downstreame elements to currently configured #GstAudioInfo. + * Negotiate with downstream elements to currently configured #GstAudioInfo. + * Unmark GST_PAD_FLAG_NEED_RECONFIGURE in any case. But mark it again if + * negotiate fails. * * Returns: #TRUE if the negotiation succeeded, else #FALSE. */ @@ -675,8 +690,12 @@ gst_audio_decoder_negotiate (GstAudioDecoder * dec) klass = GST_AUDIO_DECODER_GET_CLASS (dec); GST_AUDIO_DECODER_STREAM_LOCK (dec); - if (klass->negotiate) + gst_pad_check_reconfigure (dec->srcpad); + if (klass->negotiate) { res = klass->negotiate (dec); + if (!res) + gst_pad_mark_reconfigure (dec->srcpad); + } GST_AUDIO_DECODER_STREAM_UNLOCK (dec); return res; @@ -1017,6 +1036,7 @@ gst_audio_decoder_finish_frame (GstAudioDecoder * dec, GstBuffer * buf, GstClockTime ts, next_ts; gsize size; GstFlowReturn ret = GST_FLOW_OK; + gboolean needs_reconfigure = FALSE; /* subclass should not hand us no data */ g_return_val_if_fail (buf == NULL || gst_buffer_get_size (buf) > 0, @@ -1039,10 +1059,11 @@ gst_audio_decoder_finish_frame (GstAudioDecoder * dec, GstBuffer * buf, GST_AUDIO_DECODER_STREAM_LOCK (dec); + needs_reconfigure = gst_pad_check_reconfigure (dec->srcpad); if (buf && G_UNLIKELY (ctx->output_format_changed || (GST_AUDIO_INFO_IS_VALID (&ctx->info) - && gst_pad_check_reconfigure (dec->srcpad)))) { - if (!gst_audio_decoder_negotiate (dec)) { + && needs_reconfigure))) { + if (!gst_audio_decoder_negotiate_unlocked (dec)) { gst_pad_mark_reconfigure (dec->srcpad); if (GST_PAD_IS_FLUSHING (dec->srcpad)) ret = GST_FLOW_FLUSHING; @@ -3013,6 +3034,7 @@ GstBuffer * gst_audio_decoder_allocate_output_buffer (GstAudioDecoder * dec, gsize size) { GstBuffer *buffer = NULL; + gboolean needs_reconfigure = FALSE; g_return_val_if_fail (size > 0, NULL); @@ -3020,10 +3042,11 @@ gst_audio_decoder_allocate_output_buffer (GstAudioDecoder * dec, gsize size) GST_AUDIO_DECODER_STREAM_LOCK (dec); + needs_reconfigure = gst_pad_check_reconfigure (dec->srcpad); if (G_UNLIKELY (dec->priv->ctx.output_format_changed || (GST_AUDIO_INFO_IS_VALID (&dec->priv->ctx.info) - && gst_pad_check_reconfigure (dec->srcpad)))) { - if (!gst_audio_decoder_negotiate (dec)) { + && needs_reconfigure))) { + if (!gst_audio_decoder_negotiate_unlocked (dec)) { GST_INFO_OBJECT (dec, "Failed to negotiate, fallback allocation"); gst_pad_mark_reconfigure (dec->srcpad); goto fallback; diff --git a/gst-libs/gst/audio/gstaudioencoder.c b/gst-libs/gst/audio/gstaudioencoder.c index c124c59..52b2552 100644 --- a/gst-libs/gst/audio/gstaudioencoder.c +++ b/gst-libs/gst/audio/gstaudioencoder.c @@ -341,6 +341,7 @@ static gboolean gst_audio_encoder_decide_allocation_default (GstAudioEncoder * static gboolean gst_audio_encoder_propose_allocation_default (GstAudioEncoder * enc, GstQuery * query); static gboolean gst_audio_encoder_negotiate_default (GstAudioEncoder * enc); +static gboolean gst_audio_encoder_negotiate_unlocked (GstAudioEncoder * enc); static void gst_audio_encoder_class_init (GstAudioEncoderClass * klass) @@ -605,6 +606,7 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf, GstAudioEncoderPrivate *priv; GstAudioEncoderContext *ctx; GstFlowReturn ret = GST_FLOW_OK; + gboolean needs_reconfigure = FALSE; klass = GST_AUDIO_ENCODER_GET_CLASS (enc); priv = enc->priv; @@ -624,9 +626,9 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf, "accepting %" G_GSIZE_FORMAT " bytes encoded data as %d samples", buf ? gst_buffer_get_size (buf) : -1, samples); - if (G_UNLIKELY (ctx->output_caps_changed - || gst_pad_check_reconfigure (enc->srcpad))) { - if (!gst_audio_encoder_negotiate (enc)) { + needs_reconfigure = gst_pad_check_reconfigure (enc->srcpad); + if (G_UNLIKELY (ctx->output_caps_changed || needs_reconfigure)) { + if (!gst_audio_encoder_negotiate_unlocked (enc)) { gst_pad_mark_reconfigure (enc->srcpad); if (GST_PAD_IS_FLUSHING (enc->srcpad)) ret = GST_FLOW_FLUSHING; @@ -2619,12 +2621,26 @@ no_decide_allocation: } } +static gboolean +gst_audio_encoder_negotiate_unlocked (GstAudioEncoder * enc) +{ + GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc); + gboolean ret = TRUE; + + if (G_LIKELY (klass->negotiate)) + ret = klass->negotiate (enc); + + return ret; +} + /** * gst_audio_encoder_negotiate: * @enc: a #GstAudioEncoder * - * Negotiate with downstreame elements to currently configured #GstCaps. - * + * Negotiate with downstream elements to currently configured #GstCaps. + * Unmark GST_PAD_FLAG_NEED_RECONFIGURE in any case. But mark it again if + * negotiate fails. + * * Returns: #TRUE if the negotiation succeeded, else #FALSE. */ gboolean @@ -2638,8 +2654,12 @@ gst_audio_encoder_negotiate (GstAudioEncoder * enc) klass = GST_AUDIO_ENCODER_GET_CLASS (enc); GST_AUDIO_ENCODER_STREAM_LOCK (enc); - if (klass->negotiate) + gst_pad_check_reconfigure (enc->srcpad); + if (klass->negotiate) { ret = klass->negotiate (enc); + if (!ret) + gst_pad_mark_reconfigure (enc->srcpad); + } GST_AUDIO_ENCODER_STREAM_UNLOCK (enc); return ret; @@ -2705,6 +2725,7 @@ GstBuffer * gst_audio_encoder_allocate_output_buffer (GstAudioEncoder * enc, gsize size) { GstBuffer *buffer = NULL; + gboolean needs_reconfigure = FALSE; g_return_val_if_fail (size > 0, NULL); @@ -2712,9 +2733,10 @@ gst_audio_encoder_allocate_output_buffer (GstAudioEncoder * enc, gsize size) GST_AUDIO_ENCODER_STREAM_LOCK (enc); + needs_reconfigure = gst_pad_check_reconfigure (enc->srcpad); if (G_UNLIKELY (enc->priv->ctx.output_caps_changed || (enc->priv->ctx.caps - && gst_pad_check_reconfigure (enc->srcpad)))) { - if (!gst_audio_encoder_negotiate (enc)) { + && needs_reconfigure))) { + if (!gst_audio_encoder_negotiate_unlocked (enc)) { GST_INFO_OBJECT (enc, "Failed to negotiate, fallback allocation"); gst_pad_mark_reconfigure (enc->srcpad); goto fallback; -- 2.7.4