static gboolean ensure_context (GstGLStereoSplit * self) { GError *error = NULL; if (!gst_gl_ensure_element_data (self, &self->display, &self->other_context)) return FALSE; gst_gl_display_filter_gl_api (self->display, SUPPORTED_GL_APIS); _find_local_gl_context (self); if (!self->context) { GST_OBJECT_LOCK (self->display); do { if (self->context) gst_object_unref (self->context); /* just get a GL context. we don't care */ self->context = gst_gl_display_get_gl_context_for_thread (self->display, NULL); if (!self->context) { if (!gst_gl_display_create_context (self->display, self->other_context, &self->context, &error)) { GST_OBJECT_UNLOCK (self->display); goto context_error; } } } while (!gst_gl_display_add_context (self->display, self->context)); GST_OBJECT_UNLOCK (self->display); } return TRUE; context_error: { GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, ("%s", error->message), (NULL)); g_clear_error (&error); return FALSE; } }
static gboolean gst_gl_base_mixer_decide_allocation (GstGLBaseMixer * mix, GstQuery * query) { GstGLBaseMixerClass *mix_class = GST_GL_BASE_MIXER_GET_CLASS (mix); GError *error = NULL; gboolean ret = TRUE; if (!gst_gl_ensure_element_data (mix, &mix->display, &mix->priv->other_context)) return FALSE; gst_gl_display_filter_gl_api (mix->display, mix_class->supported_gl_api); _find_local_gl_context (mix); if (!mix->context) { GST_OBJECT_LOCK (mix->display); do { if (mix->context) { gst_object_unref (mix->context); mix->context = NULL; } /* just get a GL context. we don't care */ mix->context = gst_gl_display_get_gl_context_for_thread (mix->display, NULL); if (!mix->context) { if (!gst_gl_display_create_context (mix->display, mix->priv->other_context, &mix->context, &error)) { GST_OBJECT_UNLOCK (mix->display); goto context_error; } } } while (!gst_gl_display_add_context (mix->display, mix->context)); GST_OBJECT_UNLOCK (mix->display); } { GstGLAPI current_gl_api = gst_gl_context_get_gl_api (mix->context); if ((current_gl_api & mix_class->supported_gl_api) == 0) goto unsupported_gl_api; } if (mix_class->decide_allocation) ret = mix_class->decide_allocation (mix, query); return ret; unsupported_gl_api: { GstGLAPI gl_api = gst_gl_context_get_gl_api (mix->context); gchar *gl_api_str = gst_gl_api_to_string (gl_api); gchar *supported_gl_api_str = gst_gl_api_to_string (mix_class->supported_gl_api); GST_ELEMENT_ERROR (mix, RESOURCE, BUSY, ("GL API's not compatible context: %s supported: %s", gl_api_str, supported_gl_api_str), (NULL)); g_free (supported_gl_api_str); g_free (gl_api_str); return FALSE; } context_error: { GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s", error->message), (NULL)); g_clear_error (&error); return FALSE; } }
static gboolean gst_gl_test_src_decide_allocation (GstBaseSrc * basesrc, GstQuery * query) { GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc); GstBufferPool *pool = NULL; GstStructure *config; GstCaps *caps; guint min, max, size; gboolean update_pool; GError *error = NULL; if (!gst_gl_ensure_element_data (src, &src->display, &src->other_context)) return FALSE; gst_gl_display_filter_gl_api (src->display, SUPPORTED_GL_APIS); _find_local_gl_context (src); if (!src->context) { GST_OBJECT_LOCK (src->display); do { if (src->context) { gst_object_unref (src->context); src->context = NULL; } /* just get a GL context. we don't care */ src->context = gst_gl_display_get_gl_context_for_thread (src->display, NULL); if (!src->context) { if (!gst_gl_display_create_context (src->display, src->other_context, &src->context, &error)) { GST_OBJECT_UNLOCK (src->display); goto context_error; } } } while (!gst_gl_display_add_context (src->display, src->context)); GST_OBJECT_UNLOCK (src->display); } if ((gst_gl_context_get_gl_api (src->context) & SUPPORTED_GL_APIS) == 0) goto unsupported_gl_api; gst_gl_context_thread_add (src->context, (GstGLContextThreadFunc) _src_generate_fbo_gl, src); if (!src->fbo) goto context_error; gst_query_parse_allocation (query, &caps, NULL); if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); update_pool = TRUE; } else { GstVideoInfo vinfo; gst_video_info_init (&vinfo); gst_video_info_from_caps (&vinfo, caps); size = vinfo.size; min = max = 0; update_pool = FALSE; } if (!pool || !GST_IS_GL_BUFFER_POOL (pool)) { /* can't use this pool */ if (pool) gst_object_unref (pool); pool = gst_gl_buffer_pool_new (src->context); } config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, min, max); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); if (gst_query_find_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, NULL)) gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_GL_SYNC_META); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META); gst_buffer_pool_set_config (pool, config); if (update_pool) gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); else gst_query_add_allocation_pool (query, pool, size, min, max); gst_gl_test_src_init_shader (src); gst_object_unref (pool); return TRUE; unsupported_gl_api: { GstGLAPI gl_api = gst_gl_context_get_gl_api (src->context); gchar *gl_api_str = gst_gl_api_to_string (gl_api); gchar *supported_gl_api_str = gst_gl_api_to_string (SUPPORTED_GL_APIS); GST_ELEMENT_ERROR (src, RESOURCE, BUSY, ("GL API's not compatible context: %s supported: %s", gl_api_str, supported_gl_api_str), (NULL)); g_free (supported_gl_api_str); g_free (gl_api_str); return FALSE; } context_error: { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("%s", error->message), (NULL)); g_clear_error (&error); if (src->context) gst_object_unref (src->context); src->context = NULL; return FALSE; } }
void gst_gl_context_helper_ensure_context (GstGLContextHelper * ctxh) { GError *error = NULL; GstGLContext *context; g_return_if_fail (ctxh != NULL); if (!ctxh->display) gst_gl_ensure_element_data (ctxh->element, &ctxh->display, &ctxh->other_context); if (!ctxh->display) goto display_error; context = _find_local_gl_context (ctxh); if (context) { GST_INFO_OBJECT (ctxh->element, "found local context %p, old context %p", context, ctxh->context); if (ctxh->context) gst_object_unref (ctxh->context); ctxh->context = context; } if (!ctxh->context) { GST_OBJECT_LOCK (ctxh->display); do { if (ctxh->context) gst_object_unref (ctxh->context); ctxh->context = gst_gl_display_get_gl_context_for_thread (ctxh->display, NULL); if (!ctxh->context) { if (!gst_gl_display_create_context (ctxh->display, ctxh->other_context, &ctxh->context, &error)) { GST_OBJECT_UNLOCK (ctxh->display); goto context_error; } } } while (!gst_gl_display_add_context (ctxh->display, ctxh->context)); GST_OBJECT_UNLOCK (ctxh->display); } return; context_error: { GST_ELEMENT_ERROR (ctxh->element, RESOURCE, NOT_FOUND, ("%s", error->message), (NULL)); g_clear_error (&error); return; } display_error: { GST_ELEMENT_ERROR (ctxh->element, RESOURCE, NOT_FOUND, ("Failed to obtain display"), (NULL)); return; } }