mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
[793/906] add a GstGLContext object that will be the basis of OpenGL contexts
At the moment it just sits in between GstGLDisplay and GstGLWindow performing some of the stuff that GstGLWindow used to do.
This commit is contained in:
parent
b5d595f402
commit
cf5e910d9b
21 changed files with 868 additions and 436 deletions
|
@ -8,6 +8,7 @@ noinst_HEADERS =
|
|||
|
||||
libgstgl_@GST_API_VERSION@_la_SOURCES = \
|
||||
gstgldisplay.c \
|
||||
gstglcontext.c \
|
||||
gstglmemory.c \
|
||||
gstglbufferpool.c \
|
||||
gstglfilter.c \
|
||||
|
@ -64,6 +65,7 @@ libgstgl_@GST_API_VERSION@include_HEADERS = \
|
|||
gstglconfig.h \
|
||||
gstglwindow.h \
|
||||
gstgldisplay.h \
|
||||
gstglcontext.h \
|
||||
gstglmemory.h \
|
||||
gstglbufferpool.h \
|
||||
gstgles2.h \
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "../gstgl_fwd.h"
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
#include "gstglwindow_android_egl.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_window_debug
|
||||
|
@ -307,13 +310,14 @@ static gpointer
|
|||
gst_gl_window_android_egl_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name)
|
||||
{
|
||||
GstGLContext *context = NULL;
|
||||
GstGLWindowAndroidEGL *window_egl;
|
||||
gpointer result;
|
||||
|
||||
window_egl = GST_GL_WINDOW_ANDROID_EGL (window);
|
||||
|
||||
if (!(result = gst_gl_egl_get_proc_address (window_egl->egl, name))) {
|
||||
result = gst_gl_window_default_get_proc_address (window, name);
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <gst/gl/gstglconfig.h>
|
||||
#include <gst/gl/gstglapi.h>
|
||||
#include <gst/gl/gstgldisplay.h>
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
#include <gst/gl/gstglfeature.h>
|
||||
#include <gst/gl/gstglutils.h>
|
||||
#include <gst/gl/gstglwindow.h>
|
||||
|
|
|
@ -31,6 +31,10 @@ typedef struct _GstGLDisplay GstGLDisplay;
|
|||
typedef struct _GstGLDisplayClass GstGLDisplayClass;
|
||||
typedef struct _GstGLDisplayPrivate GstGLDisplayPrivate;
|
||||
|
||||
typedef struct _GstGLContext GstGLContext;
|
||||
typedef struct _GstGLContextClass GstGLContextClass;
|
||||
typedef struct _GstGLContextPrivate GstGLContextPrivate;
|
||||
|
||||
typedef struct _GstGLWindow GstGLWindow;
|
||||
typedef struct _GstGLWindowPrivate GstGLWindowPrivate;
|
||||
typedef struct _GstGLWindowClass GstGLWindowClass;
|
||||
|
|
624
gst-libs/gst/gl/gstglcontext.c
Normal file
624
gst-libs/gst/gl/gstglcontext.c
Normal file
|
@ -0,0 +1,624 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2013 Matthew Waters <ystreet00@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
#include "gl.h"
|
||||
#include "gstglcontext.h"
|
||||
|
||||
#define USING_OPENGL(display) (display->gl_api & GST_GL_API_OPENGL)
|
||||
#define USING_OPENGL3(display) (display->gl_api & GST_GL_API_OPENGL3)
|
||||
#define USING_GLES(display) (display->gl_api & GST_GL_API_GLES)
|
||||
#define USING_GLES2(display) (display->gl_api & GST_GL_API_GLES2)
|
||||
#define USING_GLES3(display) (display->gl_api & GST_GL_API_GLES3)
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_context_debug
|
||||
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
|
||||
|
||||
#define gst_gl_context_parent_class parent_class
|
||||
G_DEFINE_TYPE (GstGLContext, gst_gl_context, G_TYPE_OBJECT);
|
||||
|
||||
#define GST_GL_CONTEXT_GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_CONTEXT, GstGLContextPrivate))
|
||||
|
||||
static gpointer gst_gl_context_create_thread (GstGLContext * context);
|
||||
static void gst_gl_context_finalize (GObject * object);
|
||||
|
||||
struct _GstGLContextPrivate
|
||||
{
|
||||
GstGLDisplay *display;
|
||||
|
||||
GThread *gl_thread;
|
||||
|
||||
/* conditions */
|
||||
GMutex render_lock;
|
||||
GCond create_cond;
|
||||
GCond destroy_cond;
|
||||
|
||||
gboolean created;
|
||||
gboolean alive;
|
||||
|
||||
guintptr external_gl_context;
|
||||
GstGLAPI gl_api;
|
||||
GError **error;
|
||||
};
|
||||
|
||||
GQuark
|
||||
gst_gl_context_error_quark (void)
|
||||
{
|
||||
return g_quark_from_static_string ("gst-gl-context-error-quark");
|
||||
}
|
||||
|
||||
static void
|
||||
_ensure_window (GstGLContext * context)
|
||||
{
|
||||
GstGLWindow *window;
|
||||
|
||||
if (context->window)
|
||||
return;
|
||||
|
||||
window = gst_gl_window_new (context->priv->display);
|
||||
|
||||
gst_gl_context_set_window (context, window);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_context_init (GstGLContext * context)
|
||||
{
|
||||
context->priv = GST_GL_CONTEXT_GET_PRIVATE (context);
|
||||
|
||||
g_mutex_init (&context->priv->render_lock);
|
||||
|
||||
g_cond_init (&context->priv->create_cond);
|
||||
g_cond_init (&context->priv->destroy_cond);
|
||||
context->priv->created = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_context_class_init (GstGLContextClass * klass)
|
||||
{
|
||||
g_type_class_add_private (klass, sizeof (GstGLContextPrivate));
|
||||
|
||||
klass->get_proc_address =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_context_default_get_proc_address);
|
||||
|
||||
G_OBJECT_CLASS (klass)->finalize = gst_gl_context_finalize;
|
||||
}
|
||||
|
||||
GstGLContext *
|
||||
gst_gl_context_new (GstGLDisplay * display)
|
||||
{
|
||||
GstGLContext *context = NULL;
|
||||
const gchar *user_choice;
|
||||
static volatile gsize _init = 0;
|
||||
|
||||
if (g_once_init_enter (&_init)) {
|
||||
GST_DEBUG_CATEGORY_INIT (gst_gl_context_debug, "glcontext", 0,
|
||||
"glcontext element");
|
||||
g_once_init_leave (&_init, 1);
|
||||
}
|
||||
|
||||
user_choice = g_getenv ("GST_GL_PLATFORM");
|
||||
GST_INFO ("creating a context, user choice:%s", user_choice);
|
||||
#if 0
|
||||
#if GST_GL_HAVE_PLATFORM_EGL
|
||||
if (!context && (!user_choice || g_strstr_len (user_choice, 7, "egl")))
|
||||
context = GST_GL_CONTEXT (gst_gl_context_egl_new ());
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_GLX
|
||||
if (!context && (!user_choice || g_strstr_len (user_choice, 3, "glx")))
|
||||
context = GST_GL_CONTEXT (gst_gl_context_glx_new ());
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_WIN32
|
||||
if (!context && (!user_choice || g_strstr_len (user_choice, 5, "win32")))
|
||||
context = GST_GL_CONTEXT (gst_gl_context_win32_new ());
|
||||
#endif
|
||||
#if GST_GL_HAVE_PLATFORM_COCOA
|
||||
if (!context && (!user_choice || g_strstr_len (user_choice, 5, "cocoa"))) {
|
||||
context = GST_GL_CONTEXT (gst_gl_context_cocoa_new ());
|
||||
}
|
||||
#endif
|
||||
if (!context) {
|
||||
/* subclass returned a NULL context */
|
||||
GST_WARNING ("Could not create context. user specified %s",
|
||||
user_choice ? user_choice : "(null)");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
context = g_object_new (GST_GL_TYPE_CONTEXT, NULL);
|
||||
|
||||
context->priv->display = display;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_context_finalize (GObject * object)
|
||||
{
|
||||
GstGLContext *context = GST_GL_CONTEXT (object);
|
||||
|
||||
gst_gl_window_set_resize_callback (context->window, NULL, NULL, NULL);
|
||||
gst_gl_window_set_draw_callback (context->window, NULL, NULL, NULL);
|
||||
|
||||
if (context->priv->alive) {
|
||||
GST_INFO ("send quit gl window loop");
|
||||
gst_gl_window_quit (context->window);
|
||||
g_cond_wait (&context->priv->destroy_cond, &context->priv->render_lock);
|
||||
}
|
||||
|
||||
gst_gl_window_set_close_callback (context->window, NULL, NULL, NULL);
|
||||
|
||||
if (context->priv->gl_thread) {
|
||||
gpointer ret = g_thread_join (context->priv->gl_thread);
|
||||
GST_INFO ("gl thread joined");
|
||||
if (ret != NULL)
|
||||
GST_ERROR ("gl thread returned a non-null pointer");
|
||||
context->priv->gl_thread = NULL;
|
||||
}
|
||||
|
||||
gst_object_unref (context->window);
|
||||
|
||||
g_mutex_clear (&context->priv->render_lock);
|
||||
|
||||
g_cond_clear (&context->priv->destroy_cond);
|
||||
g_cond_clear (&context->priv->create_cond);
|
||||
|
||||
G_OBJECT_CLASS (gst_gl_context_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/* FIXME move the relevant window vfuncs into GstGLContext */
|
||||
gboolean
|
||||
gst_gl_context_activate (GstGLContext * context, gboolean activate)
|
||||
{
|
||||
GstGLWindowClass *window_class;
|
||||
gboolean result;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), FALSE);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
||||
g_return_val_if_fail (window_class->activate != NULL, FALSE);
|
||||
|
||||
result = window_class->activate (context->window, activate);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
gst_gl_context_get_gl_api (GstGLContext * context)
|
||||
{
|
||||
GstGLWindowClass *window_class;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), GST_GL_API_NONE);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
||||
g_return_val_if_fail (window_class->get_gl_api != NULL, GST_GL_API_NONE);
|
||||
|
||||
return window_class->get_gl_api (context->window);
|
||||
}
|
||||
|
||||
gpointer
|
||||
gst_gl_context_get_proc_address (GstGLContext * context, const gchar * name)
|
||||
{
|
||||
gpointer ret;
|
||||
GstGLWindowClass *window_class;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), NULL);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
||||
g_return_val_if_fail (window_class->get_proc_address != NULL, NULL);
|
||||
|
||||
ret = window_class->get_proc_address (context->window, name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gst_gl_context_default_get_proc_address (GstGLContext * context,
|
||||
const gchar * name)
|
||||
{
|
||||
static GModule *module = NULL;
|
||||
gpointer ret = NULL;
|
||||
|
||||
if (!module)
|
||||
module = g_module_open (NULL, G_MODULE_BIND_LAZY);
|
||||
|
||||
if (module) {
|
||||
if (!g_module_symbol (module, name, &ret))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_context_set_window (GstGLContext * context, GstGLWindow * window)
|
||||
{
|
||||
/* we can't change the window while we are running */
|
||||
if (context->priv->alive)
|
||||
return FALSE;
|
||||
|
||||
if (window) {
|
||||
if (gst_gl_window_is_running (window))
|
||||
return FALSE;
|
||||
|
||||
g_weak_ref_set (&window->context_ref, context);
|
||||
}
|
||||
|
||||
if (context->window)
|
||||
gst_object_unref (context->window);
|
||||
|
||||
context->window = window ? gst_object_ref (window) : NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstGLWindow *
|
||||
gst_gl_context_get_window (GstGLContext * context)
|
||||
{
|
||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), NULL);
|
||||
|
||||
_ensure_window (context);
|
||||
|
||||
return gst_object_ref (context->window);
|
||||
}
|
||||
|
||||
/* Create an opengl context (one context for one GstGLDisplay) */
|
||||
gboolean
|
||||
gst_gl_context_create (GstGLContext * context,
|
||||
guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
gboolean alive = FALSE;
|
||||
GstGLWindowClass *window_class;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), FALSE);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
||||
g_return_val_if_fail (window_class->create_context != NULL, FALSE);
|
||||
|
||||
_ensure_window (context);
|
||||
|
||||
g_mutex_lock (&context->priv->render_lock);
|
||||
|
||||
if (window_class->open) {
|
||||
if (!(alive = window_class->open (context->window, error)))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!context->priv->created) {
|
||||
context->priv->external_gl_context = external_gl_context;
|
||||
context->priv->error = error;
|
||||
|
||||
context->priv->gl_thread = g_thread_new ("gstglcontext",
|
||||
(GThreadFunc) gst_gl_context_create_thread, context);
|
||||
|
||||
g_cond_wait (&context->priv->create_cond, &context->priv->render_lock);
|
||||
|
||||
context->priv->created = TRUE;
|
||||
|
||||
GST_INFO ("gl thread created");
|
||||
}
|
||||
|
||||
alive = context->priv->alive;
|
||||
|
||||
g_mutex_unlock (&context->priv->render_lock);
|
||||
|
||||
out:
|
||||
return alive;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_create_context_gles2 (GstGLContext * context, gint * gl_major, gint * gl_minor,
|
||||
GError ** error)
|
||||
{
|
||||
GstGLDisplay *display;
|
||||
const GstGLFuncs *gl;
|
||||
GLenum gl_err = GL_NO_ERROR;
|
||||
|
||||
display = context->priv->display;
|
||||
gl = display->gl_vtable;
|
||||
|
||||
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
|
||||
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
|
||||
gl->GetString (GL_SHADING_LANGUAGE_VERSION));
|
||||
GST_INFO ("GL_VENDOR: %s", gl->GetString (GL_VENDOR));
|
||||
GST_INFO ("GL_RENDERER: %s", gl->GetString (GL_RENDERER));
|
||||
|
||||
gl_err = gl->GetError ();
|
||||
if (gl_err != GL_NO_ERROR) {
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||
"glGetString error: 0x%x", gl_err);
|
||||
return FALSE;
|
||||
}
|
||||
#if GST_GL_HAVE_GLES2
|
||||
if (!GL_ES_VERSION_2_0) {
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_OLD_LIBS,
|
||||
"OpenGL|ES >= 2.0 is required");
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
_gst_gl_feature_check_ext_functions (display, 0, 0,
|
||||
(const gchar *) gl->GetString (GL_EXTENSIONS));
|
||||
|
||||
if (gl_major)
|
||||
*gl_major = 2;
|
||||
if (gl_minor)
|
||||
*gl_minor = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_create_context_opengl (GstGLContext * context, gint * gl_major,
|
||||
gint * gl_minor, GError ** error)
|
||||
{
|
||||
GstGLDisplay *display;
|
||||
const GstGLFuncs *gl;
|
||||
guint maj, min;
|
||||
GLenum gl_err = GL_NO_ERROR;
|
||||
GString *opengl_version = NULL;
|
||||
|
||||
display = context->priv->display;
|
||||
gl = display->gl_vtable;
|
||||
|
||||
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
|
||||
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
|
||||
gl->GetString (GL_SHADING_LANGUAGE_VERSION));
|
||||
GST_INFO ("GL_VENDOR: %s", gl->GetString (GL_VENDOR));
|
||||
GST_INFO ("GL_RENDERER: %s", gl->GetString (GL_RENDERER));
|
||||
|
||||
gl_err = gl->GetError ();
|
||||
if (gl_err != GL_NO_ERROR) {
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||
"glGetString error: 0x%x", gl_err);
|
||||
return FALSE;
|
||||
}
|
||||
opengl_version =
|
||||
g_string_truncate (g_string_new ((gchar *) gl->GetString (GL_VERSION)),
|
||||
3);
|
||||
|
||||
sscanf (opengl_version->str, "%d.%d", &maj, &min);
|
||||
|
||||
g_string_free (opengl_version, TRUE);
|
||||
|
||||
/* OpenGL > 1.2.0 */
|
||||
if ((maj < 1) || (maj < 2 && maj >= 1 && min < 2)) {
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_OLD_LIBS,
|
||||
"OpenGL >= 1.2.0 required, found %u.%u", maj, min);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_gst_gl_feature_check_ext_functions (display, maj, min,
|
||||
(const gchar *) gl->GetString (GL_EXTENSIONS));
|
||||
|
||||
if (gl_major)
|
||||
*gl_major = maj;
|
||||
if (gl_minor)
|
||||
*gl_minor = min;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
_compiled_api (void)
|
||||
{
|
||||
GstGLAPI ret = GST_GL_API_NONE;
|
||||
|
||||
#if GST_GL_HAVE_OPENGL
|
||||
ret |= GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
|
||||
#endif
|
||||
#if GST_GL_HAVE_GLES2
|
||||
ret |= GST_GL_API_GLES2;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
_parse_gl_api (const gchar * apis_s)
|
||||
{
|
||||
GstGLAPI ret = GST_GL_API_NONE;
|
||||
gchar *apis = (gchar *) apis_s;
|
||||
|
||||
while (apis) {
|
||||
if (apis[0] == '\0') {
|
||||
break;
|
||||
} else if (apis[0] == ' ' || apis[0] == ',') {
|
||||
apis = &apis[1];
|
||||
} else if (g_strstr_len (apis, 7, "opengl3")) {
|
||||
ret |= GST_GL_API_OPENGL3;
|
||||
apis = &apis[7];
|
||||
} else if (g_strstr_len (apis, 6, "opengl")) {
|
||||
ret |= GST_GL_API_OPENGL;
|
||||
apis = &apis[6];
|
||||
} else if (g_strstr_len (apis, 5, "gles1")) {
|
||||
ret |= GST_GL_API_GLES;
|
||||
apis = &apis[5];
|
||||
} else if (g_strstr_len (apis, 5, "gles2")) {
|
||||
ret |= GST_GL_API_GLES2;
|
||||
apis = &apis[5];
|
||||
} else if (g_strstr_len (apis, 5, "gles3")) {
|
||||
ret |= GST_GL_API_GLES3;
|
||||
apis = &apis[5];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == GST_GL_API_NONE)
|
||||
ret = GST_GL_API_ANY;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//gboolean
|
||||
//gst_gl_context_create (GstGLContext * context, guintptr external_gl_context, GError ** error)
|
||||
static gpointer
|
||||
gst_gl_context_create_thread (GstGLContext * context)
|
||||
{
|
||||
GstGLWindowClass *window_class;
|
||||
GstGLDisplay *display;
|
||||
GstGLFuncs *gl;
|
||||
gint gl_major = 0;
|
||||
gboolean ret = FALSE;
|
||||
GstGLAPI compiled_api, user_api;
|
||||
gchar *api_string;
|
||||
gchar *compiled_api_s;
|
||||
gchar *user_api_string;
|
||||
const gchar *user_choice;
|
||||
GError **error;
|
||||
guintptr external_gl_context;
|
||||
|
||||
error = context->priv->error;
|
||||
external_gl_context = context->priv->external_gl_context;
|
||||
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (context->window);
|
||||
|
||||
if (window_class->open) {
|
||||
if (!window_class->open (context->window, error))
|
||||
goto failure;
|
||||
}
|
||||
|
||||
display = context->priv->display;
|
||||
gl = display->gl_vtable;
|
||||
compiled_api = _compiled_api ();
|
||||
|
||||
user_choice = g_getenv ("GST_GL_API");
|
||||
|
||||
user_api = _parse_gl_api (user_choice);
|
||||
user_api_string = gst_gl_api_string (user_api);
|
||||
|
||||
compiled_api_s = gst_gl_api_string (compiled_api);
|
||||
|
||||
if ((user_api & compiled_api) == GST_GL_API_NONE) {
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API,
|
||||
"Cannot create context with the user requested api (%s). "
|
||||
"We have support for (%s)", user_api_string, compiled_api_s);
|
||||
g_free (user_api_string);
|
||||
g_free (compiled_api_s);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
GST_INFO ("Attempting to create opengl context. user chosen api(s) (%s), "
|
||||
"compiled api support (%s)", user_api_string, compiled_api_s);
|
||||
|
||||
if (!window_class->create_context (context->window, compiled_api & user_api,
|
||||
external_gl_context, error)) {
|
||||
g_assert (error == NULL || *error != NULL);
|
||||
g_free (compiled_api_s);
|
||||
g_free (user_api_string);
|
||||
goto failure;
|
||||
}
|
||||
GST_INFO ("context created context");
|
||||
|
||||
display->gl_api = gst_gl_context_get_gl_api (context);
|
||||
g_assert (display->gl_api != GST_GL_API_NONE
|
||||
&& display->gl_api != GST_GL_API_ANY);
|
||||
|
||||
api_string = gst_gl_api_string (display->gl_api);
|
||||
GST_INFO ("available GL APIs: %s", api_string);
|
||||
|
||||
if (((compiled_api & display->gl_api) & user_api) == GST_GL_API_NONE) {
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API,
|
||||
"failed to create context, context "
|
||||
"could not provide correct api. user (%s), compiled (%s), context (%s)",
|
||||
user_api_string, compiled_api_s, api_string);
|
||||
g_free (api_string);
|
||||
g_free (compiled_api_s);
|
||||
g_free (user_api_string);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
g_free (api_string);
|
||||
g_free (compiled_api_s);
|
||||
g_free (user_api_string);
|
||||
|
||||
gl->GetError = gst_gl_context_get_proc_address (context, "glGetError");
|
||||
gl->GetString = gst_gl_context_get_proc_address (context, "glGetString");
|
||||
|
||||
if (!gl->GetError || !gl->GetString) {
|
||||
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||
"could not GetProcAddress core opengl functions");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* gl api specific code */
|
||||
if (!ret && USING_OPENGL (display))
|
||||
ret = _create_context_opengl (context, &gl_major, NULL, error);
|
||||
if (!ret && USING_GLES2 (display))
|
||||
ret = _create_context_gles2 (context, &gl_major, NULL, error);
|
||||
|
||||
if (!ret)
|
||||
goto failure;
|
||||
|
||||
context->priv->alive = TRUE;
|
||||
|
||||
g_cond_signal (&context->priv->create_cond);
|
||||
g_mutex_unlock (&context->priv->render_lock);
|
||||
|
||||
gst_gl_window_run (context->window);
|
||||
|
||||
GST_INFO ("loop exited\n");
|
||||
|
||||
g_mutex_lock (&context->priv->render_lock);
|
||||
|
||||
context->priv->alive = FALSE;
|
||||
|
||||
if (window_class->close) {
|
||||
window_class->close (context->window);
|
||||
}
|
||||
|
||||
context_class->activate (context, FALSE);
|
||||
|
||||
context_class->destroy_context (context);
|
||||
|
||||
if (context->window->close)
|
||||
context->window->close (context->window->close_data);
|
||||
|
||||
g_cond_signal (&context->priv->destroy_cond);
|
||||
|
||||
g_mutex_unlock (&context->priv->render_lock);
|
||||
|
||||
return NULL;
|
||||
|
||||
failure:
|
||||
{
|
||||
g_cond_signal (&context->priv->create_cond);
|
||||
g_mutex_unlock (&context->priv->render_lock);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
guintptr
|
||||
gst_gl_context_get_gl_context (GstGLContext * context)
|
||||
{
|
||||
GstGLContextClass *context_class;
|
||||
guintptr result;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), 0);
|
||||
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||
g_return_val_if_fail (context_class->get_gl_context != NULL, 0);
|
||||
|
||||
result = context_class->get_gl_context (context);
|
||||
|
||||
return result;
|
||||
}
|
98
gst-libs/gst/gl/gstglcontext.h
Normal file
98
gst-libs/gst/gl/gstglcontext.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* GStreamer
|
||||
* Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_GL_CONTEXT_H__
|
||||
#define __GST_GL_CONTEXT_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <gst/gl/gstgl_fwd.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_GL_TYPE_CONTEXT (gst_gl_context_get_type())
|
||||
#define GST_GL_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_CAST((o), GST_GL_TYPE_CONTEXT, GstGLContext))
|
||||
#define GST_GL_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS((k), GST_GL_TYPE_CONTEXT, GstGLContextClass))
|
||||
#define GST_GL_IS_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_GL_TYPE_CONTEXT))
|
||||
#define GST_GL_IS_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), GST_GL_TYPE_CONTEXT))
|
||||
#define GST_GL_CONTEXT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_GL_TYPE_CONTEXT, GstGLContextClass))
|
||||
GType gst_gl_context_get_type (void);
|
||||
|
||||
#define GST_GL_CONTEXT_ERROR (gst_gl_context_error_quark ())
|
||||
GQuark gst_gl_window_error_quark (void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_GL_CONTEXT_ERROR_FAILED,
|
||||
GST_GL_CONTEXT_ERROR_WRONG_CONFIG,
|
||||
GST_GL_CONTEXT_ERROR_WRONG_API,
|
||||
GST_GL_CONTEXT_ERROR_OLD_LIBS,
|
||||
GST_GL_CONTEXT_ERROR_CREATE_CONTEXT,
|
||||
GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE,
|
||||
} GstGLContextError;
|
||||
|
||||
struct _GstGLContext {
|
||||
/*< private >*/
|
||||
GObject parent;
|
||||
|
||||
/*< public >*/
|
||||
GstGLWindow *window;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[GST_PADDING];
|
||||
|
||||
GstGLContextPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GstGLContextClass {
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
guintptr (*get_gl_context) (GstGLContext *context);
|
||||
GstGLAPI (*get_gl_api) (GstGLContext *context);
|
||||
gpointer (*get_proc_address) (GstGLContext *context, const gchar *name);
|
||||
gboolean (*activate) (GstGLContext *context, gboolean activate);
|
||||
gboolean (*create_context) (GstGLContext *context, GstGLAPI gl_api,
|
||||
guintptr external_gl_context, GError ** error);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
/* methods */
|
||||
|
||||
GstGLContext * gst_gl_context_new (GstGLDisplay *display);
|
||||
|
||||
gboolean gst_gl_context_activate (GstGLContext *context, gboolean activate);
|
||||
|
||||
gpointer gst_gl_context_get_proc_address (GstGLContext *context, const gchar *name);
|
||||
GstGLPlatform gst_gl_context_get_platform (GstGLContext *context);
|
||||
GstGLAPI gst_gl_context_get_gl_api (GstGLContext *context);
|
||||
|
||||
gboolean gst_gl_context_create (GstGLContext *context, guintptr external_gl_context, GError ** error);
|
||||
|
||||
gpointer gst_gl_context_default_get_proc_address (GstGLContext *context, const gchar *name);
|
||||
|
||||
gboolean gst_gl_context_set_window (GstGLContext *context, GstGLWindow *window);
|
||||
GstGLWindow * gst_gl_context_get_window (GstGLContext *context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_GL_CONTEXT_H__ */
|
|
@ -81,14 +81,21 @@ gst_gl_display_finalize (GObject * object)
|
|||
display->gl_vtable = NULL;
|
||||
}
|
||||
|
||||
if (display->window) {
|
||||
gst_object_unref (display->window);
|
||||
display->window = NULL;
|
||||
if (display->context) {
|
||||
gst_object_unref (display->context);
|
||||
display->context = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gst_gl_display_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
GstGLDisplay *
|
||||
gst_gl_display_new (void)
|
||||
{
|
||||
return g_object_new (GST_TYPE_GL_DISPLAY, NULL);
|
||||
}
|
||||
|
||||
#if 1
|
||||
typedef struct
|
||||
{
|
||||
GstGLDisplay *display;
|
||||
|
@ -104,37 +111,36 @@ _gst_gl_display_thread_run_generic (RunGenericData * data)
|
|||
data->func (data->display, data->data);
|
||||
}
|
||||
|
||||
GstGLDisplay *
|
||||
gst_gl_display_new (void)
|
||||
{
|
||||
return g_object_new (GST_TYPE_GL_DISPLAY, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gst_gl_display_thread_add (GstGLDisplay * display,
|
||||
GstGLDisplayThreadFunc func, gpointer data)
|
||||
{
|
||||
GstGLWindow *window;
|
||||
RunGenericData rdata;
|
||||
|
||||
g_return_if_fail (GST_IS_GL_DISPLAY (display));
|
||||
g_return_if_fail (GST_GL_IS_WINDOW (display->window));
|
||||
g_return_if_fail (GST_GL_IS_CONTEXT (display->context));
|
||||
g_return_if_fail (func != NULL);
|
||||
|
||||
rdata.display = display;
|
||||
rdata.data = data;
|
||||
rdata.func = func;
|
||||
|
||||
gst_gl_window_send_message (display->window,
|
||||
window = gst_gl_context_get_window (display->context);
|
||||
|
||||
gst_gl_window_send_message (window,
|
||||
GST_GL_WINDOW_CB (_gst_gl_display_thread_run_generic), &rdata);
|
||||
|
||||
gst_object_unref (window);
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
gst_gl_display_get_gl_api (GstGLDisplay * display)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_API_NONE);
|
||||
g_return_val_if_fail (GST_GL_IS_WINDOW (display->window), GST_GL_API_NONE);
|
||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (display->context), GST_GL_API_NONE);
|
||||
|
||||
return gst_gl_window_get_gl_api (display->window);
|
||||
return gst_gl_context_get_gl_api (display->context);
|
||||
}
|
||||
|
||||
gpointer
|
||||
|
@ -144,45 +150,46 @@ gst_gl_display_get_gl_vtable (GstGLDisplay * display)
|
|||
|
||||
return display->gl_vtable;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
gst_gl_display_set_window (GstGLDisplay * display, GstGLWindow * window)
|
||||
gst_gl_display_set_context (GstGLDisplay * display, GstGLContext * context)
|
||||
{
|
||||
g_return_if_fail (GST_IS_GL_DISPLAY (display));
|
||||
g_return_if_fail (GST_GL_IS_WINDOW (window));
|
||||
g_return_if_fail (GST_GL_IS_CONTEXT (context));
|
||||
|
||||
gst_gl_display_lock (display);
|
||||
|
||||
if (display->window)
|
||||
gst_object_unref (display->window);
|
||||
if (display->context)
|
||||
gst_object_unref (display->context);
|
||||
|
||||
display->window = gst_object_ref (window);
|
||||
display->context = gst_object_ref (context);
|
||||
|
||||
gst_gl_display_unlock (display);
|
||||
}
|
||||
|
||||
GstGLWindow *
|
||||
gst_gl_display_get_window (GstGLDisplay * display)
|
||||
GstGLContext *
|
||||
gst_gl_display_get_context (GstGLDisplay * display)
|
||||
{
|
||||
GstGLWindow *window;
|
||||
GstGLContext *context;
|
||||
|
||||
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);
|
||||
|
||||
gst_gl_display_lock (display);
|
||||
|
||||
window = display->window ? gst_object_ref (display->window) : NULL;
|
||||
context = display->context ? gst_object_ref (display->context) : NULL;
|
||||
|
||||
gst_gl_display_unlock (display);
|
||||
|
||||
return window;
|
||||
return context;
|
||||
}
|
||||
|
||||
GstGLWindow *
|
||||
gst_gl_display_get_window_unlocked (GstGLDisplay * display)
|
||||
GstGLContext *
|
||||
gst_gl_display_get_context_unlocked (GstGLDisplay * display)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);
|
||||
|
||||
return display->window ? gst_object_ref (display->window) : NULL;
|
||||
return display->context ? gst_object_ref (display->context) : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -57,7 +57,7 @@ struct _GstGLDisplay
|
|||
GstObject object;
|
||||
|
||||
/* <private> */
|
||||
GstGLWindow *window;
|
||||
GstGLContext *context;
|
||||
GstGLAPI gl_api;
|
||||
|
||||
GstGLFuncs *gl_vtable;
|
||||
|
@ -75,11 +75,11 @@ GstGLDisplay *gst_gl_display_new (void);
|
|||
#define gst_gl_display_lock(display) GST_OBJECT_LOCK (display)
|
||||
#define gst_gl_display_unlock(display) GST_OBJECT_UNLOCK (display)
|
||||
|
||||
GstGLAPI gst_gl_display_get_gl_api (GstGLDisplay * display);
|
||||
gpointer gst_gl_display_get_gl_vtable (GstGLDisplay * display);
|
||||
void gst_gl_display_set_window (GstGLDisplay * display, GstGLWindow * window);
|
||||
GstGLWindow * gst_gl_display_get_window (GstGLDisplay * display);
|
||||
GstGLWindow * gst_gl_display_get_window_unlocked (GstGLDisplay * display);
|
||||
GstGLAPI gst_gl_display_get_gl_api (GstGLDisplay * display);
|
||||
gpointer gst_gl_display_get_gl_vtable (GstGLDisplay * display);
|
||||
void gst_gl_display_set_context (GstGLDisplay * display, GstGLContext * context);
|
||||
GstGLContext * gst_gl_display_get_context (GstGLDisplay * display);
|
||||
GstGLContext * gst_gl_display_get_context_unlocked (GstGLDisplay * display);
|
||||
|
||||
void gst_gl_display_thread_add (GstGLDisplay * display,
|
||||
GstGLDisplayThreadFunc func, gpointer data);
|
||||
|
|
|
@ -149,7 +149,7 @@ _gst_gl_feature_check (GstGLDisplay * display,
|
|||
const char *suffix = NULL;
|
||||
int func_num;
|
||||
GstGLFuncs *gst_gl = display->gl_vtable;
|
||||
GstGLWindow *window = NULL;
|
||||
GstGLContext *context = NULL;
|
||||
|
||||
/* First check whether the functions should be directly provided by
|
||||
GL */
|
||||
|
@ -172,8 +172,8 @@ _gst_gl_feature_check (GstGLDisplay * display,
|
|||
if (suffix == NULL)
|
||||
goto error;
|
||||
|
||||
window = gst_gl_display_get_window (display);
|
||||
g_assert (window);
|
||||
context = gst_gl_display_get_context (display);
|
||||
g_assert (context);
|
||||
|
||||
/* Try to get all of the entry points */
|
||||
for (func_num = 0; data->functions[func_num].name; func_num++) {
|
||||
|
@ -186,7 +186,7 @@ _gst_gl_feature_check (GstGLDisplay * display,
|
|||
suffix, NULL);
|
||||
GST_TRACE ("%s should %sbe in core", full_function_name,
|
||||
in_core ? "" : "not ");
|
||||
func = gst_gl_window_get_proc_address (window, full_function_name);
|
||||
func = gst_gl_context_get_proc_address (context, full_function_name);
|
||||
|
||||
if (func == NULL && in_core) {
|
||||
GST_TRACE ("%s was not found in core, trying the extension version",
|
||||
|
@ -198,7 +198,7 @@ _gst_gl_feature_check (GstGLDisplay * display,
|
|||
g_free (full_function_name);
|
||||
full_function_name = g_strconcat ("gl", data->functions[func_num].name,
|
||||
suffix, NULL);
|
||||
func = gst_gl_window_get_proc_address (window, full_function_name);
|
||||
func = gst_gl_context_get_proc_address (context, full_function_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ _gst_gl_feature_check (GstGLDisplay * display,
|
|||
}
|
||||
|
||||
g_free (full_function_name);
|
||||
gst_object_unref (window);
|
||||
gst_object_unref (context);
|
||||
|
||||
return TRUE;
|
||||
|
||||
|
@ -232,8 +232,8 @@ error:
|
|||
g_free (full_function_name);
|
||||
}
|
||||
|
||||
if (window)
|
||||
gst_object_unref (window);
|
||||
if (context)
|
||||
gst_object_unref (context);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -256,16 +256,16 @@ gst_gl_filter_start (GstBaseTransform * bt)
|
|||
filter->display =
|
||||
gst_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
|
||||
else {
|
||||
GstGLWindow *window;
|
||||
GstGLContext *context;
|
||||
GError *error = NULL;
|
||||
|
||||
GST_INFO ("Creating GstGLDisplay");
|
||||
filter->display = gst_gl_display_new ();
|
||||
window = gst_gl_window_new (filter->display);
|
||||
gst_gl_display_set_window (filter->display, window);
|
||||
gst_object_unref (window);
|
||||
context = gst_gl_context_new (filter->display);
|
||||
gst_gl_display_set_context (filter->display, context);
|
||||
gst_object_unref (context);
|
||||
|
||||
if (!gst_gl_window_create_context (window, 0, &error)) {
|
||||
if (!gst_gl_context_create (context, 0, &error)) {
|
||||
GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND,
|
||||
("%s", error->message), (NULL));
|
||||
return FALSE;
|
||||
|
|
|
@ -935,16 +935,16 @@ gst_gl_mixer_activate (GstGLMixer * mix, gboolean activate)
|
|||
mix->display =
|
||||
gst_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
|
||||
else {
|
||||
GstGLWindow *window;
|
||||
GstGLContext *context;
|
||||
GError *error = NULL;
|
||||
|
||||
GST_INFO ("Creating GstGLDisplay");
|
||||
mix->display = gst_gl_display_new ();
|
||||
window = gst_gl_window_new (mix->display);
|
||||
gst_gl_display_set_window (mix->display, window);
|
||||
gst_object_unref (window);
|
||||
context = gst_gl_context_new (mix->display);
|
||||
gst_gl_display_set_context (mix->display, context);
|
||||
gst_object_unref (context);
|
||||
|
||||
if (!gst_gl_window_create_context (window, 0, &error)) {
|
||||
if (!gst_gl_context_create (context, 0, &error)) {
|
||||
GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND,
|
||||
("%s", error->message), (NULL));
|
||||
return FALSE;
|
||||
|
|
|
@ -141,32 +141,34 @@ gst_gl_display_check_framebuffer_status (GstGLDisplay * display)
|
|||
void
|
||||
gst_gl_display_activate_gl_context (GstGLDisplay * display, gboolean activate)
|
||||
{
|
||||
GstGLWindow *window;
|
||||
GstGLContext *context;
|
||||
|
||||
g_return_if_fail (GST_IS_GL_DISPLAY (display));
|
||||
|
||||
if (!activate)
|
||||
gst_gl_display_lock (display);
|
||||
|
||||
window = gst_gl_display_get_window_unlocked (display);
|
||||
context = gst_gl_display_get_context_unlocked (display);
|
||||
|
||||
gst_gl_window_activate (window, activate);
|
||||
gst_gl_context_activate (context, activate);
|
||||
|
||||
if (activate)
|
||||
gst_gl_display_unlock (display);
|
||||
|
||||
gst_object_unref (window);
|
||||
gst_object_unref (context);
|
||||
}
|
||||
|
||||
void
|
||||
gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture,
|
||||
GstVideoFormat v_format, GLint width, GLint height)
|
||||
{
|
||||
GstGLContext *context;
|
||||
GstGLWindow *window;
|
||||
|
||||
gst_gl_display_lock (display);
|
||||
|
||||
window = gst_gl_display_get_window_unlocked (display);
|
||||
context = gst_gl_display_get_context_unlocked (display);
|
||||
window = gst_gl_context_get_window (context);
|
||||
|
||||
if (gst_gl_window_is_running (window)) {
|
||||
gen_texture_width = width;
|
||||
|
@ -178,6 +180,7 @@ gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture,
|
|||
} else
|
||||
*pTexture = 0;
|
||||
|
||||
gst_object_unref (context);
|
||||
gst_object_unref (window);
|
||||
|
||||
gst_gl_display_unlock (display);
|
||||
|
@ -186,17 +189,20 @@ gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture,
|
|||
void
|
||||
gst_gl_display_del_texture (GstGLDisplay * display, GLuint * pTexture)
|
||||
{
|
||||
GstGLContext *context;
|
||||
GstGLWindow *window;
|
||||
|
||||
gst_gl_display_lock (display);
|
||||
|
||||
window = gst_gl_display_get_window_unlocked (display);
|
||||
context = gst_gl_display_get_context_unlocked (display);
|
||||
window = gst_gl_context_get_window (context);
|
||||
if (gst_gl_window_is_running (window) && *pTexture) {
|
||||
del_texture = pTexture;
|
||||
gst_gl_window_send_message (window,
|
||||
GST_GL_WINDOW_CB (gst_gl_display_del_texture_window_cb), display);
|
||||
}
|
||||
|
||||
gst_object_unref (context);
|
||||
gst_object_unref (window);
|
||||
|
||||
gst_gl_display_unlock (display);
|
||||
|
|
|
@ -78,7 +78,6 @@ struct _GstGLWindowPrivate
|
|||
GError **error;
|
||||
};
|
||||
|
||||
static gpointer _gst_gl_window_thread_create_context (GstGLWindow * window);
|
||||
static void gst_gl_window_finalize (GObject * object);
|
||||
|
||||
GQuark
|
||||
|
@ -99,6 +98,8 @@ gst_gl_window_init (GstGLWindow * window)
|
|||
g_cond_init (&window->priv->cond_create_context);
|
||||
g_cond_init (&window->priv->cond_destroy_context);
|
||||
window->priv->context_created = FALSE;
|
||||
|
||||
g_weak_ref_init (&window->context_ref, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -106,9 +107,6 @@ gst_gl_window_class_init (GstGLWindowClass * klass)
|
|||
{
|
||||
g_type_class_add_private (klass, sizeof (GstGLWindowPrivate));
|
||||
|
||||
klass->get_proc_address =
|
||||
GST_DEBUG_FUNCPTR (gst_gl_window_default_get_proc_address);
|
||||
|
||||
G_OBJECT_CLASS (klass)->finalize = gst_gl_window_finalize;
|
||||
}
|
||||
|
||||
|
@ -167,28 +165,7 @@ gst_gl_window_finalize (GObject * object)
|
|||
{
|
||||
GstGLWindow *window = GST_GL_WINDOW (object);
|
||||
|
||||
gst_gl_window_set_resize_callback (window, NULL, NULL, NULL);
|
||||
gst_gl_window_set_draw_callback (window, NULL, NULL, NULL);
|
||||
|
||||
if (window->priv->alive) {
|
||||
GST_INFO ("send quit gl window loop");
|
||||
gst_gl_window_quit (window);
|
||||
}
|
||||
|
||||
gst_gl_window_set_close_callback (window, NULL, NULL, NULL);
|
||||
|
||||
if (window->priv->gl_thread) {
|
||||
gpointer ret = g_thread_join (window->priv->gl_thread);
|
||||
GST_INFO ("gl thread joined");
|
||||
if (ret != NULL)
|
||||
GST_ERROR ("gl thread returned a non-null pointer");
|
||||
window->priv->gl_thread = NULL;
|
||||
}
|
||||
|
||||
g_mutex_clear (&window->priv->render_lock);
|
||||
|
||||
g_cond_clear (&window->priv->cond_destroy_context);
|
||||
g_cond_clear (&window->priv->cond_create_context);
|
||||
g_weak_ref_clear (&window->context_ref);
|
||||
|
||||
G_OBJECT_CLASS (gst_gl_window_parent_class)->finalize (object);
|
||||
}
|
||||
|
@ -278,6 +255,7 @@ gst_gl_window_run (GstGLWindow * window)
|
|||
g_return_if_fail (window_class->run != NULL);
|
||||
|
||||
GST_GL_WINDOW_LOCK (window);
|
||||
window->priv->alive = TRUE;
|
||||
window_class->run (window);
|
||||
GST_GL_WINDOW_UNLOCK (window);
|
||||
}
|
||||
|
@ -301,7 +279,6 @@ gst_gl_window_quit (GstGLWindow * window)
|
|||
|
||||
GST_GL_WINDOW_UNLOCK (window);
|
||||
|
||||
g_cond_wait (&window->priv->cond_destroy_context, &window->priv->render_lock);
|
||||
GST_INFO ("quit received from gl window");
|
||||
}
|
||||
|
||||
|
@ -423,338 +400,16 @@ gst_gl_window_get_proc_address (GstGLWindow * window, const gchar * name)
|
|||
return ret;
|
||||
}
|
||||
|
||||
gpointer
|
||||
gst_gl_window_default_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name)
|
||||
{
|
||||
static GModule *module = NULL;
|
||||
gpointer ret = NULL;
|
||||
|
||||
if (!module)
|
||||
module = g_module_open (NULL, G_MODULE_BIND_LAZY);
|
||||
|
||||
if (module) {
|
||||
if (!g_module_symbol (module, name, &ret))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Create an opengl context (one context for one GstGLDisplay) */
|
||||
gboolean
|
||||
gst_gl_window_create_context (GstGLWindow * window,
|
||||
guintptr external_gl_context, GError ** error)
|
||||
{
|
||||
gboolean alive = FALSE;
|
||||
GstGLWindowClass *window_class;
|
||||
|
||||
g_return_val_if_fail (GST_GL_IS_WINDOW (window), FALSE);
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (window);
|
||||
g_return_val_if_fail (window_class->create_context != NULL, FALSE);
|
||||
|
||||
g_mutex_lock (&window->priv->render_lock);
|
||||
|
||||
if (window_class->open) {
|
||||
if (!(alive = window_class->open (window, error)))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!window->priv->context_created) {
|
||||
window->priv->external_gl_context = external_gl_context;
|
||||
window->priv->error = error;
|
||||
|
||||
window->priv->gl_thread = g_thread_new ("gstglcontext",
|
||||
(GThreadFunc) _gst_gl_window_thread_create_context, window);
|
||||
|
||||
g_cond_wait (&window->priv->cond_create_context,
|
||||
&window->priv->render_lock);
|
||||
|
||||
window->priv->context_created = TRUE;
|
||||
|
||||
GST_INFO ("gl thread created");
|
||||
}
|
||||
|
||||
alive = window->priv->alive;
|
||||
|
||||
g_mutex_unlock (&window->priv->render_lock);
|
||||
|
||||
out:
|
||||
return alive;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_gl_window_is_running (GstGLWindow * window)
|
||||
{
|
||||
return window->priv->alive;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_create_context_gles2 (GstGLWindow * window, gint * gl_major, gint * gl_minor,
|
||||
GError ** error)
|
||||
GstGLContext *
|
||||
gst_gl_window_get_context (GstGLWindow * window)
|
||||
{
|
||||
GstGLDisplay *display;
|
||||
const GstGLFuncs *gl;
|
||||
GLenum gl_err = GL_NO_ERROR;
|
||||
g_return_val_if_fail (GST_GL_IS_WINDOW (window), NULL);
|
||||
|
||||
display = window->priv->display;
|
||||
gl = display->gl_vtable;
|
||||
|
||||
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
|
||||
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
|
||||
gl->GetString (GL_SHADING_LANGUAGE_VERSION));
|
||||
GST_INFO ("GL_VENDOR: %s", gl->GetString (GL_VENDOR));
|
||||
GST_INFO ("GL_RENDERER: %s", gl->GetString (GL_RENDERER));
|
||||
|
||||
gl_err = gl->GetError ();
|
||||
if (gl_err != GL_NO_ERROR) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
|
||||
"glGetString error: 0x%x", gl_err);
|
||||
return FALSE;
|
||||
}
|
||||
#if GST_GL_HAVE_GLES2
|
||||
if (!GL_ES_VERSION_2_0) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_OLD_LIBS,
|
||||
"OpenGL|ES >= 2.0 is required");
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
_gst_gl_feature_check_ext_functions (display, 0, 0,
|
||||
(const gchar *) gl->GetString (GL_EXTENSIONS));
|
||||
|
||||
if (gl_major)
|
||||
*gl_major = 2;
|
||||
if (gl_minor)
|
||||
*gl_minor = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_create_context_opengl (GstGLWindow * window, gint * gl_major, gint * gl_minor,
|
||||
GError ** error)
|
||||
{
|
||||
GstGLDisplay *display;
|
||||
const GstGLFuncs *gl;
|
||||
guint maj, min;
|
||||
GLenum gl_err = GL_NO_ERROR;
|
||||
GString *opengl_version = NULL;
|
||||
|
||||
display = window->priv->display;
|
||||
gl = display->gl_vtable;
|
||||
|
||||
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
|
||||
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
|
||||
gl->GetString (GL_SHADING_LANGUAGE_VERSION));
|
||||
GST_INFO ("GL_VENDOR: %s", gl->GetString (GL_VENDOR));
|
||||
GST_INFO ("GL_RENDERER: %s", gl->GetString (GL_RENDERER));
|
||||
|
||||
gl_err = gl->GetError ();
|
||||
if (gl_err != GL_NO_ERROR) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
|
||||
"glGetString error: 0x%x", gl_err);
|
||||
return FALSE;
|
||||
}
|
||||
opengl_version =
|
||||
g_string_truncate (g_string_new ((gchar *) gl->GetString (GL_VERSION)),
|
||||
3);
|
||||
|
||||
sscanf (opengl_version->str, "%d.%d", &maj, &min);
|
||||
|
||||
g_string_free (opengl_version, TRUE);
|
||||
|
||||
/* OpenGL > 1.2.0 */
|
||||
if ((maj < 1) || (maj < 2 && maj >= 1 && min < 2)) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_OLD_LIBS,
|
||||
"OpenGL >= 1.2.0 required, found %u.%u", maj, min);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_gst_gl_feature_check_ext_functions (display, maj, min,
|
||||
(const gchar *) gl->GetString (GL_EXTENSIONS));
|
||||
|
||||
if (gl_major)
|
||||
*gl_major = maj;
|
||||
if (gl_minor)
|
||||
*gl_minor = min;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
_compiled_api (void)
|
||||
{
|
||||
GstGLAPI ret = GST_GL_API_NONE;
|
||||
|
||||
#if GST_GL_HAVE_OPENGL
|
||||
ret |= GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
|
||||
#endif
|
||||
#if GST_GL_HAVE_GLES2
|
||||
ret |= GST_GL_API_GLES2;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GstGLAPI
|
||||
_parse_gl_api (const gchar * apis_s)
|
||||
{
|
||||
GstGLAPI ret = GST_GL_API_NONE;
|
||||
gchar *apis = (gchar *) apis_s;
|
||||
|
||||
while (apis) {
|
||||
if (apis[0] == '\0') {
|
||||
break;
|
||||
} else if (apis[0] == ' ' || apis[0] == ',') {
|
||||
apis = &apis[1];
|
||||
} else if (g_strstr_len (apis, 7, "opengl3")) {
|
||||
ret |= GST_GL_API_OPENGL3;
|
||||
apis = &apis[7];
|
||||
} else if (g_strstr_len (apis, 6, "opengl")) {
|
||||
ret |= GST_GL_API_OPENGL;
|
||||
apis = &apis[6];
|
||||
} else if (g_strstr_len (apis, 5, "gles1")) {
|
||||
ret |= GST_GL_API_GLES;
|
||||
apis = &apis[5];
|
||||
} else if (g_strstr_len (apis, 5, "gles2")) {
|
||||
ret |= GST_GL_API_GLES2;
|
||||
apis = &apis[5];
|
||||
} else if (g_strstr_len (apis, 5, "gles3")) {
|
||||
ret |= GST_GL_API_GLES3;
|
||||
apis = &apis[5];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == GST_GL_API_NONE)
|
||||
ret = GST_GL_API_ANY;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
_gst_gl_window_thread_create_context (GstGLWindow * window)
|
||||
{
|
||||
GstGLWindowClass *window_class;
|
||||
GstGLDisplay *display;
|
||||
GstGLFuncs *gl;
|
||||
gint gl_major = 0;
|
||||
gboolean ret = FALSE;
|
||||
GstGLAPI compiled_api, user_api;
|
||||
gchar *api_string;
|
||||
gchar *compiled_api_s;
|
||||
gchar *user_api_string;
|
||||
const gchar *user_choice;
|
||||
GError **error;
|
||||
|
||||
window_class = GST_GL_WINDOW_GET_CLASS (window);
|
||||
error = window->priv->error;
|
||||
display = window->priv->display;
|
||||
|
||||
g_mutex_lock (&window->priv->render_lock);
|
||||
|
||||
gl = display->gl_vtable;
|
||||
compiled_api = _compiled_api ();
|
||||
|
||||
user_choice = g_getenv ("GST_GL_API");
|
||||
|
||||
user_api = _parse_gl_api (user_choice);
|
||||
user_api_string = gst_gl_api_string (user_api);
|
||||
|
||||
compiled_api_s = gst_gl_api_string (compiled_api);
|
||||
|
||||
if ((user_api & compiled_api) == GST_GL_API_NONE) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_API,
|
||||
"Cannot create context with the user requested api (%s). "
|
||||
"We have support for (%s)", user_api_string, compiled_api_s);
|
||||
g_free (user_api_string);
|
||||
g_free (compiled_api_s);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
GST_INFO ("Attempting to create opengl context. user chosen api(s) (%s), "
|
||||
"compiled api support (%s)", user_api_string, compiled_api_s);
|
||||
|
||||
if (!window_class->create_context (window, compiled_api & user_api,
|
||||
window->priv->external_gl_context, error)) {
|
||||
g_assert (error == NULL || *error != NULL);
|
||||
g_free (compiled_api_s);
|
||||
g_free (user_api_string);
|
||||
goto failure;
|
||||
}
|
||||
GST_INFO ("window created context");
|
||||
|
||||
display->gl_api = gst_gl_window_get_gl_api (window);
|
||||
g_assert (display->gl_api != GST_GL_API_NONE
|
||||
&& display->gl_api != GST_GL_API_ANY);
|
||||
|
||||
api_string = gst_gl_api_string (display->gl_api);
|
||||
GST_INFO ("available GL APIs: %s", api_string);
|
||||
|
||||
if (((compiled_api & display->gl_api) & user_api) == GST_GL_API_NONE) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_WRONG_API,
|
||||
"failed to create context, window "
|
||||
"could not provide correct api. user (%s), compiled (%s), window (%s)",
|
||||
user_api_string, compiled_api_s, api_string);
|
||||
g_free (api_string);
|
||||
g_free (compiled_api_s);
|
||||
g_free (user_api_string);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
g_free (api_string);
|
||||
g_free (compiled_api_s);
|
||||
g_free (user_api_string);
|
||||
|
||||
gl->GetError = gst_gl_window_get_proc_address (window, "glGetError");
|
||||
gl->GetString = gst_gl_window_get_proc_address (window, "glGetString");
|
||||
|
||||
if (!gl->GetError || !gl->GetString) {
|
||||
g_set_error (error, GST_GL_WINDOW_ERROR, GST_GL_WINDOW_ERROR_FAILED,
|
||||
"could not GetProcAddress core opengl functions");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* gl api specific code */
|
||||
if (!ret && USING_OPENGL (display))
|
||||
ret = _create_context_opengl (window, &gl_major, NULL, error);
|
||||
if (!ret && USING_GLES2 (display))
|
||||
ret = _create_context_gles2 (window, &gl_major, NULL, error);
|
||||
|
||||
if (!ret)
|
||||
goto failure;
|
||||
|
||||
g_cond_signal (&window->priv->cond_create_context);
|
||||
|
||||
window->priv->alive = TRUE;
|
||||
g_mutex_unlock (&window->priv->render_lock);
|
||||
|
||||
gst_gl_window_run (window);
|
||||
|
||||
GST_INFO ("loop exited\n");
|
||||
|
||||
g_mutex_lock (&window->priv->render_lock);
|
||||
|
||||
window->priv->alive = FALSE;
|
||||
|
||||
if (window_class->close) {
|
||||
window_class->close (window);
|
||||
if (window->close)
|
||||
window->close (window->close_data);
|
||||
}
|
||||
|
||||
g_cond_signal (&window->priv->cond_destroy_context);
|
||||
|
||||
g_mutex_unlock (&window->priv->render_lock);
|
||||
|
||||
return NULL;
|
||||
|
||||
failure:
|
||||
{
|
||||
g_cond_signal (&window->priv->cond_create_context);
|
||||
g_mutex_unlock (&window->priv->render_lock);
|
||||
return NULL;
|
||||
}
|
||||
return (GstGLContext *) g_weak_ref_get (&window->context_ref);
|
||||
}
|
||||
|
|
|
@ -75,6 +75,8 @@ struct _GstGLWindow {
|
|||
GMutex lock;
|
||||
gboolean need_lock;
|
||||
|
||||
GWeakRef context_ref;
|
||||
|
||||
guintptr external_gl_context;
|
||||
|
||||
GstGLWindowCB draw;
|
||||
|
@ -131,7 +133,6 @@ void gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB
|
|||
void gst_gl_window_set_need_lock (GstGLWindow *window, gboolean need_lock);
|
||||
|
||||
guintptr gst_gl_window_get_gl_context (GstGLWindow *window);
|
||||
gboolean gst_gl_window_activate (GstGLWindow *window, gboolean activate);
|
||||
void gst_gl_window_set_window_handle (GstGLWindow *window, guintptr handle);
|
||||
guintptr gst_gl_window_get_window_handle (GstGLWindow *window);
|
||||
void gst_gl_window_draw_unlocked (GstGLWindow *window, guint width, guint height);
|
||||
|
@ -140,13 +141,7 @@ void gst_gl_window_run (GstGLWindow *window);
|
|||
void gst_gl_window_quit (GstGLWindow *window);
|
||||
void gst_gl_window_send_message (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
|
||||
|
||||
gpointer gst_gl_window_get_proc_address (GstGLWindow *window, const gchar *name);
|
||||
GstGLPlatform gst_gl_window_get_platform (GstGLWindow *window);
|
||||
GstGLAPI gst_gl_window_get_gl_api (GstGLWindow *window);
|
||||
|
||||
gboolean gst_gl_window_create_context (GstGLWindow *window, guintptr external_gl_context, GError ** error);
|
||||
|
||||
gpointer gst_gl_window_default_get_proc_address (GstGLWindow *window, const gchar *name);
|
||||
GstGLContext * gst_gl_window_get_context (GstGLWindow *window);
|
||||
|
||||
gboolean gst_gl_window_is_running (GstGLWindow *window);
|
||||
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
|
||||
#include "wayland_event_source.h"
|
||||
|
||||
#include "../gstgl_fwd.h"
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
#include "gstglwindow_wayland_egl.h"
|
||||
|
||||
const gchar *WlEGLErrorString ();
|
||||
|
@ -572,13 +575,14 @@ static gpointer
|
|||
gst_gl_window_wayland_egl_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name)
|
||||
{
|
||||
GstGLContext *context = NULL;
|
||||
GstGLWindowWaylandEGL *window_egl;
|
||||
gpointer result;
|
||||
|
||||
window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
|
||||
|
||||
if (!(result = gst_gl_egl_get_proc_address (window_egl->egl, name))) {
|
||||
result = gst_gl_window_default_get_proc_address (window, name);
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "../gstgl_fwd.h"
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
#include "gstglwindow_win32_egl.h"
|
||||
|
||||
static guintptr gst_gl_window_win32_wgl_get_gl_context (GstGLWindowWin32 *
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "../gstgl_fwd.h"
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
#include "gstglwindow_win32_wgl.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_gl_window_debug
|
||||
|
@ -215,10 +218,11 @@ static gpointer
|
|||
gst_gl_window_win32_wgl_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name)
|
||||
{
|
||||
GstGLContext *context;
|
||||
gpointer result;
|
||||
|
||||
if (!(result = wglGetProcAddress ((LPCSTR) name))) {
|
||||
result = gst_gl_window_default_get_proc_address (window, name);
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "../gstgl_fwd.h"
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
#include "gstglwindow_x11_egl.h"
|
||||
|
||||
const gchar *X11EGLErrorString ();
|
||||
|
@ -188,11 +191,12 @@ static gpointer
|
|||
gst_gl_window_x11_egl_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name)
|
||||
{
|
||||
GstGLContext *context = NULL;
|
||||
GstGLWindowX11EGL *window_egl = GST_GL_WINDOW_X11_EGL (window);
|
||||
gpointer result;
|
||||
|
||||
if (!(result = gst_gl_egl_get_proc_address (window_egl->egl, name))) {
|
||||
result = gst_gl_window_default_get_proc_address (window, name);
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "../gstgl_fwd.h"
|
||||
#include <gst/gl/gstglcontext.h>
|
||||
|
||||
#include <gst/gl/gl.h>
|
||||
#include "gstglwindow_x11_glx.h"
|
||||
|
||||
|
@ -352,10 +355,11 @@ static gpointer
|
|||
gst_gl_window_x11_glx_get_proc_address (GstGLWindow * window,
|
||||
const gchar * name)
|
||||
{
|
||||
GstGLContext *context = NULL;
|
||||
gpointer result;
|
||||
|
||||
if (!(result = glXGetProcAddressARB ((const GLubyte *) name))) {
|
||||
result = gst_gl_window_default_get_proc_address (window, name);
|
||||
result = gst_gl_context_default_get_proc_address (context, name);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -415,12 +415,14 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
g_atomic_int_set (&glimage_sink->to_quit, 0);
|
||||
if (!glimage_sink->display) {
|
||||
GstGLWindow *window;
|
||||
GstGLContext *context;
|
||||
GError *error = NULL;
|
||||
|
||||
GST_INFO ("Creating GstGLDisplay");
|
||||
glimage_sink->display = gst_gl_display_new ();
|
||||
window = gst_gl_window_new (glimage_sink->display);
|
||||
gst_gl_display_set_window (glimage_sink->display, window);
|
||||
context = gst_gl_context_new (glimage_sink->display);
|
||||
gst_gl_display_set_context (glimage_sink->display, context);
|
||||
window = gst_gl_context_get_window (context);
|
||||
|
||||
if (!glimage_sink->window_id && !glimage_sink->new_window_id)
|
||||
gst_video_overlay_prepare_window_handle (GST_VIDEO_OVERLAY
|
||||
|
@ -431,7 +433,7 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
gst_gl_window_set_window_handle (window, glimage_sink->window_id);
|
||||
}
|
||||
|
||||
if (!gst_gl_window_create_context (window, 0, &error)) {
|
||||
if (!gst_gl_context_create (context, 0, &error)) {
|
||||
GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND,
|
||||
("%s", error->message), (NULL));
|
||||
|
||||
|
@ -439,7 +441,7 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
gst_object_unref (glimage_sink->display);
|
||||
glimage_sink->display = NULL;
|
||||
}
|
||||
gst_object_unref (window);
|
||||
gst_object_unref (context);
|
||||
|
||||
return GST_STATE_CHANGE_FAILURE;
|
||||
}
|
||||
|
@ -456,6 +458,7 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
gst_object_ref (glimage_sink), (GDestroyNotify) gst_object_unref);
|
||||
|
||||
gst_object_unref (window);
|
||||
gst_object_unref (context);
|
||||
}
|
||||
break;
|
||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||
|
@ -494,7 +497,9 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
GST_VIDEO_SINK_WIDTH (glimage_sink) = 1;
|
||||
GST_VIDEO_SINK_HEIGHT (glimage_sink) = 1;
|
||||
if (glimage_sink->display) {
|
||||
GstGLWindow *window = gst_gl_display_get_window (glimage_sink->display);
|
||||
GstGLContext *context =
|
||||
gst_gl_display_get_context (glimage_sink->display);
|
||||
GstGLWindow *window = gst_gl_context_get_window (context);
|
||||
|
||||
gst_gl_window_send_message (window,
|
||||
GST_GL_WINDOW_CB (gst_glimage_sink_cleanup_glthread), glimage_sink);
|
||||
|
@ -504,6 +509,7 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
gst_gl_window_set_close_callback (window, NULL, NULL, NULL);
|
||||
|
||||
gst_object_unref (window);
|
||||
gst_object_unref (context);
|
||||
gst_object_unref (glimage_sink->display);
|
||||
glimage_sink->display = NULL;
|
||||
}
|
||||
|
@ -692,12 +698,14 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
}
|
||||
|
||||
if (glimage_sink->window_id != glimage_sink->new_window_id) {
|
||||
GstGLWindow *window = gst_gl_display_get_window (glimage_sink->display);
|
||||
GstGLContext *context = gst_gl_display_get_context (glimage_sink->display);
|
||||
GstGLWindow *window = gst_gl_context_get_window (context);
|
||||
|
||||
glimage_sink->window_id = glimage_sink->new_window_id;
|
||||
gst_gl_window_set_window_handle (window, glimage_sink->window_id);
|
||||
|
||||
gst_object_unref (window);
|
||||
gst_object_unref (context);
|
||||
}
|
||||
|
||||
gst_buffer_replace (&glimage_sink->stored_buffer, buf);
|
||||
|
@ -771,12 +779,15 @@ gst_glimage_sink_expose (GstVideoOverlay * overlay)
|
|||
if (glimage_sink->display && glimage_sink->window_id) {
|
||||
|
||||
if (glimage_sink->window_id != glimage_sink->new_window_id) {
|
||||
GstGLWindow *window = gst_gl_display_get_window (glimage_sink->display);
|
||||
GstGLContext *context =
|
||||
gst_gl_display_get_context (glimage_sink->display);
|
||||
GstGLWindow *window = gst_gl_context_get_window (context);
|
||||
|
||||
glimage_sink->window_id = glimage_sink->new_window_id;
|
||||
gst_gl_window_set_window_handle (window, glimage_sink->window_id);
|
||||
|
||||
gst_object_unref (window);
|
||||
gst_object_unref (context);
|
||||
}
|
||||
|
||||
gst_glimage_sink_redisplay (glimage_sink, 0, 0, 0, 0, 0,
|
||||
|
@ -959,6 +970,7 @@ gst_glimage_sink_on_draw (GstGLImageSink * gl_sink)
|
|||
|
||||
/* check if a client draw callback is registered */
|
||||
if (gl_sink->clientDrawCallback) {
|
||||
|
||||
gboolean doRedisplay =
|
||||
gl_sink->clientDrawCallback (gl_sink->redisplay_texture,
|
||||
gl_sink->redisplay_texture_width,
|
||||
|
@ -966,12 +978,14 @@ gst_glimage_sink_on_draw (GstGLImageSink * gl_sink)
|
|||
gl_sink->client_data);
|
||||
|
||||
if (doRedisplay) {
|
||||
GstGLWindow *window = gst_gl_display_get_window (gl_sink->display);
|
||||
GstGLContext *context = gst_gl_display_get_context (gl_sink->display);
|
||||
GstGLWindow *window = gst_gl_context_get_window (context);
|
||||
|
||||
gst_gl_window_draw_unlocked (window,
|
||||
gl_sink->redisplay_texture_width, gl_sink->redisplay_texture_height);
|
||||
|
||||
gst_object_unref (window);
|
||||
gst_object_unref (context);
|
||||
}
|
||||
}
|
||||
/* default opengl scene */
|
||||
|
@ -1062,10 +1076,12 @@ gst_glimage_sink_redisplay (GstGLImageSink * gl_sink, GLuint texture,
|
|||
gint gl_width, gint gl_height, gint window_width, gint window_height,
|
||||
gboolean keep_aspect_ratio)
|
||||
{
|
||||
GstGLContext *context;
|
||||
GstGLWindow *window;
|
||||
gboolean alive;
|
||||
|
||||
window = gst_gl_display_get_window (gl_sink->display);
|
||||
context = gst_gl_display_get_context (gl_sink->display);
|
||||
window = gst_gl_context_get_window (context);
|
||||
|
||||
if (window && gst_gl_window_is_running (window)) {
|
||||
|
||||
|
@ -1089,6 +1105,7 @@ gst_glimage_sink_redisplay (GstGLImageSink * gl_sink, GLuint texture,
|
|||
}
|
||||
alive = gst_gl_window_is_running (window);
|
||||
gst_object_unref (window);
|
||||
gst_object_unref (context);
|
||||
|
||||
return alive;
|
||||
}
|
||||
|
|
|
@ -561,16 +561,16 @@ gst_gl_test_src_start (GstBaseSrc * basesrc)
|
|||
src->display =
|
||||
gst_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
|
||||
else {
|
||||
GstGLWindow *window;
|
||||
GstGLContext *context;
|
||||
GError *error = NULL;
|
||||
|
||||
GST_INFO ("Creating GstGLDisplay");
|
||||
src->display = gst_gl_display_new ();
|
||||
window = gst_gl_window_new (src->display);
|
||||
gst_gl_display_set_window (src->display, window);
|
||||
gst_object_unref (window);
|
||||
context = gst_gl_context_new (src->display);
|
||||
gst_gl_display_set_context (src->display, context);
|
||||
gst_object_unref (context);
|
||||
|
||||
if (!gst_gl_window_create_context (window, 0, &error)) {
|
||||
if (!gst_gl_context_create (context, 0, &error)) {
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
|
||||
("%s", error->message), (NULL));
|
||||
return FALSE;
|
||||
|
|
Loading…
Reference in a new issue