mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 12:41:05 +00:00
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.
This commit is contained in:
parent
720e9ec2cc
commit
e0268c02ab
3 changed files with 56 additions and 14 deletions
|
@ -393,6 +393,7 @@ GST_AUDIO_DECODER_STREAM_LOCK
|
||||||
GST_AUDIO_DECODER_STREAM_UNLOCK
|
GST_AUDIO_DECODER_STREAM_UNLOCK
|
||||||
gst_audio_decoder_finish_frame
|
gst_audio_decoder_finish_frame
|
||||||
gst_audio_decoder_set_output_format
|
gst_audio_decoder_set_output_format
|
||||||
|
gst_audio_decoder_set_output_caps
|
||||||
gst_audio_decoder_negotiate
|
gst_audio_decoder_negotiate
|
||||||
gst_audio_decoder_allocate_output_buffer
|
gst_audio_decoder_allocate_output_buffer
|
||||||
gst_audio_decoder_get_allocator
|
gst_audio_decoder_get_allocator
|
||||||
|
|
|
@ -158,6 +158,7 @@ typedef struct _GstAudioDecoderContext
|
||||||
|
|
||||||
/* (output) audio format */
|
/* (output) audio format */
|
||||||
GstAudioInfo info;
|
GstAudioInfo info;
|
||||||
|
GstCaps *caps;
|
||||||
gboolean output_format_changed;
|
gboolean output_format_changed;
|
||||||
|
|
||||||
/* parsing state */
|
/* parsing state */
|
||||||
|
@ -513,6 +514,7 @@ gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full)
|
||||||
|
|
||||||
GST_OBJECT_LOCK (dec);
|
GST_OBJECT_LOCK (dec);
|
||||||
gst_caps_replace (&dec->priv->ctx.input_caps, NULL);
|
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);
|
gst_caps_replace (&dec->priv->ctx.allocation_caps, NULL);
|
||||||
|
|
||||||
memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx));
|
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_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_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);
|
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)
|
if (dec->priv->ctx.allocation_caps == NULL)
|
||||||
dec->priv->ctx.allocation_caps = gst_caps_ref (caps);
|
dec->priv->ctx.allocation_caps = gst_caps_ref (caps);
|
||||||
|
|
||||||
|
@ -697,7 +700,6 @@ done:
|
||||||
|
|
||||||
if (query)
|
if (query)
|
||||||
gst_query_unref (query);
|
gst_query_unref (query);
|
||||||
gst_caps_unref (caps);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
@ -767,21 +769,58 @@ gst_audio_decoder_set_output_format (GstAudioDecoder * dec,
|
||||||
const GstAudioInfo * info)
|
const GstAudioInfo * info)
|
||||||
{
|
{
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
guint old_rate;
|
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
GstCaps *templ_caps;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);
|
g_return_val_if_fail (GST_IS_AUDIO_DECODER (dec), FALSE);
|
||||||
g_return_val_if_fail (GST_AUDIO_INFO_IS_VALID (info), 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,
|
/* If the audio info can't be converted to caps,
|
||||||
* it was invalid */
|
* it was invalid */
|
||||||
caps = gst_audio_info_to_caps (info);
|
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;
|
goto refuse_caps;
|
||||||
|
|
||||||
/* Only allow caps that are a subset of the template 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 */
|
/* copy the GstAudioInfo */
|
||||||
GST_OBJECT_LOCK (dec);
|
GST_OBJECT_LOCK (dec);
|
||||||
dec->priv->ctx.info = *info;
|
dec->priv->ctx.info = info;
|
||||||
GST_OBJECT_UNLOCK (dec);
|
GST_OBJECT_UNLOCK (dec);
|
||||||
|
|
||||||
|
gst_caps_replace (&dec->priv->ctx.caps, caps);
|
||||||
dec->priv->ctx.output_format_changed = TRUE;
|
dec->priv->ctx.output_format_changed = TRUE;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
|
GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
|
||||||
|
|
||||||
if (caps)
|
|
||||||
gst_caps_unref (caps);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
|
|
@ -322,6 +322,9 @@ gboolean gst_audio_decoder_set_output_format (GstAudioDecoder * dec
|
||||||
const GstAudioInfo * info);
|
const GstAudioInfo * info);
|
||||||
|
|
||||||
GST_AUDIO_API
|
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 * gst_audio_decoder_proxy_getcaps (GstAudioDecoder * decoder,
|
||||||
GstCaps * caps,
|
GstCaps * caps,
|
||||||
GstCaps * filter);
|
GstCaps * filter);
|
||||||
|
|
Loading…
Reference in a new issue