summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim.muller@collabora.co.uk>2011-02-03 18:18:35 (GMT)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>2011-02-03 18:27:05 (GMT)
commit7417ad6d5feb74696b030a179f390656ecaf7ac7 (patch)
tree167679f2f0a5e1988c7586daa33b3b2583cc4040
parent67f754a9ea60052a023dfb2a3cc919bda80dbea8 (diff)
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
-rw-r--r--ext/lame/gstlamemp3enc.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/ext/lame/gstlamemp3enc.c b/ext/lame/gstlamemp3enc.c
index 7ad7829..21bc956 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 =