mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 05:22:30 +00:00
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.
This commit is contained in:
parent
5c244e8374
commit
5d592f709f
2 changed files with 61 additions and 42 deletions
|
@ -99,6 +99,7 @@ static void gst_level_class_init (GstLevelClass *klass);
|
||||||
static void gst_level_base_init (GstLevelClass *klass);
|
static void gst_level_base_init (GstLevelClass *klass);
|
||||||
static void gst_level_init (GstLevel *filter);
|
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_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);
|
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
|
static GstPadLinkReturn
|
||||||
gst_level_connect (GstPad *pad, GstCaps *caps)
|
gst_level_link (GstPad *pad, GstCaps *caps)
|
||||||
{
|
{
|
||||||
GstLevel *filter;
|
GstLevel *filter;
|
||||||
GstPad *otherpad;
|
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);
|
g_return_val_if_fail (GST_IS_LEVEL (filter), GST_PAD_LINK_REFUSED);
|
||||||
otherpad = (pad == filter->srcpad ? filter->sinkpad : filter->srcpad);
|
otherpad = (pad == filter->srcpad ? filter->sinkpad : filter->srcpad);
|
||||||
|
|
||||||
if (GST_CAPS_IS_FIXED (caps))
|
if (!GST_CAPS_IS_FIXED (caps)) {
|
||||||
{
|
return GST_PAD_LINK_DELAYED;
|
||||||
/* 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 */
|
res = gst_pad_try_set_caps (otherpad, caps);
|
||||||
if (filter->CS) g_free (filter->CS);
|
/* if ok, set filter */
|
||||||
if (filter->peak) g_free (filter->peak);
|
if (res != GST_PAD_LINK_OK && res != GST_PAD_LINK_DONE) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
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
|
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 (GST_IS_PAD (pad));
|
||||||
g_return_if_fail (buf != NULL);
|
g_return_if_fail (buf != NULL);
|
||||||
|
|
||||||
|
|
||||||
filter = GST_LEVEL (GST_OBJECT_PARENT (pad));
|
filter = GST_LEVEL (GST_OBJECT_PARENT (pad));
|
||||||
g_return_if_fail (filter != NULL);
|
g_return_if_fail (filter != NULL);
|
||||||
g_return_if_fail (GST_IS_LEVEL (filter));
|
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
|
static void
|
||||||
gst_level_set_property (GObject *object, guint prop_id,
|
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_element_class_add_pad_template (element_class,
|
||||||
GST_PAD_TEMPLATE_GET (src_template_factory));
|
GST_PAD_TEMPLATE_GET (src_template_factory));
|
||||||
gst_element_class_set_details (element_class, &level_details);
|
gst_element_class_set_details (element_class, &level_details);
|
||||||
|
|
||||||
|
element_class->change_state = gst_level_change_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -426,9 +444,9 @@ static void
|
||||||
gst_level_init (GstLevel *filter)
|
gst_level_init (GstLevel *filter)
|
||||||
{
|
{
|
||||||
filter->sinkpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (sink_template_factory), "sink");
|
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");
|
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_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
|
||||||
gst_pad_set_chain_function (filter->sinkpad, gst_level_chain);
|
gst_pad_set_chain_function (filter->sinkpad, gst_level_chain);
|
||||||
|
|
|
@ -54,6 +54,7 @@ struct _GstLevel {
|
||||||
|
|
||||||
GstPad *sinkpad, *srcpad;
|
GstPad *sinkpad, *srcpad;
|
||||||
gboolean signal; /* whether or not to emit signals */
|
gboolean signal; /* whether or not to emit signals */
|
||||||
|
gboolean inited; /* whether or not the element is initialized */
|
||||||
gdouble interval; /* how many seconds between emits */
|
gdouble interval; /* how many seconds between emits */
|
||||||
|
|
||||||
gint rate; /* caps variables */
|
gint rate; /* caps variables */
|
||||||
|
|
Loading…
Reference in a new issue