From 7417ad6d5feb74696b030a179f390656ecaf7ac7 Mon Sep 17 00:00:00 2001 From: Tim-Philipp Müller Date: Thu, 3 Feb 2011 18:18:35 +0000 Subject: lamemp3enc: implement sinkpad get_caps() function to proxy rate and channels restrictions from downstream The element downstream of mp3enc might only accept certain sample rates or channels, make sure we relay any restrictions that do exist to upstream when it does a get_caps() on the sink pad. That way upstream elements like audioresample or audioconvert can pick a sample rate / channel configuration that will be accepted, instead of just negotiating to the highest, which might then be rejected. https://bugzilla.gnome.org/show_bug.cgi?id=641151 --- ext/lame/gstlamemp3enc.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/ext/lame/gstlamemp3enc.c b/ext/lame/gstlamemp3enc.c index 7ad7829e..21bc9563 100644 --- a/ext/lame/gstlamemp3enc.c +++ b/ext/lame/gstlamemp3enc.c @@ -389,6 +389,61 @@ setup_failed: } } +static GstCaps * +gst_lamemp3enc_sink_getcaps (GstPad * pad) +{ + const GstCaps *templ_caps; + GstLameMP3Enc *lame; + GstCaps *allowed = NULL; + GstCaps *caps, *filter_caps; + gint i, j; + + lame = GST_LAMEMP3ENC (gst_pad_get_parent (pad)); + + /* we want to be able to communicate to upstream elements like audioconvert + * and audioresample any rate/channel restrictions downstream (e.g. muxer + * only accepting certain sample rates) */ + templ_caps = gst_pad_get_pad_template_caps (pad); + allowed = gst_pad_get_allowed_caps (lame->srcpad); + if (!allowed || gst_caps_is_empty (allowed) || gst_caps_is_any (allowed)) { + caps = gst_caps_copy (templ_caps); + goto done; + } + + filter_caps = gst_caps_new_empty (); + + for (i = 0; i < gst_caps_get_size (templ_caps); i++) { + GQuark q_name; + + q_name = gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i)); + + /* pick rate + channel fields from allowed caps */ + for (j = 0; j < gst_caps_get_size (allowed); j++) { + const GstStructure *allowed_s = gst_caps_get_structure (allowed, j); + const GValue *val; + GstStructure *s; + + s = gst_structure_id_empty_new (q_name); + if ((val = gst_structure_get_value (allowed_s, "rate"))) + gst_structure_set_value (s, "rate", val); + if ((val = gst_structure_get_value (allowed_s, "channels"))) + gst_structure_set_value (s, "channels", val); + + gst_caps_merge_structure (filter_caps, s); + } + } + + caps = gst_caps_intersect (filter_caps, templ_caps); + gst_caps_unref (filter_caps); + +done: + + gst_caps_replace (&allowed, NULL); + gst_object_unref (lame); + + return caps; +} + static gint64 gst_lamemp3enc_get_latency (GstLameMP3Enc * lame) { @@ -453,6 +508,8 @@ gst_lamemp3enc_init (GstLameMP3Enc * lame) GST_DEBUG_FUNCPTR (gst_lamemp3enc_chain)); gst_pad_set_setcaps_function (lame->sinkpad, GST_DEBUG_FUNCPTR (gst_lamemp3enc_sink_setcaps)); + gst_pad_set_getcaps_function (lame->sinkpad, + GST_DEBUG_FUNCPTR (gst_lamemp3enc_sink_getcaps)); gst_element_add_pad (GST_ELEMENT (lame), lame->sinkpad); lame->srcpad = -- cgit v1.2.3