From 37c491510995e77b3ab4f340b0edcd4f7aff33ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Fri, 1 Apr 2016 12:25:14 +0200 Subject: [PATCH] libs: audio: split allocation query caps and pad caps Since the allocation query caps contains memory size and the pad's caps contains the display size, an audio encoder or decoder might need to allocate a different buffer size than the size negotiated in the caps. This patch splits this logic distinction for audiodecoder and audioencoder. Thus the user, if needs a different allocation caps, should set it through gst_audio_{encoder,decoder}_set_allocation_cap() before calling the negotiate() vmethod. Otherwise the allocation_caps will be the same as the caps in the src pad. https://bugzilla.gnome.org/show_bug.cgi?id=764421 --- gst-libs/gst/audio/gstaudiodecoder.c | 27 ++++++++++++++++++++++++++- gst-libs/gst/audio/gstaudiodecoder.h | 2 ++ gst-libs/gst/audio/gstaudioencoder.c | 27 ++++++++++++++++++++++++++- gst-libs/gst/audio/gstaudioencoder.h | 3 +++ 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c index e65b76c2bd..4a43c94dcc 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.c +++ b/gst-libs/gst/audio/gstaudiodecoder.c @@ -203,6 +203,7 @@ typedef struct _GstAudioDecoderContext gboolean do_plc; gboolean do_estimate_rate; gint max_errors; + GstCaps *allocation_caps; /* MT-protected (with LOCK) */ GstClockTime min_latency; GstClockTime max_latency; @@ -525,6 +526,7 @@ gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full) gst_object_unref (dec->priv->ctx.allocator); gst_caps_replace (&dec->priv->ctx.input_caps, NULL); + gst_caps_replace (&dec->priv->ctx.allocation_caps, NULL); memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx)); @@ -639,6 +641,8 @@ gst_audio_decoder_negotiate_default (GstAudioDecoder * dec) klass = GST_AUDIO_DECODER_GET_CLASS (dec); caps = gst_audio_info_to_caps (&dec->priv->ctx.info); + if (dec->priv->ctx.allocation_caps == NULL) + dec->priv->ctx.allocation_caps = gst_caps_ref (caps); GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps); @@ -673,7 +677,7 @@ gst_audio_decoder_negotiate_default (GstAudioDecoder * dec) goto done; dec->priv->ctx.output_format_changed = FALSE; - query = gst_query_new_allocation (caps, TRUE); + query = gst_query_new_allocation (dec->priv->ctx.allocation_caps, TRUE); if (!gst_pad_peer_query (dec->srcpad, query)) { GST_DEBUG_OBJECT (dec, "didn't get downstream ALLOCATION hints"); } @@ -3265,6 +3269,27 @@ gst_audio_decoder_get_parse_state (GstAudioDecoder * dec, *eos = dec->priv->ctx.eos; } +/** + * gst_audio_decoder_set_allocation_caps: + * @dec: a #GstAudioDecoder + * @allocation_caps: (allow-none): a #GstCaps or %NULL + * + * Sets a caps in allocation query which are different from the set + * pad's caps. Use this function before calling + * gst_audio_decoder_negotiate(). Setting to %NULL the allocation + * query will use the caps from the pad. + * + * Since: 1.10 + */ +void +gst_audio_decoder_set_allocation_caps (GstAudioDecoder * dec, + GstCaps * allocation_caps) +{ + g_return_if_fail (GST_IS_AUDIO_DECODER (dec)); + + gst_caps_replace (&dec->priv->ctx.allocation_caps, allocation_caps); +} + /** * gst_audio_decoder_set_plc: * @dec: a #GstAudioDecoder diff --git a/gst-libs/gst/audio/gstaudiodecoder.h b/gst-libs/gst/audio/gstaudiodecoder.h index f36416186b..71e0ce7921 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.h +++ b/gst-libs/gst/audio/gstaudiodecoder.h @@ -360,6 +360,8 @@ void gst_audio_decoder_get_parse_state (GstAudioDecoder * dec, gboolean * sync, gboolean * eos); +void gst_audio_decoder_set_allocation_caps (GstAudioDecoder * dec, + GstCaps * allocation_caps); /* object properties */ void gst_audio_decoder_set_plc (GstAudioDecoder * dec, diff --git a/gst-libs/gst/audio/gstaudioencoder.c b/gst-libs/gst/audio/gstaudioencoder.c index ac751a85b9..50ed79cae4 100644 --- a/gst-libs/gst/audio/gstaudioencoder.c +++ b/gst-libs/gst/audio/gstaudioencoder.c @@ -194,6 +194,7 @@ typedef struct _GstAudioEncoderContext /* output */ GstCaps *caps; + GstCaps *allocation_caps; gboolean output_caps_changed; gint frame_samples_min, frame_samples_max; gint frame_max; @@ -492,6 +493,7 @@ gst_audio_encoder_reset (GstAudioEncoder * enc, gboolean full) gst_caps_replace (&enc->priv->ctx.input_caps, NULL); gst_caps_replace (&enc->priv->ctx.caps, NULL); + gst_caps_replace (&enc->priv->ctx.allocation_caps, NULL); memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx)); gst_audio_info_init (&enc->priv->ctx.info); @@ -2386,6 +2388,27 @@ gst_audio_encoder_set_headers (GstAudioEncoder * enc, GList * headers) enc->priv->ctx.new_headers = TRUE; } +/** + * gst_audio_encoder_set_allocation_caps: + * @enc: a #GstAudioEncoder + * @allocation_caps: (allow-none): a #GstCaps or %NULL + * + * Sets a caps in allocation query which are different from the set + * pad's caps. Use this function before calling + * gst_audio_encoder_negotiate(). Setting to %NULL the allocation + * query will use the caps from the pad. + * + * Since: 1.10 + */ +void +gst_audio_encoder_set_allocation_caps (GstAudioEncoder * enc, + GstCaps * allocation_caps) +{ + g_return_if_fail (GST_IS_AUDIO_ENCODER (enc)); + + gst_caps_replace (&enc->priv->ctx.allocation_caps, allocation_caps); +} + /** * gst_audio_encoder_set_mark_granule: * @enc: a #GstAudioEncoder @@ -2717,6 +2740,8 @@ gst_audio_encoder_negotiate_default (GstAudioEncoder * enc) klass = GST_AUDIO_ENCODER_GET_CLASS (enc); caps = enc->priv->ctx.caps; + if (enc->priv->ctx.allocation_caps == NULL) + enc->priv->ctx.allocation_caps = gst_caps_ref (caps); GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps); @@ -2751,7 +2776,7 @@ gst_audio_encoder_negotiate_default (GstAudioEncoder * enc) goto done; enc->priv->ctx.output_caps_changed = FALSE; - query = gst_query_new_allocation (caps, TRUE); + query = gst_query_new_allocation (enc->priv->ctx.allocation_caps, TRUE); if (!gst_pad_peer_query (enc->srcpad, query)) { GST_DEBUG_OBJECT (enc, "didn't get downstream ALLOCATION hints"); } diff --git a/gst-libs/gst/audio/gstaudioencoder.h b/gst-libs/gst/audio/gstaudioencoder.h index 47ca340bfc..a186bd582b 100644 --- a/gst-libs/gst/audio/gstaudioencoder.h +++ b/gst-libs/gst/audio/gstaudioencoder.h @@ -295,6 +295,9 @@ void gst_audio_encoder_set_latency (GstAudioEncoder * enc, void gst_audio_encoder_set_headers (GstAudioEncoder * enc, GList * headers); +void gst_audio_encoder_set_allocation_caps (GstAudioEncoder * enc, + GstCaps * allocation_caps); + /* object properties */ void gst_audio_encoder_set_mark_granule (GstAudioEncoder * enc,