From e0268c02abf58fb09474acfac779cd830a665bdd Mon Sep 17 00:00:00 2001 From: Tomasz Andrzejak Date: Tue, 13 Nov 2018 17:40:23 +0100 Subject: [PATCH] audiodecoder: add API for setting caps on the source pad This patch adds API in the audio decoder base class for setting the arbitrary caps on the source pad. Previously only caps converted from audio info were possible. This is particularly useful when subclass wants to set caps features for audio decoder producing metadata. --- docs/libs/gst-plugins-base-libs-sections.txt | 1 + gst-libs/gst/audio/gstaudiodecoder.c | 66 +++++++++++++++----- gst-libs/gst/audio/gstaudiodecoder.h | 3 + 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 6e3204a277..1e5a9538d5 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -393,6 +393,7 @@ GST_AUDIO_DECODER_STREAM_LOCK GST_AUDIO_DECODER_STREAM_UNLOCK gst_audio_decoder_finish_frame gst_audio_decoder_set_output_format +gst_audio_decoder_set_output_caps gst_audio_decoder_negotiate gst_audio_decoder_allocate_output_buffer gst_audio_decoder_get_allocator diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c index 00dd092dc6..7900be63b0 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.c +++ b/gst-libs/gst/audio/gstaudiodecoder.c @@ -158,6 +158,7 @@ typedef struct _GstAudioDecoderContext /* (output) audio format */ GstAudioInfo info; + GstCaps *caps; gboolean output_format_changed; /* parsing state */ @@ -513,6 +514,7 @@ gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full) GST_OBJECT_LOCK (dec); gst_caps_replace (&dec->priv->ctx.input_caps, NULL); + gst_caps_replace (&dec->priv->ctx.caps, NULL); gst_caps_replace (&dec->priv->ctx.allocation_caps, NULL); memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx)); @@ -625,10 +627,11 @@ gst_audio_decoder_negotiate_default (GstAudioDecoder * dec) g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE); g_return_val_if_fail (GST_AUDIO_INFO_IS_VALID (&dec->priv->ctx.info), FALSE); + g_return_val_if_fail (GST_IS_CAPS (dec->priv->ctx.caps), FALSE); klass = GST_AUDIO_DECODER_GET_CLASS (dec); - caps = gst_audio_info_to_caps (&dec->priv->ctx.info); + caps = dec->priv->ctx.caps; if (dec->priv->ctx.allocation_caps == NULL) dec->priv->ctx.allocation_caps = gst_caps_ref (caps); @@ -697,7 +700,6 @@ done: if (query) gst_query_unref (query); - gst_caps_unref (caps); return res; @@ -767,21 +769,58 @@ gst_audio_decoder_set_output_format (GstAudioDecoder * dec, const GstAudioInfo * info) { gboolean res = TRUE; - guint old_rate; GstCaps *caps = NULL; - GstCaps *templ_caps; g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE); g_return_val_if_fail (GST_AUDIO_INFO_IS_VALID (info), FALSE); - GST_DEBUG_OBJECT (dec, "Setting output format"); - - GST_AUDIO_DECODER_STREAM_LOCK (dec); - /* If the audio info can't be converted to caps, * it was invalid */ caps = gst_audio_info_to_caps (info); - if (!caps) + if (!caps) { + GST_WARNING_OBJECT (dec, "invalid output format"); + return FALSE; + } + + res = gst_audio_decoder_set_output_caps (dec, caps); + gst_caps_unref (caps); + + return res; +} + +/** + * gst_audio_decoder_set_output_caps: + * @dec: a #GstAudioDecoder + * @caps: (transfer none): (fixed) #GstCaps + * + * Configure output caps on the srcpad of @dec. Similar to + * gst_audio_decoder_set_output_format(), but allows subclasses to specify + * output caps that can't be expressed via #GstAudioInfo e.g. caps that have + * caps features. + * + * Returns: %TRUE on success. + * + * Since: 1.16 + **/ +gboolean +gst_audio_decoder_set_output_caps (GstAudioDecoder * dec, GstCaps * caps) +{ + gboolean res = TRUE; + guint old_rate; + GstCaps *templ_caps; + GstAudioInfo info; + + g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE); + + GST_DEBUG_OBJECT (dec, "Setting srcpad caps %" GST_PTR_FORMAT, caps); + + GST_AUDIO_DECODER_STREAM_LOCK (dec); + + if (!gst_caps_is_fixed (caps)) + goto refuse_caps; + + /* check if caps can be parsed */ + if (!gst_audio_info_from_caps (&info, caps)) goto refuse_caps; /* Only allow caps that are a subset of the template caps */ @@ -804,16 +843,15 @@ gst_audio_decoder_set_output_format (GstAudioDecoder * dec, /* copy the GstAudioInfo */ GST_OBJECT_LOCK (dec); - dec->priv->ctx.info = *info; + dec->priv->ctx.info = info; GST_OBJECT_UNLOCK (dec); + + gst_caps_replace (&dec->priv->ctx.caps, caps); dec->priv->ctx.output_format_changed = TRUE; done: GST_AUDIO_DECODER_STREAM_UNLOCK (dec); - if (caps) - gst_caps_unref (caps); - return res; /* ERRORS */ @@ -882,7 +920,7 @@ gst_audio_decoder_setup (GstAudioDecoder * dec) gst_query_unref (query); /* normalize to bool */ - dec->priv->agg = ! !res; + dec->priv->agg = !!res; } static GstFlowReturn diff --git a/gst-libs/gst/audio/gstaudiodecoder.h b/gst-libs/gst/audio/gstaudiodecoder.h index f03d9ac7db..19faa7a1c4 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.h +++ b/gst-libs/gst/audio/gstaudiodecoder.h @@ -322,6 +322,9 @@ gboolean gst_audio_decoder_set_output_format (GstAudioDecoder * dec const GstAudioInfo * info); GST_AUDIO_API +gboolean gst_audio_decoder_set_output_caps (GstAudioDecoder * dec, + GstCaps * caps); +GST_AUDIO_API GstCaps * gst_audio_decoder_proxy_getcaps (GstAudioDecoder * decoder, GstCaps * caps, GstCaps * filter);