diff options
Diffstat (limited to 'ext/eglgles/video_platform_wrapper.c')
-rw-r--r-- | ext/eglgles/video_platform_wrapper.c | 173 |
1 files changed, 142 insertions, 31 deletions
diff --git a/ext/eglgles/video_platform_wrapper.c b/ext/eglgles/video_platform_wrapper.c index 9ec582c3..e44b7dbe 100644 --- a/ext/eglgles/video_platform_wrapper.c +++ b/ext/eglgles/video_platform_wrapper.c @@ -55,10 +55,6 @@ #include <gst/gst.h> #include "video_platform_wrapper.h" -#ifndef __BIONIC__ -#include <X11/Xlib.h> -#endif - GST_DEBUG_CATEGORY_STATIC (eglgles_platform_wrapper); #define GST_CAT_DEFAULT eglgles_platform_wrapper @@ -67,23 +63,30 @@ gboolean platform_wrapper_init (void) { GST_DEBUG_CATEGORY_INIT (eglgles_platform_wrapper, - "EglGles Platform Wrapper", 0, + "eglglessink-platform", 0, "Platform dependent native-window utility routines for EglGles"); return TRUE; } -#ifndef __BIONIC__ +#ifdef USE_EGL_X11 +#include <X11/Xlib.h> + +typedef struct +{ + Display *display; +} X11WindowData; + EGLNativeWindowType -platform_create_native_window (gint width, gint height) +platform_create_native_window (gint width, gint height, gpointer * window_data) { Display *d; Window w; - //XEvent e; int s; + X11WindowData *data; d = XOpenDisplay (NULL); if (d == NULL) { - GST_CAT_ERROR (GST_CAT_DEFAULT, "Can't open X11 display"); + GST_ERROR ("Can't open X11 display"); return (EGLNativeWindowType) 0; } @@ -93,49 +96,157 @@ platform_create_native_window (gint width, gint height) XStoreName (d, w, "eglglessink"); XMapWindow (d, w); XFlush (d); + + *window_data = data = g_slice_new0 (X11WindowData); + data->display = d; + return (EGLNativeWindowType) w; } gboolean platform_destroy_native_window (EGLNativeDisplayType display, - EGLNativeWindowType window) + EGLNativeWindowType window, gpointer * window_data) { + X11WindowData *data = *window_data; + /* XXX: Should proly catch BadWindow */ - XDestroyWindow (display, window); + XDestroyWindow (data->display, (Window) window); + XSync (data->display, FALSE); + XCloseDisplay (data->display); + + g_slice_free (X11WindowData, data); + *window_data = NULL; return TRUE; } +#endif + +#ifdef USE_EGL_MALI_FB +#include <EGL/fbdev_window.h> -/* XXX: Missing implementation */ -EGLint * -platform_crate_native_image_buffer (EGLNativeWindowType win, EGLConfig config, - EGLNativeDisplayType display, const EGLint * egl_attribs) +EGLNativeWindowType +platform_create_native_window (gint width, gint height, gpointer * window_data) { - return NULL; + fbdev_window *w = g_slice_new0 (fbdev_window); + + w->width = width; + w->height = height; + + return (EGLNativeWindowType) w; } -#else -/* Android does not support the creation of an egl window surface - * from native code. Hence, we just return NULL here for the time - * being. Function is left for reference as implementing it should - * help us suport other EGL platforms. - */ -EGLNativeWindowType -platform_create_native_window (gint width, gint height) +gboolean +platform_destroy_native_window (EGLNativeDisplayType display, + EGLNativeWindowType window, gpointer * window_data) { - /* XXX: There was one example on AOSP that was using something - * along the lines of window = android_createDisplaySurface(); - * but wasn't working properly. - */ + g_slice_free (fbdev_window, ((fbdev_window *) window)); - GST_CAT_ERROR (GST_CAT_DEFAULT, "Android: Can't create native window"); + return TRUE; +} +#endif + +#if !defined(USE_EGL_X11) && !defined(USE_EGL_MALI_FB) && !defined(USE_EGL_RPI) +/* Dummy functions for creating a native Window */ +EGLNativeWindowType +platform_create_native_window (gint width, gint height, gpointer * window_data) +{ + GST_ERROR ("Can't create native window"); return (EGLNativeWindowType) 0; } gboolean platform_destroy_native_window (EGLNativeDisplayType display, - EGLNativeWindowType window) + EGLNativeWindowType window, gpointer * window_data) +{ + GST_ERROR ("Can't destroy native window"); + return TRUE; +} +#endif + +#ifdef USE_EGL_RPI +#include <bcm_host.h> +#include <gst/video/gstvideosink.h> + +typedef struct +{ + EGL_DISPMANX_WINDOW_T w; + DISPMANX_DISPLAY_HANDLE_T d; +} 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; + GstVideoRectangle src, dst, res; + + 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); + + /* Center width*height frame inside dp_width*dp_height */ + src.w = width; + src.h = height; + src.x = src.y = 0; + dst.w = dp_width; + dst.h = dp_height; + dst.x = dst.y = 0; + gst_video_sink_center_rect (src, dst, &res, TRUE); + + dst_rect.x = res.x; + dst_rect.y = res.y; + dst_rect.width = res.w; + dst_rect.height = res.h; + + 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->d = dispman_display; + 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) { - GST_CAT_ERROR (GST_CAT_DEFAULT, "Android: Can't destroy native window"); + DISPMANX_DISPLAY_HANDLE_T dispman_display; + DISPMANX_UPDATE_HANDLE_T dispman_update; + RPIWindowData *data = *window_data; + + dispman_display = data->d; + dispman_update = vc_dispmanx_update_start (0); + vc_dispmanx_element_remove (dispman_update, data->w.element); + vc_dispmanx_update_submit_sync (dispman_update); + vc_dispmanx_display_close (dispman_display); + + g_slice_free (RPIWindowData, data); + *window_data = NULL; return TRUE; } |