summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorWang Xin-yu (王昕宇) <comicfans44@gmail.com>2014-08-14 23:51:21 -0400
committerMatthew Waters <ystreet00@gmail.com>2014-08-19 17:00:58 +1000
commit98152017b7f866bc4d87c434b6ae1b0f978245ff (patch)
treea578915b594e2e7f73f457a7773b54aa23ab719a /ext
parent0b0c11632707f9abe94ef776d913ecbcdea6fb73 (diff)
glvideomixer: avoid gl resource race condition between different thread
https://bugzilla.gnome.org/show_bug.cgi?id=734830
Diffstat (limited to 'ext')
-rw-r--r--ext/gl/gstglmixer.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/ext/gl/gstglmixer.c b/ext/gl/gstglmixer.c
index 0d4d7e92b..1420b836c 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)) {