[MPlayer-dev-eng] [PATCH] add Opengl ES vo

kirin_e at users.sourceforge.net kirin_e at users.sourceforge.net
Wed Nov 23 13:02:41 CET 2011


Hi,

I needed OpenGL ES X11 output for a device i have so i ended up writing a gles vo, here it is in case it's useful to others. Patch against snapshot 2011-10-31, uses OpenGL ES 1.1 and currently needs support for npot textures. Any comments or improvements are welcome.

/kirin
-------------- next part --------------
diff -Naur --exclude '*.o' --exclude '*.d' --exclude ffmpeg --exclude codec-cfg --exclude codecs.conf.h --exclude 'config.*' --exclude GLES --exclude help_mp.h --exclude mplayer --exclude mencoder --exclude version.h --exclude mplayer.c org/mplayer-export-2011-10-31/configure mplayer-export-2011-10-31/configure
--- org/mplayer-export-2011-10-31/configure     2011-10-30 18:40:22.000000000 +0100
+++ mplayer-export-2011-10-31/configure 2011-11-23 03:33:30.000000000 +0100
@@ -470,6 +470,7 @@
   --enable-dhahelper       enable VIDIX dhahelper support
   --enable-svgalib_helper  enable VIDIX svgalib_helper support
   --enable-gl              enable OpenGL video output [autodetect]
+  --enable-gles            enable OpenGL ES X11 video output [disable]
   --disable-matrixview     disable OpenGL MatrixView video output [autodetect]
   --enable-dga2            enable DGA 2 support [autodetect]
   --enable-dga1            enable DGA 1 support [autodetect]
@@ -697,6 +698,7 @@
 _yuv4mpeg=yes
 _gif=auto
 _gl=auto
+_gles=no
 matrixview=auto
 _ggi=auto
 _ggiwmh=auto
@@ -1053,6 +1055,8 @@
   --disable-gif)        _gif=no         ;;
   --enable-gl)          _gl=yes         ;;
   --disable-gl)         _gl=no          ;;
+  --enable-gles)        _gles=yes       ;;
+  --disable-gles)       _gles=no        ;;
   --enable-matrixview)  matrixview=yes  ;;
   --disable-matrixview) matrixview=no   ;;
   --enable-ggi)         _ggi=yes        ;;
@@ -5040,6 +5044,18 @@
 echores "$_sdl"


+echocheck "OpenGL ES"
+if test "$_gles" = yes ; then
+  vomodules="gles $vomodules"
+  libs_mplayer="$libs_mplayer -lEGL -lGLESv1_CM"
+  def_gles='#define CONFIG_GLES 1'
+else
+  novomodules="gles $novomodules"
+  def_gles='#undef CONFIG_GLES'
+fi
+echores "$_gles"
+
+
 # make sure this stays below CoreVideo to avoid issues due to namespace
 # conflicts between -lGL and -framework OpenGL
 echocheck "OpenGL"
@@ -7896,6 +7912,7 @@
 GL_WIN32 = $_gl_win32
 GL_X11 = $_gl_x11
 GL_SDL = $_gl_sdl
+GLES = $_gles
 MATRIXVIEW = $matrixview
 GUI = $_gui
 GUI_GTK = $_gui_gtk
@@ -8441,6 +8458,7 @@
 $def_gl_win32
 $def_gl_x11
 $def_gl_sdl
+$def_gles
 $def_matrixview
 $def_ivtv
 $def_jpeg
diff -Naur --exclude '*.o' --exclude '*.d' --exclude ffmpeg --exclude codec-cfg --exclude codecs.conf.h --exclude 'config.*' --exclude GLES --exclude help_mp.h --exclude mplayer --exclude mencoder --exclude version.h --exclude mplayer.c org/mplayer-export-2011-10-31/DOCS/man/en/mplayer.1 mplayer-export-2011-10-31/DOCS/man/en/mplayer.1
--- org/mplayer-export-2011-10-31/DOCS/man/en/mplayer.1 2011-10-24 19:44:13.000000000 +0200
+++ mplayer-export-2011-10-31/DOCS/man/en/mplayer.1     2011-11-23 00:51:22.000000000 +0100
@@ -4355,6 +4355,10 @@
 .REss
 .
 .TP
+.B gles (X11 only)
+OpenGL ES output driver.
+.
+.TP
 .B matrixview
 OpenGL-based renderer creating a Matrix-like running-text effect.
 .PD 0
