mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 11:11:08 +00:00
glmixer: don't hold the object lock while calling into GL
Doing so can deadlock between the GL thread and the object lock e.g. when performing reconfigure events in glimagesink on a resize event. https://bugzilla.gnome.org/show_bug.cgi?id=760559
This commit is contained in:
parent
745071b5bf
commit
03fdd2fc82
1 changed files with 60 additions and 55 deletions
|
@ -599,16 +599,67 @@ context_error:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_upload_frames (GstAggregator * agg, GstAggregatorPad * agg_pad,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GstVideoAggregatorPad *vaggpad = GST_VIDEO_AGGREGATOR_PAD (agg_pad);
|
||||||
|
GstGLMixerPad *pad = GST_GL_MIXER_PAD (agg_pad);
|
||||||
|
GstElement *element = GST_ELEMENT (agg);
|
||||||
|
GstGLMixer *mix = GST_GL_MIXER (agg);
|
||||||
|
GstGLMixerFrameData *frame;
|
||||||
|
guint *array_index, i;
|
||||||
|
|
||||||
|
array_index = (guint *) user_data;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (agg);
|
||||||
|
/* make sure the frames array is big enough */
|
||||||
|
i = mix->frames->len;
|
||||||
|
g_ptr_array_set_size (mix->frames, element->numsinkpads);
|
||||||
|
for (; i < element->numsinkpads; i++)
|
||||||
|
mix->frames->pdata[i] = g_new0 (GstGLMixerFrameData, 1);
|
||||||
|
|
||||||
|
frame = g_ptr_array_index (mix->frames, *array_index);
|
||||||
|
frame->pad = pad;
|
||||||
|
frame->texture = 0;
|
||||||
|
GST_OBJECT_UNLOCK (agg);
|
||||||
|
|
||||||
|
if (vaggpad->buffer != NULL) {
|
||||||
|
GstVideoInfo gl_info;
|
||||||
|
GstVideoFrame gl_frame;
|
||||||
|
GstGLSyncMeta *sync_meta;
|
||||||
|
|
||||||
|
gst_video_info_set_format (&gl_info,
|
||||||
|
GST_VIDEO_FORMAT_RGBA,
|
||||||
|
GST_VIDEO_INFO_WIDTH (&vaggpad->info),
|
||||||
|
GST_VIDEO_INFO_HEIGHT (&vaggpad->info));
|
||||||
|
|
||||||
|
sync_meta = gst_buffer_get_gl_sync_meta (vaggpad->buffer);
|
||||||
|
if (sync_meta)
|
||||||
|
gst_gl_sync_meta_wait (sync_meta, GST_GL_BASE_MIXER (mix)->context);
|
||||||
|
|
||||||
|
if (!gst_video_frame_map (&gl_frame, &gl_info, vaggpad->buffer,
|
||||||
|
GST_MAP_READ | GST_MAP_GL)) {
|
||||||
|
GST_ERROR_OBJECT (agg_pad, "Failed to map input frame");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->texture = *(guint *) gl_frame.data[0];
|
||||||
|
gst_video_frame_unmap (&gl_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*array_index)++;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
||||||
{
|
{
|
||||||
guint i;
|
|
||||||
GList *walk;
|
|
||||||
guint out_tex;
|
guint out_tex;
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
guint array_index = 0;
|
guint array_index = 0;
|
||||||
GstVideoFrame out_frame;
|
GstVideoFrame out_frame;
|
||||||
GstElement *element = GST_ELEMENT (mix);
|
|
||||||
GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix);
|
GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix);
|
||||||
GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix);
|
GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix);
|
||||||
GstGLMixerPrivate *priv = mix->priv;
|
GstGLMixerPrivate *priv = mix->priv;
|
||||||
|
@ -622,47 +673,9 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
||||||
|
|
||||||
out_tex = *(guint *) out_frame.data[0];
|
out_tex = *(guint *) out_frame.data[0];
|
||||||
|
|
||||||
GST_OBJECT_LOCK (mix);
|
if (!gst_aggregator_iterate_sinkpads (GST_AGGREGATOR (mix),
|
||||||
walk = element->sinkpads;
|
(GstAggregatorPadForeachFunc) _upload_frames, &array_index))
|
||||||
|
return FALSE;
|
||||||
i = mix->frames->len;
|
|
||||||
g_ptr_array_set_size (mix->frames, element->numsinkpads);
|
|
||||||
for (; i < element->numsinkpads; i++)
|
|
||||||
mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData);
|
|
||||||
while (walk) {
|
|
||||||
GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
|
|
||||||
GstVideoAggregatorPad *vaggpad = walk->data;
|
|
||||||
GstGLMixerFrameData *frame;
|
|
||||||
|
|
||||||
frame = g_ptr_array_index (mix->frames, array_index);
|
|
||||||
frame->pad = pad;
|
|
||||||
frame->texture = 0;
|
|
||||||
|
|
||||||
walk = g_list_next (walk);
|
|
||||||
|
|
||||||
if (vaggpad->buffer != NULL) {
|
|
||||||
GstVideoInfo gl_info;
|
|
||||||
GstVideoFrame gl_frame;
|
|
||||||
GstGLSyncMeta *sync_meta;
|
|
||||||
|
|
||||||
gst_video_info_set_format (&gl_info,
|
|
||||||
GST_VIDEO_FORMAT_RGBA,
|
|
||||||
GST_VIDEO_INFO_WIDTH (&vaggpad->info),
|
|
||||||
GST_VIDEO_INFO_HEIGHT (&vaggpad->info));
|
|
||||||
|
|
||||||
sync_meta = gst_buffer_get_gl_sync_meta (vaggpad->buffer);
|
|
||||||
if (sync_meta)
|
|
||||||
gst_gl_sync_meta_wait (sync_meta, GST_GL_BASE_MIXER (mix)->context);
|
|
||||||
|
|
||||||
if (gst_video_frame_map (&gl_frame, &gl_info, vaggpad->buffer,
|
|
||||||
GST_MAP_READ | GST_MAP_GL)) {
|
|
||||||
frame->texture = *(guint *) gl_frame.data[0];
|
|
||||||
gst_video_frame_unmap (&gl_frame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
++array_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_mutex_lock (&priv->gl_resource_lock);
|
g_mutex_lock (&priv->gl_resource_lock);
|
||||||
if (!priv->gl_resource_ready)
|
if (!priv->gl_resource_ready)
|
||||||
|
@ -681,8 +694,6 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
||||||
g_mutex_unlock (&priv->gl_resource_lock);
|
g_mutex_unlock (&priv->gl_resource_lock);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
GST_OBJECT_UNLOCK (mix);
|
|
||||||
|
|
||||||
gst_video_frame_unmap (&out_frame);
|
gst_video_frame_unmap (&out_frame);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -701,7 +712,7 @@ gst_gl_mixer_process_buffers (GstGLMixer * mix, GstBuffer * outbuf)
|
||||||
i = mix->frames->len;
|
i = mix->frames->len;
|
||||||
g_ptr_array_set_size (mix->frames, element->numsinkpads);
|
g_ptr_array_set_size (mix->frames, element->numsinkpads);
|
||||||
for (; i < element->numsinkpads; i++)
|
for (; i < element->numsinkpads; i++)
|
||||||
mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData);
|
mix->frames->pdata[i] = g_new0 (GstGLMixerFrameData, 1);
|
||||||
while (walk) { /* We walk with this list because it's ordered */
|
while (walk) { /* We walk with this list because it's ordered */
|
||||||
GstVideoAggregatorPad *vaggpad = walk->data;
|
GstVideoAggregatorPad *vaggpad = walk->data;
|
||||||
|
|
||||||
|
@ -761,12 +772,6 @@ gst_gl_mixer_set_property (GObject * object,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_free_glmixer_frame_data (GstGLMixerFrameData * frame)
|
|
||||||
{
|
|
||||||
g_slice_free1 (sizeof (GstGLMixerFrameData), frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gl_mixer_start (GstAggregator * agg)
|
gst_gl_mixer_start (GstAggregator * agg)
|
||||||
{
|
{
|
||||||
|
@ -777,13 +782,13 @@ gst_gl_mixer_start (GstAggregator * agg)
|
||||||
GST_OBJECT_LOCK (mix);
|
GST_OBJECT_LOCK (mix);
|
||||||
mix->array_buffers = g_ptr_array_new_full (element->numsinkpads, NULL);
|
mix->array_buffers = g_ptr_array_new_full (element->numsinkpads, NULL);
|
||||||
mix->frames = g_ptr_array_new_full (element->numsinkpads,
|
mix->frames = g_ptr_array_new_full (element->numsinkpads,
|
||||||
(GDestroyNotify) _free_glmixer_frame_data);
|
(GDestroyNotify) g_free);
|
||||||
|
|
||||||
g_ptr_array_set_size (mix->array_buffers, element->numsinkpads);
|
g_ptr_array_set_size (mix->array_buffers, element->numsinkpads);
|
||||||
g_ptr_array_set_size (mix->frames, element->numsinkpads);
|
g_ptr_array_set_size (mix->frames, element->numsinkpads);
|
||||||
|
|
||||||
for (i = 0; i < element->numsinkpads; i++)
|
for (i = 0; i < element->numsinkpads; i++)
|
||||||
mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData);
|
mix->frames->pdata[i] = g_new0 (GstGLMixerFrameData, 1);
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (mix);
|
GST_OBJECT_UNLOCK (mix);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue