From 98152017b7f866bc4d87c434b6ae1b0f978245ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wang=20Xin-yu=20=28=E7=8E=8B=E6=98=95=E5=AE=87=29?= Date: Thu, 14 Aug 2014 23:51:21 -0400 Subject: [PATCH] glvideomixer: avoid gl resource race condition between different thread https://bugzilla.gnome.org/show_bug.cgi?id=734830 --- ext/gl/gstglmixer.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/ext/gl/gstglmixer.c b/ext/gl/gstglmixer.c index 0d4d7e92ba..1420b836c9 100644 --- a/ext/gl/gstglmixer.c +++ b/ext/gl/gstglmixer.c @@ -70,6 +70,10 @@ struct _GstGLMixerPrivate GstAllocator *allocator; GstAllocationParams params; GstQuery *query; + + gboolean gl_resource_ready; + GMutex gl_resource_lock; + GCond gl_resource_cond; }; G_DEFINE_TYPE (GstGLMixerPad, gst_gl_mixer_pad, GST_TYPE_VIDEO_AGGREGATOR_PAD); @@ -427,6 +431,9 @@ gst_gl_mixer_init (GstGLMixer * mix) mix->fbo = 0; mix->depthbuffer = 0; + mix->priv->gl_resource_ready = FALSE; + g_mutex_init (&mix->priv->gl_resource_lock); + g_cond_init (&mix->priv->gl_resource_cond); /* initialize variables */ gst_gl_mixer_reset (mix); } @@ -434,6 +441,10 @@ gst_gl_mixer_init (GstGLMixer * mix) static void gst_gl_mixer_finalize (GObject * object) { + GstGLMixerPrivate *priv = GST_GL_MIXER (object)->priv; + + g_mutex_clear (&priv->gl_resource_lock); + g_cond_clear (&priv->gl_resource_cond); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -641,6 +652,8 @@ gst_gl_mixer_decide_allocation (GstGLMixer * mix, GstQuery * query) out_width = GST_VIDEO_INFO_WIDTH (&vagg->info); out_height = GST_VIDEO_INFO_HEIGHT (&vagg->info); + g_mutex_lock (&mix->priv->gl_resource_lock); + mix->priv->gl_resource_ready = FALSE; if (mix->fbo) { gst_gl_context_del_fbo (mix->context, mix->fbo, mix->depthbuffer); mix->fbo = 0; @@ -648,8 +661,11 @@ gst_gl_mixer_decide_allocation (GstGLMixer * mix, GstQuery * query) } if (!gst_gl_context_gen_fbo (mix->context, out_width, out_height, - &mix->fbo, &mix->depthbuffer)) + &mix->fbo, &mix->depthbuffer)) { + g_cond_signal (&mix->priv->gl_resource_cond); + g_mutex_unlock (&mix->priv->gl_resource_lock); goto context_error; + } if (mix->out_tex_id) gst_gl_context_del_texture (mix->context, &mix->out_tex_id); @@ -659,6 +675,10 @@ gst_gl_mixer_decide_allocation (GstGLMixer * mix, GstQuery * query) if (mixer_class->set_caps) mixer_class->set_caps (mix, caps); + mix->priv->gl_resource_ready = TRUE; + g_cond_signal (&mix->priv->gl_resource_cond); + g_mutex_unlock (&mix->priv->gl_resource_lock); + if (!pool) pool = gst_gl_buffer_pool_new (mix->context); @@ -797,6 +817,7 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) GstElement *element = GST_ELEMENT (mix); GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix); GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix); + GstGLMixerPrivate *priv = mix->priv; GST_TRACE ("Processing buffers"); @@ -860,8 +881,22 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) ++array_index; } + g_mutex_lock (&priv->gl_resource_lock); + if (!priv->gl_resource_ready) + g_cond_wait (&priv->gl_resource_cond, &priv->gl_resource_lock); + + if (!priv->gl_resource_ready) { + g_mutex_unlock (&priv->gl_resource_lock); + GST_ERROR_OBJECT (mix, + "fbo used to render can't be created, do not run process_textures"); + res = FALSE; + goto out; + } + mix_class->process_textures (mix, mix->frames, out_tex); + g_mutex_unlock (&priv->gl_resource_lock); + if (out_gl_wrapped) { if (!gst_gl_download_perform_with_data (mix->download, out_tex, out_frame.data)) {