gl: Add EGLDisplay display subclass

This commit is contained in:
Matthew Waters 2014-03-17 10:56:39 +01:00 committed by Tim-Philipp Müller
parent 1af7847fdc
commit 894035f0d7
6 changed files with 284 additions and 48 deletions

View file

@ -25,9 +25,32 @@ libgstgl_@GST_API_VERSION@_la_SOURCES = \
gstglutils.c \
gstglframebuffer.c
libgstgl_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl
libgstgl_@GST_API_VERSION@include_HEADERS = \
gstglwindow.h \
gstgldisplay.h \
gstglcontext.h \
gstglmemory.h \
gstglbufferpool.h \
gstgles2.h \
gstglfilter.h \
gstglmixer.h \
gstglmixerpad.h \
gstglshadervariables.h \
gstglshader.h \
gstgldownload.h \
gstglupload.h \
gstglapi.h \
gstglfeature.h \
gstglutils.h \
gstglframebuffer.h \
gstgl_fwd.h \
gl.h
libgstgl_@GST_API_VERSION@_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) \
-lgstvideo-$(GST_API_VERSION) \
-lgstegl-$(GST_API_VERSION) \
$(GST_BASE_LIBS) \
$(GST_LIBS) \
$(GL_LIBS)
@ -63,32 +86,12 @@ libgstgl_@GST_API_VERSION@_la_LIBADD += android/libgstgl-android.la
endif
if USE_EGL
libgstgl_@GST_API_VERSION@_la_SOURCES += egl/gstglcontext_egl.c
libgstgl_@GST_API_VERSION@_la_SOURCES += egl/gstglcontext_egl.c \
egl/gstgldisplay_egl.c
libgstgl_@GST_API_VERSION@include_HEADERS += egl/gstgldisplay_egl.h
noinst_HEADERS += egl/gstglcontext_egl.h
endif
libgstgl_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl
libgstgl_@GST_API_VERSION@include_HEADERS = \
gstglwindow.h \
gstgldisplay.h \
gstglcontext.h \
gstglmemory.h \
gstglbufferpool.h \
gstgles2.h \
gstglfilter.h \
gstglmixer.h \
gstglmixerpad.h \
gstglshadervariables.h \
gstglshader.h \
gstgldownload.h \
gstglupload.h \
gstglapi.h \
gstglfeature.h \
gstglutils.h \
gstglframebuffer.h \
gstgl_fwd.h \
gl.h
nodist_libgstgl_@GST_API_VERSION@include_HEADERS = \
$(built_header_configure)

View file

