summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Scheel <julian@jusst.de>2013-02-12 18:36:10 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2013-02-13 12:38:31 +0100
commitf337777eb50de860f5467b63a462eb9ed91fed2f (patch)
treeb7f6aa8d4596f84953bc22b3fb30b93914b32d0f
parentf25b0eda0928af67a7b4d0c98f7489b1fadf44f8 (diff)
eglglessink: Add bcm/Raspberry Pi support.
This adds a video platform backend for the dispmanx display manager used by broadcom and the Raspberry Pi. Signed-off-by: Julian Scheel <julian@jusst.de>
-rw-r--r--configure.ac14
-rw-r--r--ext/eglgles/gsteglglessink.c22
-rw-r--r--ext/eglgles/video_platform_wrapper.c108
3 files changed, 142 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index 5b64eab70..f62378176 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1635,7 +1635,7 @@ AG_GST_CHECK_FEATURE(RSVG, [rsvg decoder], rsvg, [
dnl *** eglgles ***
AC_ARG_WITH([egl-window-system],
- AS_HELP_STRING([--with-egl-window-system],[EGL window system to use (x11, mali-fb, none)]),
+ AS_HELP_STRING([--with-egl-window-system],[EGL window system to use (x11, mali-fb, rpi, none)]),
[EGL_WINDOW_SYSTEM="$withval"],
[EGL_WINDOW_SYSTEM="none"])
@@ -1711,6 +1711,18 @@ AG_GST_CHECK_FEATURE(EGLGLES, [eglgles sink], eglgles, [
CFLAGS=$old_CFLAGS
])
;;
+ rpi)
+ old_LIBS=$LIBS
+ old_CFLAGS=$CFLAGS
+
+ AC_CHECK_HEADER(bcm_host.h, [
+ HAVE_EGLGLES="yes"
+ EGLGLES_LIBS="-lGLESv2 -lEGL -lbcm_host"
+ AC_DEFINE(USE_EGL_RPI, [1], [Use RPi EGL window system])
+ LIBS=$old_LIBS
+ CFLAGS=$old_CFLAGS
+ ])
+ ;;
*)
AC_MSG_ERROR([invalid EGL window system specified])
;;
diff --git a/ext/eglgles/gsteglglessink.c b/ext/eglgles/gsteglglessink.c
index 4d0ae46d3..8622649a5 100644
--- a/ext/eglgles/gsteglglessink.c
+++ b/ext/eglgles/gsteglglessink.c
@@ -128,6 +128,11 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+#ifdef USE_EGL_RPI
+#include <bcm_host.h>
+#include <GLES/gl.h>
+#endif
+
#include "video_platform_wrapper.h"
#include "gsteglglessink.h"
@@ -1535,12 +1540,29 @@ static gboolean
gst_eglglessink_init_egl_display (GstEglGlesSink * eglglessink)
{
GST_DEBUG_OBJECT (eglglessink, "Enter EGL initial configuration");
+#ifdef USE_EGL_RPI
+ GST_DEBUG_OBJECT (eglglessink, "Initialize BCM host");
+ bcm_host_init ();
+#endif
+#ifndef USE_EGL_RPI
+ eglglessink->eglglesctx.display = eglGetDisplay (EGL_DEFAULT_DISPLAY);
+ if (eglglessink->eglglesctx.display == EGL_NO_DISPLAY) {
+ GST_ERROR_OBJECT (eglglessink, "Could not get EGL display connection");
+ goto HANDLE_ERROR; /* No EGL error is set by eglGetDisplay() */
+ }
+#else
+ if (!eglMakeCurrent (1, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
+ got_egl_error ("eglMakeCurrent");
+ GST_ERROR_OBJECT (eglglessink, "Couldn't unbind context");
+ return FALSE;
+ }
eglglessink->eglglesctx.display = eglGetDisplay (EGL_DEFAULT_DISPLAY);
if (eglglessink->eglglesctx.display == EGL_NO_DISPLAY) {
GST_ERROR_OBJECT (eglglessink, "Could not get EGL display connection");
goto HANDLE_ERROR; /* No EGL error is set by eglGetDisplay() */
}
+#endif
if (!eglInitialize (eglglessink->eglglesctx.display,
&eglglessink->eglglesctx.egl_major,
diff --git a/ext/eglgles/video_platform_wrapper.c b/ext/eglgles/video_platform_wrapper.c
index bc71a6921..1a95cf355 100644
--- a/ext/eglgles/video_platform_wrapper.c
+++ b/ext/eglgles/video_platform_wrapper.c
@@ -616,7 +616,7 @@ platform_free_eglimage (EGLDisplay display, EGLContext context, GLuint tex_id,
#endif
-#if !defined(USE_EGL_X11) && !defined(USE_EGL_MALI_FB)
+#if !defined(USE_EGL_X11) && !defined(USE_EGL_MALI_FB) && !defined(USE_EGL_RPI)
#include <gst/video/gstvideopool.h>
/* Dummy functions for creating a native Window */
@@ -665,3 +665,109 @@ platform_free_eglimage (EGLDisplay display, EGLContext context, GLuint tex_id,
g_assert_not_reached ();
}
#endif
+
+#ifdef USE_EGL_RPI
+#include <bcm_host.h>
+#include <gst/video/gstvideopool.h>
+
+typedef struct
+{
+ EGL_DISPMANX_WINDOW_T w;
+} RPIWindowData;
+
+EGLNativeWindowType
+platform_create_native_window (gint width, gint height, gpointer * window_data)
+{
+ DISPMANX_ELEMENT_HANDLE_T dispman_element;
+ DISPMANX_DISPLAY_HANDLE_T dispman_display;
+ DISPMANX_UPDATE_HANDLE_T dispman_update;
+ RPIWindowData *data;
+ VC_RECT_T dst_rect;
+ VC_RECT_T src_rect;
+
+ uint32_t dp_height;
+ uint32_t dp_width;
+
+ int ret;
+
+ ret = graphics_get_display_size (0, &dp_width, &dp_height);
+ if (ret < 0) {
+ GST_ERROR ("Can't open display");
+ return (EGLNativeWindowType) 0;
+ }
+ GST_DEBUG ("Got display size: %dx%d\n", dp_width, dp_height);
+ GST_DEBUG ("Source size: %dx%d\n", width, height);
+
+ dst_rect.x = 0;
+ dst_rect.y = 0;
+ dst_rect.width = dp_width;
+ dst_rect.height = dp_height;
+
+ src_rect.x = 0;
+ src_rect.y = 0;
+ src_rect.width = width << 16;
+ src_rect.height = height << 16;
+
+ dispman_display = vc_dispmanx_display_open (0);
+ dispman_update = vc_dispmanx_update_start (0);
+ dispman_element = vc_dispmanx_element_add (dispman_update,
+ dispman_display, 0, &dst_rect, 0, &src_rect,
+ DISPMANX_PROTECTION_NONE, 0, 0, 0);
+
+ *window_data = data = g_slice_new0 (RPIWindowData);
+ data->w.element = dispman_element;
+ data->w.width = width;
+ data->w.height = height;
+ vc_dispmanx_update_submit_sync (dispman_update);
+
+ return (EGLNativeWindowType) data;
+}
+
+gboolean
+platform_destroy_native_window (EGLNativeDisplayType display,
+ EGLNativeWindowType window, gpointer * window_data)
+{
+ DISPMANX_DISPLAY_HANDLE_T dispman_display;
+ DISPMANX_UPDATE_HANDLE_T dispman_update;
+ RPIWindowData *data = *window_data;
+
+ dispman_display = vc_dispmanx_display_open (0);
+ dispman_update = vc_dispmanx_update_start (0);
+ vc_dispmanx_element_remove (dispman_update, data->w.element);
+ vc_dispmanx_update_submit_sync (dispman_update);
+
+ g_slice_free (RPIWindowData, data);
+ *window_data = NULL;
+ return TRUE;
+}
+
+gboolean
+platform_can_map_eglimage (GstMemoryMapFunction * map,
+ GstMemoryUnmapFunction * unmap, PlatformMapVideo * video_map,
+ PlatformUnmapVideo * video_unmap)
+{
+ return FALSE;
+}
+
+gboolean
+platform_has_custom_eglimage_alloc (void)
+{
+ return FALSE;
+}
+
+gboolean
+platform_alloc_eglimage (EGLDisplay display, EGLContext context, GLint format,
+ GLint type, gint width, gint height, GLuint tex_id, EGLImageKHR * image,
+ gpointer * image_platform_data)
+{
+ g_assert_not_reached ();
+ return FALSE;
+}
+
+void
+platform_free_eglimage (EGLDisplay display, EGLContext context, GLuint tex_id,
+ EGLImageKHR * image, gpointer * image_platform_data)
+{
+ g_assert_not_reached ();
+}
+#endif