From 5d592f709fcf7e474289545774c87f56abd2bd85 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Wed, 19 Nov 2003 03:46:21 +0000 Subject: [PATCH] Fix segfault in #125471 by denying a state change to PLAYING when not inited. This is arguably not the right fix. Original commit message from CVS: Fix segfault in #125471 by denying a state change to PLAYING when not inited. This is arguably not the right fix. --- gst/level/gstlevel.c | 104 ++++++++++++++++++++++++++++++--------------------- gst/level/gstlevel.h | 1 + 2 files changed, 62 insertions(+), 43 deletions(-) diff --git a/gst/level/gstlevel.c b/gst/level/gstlevel.c index 736d258..42f128a 100644 --- a/gst/level/gstlevel.c +++ b/gst/level/gstlevel.c @@ -99,6 +99,7 @@ static void gst_level_class_init (GstLevelClass *klass); static void gst_level_base_init (GstLevelClass *klass); static void gst_level_init (GstLevel *filter); +static GstElementStateReturn gst_level_change_state (GstElement *element); static void gst_level_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_level_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); @@ -129,7 +130,7 @@ gst_level_get_type (void) } static GstPadLinkReturn -gst_level_connect (GstPad *pad, GstCaps *caps) +gst_level_link (GstPad *pad, GstCaps *caps) { GstLevel *filter; GstPad *otherpad; @@ -141,47 +142,49 @@ gst_level_connect (GstPad *pad, GstCaps *caps) g_return_val_if_fail (GST_IS_LEVEL (filter), GST_PAD_LINK_REFUSED); otherpad = (pad == filter->srcpad ? filter->sinkpad : filter->srcpad); - if (GST_CAPS_IS_FIXED (caps)) - { - /* yep, got them */ - res = gst_pad_try_set_caps (otherpad, caps); - /* if ok, set filter */ - if (res == GST_PAD_LINK_OK) - { - filter->num_samples = 0; - /* FIXME: error handling */ - if (! gst_caps_get_int (caps, "rate", &(filter->rate))) - g_warning ("WARNING: level: Could not get rate from caps\n"); - if (!gst_caps_get_int (caps, "width", &(filter->width))) - g_warning ("WARNING: level: Could not get width from caps\n"); - if (!gst_caps_get_int (caps, "channels", &(filter->channels))) - g_warning ("WARNING: level: Could not get number of channels from caps\n"); - - /* allocate channel variable arrays */ - if (filter->CS) g_free (filter->CS); - if (filter->peak) g_free (filter->peak); - if (filter->last_peak) g_free (filter->last_peak); - if (filter->decay_peak) g_free (filter->decay_peak); - if (filter->decay_peak_age) g_free (filter->decay_peak_age); - if (filter->MS) g_free (filter->MS); - if (filter->RMS_dB) g_free (filter->RMS_dB); - filter->CS = g_new (double, filter->channels); - filter->peak = g_new (double, filter->channels); - filter->last_peak = g_new (double, filter->channels); - filter->decay_peak = g_new (double, filter->channels); - filter->decay_peak_age = g_new (double, filter->channels); - filter->MS = g_new (double, filter->channels); - filter->RMS_dB = g_new (double, filter->channels); - for (i = 0; i < filter->channels; ++i) - { - filter->CS[i] = filter->peak[i] = filter->last_peak[i] = - filter->decay_peak[i] = filter->decay_peak_age[i] = - filter->MS[i] = filter->RMS_dB[i] = 0.0; - } - } + if (!GST_CAPS_IS_FIXED (caps)) { + return GST_PAD_LINK_DELAYED; + } + + res = gst_pad_try_set_caps (otherpad, caps); + /* if ok, set filter */ + if (res != GST_PAD_LINK_OK && res != GST_PAD_LINK_DONE) { return res; } - return GST_PAD_LINK_DELAYED; + + filter->num_samples = 0; + + if (!gst_caps_get_int (caps, "rate", &(filter->rate))) + return GST_PAD_LINK_REFUSED; + if (!gst_caps_get_int (caps, "width", &(filter->width))) + return GST_PAD_LINK_REFUSED; + if (!gst_caps_get_int (caps, "channels", &(filter->channels))) + return GST_PAD_LINK_REFUSED; + + /* allocate channel variable arrays */ + if (filter->CS) g_free (filter->CS); + if (filter->peak) g_free (filter->peak); + if (filter->last_peak) g_free (filter->last_peak); + if (filter->decay_peak) g_free (filter->decay_peak); + if (filter->decay_peak_age) g_free (filter->decay_peak_age); + if (filter->MS) g_free (filter->MS); + if (filter->RMS_dB) g_free (filter->RMS_dB); + filter->CS = g_new (double, filter->channels); + filter->peak = g_new (double, filter->channels); + filter->last_peak = g_new (double, filter->channels); + filter->decay_peak = g_new (double, filter->channels); + filter->decay_peak_age = g_new (double, filter->channels); + filter->MS = g_new (double, filter->channels); + filter->RMS_dB = g_new (double, filter->channels); + for (i = 0; i < filter->channels; ++i) { + filter->CS[i] = filter->peak[i] = filter->last_peak[i] = + filter->decay_peak[i] = filter->decay_peak_age[i] = + filter->MS[i] = filter->RMS_dB[i] = 0.0; + } + + filter->inited = TRUE; + + return GST_PAD_LINK_OK; } static void inline @@ -209,7 +212,6 @@ gst_level_chain (GstPad *pad, GstData *_data) g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); - filter = GST_LEVEL (GST_OBJECT_PARENT (pad)); g_return_if_fail (filter != NULL); g_return_if_fail (GST_IS_LEVEL (filter)); @@ -313,6 +315,20 @@ gst_level_chain (GstPad *pad, GstData *_data) } } +static GstElementStateReturn gst_level_change_state (GstElement *element) +{ + GstLevel *filter = GST_LEVEL (element); + + switch(GST_STATE_TRANSITION(element)){ + case GST_STATE_PAUSED_TO_PLAYING: + if (!filter->inited) return GST_STATE_FAILURE; + break; + default: + break; + } + + return GST_ELEMENT_CLASS(parent_class)->change_state(element); +} static void gst_level_set_property (GObject *object, guint prop_id, @@ -381,6 +397,8 @@ gst_level_base_init (GstLevelClass *klass) gst_element_class_add_pad_template (element_class, GST_PAD_TEMPLATE_GET (src_template_factory)); gst_element_class_set_details (element_class, &level_details); + + element_class->change_state = gst_level_change_state; } static void @@ -426,9 +444,9 @@ static void gst_level_init (GstLevel *filter) { filter->sinkpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (sink_template_factory), "sink"); - gst_pad_set_link_function (filter->sinkpad, gst_level_connect); + gst_pad_set_link_function (filter->sinkpad, gst_level_link); filter->srcpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (src_template_factory), "src"); - gst_pad_set_link_function (filter->srcpad, gst_level_connect); + gst_pad_set_link_function (filter->srcpad, gst_level_link); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); gst_pad_set_chain_function (filter->sinkpad, gst_level_chain); diff --git a/gst/level/gstlevel.h b/gst/level/gstlevel.h index 59427c7..7a85377 100644 --- a/gst/level/gstlevel.h +++ b/gst/level/gstlevel.h @@ -54,6 +54,7 @@ struct _GstLevel { GstPad *sinkpad, *srcpad; gboolean signal; /* whether or not to emit signals */ + gboolean inited; /* whether or not the element is initialized */ gdouble interval; /* how many seconds between emits */ gint rate; /* caps variables */ -- 2.7.4