summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_out/Makefile.am10
-rw-r--r--src/video_out/video_out_opengl.c1762
2 files changed, 873 insertions, 899 deletions
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
index f5f0e6138..811d67856 100644
--- a/src/video_out/Makefile.am
+++ b/src/video_out/Makefile.am
@@ -43,7 +43,7 @@ endif
# $(sdl_module) $(opengl_module)
lib_LTLIBRARIES = $(xshm_module) $(xv_module) $(directfb_module) $(aa_module) \
- $(syncfb_module) $(fb_module)
+ $(syncfb_module) $(fb_module) $(opengl_module)
xineplug_vo_out_xv_la_SOURCES = deinterlace.c alphablend.c video_out_xv.c
xineplug_vo_out_xv_la_LIBADD = $(XV_LIB) $(X_LIBS) -lXext
@@ -54,10 +54,10 @@ xineplug_vo_out_xshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \
xineplug_vo_out_xshm_la_LIBADD = $(X_LIBS) -lXext
xineplug_vo_out_xshm_la_LDFLAGS = -avoid-version -module
-#xineplug_vo_out_opengl_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \
-# alphablend.c video_out_opengl.c
-#xineplug_vo_out_opengl_la_LIBADD = $(OPENGL_LIBS) $(GLUT_LIBS) $(GLU_LIBS) $(X_LIBS)
-#xineplug_vo_out_opengl_la_LDFLAGS = -avoid-version -module
+xineplug_vo_out_opengl_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \
+ alphablend.c video_out_opengl.c
+xineplug_vo_out_opengl_la_LIBADD = $(OPENGL_LIBS) $(GLUT_LIBS) $(GLU_LIBS) $(X_LIBS)
+xineplug_vo_out_opengl_la_LDFLAGS = -avoid-version -module
xineplug_vo_out_syncfb_la_SOURCES = alphablend.c video_out_syncfb.c
xineplug_vo_out_syncfb_la_LDFLAGS = -avoid-version -module
diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c
index 06645c206..903c4aa90 100644
--- a/src/video_out/video_out_opengl.c
+++ b/src/video_out/video_out_opengl.c
@@ -1,7 +1,7 @@
/*
- * Copyright (C) 2000, 2001 the xine project
+ * Copyright (C) 2000-2002 the xine project
*
- * This file is part of xine, a unix video player.
+ * This file is part of xine, a free video player.
*
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,42 +17,41 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_opengl.c,v 1.7 2002/03/07 13:26:16 jcdutton Exp $
+ * $Id: video_out_opengl.c,v 1.8 2002/03/26 19:43:42 mshopf Exp $
*
* video_out_glut.c, glut based OpenGL rendering interface for xine
* Matthias Hopf <mat@mshopf.de>
*
- * Based on video_out_xshm.c and video_out_xv.c
+ * Based on video_out_xshm.c (1.70) and video_out_xv.c (1.108)
*/
/*
* TODO:
*
- * - Race Condition? Sometimes the output window remains empty...
- * - Strange frame when stopping playback
- * - Works only with first video so far - the next video seems to be
- * rendered by a different thread, without notification :-(
- * - Textures instead of glDraw()
- * - Use GL_RGBA vs GL_BGRA (endianess?!?)
- * - Check extensions
+ * - BUG: xitk is creating images in the wrong visual type on e.g. SGI
+ * (due to driver visual selection?). this is a xitk issue.
+ * this creates a strange looking gui interface and all dialogs fail
+ * (X_PutImage: BadMatch).
+ * - Rendering method to be chosen on runtime
+ * - glut autoconf detection buggy
+ * - Check extensions (GL_BGRA)
* - Color conversion in hardware?
* - Video extension
- * - ColorMatrix (OpenGL-1.2 or SGI_color_matrix)
+ * - ColorMatrix (OpenGL-1.2 or SGI_color_matrix) ?possible? don't think so
* - Alpha Blending for overlays using texture hardware
- * - Check overlay colors (still YUV?!?)
*/
-#if 0
+#if 0 /* set to 1 for debugging messages */
# define DEBUGF(x) fprintf x
#else
# define DEBUGF(x) ((void) 0)
#endif
-/* Uncomment for some fun! */
-/*
-#define SPHERE
-*/
+
+#define USE_SPHERE 0 /* 1 for some fun! */ /* FIXME: untested */
+#define USE_TEXTURES 1 /* 1 Use texture hardware 0 glDrawPixels */
+
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -74,6 +73,7 @@
#ifdef HAVE_GLUT
#include <GL/glut.h>
#else
+#define USE_SPHERE 0 /* unable to do that w/o glut */
#ifdef HAVE_GLU
#include <GL/glu.h>
#endif
@@ -93,9 +93,9 @@
#define STRIPE_HEIGHT 16
-
#define BYTES_PER_PIXEL 4
+
# if (BYTES_PER_PIXEL != 4)
/* currently nothing else is supported */
# error "BYTES_PER_PIXEL bad"
@@ -111,110 +111,110 @@
# define YUV_SWAP_MODE 0
#endif
-typedef struct opengl_frame_s {
- vo_frame_t vo_frame;
- uint8_t *chunk[3];
-
- int width, height;
- int ratio_code;
- int format;
- int stripe_inc;
- uint8_t *rgb_dst;
- uint8_t *texture;
+typedef struct opengl_frame_s {
+ vo_frame_t vo_frame;
+
+ /* frame properties as delivered by the decoder: */
+ int width, height;
+ int ratio_code;
+ int format;
+ int flags;
+
+ /* opengl only data */
+ uint8_t *rgb_dst;
+ yuv2rgb_t *yuv2rgb;
+ uint8_t *chunk[3];
+ int stripe_inc;
+ uint8_t *texture;
} opengl_frame_t;
typedef struct opengl_driver_s {
- vo_driver_t vo_driver;
-
- config_values_t *config;
-
- opengl_frame_t *cur_frame;
- vo_overlay_t *overlay;
-
- /* X11 / Xv related stuff */
- Display *display;
- int screen;
- Drawable drawable;
-
- /* OpenGL related */
- volatile GLXContext context;
- volatile int context_state; /* is the context ok, or reload? */
- XVisualInfo *vinfo;
- pthread_t renderthread;
-/* int texwidth, texheight; */
-
- /* size / aspect ratio calculations */
- /* delivered from the decoder */
- int delivered_width;
- int delivered_height;
- int delivered_ratio_code;
- int delivered_flags;
- double ratio_factor; /* output frame must fulfill: height = width * ratio_factor */
-
- /* output area */
- int window_width;
- int window_height;
- int output_width;
- int output_height;
- int user_ratio;
+ vo_driver_t vo_driver;
+
+ config_values_t *config;
+
+ /* X11 / Xv related stuff */
+ Display *display;
+ int screen;
+ Drawable drawable;
+
+ /* Output data */
+ opengl_frame_t *cur_frame;
+ vo_overlay_t *overlay;
+
+ /* display anatomy */
+ double display_ratio;
+
+ /* OpenGL related */
+ GLXContext context;
+ volatile int context_state; /* is the context ok, or reload? */
+ XVisualInfo *vinfo;
+ pthread_t renderthread;
+
+ /* current texture size - this is not frame dependend! */
+ int texture_width, texture_height;
+
+ /* last frame delivered from the decoder */
+ int last_width;
+ int last_height;
+ int last_ratio_code;
+
+ /* ideal size */
+ int ideal_width, ideal_height;
+ int user_ratio;
+
+ /* gui size */
+ int gui_width, gui_height;
+ int gui_x, gui_y, gui_win_x, gui_win_y;
+
+ /* output size */
+ int output_width, output_height;
+ int output_xoffset, output_yoffset;
- /* last displayed frame */
- int last_frame_width; /* original size */
- int last_frame_height; /* original size */
- int last_frame_ratio_code;
-
- /* software yuv2rgb related */
- yuv2rgb_t *yuv2rgb;
- int prof_yuv2rgb;
- int yuv_width; /* width/height yuv2rgb is configured for */
- int yuv_stride;
-
- /* TODO: check */
- int zoom_mpeg1;
-
- /* display anatomy */
- double display_ratio; /* given by visual parameter from init function */
- void *user_data;
- /* Current frame texture data */
- char *texture_data;
- int texture_width, texture_height;
-
- /* gui callbacks */
-
- void (*request_dest_size) (void *user_data,
+ /* software yuv2rgb related */
+ int yuv2rgb_gamma;
+ uint8_t *yuv2rgb_cmap;
+ yuv2rgb_factory_t *yuv2rgb_factory;
+
+
+ void *user_data;
+
+ /* gui callbacks */
+
+ void (*frame_output_cb) (void *user_data,
int video_width, int video_height,
int *dest_x, int *dest_y,
- int *dest_height, int *dest_width);
+ int *dest_height, int *dest_width,
+ int *win_x, int *win_u);
- void (*calc_dest_size) (void *user_data,
+ void (*dest_size_cb) (void *user_data,
int video_width, int video_height,
int *dest_width, int *dest_height);
} opengl_driver_t;
-#define CONTEXT_BAD 0
-#define CONTEXT_SAME_DRAWABLE 1
-#define CONTEXT_SET 2
-#define CONTEXT_RELOAD 3
+
+enum { CONTEXT_BAD = 0, CONTEXT_SAME_DRAWABLE, CONTEXT_RELOAD, CONTEXT_SET };
/*
* first, some utility functions
*/
+
static void *my_malloc_aligned (size_t alignment, size_t size, uint8_t **chunk) {
- uint8_t *pMem;
+ uint8_t *pMem;
- pMem = xine_xmalloc (size+alignment);
+ pMem = xine_xmalloc (size+alignment);
- *chunk = pMem;
+ *chunk = pMem;
- while ((int) pMem % alignment)
- pMem++;
+ while ((int) pMem % alignment)
+ pMem++;
- return pMem;
+ return pMem;
}
@@ -222,932 +222,906 @@ static void *my_malloc_aligned (size_t alignment, size_t size, uint8_t **chunk)
* and now, the driver functions
*/
+
static uint32_t opengl_get_capabilities (vo_driver_t *this_gen) {
- return VO_CAP_COPIES_IMAGE | VO_CAP_YV12 | VO_CAP_YUY2;
+ return VO_CAP_COPIES_IMAGE | VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS;
}
static void opengl_frame_copy (vo_frame_t *vo_img, uint8_t **src) {
- opengl_frame_t *frame = (opengl_frame_t *) vo_img ;
- opengl_driver_t *this = (opengl_driver_t *) vo_img->driver;
+ opengl_frame_t *frame = (opengl_frame_t *) vo_img ;
-/*fprintf (stderr, "*** frame_copy\n"); */
- xine_profiler_start_count (this->prof_yuv2rgb);
+/* DEBUGF ((stderr, "*** %p: frame_copy src %p/%p/%p to %p\n", frame, src[0], src[1], src[2], frame->rgb_dst)); */
- if (frame->format == IMGFMT_YV12) {
- this->yuv2rgb->yuv2rgb_fun (this->yuv2rgb, frame->rgb_dst,
- src[0], src[1], src[2]);
- } else {
+ if (frame->format == IMGFMT_YV12) {
+ frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst,
+ src[0], src[1], src[2]);
+ } else {
- this->yuv2rgb->yuy22rgb_fun (this->yuv2rgb, frame->rgb_dst,
- src[0]);
+ frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst,
+ src[0]);
- }
-
- xine_profiler_stop_count (this->prof_yuv2rgb);
+ }
- frame->rgb_dst += frame->stripe_inc;
+ frame->rgb_dst += frame->stripe_inc;
+/* DEBUGF ((stderr, "frame_copy done\n")); */
}
static void opengl_frame_field (vo_frame_t *vo_img, int which_field) {
- opengl_frame_t *frame = (opengl_frame_t *) vo_img ;
-
-/*fprintf (stderr, "*** frame_field\n"); */
- switch (which_field) {
- case VO_TOP_FIELD:
- frame->rgb_dst = frame->texture;
- frame->stripe_inc = 2*STRIPE_HEIGHT * frame->width * BYTES_PER_PIXEL;
- break;
- case VO_BOTTOM_FIELD:
- frame->rgb_dst = frame->texture + frame->width * BYTES_PER_PIXEL ;
- frame->stripe_inc = 2*STRIPE_HEIGHT * frame->width * BYTES_PER_PIXEL;
- break;
- case VO_BOTH_FIELDS:
- frame->rgb_dst = frame->texture;
- frame->stripe_inc = STRIPE_HEIGHT * frame->width * BYTES_PER_PIXEL;
- break;
- }
+ opengl_frame_t *frame = (opengl_frame_t *) vo_img ;
+
+ switch (which_field & VO_BOTH_FIELDS) {
+ case VO_TOP_FIELD:
+ frame->rgb_dst = frame->texture;
+ frame->stripe_inc = 2*STRIPE_HEIGHT * frame->width * BYTES_PER_PIXEL;
+ break;
+ case VO_BOTTOM_FIELD:
+ frame->rgb_dst = frame->texture + frame->width * BYTES_PER_PIXEL ;
+ frame->stripe_inc = 2*STRIPE_HEIGHT * frame->width * BYTES_PER_PIXEL;
+ break;
+ case VO_BOTH_FIELDS:
+ frame->rgb_dst = frame->texture;
+ frame->stripe_inc = STRIPE_HEIGHT * frame->width * BYTES_PER_PIXEL;
+ break;
+ }
+/* DEBUGF ((stderr, "*** %p: frame_field: rgb_dst %p\n", frame, frame->rgb_dst)); */
}
+
static void opengl_frame_dispose (vo_frame_t *vo_img) {
- opengl_frame_t *frame = (opengl_frame_t *) vo_img ;
-
-/*fprintf (stderr, "*** frame_dispose ***\n"); */
- if (frame)
- {
- free (frame->texture);
- free (frame->chunk[0]);
- free (frame->chunk[1]);
- free (frame->chunk[2]);
- }
- free (frame);
+ opengl_frame_t *frame = (opengl_frame_t *) vo_img ;
+ opengl_driver_t *this = (opengl_driver_t *) vo_img->driver;
+
+ DEBUGF ((stderr, "*** frame_dispose ***\n"));
+ if (frame)
+ {
+ XLockDisplay (this->display);
+ free (frame->texture);
+ free (frame->chunk[0]);
+ free (frame->chunk[1]);
+ free (frame->chunk[2]);
+ frame->texture = NULL;
+ frame->chunk[0] = frame->chunk[1] = frame->chunk[2] = NULL;
+ XUnlockDisplay (this->display);
+ }
+ free (frame);
}
static vo_frame_t *opengl_alloc_frame (vo_driver_t *this_gen) {
- opengl_frame_t *frame ;
-/*fprintf (stderr, "*** alloc_frame ***\n"); */
- frame = (opengl_frame_t *) calloc (1, sizeof (opengl_frame_t));
- if (frame==NULL) {
- printf ("opengl_alloc_frame: out of memory\n");
- return NULL;
- }
+ opengl_frame_t *frame ;
+ opengl_driver_t *this = (opengl_driver_t *) this_gen;
- pthread_mutex_init (&frame->vo_frame.mutex, NULL);
+ DEBUGF ((stderr, "*** alloc_frame ***\n"));
+ frame = (opengl_frame_t *) calloc (1, sizeof (opengl_frame_t));
+ if (frame==NULL) {
+ printf ("opengl_alloc_frame: out of memory\n");
+ return NULL;
+ }
- /*
- * supply required functions/fields
- */
-
- frame->vo_frame.copy = opengl_frame_copy;
- frame->vo_frame.field = opengl_frame_field;
- frame->vo_frame.dispose = opengl_frame_dispose;
- frame->vo_frame.driver = this_gen;
-
- return (vo_frame_t *) frame;
-}
+ pthread_mutex_init (&frame->vo_frame.mutex, NULL);
+ /*
+ * supply required functions/fields
+ */
+ frame->vo_frame.copy = opengl_frame_copy;
+ frame->vo_frame.field = opengl_frame_field;
+ frame->vo_frame.dispose = opengl_frame_dispose;
+ frame->vo_frame.driver = this_gen;
+
+ /*
+ * colorspace converter for this frame
+ */
+ frame->yuv2rgb = this->yuv2rgb_factory->create_converter (this->yuv2rgb_factory);
-static void opengl_adapt_to_output_area (opengl_driver_t *this,
- int dest_width, int dest_height)
-{
- this->window_width = dest_width;
- this->window_height = dest_height;
-
- /*
- * make the frames fit into the given destination area
- */
- if ( ((double) dest_width / this->ratio_factor) < dest_height ) {
- this->output_width = dest_width ;
- this->output_height = (double) dest_width / this->ratio_factor + .5;
- } else {
- this->output_width = (double) dest_height * this->ratio_factor + .5;
- this->output_height = dest_height;
- }
-
- /* Force reload / state reinitialization / clear */
- if (this->context_state == CONTEXT_SET)
- this->context_state = CONTEXT_RELOAD;
-}
-
-
-static void opengl_calc_format (opengl_driver_t *this,
- int width, int height, int ratio_code) {
- double image_ratio, desired_ratio;
- double corr_factor;
- int ideal_width, ideal_height;
- int dest_x, dest_y, dest_width, dest_height;
-
- this->delivered_width = width;
- this->delivered_height = height;
- this->delivered_ratio_code = ratio_code;
-
- if ( (!width) || (!height) )
- return;
-
- /*
- * aspect ratio calculation
- */
- image_ratio =
- (double) this->delivered_width / (double) this->delivered_height;
-
- switch (this->user_ratio) {
- case ASPECT_AUTO:
- switch (ratio_code) {
- case XINE_ASPECT_RATIO_ANAMORPHIC: /* anamorphic */
- desired_ratio = 16.0 /9.0;
- break;
- case XINE_ASPECT_RATIO_211_1: /* 2.11:1 */
- desired_ratio = 2.11/1.0;
- break;
- case XINE_ASPECT_RATIO_SQUARE: /* square pels */
- case XINE_ASPECT_RATIO_DONT_TOUCH: /* probably non-mpeg stream => don't tou
-ch aspect ratio */
- desired_ratio = image_ratio;
- break;
- case 0: /* forbidden -> 4:3 */
- printf ("video_out_opengl: invalid ratio, using 4:3\n");
- default:
- printf ("video_out_opengl: unknown aspect ratio (%d) in stream => using
-4:3\n",
- this->delivered_ratio_code);
- case XINE_ASPECT_RATIO_4_3: /* 4:3 */
- desired_ratio = 4.0 / 3.0;
- break;
- }
- break;
- case ASPECT_ANAMORPHIC:
- desired_ratio = 16.0 / 9.0;
- break;
- case ASPECT_DVB:
- desired_ratio = 2.0 / 1.0;
- break;
- case ASPECT_SQUARE:
- desired_ratio = image_ratio;
- break;
- case ASPECT_FULL:
- default:
- desired_ratio = 4.0 / 3.0;
- }
-
- this->ratio_factor = this->display_ratio * desired_ratio;
-
- /*
- * calc ideal output frame size
- */
-
- corr_factor = this->ratio_factor / image_ratio ;
-
- if (fabs(corr_factor - 1.0) < 0.005) {
- ideal_width = this->delivered_width;
- ideal_height = this->delivered_height;
- }
- else if (corr_factor >= 1.0) {
- ideal_width = this->delivered_width * corr_factor + 0.5;
- ideal_height = this->delivered_height;
- }
- else {
- ideal_width = this->delivered_width;
- ideal_height = this->delivered_height / corr_factor + 0.5;
- }
-
- /* little hack to zoom mpeg1 / other small streams by default*/
- if (this->zoom_mpeg1 && (this->delivered_width<400)) {
- ideal_width *= 2;
- ideal_height *= 2;
- }
-
- /* yuv2rgb_mmx prefers "width%8 == 0" */
- /* but don't change if it would introduce scaling */
- if( ideal_width != this->delivered_width ||
- ideal_height != this->delivered_height )
- ideal_width &= ~7;
-
- /*
- * ask gui to adapt to this size
- */
- this->request_dest_size (this->user_data,
- ideal_width, ideal_height,
- &dest_x, &dest_y, &dest_width, &dest_height);
- DEBUGF ((stderr, "*** request_dest_size %dx%d -> %dx%d\n",
- ideal_width, ideal_height, dest_width, dest_height));
-
- opengl_adapt_to_output_area (this, dest_width, dest_height);
+ return (vo_frame_t *) frame;
}
static void opengl_update_frame_format (vo_driver_t *this_gen,
- vo_frame_t *frame_gen,
- uint32_t width, uint32_t height,
- int ratio_code, int format, int flags) {
+ vo_frame_t *frame_gen,
+ uint32_t width, uint32_t height,
+ int ratio_code, int format, int flags) {
- opengl_driver_t *this = (opengl_driver_t *) this_gen;
- opengl_frame_t *frame = (opengl_frame_t *) frame_gen;
- int setup_yuv = 0;
+ opengl_driver_t *this = (opengl_driver_t *) this_gen;
+ opengl_frame_t *frame = (opengl_frame_t *) frame_gen;
-/*fprintf (stderr, "*** update_frame_format ***\n"); */
- flags &= VO_BOTH_FIELDS;
+/* DEBUGF ((stderr, "*** %p: update_frame_format ***\n", frame)); */
+ flags &= VO_BOTH_FIELDS;
- if ((width != this->delivered_width)
- || (height != this->delivered_height)
- || (ratio_code != this->delivered_ratio_code)
- || (flags != this->delivered_flags)) {
+ if ((frame->width != width)
+ || (frame->height != height)
+ || (frame->format != format)
+ || (frame->flags != flags)) {
- this->delivered_width = width;
- this->delivered_height = height;
- this->delivered_ratio_code = ratio_code;
- this->delivered_flags = flags;
- setup_yuv = 1;
- }
+ int image_size = width * height;
+
+ DEBUGF ((stderr, "video_out_opengl: updating frame to %dx%d (ratio=%d, format=%c%c%c%c)\n",
+ width, height, ratio_code, format&0xff, (format>>8)&0xff,
+ (format>>16)&0xff, (format>>24)&0xff));
- if ((frame->width != width) || (frame->height != height)
- || (frame->format != format)) {
+ /* update frame allocated data */
- int image_size;
+ XLockDisplay (this->display);
- DEBUGF ((stderr, "*** updating frame to %d x %d\n", width, height));
+ free (frame->texture);
+ free (frame->chunk[0]);
+ free (frame->chunk[1]);
+ free (frame->chunk[2]);
+ frame->chunk[0] = frame->chunk[1] = frame->chunk[2] = NULL;
+
+ frame->texture = calloc (1, BYTES_PER_PIXEL * image_size);
+ assert (frame->texture);
+
+ switch (format) {
+ case IMGFMT_YV12:
+ frame->vo_frame.base[0] = my_malloc_aligned(16,image_size,
+ &frame->chunk[0]);
+ frame->vo_frame.base[1] = my_malloc_aligned(16,image_size/4,
+ &frame->chunk[1]);
+ frame->vo_frame.base[2] = my_malloc_aligned(16,image_size/4,
+ &frame->chunk[2]);
+ break;
+ case IMGFMT_YUY2:
+ frame->vo_frame.base[0] = my_malloc_aligned(16,image_size*2,
+ &frame->chunk[0]);
+ break;
+ default:
+ fprintf (stderr, "video_out_opengl: image format %d not supported, update video driver!\n", format);
+ return;
+ }
+
+ switch (flags) {
+ case VO_TOP_FIELD:
+ case VO_BOTTOM_FIELD:
+ frame->yuv2rgb->configure (frame->yuv2rgb,
+ width, 16, width*2, width, width,
+ STRIPE_HEIGHT,
+ width * BYTES_PER_PIXEL * 2);
+ break;
+ case VO_BOTH_FIELDS:
+ frame->yuv2rgb->configure (frame->yuv2rgb,
+ width, 16, width, width/2, width,
+ STRIPE_HEIGHT,
+ width * BYTES_PER_PIXEL);
+ break;
+ }
+
+ frame->width = width;
+ frame->height = height;
+ frame->format = format;
+ frame->flags = flags;
+
+ XUnlockDisplay (this->display);
+ }
- XLockDisplay (this->display);
+ frame->ratio_code = ratio_code;
+ opengl_frame_field ((vo_frame_t *)frame, flags);
+}
- free (frame->texture);
- free (frame->chunk[0]);
- free (frame->chunk[1]);
- free (frame->chunk[2]);
- frame->texture = calloc (1, BYTES_PER_PIXEL * width * height);
- assert (frame->texture);
+static void opengl_compute_ideal_size (opengl_driver_t *this,
+ int width, int height, int ratio_code) {
+ double image_ratio, desired_ratio;
+ double corr_factor;
+/* DEBUGF ((stderr, "*** compute_ideal_size\n")); */
+ /*
+ * aspect ratio calculation
+ */
+ image_ratio = (double) width / (double) height;
+
+ switch (this->user_ratio) {
+ case ASPECT_AUTO:
+ switch (ratio_code) {
+ case XINE_ASPECT_RATIO_ANAMORPHIC: /* anamorphic */
+ desired_ratio = 16.0 /9.0;
+ break;
+ case XINE_ASPECT_RATIO_211_1: /* 2.11:1 */
+ desired_ratio = 2.11/1.0;
+ break;
+ case XINE_ASPECT_RATIO_SQUARE: /* square pels */
+ case XINE_ASPECT_RATIO_DONT_TOUCH: /* probably non-mpeg stream => don't touch aspect ratio */
+ desired_ratio = image_ratio;
+ break;
+ case 0: /* forbidden -> 4:3 */
+ printf ("video_out_opengl: invalid ratio, using 4:3\n");
+ default:
+ printf ("video_out_opengl: unknown aspect ratio (%d) in stream => using
+4:3\n",
+ ratio_code);
+ case XINE_ASPECT_RATIO_4_3: /* 4:3 */
+ desired_ratio = 4.0 / 3.0;
+ break;
+ }
+ break;
+ case ASPECT_ANAMORPHIC:
+ desired_ratio = 16.0 / 9.0;
+ break;
+ case ASPECT_DVB:
+ desired_ratio = 2.0 / 1.0;
+ break;
+ case ASPECT_SQUARE:
+ desired_ratio = image_ratio;
+ break;
+ case ASPECT_FULL:
+ default:
+ desired_ratio = 4.0 / 3.0;
+ }
+
+ corr_factor = desired_ratio * this->display_ratio / image_ratio;
- if (format == IMGFMT_YV12) {
- image_size = width * height;
- frame->vo_frame.base[0] = my_malloc_aligned(16,image_size, &frame->chunk[0]);
- frame->vo_frame.base[1] = my_malloc_aligned(16,image_size/4, &frame->chunk[1]);
- frame->vo_frame.base[2] = my_malloc_aligned(16,image_size/4, &frame->chunk[2]);
+ if (fabs (corr_factor - 1.0) < 0.005) {
+ this->ideal_width = width;
+ this->ideal_height = height;
} else {
- image_size = width * height;
- frame->vo_frame.base[0] = my_malloc_aligned(16,image_size*2, &frame->chunk[0]);
+ if (corr_factor >= 1.0) {
+ this->ideal_width = width * corr_factor + 0.5;
+ this->ideal_height = height;
+ } else {
+ this->ideal_width = width;
+ this->ideal_height = height / corr_factor + 0.5;
+ }
}
-
- frame->format = format;
- frame->width = width;
- frame->height = height;
- XUnlockDisplay (this->display);
- }
- frame->ratio_code = ratio_code;
+ DEBUGF ((stderr, "*** opengl_compute_ideal_size %dx%d -> %dx%d\n",
+ width, height,
+ this->ideal_width, this->ideal_height));
+}
- opengl_frame_field ((vo_frame_t *)frame, flags);
- if (flags == VO_BOTH_FIELDS) {
- if (this->yuv_stride != frame->width * BYTES_PER_PIXEL)
- setup_yuv = 1;
- } else { /* VO_TOP_FIELD, VO_BOTTOM_FIELD */
- if (this->yuv_stride != (frame->width * BYTES_PER_PIXEL * 2))
- setup_yuv = 1;
- }
+static void opengl_compute_output_size (opengl_driver_t *this) {
- if (setup_yuv || (this->yuv_width != width)) {
- switch (flags) {
- case VO_TOP_FIELD:
- case VO_BOTTOM_FIELD:
- yuv2rgb_setup (this->yuv2rgb,
- this->delivered_width,
- 16,
- this->delivered_width*2,
- this->delivered_width,
- width,
- STRIPE_HEIGHT,
- width * BYTES_PER_PIXEL * 2);
- this->yuv_stride = frame->width * BYTES_PER_PIXEL * 2;
- break;
- case VO_BOTH_FIELDS:
- yuv2rgb_setup (this->yuv2rgb,
- this->delivered_width,
- 16,
- this->delivered_width,
- this->delivered_width/2,
- width,
- STRIPE_HEIGHT,
- width * BYTES_PER_PIXEL);
- this->yuv_stride = frame->width * BYTES_PER_PIXEL;
- break;
+ double x_factor, y_factor;
+ int old_width = this->output_width, old_height = this->output_height;
+ int old_x = this->output_xoffset, old_y = this->output_yoffset;
+
+ DEBUGF ((stderr, "*** compute_output_size for gui %dx%d ideal %dx%d\n",
+ this->gui_width, this->gui_height,
+ this->ideal_width, this->ideal_height));
+ /*
+ * make the frame fit into the given destination area
+ */
+
+ x_factor = (double) this->gui_width / (double) this->ideal_width;
+ y_factor = (double) this->gui_height / (double) this->ideal_height;
+
+ if ( x_factor < y_factor ) {
+ this->output_width = (double) this->ideal_width * x_factor ;
+ this->output_height = (double) this->ideal_height * x_factor ;
+ } else {
+ this->output_width = (double) this->ideal_width * y_factor ;
+ this->output_height = (double) this->ideal_height * y_factor ;
}
- this->yuv_width = width;
- }
+ this->output_xoffset = (this->gui_width - this->output_width) / 2 + this->gui_x;
+ this->output_yoffset = (this->gui_height - this->output_height) / 2 - this->gui_y;
+
+ DEBUGF ((stderr,
+ "video_out_opengl: screen output %d x %d offset %d/%d\n",
+ this->output_width, this->output_height,
+ this->output_xoffset, this->output_yoffset
+ ));
+
+ /* Force state reinitialization / clear */
+ if ( (old_width != this->ideal_width || old_height != this->ideal_height
+ || old_x != this->output_xoffset || old_y != this->output_yoffset)
+ && this->context_state == CONTEXT_SET)
+ this->context_state = CONTEXT_RELOAD;
}
-static void opengl_overlay_clut_yuv2rgb(opengl_driver_t *this, vo_overlay_t *overlay)
-{
- int i;
- clut_t* clut = (clut_t*) overlay->color;
- if (!overlay->rgb_clut) {
- for (i = 0; i < sizeof(overlay->color)/sizeof(overlay->color[0]); i++) {
- *((uint32_t *)&clut[i]) =
- this->yuv2rgb->yuv2rgb_single_pixel_fun(this->yuv2rgb,
- clut[i].y, clut[i].cb, clut[i].cr);
+
+static void opengl_overlay_clut_yuv2rgb (opengl_driver_t *this,
+ vo_overlay_t *overlay,
+ opengl_frame_t *frame) {
+ int i;
+ clut_t* clut = (clut_t*) overlay->color;
+ if (!overlay->rgb_clut) {
+ for (i = 0; i < sizeof(overlay->color)/sizeof(overlay->color[0]); i++) {
+ *((uint32_t *)&clut[i]) =
+ frame->yuv2rgb->yuv2rgb_single_pixel_fun(frame->yuv2rgb,
+ clut[i].y, clut[i].cb, clut[i].cr);
+ }
+ overlay->rgb_clut++;
}
- overlay->rgb_clut++;
- }
- if (!overlay->clip_rgb_clut) {
- clut = (clut_t*) overlay->clip_color;
- for (i = 0; i < sizeof(overlay->color)/sizeof(overlay->color[0]); i++) {
- *((uint32_t *)&clut[i]) =
- this->yuv2rgb->yuv2rgb_single_pixel_fun(this->yuv2rgb,
- clut[i].y, clut[i].cb, clut[i].cr);
+ if (!overlay->clip_rgb_clut) {
+ clut = (clut_t*) overlay->clip_color;
+ for (i = 0; i < sizeof(overlay->color)/sizeof(overlay->color[0]); i++) {
+ *((uint32_t *)&clut[i]) =
+ frame->yuv2rgb->yuv2rgb_single_pixel_fun(frame->yuv2rgb,
+ clut[i].y, clut[i].cb, clut[i].cr);
+ }
+ overlay->clip_rgb_clut++;
}
- overlay->clip_rgb_clut++;
- }
}
-static void opengl_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) {
- opengl_driver_t *this = (opengl_driver_t *) this_gen;
- opengl_frame_t *frame = (opengl_frame_t *) frame_gen;
-
- /* Alpha Blend here */
- if (overlay->rle) {
- if( !overlay->rgb_clut || !overlay->clip_rgb_clut)
- opengl_overlay_clut_yuv2rgb(this,overlay);
-
- assert (this->delivered_width == frame->width);
- assert (this->delivered_height == frame->height);
-# if BYTES_PER_PIXEL == 3
- blend_rgb24 ((uint8_t *)frame->texture, overlay,
- frame->width, frame->height,
- this->delivered_width, this->delivered_height);
-# elif BYTES_PER_PIXEL == 4
- blend_rgb32 ((uint8_t *)frame->texture, overlay,
- frame->width, frame->height,
- this->delivered_width, this->delivered_height);
-# else
-# error "bad BYTES_PER_PIXEL"
-# endif
- }
+
+static void opengl_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen,
+ vo_overlay_t *overlay) {
+ opengl_driver_t *this = (opengl_driver_t *) this_gen;
+ opengl_frame_t *frame = (opengl_frame_t *) frame_gen;
+
+ DEBUGF ((stderr, "*** overlay_blend\n"));
+ /* Alpha Blend here */
+ if (overlay->rle) {
+ if( !overlay->rgb_clut || !overlay->clip_rgb_clut)
+ opengl_overlay_clut_yuv2rgb (this,overlay, frame);
+
+# if BYTES_PER_PIXEL == 3
+ blend_rgb24 ((uint8_t *)frame->texture, overlay,
+ frame->width, frame->height,
+ frame->width, frame->height);
+# elif BYTES_PER_PIXEL == 4
+ blend_rgb32 ((uint8_t *)frame->texture, overlay,
+ frame->width, frame->height,
+ frame->width, frame->height);
+# else
+# error "bad BYTES_PER_PIXEL"
+# endif
+ }
+}
+
+
+static int opengl_redraw_needed (vo_driver_t *this_gen) {
+ opengl_driver_t *this = (opengl_driver_t *) this_gen;
+ int gui_x, gui_y, gui_width, gui_height, gui_win_x, gui_win_y;
+
+ DEBUGF ((stderr, "*** redraw_needed %dx%d\n", this->ideal_width, this->ideal_height));
+ this->frame_output_cb (this->user_data,
+ this->ideal_width,
+ this->ideal_height,
+ &gui_x, &gui_y, &gui_width, &gui_height,
+ &gui_win_x, &gui_win_y );
+ DEBUGF ((stderr, "*** frame_output_cb returned\n"));
+
+ if ( (this->gui_x != gui_x) || (this->gui_y != gui_y) ||
+ (this->gui_width != gui_width) || (this->gui_height != gui_height) ||
+ (this->gui_win_x != gui_win_x) || (this->gui_win_y != gui_win_y) ||
+ (this->context_state != CONTEXT_SET)) {
+
+ this->gui_x = gui_x;
+ this->gui_y = gui_y;
+ this->gui_width = gui_width;
+ this->gui_height = gui_height;
+ this->gui_win_x = gui_win_x;
+ this->gui_win_y = gui_win_y;
+
+ opengl_compute_output_size (this);
+
+ /* Actually, the output area is cleared in render_image */
+ return 1;
+ }
+ return 0;
}
+
static void opengl_render_image (opengl_driver_t *this, opengl_frame_t *frame,
GLXContext ctx)
{
- int xoffset;
- int yoffset;
- pthread_t self = pthread_self ();
-
- DEBUGF ((stderr, "*** render_image %p frame %p %dx%d ctx %p%s\n",
- this, frame, frame->width, frame->height, ctx,
- self != this->renderthread ? " THREAD" :
- ctx && ctx != this->context ? " gui" :
- this->context_state == CONTEXT_SET ?
- ctx ? " set, but reload anyway" : " set" :
- this->context_state == CONTEXT_RELOAD ? " reload" :
- this->context_state == CONTEXT_SAME_DRAWABLE ? " DESTROY+CREATE" :
- " CREATE" ));
-
- if (((ctx == this->context || ! ctx) &&
- (this->context_state == CONTEXT_BAD ||
- this->context_state == CONTEXT_SAME_DRAWABLE)) ||
- (self != this->renderthread))
- {
- assert (this->vinfo);
- if ((this->context_state == CONTEXT_SAME_DRAWABLE) && (self == this->renderthread))
- {
-/*fprintf (stderr, "destroy: %p\n", this->context); */
- /* Unfortunately for _BAD the drawable is already destroyed.
- * This cannot be resolved right now and may be a memory leak. */
- if (this->context)
- glXDestroyContext (this->display, this->context);
- }
-/*fprintf (stderr, "create\n"); */
- ctx = glXCreateContext (this->display, this->vinfo, NULL, True);
- assert (ctx);
- this->context = ctx;
- this->context_state = CONTEXT_RELOAD;
- this->renderthread = self;
- }
-
- if (this->context_state == CONTEXT_RELOAD && ! ctx)
- ctx = this->context;
-
- if (ctx)
- {
- int i;
-
-/*fprintf (stderr, "set context %p\n", ctx); */
- /* Set and initialize context */
- if (! glXMakeCurrent (this->display, this->drawable, ctx))
+ pthread_t self = pthread_self ();
+
+ DEBUGF ((stderr, "*** render_image %p frame %p %dx%d ctx %p%s\n",
+ this, frame, frame->width, frame->height, ctx,
+ self != this->renderthread ? " THREAD" :
+ ctx && ctx != this->context ? " gui" :
+ this->context_state == CONTEXT_SET ?
+ ctx ? " set, but reload anyway" : " set" :
+ this->context_state == CONTEXT_RELOAD ? " reload" :
+ this->context_state == CONTEXT_SAME_DRAWABLE ? " DESTROY+CREATE" :
+ " CREATE" ));
+
+ /* already initialized? */
+ if (! this->drawable || ! this->vinfo)
{
- fprintf (stderr, "video_out_opengl: no OpenGL support available (glXMakeCurrent)\n");
- exit (1);
+ fprintf (stderr, "video_out_opengl: early exit due to missing drawable %lx vinfo %p\n", this->drawable, this->vinfo);
+ return;
}
-/*fprintf (stderr, "set context done\n"); */
- if (ctx == this->context)
- this->context_state = CONTEXT_SET;
- else if (this->context_state == CONTEXT_SET ||
- this->context_state == CONTEXT_RELOAD)
- this->context_state = CONTEXT_RELOAD;
- /* glViewport (0, 0, this->window_width, this->window_height);
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
- glOrtho (0, this->window_width, this->window_height, 0, -1, 1);
- glMatrixMode (GL_MODELVIEW);
- glLoadIdentity ();
- glDisable (GL_BLEND);
- glDisable (GL_DEPTH_TEST);
- glDisable (GL_CULL_FACE);
- glEnable (GL_TEXTURE_2D);
- glDepthMask (GL_FALSE);
- glClearColor (0, 0, 0, 0);
- */
- glViewport (0, 0, this->window_width,
- this->window_height);
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
-
- gluPerspective (45.0f,
- (GLfloat)(this->window_width)/
- (GLfloat)(this->window_height),
- 1.0f, 1000.0f);
- glMatrixMode (GL_MODELVIEW);
- glLoadIdentity ();
+ /*
+ * check for size changes
+ */
+ if (frame->width != this->last_width ||
+ frame->height != this->last_height ||
+ frame->ratio_code != this->last_ratio_code) {
- glClearColor (0.0f, 0.0f, 0.0f, 0.5f);
- glClearDepth (1.0f);
- glDepthFunc (GL_LEQUAL);
- glEnable(GL_DEPTH_TEST);
- glShadeModel (GL_FLAT);
- glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
-
- glEnable(GL_TEXTURE_2D);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
-
- this->texture_width = 1;
- i = frame->width;
- while(i > 0) {
- i = i>>1;
- this->texture_width = (this->texture_width) << 1;
+ this->last_width = frame->width;
+ this->last_height = frame->height;
+ this->last_ratio_code = frame->ratio_code;
+
+ DEBUGF ((stderr, "video_out_opengl: display format changed\n"));
+ opengl_compute_ideal_size (this, frame->width, frame->height,
+ frame->ratio_code);
+ this->gui_width = 0; /* trigger re-calc of output size */
}
-
- this->texture_height = 1;
- i = frame->height;
- while(i > 0) {
- i = i>>1;
- this->texture_height = (this->texture_height) << 1;
+
+ /*
+ * tell gui about image size and ask for offset
+ */
+ this->cur_frame = frame;
+ opengl_redraw_needed ((vo_driver_t *) this);
+
+ /*
+ * check whether a new context has to be created
+ */
+ if (((ctx == this->context || ! ctx) &&
+ (this->context_state == CONTEXT_BAD ||
+ this->context_state == CONTEXT_SAME_DRAWABLE)) ||
+ (self != this->renderthread))
+ {
+ assert (this->vinfo);
+ if ((this->context_state == CONTEXT_SAME_DRAWABLE) &&
+ (self == this->renderthread))
+ {
+ DEBUGF ((stderr, "destroy: %p\n", this->context));
+ /* Unfortunately for _BAD the drawable is already destroyed.
+ * This cannot be resolved right now and will be a memory leak. */
+ if (this->context)
+ glXDestroyContext (this->display, this->context);
+ }
+ DEBUGF ((stderr, "create\n"));
+ ctx = glXCreateContext (this->display, this->vinfo, NULL, True);
+ assert (ctx);
+ this->context = ctx;
+ this->context_state = CONTEXT_RELOAD;
+ this->renderthread = self;
}
-
- if(this->texture_data) {
- free(this->texture_data);
+
+ if (this->context_state == CONTEXT_RELOAD && ! ctx)
+ ctx = this->context;
+
+ /*
+ * reload and initialize context and clear display
+ * this is handled together due to close relationship
+ */
+ if (ctx)
+ {
+ int i;
+ void *texture_data;
+
+ DEBUGF ((stderr, "set context %p\n", ctx));
+ /*
+ * Set and initialize context
+ */
+ if (! glXMakeCurrent (this->display, this->drawable, ctx)) {
+ fprintf (stderr, "video_out_opengl: no OpenGL support available (glXMakeCurrent)\n The drawable does not seem to be updated correctly.\n");
+ exit (1);
+ }
+ DEBUGF ((stderr, "set context done\n"));
+ if (ctx == this->context)
+ this->context_state = CONTEXT_SET;
+ else if (this->context_state == CONTEXT_SET ||
+ this->context_state == CONTEXT_RELOAD)
+ this->context_state = CONTEXT_RELOAD;
+ glViewport (0, 0, this->gui_width, this->gui_height);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+ glClearColor (0, 0, 0, 0);
+ glClearDepth (1.0f);
+ glDisable (GL_BLEND);
+ glDisable (GL_DEPTH_TEST);
+ glDepthMask (GL_FALSE);
+ glDisable (GL_CULL_FACE);
+ glShadeModel (GL_FLAT);
+ glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+
+#if USE_SPHERE
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glDepthFunc (GL_LEQUAL);
+ glEnable (GL_DEPTH_TEST);
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glScalef((float)(frame->width)/(float)(this->texture_width),
+ (float)(frame->height)/(float)(this->texture_height),
+ 1.0f);
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ gluPerspective (45.0f,
+ (GLfloat)(this->gui_width)/
+ (GLfloat)(this->gui_height),
+ 1.0f, 1000.0f);
+ glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+
+#else
+ glClear (GL_COLOR_BUFFER_BIT);
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho (0, this->gui_width, this->gui_height, 0, -1, 1);
+#endif
+
+#if USE_TEXTURES
+ glEnable (GL_TEXTURE_2D);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ /*
+ * check necessary texture size and allocate
+ */
+ this->texture_width = 1;
+ while (this->texture_width < frame->width)
+ this->texture_width <<= 1;
+ this->texture_height = 1;
+ while (this->texture_height < frame->height)
+ this->texture_height <<= 1;
+
+ texture_data = malloc (this->texture_width * this->texture_height * 3);
+ glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB,
+ this->texture_width, this->texture_height,
+ 0, GL_RGB, GL_UNSIGNED_BYTE, texture_data);
+ free (texture_data);
+#endif
}
-
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glScalef((float)(frame->width)/(float)(this->texture_width),
- (float)(frame->height)/(float)(this->texture_height),
- 1.0f);
- glMatrixMode(GL_MODELVIEW);
-
- this->texture_data = malloc(this->texture_width * this->texture_height * 3);
- glTexImage2D(GL_TEXTURE_2D, 0, 3,
- this->texture_width, this->texture_height,
- 0, RGB_TEXTURE_FORMAT, GL_UNSIGNED_BYTE,
- this->texture_data);
-
- /* for fullscreen and misratioed modes, clear unused areas of old
- * video area */
- if (this->window_width != this->output_width
- || this->window_height != this->output_height)
- glClear (GL_COLOR_BUFFER_BIT);
- }
-
- if (frame)
- {
-
- xoffset = (this->window_width - this->output_width) / 2;
- yoffset = (this->window_height - this->output_height) / 2;
- if (xoffset < 0)
- xoffset = 0;
- if (yoffset < 0)
- yoffset = 0;
-
-/*fprintf (stderr, "render %p %p: +%d+%d\n", frame, ctx, xoffset, yoffset); */
-
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
- (GLsizei)(frame->width),
- (GLsizei)(frame->height),
- RGB_TEXTURE_FORMAT, GL_UNSIGNED_BYTE,
- frame->texture);
- glClear (GL_DEPTH_BUFFER_BIT);
- glLoadIdentity();
- glBegin(GL_QUADS);
- glTexCoord2f(1.0f, 1.0f); glVertex3f( 11.0f, -8.3f, -20.0f);
- glTexCoord2f(0.0f, 1.0f); glVertex3f(-11.0f, -8.3f, -20.0f);
- glTexCoord2f(0.0f, 0.0f); glVertex3f(-11.0f, 8.3f, -20.0f);
- glTexCoord2f(1.0f, 0.0f); glVertex3f( 11.0f, 8.3f, -20.0f);
- glEnd();
-
-#ifdef SPHERE
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
-
- glTranslatef(0.0f, 0.0f, -10.0f);
- glutSolidSphere(3.0f, 20, 10);
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
+
+
+ if (frame)
+ {
+ /*
+ * Render one image
+ */
+#if USE_TEXTURES
+ int x1 = this->output_xoffset, y1 = this->output_yoffset;
+ int x2 = x1 + this->output_width, y2 = y1 + this->output_height;
+ float tx = (float) frame->width / this->texture_width;
+ float ty = (float) frame->height / this->texture_height;
+
+ glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0,
+ (GLsizei)(frame->width),
+ (GLsizei)(frame->height),
+ RGB_TEXTURE_FORMAT, GL_UNSIGNED_BYTE,
+ frame->texture);
+
+ glBegin (GL_QUADS);
+ glTexCoord2f (tx, ty); glVertex2i (x2, y2);
+ glTexCoord2f (0, ty); glVertex2i (x1, y2);
+ glTexCoord2f (0, 0); glVertex2i (x1, y1);
+ glTexCoord2f (tx, 0); glVertex2i (x2, y1);
+ glEnd ();
+
+#if USE_SPHERE
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+
+ glTranslatef(0.0f, 0.0f, -10.0f);
+ glutSolidSphere(3.0f, 20, 10);
+
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
#endif
- /*
- glPixelZoom (((float)this->output_width) / frame->width,
+#else
+ glPixelZoom (((float)this->output_width) / frame->width,
- ((float)this->output_height) / frame->height);
- glRasterPos2i (xoffset, yoffset);
- glDrawPixels (frame->width, frame->height, RGB_TEXTURE_FORMAT,
- GL_UNSIGNED_BYTE, frame->texture);
- */
-/*fprintf (stderr, "render done\n"); */
- }
- glFlush ();
- /* Note: no glFinish() - work concurrently to the graphics pipe */
+ glRasterPos2i (this->output_xoffset, this->output_yoffset);
+ glDrawPixels (frame->width, frame->height, RGB_TEXTURE_FORMAT,
+ GL_UNSIGNED_BYTE, frame->texture);
+#endif
+ DEBUGF ((stderr, "render done\n"));
+ }
+
+ glFlush ();
+ DEBUGF ((stderr, "video_output_opengl: OpenGL error: '%s'\n", gluErrorString (glGetError ())));
+ /* Note: no glFinish() - work concurrently to the graphics pipe */
}
static void opengl_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) {
- opengl_driver_t *this = (opengl_driver_t *) this_gen;
- opengl_frame_t *frame = (opengl_frame_t *) frame_gen;
-
-/*fprintf (stderr, "*** display_frame ***\n"); */
- if( this->cur_frame )
- this->cur_frame->vo_frame.displayed (&this->cur_frame->vo_frame);
- this->cur_frame = frame;
-
- if ( (frame->width != this->last_frame_width) ||
- (frame->height != this->last_frame_height) ||
- (frame->ratio_code != this->delivered_ratio_code) )
- {
- opengl_calc_format (this, frame->width, frame->height, frame->ratio_code);
- this->last_frame_width = frame->width;
- this->last_frame_height = frame->height;
- this->last_frame_ratio_code = frame->ratio_code;
-
- printf ("video_out_opengl: window size %d x %d, frame size %d x %d\n",
- this->window_width, this->window_height,
- this->output_width, this->output_height);
- }
-
- XLockDisplay (this->display);
- opengl_render_image (this, frame, NULL);
- XUnlockDisplay (this->display);
-
- /* Theoretically, the frame data is not used immedeately, and the
- * graphics system might address altered data - but only if we
- * are faster than the graphics hardware... */
- /* If this doesn't work, remove the following two lines */
- /* Note: We cannot do expose events, when the frame is deleted. */
- /* Note: We cannot do expose events anyway right now (errors with
- * multiple threads rendering in many OpenGL implementations) */
+ opengl_driver_t *this = (opengl_driver_t *) this_gen;
+ opengl_frame_t *frame = (opengl_frame_t *) frame_gen;
+
+ DEBUGF ((stderr, "*** display_frame ***\n"));
+ if( this->cur_frame )
+ this->cur_frame->vo_frame.displayed (&this->cur_frame->vo_frame);
+ this->cur_frame = frame;
+
+ XLockDisplay (this->display);
+ opengl_render_image (this, frame, NULL);
+ XUnlockDisplay (this->display);
+
+ /* Theoretically, the frame data is not used immedeately, and the
+ * graphics system might address altered data - but only if we
+ * are faster than the graphics hardware... */
+ /* If the image seems to be clobbered, remove the following two lines */
+ /* Note: We cannot do expose events, when the frame is deleted. */
+ /* Note: We cannot do expose events anyway right now (errors with
+ * multiple threads rendering in many OpenGL implementations) */
+ /* FIXME: check that */
#if 1
- frame->vo_frame.displayed (&frame->vo_frame);
- this->cur_frame = NULL;
+ frame->vo_frame.displayed (&frame->vo_frame);
+ this->cur_frame = NULL;
#endif
-/*fprintf (stderr, "done display_frame\n"); */
+ DEBUGF ((stderr, "done display_frame\n"));
}
static int opengl_get_property (vo_driver_t *this_gen, int property) {
- opengl_driver_t *this = (opengl_driver_t *) this_gen;
+ opengl_driver_t *this = (opengl_driver_t *) this_gen;
- if ( property == VO_PROP_ASPECT_RATIO) {
- return this->user_ratio ;
- } else if ( property == VO_PROP_BRIGHTNESS) {
- return yuv2rgb_get_gamma(this->yuv2rgb);
- } else {
- printf ("video_out_opengl: tried to get unsupported property %d\n", property);
- }
+ DEBUGF ((stderr, "*** get_property\n"));
+ switch (property) {
+ case VO_PROP_ASPECT_RATIO:
+ return this->user_ratio ;
+ case VO_PROP_BRIGHTNESS:
+ return this->yuv2rgb_gamma;
+ default:
+ printf ("video_out_opengl: tried to get unsupported property %d\n",
+ property);
+ }
- return 0;
+ return 0;
}
-static char *aspect_ratio_name(int a)
-{
- switch (a) {
- case ASPECT_AUTO:
- return "auto";
- case ASPECT_SQUARE:
- return "square";
- case ASPECT_FULL:
- return "4:3";
- case ASPECT_ANAMORPHIC:
- return "16:9";
- case ASPECT_DVB:
- return "2:1";
- default:
- return "unknown";
- }
+static char *aspect_ratio_name(int a) {
+ switch (a) {
+ case ASPECT_AUTO:
+ return "auto";
+ case ASPECT_SQUARE:
+ return "square";
+ case ASPECT_FULL:
+ return "4:3";
+ case ASPECT_ANAMORPHIC:
+ return "16:9";
+ case ASPECT_DVB:
+ return "2:1";
+ default:
+ return "unknown";
+ }
}
static int opengl_set_property (vo_driver_t *this_gen,
- int property, int value) {
-
- opengl_driver_t *this = (opengl_driver_t *) this_gen;
-
- if ( property == VO_PROP_ASPECT_RATIO) {
- if (value>=NUM_ASPECT_RATIOS)
- value = ASPECT_AUTO;
- this->user_ratio = value;
- opengl_calc_format (this, this->delivered_width, this->delivered_height,
- this->delivered_ratio_code);
- printf("video_out_opengl: aspect ratio changed to %s\n",
- aspect_ratio_name(value));
-#if 0
- } else if ( property == VO_PROP_BRIGHTNESS) {
- yuv2rgb_set_gamma(this->yuv2rgb,value);
-
- printf("video_out_opengl: gamma changed to %d\n",value);
-#endif
- } else {
- printf ("video_out_opengl: tried to set unsupported property %d\n", property);
- }
+ int property, int value) {
- return value;
+ opengl_driver_t *this = (opengl_driver_t *) this_gen;
+
+ DEBUGF ((stderr, "*** set_property\n"));
+ switch (property) {
+ case VO_PROP_ASPECT_RATIO:
+ if (value>=NUM_ASPECT_RATIOS)
+ value = ASPECT_AUTO;
+ this->user_ratio = value;
+ fprintf(stderr, "video_out_opengl: aspect ratio changed to %s\n",
+ aspect_ratio_name(value));
+ this->gui_width = 0; /* trigger re-calc of output size */
+ opengl_compute_ideal_size (this, this->last_width,
+ this->last_height, this->last_ratio_code);
+ opengl_redraw_needed ((vo_driver_t *) this);
+ break;
+ case VO_PROP_BRIGHTNESS:
+ this->yuv2rgb_gamma = value;
+ this->yuv2rgb_factory->set_gamma (this->yuv2rgb_factory, value);
+ printf("video_out_opengl: gamma changed to %d\n",value);
+ break;
+ default:
+ printf ("video_out_opengl: tried to set unsupported property %d\n", property);
+ }
+
+ return value;
}
static void opengl_get_property_min_max (vo_driver_t *this_gen,
- int property, int *min, int *max) {
+ int property, int *min, int *max) {
-#if 0
- /* opengl_driver_t *this = (opengl_driver_t *) this_gen; */
- if ( property == VO_PROP_BRIGHTNESS) {
- *min = -100;
- *max = +100;
- } else {
-#endif
- *min = 0;
- *max = 0;
-#if 0
- }
-#endif
+ DEBUGF ((stderr, "get_property_min_max\n"));
+ /* opengl_driver_t *this = (opengl_driver_t *) this_gen; */
+ if ( property == VO_PROP_BRIGHTNESS) {
+ *min = -100;
+ *max = +100;
+ } else {
+ *min = 0;
+ *max = 0;
+ }
}
-static int is_fullscreen_size (opengl_driver_t *this, int w, int h)
-{
- return w == DisplayWidth(this->display, this->screen)
- && h == DisplayHeight(this->display, this->screen);
-}
-
static void opengl_translate_gui2video(opengl_driver_t *this,
- int x, int y,
- int *vid_x, int *vid_y)
-{
-/*fprintf (stderr, "*** translate_gui2video ***\n"); */
- if (this->output_width > 0 && this->output_height > 0) {
- /*
- * the driver may center a small output area inside a larger
- * gui area. This is the case in fullscreen mode, where we often
- * have black borders on the top/bottom/left/right side.
- */
- /* Fixme: not true. Simplify? */
- x -= (this->window_width - this->output_width) >> 1;
- y -= (this->window_height - this->output_height) >> 1;
-
- /*
- * the driver scales the delivered area into an output area.
- * translate output area coordianates into the delivered area
- * coordiantes.
- */
- x = x * this->delivered_width / this->output_width;
- y = y * this->delivered_height / this->output_height;
- }
+ opengl_frame_t *frame,
+ int x, int y,
+ int *vid_x, int *vid_y) {
+
+ DEBUGF ((stderr, "*** translate_gui2video ***\n"));
+ if (this->output_width > 0 && this->output_height > 0) {
+ /*
+ * the driver may center a small output area inside a larger
+ * gui area. This is the case in fullscreen mode, where we often
+ * have black borders on the top/bottom/left/right side.
+ */
+ x -= this->output_xoffset;
+ y -= this->output_yoffset;
+
+ /*
+ * the driver scales the delivered area into an output area.
+ * translate output area coordianates into the delivered area
+ * coordiantes.
+ */
+ x = x * frame->width / this->output_width;
+ y = y * frame->height / this->output_height;
+ }
- *vid_x = x;
- *vid_y = y;
+ *vid_x = x;
+ *vid_y = y;
}
static int opengl_gui_data_exchange (vo_driver_t *this_gen,
- int data_type, void *data) {
-
- opengl_driver_t *this = (opengl_driver_t *) this_gen;
- x11_rectangle_t *area;
- static int glxAttrib[] = {
- GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None
- } ;
-
-/*fprintf (stderr, "*** gui_data_exchange ***\n"); */
-
- switch (data_type) {
- case GUI_SELECT_VISUAL:
-fprintf (stderr, "*** gui_select_visual ***\n");
- XLockDisplay (this->display);
- this->vinfo = glXChooseVisual (this->display, this->screen, glxAttrib);
- XUnlockDisplay (this->display);
- if (this->vinfo == NULL)
- fprintf (stderr, "video_out_opengl: no OpenGL support available (glXChooseVisual)\n");
- *(XVisualInfo**)data = this->vinfo;
-/*fprintf (stderr, "*** visual %p depth %d\n", this->vinfo->visual, this->vinfo->depth); */
- break;
+ int data_type, void *data) {
+
+ opengl_driver_t *this = (opengl_driver_t *) this_gen;
+ static int glxAttrib[] = {
+ GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None
+ } ;
+
+ DEBUGF ((stderr, "*** gui_data_exchange ***\n"));
+
+ switch (data_type) {
+ case GUI_SELECT_VISUAL:
+ DEBUGF ((stderr, "*** gui_select_visual ***\n"));
+ XLockDisplay (this->display);
+ this->vinfo = glXChooseVisual (this->display, this->screen, glxAttrib);
+ XUnlockDisplay (this->display);
+ if (this->vinfo == NULL)
+ fprintf (stderr, "video_out_opengl: no OpenGL support available (glXChooseVisual)\n");
+ *(XVisualInfo**)data = this->vinfo;
+ DEBUGF ((stderr, "*** visual %p depth %d\n", this->vinfo->visual, this->vinfo->depth));
+ break;
- case GUI_DATA_EX_DEST_POS_SIZE_CHANGED:
-/*fprintf (stderr, "*** gui_dest_pos_size_changed ***\n"); */
-
- area = (x11_rectangle_t *) data;
+ case GUI_DATA_EX_EXPOSE_EVENT:
+ DEBUGF ((stderr, "*** gui_expose ***\n"));
+
+ /* Note that the global GLX context is not available on all
+ * architectures in this thread */
+ /* Note that using different contextes in different threads
+ * for the same drawable seems to be broken with several
+ * OpenGL implementations */
+ /* Thus nothing is updated here, just the render thread is
+ * notified */
+ if (this->context_state == CONTEXT_SET)
+ this->context_state = CONTEXT_RELOAD;
+ break;
- if (this->window_width != area->w || this->window_height != area->h)
- {
- XLockDisplay (this->display);
- DEBUGF ((stderr, "*** video window size changed from %d x %d to %d x %d\n",
- this->window_width, this->window_height,
- area->w, area->h));
- opengl_adapt_to_output_area (this, area->w, area->h);
- XUnlockDisplay (this->display);
- }
- break;
-// ????? What's this?
+ case GUI_DATA_EX_DRAWABLE_CHANGED:
+ DEBUGF ((stderr, "*** gui_drawable_changed: %ld\n", (Drawable) data));
+ XLockDisplay (this->display);
+ /* Unfortunately, the last drawable is already gone, so we cannot
+ * destroy the former context. This is a memory leak. Unfortunately. */
+ /* Even if the drawable remains the same, this does not seem to
+ * work :( */
+ /* FIXME: check that */
#if 0
- case GUI_DATA_EX_COMPLETION_EVENT: {
-
- XShmCompletionEvent *cev = (XShmCompletionEvent *) data;
+ if (this->drawable == (Drawable) data)
+ this->context_state = CONTEXT_SAME_DRAWABLE;
+ else
+ this->context_state = CONTEXT_BAD;
+#else
+ this->context_state = CONTEXT_BAD;
+#endif
+ if (this->context_state == CONTEXT_BAD)
+ DEBUGF ((stderr, "*** drawable changed, state now bad\n"));
+ this->drawable = (Drawable) data;
+ XUnlockDisplay (this->display);
+ break;
- if (cev->drawable == this->drawable) {
- this->expecting_event = 0;
+ case GUI_DATA_EX_TRANSLATE_GUI_TO_VIDEO:
+/* DEBUGF ((stderr, "*** gui_translate_gui_to_video ***\n")); */
+ if (this->cur_frame) {
+ int x1, y1, x2, y2;
+ x11_rectangle_t *rect = data;
+
+ opengl_translate_gui2video(this, this->cur_frame,
+ rect->x, rect->y, &x1, &y1);
+ opengl_translate_gui2video(this, this->cur_frame,
+ rect->x + rect->w, rect->y + rect->h,
+ &x2, &y2);
+ rect->x = x1;
+ rect->y = y1;
+ rect->w = x2-x1;
+ rect->h = y2-y1;
+ }
+ break;
- if (this->cur_frame) {
- this->cur_frame->vo_frame.displayed (&this->cur_frame->vo_frame);
- this->cur_frame = NULL;
- }
+ default:
+ return -1;
}
- }
- break;
-#endif
-
- case GUI_DATA_EX_EXPOSE_EVENT:
-/*fprintf (stderr, "*** gui_expose ***\n"); */
-
- /* FIXME: called for EVERY SINGLE expose event (no peek so far) */
- if (this->cur_frame) {
+/* DEBUGF ((stderr, "done gui_data_exchange\n")); */
+ return 0;
+}
- XExposeEvent * xev = (XExposeEvent *) data;
- if (xev->count == 0) {
- /* Note that the global GLX context is not available on all
- * architectures in this thread */
- /* Note that using different contextes in different threads for the
- * same drawable seems to be broken with several OpenGL implementations */
- /* Thus this is currently disabled */
-#if 0
- GLXContext ctx;
- XLockDisplay (this->display);
-// FIXME: this does not work - at least on linux...
-fprintf (stderr, "create/gui\n");
-assert (this->vinfo);
-ctx = glXCreateContext (this->display, this->vinfo, NULL, True);
-assert (ctx);
-opengl_render_image (this, this->cur_frame, ctx);
-glXMakeCurrent (this->display, None, NULL);
-glXDestroyContext (this->display, ctx);
-XUnlockDisplay (this->display);
-#endif
- }
- }
- if (this->context_state == CONTEXT_SET || this->context_state == CONTEXT_RELOAD)
- this->context_state = CONTEXT_RELOAD;
- break;
+static void opengl_exit (vo_driver_t *this_gen) {
+ opengl_driver_t *this = (opengl_driver_t *) this_gen;
- case GUI_DATA_EX_DRAWABLE_CHANGED:
- DEBUGF ((stderr, "*** gui_drawable_changed: %ld\n", (Drawable) data));
XLockDisplay (this->display);
- /* Unfortunately, the last drawable is already gone, so we cannot destroy
- * the former context. This is a memory leak. Unfortunately. */
- /* Even if the drawable remains the same, this does not seem to work :( */
-#if 0
- if (this->drawable == (Drawable) data)
- this->context_state = CONTEXT_SAME_DRAWABLE;
- else
- this->context_state = CONTEXT_BAD;
-#else
- this->context_state = CONTEXT_BAD;
-#endif
- if (this->drawable == (Drawable) data)
- DEBUGF ((stderr, "*** drawable changed, state now bad\n"));
- this->last_frame_width = this->last_frame_height = 0;
- this->drawable = (Drawable) data;
+ if (this->cur_frame)
+ this->cur_frame->vo_frame.dispose (&this->cur_frame->vo_frame);
XUnlockDisplay (this->display);
- break;
- case GUI_DATA_EX_TRANSLATE_GUI_TO_VIDEO:
-/*fprintf (stderr, "*** gui_translate_gui_to_video ***\n"); */
- {
- int x1, y1, x2, y2;
- x11_rectangle_t *rect = data;
-
- opengl_translate_gui2video(this, rect->x, rect->y,
- &x1, &y1);
- opengl_translate_gui2video(this, rect->x + rect->w, rect->y + rect->h,
- &x2, &y2);
- rect->x = x1;
- rect->y = y1;
- rect->w = x2-x1;
- rect->h = y2-y1;
- }
- break;
+ glXMakeCurrent (this->display, None, NULL);
+ glXDestroyContext (this->display, this->context);
+ this->context = NULL;
- default:
- return -1;
- }
-
-/*fprintf (stderr, "done gui_data_exchange\n"); */
- return 0;
+ free (this);
}
-static void opengl_exit (vo_driver_t *this_gen) {
- opengl_driver_t *this = (opengl_driver_t *) this_gen;
- glXMakeCurrent (this->display, None, NULL);
- glXDestroyContext (this->display, this->context);
- this->context = NULL;
-}
+vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
+ opengl_driver_t *this;
+ x11_visual_t *visual = (x11_visual_t *) visual_gen;
+ Display *display = NULL;
-vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) {
+ visual = (x11_visual_t *) visual_gen;
+ display = visual->display;
+
+ fprintf (stderr, "EXPERIMENTAL opengl output plugin\n");
+ /*
+ * allocate plugin struct
+ */
+
+ this = malloc (sizeof (opengl_driver_t));
+
+ if (!this) {
+ printf ("video_out_opengl: malloc failed\n");
+ return NULL;
+ }
- opengl_driver_t *this;
- x11_visual_t *visual = (x11_visual_t *) visual_gen;
- Display *display = NULL;
-
- visual = (x11_visual_t *) visual_gen;
- display = visual->display;
-
- fprintf (stderr, "EXPERIMENTAL opengl output plugin\n");
- /*
- * allocate plugin struct
- */
-
- this = malloc (sizeof (opengl_driver_t));
-
- if (!this) {
- printf ("video_out_opengl: malloc failed\n");
- return NULL;
- }
-
- memset (this, 0, sizeof(opengl_driver_t));
-
- this->config = config;
- this->display = visual->display;
- this->screen = visual->screen;
- this->display_ratio = visual->display_ratio;
- this->request_dest_size = visual->request_dest_size;
- this->calc_dest_size = visual->calc_dest_size;
- this->user_data = visual->user_data;
- this->output_width = 0;
- this->output_height = 0;
- this->window_width = 0;
- this->window_height = 0;
- this->zoom_mpeg1 = config->register_bool (config, "video.zoom_mpeg1", 1,
- "Zoom small video formats to double size",
- NULL, NULL, NULL);
- this->texture_data = NULL;
- this->texture_width = 0;
- this->texture_height = 0;
- this->drawable = None; /* We need a different one with a dedicated visual anyway */
- this->context_state = CONTEXT_BAD;
-
- this->prof_yuv2rgb = xine_profiler_allocate_slot ("xshm yuv2rgb convert");
-
- this->vo_driver.get_capabilities = opengl_get_capabilities;
- this->vo_driver.alloc_frame = opengl_alloc_frame;
- this->vo_driver.update_frame_format = opengl_update_frame_format;
- this->vo_driver.overlay_blend = opengl_overlay_blend;
- this->vo_driver.display_frame = opengl_display_frame;
- this->vo_driver.get_property = opengl_get_property;
- this->vo_driver.set_property = opengl_set_property;
- this->vo_driver.get_property_min_max = opengl_get_property_min_max;
- this->vo_driver.gui_data_exchange = opengl_gui_data_exchange;
- this->vo_driver.exit = opengl_exit;
-
- this->yuv2rgb = yuv2rgb_init (YUV_FORMAT, YUV_SWAP_MODE, NULL);
-
- yuv2rgb_set_gamma(this->yuv2rgb, config->register_range (config, "video.opengl_gamma", 0,
- -100, 100, "(software) gamma correction for OpenGL driver",
- NULL, NULL, NULL));
- return &this->vo_driver;
+ memset (this, 0, sizeof(opengl_driver_t));
+
+ this->config = config;
+ this->display = visual->display;
+ this->screen = visual->screen;
+ this->display_ratio = visual->display_ratio;
+ this->frame_output_cb = visual->frame_output_cb;
+ this->dest_size_cb = visual->dest_size_cb;
+ this->user_data = visual->user_data;
+ this->gui_x = 0;
+ this->gui_y = 0;
+ this->gui_width = 0;
+ this->gui_height = 0;
+ this->user_ratio = ASPECT_AUTO;
+ this->texture_width = 0;
+ this->texture_height = 0;
+ this->drawable = None; /* We need a different one with a dedicated visual anyway */
+ this->context_state = CONTEXT_BAD;
+ this->cur_frame = NULL;
+
+ this->vo_driver.get_capabilities = opengl_get_capabilities;
+ this->vo_driver.alloc_frame = opengl_alloc_frame;
+ this->vo_driver.update_frame_format = opengl_update_frame_format;
+ this->vo_driver.overlay_blend = opengl_overlay_blend;
+ this->vo_driver.display_frame = opengl_display_frame;
+ this->vo_driver.get_property = opengl_get_property;
+ this->vo_driver.set_property = opengl_set_property;
+ this->vo_driver.get_property_min_max = opengl_get_property_min_max;
+ this->vo_driver.gui_data_exchange = opengl_gui_data_exchange;
+ this->vo_driver.redraw_needed = opengl_redraw_needed;
+ this->vo_driver.exit = opengl_exit;
+
+ this->yuv2rgb_gamma = config->register_range (config,
+ "video.opengl_gamma", 0,
+ -100, 100,
+ "gamma correction for OpenGL driver",
+ NULL, NULL, NULL);
+ this->yuv2rgb_factory = yuv2rgb_factory_init (YUV_FORMAT, YUV_SWAP_MODE,
+ this->yuv2rgb_cmap);
+ this->yuv2rgb_factory->set_gamma (this->yuv2rgb_factory, this->yuv2rgb_gamma);
+
+ return &this->vo_driver;
}
static vo_info_t vo_info_shm = {
- 3,
- "OpenGL",
- "xine video output plugin using the MIT X shared memory extension",
- VISUAL_TYPE_X11,
- 8
+ 5,
+ "OpenGL",
+ "xine video output plugin using OpenGL(tm)",
+ VISUAL_TYPE_X11,
+ 8
};
vo_info_t *get_video_out_plugin_info() {
- return &vo_info_shm;
+ return &vo_info_shm;
}