diff -Naur --exclude '*.o' --exclude '*.d' --exclude ffmpeg --exclude codec-cfg --exclude codecs.conf.h --exclude 'config.*' --exclude GLES --exclude help_mp.h --exclude mplayer --exclude mencoder --exclude version.h --exclude mplayer.c org/mplayer-export-2011-10-31/libvo/video_out.c mplayer-export-2011-10-31/libvo/video_out.c
--- org/mplayer-export-2011-10-31/libvo/video_out.c     2011-07-05 14:05:06.000000000 +0200
+++ mplayer-export-2011-10-31/libvo/video_out.c 2011-11-01 00:26:10.000000000 +0100
@@ -99,6 +99,7 @@
 extern const vo_functions_t video_out_gl_nosw;
 extern const vo_functions_t video_out_gl;
 extern const vo_functions_t video_out_gl2;
+extern const vo_functions_t video_out_gles;
 extern const vo_functions_t video_out_matrixview;
 extern const vo_functions_t video_out_dga;
 extern const vo_functions_t video_out_sdl;
@@ -208,6 +209,9 @@
         &video_out_gl,
         &video_out_gl2,
 #endif
+#ifdef CONFIG_GLES
+        &video_out_gles,
+#endif
 #ifdef CONFIG_DGA
         &video_out_dga,
 #endif
