gldisplay: synchronize the searching and creation of GstGLContext's

Ootherwise we could end up with multiple elements in different chains
each creating a context.  Fixes context creation with glvideomixer.
This commit is contained in:
Matthew Waters 2015-04-21 12:19:46 +10:00
parent 8ba1fbbe64
commit 6cb6d8f9e8
7 changed files with 25 additions and 6 deletions

View file

@ -484,6 +484,7 @@ gst_gl_base_mixer_decide_allocation (GstGLBaseMixer * mix, GstQuery * query)
_find_local_gl_context (mix);
if (!mix->context) {
GST_OBJECT_LOCK (mix->display);
do {
if (mix->context)
gst_object_unref (mix->context);
@ -497,6 +498,7 @@ gst_gl_base_mixer_decide_allocation (GstGLBaseMixer * mix, GstQuery * query)
goto context_error;
}
} while (!gst_gl_display_add_context (mix->display, mix->context));
GST_OBJECT_UNLOCK (mix->display);
}
if (mix_class->decide_allocation)

View file

@ -698,6 +698,7 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
GST_DEBUG_OBJECT (gl_sink, "Ensuring setup");
if (!gl_sink->context) {
GST_OBJECT_LOCK (gl_sink->display);
do {
GstGLContext *other_context;
GstGLWindow *window;
@ -770,6 +771,7 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
gst_object_unref (other_context);
gst_object_unref (window);
} while (!gst_gl_display_add_context (gl_sink->display, gl_sink->context));
GST_OBJECT_UNLOCK (gl_sink->display);
} else
GST_DEBUG_OBJECT (gl_sink, "Already have a context");
@ -908,6 +910,9 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
gst_gl_display_filter_gl_api (glimage_sink->display, SUPPORTED_GL_APIS);
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
if (!_ensure_gl_setup (glimage_sink))
return GST_STATE_CHANGE_FAILURE;
g_atomic_int_set (&glimage_sink->to_quit, 0);
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:

View file

@ -816,6 +816,7 @@ gst_gl_test_src_decide_allocation (GstBaseSrc * basesrc, GstQuery * query)
_find_local_gl_context (src);
if (!src->context) {
GST_OBJECT_LOCK (src->display);
do {
if (src->context)
gst_object_unref (src->context);
@ -828,6 +829,7 @@ gst_gl_test_src_decide_allocation (GstBaseSrc * basesrc, GstQuery * query)
goto context_error;
}
} while (!gst_gl_display_add_context (src->display, src->context));
GST_OBJECT_UNLOCK (src->display);
}
out_width = GST_VIDEO_INFO_WIDTH (&src->out_info);

View file

@ -334,6 +334,7 @@ gst_gl_base_filter_decide_allocation (GstBaseTransform * trans,
_find_local_gl_context (filter);
if (!filter->context) {
GST_OBJECT_LOCK (filter->display);
do {
if (filter->context)
gst_object_unref (filter->context);
@ -350,6 +351,7 @@ gst_gl_base_filter_decide_allocation (GstBaseTransform * trans,
goto context_error;
}
} while (!gst_gl_display_add_context (filter->display, filter->context));
GST_OBJECT_UNLOCK (filter->display);
}
gst_gl_context_thread_add (filter->context, gst_gl_base_filter_gl_start,

View file

@ -1216,7 +1216,7 @@ gst_gl_context_create_thread (GstGLContext * context)
context_class = GST_GL_CONTEXT_GET_CLASS (context);
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
display_api = gst_gl_display_get_gl_api (context->priv->display);
display_api = gst_gl_display_get_gl_api_unlocked (context->priv->display);
if (display_api == GST_GL_API_NONE) {
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API,
"Cannot create context with satisfying requested apis "

View file

@ -237,6 +237,14 @@ gst_gl_display_filter_gl_api (GstGLDisplay * display, GstGLAPI gl_api)
GST_OBJECT_UNLOCK (display);
}
GstGLAPI
gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display)
{
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_API_NONE);
return display->priv->gl_api;
}
/**
* gst_gl_display_get_gl_api:
* @display: a #GstGLDisplay
@ -372,6 +380,8 @@ _get_gl_context_for_thread_unlocked (GstGLDisplay * display, GThread * thread)
*
* Returns: (transfer full): the #GstGLContext current on @thread or %NULL
*
* Must be called with the object lock held.
*
* Since: 1.6
*/
GstGLContext *
@ -382,11 +392,9 @@ gst_gl_display_get_gl_context_for_thread (GstGLDisplay * display,
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);
GST_OBJECT_LOCK (display);
context = _get_gl_context_for_thread_unlocked (display, thread);
GST_DEBUG_OBJECT (display, "returning context %" GST_PTR_FORMAT " for thread "
"%p", context, thread);
GST_OBJECT_UNLOCK (display);
return context;
}
@ -430,6 +438,8 @@ out:
* Returns: whether @context was successfully added. %FALSE may be returned
* if there already exists another context for @context's active thread.
*
* Must be called with the object lock held.
*
* Since: 1.6
*/
gboolean
@ -448,8 +458,6 @@ gst_gl_display_add_context (GstGLDisplay * display, GstGLContext * context)
g_assert (context_display == display);
gst_object_unref (context_display);
GST_OBJECT_LOCK (display);
thread = gst_gl_context_get_thread (context);
if (thread) {
collision = _get_gl_context_for_thread_unlocked (display, thread);
@ -471,7 +479,6 @@ out:
GST_DEBUG_OBJECT (display, "%ssuccessfully inserted context %" GST_PTR_FORMAT,
ret ? "" : "un", context);
GST_OBJECT_UNLOCK (display);
return ret;
}

View file

@ -86,6 +86,7 @@ GstGLDisplayType gst_gl_display_get_handle_type (GstGLDisplay * display);
void gst_gl_display_filter_gl_api (GstGLDisplay * display,
GstGLAPI api);
GstGLAPI gst_gl_display_get_gl_api (GstGLDisplay * display);
GstGLAPI gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display);
#define GST_GL_DISPLAY_CONTEXT_TYPE "gst.gl.GLDisplay"
void gst_context_set_gl_display (GstContext * context, GstGLDisplay * display);