2008-06-19 23:38:36 +00:00
|
|
|
/*
|
2008-05-19 16:57:39 +00:00
|
|
|
* GStreamer
|
2008-09-20 13:44:24 +00:00
|
|
|
* Copyright (C) 2007 David A. Schleef <ds@schleef.org>
|
2008-05-19 16:57:39 +00:00
|
|
|
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
2008-08-11 07:52:16 +00:00
|
|
|
* Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
|
2008-05-19 16:57:39 +00:00
|
|
|
*
|
|
|
|
* 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
|
2012-11-08 11:53:56 +00:00
|
|
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
2008-05-19 16:57:39 +00:00
|
|
|
*/
|
|
|
|
|
2008-05-18 11:12:46 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2009-10-16 15:08:11 +00:00
|
|
|
#include <stdio.h>
|
2009-10-16 14:29:08 +00:00
|
|
|
|
2012-09-16 11:23:09 +00:00
|
|
|
#include <gst/gst.h>
|
2009-04-19 22:52:41 +00:00
|
|
|
#include <gst/video/gstvideosink.h>
|
2012-09-16 11:23:09 +00:00
|
|
|
#include "gstgldownload.h"
|
|
|
|
#include "gstglmemory.h"
|
2013-01-09 13:30:03 +00:00
|
|
|
#include "gstglfeature.h"
|
2013-01-16 04:21:44 +00:00
|
|
|
#include "gstglapi.h"
|
2008-05-18 11:12:46 +00:00
|
|
|
|
2013-01-16 04:21:44 +00:00
|
|
|
#include "gstgldisplay.h"
|
2009-08-03 15:52:31 +00:00
|
|
|
|
2012-12-06 07:40:26 +00:00
|
|
|
#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)
|
2008-09-13 01:32:04 +00:00
|
|
|
|
|
|
|
GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug);
|
|
|
|
#define GST_CAT_DEFAULT gst_gl_display_debug
|
|
|
|
|
2012-05-30 03:46:21 +00:00
|
|
|
#define DEBUG_INIT \
|
2008-09-13 01:32:04 +00:00
|
|
|
GST_DEBUG_CATEGORY_INIT (gst_gl_display_debug, "gldisplay", 0, "opengl display");
|
|
|
|
|
2012-05-30 03:46:21 +00:00
|
|
|
G_DEFINE_TYPE_WITH_CODE (GstGLDisplay, gst_gl_display, G_TYPE_OBJECT,
|
2009-02-11 06:39:14 +00:00
|
|
|
DEBUG_INIT);
|
2012-12-06 07:40:26 +00:00
|
|
|
|
|
|
|
#define GST_GL_DISPLAY_GET_PRIVATE(o) \
|
|
|
|
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_DISPLAY, GstGLDisplayPrivate))
|
|
|
|
|
2009-02-11 06:39:14 +00:00
|
|
|
static void gst_gl_display_finalize (GObject * object);
|
2008-06-29 17:27:43 +00:00
|
|
|
|
|
|
|
/* Called in the gl thread, protected by lock and unlock */
|
2009-02-11 06:39:14 +00:00
|
|
|
gpointer gst_gl_display_thread_create_context (GstGLDisplay * display);
|
|
|
|
void gst_gl_display_thread_destroy_context (GstGLDisplay * display);
|
|
|
|
void gst_gl_display_thread_run_generic (GstGLDisplay * display);
|
2012-12-06 07:40:26 +00:00
|
|
|
|
|
|
|
struct _GstGLDisplayPrivate
|
|
|
|
{
|
2013-01-09 14:44:54 +00:00
|
|
|
/* conditions */
|
2013-02-18 10:40:34 +00:00
|
|
|
GCond cond_create_context;
|
|
|
|
GCond cond_destroy_context;
|
2013-01-09 14:44:54 +00:00
|
|
|
|
|
|
|
/* generic gl code */
|
|
|
|
GstGLDisplayThreadFunc generic_callback;
|
|
|
|
gpointer data;
|
2012-12-06 07:40:26 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*------------------------------------------------------------
|
|
|
|
--------------------- For klass GstGLDisplay ---------------
|
|
|
|
----------------------------------------------------------*/
|
2008-05-18 11:12:46 +00:00
|
|
|
static void
|
|
|
|
gst_gl_display_class_init (GstGLDisplayClass * klass)
|
2008-06-19 23:38:36 +00:00
|
|
|
{
|
2012-12-06 07:40:26 +00:00
|
|
|
g_type_class_add_private (klass, sizeof (GstGLDisplayPrivate));
|
|
|
|
|
2008-08-01 09:00:49 +00:00
|
|
|
G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize;
|
2008-05-18 11:12:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2012-05-30 03:46:21 +00:00
|
|
|
gst_gl_display_init (GstGLDisplay * display)
|
2008-05-18 11:12:46 +00:00
|
|
|
{
|
2012-12-06 07:40:26 +00:00
|
|
|
display->priv = GST_GL_DISPLAY_GET_PRIVATE (display);
|
|
|
|
|
|
|
|
/* thread safe */
|
2013-02-18 10:40:34 +00:00
|
|
|
g_mutex_init (&display->mutex);
|
2008-08-01 09:00:49 +00:00
|
|
|
|
2013-02-18 10:40:34 +00:00
|
|
|
g_cond_init (&display->priv->cond_create_context);
|
|
|
|
g_cond_init (&display->priv->cond_destroy_context);
|
2012-09-16 11:23:09 +00:00
|
|
|
|
2013-01-16 04:21:44 +00:00
|
|
|
display->gl_vtable = g_slice_alloc0 (sizeof (GstGLFuncs));
|
|
|
|
|
2013-02-12 12:48:36 +00:00
|
|
|
display->gl_window = gst_gl_window_new ();
|
|
|
|
|
2012-09-16 11:23:09 +00:00
|
|
|
gst_gl_memory_init ();
|
2008-05-18 11:12:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-02-11 06:39:14 +00:00
|
|
|
gst_gl_display_finalize (GObject * object)
|
2008-05-18 11:12:46 +00:00
|
|
|
{
|
2009-02-11 06:39:14 +00:00
|
|
|
GstGLDisplay *display = GST_GL_DISPLAY (object);
|
2008-08-01 09:00:49 +00:00
|
|
|
|
2013-02-18 10:40:34 +00:00
|
|
|
if (display->gl_window) {
|
2008-11-21 00:31:19 +00:00
|
|
|
gst_gl_display_lock (display);
|
|
|
|
|
|
|
|
gst_gl_window_set_resize_callback (display->gl_window, NULL, NULL);
|
|
|
|
gst_gl_window_set_draw_callback (display->gl_window, NULL, NULL);
|
|
|
|
gst_gl_window_set_close_callback (display->gl_window, NULL, NULL);
|
|
|
|
|
2013-02-12 12:48:36 +00:00
|
|
|
if (display->context_created) {
|
|
|
|
GST_INFO ("send quit gl window loop");
|
|
|
|
gst_gl_window_quit (display->gl_window,
|
|
|
|
GST_GL_WINDOW_CB (gst_gl_display_thread_destroy_context), display);
|
2008-11-21 00:31:19 +00:00
|
|
|
|
2013-02-12 12:48:36 +00:00
|
|
|
GST_INFO ("quit sent to gl window loop");
|
2008-11-21 00:31:19 +00:00
|
|
|
|
2013-02-18 10:40:34 +00:00
|
|
|
g_cond_wait (&display->priv->cond_destroy_context, &display->mutex);
|
2013-02-12 12:48:36 +00:00
|
|
|
GST_INFO ("quit received from gl window");
|
|
|
|
}
|
2008-11-21 00:31:19 +00:00
|
|
|
gst_gl_display_unlock (display);
|
|
|
|
}
|
2008-08-01 09:00:49 +00:00
|
|
|
|
2009-02-11 06:39:14 +00:00
|
|
|
if (display->gl_thread) {
|
2008-10-25 00:03:16 +00:00
|
|
|
gpointer ret = g_thread_join (display->gl_thread);
|
2008-10-23 23:39:00 +00:00
|
|
|
GST_INFO ("gl thread joined");
|
2008-11-21 18:11:11 +00:00
|
|
|
if (ret != NULL)
|
|
|
|
GST_ERROR ("gl thread returned a not null pointer");
|
2008-10-23 23:39:00 +00:00
|
|
|
display->gl_thread = NULL;
|
|
|
|
}
|
2013-02-18 10:40:34 +00:00
|
|
|
|
|
|
|
g_mutex_clear (&display->mutex);
|
|
|
|
|
|
|
|
g_cond_clear (&display->priv->cond_destroy_context);
|
|
|
|
g_cond_clear (&display->priv->cond_create_context);
|
|
|
|
|
2011-11-24 15:02:32 +00:00
|
|
|
if (display->error_message) {
|
|
|
|
g_free (display->error_message);
|
|
|
|
display->error_message = NULL;
|
|
|
|
}
|
2013-01-16 04:21:44 +00:00
|
|
|
|
|
|
|
if (display->gl_vtable) {
|
|
|
|
g_slice_free (GstGLFuncs, display->gl_vtable);
|
|
|
|
display->gl_vtable = NULL;
|
|
|
|
}
|
2008-05-18 11:12:46 +00:00
|
|
|
}
|
|
|
|
|
2012-12-06 07:40:26 +00:00
|
|
|
static gboolean
|
|
|
|
_create_context_gles2 (GstGLDisplay * display, gint * gl_major, gint * gl_minor)
|
|
|
|
{
|
2013-03-09 11:05:28 +00:00
|
|
|
const GstGLFuncs *gl;
|
2012-12-06 07:40:26 +00:00
|
|
|
GLenum gl_err = GL_NO_ERROR;
|
|
|
|
|
2013-01-16 04:21:44 +00:00
|
|
|
gl = display->gl_vtable;
|
|
|
|
|
|
|
|
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
|
2013-01-09 13:30:03 +00:00
|
|
|
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
|
2013-01-16 04:21:44 +00:00
|
|
|
gl->GetString (GL_SHADING_LANGUAGE_VERSION));
|
|
|
|
GST_INFO ("GL_VENDOR: %s", gl->GetString (GL_VENDOR));
|
|
|
|
GST_INFO ("GL_RENDERER: %s", gl->GetString (GL_RENDERER));
|
2012-12-06 07:40:26 +00:00
|
|
|
|
2013-01-16 04:21:44 +00:00
|
|
|
gl_err = gl->GetError ();
|
2012-12-06 07:40:26 +00:00
|
|
|
if (gl_err != GL_NO_ERROR) {
|
|
|
|
gst_gl_display_set_error (display, "glGetString error: 0x%x", gl_err);
|
2013-01-16 04:21:44 +00:00
|
|
|
return FALSE;
|
2012-12-06 07:40:26 +00:00
|
|
|
}
|
2013-01-16 04:21:44 +00:00
|
|
|
#if GST_GL_HAVE_GLES2
|
|
|
|
if (!GL_ES_VERSION_2_0) {
|
2012-12-06 07:40:26 +00:00
|
|
|
gst_gl_display_set_error (display, "OpenGL|ES >= 2.0 is required");
|
2013-01-16 04:21:44 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
#endif
|
2012-12-06 07:40:26 +00:00
|
|
|
|
2013-01-09 13:30:03 +00:00
|
|
|
_gst_gl_feature_check_ext_functions (display, 0, 0,
|
2013-01-16 04:21:44 +00:00
|
|
|
(const gchar *) gl->GetString (GL_EXTENSIONS));
|
2012-12-06 07:40:26 +00:00
|
|
|
|
2013-01-09 13:30:03 +00:00
|
|
|
if (gl_major)
|
|
|
|
*gl_major = 2;
|
|
|
|
if (gl_minor)
|
|
|
|
*gl_minor = 0;
|
2012-12-06 07:40:26 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2013-01-09 14:44:54 +00:00
|
|
|
_create_context_opengl (GstGLDisplay * display, gint * gl_major,
|
|
|
|
gint * gl_minor)
|
2012-12-06 07:40:26 +00:00
|
|
|
{
|
2013-03-09 11:05:28 +00:00
|
|
|
const GstGLFuncs *gl;
|
2013-01-09 13:30:03 +00:00
|
|
|
guint maj, min;
|
2012-12-06 07:40:26 +00:00
|
|
|
GLenum gl_err = GL_NO_ERROR;
|
|
|
|
GString *opengl_version = NULL;
|
|
|
|
|
2013-01-16 04:21:44 +00:00
|
|
|
gl = display->gl_vtable;
|
2012-12-06 07:40:26 +00:00
|
|
|
|
2013-01-16 04:21:44 +00:00
|
|
|
GST_INFO ("GL_VERSION: %s", gl->GetString (GL_VERSION));
|
2013-01-09 13:30:03 +00:00
|
|
|
GST_INFO ("GL_SHADING_LANGUAGE_VERSION: %s",
|
2013-01-16 04:21:44 +00:00
|
|
|
gl->GetString (GL_SHADING_LANGUAGE_VERSION));
|
|
|
|
GST_INFO ("GL_VENDOR: %s", gl->GetString (GL_VENDOR));
|
|
|
|
GST_INFO ("GL_RENDERER: %s", gl->GetString (GL_RENDERER));
|
2012-12-06 07:40:26 +00:00
|
|
|
|
2013-01-16 04:21:44 +00:00
|
|
|
gl_err = gl->GetError ();
|
2012-12-06 07:40:26 +00:00
|
|
|
if (gl_err != GL_NO_ERROR) {
|
|
|
|
gst_gl_display_set_error (display, "glGetString error: 0x%x", gl_err);
|
2013-01-16 04:21:44 +00:00
|
|
|
return FALSE;
|
2012-12-06 07:40:26 +00:00
|
|
|
}
|
2013-01-09 13:30:03 +00:00
|
|
|
opengl_version =
|
2013-01-16 04:21:44 +00:00
|
|
|
g_string_truncate (g_string_new ((gchar *) gl->GetString (GL_VERSION)),
|
|
|
|
3);
|
2013-01-09 13:30:03 +00:00
|
|
|
|
|
|
|
sscanf (opengl_version->str, "%d.%d", &maj, &min);
|
|
|
|
|
|
|
|
g_string_free (opengl_version, TRUE);
|
|
|
|
|
2013-01-16 04:21:44 +00:00
|
|
|
/* OpenGL > 1.2.0 */
|
2013-01-09 13:30:03 +00:00
|
|
|
if ((maj < 1) || (maj < 2 && maj >= 1 && min < 2)) {
|
2013-01-16 04:21:44 +00:00
|
|
|
gst_gl_display_set_error (display, "OpenGL >= 1.2.0 required, found %u.%u",
|
|
|
|
maj, min);
|
2013-01-09 13:30:03 +00:00
|
|
|
return FALSE;
|
2012-12-06 07:40:26 +00:00
|
|
|
}
|
|
|
|
|
2013-01-09 13:30:03 +00:00
|
|
|
_gst_gl_feature_check_ext_functions (display, maj, min,
|
2013-01-16 04:21:44 +00:00
|
|
|
(const gchar *) gl->GetString (GL_EXTENSIONS));
|
2012-12-06 07:40:26 +00:00
|
|
|
|
2013-01-09 13:30:03 +00:00
|
|
|
if (gl_major)
|
|
|
|
*gl_major = maj;
|
|
|
|
if (gl_minor)
|
|
|
|
*gl_minor = min;
|
|
|
|
|
2012-12-06 07:40:26 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2012-12-08 22:32:48 +00:00
|
|
|
GstGLAPI
|
|
|
|
_compiled_api (void)
|
|
|
|
{
|
|
|
|
GstGLAPI ret = GST_GL_API_NONE;
|
|
|
|
|
2013-01-09 14:13:23 +00:00
|
|
|
#if GST_GL_HAVE_OPENGL
|
2012-12-08 22:32:48 +00:00
|
|
|
ret |= GST_GL_API_OPENGL;
|
|
|
|
#endif
|
2013-01-09 14:13:23 +00:00
|
|
|
#if GST_GL_HAVE_GLES2
|
2012-12-08 22:32:48 +00:00
|
|
|
ret |= GST_GL_API_GLES2;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-06-11 01:27:56 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-10-23 23:39:00 +00:00
|
|
|
gpointer
|
2009-02-11 06:39:14 +00:00
|
|
|
gst_gl_display_thread_create_context (GstGLDisplay * display)
|
2008-05-18 11:12:46 +00:00
|
|
|
{
|
2013-01-16 04:21:44 +00:00
|
|
|
GstGLFuncs *gl;
|
2013-01-09 13:30:03 +00:00
|
|
|
gint gl_major = 0;
|
2012-12-06 07:40:26 +00:00
|
|
|
gboolean ret = FALSE;
|
2012-12-08 22:32:48 +00:00
|
|
|
GError *error = NULL;
|
2013-06-11 01:27:56 +00:00
|
|
|
GstGLAPI compiled_api, user_api;
|
2012-12-08 22:32:48 +00:00
|
|
|
gchar *api_string;
|
|
|
|
gchar *compiled_api_s;
|
2013-06-11 01:27:56 +00:00
|
|
|
gchar *user_api_string;
|
|
|
|
const gchar *user_choice;
|
2008-05-18 11:12:46 +00:00
|
|
|
|
2009-07-13 11:53:17 +00:00
|
|
|
gst_gl_display_lock (display);
|
2012-12-08 22:32:48 +00:00
|
|
|
|
2013-01-16 04:21:44 +00:00
|
|
|
gl = display->gl_vtable;
|
2012-12-08 22:32:48 +00:00
|
|
|
compiled_api = _compiled_api ();
|
|
|
|
|
2013-02-12 12:48:36 +00:00
|
|
|
if (!display->gl_window) {
|
|
|
|
gst_gl_display_set_error (display, "Failed to create opengl window");
|
|
|
|
goto failure;
|
|
|
|
}
|
2008-05-18 11:12:46 +00:00
|
|
|
|
2013-06-11 01:27:56 +00:00
|
|
|
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);
|
|
|
|
|
|
|
|
GST_INFO ("Attempting to create opengl context. user chosen api(s):%s, "
|
|
|
|
"compiled api support:%s", user_api_string, compiled_api_s);
|
|
|
|
|
|
|
|
if (!gst_gl_window_create_context (display->gl_window,
|
|
|
|
compiled_api & user_api, display->external_gl_context, &error)) {
|
2013-01-09 14:44:54 +00:00
|
|
|
gst_gl_display_set_error (display,
|
|
|
|
error ? error->message : "Failed to create gl window");
|
2013-06-11 01:27:56 +00:00
|
|
|
g_free (compiled_api_s);
|
|
|
|
g_free (user_api_string);
|
2012-12-19 03:32:20 +00:00
|
|
|
goto failure;
|
2008-10-25 00:03:16 +00:00
|
|
|
}
|
2013-02-12 12:48:36 +00:00
|
|
|
GST_INFO ("window created context");
|
2008-05-18 11:12:46 +00:00
|
|
|
|
2012-12-06 07:40:26 +00:00
|
|
|
display->gl_api = gst_gl_window_get_gl_api (display->gl_window);
|
2013-01-09 14:44:54 +00:00
|
|
|
g_assert (display->gl_api != GST_GL_API_NONE
|
|
|
|
&& display->gl_api != GST_GL_API_ANY);
|
2008-08-01 09:00:49 +00:00
|
|
|
|
2012-12-08 22:32:48 +00:00
|
|
|
api_string = gst_gl_api_string (display->gl_api);
|
|
|
|
GST_INFO ("available GL APIs: %s", api_string);
|
|
|
|
|
2013-06-11 01:27:56 +00:00
|
|
|
if (((compiled_api & display->gl_api) & user_api) == GST_GL_API_NONE) {
|
|
|
|
gst_gl_display_set_error (display, "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);
|
2012-12-19 03:32:20 +00:00
|
|
|
goto failure;
|
|
|
|
}
|
2012-12-08 22:32:48 +00:00
|
|
|
|
|
|
|
g_free (api_string);
|
|
|
|
g_free (compiled_api_s);
|
2013-06-11 01:27:56 +00:00
|
|
|
g_free (user_api_string);
|
2012-12-08 22:32:48 +00:00
|
|
|
|
2013-01-16 04:21:44 +00:00
|
|
|
gl->GetError =
|
|
|
|
gst_gl_window_get_proc_address (display->gl_window, "glGetError");
|
|
|
|
gl->GetString =
|
|
|
|
gst_gl_window_get_proc_address (display->gl_window, "glGetString");
|
|
|
|
|
|
|
|
if (!gl->GetError || !gl->GetString) {
|
|
|
|
gst_gl_display_set_error (display,
|
|
|
|
"could not GetProcAddress core opengl functions");
|
|
|
|
goto failure;
|
|
|
|
}
|
|
|
|
|
2012-12-06 07:40:26 +00:00
|
|
|
/* gl api specific code */
|
2013-01-09 14:44:54 +00:00
|
|
|
if (!ret && USING_OPENGL (display))
|
2013-01-09 13:30:03 +00:00
|
|
|
ret = _create_context_opengl (display, &gl_major, NULL);
|
2013-01-09 14:44:54 +00:00
|
|
|
if (!ret && USING_GLES2 (display))
|
2013-01-09 13:30:03 +00:00
|
|
|
ret = _create_context_gles2 (display, &gl_major, NULL);
|
2008-05-18 11:12:46 +00:00
|
|
|
|
2012-12-19 03:32:20 +00:00
|
|
|
if (!ret || !gl_major) {
|
2013-02-12 12:48:36 +00:00
|
|
|
GST_WARNING ("GL api specific initialization failed");
|
2012-12-19 03:32:20 +00:00
|
|
|
goto failure;
|
|
|
|
}
|
2012-12-06 07:40:26 +00:00
|
|
|
|
2013-02-18 10:40:34 +00:00
|
|
|
g_cond_signal (&display->priv->cond_create_context);
|
2008-06-28 15:38:41 +00:00
|
|
|
|
2013-01-09 14:44:54 +00:00
|
|
|
display->isAlive = TRUE;
|
2009-07-13 11:53:17 +00:00
|
|
|
gst_gl_display_unlock (display);
|
|
|
|
|
2012-11-13 11:12:20 +00:00
|
|
|
gst_gl_window_run (display->gl_window);
|
2008-06-28 15:38:41 +00:00
|
|
|
|
2008-10-25 14:18:23 +00:00
|
|
|
GST_INFO ("loop exited\n");
|
|
|
|
|
2008-11-13 01:05:33 +00:00
|
|
|
gst_gl_display_lock (display);
|
|
|
|
|
2008-10-25 14:18:23 +00:00
|
|
|
display->isAlive = FALSE;
|
2008-10-22 23:40:52 +00:00
|
|
|
|
|
|
|
g_object_unref (G_OBJECT (display->gl_window));
|
|
|
|
|
2008-10-23 23:39:00 +00:00
|
|
|
display->gl_window = NULL;
|
2008-10-22 23:40:52 +00:00
|
|
|
|
2013-02-18 10:40:34 +00:00
|
|
|
g_cond_signal (&display->priv->cond_destroy_context);
|
2008-11-21 00:31:19 +00:00
|
|
|
|
2008-11-13 01:05:33 +00:00
|
|
|
gst_gl_display_unlock (display);
|
|
|
|
|
2008-10-22 23:40:52 +00:00
|
|
|
return NULL;
|
2012-12-19 03:32:20 +00:00
|
|
|
|
|
|
|
failure:
|
|
|
|
{
|
|
|
|
if (display->gl_window) {
|
|
|
|
g_object_unref (display->gl_window);
|
|
|
|
display->gl_window = NULL;
|
|
|
|
}
|
|
|
|
|
2013-02-18 10:40:34 +00:00
|
|
|
g_cond_signal (&display->priv->cond_create_context);
|
2012-12-19 03:32:20 +00:00
|
|
|
gst_gl_display_unlock (display);
|
|
|
|
return NULL;
|
|
|
|
}
|
2008-06-29 17:27:43 +00:00
|
|
|
}
|
|
|
|
|
2008-10-23 23:39:00 +00:00
|
|
|
void
|
2009-02-11 06:39:14 +00:00
|
|
|
gst_gl_display_thread_destroy_context (GstGLDisplay * display)
|
2008-06-29 17:27:43 +00:00
|
|
|
{
|
2008-10-22 23:40:52 +00:00
|
|
|
GST_INFO ("Context destroyed");
|
2008-06-29 17:27:43 +00:00
|
|
|
}
|
|
|
|
|
2013-06-11 15:04:55 +00:00
|
|
|
//------------------------------------------------------------
|
|
|
|
//------------------ BEGIN GL THREAD PROCS -------------------
|
|
|
|
//------------------------------------------------------------
|
2008-06-07 00:01:18 +00:00
|
|
|
|
2008-06-29 17:27:43 +00:00
|
|
|
/* Called in the gl thread */
|
2008-06-13 00:01:26 +00:00
|
|
|
|
2008-10-23 23:39:00 +00:00
|
|
|
void
|
2013-06-11 15:04:55 +00:00
|
|
|
gst_gl_display_set_error (GstGLDisplay * display, const char *format, ...)
|
2008-06-13 00:01:26 +00:00
|
|
|
{
|
2013-06-11 15:04:55 +00:00
|
|
|
va_list args;
|
2008-06-13 00:01:26 +00:00
|
|
|
|
2013-06-11 15:04:55 +00:00
|
|
|
if (display->error_message)
|
|
|
|
g_free (display->error_message);
|
2008-06-13 00:01:26 +00:00
|
|
|
|
2013-06-11 15:04:55 +00:00
|
|
|
va_start (args, format);
|
|
|
|
display->error_message = g_strdup_vprintf (format, args);
|
|
|
|
va_end (args);
|
2008-05-18 11:12:46 +00:00
|
|
|
|
2013-06-11 15:04:55 +00:00
|
|
|
GST_WARNING ("%s", display->error_message);
|
2008-05-18 11:12:46 +00:00
|
|
|
|
2013-06-11 15:04:55 +00:00
|
|
|
display->isAlive = FALSE;
|
2012-07-06 08:51:02 +00:00
|
|
|
}
|
2008-05-18 11:12:46 +00:00
|
|
|
|
2008-06-29 17:27:43 +00:00
|
|
|
void
|
2013-06-11 15:04:55 +00:00
|
|
|
gst_gl_display_thread_run_generic (GstGLDisplay * display)
|
2008-05-18 11:12:46 +00:00
|
|
|
{
|
2013-06-11 15:04:55 +00:00
|
|
|
GST_TRACE ("running function:%p data:%p",
|
|
|
|
display->priv->generic_callback, display->priv->data);
|
2008-05-18 11:12:46 +00:00
|
|
|
|
2013-06-11 15:04:55 +00:00
|
|
|
display->priv->generic_callback (display, display->priv->data);
|
2008-08-11 17:01:33 +00:00
|
|
|
}
|
|
|
|
|
2012-12-06 07:40:26 +00:00
|
|
|
/*------------------------------------------------------------
|
|
|
|
--------------------- BEGIN PUBLIC -------------------------
|
|
|
|
----------------------------------------------------------*/
|
2012-09-16 11:23:09 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
gst_gl_display_lock (GstGLDisplay * display)
|
|
|
|
{
|
2013-02-18 10:40:34 +00:00
|
|
|
g_mutex_lock (&display->mutex);
|
2012-09-16 11:23:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gst_gl_display_unlock (GstGLDisplay * display)
|
|
|
|
{
|
2013-02-18 10:40:34 +00:00
|
|
|
g_mutex_unlock (&display->mutex);
|
2012-09-16 11:23:09 +00:00
|
|
|
}
|
|
|
|
|
2008-06-29 17:27:43 +00:00
|
|
|
/* Called by the first gl element of a video/x-raw-gl flow */
|
2009-02-11 06:39:14 +00:00
|
|
|
GstGLDisplay *
|
2008-05-18 11:12:46 +00:00
|
|
|
gst_gl_display_new (void)
|
|
|
|
{
|
2012-12-06 07:40:26 +00:00
|
|
|
return g_object_new (GST_GL_TYPE_DISPLAY, NULL);
|
2008-05-18 11:12:46 +00:00
|
|
|
}
|
|
|
|
|
2009-10-22 23:11:27 +00:00
|
|
|
/* Create an opengl context (one context for one GstGLDisplay) */
|
2011-11-24 15:02:32 +00:00
|
|
|
gboolean
|
2009-10-27 16:02:23 +00:00
|
|
|
gst_gl_display_create_context (GstGLDisplay * display,
|
|
|
|
gulong external_gl_context)
|
2008-06-19 23:38:36 +00:00
|
|
|
{
|
2011-11-24 15:02:32 +00:00
|
|
|
gboolean isAlive = FALSE;
|
|
|
|
|
2008-08-01 09:00:49 +00:00
|
|
|
gst_gl_display_lock (display);
|
|
|
|
|
2013-02-12 12:48:36 +00:00
|
|
|
if (!display->context_created) {
|
2009-10-22 23:11:27 +00:00
|
|
|
display->external_gl_context = external_gl_context;
|
2008-08-01 09:00:49 +00:00
|
|
|
|
2013-02-18 10:40:34 +00:00
|
|
|
display->gl_thread = g_thread_new ("gstglcontext",
|
|
|
|
(GThreadFunc) gst_gl_display_thread_create_context, display);
|
2008-10-22 23:40:52 +00:00
|
|
|
|
2013-02-18 10:40:34 +00:00
|
|
|
g_cond_wait (&display->priv->cond_create_context, &display->mutex);
|
2008-10-22 23:40:52 +00:00
|
|
|
|
2013-04-24 04:25:21 +00:00
|
|
|
display->context_created = TRUE;
|
|
|
|
|
2009-10-22 23:11:27 +00:00
|
|
|
GST_INFO ("gl thread created");
|
|
|
|
}
|
2008-11-06 22:41:11 +00:00
|
|
|
|
2011-11-24 15:02:32 +00:00
|
|
|
isAlive = display->isAlive;
|
|
|
|
|
2008-08-01 09:00:49 +00:00
|
|
|
gst_gl_display_unlock (display);
|
2011-11-24 15:02:32 +00:00
|
|
|
|
|
|
|
return isAlive;
|
2008-05-18 11:12:46 +00:00
|
|
|
}
|
|
|
|
|
2008-08-11 17:01:33 +00:00
|
|
|
void
|
2009-02-11 06:39:14 +00:00
|
|
|
gst_gl_display_thread_add (GstGLDisplay * display,
|
|
|
|
GstGLDisplayThreadFunc func, gpointer data)
|
2008-08-11 07:00:40 +00:00
|
|
|
{
|
|
|
|
gst_gl_display_lock (display);
|
2013-01-09 14:44:54 +00:00
|
|
|
display->priv->data = data;
|
|
|
|
display->priv->generic_callback = func;
|
2009-02-11 06:39:14 +00:00
|
|
|
gst_gl_window_send_message (display->gl_window,
|
|
|
|
GST_GL_WINDOW_CB (gst_gl_display_thread_run_generic), display);
|
2008-08-11 07:00:40 +00:00
|
|
|
gst_gl_display_unlock (display);
|
|
|
|
}
|
2008-05-18 11:12:46 +00:00
|
|
|
|
2013-06-11 15:04:55 +00:00
|
|
|
guintptr
|
2009-10-22 23:11:27 +00:00
|
|
|
gst_gl_display_get_internal_gl_context (GstGLDisplay * display)
|
|
|
|
{
|
|
|
|
gulong external_gl_context = 0;
|
|
|
|
gst_gl_display_lock (display);
|
2012-11-13 11:12:20 +00:00
|
|
|
external_gl_context = gst_gl_window_get_gl_context (display->gl_window);
|
2009-10-22 23:11:27 +00:00
|
|
|
gst_gl_display_unlock (display);
|
|
|
|
return external_gl_context;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gst_gl_display_activate_gl_context (GstGLDisplay * display, gboolean activate)
|
|
|
|
{
|
|
|
|
if (!activate)
|
|
|
|
gst_gl_display_lock (display);
|
2012-11-13 11:12:20 +00:00
|
|
|
gst_gl_window_activate (display->gl_window, activate);
|
2009-10-22 23:11:27 +00:00
|
|
|
if (activate)
|
|
|
|
gst_gl_display_unlock (display);
|
|
|
|
}
|
|
|
|
|
2012-12-06 07:40:26 +00:00
|
|
|
GstGLAPI
|
|
|
|
gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display)
|
|
|
|
{
|
|
|
|
return display->gl_api;
|
|
|
|
}
|
|
|
|
|
|
|
|
GstGLAPI
|
|
|
|
gst_gl_display_get_gl_api (GstGLDisplay * display)
|
|
|
|
{
|
|
|
|
GstGLAPI api;
|
|
|
|
|
|
|
|
gst_gl_display_lock (display);
|
|
|
|
api = gst_gl_display_get_gl_api_unlocked (display);
|
|
|
|
gst_gl_display_unlock (display);
|
|
|
|
|
|
|
|
return api;
|
|
|
|
}
|
|
|
|
|
2013-01-16 04:21:44 +00:00
|
|
|
gpointer
|
|
|
|
gst_gl_display_get_gl_vtable (GstGLDisplay * display)
|
|
|
|
{
|
|
|
|
gpointer gl;
|
|
|
|
|
|
|
|
gst_gl_display_lock (display);
|
|
|
|
gl = display->gl_vtable;
|
|
|
|
gst_gl_display_unlock (display);
|
|
|
|
|
|
|
|
return gl;
|
|
|
|
}
|
|
|
|
|
2008-06-29 17:27:43 +00:00
|
|
|
//------------------------------------------------------------
|
|
|
|
//------------------------ END PUBLIC ------------------------
|
|
|
|
//------------------------------------------------------------
|