@ -209,7 +209,7 @@ gst_gl_context_egl_create_context (GstGLContext * context,
{
GstGLContextEGL *egl;
GstGLWindow *window = NULL;
EGLNativeWindowType window_handle;
EGLNativeWindowType window_handle = (EGLNativeWindowType) 0;
gint i = 0;
EGLint context_attrib[3];
EGLint majorVersion;
@ -217,7 +217,6 @@ gst_gl_context_egl_create_context (GstGLContext * context,
const gchar *egl_exts;
gboolean need_surface = TRUE;
guintptr external_gl_context = 0;
guintptr native_display;
GstGLDisplay *display;
egl = GST_GL_CONTEXT_EGL (context);
@ -240,24 +239,29 @@ gst_gl_context_egl_create_context (GstGLContext * context,
}
display = gst_gl_context_get_display (context);
native_display = gst_gl_display_get_handle (display);
if (!native_display) {
GstGLWindow *window = NULL;
GST_WARNING ("Failed to get a global display handle, falling back to "
"per-window display handles. Context sharing may not work");
if (display->type == GST_GL_DISPLAY_TYPE_EGL) {
egl->egl_display = (EGLDisplay) gst_gl_display_get_handle (display);
} else {
guintptr native_display = gst_gl_display_get_handle (display);
if (other_context)
window = gst_gl_context_get_window (other_context);
if (!window)
window = gst_gl_context_get_window (context);
if (window) {
native_display = gst_gl_window_get_display (window);
gst_object_unref (window);
if (!native_display) {
GstGLWindow *window = NULL;
GST_WARNING ("Failed to get a global display handle, falling back to "
"per-window display handles. Context sharing may not work");
if (other_context)
window = gst_gl_context_get_window (other_context);
if (!window)
window = gst_gl_context_get_window (context);
if (window) {
native_display = gst_gl_window_get_display (window);
gst_object_unref (window);
}
}
}
egl->egl_display = eglGetDisplay ((EGLNativeDisplayType) native_display);
egl->egl_display = eglGetDisplay ((EGLNativeDisplayType) native_display);
}
gst_object_unref (display);
if (eglInitialize (egl->egl_display, &majorVersion, &minorVersion)) {
@ -358,8 +362,9 @@ gst_gl_context_egl_create_context (GstGLContext * context,
#endif
}
window_handle =
(EGLNativeWindowType) gst_gl_window_get_window_handle (window);
if (window)
window_handle =
(EGLNativeWindowType) gst_gl_window_get_window_handle (window);
if (window_handle) {
egl->egl_surface =
@ -398,7 +403,8 @@ gst_gl_context_egl_create_context (GstGLContext * context,
}
}
gst_object_unref (window);
if (window)
gst_object_unref (window);
return TRUE;
@ -424,10 +430,7 @@ gst_gl_context_egl_destroy_context (GstGLContext * context)
if (egl->egl_context)
eglDestroyContext (egl->egl_display, egl->egl_context);
if (egl->egl_display) {
eglTerminate (egl->egl_display);
eglReleaseThread ();
}
eglReleaseThread ();
}
static gboolean

View file

@ -0,0 +1,150 @@
/*
* GStreamer
* Copyright (C) 2014 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gl/egl/gstgldisplay_egl.h>
GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug);
#define GST_CAT_DEFAULT gst_gl_display_debug
G_DEFINE_TYPE (GstGLDisplayEGL, gst_gl_display_egl, GST_TYPE_GL_DISPLAY);
static void gst_gl_display_egl_finalize (GObject * object);
static guintptr gst_gl_display_egl_get_handle (GstGLDisplay * display);
static void
gst_gl_display_egl_class_init (GstGLDisplayEGLClass * klass)
{
GST_GL_DISPLAY_CLASS (klass)->get_handle =
GST_DEBUG_FUNCPTR (gst_gl_display_egl_get_handle);
G_OBJECT_CLASS (klass)->finalize = gst_gl_display_egl_finalize;
}
static void
gst_gl_display_egl_init (GstGLDisplayEGL * display_egl)
{
GstGLDisplay *display = (GstGLDisplay *) display_egl;
display->type = GST_GL_DISPLAY_TYPE_EGL;
display_egl->foreign_display = FALSE;
}
static void
gst_gl_display_egl_finalize (GObject * object)
{
GstGLDisplayEGL *display_egl = GST_GL_DISPLAY_EGL (object);
if (display_egl->gst_display) {
gst_egl_display_unref (display_egl->gst_display);
display_egl->gst_display = NULL;
} else if (display_egl->display && !display_egl->foreign_display) {
eglTerminate (display_egl->display);
display_egl->display = NULL;
}
G_OBJECT_CLASS (gst_gl_display_egl_parent_class)->finalize (object);
}
/**
* gst_gl_display_egl_new:
* @name: (allow-none): a display name
*
* Create a new #GstGLDisplayEGL from the x11 display name. See XOpenDisplay()
* for details on what is a valid name.
*
* Returns: (transfer full): a new #GstGLDisplayEGL or %NULL
*/
GstGLDisplayEGL *
gst_gl_display_egl_new (void)
{
GstGLDisplayEGL *ret;
GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
ret = g_object_new (GST_TYPE_GL_DISPLAY_EGL, NULL);
ret->display = eglGetDisplay ((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY);
if (!ret->display) {
GST_ERROR ("Failed to open EGL display connection");
}
return ret;
}
/**
* gst_gl_display_egl_new_with_display:
* @display: an existing, x11 display
*
* Creates a new display connection from a X11 Display.
*
* Returns: (transfer full): a new #GstGLDisplayEGL
*/
GstGLDisplayEGL *
gst_gl_display_egl_new_with_egl_display (EGLDisplay * display)
{
GstGLDisplayEGL *ret;
g_return_val_if_fail (display != NULL, NULL);
GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
ret = g_object_new (GST_TYPE_GL_DISPLAY_EGL, NULL);
ret->display = display;
ret->foreign_display = TRUE;
return ret;
}
/**
* gst_gl_display_egl_new_with_display:
* @display: an existing, x11 display
*
* Creates a new display connection from a X11 Display.
*
* Returns: (transfer full): a new #GstGLDisplayEGL
*/
GstGLDisplayEGL *
gst_gl_display_egl_new_with_gst_egl_display (GstEGLDisplay * display)
{
GstGLDisplayEGL *ret;
g_return_val_if_fail (display != NULL, NULL);
GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
ret = g_object_new (GST_TYPE_GL_DISPLAY_EGL, NULL);
ret->gst_display = gst_egl_display_ref (display);
ret->display = gst_egl_display_get (display);
ret->foreign_display = TRUE;
return ret;
}
static guintptr
gst_gl_display_egl_get_handle (GstGLDisplay * display)
{
return (guintptr) GST_GL_DISPLAY_EGL (display)->display;
}

View file

@ -0,0 +1,73 @@
/*
* GStreamer
* Copyright (C) 2014 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_DISPLAY_EGL_H__
#define __GST_GL_DISPLAY_EGL_H__
#include <gst/gst.h>
#include <gst/egl/egl.h>
#include <gst/gl/gstgl_fwd.h>
#include <gst/gl/gstgldisplay.h>
G_BEGIN_DECLS
GType gst_gl_display_egl_get_type (void);
#define GST_TYPE_GL_DISPLAY_EGL (gst_gl_display_egl_get_type())
#define GST_GL_DISPLAY_EGL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_DISPLAY_EGL,GstGLDisplayEGL))
#define GST_GL_DISPLAY_EGL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_GL_DISPLAY_EGL,GstGLDisplayEGLClass))
#define GST_IS_GL_DISPLAY_EGL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_DISPLAY_EGL))
#define GST_IS_GL_DISPLAY_EGL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_GL_DISPLAY_EGL))
#define GST_GL_DISPLAY_EGL_CAST(obj) ((GstGLDisplayEGL*)(obj))
typedef struct _GstGLDisplayEGL GstGLDisplayEGL;
typedef struct _GstGLDisplayEGLClass GstGLDisplayEGLClass;
/**
* GstGLDisplayEGL:
*
* the contents of a #GstGLDisplayEGL are private and should only be accessed
* through the provided API
*/
struct _GstGLDisplayEGL
{
GstGLDisplay parent;
/* <private> */
GstEGLDisplay *gst_display;
EGLDisplay *display;
gboolean foreign_display;
};
struct _GstGLDisplayEGLClass
{
GstGLDisplayClass object_class;
};
GstGLDisplayEGL *gst_gl_display_egl_new (void);
GstGLDisplayEGL *gst_gl_display_egl_new_with_egl_display (EGLDisplay *display);
GstGLDisplayEGL *gst_gl_display_egl_new_with_gst_egl_display (GstEGLDisplay *display);
G_END_DECLS
#endif /* __GST_GL_DISPLAY_EGL_H__ */

View file

@ -42,6 +42,9 @@
#if GST_GL_HAVE_WINDOW_X11
#include <gst/gl/x11/gstgldisplay_x11.h>
#endif
#if GST_GL_HAVE_PLATFORM_EGL
#include <gst/gl/egl/gstgldisplay_egl.h>
#endif
GST_DEBUG_CATEGORY_STATIC (gst_context);
GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug);
@ -127,6 +130,10 @@ gst_gl_display_new (void)
#if GST_GL_HAVE_WINDOW_X11
if (!display && (!user_choice || g_strstr_len (user_choice, 3, "x11")))
display = GST_GL_DISPLAY (gst_gl_display_x11_new (NULL));
#endif
#if GST_GL_HAVE_PLATFORM_EGL
if (!display && (!user_choice || g_strstr_len (user_choice, 3, "egl")))
display = GST_GL_DISPLAY (gst_gl_display_egl_new ());
#endif
if (!display) {
/* subclass returned a NULL window */

View file

@ -47,8 +47,8 @@ typedef enum
GST_GL_DISPLAY_TYPE_WAYLAND = (1 << 1),
GST_GL_DISPLAY_TYPE_COCOA = (1 << 2),
GST_GL_DISPLAY_TYPE_WIN32 = (1 << 3),
GST_GL_DISPLAY_TYPE_ANDROID = (1 << 4),
GST_GL_DISPLAY_TYPE_DISPMANX = (1 << 5),
GST_GL_DISPLAY_TYPE_DISPMANX = (1 << 4),
GST_GL_DISPLAY_TYPE_EGL = (1 << 5),
GST_GL_DISPLAY_TYPE_ANY = G_MAXUINT32
} GstGLDisplayType;