From 9309272309fdfc094d8ea7982a14cea06791633d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 9 Aug 2012 15:20:45 +0200 Subject: [PATCH] audioencoder: Decouple setting of output format and downstream negotiation This makes the audio encoder base class more similar to the video encoder base class. --- gst-libs/gst/audio/gstaudioencoder.c | 118 +++++++++++++++++---------- gst-libs/gst/audio/gstaudioencoder.h | 1 + 2 files changed, 77 insertions(+), 42 deletions(-) diff --git a/gst-libs/gst/audio/gstaudioencoder.c b/gst-libs/gst/audio/gstaudioencoder.c index 05ef689b61..c2718b1ce5 100644 --- a/gst-libs/gst/audio/gstaudioencoder.c +++ b/gst-libs/gst/audio/gstaudioencoder.c @@ -188,6 +188,8 @@ typedef struct _GstAudioEncoderContext GstAudioInfo info; /* output */ + GstCaps *caps; + gboolean output_caps_changed; gint frame_samples_min, frame_samples_max; gint frame_max; gint lookahead; @@ -458,6 +460,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); + gst_caps_replace (&enc->priv->ctx.caps, NULL); if (enc->priv->tags) gst_tag_list_free (enc->priv->tags); @@ -602,7 +605,7 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf, GST_FLOW_ERROR); /* subclass should know what it is producing by now */ - if (!gst_pad_has_current_caps (enc->srcpad)) + if (!ctx->caps) goto no_caps; GST_AUDIO_ENCODER_STREAM_LOCK (enc); @@ -611,13 +614,12 @@ 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 (gst_pad_check_reconfigure (enc->srcpad))) { - GstCaps *caps = gst_pad_get_current_caps (enc->srcpad); - if (!gst_audio_encoder_set_output_format (enc, caps)) { + if (G_UNLIKELY (ctx->output_caps_changed + || gst_pad_check_reconfigure (enc->srcpad))) { + if (!gst_audio_encoder_negotiate (enc)) { ret = GST_FLOW_NOT_NEGOTIATED; goto exit; } - gst_caps_unref (caps); } /* mark subclass still alive and providing */ @@ -2508,44 +2510,39 @@ gst_audio_encoder_merge_tags (GstAudioEncoder * enc, GST_OBJECT_UNLOCK (enc); } -/* - * gst_audio_encoder_set_output_format: - * @enc: a #GstAudioEncoder - * @caps: #GstCaps +/** + * gst_audio_encoder_negotiate: + * @dec: a #GstAudioEncoder * - * Configure output caps on the srcpad of @enc. + * Negotiate with downstreame elements to currently configured #GstCaps. * - * Returns: %TRUE on success. - **/ + * Returns: #TRUE if the negotiation succeeded, else #FALSE. + */ gboolean -gst_audio_encoder_set_output_format (GstAudioEncoder * enc, GstCaps * caps) +gst_audio_encoder_negotiate (GstAudioEncoder * enc) { - GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc); + GstAudioEncoderClass *klass; gboolean res = FALSE; - GstCaps *templ_caps; GstQuery *query = NULL; GstAllocator *allocator; GstAllocationParams params; + GstCaps *caps; + + g_return_val_if_fail (GST_IS_AUDIO_ENCODER (enc), FALSE); + g_return_val_if_fail (GST_IS_CAPS (enc->priv->ctx.caps), FALSE); + + klass = GST_AUDIO_ENCODER_GET_CLASS (enc); + + GST_AUDIO_ENCODER_STREAM_LOCK (enc); + + caps = enc->priv->ctx.caps; GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps); - if (!gst_caps_is_fixed (caps)) - goto refuse_caps; - - /* Only allow caps that are a subset of the template caps */ - templ_caps = gst_pad_get_pad_template_caps (enc->srcpad); - if (!gst_caps_is_subset (caps, templ_caps)) { - gst_caps_unref (templ_caps); - goto refuse_caps; - } - gst_caps_unref (templ_caps); - res = gst_pad_set_caps (enc->srcpad, caps); if (!res) goto done; - - /* clear reconfigure so we don't set caps twice */ - gst_pad_check_reconfigure (enc->srcpad); + enc->priv->ctx.output_caps_changed = FALSE; query = gst_query_new_allocation (caps, TRUE); if (!gst_pad_peer_query (enc->srcpad, query)) { @@ -2579,6 +2576,53 @@ done: if (query) gst_query_unref (query); + GST_AUDIO_ENCODER_STREAM_UNLOCK (enc); + + return res; + + /* ERRORS */ +no_decide_allocation: + { + GST_WARNING_OBJECT (enc, "Subclass failed to decide allocation"); + goto done; + } +} + +/* + * gst_audio_encoder_set_output_format: + * @enc: a #GstAudioEncoder + * @caps: #GstCaps + * + * Configure output caps on the srcpad of @enc. + * + * Returns: %TRUE on success. + **/ +gboolean +gst_audio_encoder_set_output_format (GstAudioEncoder * enc, GstCaps * caps) +{ + gboolean res = FALSE; + GstCaps *templ_caps; + + GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps); + + GST_AUDIO_ENCODER_STREAM_LOCK (enc); + if (!gst_caps_is_fixed (caps)) + goto refuse_caps; + + /* Only allow caps that are a subset of the template caps */ + templ_caps = gst_pad_get_pad_template_caps (enc->srcpad); + if (!gst_caps_is_subset (caps, templ_caps)) { + gst_caps_unref (templ_caps); + goto refuse_caps; + } + gst_caps_unref (templ_caps); + + gst_caps_replace (&enc->priv->ctx.caps, caps); + enc->priv->ctx.output_caps_changed = TRUE; + +done: + GST_AUDIO_ENCODER_STREAM_UNLOCK (enc); + return res; /* ERRORS */ @@ -2588,12 +2632,6 @@ refuse_caps: res = FALSE; goto done; } - /* Errors */ -no_decide_allocation: - { - GST_WARNING_OBJECT (enc, "Subclass failed to decide allocation"); - goto done; - } } /** @@ -2617,14 +2655,10 @@ gst_audio_encoder_allocate_output_buffer (GstAudioEncoder * enc, gsize size) GST_AUDIO_ENCODER_STREAM_LOCK (enc); - if (G_UNLIKELY (gst_pad_has_current_caps (enc->srcpad) - && gst_pad_check_reconfigure (enc->srcpad))) { - GstCaps *caps = gst_pad_get_current_caps (enc->srcpad); - if (!gst_audio_encoder_set_output_format (enc, caps)) { - gst_caps_unref (caps); + 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)) goto done; - } - gst_caps_unref (caps); } buffer = diff --git a/gst-libs/gst/audio/gstaudioencoder.h b/gst-libs/gst/audio/gstaudioencoder.h index 946f72ae3c..1f9bf2f7f8 100644 --- a/gst-libs/gst/audio/gstaudioencoder.h +++ b/gst-libs/gst/audio/gstaudioencoder.h @@ -222,6 +222,7 @@ GstCaps * gst_audio_encoder_proxy_getcaps (GstAudioEncoder * enc, gboolean gst_audio_encoder_set_output_format (GstAudioEncoder * enc, GstCaps * caps); +gboolean gst_audio_encoder_negotiate (GstAudioEncoder * enc); GstBuffer * gst_audio_encoder_allocate_output_buffer (GstAudioEncoder * encoder, gsize size);