From 6feb5eb84086f2369e0ad6112c32dc553408002c Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Fri, 6 Jul 2007 15:00:47 +0000 Subject: [PATCH] gst/law/: Fix capsnego bogosity in *law decoders. Original commit message from CVS: * gst/law/alaw-decode.c: (alawdec_sink_setcaps), (gst_alawdec_class_init), (gst_alawdec_init), (gst_alawdec_chain), (gst_alawdec_change_state): * gst/law/alaw-decode.h: * gst/law/mulaw-decode.c: (mulawdec_sink_setcaps), (gst_mulawdec_class_init), (gst_mulawdec_init), (gst_mulawdec_chain), (gst_mulawdec_change_state): * gst/law/mulaw-decode.h: Fix capsnego bogosity in *law decoders. --- ChangeLog | 12 ++++ gst/law/alaw-decode.c | 136 ++++++++++++++++------------------------- gst/law/alaw-decode.h | 1 + gst/law/mulaw-decode.c | 134 ++++++++++++++++------------------------ gst/law/mulaw-decode.h | 1 + 5 files changed, 119 insertions(+), 165 deletions(-) diff --git a/ChangeLog b/ChangeLog index b8d38f4de1..f5771fe967 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2007-07-06 Michael Smith + + * gst/law/alaw-decode.c: (alawdec_sink_setcaps), + (gst_alawdec_class_init), (gst_alawdec_init), (gst_alawdec_chain), + (gst_alawdec_change_state): + * gst/law/alaw-decode.h: + * gst/law/mulaw-decode.c: (mulawdec_sink_setcaps), + (gst_mulawdec_class_init), (gst_mulawdec_init), + (gst_mulawdec_chain), (gst_mulawdec_change_state): + * gst/law/mulaw-decode.h: + Fix capsnego bogosity in *law decoders. + 2007-07-06 Michael Smith * ext/jpeg/gstsmokeenc.c: (gst_smokeenc_init), diff --git a/gst/law/alaw-decode.c b/gst/law/alaw-decode.c index be7eed2fd2..43d127d56f 100644 --- a/gst/law/alaw-decode.c +++ b/gst/law/alaw-decode.c @@ -42,6 +42,8 @@ enum static void gst_alawdec_class_init (GstALawDecClass * klass); static void gst_alawdec_base_init (GstALawDecClass * klass); static void gst_alawdec_init (GstALawDec * alawdec); +static GstStateChangeReturn +gst_alawdec_change_state (GstElement * element, GstStateChange transition); static GstFlowReturn gst_alawdec_chain (GstPad * pad, GstBuffer * buffer); @@ -71,95 +73,30 @@ alaw_to_s16 (guint8 a_val) return ((a_val & 0x80) ? t : -t); } -static GstCaps * -alawdec_getcaps (GstPad * pad) -{ - GstALawDec *alawdec; - GstPad *otherpad; - GstCaps *base_caps, *othercaps; - - alawdec = GST_ALAWDEC (GST_PAD_PARENT (pad)); - - /* we can do what our template says */ - base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); - - if (pad == alawdec->sinkpad) { - otherpad = alawdec->srcpad; - } else { - otherpad = alawdec->sinkpad; - } - /* now intersect rate and channels from peer caps */ - othercaps = gst_pad_peer_get_caps (otherpad); - if (othercaps) { - GstStructure *structure; - const GValue *orate, *ochans; - const GValue *rate, *chans; - GValue irate = { 0 }, ichans = { - 0}; - - if (gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) - goto done; - - structure = gst_caps_get_structure (othercaps, 0); - orate = gst_structure_get_value (structure, "rate"); - ochans = gst_structure_get_value (structure, "channels"); - if (!orate || !ochans) - goto done; - - structure = gst_caps_get_structure (base_caps, 0); - rate = gst_structure_get_value (structure, "rate"); - chans = gst_structure_get_value (structure, "channels"); - if (!rate || !chans) - goto done; - - gst_value_intersect (&irate, orate, rate); - gst_value_intersect (&ichans, ochans, chans); - - /* Set the samplerate/channels on the to-be-returned caps */ - structure = gst_caps_get_structure (base_caps, 0); - gst_structure_set_value (structure, "rate", &irate); - gst_structure_set_value (structure, "channels", &ichans); - - done: - gst_caps_unref (othercaps); - } - return base_caps; -} - static gboolean -alawdec_setcaps (GstPad * pad, GstCaps * caps) +alawdec_sink_setcaps (GstPad * pad, GstCaps * caps) { GstALawDec *alawdec; - GstPad *otherpad; GstStructure *structure; - const GValue *rate, *chans; - GstCaps *base_caps; + int rate, channels; + gboolean ret; alawdec = GST_ALAWDEC (GST_PAD_PARENT (pad)); - /* take rate and channels */ structure = gst_caps_get_structure (caps, 0); - rate = gst_structure_get_value (structure, "rate"); - chans = gst_structure_get_value (structure, "channels"); - if (!rate || !chans) + ret = gst_structure_get_int (structure, "rate", &rate); + ret = ret && gst_structure_get_int (structure, "channels", &channels); + if (!ret) return FALSE; - if (pad == alawdec->srcpad) { - otherpad = alawdec->sinkpad; - } else { - otherpad = alawdec->srcpad; - } - - /* fill in values for otherpad */ - base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad)); - structure = gst_caps_get_structure (base_caps, 0); - gst_structure_set_value (structure, "rate", rate); - gst_structure_set_value (structure, "channels", chans); - - /* and set on otherpad */ - gst_pad_set_caps (otherpad, base_caps); - - gst_caps_unref (base_caps); + if (alawdec->srccaps) + gst_caps_unref (alawdec->srccaps); + alawdec->srccaps = gst_caps_new_simple ("audio/x-raw-int", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "endianness", G_TYPE_INT, G_BYTE_ORDER, + "signed", G_TYPE_BOOLEAN, TRUE, + "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, channels, NULL); return TRUE; } @@ -207,21 +144,23 @@ gst_alawdec_base_init (GstALawDecClass * klass) static void gst_alawdec_class_init (GstALawDecClass * klass) { + GstElementClass *element_class = (GstElementClass *) klass; + parent_class = g_type_class_peek_parent (klass); + + element_class->change_state = GST_DEBUG_FUNCPTR (gst_alawdec_change_state); } static void gst_alawdec_init (GstALawDec * alawdec) { alawdec->sinkpad = gst_pad_new_from_template (alawdec_sink_template, "sink"); - gst_pad_set_setcaps_function (alawdec->sinkpad, alawdec_setcaps); - gst_pad_set_getcaps_function (alawdec->sinkpad, alawdec_getcaps); + gst_pad_set_setcaps_function (alawdec->sinkpad, alawdec_sink_setcaps); gst_pad_set_chain_function (alawdec->sinkpad, gst_alawdec_chain); gst_element_add_pad (GST_ELEMENT (alawdec), alawdec->sinkpad); alawdec->srcpad = gst_pad_new_from_template (alawdec_src_template, "src"); - gst_pad_set_setcaps_function (alawdec->srcpad, alawdec_setcaps); - gst_pad_set_getcaps_function (alawdec->srcpad, alawdec_getcaps); + gst_pad_use_fixed_caps (alawdec->srcpad); gst_element_add_pad (GST_ELEMENT (alawdec), alawdec->srcpad); } @@ -250,7 +189,7 @@ gst_alawdec_chain (GstPad * pad, GstBuffer * buffer) GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer); GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer); - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (alawdec->srcpad)); + gst_buffer_set_caps (outbuf, alawdec->srccaps); for (i = 0; i < alaw_size; i++) { linear_data[i] = alaw_to_s16 (alaw_data[i]); @@ -263,3 +202,32 @@ gst_alawdec_chain (GstPad * pad, GstBuffer * buffer) return ret; } + +static GstStateChangeReturn +gst_alawdec_change_state (GstElement * element, GstStateChange transition) +{ + GstStateChangeReturn ret; + GstALawDec *dec = GST_ALAWDEC (element); + + switch (transition) { + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + if (ret != GST_STATE_CHANGE_SUCCESS) + return ret; + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + if (dec->srccaps) { + gst_caps_unref (dec->srccaps); + dec->srccaps = NULL; + } + break; + default: + break; + } + + return ret; +} diff --git a/gst/law/alaw-decode.h b/gst/law/alaw-decode.h index 45f608101a..108b81684f 100644 --- a/gst/law/alaw-decode.h +++ b/gst/law/alaw-decode.h @@ -43,6 +43,7 @@ struct _GstALawDec { GstElement element; GstPad *sinkpad,*srcpad; + GstCaps *srccaps; }; struct _GstALawDecClass { diff --git a/gst/law/mulaw-decode.c b/gst/law/mulaw-decode.c index 786a43f9e1..20ccb5230a 100644 --- a/gst/law/mulaw-decode.c +++ b/gst/law/mulaw-decode.c @@ -41,96 +41,37 @@ enum static void gst_mulawdec_class_init (GstMuLawDecClass * klass); static void gst_mulawdec_base_init (GstMuLawDecClass * klass); static void gst_mulawdec_init (GstMuLawDec * mulawdec); +static GstStateChangeReturn +gst_mulawdec_change_state (GstElement * element, GstStateChange transition); static GstFlowReturn gst_mulawdec_chain (GstPad * pad, GstBuffer * buffer); static GstElementClass *parent_class = NULL; -/*static guint gst_stereo_signals[LAST_SIGNAL] = { 0 };*/ - -static GstCaps * -mulawdec_getcaps (GstPad * pad) -{ - GstMuLawDec *mulawdec; - GstPad *otherpad; - GstCaps *base_caps, *othercaps; - - mulawdec = GST_MULAWDEC (GST_PAD_PARENT (pad)); - - base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); - - if (pad == mulawdec->sinkpad) { - otherpad = mulawdec->srcpad; - } else { - otherpad = mulawdec->sinkpad; - } - othercaps = gst_pad_peer_get_caps (otherpad); - if (othercaps) { - GstStructure *structure; - const GValue *orate, *ochans; - const GValue *rate, *chans; - GValue irate = { 0 }, ichans = { - 0}; - - if (gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) - goto done; - - structure = gst_caps_get_structure (othercaps, 0); - orate = gst_structure_get_value (structure, "rate"); - ochans = gst_structure_get_value (structure, "channels"); - if (!orate || !ochans) - goto done; - - structure = gst_caps_get_structure (base_caps, 0); - rate = gst_structure_get_value (structure, "rate"); - chans = gst_structure_get_value (structure, "channels"); - if (!rate || !chans) - goto done; - - gst_value_intersect (&irate, orate, rate); - gst_value_intersect (&ichans, ochans, chans); - - /* Set the samplerate/channels on the to-be-returned caps */ - structure = gst_caps_get_structure (base_caps, 0); - gst_structure_set_value (structure, "rate", &irate); - gst_structure_set_value (structure, "channels", &ichans); - - done: - gst_caps_unref (othercaps); - } - return base_caps; -} - static gboolean -mulawdec_setcaps (GstPad * pad, GstCaps * caps) +mulawdec_sink_setcaps (GstPad * pad, GstCaps * caps) { GstMuLawDec *mulawdec; - GstPad *otherpad; GstStructure *structure; - const GValue *rate, *chans; - GstCaps *base_caps; + int rate, channels; + gboolean ret; mulawdec = GST_MULAWDEC (GST_PAD_PARENT (pad)); structure = gst_caps_get_structure (caps, 0); - rate = gst_structure_get_value (structure, "rate"); - chans = gst_structure_get_value (structure, "channels"); - if (!rate || !chans) + ret = gst_structure_get_int (structure, "rate", &rate); + ret = ret && gst_structure_get_int (structure, "channels", &channels); + if (!ret) return FALSE; - if (pad == mulawdec->srcpad) { - otherpad = mulawdec->sinkpad; - } else { - otherpad = mulawdec->srcpad; - } - - base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad)); - structure = gst_caps_get_structure (base_caps, 0); - gst_structure_set_value (structure, "rate", rate); - gst_structure_set_value (structure, "channels", chans); - - gst_pad_set_caps (otherpad, base_caps); - gst_caps_unref (base_caps); + if (mulawdec->srccaps) + gst_caps_unref (mulawdec->srccaps); + mulawdec->srccaps = gst_caps_new_simple ("audio/x-raw-int", + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "endianness", G_TYPE_INT, G_BYTE_ORDER, + "signed", G_TYPE_BOOLEAN, TRUE, + "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, channels, NULL); return TRUE; } @@ -178,7 +119,11 @@ gst_mulawdec_base_init (GstMuLawDecClass * klass) static void gst_mulawdec_class_init (GstMuLawDecClass * klass) { - parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + GstElementClass *element_class = (GstElementClass *) klass; + + parent_class = g_type_class_peek_parent (klass); + + element_class->change_state = GST_DEBUG_FUNCPTR (gst_mulawdec_change_state); } static void @@ -186,14 +131,12 @@ gst_mulawdec_init (GstMuLawDec * mulawdec) { mulawdec->sinkpad = gst_pad_new_from_template (mulawdec_sink_template, "sink"); - gst_pad_set_setcaps_function (mulawdec->sinkpad, mulawdec_setcaps); - gst_pad_set_getcaps_function (mulawdec->sinkpad, mulawdec_getcaps); + gst_pad_set_setcaps_function (mulawdec->sinkpad, mulawdec_sink_setcaps); gst_pad_set_chain_function (mulawdec->sinkpad, gst_mulawdec_chain); gst_element_add_pad (GST_ELEMENT (mulawdec), mulawdec->sinkpad); mulawdec->srcpad = gst_pad_new_from_template (mulawdec_src_template, "src"); - gst_pad_set_setcaps_function (mulawdec->srcpad, mulawdec_setcaps); - gst_pad_set_getcaps_function (mulawdec->srcpad, mulawdec_getcaps); + gst_pad_use_fixed_caps (mulawdec->srcpad); gst_element_add_pad (GST_ELEMENT (mulawdec), mulawdec->srcpad); } @@ -221,7 +164,7 @@ gst_mulawdec_chain (GstPad * pad, GstBuffer * buffer) GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer); GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer); - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (mulawdec->srcpad)); + gst_buffer_set_caps (outbuf, mulawdec->srccaps); mulaw_decode (mulaw_data, linear_data, mulaw_size); @@ -233,3 +176,32 @@ gst_mulawdec_chain (GstPad * pad, GstBuffer * buffer) return ret; } + +static GstStateChangeReturn +gst_mulawdec_change_state (GstElement * element, GstStateChange transition) +{ + GstStateChangeReturn ret; + GstMuLawDec *dec = GST_MULAWDEC (element); + + switch (transition) { + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + if (ret != GST_STATE_CHANGE_SUCCESS) + return ret; + + switch (transition) { + case GST_STATE_CHANGE_PAUSED_TO_READY: + if (dec->srccaps) { + gst_caps_unref (dec->srccaps); + dec->srccaps = NULL; + } + break; + default: + break; + } + + return ret; +} diff --git a/gst/law/mulaw-decode.h b/gst/law/mulaw-decode.h index 6ee85b94c3..ee1a14d436 100644 --- a/gst/law/mulaw-decode.h +++ b/gst/law/mulaw-decode.h @@ -42,6 +42,7 @@ struct _GstMuLawDec { GstElement element; GstPad *sinkpad,*srcpad; + GstCaps *srccaps; }; struct _GstMuLawDecClass {