diff -Naur --exclude '*.o' --exclude '*.d' --exclude ffmpeg --exclude codec-cfg --exclude codecs.conf.h --exclude 'config.*' --exclude GLES --exclude help_mp.h --exclude mplayer --exclude mencoder --exclude version.h --exclude mplayer.c org/mplayer-export-2011-10-31/libvo/vo_gles.c mplayer-export-2011-10-31/libvo/vo_gles.c
--- org/mplayer-export-2011-10-31/libvo/vo_gles.c       1970-01-01 01:00:00.000000000 +0100
+++ mplayer-export-2011-10-31/libvo/vo_gles.c   2011-11-23 03:52:53.000000000 +0100
@@ -0,0 +1,480 @@
+/*
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * You can alternatively redistribute this file and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ */
+
+// TODO
+// - handle aspect
+// - check for extensions
+// - fallback if no support for NPOT textures
+// - GLES 2.0 (YUV conversion using shader)
+// MPlayer quirks
+// - OSD resize delay
+// - fixed-vo no resize event on nofs->fs->loop->nofs
+// - 640x480 default on fs->nofs
+// - drawing before check_events(resize)
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mp_core.h"
+#include "video_out.h"
+#include "video_out_internal.h"
+#include "x11_common.h"
+#include "sub/sub.h"
+
+#include <GLES/egl.h>
+#include <GLES/gl.h>
+#define GL_GLEXT_PROTOTYPES 1
+#include <GLES/glext.h>
+
+#ifndef GL_EXT_bgra // not defined in Khronos GLES/glext.h
+#define GL_EXT_bgra    1
+#define GL_BGR_EXT     0x80E0
+#define GL_BGRA_EXT    0x80E1
+#endif
+
+//uncomment to disable extensions
+//#undef GL_OES_draw_texture
+//#undef GL_EXT_bgra
+//#undef GL_EXT_texture_format_BGRA8888
+
+#define IS_ALIGNED(a, b)                ((((uintptr_t)(const void *)(a)) & ((b) - 1)) == 0)
+#define MAX_CONFIGS    10
+
+//#define FAST_OSD     1
+
+static const vo_info_t info = {
+  "OpenGL ES (X11)",
+  "gles",
+  "kirin_e at users.sourceforge.net",
+  ""
+};
+
+const LIBVO_EXTERN(gles)
+
+static int unshown = 0;
+static unsigned int src_width = 0, src_height = 0;
+static unsigned int win_width = 0, win_height = 0;
+static unsigned int src_pixel_bytes = 0;
+static GLenum tex_format = GL_RGBA;
+static GLuint texture[2] = { 0, 0 };
+
+#ifndef GL_OES_draw_texture
+static const GLshort texcoord_buffer[16] = { 0, 1, 0, 0, 1, 1, 1, 0,
+                                            0, 1, 0, 0, 1, 1, 1, 0 };
+static GLshort vertex_buffer[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
+                                    0, 0, 0, 0, 0, 0, 0, 0 };
+#endif
+
+static void draw(uint8_t *src[], int stride[], int w, int h, int x, int y)
+{
+       int src_align, align, w_bytes_aligned, i;
+
+       for (src_align = 8; !IS_ALIGNED(src[0], src_align); src_align >>= 1);
+       for (align = src_align; !IS_ALIGNED(stride[0], align); align >>= 1);
+
+       glPixelStorei(GL_UNPACK_ALIGNMENT, align);
+       glBindTexture(GL_TEXTURE_2D, texture[0]);
+
+       w_bytes_aligned = (w * src_pixel_bytes + align - 1) & ~(align - 1);
+       if (w_bytes_aligned == stride[0]) {
+               if (x != 0 || y != 0 || w != src_width || h != src_height) {
+                       glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, tex_format, GL_UNSIGNED_BYTE, src[0]);
+               } else {
+                       glTexImage2D(GL_TEXTURE_2D, 0, tex_format, w, h, 0, tex_format, GL_UNSIGNED_BYTE, src[0]);
+               }
+       } else {
+               for (i = 0;  i < h; i++) {
+                       glTexSubImage2D(GL_TEXTURE_2D, 0, x, y + i, w, 1, tex_format, GL_UNSIGNED_BYTE, src[0] + stride[0] * i);
+               }
+       }
+#ifndef GL_OES_draw_texture
+       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+#else
+       glDrawTexiOES(0, 0, 0, win_width, win_height);
+#endif
+       unshown = 1;
+}
+
+static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src,
+       unsigned char *srca, int stride)
+{
+       int src_align, align, w_bytes_aligned, i;
+#ifdef FAST_OSD
+       GLenum osd_tex_format = GL_LUMINANCE;
+       int osd_pixel_bytes = 1;
+#else
+       GLenum osd_tex_format = GL_LUMINANCE_ALPHA;
+       int osd_pixel_bytes = 2, j;
+       char src_la[h * stride * 2];
+
+       for (i = 0; i < h; i++) {
+               for (j = 0; j < w; j++) {
+                       src_la[i * stride * 2 + j * 2] = src[i * stride + j];
+                       src_la[i * stride * 2 + j * 2 + 1] = srca[i * stride + j] ? srca[i * stride + j] : 255;
+               }
+       }
+       src = src_la;
+       stride = stride * 2;
+#endif
+
+       //printf("\n at draw_alpha: %ix%i xoffset %i yoffset %i stride %i (%p %p)\n", w, h, x0, y0, stride, src, srca);
+       for (src_align = 8; !IS_ALIGNED(src, src_align); src_align >>= 1);
+       for (align = src_align; !IS_ALIGNED(stride, align); align >>= 1);
+
+       glPixelStorei(GL_UNPACK_ALIGNMENT, align);
+       glBindTexture(GL_TEXTURE_2D, texture[1]);
+#ifdef GL_OES_draw_texture
+       {
+               GLint crop_rect[4] = { 0, h, w, -h };
+
+               glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop_rect);
+       }
+#endif
+
+       w_bytes_aligned = (w * osd_pixel_bytes + align - 1) & ~(align - 1);
+       //printf("osd data alignment: %i, w_bytes_aligned: %i\n", align, w_bytes_aligned);
+       if (w_bytes_aligned == stride) {
+               glTexImage2D(GL_TEXTURE_2D, 0, osd_tex_format, w, h, 0, osd_tex_format, GL_UNSIGNED_BYTE, src);
+       } else {
+               glTexImage2D(GL_TEXTURE_2D, 0, osd_tex_format, w, h, 0, osd_tex_format, GL_UNSIGNED_BYTE, NULL);
+               for (i = 0; i < h; i ++) {
+                       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i, w, 1, osd_tex_format, GL_UNSIGNED_BYTE, src + stride * i);
+               }
+       }
+       glEnable(GL_BLEND);
+#ifndef GL_OES_draw_texture
+       {
+               int y0i = win_height - y0 - h;
+
+               vertex_buffer[8] = x0;
+               vertex_buffer[9] = y0i;
+               vertex_buffer[10] = x0;
+               vertex_buffer[11] = y0i + h;
+               vertex_buffer[12] = x0 + w;
+               vertex_buffer[13] = y0i;
+               vertex_buffer[14] = x0 + w;
+               vertex_buffer[15] = y0i + h;
+               glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
+       }
+#else
+       glDrawTexiOES(x0, win_height - y0 - h, 0, w, h);
+#endif
+       glDisable(GL_BLEND);
+}
+
+static void reshape(int width, int height)
+{
+#ifndef GL_OES_draw_texture
+       vertex_buffer[3] = height;
+       vertex_buffer[4] = width;
+       vertex_buffer[6] = width;
+       vertex_buffer[7] = height;
+#endif
+       glViewport(0, 0, (GLint) width, (GLint) height);
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       glOrthox(0 << 16, width << 16, 0 << 16, height << 16, -1 << 16, 1 << 16);
+       glMatrixMode(GL_MODELVIEW);
+}
+
+static void gl_init(void)
+{
+       mp_msg(MSGT_VO, MSGL_V, "GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
+       mp_msg(MSGT_VO, MSGL_V, "GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
+       mp_msg(MSGT_VO, MSGL_V, "GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
+       mp_msg(MSGT_VO, MSGL_V, "GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
+
+       reshape(win_width, win_height);
+       glGenTextures(2, texture);
+
+       glBindTexture(GL_TEXTURE_2D, texture[0]);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#ifdef GL_OES_draw_texture
+       {
+               GLint crop_rect[4] = { 0, src_height, src_width, -src_height };
+
+               glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop_rect);
+       }
+#endif
+       glTexImage2D(GL_TEXTURE_2D, 0, tex_format, src_width, src_height, 0, tex_format, GL_UNSIGNED_BYTE, NULL);
+
+       glBindTexture(GL_TEXTURE_2D, texture[1]);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+#ifndef GL_OES_draw_texture
+       glTexCoordPointer(2, GL_SHORT, 0, texcoord_buffer);
+       glVertexPointer(2, GL_SHORT, 0, vertex_buffer);
+       glEnableClientState(GL_VERTEX_ARRAY);
+       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+#endif
+       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+       glEnable(GL_TEXTURE_2D);
+       glBlendFunc(GL_ONE, GL_SRC_ALPHA);
+}
+
+// -----------------------------------------------
+
+static Display *dpy = NULL;
+static Window window = 0;
+static Colormap colormap = 0;
+
+static EGLDisplay egldpy;
+static EGLSurface eglwindow;
+static EGLContext eglctx;
+
+static void createEGLWindow(int width, int height, char *name, uint32_t flags)
+{
+       const EGLint attrib_list[] = { EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_NONE };
+       EGLConfig configs[MAX_CONFIGS];
+       EGLint num_configs;
+       EGLint visual_id = 0, attrib;
+
+       XVisualInfo *vinfo, vinfo_template;
+       int i, cfg, num_visuals;
+
+       dpy = mDisplay; // set by vo_init()
+
+       egldpy = eglGetDisplay(dpy);
+       if (egldpy == EGL_NO_DISPLAY) exit_player(EXIT_ERROR);
+       if (eglInitialize(egldpy, NULL, NULL) == EGL_FALSE) exit_player(EXIT_ERROR);
+       if (eglChooseConfig(egldpy, attrib_list, configs, MAX_CONFIGS, &num_configs) == EGL_FALSE) exit_player(EXIT_ERROR);
+       if (num_configs == 0) {
+               mp_msg(MSGT_VO, MSGL_ERR, "gles: no matching EGL frame buffer configurations found!\n");
+               exit_player(EXIT_ERROR);
+       }
+       for (cfg = 0; cfg < num_configs && visual_id == 0; cfg++) {
+               mp_msg(MSGT_VO, MSGL_V, "gles: configs[%i]: ", cfg);
+               eglGetConfigAttrib(egldpy, configs[cfg], EGL_NATIVE_VISUAL_ID, &visual_id);
+               mp_msg(MSGT_VO, MSGL_V, "VisualID: 0x%02x ", visual_id);
+               eglGetConfigAttrib(egldpy, configs[cfg], EGL_BUFFER_SIZE, &attrib);
+               mp_msg(MSGT_VO, MSGL_V, "bpp: %i ", attrib);
+               eglGetConfigAttrib(egldpy, configs[cfg], EGL_RED_SIZE, &attrib);
+               mp_msg(MSGT_VO, MSGL_V, "R: %i ", attrib);
+               eglGetConfigAttrib(egldpy, configs[cfg], EGL_GREEN_SIZE, &attrib);
+               mp_msg(MSGT_VO, MSGL_V, "G: %i ", attrib);
+               eglGetConfigAttrib(egldpy, configs[cfg], EGL_BLUE_SIZE, &attrib);
+               mp_msg(MSGT_VO, MSGL_V, "B: %i ", attrib);
+               eglGetConfigAttrib(egldpy, configs[cfg], EGL_ALPHA_SIZE, &attrib);
+               mp_msg(MSGT_VO, MSGL_V, "A: %i ", attrib);
+               eglGetConfigAttrib(egldpy, configs[cfg], EGL_DEPTH_SIZE, &attrib);
+               mp_msg(MSGT_VO, MSGL_V, "Z: %i ", attrib);
+               eglGetConfigAttrib(egldpy, configs[cfg], EGL_STENCIL_SIZE, &attrib);
+               mp_msg(MSGT_VO, MSGL_V, "S: %i\n", attrib);
+       }
+       if (visual_id == 0) {
+               mp_msg(MSGT_VO, MSGL_INFO, "gles: no useable VisualID found in configs, matching on depth instead!\n");
+               cfg = 0;
+               eglGetConfigAttrib(egldpy, configs[cfg], EGL_BUFFER_SIZE, &vinfo_template.depth);
+               vinfo = XGetVisualInfo(dpy, VisualDepthMask, &vinfo_template, &num_visuals);
+       } else {
+               vinfo_template.visualid = visual_id;
+               vinfo = XGetVisualInfo(dpy, VisualIDMask, &vinfo_template, &num_visuals);
+       }
+       if (vinfo == NULL || num_visuals == 0) exit_player(EXIT_ERROR);
+       for (i = 0; i < num_visuals; i++) {
+               mp_msg(MSGT_VO, MSGL_V, "gles: visuals[%i]: visual depth: %i\n", i, vinfo[i].depth);
+       }
+
+       colormap = XCreateColormap(dpy, RootWindow(dpy, vinfo->screen), vinfo->visual, AllocNone);
+
+       vo_x11_create_vo_window(vinfo, 0, 0, width, height, flags, colormap, "EGL", name);
+       window = vo_window; // set by vo_x11_create_vo_window()
+
+       XFree(vinfo);
+
+       eglctx = eglCreateContext(egldpy, configs[cfg], EGL_NO_CONTEXT, NULL);
+       if (eglctx == EGL_NO_CONTEXT) exit_player(EXIT_ERROR);
+       eglwindow = eglCreateWindowSurface(egldpy, configs[cfg], (NativeWindowType) window, NULL);
+       if (eglwindow == EGL_NO_SURFACE) exit_player(EXIT_ERROR);
+       if (eglMakeCurrent(egldpy, eglwindow, eglwindow, eglctx) == EGL_FALSE) exit_player(EXIT_ERROR);
+
+       win_width = width;
+       win_height = height;
+}
+
+static void destroyEGLWindow(void)
+{
+       eglMakeCurrent(egldpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+       eglDestroySurface(egldpy, eglwindow);
+       eglDestroyContext(egldpy, eglctx);
+       eglTerminate(egldpy);
+}
+
+static void postEGLWindow(void)
+{
+       eglSwapBuffers(egldpy, eglwindow);
+}
+
+// -----------------------------------------------
+
+static int query_format(uint32_t format)
+{
+       int flags = VFCAP_CSP_SUPPORTED | VFCAP_ACCEPT_STRIDE | VFCAP_OSD;
+       //uint32_t fourcc[2] = { format, 0 };
+
+       //printf("\n at query_format: 0x%08x (%s)\n", format, (char *) fourcc);
+       switch (format) {
+               case IMGFMT_RGB32:
+               case IMGFMT_RGB24:
+#if defined(GL_EXT_bgra) || defined(GL_EXT_texture_format_BGRA8888)
+               case IMGFMT_BGR32:
+#endif
+#if defined(GL_EXT_bgra)
+               case IMGFMT_BGR24:
+#endif
+                       return flags;
+       }
+
+       return 0;
+}
+
+// -----------------------------------------------
+
+static int draw_frame(uint8_t *src[])
+{
+       int stride[] = { src_width * src_pixel_bytes };
+
+       //printf("\n at draw_frame\n");
+       draw(src, stride, src_width, src_height, 0, 0);
+
+       return 0;
+}
+
+static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y)
+{
+       //printf("\n at draw_slice x: %i y: %i w: %i h: %i stride: %i src@%p\n", x, y, w, h, stride[0], src[0]);
+       draw(src, stride, w, h, x, y);
+
+       return 0;
+}
+
+static void draw_osd(void)
+{
+       vo_draw_text(win_width, win_height, draw_alpha);
+}
+
+static void check_events(void)
+{
+       int event = vo_x11_check_events(dpy);
+
+       if (event & VO_EVENT_RESIZE) {
+               XWindowAttributes window_attributes;
+
+               XGetWindowAttributes(dpy, window, &window_attributes);
+               mp_msg(MSGT_VO, MSGL_INFO, "gles: resize event! (%ix%i, vo: %ix%i)\n",
+                       window_attributes.width, window_attributes.height, vo_dwidth, vo_dheight);
+               if (unshown) mp_msg(MSGT_VO, MSGL_INFO, "gles: resizing with non-empty buffer!\n");
+               if (win_width != window_attributes.width || win_height != window_attributes.height) {
+                       win_width = window_attributes.width;
+                       win_height = window_attributes.height;
+                       reshape(win_width, win_height);
+               } else mp_msg(MSGT_VO, MSGL_INFO, "gles: hmm.. resize event without size change!\n");
+       }
+}
+
+static void flip_page(void)
+{
+       if (!unshown) mp_msg(MSGT_VO, MSGL_INFO, "gles: flipping empty buffer!\n");
+       postEGLWindow();
+       unshown = 0;
+}
+
+static int config(uint32_t width, uint32_t height, uint32_t d_width,
+               uint32_t d_height, uint32_t flags, char *title,
+               uint32_t format)
+{
+       switch (format) {
+               case IMGFMT_RGB32:
+                       tex_format = GL_RGBA;
+                       src_pixel_bytes = 4;
+                       break;
+               case IMGFMT_RGB24:
+                       tex_format = GL_RGB;
+                       src_pixel_bytes = 3;
+                       break;
+#if defined(GL_EXT_bgra) || defined(GL_EXT_texture_format_BGRA8888)
+               case IMGFMT_BGR32:
+                       tex_format = GL_BGRA_EXT;
+                       src_pixel_bytes = 4;
+                       break;
+#endif
+#if defined(GL_EXT_bgra)
+               case IMGFMT_BGR24:
+                       tex_format = GL_BGR_EXT;
+                       src_pixel_bytes = 3;
+                       break;
+#endif
+               default: /* unsupported */
+                       return 1;
+       };
+
+       src_width = width;
+       src_height = height;
+
+       if (!eglwindow) createEGLWindow(width, height, title, flags);
+       gl_init();
+
+       return 0;
+}
+
+static int preinit(const char *arg)
+{
+       if (!vo_init()) return VO_FALSE; // x11 init
+
+       return 0;
+}
+
+static void uninit(void)
+{
+       if (eglwindow) destroyEGLWindow();
+       vo_x11_uninit();
+       if (colormap) XFreeColormap(dpy, colormap);
+}
+
+static int control(uint32_t request, void *data)
+{
+       switch (request) {
+               case VOCTRL_QUERY_FORMAT:
+                       return query_format(*((uint32_t *) data));
+               case VOCTRL_ONTOP:
+                       vo_x11_ontop();
+                       return VO_TRUE;
+               case VOCTRL_BORDER:
+                       vo_x11_border();
+                       return VO_TRUE;
+               case VOCTRL_FULLSCREEN:
+                       vo_x11_fullscreen();
+                       return VO_TRUE;
+               case VOCTRL_UPDATE_SCREENINFO:
+                       update_xinerama_info();
+                       return VO_TRUE;
+       }
+
+       return VO_NOTIMPL;
+}
diff -Naur --exclude '*.o' --exclude '*.d' --exclude ffmpeg --exclude codec-cfg --exclude codecs.conf.h --exclude 'config.*' --exclude GLES --exclude help_mp.h --exclude mplayer --exclude mencoder --exclude version.h --exclude mplayer.c org/mplayer-export-2011-10-31/Makefile mplayer-export-2011-10-31/Makefile
--- org/mplayer-export-2011-10-31/Makefile      2011-10-27 14:16:01.000000000 +0200
+++ mplayer-export-2011-10-31/Makefile  2011-10-31 23:38:39.000000000 +0100
@@ -520,6 +520,7 @@
 SRCS_MPLAYER-$(GIF)          += libvo/vo_gif89a.c
 SRCS_MPLAYER-$(GL)           += libvo/gl_common.c libvo/vo_gl.c \
                                 libvo/vo_gl2.c libvo/csputils.c
+SRCS_MPLAYER-$(GLES)         += libvo/vo_gles.c
 SRCS_MPLAYER-$(GL_SDL)       += libvo/sdl_common.c
 SRCS_MPLAYER-$(GL_WIN32)     += libvo/w32_common.c
 SRCS_MPLAYER-$(GL_X11)       += libvo/x11_common.c


More information about the MPlayer-dev-eng mailing list