From 87ffc58ab95e2a3f22a46158065692fc674e6d67 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 21 Mar 2004 02:54:37 +0000 Subject: [PATCH] gst/audioconvert/gstaudioconvert.c: add a fixation function that pretty much does the right thing (fixes #137556) Original commit message from CVS: * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_link), (_fixate_caps_to_int), (gst_audio_convert_fixate): add a fixation function that pretty much does the right thing (fixes #137556) --- ChangeLog | 7 ++++ gst/audioconvert/gstaudioconvert.c | 79 +++++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2316b43..df982d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-03-21 Benjamin Otte + + * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_link), + (_fixate_caps_to_int), (gst_audio_convert_fixate): + add a fixation function that pretty much does the right thing (fixes + #137556) + 2004-03-20 David I. Lehn * configure.ac: GST_PACKAGE default: s/GStreamer/GStreamer Plugins/ diff --git a/gst/audioconvert/gstaudioconvert.c b/gst/audioconvert/gstaudioconvert.c index 7df5825..2be4df1 100644 --- a/gst/audioconvert/gstaudioconvert.c +++ b/gst/audioconvert/gstaudioconvert.c @@ -109,6 +109,7 @@ static void gst_audio_convert_init (GstAudioConvert * audio_convert); static void gst_audio_convert_chain (GstPad * pad, GstData * _data); static GstPadLinkReturn gst_audio_convert_link (GstPad * pad, const GstCaps * caps); +static GstCaps *gst_audio_convert_fixate (GstPad * pad, const GstCaps * caps); static GstCaps *gst_audio_convert_getcaps (GstPad * pad); static GstElementStateReturn gst_audio_convert_change_state (GstElement * element); @@ -202,6 +203,7 @@ gst_audio_convert_init (GstAudioConvert * this) (&gst_audio_convert_sink_template), "sink"); gst_pad_set_getcaps_function (this->sink, gst_audio_convert_getcaps); gst_pad_set_link_function (this->sink, gst_audio_convert_link); + gst_pad_set_fixate_function (this->sink, gst_audio_convert_fixate); gst_element_add_pad (GST_ELEMENT (this), this->sink); /* srcpad */ @@ -210,6 +212,7 @@ gst_audio_convert_init (GstAudioConvert * this) (&gst_audio_convert_src_template), "src"); gst_pad_set_getcaps_function (this->src, gst_audio_convert_getcaps); gst_pad_set_link_function (this->src, gst_audio_convert_link); + gst_pad_set_fixate_function (this->src, gst_audio_convert_fixate); gst_element_add_pad (GST_ELEMENT (this), this->src); gst_pad_set_chain_function (this->sink, gst_audio_convert_chain); @@ -386,6 +389,12 @@ gst_audio_convert_link (GstPad * pad, const GstCaps * caps) } } } + if (this->sink == pad) { + this->sinkcaps = ac_caps; + } else { + this->srccaps = ac_caps; + } + GST_LOG_OBJECT (this, "trying to set caps to %" GST_PTR_FORMAT, othercaps); ret = gst_pad_try_set_caps_nonfixed (otherpad, othercaps); gst_caps_free (othercaps); if (ret < GST_PAD_LINK_OK) @@ -406,11 +415,77 @@ gst_audio_convert_link (GstPad * pad, const GstCaps * caps) this->sinkcaps = other_ac_caps; } - GST_DEBUG ("negotiated pad to %" GST_PTR_FORMAT, caps); - GST_DEBUG ("negotiated otherpad to %" GST_PTR_FORMAT, othercaps); + GST_DEBUG_OBJECT (this, "negotiated pad to %" GST_PTR_FORMAT, caps); + GST_DEBUG_OBJECT (this, "negotiated otherpad to %" GST_PTR_FORMAT, othercaps); return GST_PAD_LINK_OK; } +gboolean +_fixate_caps_to_int (GstCaps ** caps, const gchar * field, gint value) +{ + GstCaps *try, *intersection; + gboolean ret = FALSE; + guint i; + + try = + gst_caps_new_simple ("audio/x-raw-int", field, GST_TYPE_INT_RANGE, + G_MININT, value - 1, NULL), gst_caps_append (try, + gst_caps_new_simple ("audio/x-raw-float", field, GST_TYPE_INT_RANGE, + G_MININT, value - 1, NULL)); + intersection = gst_caps_intersect (*caps, try); + if (!gst_caps_is_empty (intersection)) { + gst_caps_free (try); + try = + gst_caps_new_simple ("audio/x-raw-int", field, GST_TYPE_INT_RANGE, + value, G_MAXINT, NULL), gst_caps_append (try, + gst_caps_new_simple ("audio/x-raw-float", field, GST_TYPE_INT_RANGE, + value, G_MAXINT, NULL)); + gst_caps_free (intersection); + intersection = gst_caps_intersect (*caps, try); + if (!gst_caps_is_empty (intersection)) { + gst_caps_free (*caps); + *caps = intersection; + ret = TRUE; + } else { + gst_caps_free (intersection); + } + } + for (i = 0; i < gst_caps_get_size (*caps); i++) { + GstStructure *structure = gst_caps_get_structure (*caps, i); + + if (gst_structure_has_field (structure, field)) + ret |= + gst_caps_structure_fixate_field_nearest_int (structure, field, value); + } + return ret; +} + +static GstCaps * +gst_audio_convert_fixate (GstPad * pad, const GstCaps * caps) +{ + GstAudioConvert *this = + GST_AUDIO_CONVERT (gst_object_get_parent (GST_OBJECT (pad))); + GstPad *otherpad = (pad == this->sink ? this->src : this->sink); + GstAudioConvertCaps ac_caps = + (pad == this->sink ? this->srccaps : this->sinkcaps); + GstCaps *copy; + + /* only fixate when we're proxying, so we don't fixate to some crap the other side doesn't want */ + if (!GST_PAD_IS_NEGOTIATING (otherpad)) + return NULL; + + copy = gst_caps_copy (caps); + if (_fixate_caps_to_int (©, "channels", ac_caps.channels)) + return copy; + if (_fixate_caps_to_int (©, "width", ac_caps.is_int ? ac_caps.width : 16)) + return copy; + if (_fixate_caps_to_int (©, "depth", ac_caps.is_int ? ac_caps.depth : 16)) + return copy; + + gst_caps_free (copy); + return NULL; +} + static GstElementStateReturn gst_audio_convert_change_state (GstElement * element) { -- 2.7.4