From 0278b69c8c737c66de3569a4c0b3e6f70e82da05 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Mon, 18 Mar 2013 14:39:45 -0300 Subject: eglglessink: removing egl parts for common code --- configure.ac | 4 +- ext/eglgles/Makefile.am | 4 +- ext/eglgles/gstegladaptation.c | 18 ++ ext/eglgles/gstegladaptation.h | 70 ++---- ext/eglgles/gstegladaptation_eagl.m | 279 ++++++++++++++++++++++++ ext/eglgles/gstegladaptation_egl.c | 411 ++++++++++++++++++++++++++++++++++++ ext/eglgles/gstegladaptation_ios.m | 260 ----------------------- ext/eglgles/gstegladaptation_pc.c | 364 ------------------------------- ext/eglgles/gsteglglessink.c | 6 - ext/eglgles/gsteglglessink.h | 6 - 10 files changed, 724 insertions(+), 698 deletions(-) create mode 100644 ext/eglgles/gstegladaptation_eagl.m create mode 100644 ext/eglgles/gstegladaptation_egl.c delete mode 100644 ext/eglgles/gstegladaptation_ios.m delete mode 100644 ext/eglgles/gstegladaptation_pc.c diff --git a/configure.ac b/configure.ac index 5b6a1a9c0..29b10a6f7 100644 --- a/configure.ac +++ b/configure.ac @@ -671,9 +671,7 @@ case "$host" in ;; esac HAVE_IOS="no" -if test "x$HAVE_APPLE_MEDIA" = "xyes"; then - AC_CHECK_HEADER(MobileCoreServices/MobileCoreServices.h, HAVE_IOS="yes", HAVE_IOS="no", [-]) -fi +AC_CHECK_HEADER(MobileCoreServices/MobileCoreServices.h, HAVE_IOS="yes", HAVE_IOS="no", [-]) AM_CONDITIONAL(HAVE_IOS, test "x$HAVE_IOS" = "xyes") if test "x$HAVE_IOS" = "xyes"; then diff --git a/ext/eglgles/Makefile.am b/ext/eglgles/Makefile.am index 9d50f949a..ad1e17915 100644 --- a/ext/eglgles/Makefile.am +++ b/ext/eglgles/Makefile.am @@ -1,9 +1,9 @@ plugin_LTLIBRARIES = libgsteglglessink.la if HAVE_IOS -DISTRO_SRC = gstegladaptation_ios.m +DISTRO_SRC = gstegladaptation_eagl.m else -DISTRO_SRC = gstegladaptation_pc.c +DISTRO_SRC = gstegladaptation_egl.c endif libgsteglglessink_la_SOURCES = gsteglglessink.c video_platform_wrapper.c gstegladaptation.c $(DISTRO_SRC) diff --git a/ext/eglgles/gstegladaptation.c b/ext/eglgles/gstegladaptation.c index e075ea9f5..585fbc046 100644 --- a/ext/eglgles/gstegladaptation.c +++ b/ext/eglgles/gstegladaptation.c @@ -45,6 +45,22 @@ #include #include "gstegladaptation.h" +/* + * GstEglGlesImageFmt: + * @fmt: Internal identifier for the EGL attribs / GST caps pairing + * @attribs: Pointer to the set of EGL attributes asociated with this format + * @caps: Pointer to the GST caps asociated with this format + * + * This struct holds a pairing between GST caps and the matching EGL attributes + * associated with a given pixel format + */ +struct _GstEglGlesImageFmt +{ + gint fmt; /* Private identifier */ + const EGLint *attribs; /* EGL Attributes */ + GstCaps *caps; /* Matching caps for the attribs */ +}; + /* GLESv2 GLSL Shaders * * OpenGL ES Standard does not mandate YUV support. This is @@ -302,6 +318,8 @@ gst_egl_adaptation_context_new (GstElement * element) ctx->element = gst_object_ref (element); + gst_egl_adaptation_context_init (ctx); + return ctx; } diff --git a/ext/eglgles/gstegladaptation.h b/ext/eglgles/gstegladaptation.h index 4aca04d5d..917dd03b3 100644 --- a/ext/eglgles/gstegladaptation.h +++ b/ext/eglgles/gstegladaptation.h @@ -45,11 +45,18 @@ #ifndef __GST_EGL_ADAPTATION_H__ #define __GST_EGL_ADAPTATION_H__ +#ifdef HAVE_CONFIG_H +# include +#endif + #include + +#ifndef HAVE_IOS #include #include #include #include +#endif #ifdef USE_EGL_RPI #include @@ -79,6 +86,7 @@ static const EGLint eglglessink_RGBA8888_attribs[] = { typedef struct GstEglAdaptationContext GstEglAdaptationContext; typedef struct _GstEglGlesRenderContext GstEglGlesRenderContext; typedef struct _GstEglGlesImageFmt GstEglGlesImageFmt; +typedef struct _GstEaglContext GstEaglContext; typedef struct _coord5 { @@ -89,58 +97,6 @@ typedef struct _coord5 float b; /* texpos y */ } coord5; -/* - * GstEglGlesRenderContext: - * @config: Current EGL config - * @eglcontext: Current EGL context - * @display: Current EGL display connection - * @window: Current EGL window asociated with the display connection - * @used_window: Last seen EGL window asociated with the display connection - * @surface: EGL surface the sink is rendering into - * @fragshader: Fragment shader - * @vertshader: Vertex shader - * @glslprogram: Compiled and linked GLSL program in use for rendering - * @texture Texture units in use - * @pixel_aspect_ratio: EGL display aspect ratio - * @egl_minor: EGL version (minor) - * @egl_major: EGL version (major) - * @n_textures: Texture units count - * @position_loc: Index of the position vertex attribute array - * @texpos_loc: Index of the textpos vertex attribute array - * @position_array: VBO position array - * @texpos_array: VBO texpos array - * @index_array: VBO index array - * @position_buffer: Position buffer object name - * @texpos_buffer: Texpos buffer object name - * @index_buffer: Index buffer object name - * - * This struct holds the sink's EGL/GLES rendering context. - */ -struct _GstEglGlesRenderContext -{ - EGLConfig config; - EGLContext eglcontext; - EGLSurface surface; - EGLint egl_minor, egl_major; -}; - -/* - * GstEglGlesImageFmt: - * @fmt: Internal identifier for the EGL attribs / GST caps pairing - * @attribs: Pointer to the set of EGL attributes asociated with this format - * @caps: Pointer to the GST caps asociated with this format - * - * This struct holds a pairing between GST caps and the matching EGL attributes - * associated with a given pixel format - */ -struct _GstEglGlesImageFmt -{ - gint fmt; /* Private identifier */ - const EGLint *attribs; /* EGL Attributes */ - GstCaps *caps; /* Matching caps for the attribs */ -}; - - /* * GstEglAdaptationContext: * @have_vbo: Set if the GLES VBO setup has been performed @@ -183,16 +139,16 @@ struct GstEglAdaptationContext coord5 position_array[12]; /* 4 x Frame, 4 x Border1, 4 x Border2 */ unsigned short index_array[4]; -#if USE_IOS - EAGLContext *eagl_context; - GLUint framebuffer; - GLUint color_renderbuffer; +#if HAVE_IOS + GstEaglContext *eaglctx; #else - GstEglGlesRenderContext eglglesctx; + GstEglGlesRenderContext *eglglesctx; #endif }; GstEglAdaptationContext * gst_egl_adaptation_context_new (GstElement * element); +void gst_egl_adaptation_context_init (GstEglAdaptationContext * ctx); +void gst_egl_adaptation_context_deinit (GstEglAdaptationContext * ctx); void gst_egl_adaptation_context_free (GstEglAdaptationContext * ctx); /* platform window */ diff --git a/ext/eglgles/gstegladaptation_eagl.m b/ext/eglgles/gstegladaptation_eagl.m new file mode 100644 index 000000000..55c0a23fc --- /dev/null +++ b/ext/eglgles/gstegladaptation_eagl.m @@ -0,0 +1,279 @@ +/* + * GStreamer EGL/GLES Sink Adaptation for IOS + * Copyright (C) 2013 Collabora Ltd. + * @author: Thiago Santos + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +typedef struct _GstEaglContext +{ + EAGLContext *eagl_context; + GLUint framebuffer; + GLUint color_renderbuffer; +} GstEaglContext; + +void +gst_egl_adaptation_context_init (GstEglAdaptationContext * ctx) +{ + ctx->eaglctx = g_new0 (GstEaglContext, 1); +} + +void +gst_egl_adaptation_context_deinit (GstEglAdaptationContext * ctx) +{ + g_free (ctx->eaglctx); +} + +gboolean +gst_egl_adaptation_init_display (GstEglAdaptationContext * ctx) +{ + /* NOP - the display should be initialized by the application */ +} + +void +gst_egl_adaptation_context_terminate_display (GstEglAdaptationContext * ctx) +{ + /* NOP */ +} + +void +gst_egl_adaptation_context_bind_API (GstEglAdaptationContext * ctx) +{ + /* NOP */ +} + +gboolean +gst_egl_adaptation_create_native_window (GstEglAdaptationContext * ctx, gint width, gint height, gpointer * own_window_data) +{ +} + +void +gst_egl_adaptation_destroy_native_window (GstEglAdaptationContext * ctx, gpointer * own_window_data) +{ +} + +gboolean +gst_egl_adaptation_create_egl_context (GstEglAdaptationContext * ctx) +{ + EAGLContext *context; + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + if (context == nil) + GST_ERROR_OBJECT (ctx->element, "Failed to create EAGL GLES2 context"); + return FALSE; + } + ctx->eagl_context = context; + + return TRUE; +} + +gboolean +gst_egl_adaptation_context_make_current (GstEglAdaptationContext * ctx, + gboolean bind) +{ + if (bind && ctx->eagl_context) { + EAGLContext *cur_ctx = [EAGLContext currentContext]; + + if (cur_ctx == ctx->eagl_context) { + GST_DEBUG_OBJECT (ctx->element, + "Already attached the context to thread %p", g_thread_self ()); + return TRUE; + } + + GST_DEBUG_OBJECT (ctx->element, "Attaching context to thread %p", + g_thread_self ()); + if ([EAGLContext setCurrentContext: ctx->eagl_context] == NO) { + got_egl_error ("eglMakeCurrent"); + GST_ERROR_OBJECT (ctx->element, "Couldn't bind context"); + return FALSE; + } + } else { + GST_DEBUG_OBJECT (ctx->element, "Detaching context from thread %p", + g_thread_self ()); + if ([EAGLContext setCurrentContext: nil] == NO) { + got_egl_error ("eglMakeCurrent"); + GST_ERROR_OBJECT (ctx->element, "Couldn't unbind context"); + return FALSE; + } + } + + return TRUE; +} + +gboolean +gst_egl_adaptation_create_surface (GstEglAdaptationContext * ctx) +{ + GLuint framebuffer; + GLuint colorRenderbuffer; + GLint width; + GLint height; + GLuint depthRenderbuffer; + GLenum status; + + /* Allocate framebuffer */ + glGenFramebuffers(1, &framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + + /* Allocate color render buffer */ + glGenRenderbuffers(1, &colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); + [ctx->eagl_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:myEAGLLayer]; + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, colorRenderbuffer); + + /* Get renderbuffer width/height */ + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); + + /* allocate depth render buffer */ + glGenRenderbuffers(1, &depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, depthRenderbuffer); + + /* check creation status */ + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if(status != GL_FRAMEBUFFER_COMPLETE) { + NSLog(@"failed to make complete framebuffer object %x", status); + return FALSE; + } + + ctx->framebuffer = framebuffer; + ctx->color_renderbuffer = colorRenderbuffer; + + return TRUE; +} + +gboolean +_gst_egl_choose_config (GstEglAdaptationContext * ctx, gboolean try_only, gint * num_configs) +{ + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)[[UIView ctx->window] layer]; + NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, + kEAGLColorFormatRGBA8888, kEAGLDrawablePropertyColorFormat, + nil]; + [eaglLayer setOpaque:YES]; + [eaglLayer setDrawableProperties:dict]; + + if (num_configs) + *num_configs = 1; +} + +void +gst_egl_adaptation_query_buffer_preserved (GstEglAdaptationContext * ctx) +{ + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)[[UIView ctx->window] layer]; + NSDictionary *dict = [eaglLayer drawableProperties]; + + ctx->buffer_preserved = FALSE; + if ([dict objectForKey: kEAGLDrawablePropertyRetainedBacking] != nil) { + NSNumber n = [dict objectForKey: kEAGLDrawablePropertyRetainedBacking]; + ctx->buffer_preserved = n != [NSNumber numberWithBool:NO]; + } else { + GST_DEBUG_OBJECT (ctx->element, "No information about buffer preserving in layer properties"); + } +} + +void +gst_egl_adaptation_query_par (GstEglAdaptationContext * ctx) +{ + /* TODO how can we check this? */ + ctx->pixel_aspect_ratio = EGL_DISPLAY_SCALING; +} + +gboolean +gst_egl_adaptation_context_update_surface_dimensions (GstEglAdaptationContext * + ctx) +{ + GLint width; + GLint height; + + /* Get renderbuffer width/height */ + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); + + if (width != ctx->surface_width || height != ctx->surface_height) { + ctx->surface_width = width; + ctx->surface_height = height; + GST_INFO_OBJECT (ctx->element, "Got surface of %dx%d pixels", width, + height); + return TRUE; + } + + return FALSE; +} + +void +gst_egl_adaptation_context_init_egl_exts (GstEglAdaptationContext * ctx) +{ + NSString *extensionsString = [NSString stringWithCString:glGetString(GL_EXTENSIONS) encoding: NSASCIIStringEncoding]; + + GST_DEBUG_OBJECT (ctx->element, "Available GL extensions: %s\n", + GST_STR_NULL ([extensionsString UTF8String])); +} + +void +gst_egl_adaptation_destroy_surface (GstEglAdaptationContext * ctx) +{ + if (ctx->framebuffer) { + glDeleteFrameuffers (1, &ctx->framebuffer); + ctx->framebuffer = 0; + ctx->have_surface = FALSE; + } +} + +void +gst_egl_adaptation_destroy_context (GstEglAdaptationContext * ctx) +{ + if (ctx->eglglesctx.eglcontext) { + [ctx->eagl_context dealloc]; + ctx->eagl_context = NULL; + } +} + +gboolean +gst_egl_adaptation_context_swap_buffers (GstEglAdaptationContext * ctx) +{ + glBindRenderbuffer(GL_RENDERBUFFER, ctx->colorRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER]; + + return TRUE; +} + diff --git a/ext/eglgles/gstegladaptation_egl.c b/ext/eglgles/gstegladaptation_egl.c new file mode 100644 index 000000000..25dda61b7 --- /dev/null +++ b/ext/eglgles/gstegladaptation_egl.c @@ -0,0 +1,411 @@ +/* + * GStreamer EGL/GLES Sink Adaptation + * Copyright (C) 2013 Collabora Ltd. + * @author: Thiago Santos + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Alternatively, the contents of this file may be used under the + * GNU Lesser General Public License Version 2.1 (the "LGPL"), in + * which case the following provisions apply instead of the ones + * mentioned above: + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gstegladaptation.h" + +#include "video_platform_wrapper.h" + +/* + * GstEglGlesRenderContext: + * @config: Current EGL config + * @eglcontext: Current EGL context + * @display: Current EGL display connection + * @window: Current EGL window asociated with the display connection + * @used_window: Last seen EGL window asociated with the display connection + * @surface: EGL surface the sink is rendering into + * @fragshader: Fragment shader + * @vertshader: Vertex shader + * @glslprogram: Compiled and linked GLSL program in use for rendering + * @texture Texture units in use + * @pixel_aspect_ratio: EGL display aspect ratio + * @egl_minor: EGL version (minor) + * @egl_major: EGL version (major) + * @n_textures: Texture units count + * @position_loc: Index of the position vertex attribute array + * @texpos_loc: Index of the textpos vertex attribute array + * @position_array: VBO position array + * @texpos_array: VBO texpos array + * @index_array: VBO index array + * @position_buffer: Position buffer object name + * @texpos_buffer: Texpos buffer object name + * @index_buffer: Index buffer object name + * + * This struct holds the sink's EGL/GLES rendering context. + */ +struct _GstEglGlesRenderContext +{ + EGLConfig config; + EGLContext eglcontext; + EGLSurface surface; + EGLint egl_minor, egl_major; +}; + +/* Some EGL implementations are reporting wrong + * values for the display's EGL_PIXEL_ASPECT_RATIO. + * They are required by the khronos specs to report + * this value as w/h * EGL_DISPLAY_SCALING (Which is + * a constant with value 10000) but at least the + * Galaxy SIII (Android) is reporting just 1 when + * w = h. We use these two to bound returned values to + * sanity. + */ +#define EGL_SANE_DAR_MIN ((EGL_DISPLAY_SCALING)/10) +#define EGL_SANE_DAR_MAX ((EGL_DISPLAY_SCALING)*10) + +gboolean +gst_egl_adaptation_init_display (GstEglAdaptationContext * ctx) +{ + EGLDisplay display; + GST_DEBUG_OBJECT (ctx->element, "Enter EGL initial configuration"); + +#ifdef USE_EGL_RPI + /* See https://github.com/raspberrypi/firmware/issues/99 */ + if (!eglMakeCurrent ((EGLDisplay) 1, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT)) { + got_egl_error ("eglMakeCurrent"); + GST_ERROR_OBJECT (ctx->element, "Couldn't unbind context"); + return FALSE; + } +#endif + + display = eglGetDisplay (EGL_DEFAULT_DISPLAY); + if (display == EGL_NO_DISPLAY) { + GST_ERROR_OBJECT (ctx->element, "Could not get EGL display connection"); + goto HANDLE_ERROR; /* No EGL error is set by eglGetDisplay() */ + } + ctx->display = display; + + if (!eglInitialize (display, + &ctx->eglglesctx->egl_major, &ctx->eglglesctx->egl_minor)) { + got_egl_error ("eglInitialize"); + GST_ERROR_OBJECT (ctx->element, "Could not init EGL display connection"); + goto HANDLE_EGL_ERROR; + } + + /* Check against required EGL version + * XXX: Need to review the version requirement in terms of the needed API + */ + if (ctx->eglglesctx->egl_major < GST_EGLGLESSINK_EGL_MIN_VERSION) { + GST_ERROR_OBJECT (ctx->element, "EGL v%d needed, but you only have v%d.%d", + GST_EGLGLESSINK_EGL_MIN_VERSION, ctx->eglglesctx->egl_major, + ctx->eglglesctx->egl_minor); + goto HANDLE_ERROR; + } + + GST_INFO_OBJECT (ctx->element, "System reports supported EGL version v%d.%d", + ctx->eglglesctx->egl_major, ctx->eglglesctx->egl_minor); + + eglBindAPI (EGL_OPENGL_ES_API); + + return TRUE; + + /* Errors */ +HANDLE_EGL_ERROR: + GST_ERROR_OBJECT (ctx->element, "EGL call returned error %x", eglGetError ()); +HANDLE_ERROR: + GST_ERROR_OBJECT (ctx->element, "Couldn't setup window/surface from handle"); + return FALSE; +} + +void +gst_egl_adaptation_context_terminate_display (GstEglAdaptationContext * ctx) +{ + if (ctx->display) { + eglTerminate (ctx->display); + ctx->display = NULL; + } +} + + +gboolean +_gst_egl_choose_config (GstEglAdaptationContext * ctx, gboolean try_only, + gint * num_configs) +{ + EGLint cfg_number; + gboolean ret; + EGLConfig *config = NULL; + + if (!try_only) + config = &ctx->eglglesctx->config; + + ret = eglChooseConfig (ctx->display, + eglglessink_RGBA8888_attribs, config, 1, &cfg_number) != EGL_FALSE; + + if (num_configs) + *num_configs = cfg_number; + return ret; +} + +gboolean +gst_egl_adaptation_create_egl_context (GstEglAdaptationContext * ctx) +{ + EGLint con_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + + ctx->eglglesctx->eglcontext = + eglCreateContext (ctx->display, + ctx->eglglesctx->config, EGL_NO_CONTEXT, con_attribs); + + if (ctx->eglglesctx->eglcontext == EGL_NO_CONTEXT) { + return FALSE; + } + + GST_DEBUG_OBJECT (ctx->element, "EGL Context: %p", + ctx->eglglesctx->eglcontext); + + return TRUE; +} + +gboolean +gst_egl_adaptation_context_make_current (GstEglAdaptationContext * ctx, + gboolean bind) +{ + g_assert (ctx->display != NULL); + + if (bind && ctx->eglglesctx->surface && ctx->eglglesctx->eglcontext) { + EGLContext *cur_ctx = eglGetCurrentContext (); + + if (cur_ctx == ctx->eglglesctx->eglcontext) { + GST_DEBUG_OBJECT (ctx->element, + "Already attached the context to thread %p", g_thread_self ()); + return TRUE; + } + + GST_DEBUG_OBJECT (ctx->element, "Attaching context to thread %p", + g_thread_self ()); + if (!eglMakeCurrent (ctx->display, + ctx->eglglesctx->surface, ctx->eglglesctx->surface, + ctx->eglglesctx->eglcontext)) { + got_egl_error ("eglMakeCurrent"); + GST_ERROR_OBJECT (ctx->element, "Couldn't bind context"); + return FALSE; + } + } else { + GST_DEBUG_OBJECT (ctx->element, "Detaching context from thread %p", + g_thread_self ()); + if (!eglMakeCurrent (ctx->display, EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT)) { + got_egl_error ("eglMakeCurrent"); + GST_ERROR_OBJECT (ctx->element, "Couldn't unbind context"); + return FALSE; + } + } + + return TRUE; +} + +gboolean +gst_egl_adaptation_create_surface (GstEglAdaptationContext * ctx) +{ + ctx->eglglesctx->surface = + eglCreateWindowSurface (ctx->display, + ctx->eglglesctx->config, ctx->used_window, NULL); + + if (ctx->eglglesctx->surface == EGL_NO_SURFACE) { + got_egl_error ("eglCreateWindowSurface"); + GST_ERROR_OBJECT (ctx->element, "Can't create surface"); + return FALSE; + } + return TRUE; +} + +void +gst_egl_adaptation_query_buffer_preserved (GstEglAdaptationContext * ctx) +{ + EGLint swap_behavior; + + ctx->buffer_preserved = FALSE; + if (eglQuerySurface (ctx->display, + ctx->eglglesctx->surface, EGL_SWAP_BEHAVIOR, &swap_behavior)) { + GST_DEBUG_OBJECT (ctx->element, "Buffer swap behavior %x", swap_behavior); + ctx->buffer_preserved = swap_behavior == EGL_BUFFER_PRESERVED; + } else { + GST_DEBUG_OBJECT (ctx->element, "Can't query buffer swap behavior"); + } +} + +void +gst_egl_adaptation_query_par (GstEglAdaptationContext * ctx) +{ + EGLint display_par; + + /* Save display's pixel aspect ratio + * + * DAR is reported as w/h * EGL_DISPLAY_SCALING wich is + * a constant with value 10000. This attribute is only + * supported if the EGL version is >= 1.2 + * XXX: Setup this as a property. + * or some other one time check. Right now it's being called once + * per frame. + */ + if (ctx->eglglesctx->egl_major == 1 && ctx->eglglesctx->egl_minor < 2) { + GST_DEBUG_OBJECT (ctx->element, "Can't query PAR. Using default: %dx%d", + EGL_DISPLAY_SCALING, EGL_DISPLAY_SCALING); + ctx->pixel_aspect_ratio = EGL_DISPLAY_SCALING; + } else { + eglQuerySurface (ctx->display, + ctx->eglglesctx->surface, EGL_PIXEL_ASPECT_RATIO, &display_par); + /* Fix for outbound DAR reporting on some implementations not + * honoring the 'should return w/h * EGL_DISPLAY_SCALING' spec + * requirement + */ + if (display_par == EGL_UNKNOWN || display_par < EGL_SANE_DAR_MIN || + display_par > EGL_SANE_DAR_MAX) { + GST_DEBUG_OBJECT (ctx->element, "Nonsensical PAR value returned: %d. " + "Bad EGL implementation? " + "Will use default: %d/%d", ctx->pixel_aspect_ratio, + EGL_DISPLAY_SCALING, EGL_DISPLAY_SCALING); + ctx->pixel_aspect_ratio = EGL_DISPLAY_SCALING; + } else { + ctx->pixel_aspect_ratio = display_par; + } + } +} + +/* XXX: Lock eglgles context? */ +/* TODO refactor only to get the w/h and let common code do the updates */ +gboolean +gst_egl_adaptation_context_update_surface_dimensions (GstEglAdaptationContext * + ctx) +{ + gint width, height; + + /* Save surface dims */ + eglQuerySurface (ctx->display, ctx->eglglesctx->surface, EGL_WIDTH, &width); + eglQuerySurface (ctx->display, ctx->eglglesctx->surface, EGL_HEIGHT, &height); + + if (width != ctx->surface_width || height != ctx->surface_height) { + ctx->surface_width = width; + ctx->surface_height = height; + GST_INFO_OBJECT (ctx->element, "Got surface of %dx%d pixels", width, + height); + return TRUE; + } + + return FALSE; +} + +/* Prints avilable EGL/GLES extensions + * If another rendering path is implemented this is the place + * where you want to check for the availability of its supporting + * EGL/GLES extensions. + */ +void +gst_egl_adaptation_context_init_egl_exts (GstEglAdaptationContext * ctx) +{ + const char *eglexts; + unsigned const char *glexts; + + eglexts = eglQueryString (ctx->display, EGL_EXTENSIONS); + glexts = glGetString (GL_EXTENSIONS); + + GST_DEBUG_OBJECT (ctx->element, "Available EGL extensions: %s\n", + GST_STR_NULL (eglexts)); + GST_DEBUG_OBJECT (ctx->element, "Available GLES extensions: %s\n", + GST_STR_NULL ((const char *) glexts)); + + return; +} + +void +gst_egl_adaptation_destroy_surface (GstEglAdaptationContext * ctx) +{ + if (ctx->eglglesctx->surface) { + eglDestroySurface (ctx->display, ctx->eglglesctx->surface); + ctx->eglglesctx->surface = NULL; + ctx->have_surface = FALSE; + } +} + +void +gst_egl_adaptation_destroy_context (GstEglAdaptationContext * ctx) +{ + if (ctx->eglglesctx->eglcontext) { + eglDestroyContext (ctx->display, ctx->eglglesctx->eglcontext); + ctx->eglglesctx->eglcontext = NULL; + } +} + +void +gst_egl_adaptation_context_bind_API (GstEglAdaptationContext * ctx) +{ + eglBindAPI (EGL_OPENGL_ES_API); +} + +gboolean +gst_egl_adaptation_context_swap_buffers (GstEglAdaptationContext * ctx) +{ + gboolean ret = eglSwapBuffers (ctx->display, ctx->eglglesctx->surface); + if (ret == EGL_FALSE) { + got_egl_error ("eglSwapBuffers"); + } + return ret; +} + +gboolean +gst_egl_adaptation_create_native_window (GstEglAdaptationContext * ctx, + gint width, gint height, gpointer * own_window_data) +{ + return platform_create_native_window (width, height, own_window_data); +} + +void +gst_egl_adaptation_destroy_native_window (GstEglAdaptationContext * ctx, + gpointer * own_window_data) +{ + platform_destroy_native_window (ctx->display, ctx->used_window, + own_window_data); + ctx->used_window = 0; +} + +void +gst_egl_adaptation_context_init (GstEglAdaptationContext * ctx) +{ + ctx->eglglesctx = g_new0 (GstEglGlesRenderContext, 1); +} + +void +gst_egl_adaptation_context_deinit (GstEglAdaptationContext * ctx) +{ + g_free (ctx->eglglesctx); +} diff --git a/ext/eglgles/gstegladaptation_ios.m b/ext/eglgles/gstegladaptation_ios.m deleted file mode 100644 index e4eb5576a..000000000 --- a/ext/eglgles/gstegladaptation_ios.m +++ /dev/null @@ -1,260 +0,0 @@ -/* - * GStreamer EGL/GLES Sink Adaptation for IOS - * Copyright (C) 2013 Collabora Ltd. - * @author: Thiago Santos - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -gboolean -gst_egl_adaptation_init_display (GstEglAdaptationContext * ctx) -{ - /* NOP - the display should be initialized by the application */ -} - -void -gst_egl_adaptation_context_terminate_display (GstEglAdaptationContext * ctx) -{ - /* NOP */ -} - -void -gst_egl_adaptation_context_bind_API (GstEglAdaptationContext * ctx) -{ - /* NOP */ -} - -gboolean -gst_egl_adaptation_create_native_window (GstEglAdaptationContext * ctx, gint width, gint height, gpointer * own_window_data) -{ -} - -void -gst_egl_adaptation_destroy_native_window (GstEglAdaptationContext * ctx, gpointer * own_window_data) -{ -} - -gboolean -gst_egl_adaptation_create_egl_context (GstEglAdaptationContext * ctx) -{ - EAGLContext *context; - context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; - if (context == nil) - GST_ERROR_OBJECT (ctx->element, "Failed to create EAGL GLES2 context"); - return FALSE; - } - ctx->eagl_context = context; - - return TRUE; -} - -gboolean -gst_egl_adaptation_context_make_current (GstEglAdaptationContext * ctx, - gboolean bind) -{ - if (bind && ctx->eagl_context) { - EAGLContext *cur_ctx = [EAGLContext currentContext]; - - if (cur_ctx == ctx->eagl_context) { - GST_DEBUG_OBJECT (ctx->element, - "Already attached the context to thread %p", g_thread_self ()); - return TRUE; - } - - GST_DEBUG_OBJECT (ctx->element, "Attaching context to thread %p", - g_thread_self ()); - if ([EAGLContext setCurrentContext: ctx->eagl_context] == NO) { - got_egl_error ("eglMakeCurrent"); - GST_ERROR_OBJECT (ctx->element, "Couldn't bind context"); - return FALSE; - } - } else { - GST_DEBUG_OBJECT (ctx->element, "Detaching context from thread %p", - g_thread_self ()); - if ([EAGLContext setCurrentContext: nil] == NO) { - got_egl_error ("eglMakeCurrent"); - GST_ERROR_OBJECT (ctx->element, "Couldn't unbind context"); - return FALSE; - } - } - - return TRUE; -} - -gboolean -gst_egl_adaptation_create_surface (GstEglAdaptationContext * ctx) -{ - GLuint framebuffer; - GLuint colorRenderbuffer; - GLint width; - GLint height; - GLuint depthRenderbuffer; - GLenum status; - - /* Allocate framebuffer */ - glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - - /* Allocate color render buffer */ - glGenRenderbuffers(1, &colorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); - [ctx->eagl_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:myEAGLLayer]; - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, colorRenderbuffer); - - /* Get renderbuffer width/height */ - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); - - /* allocate depth render buffer */ - glGenRenderbuffers(1, &depthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, depthRenderbuffer); - - /* check creation status */ - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if(status != GL_FRAMEBUFFER_COMPLETE) { - NSLog(@"failed to make complete framebuffer object %x", status); - return FALSE; - } - - ctx->framebuffer = framebuffer; - ctx->color_renderbuffer = colorRenderbuffer; - - return TRUE; -} - -gboolean -_gst_egl_choose_config (GstEglAdaptationContext * ctx, gboolean try_only, gint * num_configs) -{ - CAEAGLLayer *eaglLayer = (CAEAGLLayer *)[[UIView ctx->window] layer]; - NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, - kEAGLColorFormatRGBA8888, kEAGLDrawablePropertyColorFormat, - nil]; - [eaglLayer setOpaque:YES]; - [eaglLayer setDrawableProperties:dict]; - - if (num_configs) - *num_configs = 1; -} - -void -gst_egl_adaptation_query_buffer_preserved (GstEglAdaptationContext * ctx) -{ - CAEAGLLayer *eaglLayer = (CAEAGLLayer *)[[UIView ctx->window] layer]; - NSDictionary *dict = [eaglLayer drawableProperties]; - - ctx->buffer_preserved = FALSE; - if ([dict objectForKey: kEAGLDrawablePropertyRetainedBacking] != nil) { - NSNumber n = [dict objectForKey: kEAGLDrawablePropertyRetainedBacking]; - ctx->buffer_preserved = n != [NSNumber numberWithBool:NO]; - } else { - GST_DEBUG_OBJECT (ctx->element, "No information about buffer preserving in layer properties"); - } -} - -void -gst_egl_adaptation_query_par (GstEglAdaptationContext * ctx) -{ - /* TODO how can we check this? */ - ctx->pixel_aspect_ratio = EGL_DISPLAY_SCALING; -} - -gboolean -gst_egl_adaptation_context_update_surface_dimensions (GstEglAdaptationContext * - ctx) -{ - GLint width; - GLint height; - - /* Get renderbuffer width/height */ - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); - - if (width != ctx->surface_width || height != ctx->surface_height) { - ctx->surface_width = width; - ctx->surface_height = height; - GST_INFO_OBJECT (ctx->element, "Got surface of %dx%d pixels", width, - height); - return TRUE; - } - - return FALSE; -} - -void -gst_egl_adaptation_context_init_egl_exts (GstEglAdaptationContext * ctx) -{ - NSString *extensionsString = [NSString stringWithCString:glGetString(GL_EXTENSIONS) encoding: NSASCIIStringEncoding]; - - GST_DEBUG_OBJECT (ctx->element, "Available GL extensions: %s\n", - GST_STR_NULL ([extensionsString UTF8String])); -} - -void -gst_egl_adaptation_destroy_surface (GstEglAdaptationContext * ctx) -{ - if (ctx->framebuffer) { - glDeleteFrameuffers (1, &ctx->framebuffer); - ctx->framebuffer = 0; - ctx->have_surface = FALSE; - } -} - -void -gst_egl_adaptation_destroy_context (GstEglAdaptationContext * ctx) -{ - if (ctx->eglglesctx.eglcontext) { - [ctx->eagl_context dealloc]; - ctx->eagl_context = NULL; - } -} - -gboolean -gst_egl_adaptation_context_swap_buffers (GstEglAdaptationContext * ctx) -{ - glBindRenderbuffer(GL_RENDERBUFFER, ctx->colorRenderbuffer); - [context presentRenderbuffer:GL_RENDERBUFFER]; - - return TRUE; -} - diff --git a/ext/eglgles/gstegladaptation_pc.c b/ext/eglgles/gstegladaptation_pc.c deleted file mode 100644 index 1ece48bb6..000000000 --- a/ext/eglgles/gstegladaptation_pc.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * GStreamer EGL/GLES Sink Adaptation - * Copyright (C) 2013 Collabora Ltd. - * @author: Thiago Santos - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "gstegladaptation.h" - -#include "video_platform_wrapper.h" - -/* Some EGL implementations are reporting wrong - * values for the display's EGL_PIXEL_ASPECT_RATIO. - * They are required by the khronos specs to report - * this value as w/h * EGL_DISPLAY_SCALING (Which is - * a constant with value 10000) but at least the - * Galaxy SIII (Android) is reporting just 1 when - * w = h. We use these two to bound returned values to - * sanity. - */ -#define EGL_SANE_DAR_MIN ((EGL_DISPLAY_SCALING)/10) -#define EGL_SANE_DAR_MAX ((EGL_DISPLAY_SCALING)*10) - -gboolean -gst_egl_adaptation_init_display (GstEglAdaptationContext * ctx) -{ - EGLDisplay display; - GST_DEBUG_OBJECT (ctx->element, "Enter EGL initial configuration"); - -#ifdef USE_EGL_RPI - /* See https://github.com/raspberrypi/firmware/issues/99 */ - if (!eglMakeCurrent ((EGLDisplay) 1, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT)) { - got_egl_error ("eglMakeCurrent"); - GST_ERROR_OBJECT (ctx->element, "Couldn't unbind context"); - return FALSE; - } -#endif - - display = eglGetDisplay (EGL_DEFAULT_DISPLAY); - if (display == EGL_NO_DISPLAY) { - GST_ERROR_OBJECT (ctx->element, "Could not get EGL display connection"); - goto HANDLE_ERROR; /* No EGL error is set by eglGetDisplay() */ - } - ctx->display = display; - - if (!eglInitialize (display, - &ctx->eglglesctx.egl_major, &ctx->eglglesctx.egl_minor)) { - got_egl_error ("eglInitialize"); - GST_ERROR_OBJECT (ctx->element, "Could not init EGL display connection"); - goto HANDLE_EGL_ERROR; - } - - /* Check against required EGL version - * XXX: Need to review the version requirement in terms of the needed API - */ - if (ctx->eglglesctx.egl_major < GST_EGLGLESSINK_EGL_MIN_VERSION) { - GST_ERROR_OBJECT (ctx->element, "EGL v%d needed, but you only have v%d.%d", - GST_EGLGLESSINK_EGL_MIN_VERSION, ctx->eglglesctx.egl_major, - ctx->eglglesctx.egl_minor); - goto HANDLE_ERROR; - } - - GST_INFO_OBJECT (ctx->element, "System reports supported EGL version v%d.%d", - ctx->eglglesctx.egl_major, ctx->eglglesctx.egl_minor); - - eglBindAPI (EGL_OPENGL_ES_API); - - return TRUE; - - /* Errors */ -HANDLE_EGL_ERROR: - GST_ERROR_OBJECT (ctx->element, "EGL call returned error %x", eglGetError ()); -HANDLE_ERROR: - GST_ERROR_OBJECT (ctx->element, "Couldn't setup window/surface from handle"); - return FALSE; -} - -void -gst_egl_adaptation_context_terminate_display (GstEglAdaptationContext * ctx) -{ - if (ctx->display) { - eglTerminate (ctx->display); - ctx->display = NULL; - } -} - - -gboolean -_gst_egl_choose_config (GstEglAdaptationContext * ctx, gboolean try_only, - gint * num_configs) -{ - EGLint cfg_number; - gboolean ret; - EGLConfig *config = NULL; - - if (!try_only) - config = &ctx->eglglesctx.config; - - ret = eglChooseConfig (ctx->display, - eglglessink_RGBA8888_attribs, config, 1, &cfg_number) != EGL_FALSE; - - if (num_configs) - *num_configs = cfg_number; - return ret; -} - -gboolean -gst_egl_adaptation_create_egl_context (GstEglAdaptationContext * ctx) -{ - EGLint con_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - - ctx->eglglesctx.eglcontext = - eglCreateContext (ctx->display, - ctx->eglglesctx.config, EGL_NO_CONTEXT, con_attribs); - - if (ctx->eglglesctx.eglcontext == EGL_NO_CONTEXT) { - return FALSE; - } - - GST_DEBUG_OBJECT (ctx->element, "EGL Context: %p", - ctx->eglglesctx.eglcontext); - - return TRUE; -} - -gboolean -gst_egl_adaptation_context_make_current (GstEglAdaptationContext * ctx, - gboolean bind) -{ - g_assert (ctx->display != NULL); - - if (bind && ctx->eglglesctx.surface && ctx->eglglesctx.eglcontext) { - EGLContext *cur_ctx = eglGetCurrentContext (); - - if (cur_ctx == ctx->eglglesctx.eglcontext) { - GST_DEBUG_OBJECT (ctx->element, - "Already attached the context to thread %p", g_thread_self ()); - return TRUE; - } - - GST_DEBUG_OBJECT (ctx->element, "Attaching context to thread %p", - g_thread_self ()); - if (!eglMakeCurrent (ctx->display, - ctx->eglglesctx.surface, ctx->eglglesctx.surface, - ctx->eglglesctx.eglcontext)) { - got_egl_error ("eglMakeCurrent"); - GST_ERROR_OBJECT (ctx->element, "Couldn't bind context"); - return FALSE; - } - } else { - GST_DEBUG_OBJECT (ctx->element, "Detaching context from thread %p", - g_thread_self ()); - if (!eglMakeCurrent (ctx->display, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT)) { - got_egl_error ("eglMakeCurrent"); - GST_ERROR_OBJECT (ctx->element, "Couldn't unbind context"); - return FALSE; - } - } - - return TRUE; -} - -gboolean -gst_egl_adaptation_create_surface (GstEglAdaptationContext * ctx) -{ - ctx->eglglesctx.surface = - eglCreateWindowSurface (ctx->display, - ctx->eglglesctx.config, ctx->used_window, NULL); - - if (ctx->eglglesctx.surface == EGL_NO_SURFACE) { - got_egl_error ("eglCreateWindowSurface"); - GST_ERROR_OBJECT (ctx->element, "Can't create surface"); - return FALSE; - } - return TRUE; -} - -void -gst_egl_adaptation_query_buffer_preserved (GstEglAdaptationContext * ctx) -{ - EGLint swap_behavior; - - ctx->buffer_preserved = FALSE; - if (eglQuerySurface (ctx->display, - ctx->eglglesctx.surface, EGL_SWAP_BEHAVIOR, &swap_behavior)) { - GST_DEBUG_OBJECT (ctx->element, "Buffer swap behavior %x", swap_behavior); - ctx->buffer_preserved = swap_behavior == EGL_BUFFER_PRESERVED; - } else { - GST_DEBUG_OBJECT (ctx->element, "Can't query buffer swap behavior"); - } -} - -void -gst_egl_adaptation_query_par (GstEglAdaptationContext * ctx) -{ - EGLint display_par; - - /* Save display's pixel aspect ratio - * - * DAR is reported as w/h * EGL_DISPLAY_SCALING wich is - * a constant with value 10000. This attribute is only - * supported if the EGL version is >= 1.2 - * XXX: Setup this as a property. - * or some other one time check. Right now it's being called once - * per frame. - */ - if (ctx->eglglesctx.egl_major == 1 && ctx->eglglesctx.egl_minor < 2) { - GST_DEBUG_OBJECT (ctx->element, "Can't query PAR. Using default: %dx%d", - EGL_DISPLAY_SCALING, EGL_DISPLAY_SCALING); - ctx->pixel_aspect_ratio = EGL_DISPLAY_SCALING; - } else { - eglQuerySurface (ctx->display, - ctx->eglglesctx.surface, EGL_PIXEL_ASPECT_RATIO, &display_par); - /* Fix for outbound DAR reporting on some implementations not - * honoring the 'should return w/h * EGL_DISPLAY_SCALING' spec - * requirement - */ - if (display_par == EGL_UNKNOWN || display_par < EGL_SANE_DAR_MIN || - display_par > EGL_SANE_DAR_MAX) { - GST_DEBUG_OBJECT (ctx->element, "Nonsensical PAR value returned: %d. " - "Bad EGL implementation? " - "Will use default: %d/%d", ctx->pixel_aspect_ratio, - EGL_DISPLAY_SCALING, EGL_DISPLAY_SCALING); - ctx->pixel_aspect_ratio = EGL_DISPLAY_SCALING; - } else { - ctx->pixel_aspect_ratio = display_par; - } - } -} - -/* XXX: Lock eglgles context? */ -/* TODO refactor only to get the w/h and let common code do the updates */ -gboolean -gst_egl_adaptation_context_update_surface_dimensions (GstEglAdaptationContext * - ctx) -{ - gint width, height; - - /* Save surface dims */ - eglQuerySurface (ctx->display, ctx->eglglesctx.surface, EGL_WIDTH, &width); - eglQuerySurface (ctx->display, ctx->eglglesctx.surface, EGL_HEIGHT, &height); - - if (width != ctx->surface_width || height != ctx->surface_height) { - ctx->surface_width = width; - ctx->surface_height = height; - GST_INFO_OBJECT (ctx->element, "Got surface of %dx%d pixels", width, - height); - return TRUE; - } - - return FALSE; -} - -/* Prints avilable EGL/GLES extensions - * If another rendering path is implemented this is the place - * where you want to check for the availability of its supporting - * EGL/GLES extensions. - */ -void -gst_egl_adaptation_context_init_egl_exts (GstEglAdaptationContext * ctx) -{ - const char *eglexts; - unsigned const char *glexts; - - eglexts = eglQueryString (ctx->display, EGL_EXTENSIONS); - glexts = glGetString (GL_EXTENSIONS); - - GST_DEBUG_OBJECT (ctx->element, "Available EGL extensions: %s\n", - GST_STR_NULL (eglexts)); - GST_DEBUG_OBJECT (ctx->element, "Available GLES extensions: %s\n", - GST_STR_NULL ((const char *) glexts)); - - return; -} - -void -gst_egl_adaptation_destroy_surface (GstEglAdaptationContext * ctx) -{ - if (ctx->eglglesctx.surface) { - eglDestroySurface (ctx->display, ctx->eglglesctx.surface); - ctx->eglglesctx.surface = NULL; - ctx->have_surface = FALSE; - } -} - -void -gst_egl_adaptation_destroy_context (GstEglAdaptationContext * ctx) -{ - if (ctx->eglglesctx.eglcontext) { - eglDestroyContext (ctx->display, ctx->eglglesctx.eglcontext); - ctx->eglglesctx.eglcontext = NULL; - } -} - -void -gst_egl_adaptation_context_bind_API (GstEglAdaptationContext * ctx) -{ - eglBindAPI (EGL_OPENGL_ES_API); -} - -gboolean -gst_egl_adaptation_context_swap_buffers (GstEglAdaptationContext * ctx) -{ - gboolean ret = eglSwapBuffers (ctx->display, ctx->eglglesctx.surface); - if (ret == EGL_FALSE) { - got_egl_error ("eglSwapBuffers"); - } - return ret; -} - -gboolean -gst_egl_adaptation_create_native_window (GstEglAdaptationContext * ctx, - gint width, gint height, gpointer * own_window_data) -{ - return platform_create_native_window (width, height, own_window_data); -} - -void -gst_egl_adaptation_destroy_native_window (GstEglAdaptationContext * ctx, - gpointer * own_window_data) -{ - platform_destroy_native_window (ctx->display, ctx->used_window, - own_window_data); - ctx->used_window = 0; -} diff --git a/ext/eglgles/gsteglglessink.c b/ext/eglgles/gsteglglessink.c index 3d34dbba1..22d1353a9 100644 --- a/ext/eglgles/gsteglglessink.c +++ b/ext/eglgles/gsteglglessink.c @@ -118,11 +118,6 @@ #include #include -#include -#include -#include -#include - #ifdef USE_EGL_RPI #include #endif @@ -132,7 +127,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_eglglessink_debug); #define GST_CAT_DEFAULT gst_eglglessink_debug - /* Input capabilities. */ static GstStaticPadTemplate gst_eglglessink_sink_template_factory = GST_STATIC_PAD_TEMPLATE ("sink", diff --git a/ext/eglgles/gsteglglessink.h b/ext/eglgles/gsteglglessink.h index 899d45336..9733f1e4b 100644 --- a/ext/eglgles/gsteglglessink.h +++ b/ext/eglgles/gsteglglessink.h @@ -50,11 +50,6 @@ #include #include -#include -#include -#include -#include - #include "gstegladaptation.h" G_BEGIN_DECLS @@ -80,7 +75,6 @@ typedef struct _GstEglGlesSinkClass GstEglGlesSinkClass; * @sinkcaps: Full set of suported caps * @current_caps: Current caps * @rendering_path: Rendering path (Slow/Fast) - * @eglglesctx: Pointer to the associated EGL/GLESv2 rendering context * @flow_lock: Simple concurrent access ward to the sink's runtime state * @have_window: Set if the sink has access to a window to hold it's canvas * @using_own_window: Set if the sink created its own window -- cgit v1.2.1