summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Isorce <j.isorce@samsung.com>2015-06-15 16:09:54 +0100
committerJulien Isorce <j.isorce@samsung.com>2015-06-19 13:10:30 +0100
commit66d833fcf27aa5eefae2065c76b24163a3b708b2 (patch)
treefb66297b16f590dea39aea7fa60f5f4ab3ca20b7
parentb0995fcca01e58ce6b585d0f00152763fc89036f (diff)
gldisplay: add gst_gl_display_create_context
It also emits a create-context signal so that an application can provide an external GstGLContext backend. https://bugzilla.gnome.org/show_bug.cgi?id=750310
-rw-r--r--ext/gl/gstglimagesink.c66
-rw-r--r--gst-libs/gst/gl/gstgldisplay.c77
-rw-r--r--gst-libs/gst/gl/gstgldisplay.h2
3 files changed, 111 insertions, 34 deletions
diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c
index d2660977e..b8fd96c4e 100644
--- a/ext/gl/gstglimagesink.c
+++ b/ext/gl/gstglimagesink.c
@@ -696,22 +696,37 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
if (!gl_sink->context) {
GST_OBJECT_LOCK (gl_sink->display);
do {
- GstGLContext *other_context;
- GstGLWindow *window;
+ GstGLContext *other_context = NULL;
+ GstGLWindow *window = NULL;
- if (gl_sink->context)
+ if (gl_sink->context) {
gst_object_unref (gl_sink->context);
+ gl_sink->context = NULL;
+ }
GST_DEBUG_OBJECT (gl_sink,
"No current context, creating one for %" GST_PTR_FORMAT,
gl_sink->display);
- gl_sink->context = gst_gl_context_new (gl_sink->display);
- if (!gl_sink->context) {
+ if (gl_sink->other_context) {
+ other_context = gst_object_ref (gl_sink->other_context);
+ } else {
+ other_context =
+ gst_gl_display_get_gl_context_for_thread (gl_sink->display, NULL);
+ }
+
+ if (!gst_gl_display_create_context (gl_sink->display,
+ other_context, &gl_sink->context, &error)) {
+ if (other_context)
+ gst_object_unref (other_context);
GST_OBJECT_UNLOCK (gl_sink->display);
- goto context_creation_error;
+ goto context_error;
}
+ GST_DEBUG_OBJECT (gl_sink,
+ "created context %" GST_PTR_FORMAT " from other context %"
+ GST_PTR_FORMAT, gl_sink->context, gl_sink->other_context);
+
window = gst_gl_context_get_window (gl_sink->context);
GST_DEBUG_OBJECT (gl_sink, "got window %" GST_PTR_FORMAT, window);
@@ -729,25 +744,6 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
gst_gl_window_set_window_handle (window, gl_sink->window_id);
}
- if (gl_sink->other_context) {
- other_context = gst_object_ref (gl_sink->other_context);
- } else {
- other_context =
- gst_gl_display_get_gl_context_for_thread (gl_sink->display, NULL);
- }
-
- GST_DEBUG_OBJECT (gl_sink,
- "creating context %" GST_PTR_FORMAT " from other context %"
- GST_PTR_FORMAT, gl_sink->context, other_context);
-
- if (!gst_gl_context_create (gl_sink->context, other_context, &error)) {
- if (other_context)
- gst_object_unref (other_context);
- gst_object_unref (window);
- GST_OBJECT_UNLOCK (gl_sink->display);
- goto context_error;
- }
-
gst_gl_window_handle_events (window, gl_sink->handle_events);
/* setup callbacks */
@@ -782,19 +778,21 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
return TRUE;
-context_creation_error:
- {
- GST_ELEMENT_ERROR (gl_sink, RESOURCE, NOT_FOUND,
- ("Failed to create GL context"), (NULL));
- return FALSE;
- }
-
context_error:
{
GST_ELEMENT_ERROR (gl_sink, RESOURCE, NOT_FOUND, ("%s", error->message),
(NULL));
- gst_object_unref (gl_sink->context);
- gl_sink->context = NULL;
+
+ if (gl_sink->context) {
+ gst_object_unref (gl_sink->context);
+ gl_sink->context = NULL;
+ }
+
+ if (error) {
+ g_error_free (error);
+ error = NULL;
+ }
+
return FALSE;
}
}
diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c
index b1264a9c5..51c1df532 100644
--- a/gst-libs/gst/gl/gstgldisplay.c
+++ b/gst-libs/gst/gl/gstgldisplay.c
@@ -84,6 +84,15 @@ G_DEFINE_TYPE_WITH_CODE (GstGLDisplay, gst_gl_display, GST_TYPE_OBJECT,
#define GST_GL_DISPLAY_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_DISPLAY, GstGLDisplayPrivate))
+enum
+{
+ SIGNAL_0,
+ CREATE_CONTEXT,
+ LAST_SIGNAL
+};
+
+static guint gst_gl_display_signals[LAST_SIGNAL] = { 0 };
+
static void gst_gl_display_finalize (GObject * object);
static guintptr gst_gl_display_default_get_handle (GstGLDisplay * display);
@@ -99,6 +108,22 @@ gst_gl_display_class_init (GstGLDisplayClass * klass)
{
g_type_class_add_private (klass, sizeof (GstGLDisplayPrivate));
+ /**
+ * GstGLDisplay::create-context:
+ * @object: the #GstGLDisplay
+ * @context: other context to share resources with.
+ *
+ * Overrides the @GstGLContext creation mechanism.
+ * It can be called in any thread and it is emitted with
+ * display's object lock held.
+ *
+ * Returns: the new context.
+ */
+ gst_gl_display_signals[CREATE_CONTEXT] =
+ g_signal_new ("create-context", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
+ GST_GL_TYPE_CONTEXT, 1, GST_GL_TYPE_CONTEXT);
+
klass->get_handle = gst_gl_display_default_get_handle;
G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize;
@@ -341,6 +366,58 @@ gst_context_get_gl_display (GstContext * context, GstGLDisplay ** display)
return ret;
}
+/**
+ * gst_gl_display_create_context:
+ * @display: a #GstGLDisplay
+ * @other_context: other #GstGLContext to share resources with.
+ * @p_context: resulting #GstGLContext
+ * @error: resulting #GError
+ *
+ * It requires the display's object lock to be held.
+ *
+ * Returns: whether a new context could be created.
+ *
+ * Since: 1.6
+ */
+gboolean
+gst_gl_display_create_context (GstGLDisplay * display,
+ GstGLContext * other_context, GstGLContext ** p_context, GError ** error)
+{
+ GstGLContext *context = NULL;
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (display != NULL, FALSE);
+ g_return_val_if_fail (p_context != NULL, FALSE);
+ g_return_val_if_fail (error != NULL, FALSE);
+ g_return_val_if_fail (*error == NULL, FALSE);
+
+ g_signal_emit (display, gst_gl_display_signals[CREATE_CONTEXT], 0,
+ other_context, &context);
+
+ if (context) {
+ *p_context = context;
+ return TRUE;
+ }
+
+ context = gst_gl_context_new (display);
+ if (!context) {
+ g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
+ "Failed to create GL context");
+ return FALSE;
+ }
+
+ GST_DEBUG_OBJECT (display,
+ "creating context %" GST_PTR_FORMAT " from other context %"
+ GST_PTR_FORMAT, context, other_context);
+
+ ret = gst_gl_context_create (context, other_context, error);
+
+ if (ret)
+ *p_context = context;
+
+ return ret;
+}
+
static GstGLContext *
_get_gl_context_for_thread_unlocked (GstGLDisplay * display, GThread * thread)
{
diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h
index a9c143393..9341884e1 100644
--- a/gst-libs/gst/gl/gstgldisplay.h
+++ b/gst-libs/gst/gl/gstgldisplay.h
@@ -92,6 +92,8 @@ GstGLAPI gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display);
void gst_context_set_gl_display (GstContext * context, GstGLDisplay * display);
gboolean gst_context_get_gl_display (GstContext * context, GstGLDisplay ** display);
+gboolean gst_gl_display_create_context (GstGLDisplay * display,
+ GstGLContext * other_context, GstGLContext ** p_context, GError **error);
GstGLContext * gst_gl_display_get_gl_context_for_thread (GstGLDisplay * display,
GThread * thread);
gboolean gst_gl_display_add_context (GstGLDisplay * display,