glvideomixer: avoid gl resource race condition between different thread

https://bugzilla.gnome.org/show_bug.cgi?id=734830
This commit is contained in:
Wang Xin-yu (王昕宇) 2014-08-14 23:51:21 -04:00 committed by Matthew Waters
parent 0b0c116327
commit 98152017b7

View file

@ -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)) {