mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
glmixer: lock the size of mix->frames to the number of pads
Fixes a segfault with decodebin ! glmixer where the request pads on both sides were being requested after the state change to PAUSED. Also fixes dynamically adding and removing pads while glmixer is in a state >= PAUSED.
This commit is contained in:
parent
31ee764a8a
commit
6a7ccd6f3e
1 changed files with 58 additions and 59 deletions
|
@ -715,6 +715,12 @@ gst_gl_mixer_reset (GstGLMixer * mix)
|
|||
priv->negotiated = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_free_pad_frame_data (gpointer data)
|
||||
{
|
||||
g_slice_free1 (sizeof (GstGLMixerFrameData), data);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_mixer_init (GstGLMixer * mix)
|
||||
{
|
||||
|
@ -751,6 +757,9 @@ gst_gl_mixer_init (GstGLMixer * mix)
|
|||
mix->fbo = 0;
|
||||
mix->depthbuffer = 0;
|
||||
|
||||
mix->frames = g_ptr_array_new_full (4, _free_pad_frame_data);
|
||||
mix->array_buffers = g_ptr_array_new_full (4, NULL);
|
||||
|
||||
/* initialize variables */
|
||||
gst_gl_mixer_reset (mix);
|
||||
}
|
||||
|
@ -763,6 +772,9 @@ gst_gl_mixer_finalize (GObject * object)
|
|||
gst_object_unref (mix->collect);
|
||||
g_mutex_clear (&mix->lock);
|
||||
|
||||
g_ptr_array_free (mix->frames, TRUE);
|
||||
g_ptr_array_free (mix->array_buffers, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -1354,50 +1366,47 @@ gst_gl_mixer_request_new_pad (GstElement * element,
|
|||
GstGLMixer *mix;
|
||||
GstGLMixerPad *mixpad;
|
||||
GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
|
||||
gint serial = 0;
|
||||
gchar *name = NULL;
|
||||
GstGLMixerCollect *mixcol = NULL;
|
||||
|
||||
mix = GST_GL_MIXER (element);
|
||||
|
||||
if (templ == gst_element_class_get_pad_template (klass, "sink_%d")) {
|
||||
gint serial = 0;
|
||||
gchar *name = NULL;
|
||||
GstGLMixerCollect *mixcol = NULL;
|
||||
|
||||
GST_GL_MIXER_LOCK (mix);
|
||||
if (req_name == NULL || strlen (req_name) < 6
|
||||
|| !g_str_has_prefix (req_name, "sink_")) {
|
||||
/* no name given when requesting the pad, use next available int */
|
||||
serial = mix->next_sinkpad++;
|
||||
} else {
|
||||
/* parse serial number from requested padname */
|
||||
serial = g_ascii_strtoull (&req_name[5], NULL, 10);
|
||||
if (serial >= mix->next_sinkpad)
|
||||
mix->next_sinkpad = serial + 1;
|
||||
}
|
||||
/* create new pad with the name */
|
||||
name = g_strdup_printf ("sink_%d", serial);
|
||||
mixpad = g_object_new (GST_TYPE_GL_MIXER_PAD, "name", name, "direction",
|
||||
templ->direction, "template", templ, NULL);
|
||||
g_free (name);
|
||||
|
||||
mixcol = (GstGLMixerCollect *)
|
||||
gst_collect_pads_add_pad (mix->collect, GST_PAD (mixpad),
|
||||
sizeof (GstGLMixerCollect),
|
||||
(GstCollectDataDestroyNotify) gst_gl_mixer_collect_free, TRUE);
|
||||
|
||||
/* Keep track of each other */
|
||||
mixcol->mixpad = mixpad;
|
||||
mixpad->mixcol = mixcol;
|
||||
|
||||
mixcol->start_time = -1;
|
||||
mixcol->end_time = -1;
|
||||
|
||||
/* Keep an internal list of mixpads for zordering */
|
||||
mix->sinkpads = g_slist_append (mix->sinkpads, mixpad);
|
||||
mix->numpads++;
|
||||
GST_GL_MIXER_UNLOCK (mix);
|
||||
} else {
|
||||
if (templ != gst_element_class_get_pad_template (klass, "sink_%d"))
|
||||
return NULL;
|
||||
|
||||
GST_GL_MIXER_LOCK (mix);
|
||||
if (req_name == NULL || strlen (req_name) < 6
|
||||
|| !g_str_has_prefix (req_name, "sink_")) {
|
||||
/* no name given when requesting the pad, use next available int */
|
||||
serial = mix->next_sinkpad++;
|
||||
} else {
|
||||
/* parse serial number from requested padname */
|
||||
serial = g_ascii_strtoull (&req_name[5], NULL, 10);
|
||||
if (serial >= mix->next_sinkpad)
|
||||
mix->next_sinkpad = serial + 1;
|
||||
}
|
||||
/* create new pad with the name */
|
||||
name = g_strdup_printf ("sink_%d", serial);
|
||||
mixpad = g_object_new (GST_TYPE_GL_MIXER_PAD, "name", name, "direction",
|
||||
templ->direction, "template", templ, NULL);
|
||||
g_free (name);
|
||||
|
||||
mixcol = (GstGLMixerCollect *)
|
||||
gst_collect_pads_add_pad (mix->collect, GST_PAD (mixpad),
|
||||
sizeof (GstGLMixerCollect),
|
||||
(GstCollectDataDestroyNotify) gst_gl_mixer_collect_free, TRUE);
|
||||
|
||||
/* Keep track of each other */
|
||||
mixcol->mixpad = mixpad;
|
||||
mixpad->mixcol = mixcol;
|
||||
|
||||
mixcol->start_time = -1;
|
||||
mixcol->end_time = -1;
|
||||
|
||||
/* Keep an internal list of mixpads for zordering */
|
||||
mix->sinkpads = g_slist_append (mix->sinkpads, mixpad);
|
||||
mix->numpads++;
|
||||
|
||||
GST_DEBUG_OBJECT (element, "Adding pad %s", GST_PAD_NAME (mixpad));
|
||||
|
||||
|
@ -1406,6 +1415,13 @@ gst_gl_mixer_request_new_pad (GstElement * element,
|
|||
gst_child_proxy_child_added (GST_CHILD_PROXY (mix), G_OBJECT (mixpad),
|
||||
GST_OBJECT_NAME (mixpad));
|
||||
|
||||
g_ptr_array_set_size (mix->array_buffers, mix->numpads);
|
||||
g_ptr_array_set_size (mix->frames, mix->numpads);
|
||||
|
||||
mix->frames->pdata[mix->numpads - 1] = g_slice_new0 (GstGLMixerFrameData);
|
||||
|
||||
GST_GL_MIXER_UNLOCK (mix);
|
||||
|
||||
return GST_PAD (mixpad);
|
||||
}
|
||||
|
||||
|
@ -1431,6 +1447,9 @@ gst_gl_mixer_release_pad (GstElement * element, GstPad * pad)
|
|||
GST_OBJECT_NAME (mixpad));
|
||||
mix->numpads--;
|
||||
|
||||
g_ptr_array_set_size (mix->array_buffers, mix->numpads);
|
||||
g_ptr_array_set_size (mix->frames, mix->numpads);
|
||||
|
||||
update_caps =
|
||||
GST_VIDEO_INFO_FORMAT (&mix->out_info) != GST_VIDEO_FORMAT_UNKNOWN;
|
||||
GST_GL_MIXER_UNLOCK (mix);
|
||||
|
@ -2273,37 +2292,17 @@ gst_gl_mixer_change_state (GstElement * element, GstStateChange transition)
|
|||
switch (transition) {
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
{
|
||||
guint i;
|
||||
|
||||
mix->array_buffers = g_ptr_array_new_full (mix->numpads, NULL);
|
||||
mix->frames = g_ptr_array_new_full (mix->numpads, NULL);
|
||||
|
||||
g_ptr_array_set_size (mix->array_buffers, mix->numpads);
|
||||
g_ptr_array_set_size (mix->frames, mix->numpads);
|
||||
|
||||
for (i = 0; i < mix->numpads; i++) {
|
||||
mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData);
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (mix, "starting collectpads");
|
||||
gst_collect_pads_start (mix->collect);
|
||||
break;
|
||||
}
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
{
|
||||
guint i;
|
||||
GSList *walk = mix->sinkpads;
|
||||
|
||||
GST_LOG_OBJECT (mix, "stopping collectpads");
|
||||
gst_collect_pads_stop (mix->collect);
|
||||
|
||||
for (i = 0; i < mix->numpads; i++) {
|
||||
g_slice_free1 (sizeof (GstGLMixerFrameData), mix->frames->pdata[i]);
|
||||
}
|
||||
|
||||
g_ptr_array_free (mix->array_buffers, TRUE);
|
||||
g_ptr_array_free (mix->frames, TRUE);
|
||||
|
||||
if (mixer_class->reset)
|
||||
mixer_class->reset (mix);
|
||||
if (mix->fbo) {
|
||||
|
|
Loading…
Reference in a new issue