diff options
Diffstat (limited to 'src/video_out')
-rw-r--r-- | src/video_out/Makefile.am | 11 | ||||
-rw-r--r-- | src/video_out/macosx/XineOpenGLView.m | 2 | ||||
-rw-r--r-- | src/video_out/video_out_directfb.c | 18 | ||||
-rw-r--r-- | src/video_out/video_out_fb.c | 2 | ||||
-rw-r--r-- | src/video_out/video_out_opengl.c | 2 | ||||
-rw-r--r-- | src/video_out/video_out_pgx64.c | 3 | ||||
-rw-r--r-- | src/video_out/video_out_syncfb.c | 1116 | ||||
-rw-r--r-- | src/video_out/video_out_syncfb.h | 236 | ||||
-rw-r--r-- | src/video_out/video_out_vidix.c | 6 | ||||
-rw-r--r-- | src/video_out/video_out_xcbshm.c | 26 | ||||
-rw-r--r-- | src/video_out/video_out_xcbxv.c | 203 | ||||
-rw-r--r-- | src/video_out/video_out_xshm.c | 26 | ||||
-rw-r--r-- | src/video_out/video_out_xv.c | 189 | ||||
-rw-r--r-- | src/video_out/video_out_xvmc.c | 120 | ||||
-rw-r--r-- | src/video_out/video_out_xxmc.c | 171 | ||||
-rw-r--r-- | src/video_out/xv_common.h | 58 |
16 files changed, 521 insertions, 1668 deletions
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am index 0a60d242e..062c7aa68 100644 --- a/src/video_out/Makefile.am +++ b/src/video_out/Makefile.am @@ -12,7 +12,7 @@ endif EXTRA_DIST = video_out_directx.c video_out_macosx.m -noinst_HEADERS = video_out_syncfb.h yuv2rgb.h x11osd.h xcbosd.h +noinst_HEADERS = yuv2rgb.h x11osd.h xcbosd.h xv_common.h if HAVE_X11 X11OSD = x11osd.c @@ -29,9 +29,6 @@ endif if ENABLE_OPENGL opengl_module = xineplug_vo_out_opengl.la endif -if ENABLE_SYNCFB -syncfb_module = xineplug_vo_out_syncfb.la -endif if ENABLE_SUNFB if ENABLE_SUNDGA pgx64_module = xineplug_vo_out_pgx64.la @@ -99,7 +96,6 @@ libyuv2rgb_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) $(AVUTIL_LIBS) xineplug_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) \ $(opengl_module) \ - $(syncfb_module) \ $(pgx64_module) $(pgx32_module)\ $(vidix_module) \ $(aa_module) \ @@ -141,12 +137,9 @@ xineplug_vo_out_xxmc_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) $(XV_CFLAGS) -fno-stri xineplug_vo_out_opengl_la_SOURCES = video_out_opengl.c myglext.h $(X11OSD) xineplug_vo_out_opengl_la_LIBADD = libyuv2rgb.la $(OPENGL_LIBS) $(GLUT_LIBS) \ - $(GLU_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) $(AVUTIL_LIBS) + $(GLUT_LIBS) $(GLU_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) $(AVUTIL_LIBS) xineplug_vo_out_opengl_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) $(AVUTIL_CFLAGS) -fno-strict-aliasing -xineplug_vo_out_syncfb_la_SOURCES = video_out_syncfb.c -xineplug_vo_out_syncfb_la_LIBADD = $(XINE_LIB) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) - xineplug_vo_out_pgx64_la_SOURCES = video_out_pgx64.c xineplug_vo_out_pgx64_la_LIBADD = $(XINE_LIB) $(X_LIBS) $(SUNDGA_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_pgx64_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) diff --git a/src/video_out/macosx/XineOpenGLView.m b/src/video_out/macosx/XineOpenGLView.m index 5ed515704..cad087551 100644 --- a/src/video_out/macosx/XineOpenGLView.m +++ b/src/video_out/macosx/XineOpenGLView.m @@ -336,7 +336,7 @@ NSColorToYUV(NSColor *color) // http://developer.apple.com/samplecode/Sample_Code/Graphics_3D/TextureRange/MainOpenGLView.m.htm glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, videoSize.width, videoSize.height, GL_YCBCR_422_APPLE, -#if WORDS_BIG_ENDIAN +#if WORDS_BIGENDIAN GL_UNSIGNED_SHORT_8_8_APPLE, #else GL_UNSIGNED_SHORT_8_8_REV_APPLE, diff --git a/src/video_out/video_out_directfb.c b/src/video_out/video_out_directfb.c index d85df411a..fecc2c5b0 100644 --- a/src/video_out/video_out_directfb.c +++ b/src/video_out/video_out_directfb.c @@ -1742,6 +1742,20 @@ static void directfb_frame_output_cb (void *user_data, int video_width, int vide /*** DirectFB plugin functions ***/ +static inline int convert_caps (DFBDisplayLayerCapabilities caps) +{ + int vo = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; + if (caps & DLCAPS_HUE) + vo |= VO_CAP_HUE; + if (caps & DLCAPS_SATURATION) + vo |= VO_CAP_SATURATION; + if (caps & DLCAPS_CONTRAST) + vo |= VO_CAP_CONTRAST; + if (caps & DLCAPS_BRIGHTNESS) + vo |= VO_CAP_BRIGHTNESS; + return vo; +} + static vo_driver_t *open_plugin_fb (video_driver_class_t *class_gen, const void *visual_gen) { directfb_class_t *class = (directfb_class_t *) class_gen; directfb_driver_t *this; @@ -1821,7 +1835,7 @@ static vo_driver_t *open_plugin_fb (video_driver_class_t *class_gen, const void return NULL; } - this->capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_CROP; + this->capabilities = convert_caps (this->caps); /* set default configuration */ this->buffermode = 1; // double this->vsync = 0; @@ -2000,7 +2014,7 @@ static vo_driver_t *open_plugin_x11 (video_driver_class_t *class_gen, const void xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: using display layer #%d.\n"), id); - this->capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_CROP; + this->capabilities = convert_caps (this->caps); /* set default configuration */ this->buffermode = 1; // double this->vsync = 0; diff --git a/src/video_out/video_out_fb.c b/src/video_out/video_out_fb.c index cb327109e..dc3d683e1 100644 --- a/src/video_out/video_out_fb.c +++ b/src/video_out/video_out_fb.c @@ -156,7 +156,7 @@ typedef struct static uint32_t fb_get_capabilities(vo_driver_t *this_gen) { - return VO_CAP_YV12 | VO_CAP_YUY2; + return VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST | VO_CAP_SATURATION; } static void fb_frame_proc_slice(vo_frame_t *vo_img, uint8_t **src) diff --git a/src/video_out/video_out_opengl.c b/src/video_out/video_out_opengl.c index febf44519..c1416963c 100644 --- a/src/video_out/video_out_opengl.c +++ b/src/video_out/video_out_opengl.c @@ -1202,7 +1202,7 @@ static void *render_run (opengl_driver_t *this) { static uint32_t opengl_get_capabilities (vo_driver_t *this_gen) { /* opengl_driver_t *this = (opengl_driver_t *) this_gen; */ - uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2; + uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST | VO_CAP_SATURATION; /* TODO: somehow performance goes down during the first few frames */ /* if (this->xoverlay) */ diff --git a/src/video_out/video_out_pgx64.c b/src/video_out/video_out_pgx64.c index d0e74b1e3..0bdcc35fe 100644 --- a/src/video_out/video_out_pgx64.c +++ b/src/video_out/video_out_pgx64.c @@ -552,8 +552,7 @@ static uint32_t pgx64_get_capabilities(vo_driver_t *this_gen) { /*pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen;*/ - return VO_CAP_YV12 | - VO_CAP_YUY2; + return VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | VO_CAP_SATURATION; } static vo_frame_t *pgx64_alloc_frame(vo_driver_t *this_gen) diff --git a/src/video_out/video_out_syncfb.c b/src/video_out/video_out_syncfb.c deleted file mode 100644 index 983cd9b64..000000000 --- a/src/video_out/video_out_syncfb.c +++ /dev/null @@ -1,1116 +0,0 @@ -/* - * Copyright (C) 2000-2003 the xine project - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine 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 this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * video_out_syncfb.c, SyncFB (for Matrox G200/G400 cards) interface for xine - * - * based on video_out_xv.c by (see file for original authors) - * - * with lot's of code from: - * video_out_syncfb.c by Joachim Koenig <joachim.koenig@gmx.net> - * and by Matthias Oelmann <mao@well.com> - * video_out_mga by Aaron Holtzman <aholtzma@ess.engr.uvic.ca> - * - * glued together for xine by Matthias Dahl <matthew2k@web.de> - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef __sun -#include <sys/ioccom.h> -#endif - -#include <sys/ioctl.h> -#if defined (__FreeBSD__) -#include <sys/types.h> -#endif -#include <sys/mman.h> -#include <math.h> -#include <fcntl.h> -#include <unistd.h> - -#include <X11/Xlib.h> -#include <X11/Xutil.h> - -#include "video_out_syncfb.h" - -#include "xine.h" -#include <xine/video_out.h> -#include <xine/xine_internal.h> -#include <xine/xineutils.h> -#include <xine/vo_scale.h> - -/*#define DEBUG_OUTPUT*/ - -typedef struct syncfb_driver_s syncfb_driver_t; - -typedef struct { - int value; - int min; - int max; -} syncfb_property_t; - -typedef struct { - vo_frame_t vo_frame; -/* uint8_t* data_mem[3];*/ - int width, height, format; - double ratio; -} syncfb_frame_t; - -struct syncfb_driver_s { - - vo_driver_t vo_driver; - - config_values_t *config; - - /* X11 related stuff */ - Display *display; - int screen; - Drawable drawable; - XVisualInfo vinfo; - GC gc; - XColor black; - - vo_scale_t sc; - - int virtual_screen_width; - int virtual_screen_height; - int screen_depth; - - syncfb_property_t props[VO_NUM_PROPERTIES]; - - syncfb_frame_t* cur_frame; - vo_overlay_t* overlay; - - /* syncfb module related stuff */ - int fd; /* file descriptor of the syncfb device */ - int yuv_format; /* either YUV420P3, YUV420P2 or YUV422 */ - int overlay_state; /* 0 = off, 1 = on */ - uint8_t* video_mem; /* mmapped video memory */ - int default_repeat; /* how many times a frame will be repeatedly displayed */ - uint32_t supported_capabilities; - - syncfb_config_t syncfb_config; - syncfb_capability_t capabilities; - syncfb_buffer_info_t bufinfo; - syncfb_param_t params; - - int video_win_visibility; - xine_t *xine; - - alphablend_t alphablend_extra_data; -}; - -typedef struct { - video_driver_class_t driver_class; - - config_values_t *config; - char *device_name; - xine_t *xine; -} syncfb_class_t; - -/* - * internal video_out_syncfb functions - */ - -/* returns boolean value (1 success, 0 failure) */ -static int syncfb_overlay_on(syncfb_driver_t* this) -{ - if(ioctl(this->fd, SYNCFB_ON)) { - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: error. (on ioctl failed)\n"); - return 0; - } else { - this->overlay_state = 1; - return 1; - } -} - -/* returns boolean value (1 success, 0 failure) */ -static int syncfb_overlay_off(syncfb_driver_t* this) -{ - if(ioctl(this->fd, SYNCFB_OFF)) { - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: error. (off ioctl failed)\n"); - return 0; - } else { - this->overlay_state = 0; - return 1; - } -} - -static void write_frame_YUV422(syncfb_driver_t* this, syncfb_frame_t* frame) -{ - uint8_t* y = (uint_8 *)frame->vo_frame.base[0]; - uint8_t* cb = (uint_8 *)frame->vo_frame.base[1]; - uint8_t* cr = (uint_8 *)frame->vo_frame.base[2]; - uint8_t* crp; - uint8_t* cbp; - uint32_t* dst32 = (uint32_t *)(this->video_mem + this->bufinfo.offset); - int h,w; - - for(h = 0; h < (frame->height / 2); h++) { - cbp = cb; - crp = cr; - - for(w = 0; w < (frame->width / 2); w++) { - *dst32++ = (*y) + ((*cb)<<8) + ((*(y+1))<<16) + ((*cr)<<24); - y++; y++; cb++; cr++; - } - - dst32 += (this->syncfb_config.src_pitch - frame->width) / 2; - - for(w=0; w < (frame->width / 2); w++) { - *dst32++ = (*y) + ((*cbp)<<8) + ((*(y+1))<<16) + ((*crp)<<24); - y++; y++; cbp++; crp++; - } - - dst32 += (this->syncfb_config.src_pitch - frame->width) / 2; - } -} - -static void write_frame_YUV420P2(syncfb_driver_t* this, syncfb_frame_t* frame) -{ - uint8_t* y = (uint8_t *)frame->vo_frame.base[0]; - uint8_t* cb = (uint8_t *)frame->vo_frame.base[1]; - uint8_t* cr = (uint8_t *)frame->vo_frame.base[2]; - uint8_t* dst8 = this->video_mem + this->bufinfo.offset_p2; - int h, w; - - register uint32_t* tmp32; - register uint8_t* rcr; - register uint8_t* rcb; - - rcr = cr; - rcb = cb; - - for(h = 0; h < (frame->height / 2); h++) { - tmp32 = (uint32_t *)dst8; - w = (frame->width / 8) * 2; - - while(w--) { - register uint32_t temp; - - temp = (*rcb) | (*rcr << 8); - rcr++; - rcb++; - temp |= (*rcb << 16) | (*rcr << 24); - rcr++; - rcb++; - *tmp32 = temp; - tmp32++; - } - - dst8 += this->syncfb_config.src_pitch; - } - - dst8 = this->video_mem + this->bufinfo.offset; - for(h = 0; h < frame->height; h++) { - xine_fast_memcpy(dst8, y, frame->width); - y += frame->width; - dst8 += this->syncfb_config.src_pitch; - } -} - -static void write_frame_YUV420P3(syncfb_driver_t* this, syncfb_frame_t* frame) -{ - uint8_t* y = (uint8_t *)frame->vo_frame.base[0]; - uint8_t* cb = (uint8_t *)frame->vo_frame.base[1]; - uint8_t* cr = (uint8_t *)frame->vo_frame.base[2]; - uint8_t* dst8 = this->video_mem + this->bufinfo.offset; - int h, half_width = (frame->width/2); - - for(h = 0; h < frame->height; h++) { - xine_fast_memcpy(dst8, y, frame->width); - y += frame->width; - dst8 += this->syncfb_config.src_pitch; - } - - dst8 = this->video_mem; - for(h = 0; h < (frame->height / 2); h++) { - xine_fast_memcpy((dst8 + this->bufinfo.offset_p2), cb, half_width); - xine_fast_memcpy((dst8 + this->bufinfo.offset_p3), cr, half_width); - - cb += half_width; - cr += half_width; - - dst8 += (this->syncfb_config.src_pitch / 2); - } -} - -static void write_frame_YUY2(syncfb_driver_t* this, syncfb_frame_t* frame) -{ - uint8_t* src8 = (uint8_t *)frame->vo_frame.base[0]; - uint8_t* dst8 = (uint8_t *)(this->video_mem + this->bufinfo.offset); - int h, double_width = (frame->width * 2); - - for(h = 0; h < frame->height; h++) { - xine_fast_memcpy(dst8, src8, double_width); - - dst8 += (this->syncfb_config.src_pitch * 2); - src8 += double_width; - } -} - -static void write_frame_sfb(syncfb_driver_t* this, syncfb_frame_t* frame) -{ - switch(frame->format) { - case XINE_IMGFMT_YUY2: - if(this->capabilities.palettes & (1<<VIDEO_PALETTE_YUV422)) - write_frame_YUY2(this, frame); - else - xprintf(this->xine, XINE_VERBOSITY_LOG, - _("video_out_syncfb: error. (YUY2 not supported by your graphic card)\n")); - break; - - case XINE_IMGFMT_YV12: - switch(this->yuv_format) { - case VIDEO_PALETTE_YUV422: - write_frame_YUV422(this, frame); - break; - case VIDEO_PALETTE_YUV420P2: - write_frame_YUV420P2(this, frame); - break; - case VIDEO_PALETTE_YUV420P3: - write_frame_YUV420P3(this, frame); - break; - default: - xprintf(this->xine, XINE_VERBOSITY_LOG, - _("video_out_syncfb: error. (YV12 not supported by your graphic card)\n")); - } - break; - - default: - xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_syncfb: error. (unknown frame format)\n"); - break; - } - - frame->vo_frame.free(&frame->vo_frame); -} - -static void free_framedata(syncfb_frame_t* frame) -{ -/* if(frame->data_mem[0]) { - free(frame->data_mem[0]); - frame->data_mem[0] = NULL; - } - - if(frame->data_mem[1]) { - free(frame->data_mem[1]); - frame->data_mem[1] = NULL; - } - - if(frame->data_mem[2]) { - free(frame->data_mem[2]); - frame->data_mem[2] = NULL; - }*/ - - if(frame->vo_frame.base[0]) { - free(frame->vo_frame.base[0]); - frame->vo_frame.base[0] = NULL; - } - - if(frame->vo_frame.base[1]) { - free(frame->vo_frame.base[1]); - frame->vo_frame.base[1] = NULL; - } - - if(frame->vo_frame.base[2]) { - free(frame->vo_frame.base[2]); - frame->vo_frame.base[2] = NULL; - } -} - -static void syncfb_clean_output_area(syncfb_driver_t* this) -{ - XLockDisplay (this->display); - - XSetForeground (this->display, this->gc, this->black.pixel); - - XFillRectangle(this->display, this->drawable, this->gc, - this->sc.gui_x, this->sc.gui_y, this->sc.gui_width, this->sc.gui_height); - - XUnlockDisplay (this->display); -} - - -static void syncfb_compute_ideal_size (syncfb_driver_t *this) -{ - _x_vo_scale_compute_ideal_size( &this->sc ); -} - -/* make ideal width/height "fit" into the gui */ -static void syncfb_compute_output_size(syncfb_driver_t *this) -{ - _x_vo_scale_compute_output_size( &this->sc ); - -#ifdef DEBUG_OUTPUT - printf("video_out_syncfb: debug. (frame source %d x %d, screen output %d x %d)\n", - this->sc.delivered_width, this->sc.delivered_height, - this->sc.output_width, this->sc.output_height); -#endif - - /* - * configuring SyncFB module from this point on. - */ - syncfb_overlay_off(this); - - /* sanity checking - certain situations *may* crash the SyncFB module, so - * take care that we always have valid numbers. - */ - if(this->sc.output_xoffset >= 0 && this->sc.output_yoffset >= 0 && - this->cur_frame->width > 0 && this->cur_frame->height > 0 && - this->sc.output_width > 0 && this->sc.output_height > 0 && - this->cur_frame->format > 0 && this->video_win_visibility) { - - if(ioctl(this->fd, SYNCFB_GET_CONFIG, &this->syncfb_config)) - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: error. (get_config ioctl failed)\n"); - - this->syncfb_config.syncfb_mode = SYNCFB_FEATURE_SCALE | SYNCFB_FEATURE_CROP; - - if(this->props[VO_PROP_INTERLACED].value) - this->syncfb_config.syncfb_mode |= SYNCFB_FEATURE_DEINTERLACE; - - switch(this->cur_frame->format) { - case XINE_IMGFMT_YV12: - this->syncfb_config.src_palette = this->yuv_format; - break; - case XINE_IMGFMT_YUY2: - this->syncfb_config.src_palette = VIDEO_PALETTE_YUV422; - break; - default: - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: error. (unknown frame format)\n"); - this->syncfb_config.src_palette = 0; - break; - } - - this->syncfb_config.fb_screen_size = this->virtual_screen_width * this->virtual_screen_height * (this->screen_depth / 8) * 2; - this->syncfb_config.src_width = this->cur_frame->width; - this->syncfb_config.src_height = this->cur_frame->height; - - this->syncfb_config.image_width = this->sc.output_width; - this->syncfb_config.image_height = this->sc.output_height; - - this->syncfb_config.image_xorg = this->sc.output_xoffset + this->sc.gui_win_x; - this->syncfb_config.image_yorg = this->sc.output_yoffset + this->sc.gui_win_y; - - this->syncfb_config.src_crop_top = this->sc.displayed_yoffset; - this->syncfb_config.src_crop_bot = (this->props[VO_PROP_INTERLACED].value && this->sc.displayed_yoffset == 0) ? 1 : this->sc.displayed_yoffset; - this->syncfb_config.src_crop_left = this->sc.displayed_xoffset; - this->syncfb_config.src_crop_right = this->sc.displayed_xoffset; - - this->syncfb_config.default_repeat = (this->props[VO_PROP_INTERLACED].value) ? 1 : this->default_repeat; - - if(this->capabilities.palettes & (1<<this->syncfb_config.src_palette)) { - if(ioctl(this->fd,SYNCFB_SET_CONFIG,&this->syncfb_config)) - xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_syncfb: error. (set_config ioctl failed)\n"); - - syncfb_overlay_on(this); - } - } -} - -/* - * public functions defined and used by the xine interface - */ - -static int syncfb_redraw_needed(vo_driver_t* this_gen) -{ - syncfb_driver_t* this = (syncfb_driver_t *) this_gen; - - int ret = 0; - - if( _x_vo_scale_redraw_needed( &this->sc ) ) { - - syncfb_compute_output_size (this); - - syncfb_clean_output_area (this); - - ret = 1; - } - - return ret; -} - -static uint32_t syncfb_get_capabilities (vo_driver_t *this_gen) -{ - syncfb_driver_t *this = (syncfb_driver_t *) this_gen; - - return this->supported_capabilities; -} - -static void syncfb_frame_field (vo_frame_t *vo_img, int which_field) -{ - /* not needed for SyncFB */ -} - -static void syncfb_frame_dispose(vo_frame_t* vo_img) -{ - syncfb_frame_t* frame = (syncfb_frame_t *) vo_img; - - if(frame) { - free_framedata(frame); - free(frame); - } -} - -static vo_frame_t* syncfb_alloc_frame(vo_driver_t* this_gen) -{ - /* syncfb_driver_t *this = (syncfb_driver_t *) this_gen; */ - syncfb_frame_t *frame; - - frame = (syncfb_frame_t *) xine_xmalloc(sizeof(syncfb_frame_t)); - if(!frame) - return NULL; - - pthread_mutex_init(&frame->vo_frame.mutex, NULL); - - frame->vo_frame.base[0] = NULL; - frame->vo_frame.base[1] = NULL; - frame->vo_frame.base[2] = NULL; - - /* - * supply required functions - */ - frame->vo_frame.proc_slice = NULL; - frame->vo_frame.proc_frame = NULL; - frame->vo_frame.field = syncfb_frame_field; - frame->vo_frame.dispose = syncfb_frame_dispose; - - frame->vo_frame.driver = this_gen; - - return (vo_frame_t *) frame; -} - -static void syncfb_update_frame_format(vo_driver_t* this_gen, - vo_frame_t* frame_gen, - uint32_t width, uint32_t height, - double ratio, int format, int flags) -{ - syncfb_driver_t *this = (syncfb_driver_t *) this_gen; - syncfb_frame_t *frame = (syncfb_frame_t *) frame_gen; - /* uint32_t frame_size = width*height; */ - - if((frame->width != width) - || (frame->height != height) - || (frame->format != format)) { - -#ifdef DEBUG_OUTPUT - printf("video_out_syncfb: debug. (update frame format: old values [width=%d, height=%d, format=%04x], new values [width=%d, height=%d, format=%04x])\n", frame->width, frame->height, frame->format, width, height, format); -#endif - free_framedata(frame); - - frame->width = width; - frame->height = height; - frame->format = format; - - switch(format) { - case XINE_IMGFMT_YV12: - frame->vo_frame.pitches[0] = 8*((width + 7) / 8); - frame->vo_frame.pitches[1] = 8*((width + 15) / 16); - frame->vo_frame.pitches[2] = 8*((width + 15) / 16); - frame->vo_frame.base[0] = malloc(frame->vo_frame.pitches[0] * height); - frame->vo_frame.base[1] = malloc(frame->vo_frame.pitches[1] * ((height+1)/2)); - frame->vo_frame.base[2] = malloc(frame->vo_frame.pitches[2] * ((height+1)/2)); - break; - case XINE_IMGFMT_YUY2: - frame->vo_frame.pitches[0] = 8*((width + 3) / 4); - frame->vo_frame.base[0] = malloc(frame->vo_frame.pitches[0] * height); - frame->vo_frame.base[1] = NULL; - frame->vo_frame.base[2] = NULL; - break; - default: - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: error. (unable to allocate " - "framedata because of unknown frame format: %04x)\n", format); - } - -/* if((format == IMGFMT_YV12 && (frame->data_mem[0] == NULL || frame->data_mem[1] == NULL || frame->data_mem[2] == NULL)) - || (format == IMGFMT_YUY2 && frame->data_mem[0] == NULL)) {*/ - if((format == XINE_IMGFMT_YV12 && (frame->vo_frame.base[0] == NULL || frame->vo_frame.base[1] == NULL || frame->vo_frame.base[2] == NULL)) - || (format == XINE_IMGFMT_YUY2 && frame->vo_frame.base[0] == NULL)) { - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: error. (framedata allocation failed: out of memory)\n"); - - free_framedata(frame); - } - } - - frame->ratio = ratio; -} - -static void syncfb_overlay_blend(vo_driver_t* this_gen, vo_frame_t* frame_gen, vo_overlay_t* overlay) -{ - syncfb_frame_t* frame = (syncfb_frame_t *) frame_gen; - syncfb_driver_t* this = (syncfb_driver_t *) this_gen; - - this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; - this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; - - /* alpha blend here */ - if (overlay->rle) { - if (frame->format == XINE_IMGFMT_YV12) - _x_blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); - else - _x_blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); - } -} - -static void syncfb_display_frame(vo_driver_t* this_gen, vo_frame_t* frame_gen) -{ - syncfb_driver_t* this = (syncfb_driver_t *) this_gen; - syncfb_frame_t* frame = (syncfb_frame_t *) frame_gen; - - this->cur_frame = frame; - - /* - * let's see if this frame is different in size / aspect - * ratio from the previous one - */ - if((frame->width != this->sc.delivered_width) - || (frame->height != this->sc.delivered_height) - || (frame->ratio != this->sc.delivered_ratio)) { -#ifdef DEBUG_OUTPUT - printf("video_out_syncfb: debug. (frame format changed)\n"); -#endif - - this->sc.delivered_width = frame->width; - this->sc.delivered_height = frame->height; - this->sc.delivered_ratio = frame->ratio; - - this->sc.crop_left = frame->vo_frame.crop_left; - this->sc.crop_right = frame->vo_frame.crop_right; - this->sc.crop_top = frame->vo_frame.crop_top; - this->sc.crop_bottom = frame->vo_frame.crop_bottom; - - syncfb_compute_ideal_size(this); - - this->sc.force_redraw = 1; - } - - /* - * tell gui that we are about to display a frame, - * ask for offset and output size - */ - syncfb_redraw_needed(this_gen); - - /* the rest is only successful and safe, if the overlay is really on */ - if(this->overlay_state) { - if(this->bufinfo.id != -1) { - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: error. (invalid syncfb image buffer state)\n"); - frame->vo_frame.free(&frame->vo_frame); - - return; - } - - if(ioctl(this->fd, SYNCFB_REQUEST_BUFFER, &this->bufinfo)) - xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_syncfb: error. (request ioctl failed)\n"); - - if(this->bufinfo.id == -1) { - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: error. (syncfb module couldn't allocate image buffer)\n"); - frame->vo_frame.free(&frame->vo_frame); - - /* - * there are several "fixable" situations when this request will fail. - * for example when the screen resolution changes, the kernel module - * will get confused - reinitializing everything will fix things for - * the next frame in that case. - */ - syncfb_compute_ideal_size(this); - syncfb_compute_output_size(this); - syncfb_clean_output_area(this); - - return; - } - - write_frame_sfb(this, frame); - - if(ioctl(this->fd, SYNCFB_COMMIT_BUFFER, &this->bufinfo)) - xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_syncfb: error. (commit ioctl failed)\n"); - } - else - frame->vo_frame.free(&frame->vo_frame); - - this->bufinfo.id = -1; -} - -static int syncfb_get_property(vo_driver_t* this_gen, int property) -{ - syncfb_driver_t* this = (syncfb_driver_t *) this_gen; - - switch (property) { - case VO_PROP_WINDOW_WIDTH: - this->props[property].value = this->sc.gui_width; - break; - case VO_PROP_WINDOW_HEIGHT: - this->props[property].value = this->sc.gui_height; - break; - case VO_PROP_OUTPUT_WIDTH: - this->props[property].value = this->sc.output_width; - break; - case VO_PROP_OUTPUT_HEIGHT: - this->props[property].value = this->sc.output_height; - break; - case VO_PROP_OUTPUT_XOFFSET: - this->props[property].value = this->sc.output_xoffset; - break; - case VO_PROP_OUTPUT_YOFFSET: - this->props[property].value = this->sc.output_yoffset; - break; - } - - return this->props[property].value; -} - -static int syncfb_set_property(vo_driver_t* this_gen, int property, int value) -{ - syncfb_driver_t* this = (syncfb_driver_t *) this_gen; - - switch (property) { - case VO_PROP_INTERLACED: - this->props[property].value = value; - -#ifdef DEBUG_OUTPUT - printf("video_out_syncfb: debug. (VO_PROP_INTERLACED(%d))\n", - this->props[property].value); -#endif - - syncfb_compute_ideal_size(this); - syncfb_compute_output_size(this); - syncfb_clean_output_area(this); - break; - - case VO_PROP_ASPECT_RATIO: - if(value >= XINE_VO_ASPECT_NUM_RATIOS) - value = XINE_VO_ASPECT_AUTO; - - this->props[property].value = value; - this->sc.user_ratio = value; - -#ifdef DEBUG_OUTPUT - printf("video_out_syncfb: debug. (VO_PROP_ASPECT_RATIO(%d))\n", - this->props[property].value); -#endif - - syncfb_compute_ideal_size(this); - syncfb_compute_output_size(this); - syncfb_clean_output_area(this); - break; - - case VO_PROP_ZOOM_X: - if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { - this->props[property].value = value; - this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; - - syncfb_compute_ideal_size (this); - - this->sc.force_redraw = 1; - } -/* - printf("video_out_syncfb: info. (the zooming feature is not supported at the moment because of a bug with the SyncFB kernel driver, please refer to README.syncfb)\n"); -*/ - break; - - case VO_PROP_ZOOM_Y: - if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { - this->props[property].value = value; - this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; - - syncfb_compute_ideal_size (this); - - this->sc.force_redraw = 1; - } -/* - printf("video_out_syncfb: info. (the zooming feature is not supported at the moment because of a bug with the SyncFB kernel driver, please refer to README.syncfb)\n"); -*/ - break; - - case VO_PROP_CONTRAST: - this->props[property].value = value; - -#ifdef DEBUG_OUTPUT - printf("video_out_syncfb: debug. (VO_PROP_CONTRAST(%d))\n", - this->props[property].value); -#endif - - this->params.contrast = value; - this->params.brightness = this->props[VO_PROP_BRIGHTNESS].value; - this->params.image_width = this->syncfb_config.image_width; /* FIXME */ - this->params.image_height = this->syncfb_config.image_height; - this->params.image_xorg = this->syncfb_config.image_xorg; - this->params.image_yorg = this->syncfb_config.image_yorg; - - if(ioctl(this->fd,SYNCFB_SET_PARAMS,&this->params)) - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: error. (setting of contrast value failed)\n"); - - break; - - case VO_PROP_BRIGHTNESS: - this->props[property].value = value; - -#ifdef DEBUG_OUTPUT - printf("video_out_syncfb: debug. (VO_PROP_BRIGHTNESS(%d))\n", - this->props[property].value); -#endif - - this->params.brightness = value; - this->params.contrast = this->props[VO_PROP_CONTRAST].value; - this->params.image_width = this->syncfb_config.image_width; /* FIXME */ - this->params.image_height = this->syncfb_config.image_height; - this->params.image_xorg = this->syncfb_config.image_xorg; - this->params.image_yorg = this->syncfb_config.image_yorg; - - if(ioctl(this->fd,SYNCFB_SET_PARAMS,&this->params)) - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: error. (setting of brightness value failed)\n"); - - break; - } - - return value; -} - -static void syncfb_get_property_min_max(vo_driver_t *this_gen, - int property, int *min, int *max) -{ - syncfb_driver_t* this = (syncfb_driver_t *) this_gen; - - *min = this->props[property].min; - *max = this->props[property].max; -} - -static int syncfb_gui_data_exchange(vo_driver_t* this_gen, int data_type, - void *data) -{ - syncfb_driver_t* this = (syncfb_driver_t *) this_gen; - - switch (data_type) { - case XINE_GUI_SEND_DRAWABLE_CHANGED: - this->drawable = (Drawable) data; - - XLockDisplay (this->display); - XFreeGC(this->display, this->gc); - this->gc = XCreateGC (this->display, this->drawable, 0, NULL); - XUnlockDisplay (this->display); - break; - case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: - { - int x1, y1, x2, y2; - x11_rectangle_t *rect = data; - - _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, - &x1, &y1); - _x_vo_scale_translate_gui2video(&this->sc, 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; - /* - case XINE_GUI_DATA_EX_VIDEOWIN_VISIBLE: - this->video_win_visibility = (int)(int *)data; - syncfb_compute_output_size(this); - break; - */ - - default: - return -1; - } - - return 0; -} - -static void syncfb_dispose(vo_driver_t *this_gen) -{ - syncfb_driver_t *this = (syncfb_driver_t *) this_gen; - - /* get it off the screen - I wanna see my desktop again :-) */ - syncfb_overlay_off(this); - - /* don't know if it is necessary are even right, but anyway...?! */ - munmap(0, this->capabilities.memory_size); - - close(this->fd); - - XLockDisplay (this->display); - XFreeGC(this->display, this->gc); - XUnlockDisplay (this->display); - - _x_alphablend_free(&this->alphablend_extra_data); - - free(this); -} - -static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { - - syncfb_class_t *class = (syncfb_class_t *) class_gen; - config_values_t *config = class->config; - syncfb_driver_t* this; - Display* display = NULL; - unsigned int i; - x11_visual_t* visual = (x11_visual_t *) visual_gen; - XColor dummy; - XWindowAttributes attr; - - display = visual->display; - - if(!(this = xine_xmalloc(sizeof (syncfb_driver_t)))) - return NULL; - - _x_alphablend_init(&this->alphablend_extra_data, class->xine); - - /* check for syncfb device */ - if((this->fd = open(class->device_name, O_RDWR)) < 0) { - xprintf(class->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: aborting. (unable to open syncfb device \"%s\")\n", class->device_name); - free(this); - return NULL; - } - - this->xine = class->xine; - - /* get capabilities from the syncfb module */ - if(ioctl(this->fd, SYNCFB_GET_CAPS, &this->capabilities)) { - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: aborting. (syncfb_get_caps ioctl failed)\n"); - - close(this->fd); - free(this); - - return NULL; - } - - /* mmap whole video memory */ - this->video_mem = (uint8_t *) mmap(0, this->capabilities.memory_size, PROT_WRITE, MAP_SHARED, this->fd, 0); - - if(this->video_mem == MAP_FAILED) { - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: aborting. (mmap of video memory failed)\n"); - - close(this->fd); - free(this); - - return NULL; - } - - /* - * init properties and capabilities - */ - for (i = 0; i<VO_NUM_PROPERTIES; i++) { - this->props[i].value = 0; - this->props[i].min = 0; - this->props[i].max = 0; - } - - this->props[VO_PROP_INTERLACED].value = 0; - this->sc.user_ratio = this->props[VO_PROP_ASPECT_RATIO].value = XINE_VO_ASPECT_AUTO; - this->props[VO_PROP_ZOOM_X].value = 100; - this->props[VO_PROP_ZOOM_Y].value = 100; - - /* check for formats we need... */ - this->supported_capabilities = VO_CAP_CROP; - this->yuv_format = 0; - - /* - * simple fallback mechanism - we want YUV 4:2:0 (3 plane) but we can also - * convert YV12 material to YUV 4:2:0 (2 plane) and YUV 4:2:2 ... - */ - if(this->capabilities.palettes & (1<<VIDEO_PALETTE_YUV420P3)) { - this->supported_capabilities |= VO_CAP_YV12; - this->yuv_format = VIDEO_PALETTE_YUV420P3; - xprintf(this->xine, XINE_VERBOSITY_LOG, - _("video_out_syncfb: info. (SyncFB module supports YUV 4:2:0 (3 plane))\n")); - } else if(this->capabilities.palettes & (1<<VIDEO_PALETTE_YUV420P2)) { - this->supported_capabilities |= VO_CAP_YV12; - this->yuv_format = VIDEO_PALETTE_YUV420P2; - xprintf(this->xine, XINE_VERBOSITY_LOG, - _("video_out_syncfb: info. (SyncFB module supports YUV 4:2:0 (2 plane))\n")); - } else if(this->capabilities.palettes & (1<<VIDEO_PALETTE_YUV422)) { - this->supported_capabilities |= VO_CAP_YV12; - this->yuv_format = VIDEO_PALETTE_YUV422; - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - _("video_out_syncfb: info. (SyncFB module supports YUV 4:2:2)\n")); - } - - if(this->capabilities.palettes & (1<<VIDEO_PALETTE_YUV422)) { - this->supported_capabilities |= VO_CAP_YUY2; - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - _("video_out_syncfb: info. (SyncFB module supports YUY2)\n")); - } - if(this->capabilities.palettes & (1<<VIDEO_PALETTE_RGB565)) { - /* FIXME: no RGB support yet - * this->supported_capabilities |= VO_CAP_RGB; - */ - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - _("video_out_syncfb: info. (SyncFB module supports RGB565)\n")); - } - - if(!this->supported_capabilities) { - xprintf(this->xine, XINE_VERBOSITY_DEBUG, - _("video_out_syncfb: aborting. (SyncFB module does not support YV12, YUY2 nor RGB565)\n")); - - munmap(0, this->capabilities.memory_size); - close(this->fd); - free(this); - - return NULL; - } - - if(ioctl(this->fd,SYNCFB_GET_PARAMS,&this->params) == 0) { - this->props[VO_PROP_CONTRAST].value = this->params.contrast; - this->props[VO_PROP_CONTRAST].min = 0; - this->props[VO_PROP_CONTRAST].max = 255; - - this->props[VO_PROP_BRIGHTNESS].value = this->params.brightness; - this->props[VO_PROP_BRIGHTNESS].min = -128; - this->props[VO_PROP_BRIGHTNESS].max = 127; - } else { - xprintf(this->xine, XINE_VERBOSITY_LOG, - _("video_out_syncfb: info. (brightness/contrast control won\'t be available because " - "your SyncFB kernel module seems to be outdated. Please refer to README." - "syncfb for informations on how to update it.)\n")); - } - - /* check for virtual screen size and screen depth - this is rather important - because that data is later used for free memory calculation */ - XGetWindowAttributes(visual->display, DefaultRootWindow(visual->display), &attr); - - this->virtual_screen_height = attr.height; - this->virtual_screen_width = attr.width; - this->screen_depth = attr.depth; - - /* initialize the rest of the variables now with default values */ - this->bufinfo.id = -1; - this->config = config; - this->cur_frame = NULL; - - /* FIXME: setting the default_repeat to anything higher than 1 will result - in a distorted video, so for now, set this manually to 0 until - the kernel driver is fixed... */ -#if 0 - this->default_repeat = config->register_range(config, - "video.device.syncfb_default_repeat", 3, 1, 4, - _("default number of frame repetitions"), - _("This specifies how many times a single video " - "frame will be displayed consecutively."), - 10, NULL, NULL); -#endif - this->default_repeat = 0; - - this->display = visual->display; - this->drawable = visual->d; - this->gc = XCreateGC (this->display, this->drawable, 0, NULL); - - _x_vo_scale_init (&this->sc, 1, 0, config ); - this->sc.frame_output_cb = visual->frame_output_cb; - this->sc.user_data = visual->user_data; - - this->overlay = NULL; - this->screen = visual->screen; - this->video_win_visibility = 1; - - XAllocNamedColor(this->display, - DefaultColormap(this->display, this->screen), - "black", &this->black, &dummy); - - this->vo_driver.get_capabilities = syncfb_get_capabilities; - this->vo_driver.alloc_frame = syncfb_alloc_frame; - this->vo_driver.update_frame_format = syncfb_update_frame_format; - this->vo_driver.overlay_begin = NULL; /* not used */ - this->vo_driver.overlay_blend = syncfb_overlay_blend; - this->vo_driver.overlay_end = NULL; /* not used */ - this->vo_driver.display_frame = syncfb_display_frame; - this->vo_driver.get_property = syncfb_get_property; - this->vo_driver.set_property = syncfb_set_property; - this->vo_driver.get_property_min_max = syncfb_get_property_min_max; - this->vo_driver.gui_data_exchange = syncfb_gui_data_exchange; - this->vo_driver.dispose = syncfb_dispose; - this->vo_driver.redraw_needed = syncfb_redraw_needed; - - return &this->vo_driver; -} - -/* - * class functions - */ -static void *init_class (xine_t *xine, void *visual_gen) { - - syncfb_class_t *this; - char* device_name; - int fd; - - device_name = xine->config->register_filename(xine->config, "video.device.syncfb_device", "/dev/syncfb", - XINE_CONFIG_STRING_IS_DEVICE_NAME, - _("SyncFB device name"), - _("Specifies the file name for the SyncFB (TeleTux) device " - "to be used.\nThis setting is security critical, " - "because when changed to a different file, xine " - "can be used to fill this file with arbitrary content. " - "So you should be careful that the value you enter " - "really is a proper framebuffer device."), - XINE_CONFIG_SECURITY, NULL, NULL); - - /* check for syncfb device */ - if((fd = open(device_name, O_RDWR)) < 0) { - xprintf(xine, XINE_VERBOSITY_DEBUG, - "video_out_syncfb: aborting. (unable to open syncfb device \"%s\")\n", device_name); - return NULL; - } - close(fd); - - /* - * from this point on, nothing should go wrong anymore - */ - this = (syncfb_class_t *) xine_xmalloc (sizeof (syncfb_class_t)); - - this->driver_class.open_plugin = open_plugin; - this->driver_class.identifier = "SyncFB"; - this->driver_class.description = N_("xine video output plugin using the SyncFB module for Matrox G200/G400 cards"); - this->driver_class.dispose = default_video_driver_class_dispose; - - this->config = xine->config; - this->xine = xine; - this->device_name = device_name; - - return this; -} - -static const vo_info_t vo_info_syncfb = { - 7, /* priority */ - XINE_VISUAL_TYPE_X11 /* visual type */ -}; - -/* - * exported plugin catalog entry - */ - -const plugin_info_t xine_plugin_info[] EXPORTED = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_OUT, 22, "SyncFB", XINE_VERSION_CODE, &vo_info_syncfb, init_class }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; - diff --git a/src/video_out/video_out_syncfb.h b/src/video_out/video_out_syncfb.h deleted file mode 100644 index 1fc3df83a..000000000 --- a/src/video_out/video_out_syncfb.h +++ /dev/null @@ -1,236 +0,0 @@ -#ifndef __LINUX_SYNCFB_H -#define __LINUX_SYNCFB_H - -#ifdef __KERNEL__ -#include <linux/version.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/malloc.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/videodev.h> - -#include <asm/mtrr.h> -#include <asm/uaccess.h> -#include <asm/system.h> -#include <asm/io.h> - -#define TRUE 1 -#define FALSE 0 - -#define SFB_STATUS_FREE 0 -#define SFB_STATUS_OFFS 1 -#define SFB_STATUS_WAIT 2 -#define SFB_STATUS_LIVE 3 - -#endif /* KERNEL */ - - -#ifndef AARONS_TYPES -typedef unsigned long uint_32; -typedef unsigned char uint_8; -#endif - -#define SYNCFB_MAJOR 178 - -#define SYNCFB_ERROR_NO_ERROR 0; -#define SYNCFB_ERROR_NO_BUFFER_AVAILABLE 1; -#define SYNCFB_ERROR_PALETTE_NOT_SUPPORTED 2; -#define SYNCFB_ERROR_NOT_ENOUGH_MEMORY 3; - - - -#ifndef __LINUX_VIDEODEV_H -#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ -#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ -#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ -#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ -#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ -#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ -#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ -#define VIDEO_PALETTE_YUYV 8 -#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ -#define VIDEO_PALETTE_YUV420 10 -#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ -#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ -#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ -#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ -#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ -#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ -#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ -#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ -#endif - - -#define VIDEO_PALETTE_YUV422P3 13 /* YUV 4:2:2 Planar (3 Plane, same as YUV422P) */ -#define VIDEO_PALETTE_YUV422P2 17 /* YUV 4:2:2 Planar (2 Plane) */ - -#define VIDEO_PALETTE_YUV411P3 14 /* YUV 4:1:1 Planar (3 Plane, same as YUV411P) */ -#define VIDEO_PALETTE_YUV411P2 18 /* YUV 4:1:1 Planar (2 Plane) */ - -#define VIDEO_PALETTE_YUV420P3 15 /* YUV 4:2:0 Planar (3 Plane, same as YUV420P) */ -#define VIDEO_PALETTE_YUV420P2 19 /* YUV 4:2:0 Planar (2 Plane) */ - -#define VIDEO_PALETTE_YUV410P3 16 /* YUV 4:1:0 Planar (3 Plane, same as YUV410P) */ -#define VIDEO_PALETTE_YUV410P2 20 /* YUV 4:1:0 Planar (2 Plane) */ - - - -#define SYNCFB_FEATURE_SCALE_H 1 -#define SYNCFB_FEATURE_SCALE_V 2 -#define SYNCFB_FEATURE_SCALE 3 -#define SYNCFB_FEATURE_CROP 4 -#define SYNCFB_FEATURE_OFFSET 8 -#define SYNCFB_FEATURE_DEINTERLACE 16 -#define SYNCFB_FEATURE_PROCAMP 32 -#define SYNCFB_FEATURE_TRANSITIONS 64 -#define SYNCFB_FEATURE_COLKEY 128 -#define SYNCFB_FEATURE_MIRROR_H 256 -#define SYNCFB_FEATURE_MIRROR_V 512 -#define SYNCFB_FEATURE_BLOCK_REQUEST 1024 -#define SYNCFB_FEATURE_FREQDIV2 2048 - - -typedef struct syncfb_config_s -{ - uint_32 syncfb_mode; /* bitfield: turn on/off the available features */ - uint_32 error_code; /* RO: returns 0 on successful config calls, error code otherwise */ - - uint_32 fb_screen_size; /* WO, size in bytes of video memory reserved for fbdev */ - uint_32 fb_screen_width; /* WO, visible screen width in pixel */ - uint_32 fb_screen_height; /* WO, visible screen height in pixel */ - - uint_32 buffers; /* RO, number of available buffers */ - uint_32 buffer_size; /* RO, filled in by syncfb */ - - uint_32 default_repeat; /* default repeat time for a single frame, can be overridden in syncfb_buffer_info_t */ - - uint_32 src_width; /* source image width in pixel */ - uint_32 src_height; /* source image height in pixel */ - uint_32 src_palette; /* set palette mode, see videodev.h for palettes */ - uint_32 src_pitch; /* RO: filled in by ioctl: actual line length in pixel */ - - uint_32 image_xorg; /* x position of the image on the screen */ - uint_32 image_yorg; /* y position of the image on the screen */ - - /* if syncfb has FEATURE_SCALE */ - uint_32 scale_filters; /* 0: no filtering, 255: all filters on */ - uint_32 image_width; /* onscreen image width */ - uint_32 image_height; /* onscreen image height */ - - /* if syncfb has FEATURE_CROP */ - uint_32 src_crop_left; /* */ - uint_32 src_crop_right; /* */ - uint_32 src_crop_top; /* */ - uint_32 src_crop_bot; /* */ - - /* if syncfb has FEATURE_OFFSET */ - uint_32 image_offset_left; /* */ - uint_32 image_offset_right; /* */ - uint_32 image_offset_top; /* */ - uint_32 image_offset_bot; /* */ - - /* if syncfb has FEATURE_COLKEY */ - uint_8 colkey_red; - uint_8 colkey_green; - uint_8 colkey_blue; - -} syncfb_config_t; - - -/* - picture parameters, -*/ -typedef struct syncfb_param_s -{ - /* the idea is to enable smooth transitions between eg. image sizes (not yet implemented) */ - /* if syncfb has FEATURE_TRANSITIONS */ - uint_32 transition_time; - - /* if syncfb has FEATURE_PROCAMP */ - uint_32 contrast; /* 0: least contrast, 1000: normal contrast, */ - uint_32 brightness; - uint_32 color; /* for syncfb_matrox: color=0: b/w else: full color */ - - /* if syncfb has FEATURE_SCALE , currently only supported in CONFIG call */ - uint_8 scale_filters; /* 0: no filtering, 255: all filters on */ - uint_32 image_xorg; /* x position of the image on the screen */ - uint_32 image_yorg; /* y position of the image on the screen */ - uint_32 image_width; /* onscreen image width */ - uint_32 image_height; /* onscreen image height */ - -} syncfb_param_t; - - - -typedef struct syncfb_status_info_s -{ - uint_32 field_cnt; /* basically all vbi's since the start of syncfb */ - uint_32 frame_cnt; /* number of frames comitted & output */ - - uint_32 hold_field_cnt; /* number of repeated fields becaus no new data was available */ - uint_32 skip_field_cnt; /* skipped fields when fifo was about to fill up */ - - uint_32 request_frames; /* number of request_buffer calls */ - uint_32 commit_frames; /* number of commit_buffer calls */ - - uint_32 failed_requests; /* number of calls to request_buffer that failed */ - - uint_32 buffers_waiting; - uint_32 buffers_free; - -} syncfb_status_info_t; - - - - -typedef struct syncfb_capability_s -{ - char name[64]; /* A name for the syncfb ... */ - uint_32 palettes; /* supported palettes - see videodev.h for palettes, test the corresponding bit here */ - uint_32 features; /* supported features - see SYNCFB_FEATURE_* */ - uint_32 memory_size; /* total size of mappable video memory */ - -} syncfb_capability_t; - - - -typedef struct syncfb_buffer_info_s -{ - int id; /* buffer id: a return value of -1 means no buffer available */ - uint_32 repeat; /* the buffer will be shown <repeat> times */ - uint_32 offset; /* buffer offset from start of video memory */ - uint_32 offset_p2; /* yuv plane 2 buffer offset from start of video memory */ - uint_32 offset_p3; /* yuv plane 3 buffer offset from start of video memory */ - -} syncfb_buffer_info_t; - - - - - - - -/* get syncfb capabilities */ -#define SYNCFB_GET_CAPS _IOR('J', 1, syncfb_config_t) - -#define SYNCFB_GET_CONFIG _IOR('J', 2, syncfb_config_t) -#define SYNCFB_SET_CONFIG _IOR('J', 3, syncfb_config_t) -#define SYNCFB_ON _IO ('J', 4) -#define SYNCFB_OFF _IO ('J', 5) -#define SYNCFB_REQUEST_BUFFER _IOR ('J', 6, syncfb_buffer_info_t) -#define SYNCFB_COMMIT_BUFFER _IOR ('J', 7, syncfb_buffer_info_t) -#define SYNCFB_STATUS _IOR ('J', 8, syncfb_status_info_t) -#define SYNCFB_VBI _IO ('J', 9) /* simulate interrupt - debugging only */ -#define SYNCFB_SET_PARAMS _IOR('J', 10, syncfb_param_t) -#define SYNCFB_GET_PARAMS _IOR('J', 11, syncfb_param_t) - - - - -#endif /* __LINUX_SYNCFB_H */ - diff --git a/src/video_out/video_out_vidix.c b/src/video_out/video_out_vidix.c index f4b74ad2a..586268513 100644 --- a/src/video_out/video_out_vidix.c +++ b/src/video_out/video_out_vidix.c @@ -964,7 +964,7 @@ static vidix_driver_t *open_plugin (video_driver_class_t *class_gen) { this->config = config; this->got_frame_data = 0; - this->capabilities = VO_CAP_CROP; + this->capabilities = VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; /* Find what equalizer flags are supported */ if(this->vidix_cap.flags & FLAG_EQUALIZER) { @@ -973,24 +973,28 @@ static vidix_driver_t *open_plugin (video_driver_class_t *class_gen) { "video_out_vidix: couldn't get equalizer capabilities: %s\n", strerror(err)); } else { if(this->vidix_eq.cap & VEQ_CAP_BRIGHTNESS) { + this->capabilities |= VO_CAP_BRIGHTNESS; this->props[VO_PROP_BRIGHTNESS].value = 0; this->props[VO_PROP_BRIGHTNESS].min = -1000; this->props[VO_PROP_BRIGHTNESS].max = 1000; } if(this->vidix_eq.cap & VEQ_CAP_CONTRAST) { + this->capabilities |= VO_CAP_CONTRAST; this->props[VO_PROP_CONTRAST].value = 0; this->props[VO_PROP_CONTRAST].min = -1000; this->props[VO_PROP_CONTRAST].max = 1000; } if(this->vidix_eq.cap & VEQ_CAP_SATURATION) { + this->capabilities |= VO_CAP_SATURATION; this->props[VO_PROP_SATURATION].value = 0; this->props[VO_PROP_SATURATION].min = -1000; this->props[VO_PROP_SATURATION].max = 1000; } if(this->vidix_eq.cap & VEQ_CAP_HUE) { + this->capabilities |= VO_CAP_HUE; this->props[VO_PROP_HUE].value = 0; this->props[VO_PROP_HUE].min = -1000; this->props[VO_PROP_HUE].max = 1000; diff --git a/src/video_out/video_out_xcbshm.c b/src/video_out/video_out_xcbshm.c index e8fd33860..7443529d1 100644 --- a/src/video_out/video_out_xcbshm.c +++ b/src/video_out/video_out_xcbshm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2003, 2007 the xine project + * Copyright (C) 2000-2003, 2007-2008 the xine project * * This file is part of xine, a free video player. * @@ -222,7 +222,7 @@ static void dispose_ximage(xshm_driver_t *this, xshm_frame_t *frame) static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) { xshm_driver_t *this = (xshm_driver_t *) this_gen; - uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2; + uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST | VO_CAP_SATURATION; if( this->xoverlay ) capabilities |= VO_CAP_UNSCALED_OVERLAY; @@ -740,45 +740,43 @@ static int xshm_set_property (vo_driver_t *this_gen, int property, int value) { xshm_driver_t *this = (xshm_driver_t *) this_gen; - if ( property == VO_PROP_ASPECT_RATIO) { - + switch (property) { + case VO_PROP_ASPECT_RATIO: if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->sc.user_ratio = value; xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name_table[value]); + break; - } else if (property == VO_PROP_BRIGHTNESS) { - + case VO_PROP_BRIGHTNESS: this->yuv2rgb_brightness = value; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, this->yuv2rgb_saturation); - this->sc.force_redraw = 1; + break; - } else if (property == VO_PROP_CONTRAST) { - + case VO_PROP_CONTRAST: this->yuv2rgb_contrast = value; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, this->yuv2rgb_saturation); - this->sc.force_redraw = 1; + break; - } else if (property == VO_PROP_SATURATION) { - + case VO_PROP_SATURATION: this->yuv2rgb_saturation = value; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, this->yuv2rgb_saturation); - this->sc.force_redraw = 1; + break; - } else { + default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": tried to set unsupported property %d\n", property); } diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c index 19a387732..d77917a70 100644 --- a/src/video_out/video_out_xcbxv.c +++ b/src/video_out/video_out_xcbxv.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2004, 2007 the xine project + * Copyright (C) 2000-2004, 2007-2008 the xine project * * This file is part of xine, a free video player. * @@ -64,6 +64,7 @@ #include <xine/xineutils.h> #include <xine/vo_scale.h> #include "xcbosd.h" +#include "xv_common.h" typedef struct xv_driver_s xv_driver_t; @@ -944,6 +945,8 @@ static int xv_check_yv12(xcb_connection_t *connection, xcb_xv_port_t port) { list_formats_cookie = xcb_xv_list_image_formats(connection, port); list_formats_reply = xcb_xv_list_image_formats_reply(connection, list_formats_cookie, NULL); + if (!list_formats_reply) + return 1; /* no formats listed; probably due to an invalid port no. */ format_it = xcb_xv_list_image_formats_format_iterator(list_formats_reply); for (; format_it.rem; xcb_xv_image_format_info_next(&format_it)) @@ -965,7 +968,7 @@ static void xv_check_capability (xv_driver_t *this, char *config_help) { int int_default; cfg_entry_t *entry; - char *str_prop = xcb_xv_attribute_info_name(attr); + const char *str_prop = xcb_xv_attribute_info_name(attr); xcb_xv_get_port_attribute_cookie_t get_attribute_cookie; xcb_xv_get_port_attribute_reply_t *get_attribute_reply; @@ -1083,19 +1086,87 @@ static void xv_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) LOG_MODULE ": double buffering mode = %d\n", xv_double_buffer); } +static void xv_update_XV_SYNC_TO_VBLANK(void *this_gen, xine_cfg_entry_t *entry) { + xv_driver_t *this = (xv_driver_t *) this_gen; + int xv_sync_to_vblank; + + xcb_intern_atom_cookie_t atom_cookie; + xcb_intern_atom_reply_t *atom_reply; + + xv_sync_to_vblank = entry->num_value; + + pthread_mutex_lock(&this->main_mutex); + atom_cookie = xcb_intern_atom(this->connection, 0, sizeof("XV_SYNC_TO_VBLANK"), "XV_SYNC_TO_VBLANK"); + atom_reply = xcb_intern_atom_reply(this->connection, atom_cookie, NULL); + xcb_xv_set_port_attribute(this->connection, this->xv_port, atom_reply->atom, xv_sync_to_vblank); + free(atom_reply); + pthread_mutex_unlock(&this->main_mutex); + + xprintf(this->xine, XINE_VERBOSITY_DEBUG, + "video_out_xcbxv: sync to vblank = %d\n", xv_sync_to_vblank); +} + + static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) { xv_driver_t *this = (xv_driver_t *) this_gen; this->use_pitch_alignment = entry->num_value; } +static xcb_xv_port_t xv_open_port (xv_driver_t *this, xcb_xv_port_t port) { + xcb_xv_grab_port_cookie_t grab_port_cookie; + xcb_xv_grab_port_reply_t *grab_port_reply; + + if (xv_check_yv12 (this->connection, port)) + return 0; + + grab_port_cookie = xcb_xv_grab_port (this->connection, port, XCB_CURRENT_TIME); + grab_port_reply = xcb_xv_grab_port_reply (this->connection, grab_port_cookie, NULL); + + if (grab_port_reply && (grab_port_reply->result == XCB_GRAB_STATUS_SUCCESS)) + { + free (grab_port_reply); + return port; + } + free (grab_port_reply); + return 0; +} + +static xcb_xv_adaptor_info_iterator_t * +xv_find_adaptor_by_port (int port, xcb_xv_adaptor_info_iterator_t *adaptor_it) +{ + for (; adaptor_it->rem; xcb_xv_adaptor_info_next(adaptor_it)) + if (adaptor_it->data->type & XCB_XV_TYPE_IMAGE_MASK) + if (port >= adaptor_it->data->base_id && + port < adaptor_it->data->base_id + adaptor_it->data->num_ports) + return adaptor_it; + return NULL; /* shouldn't happen */ +} + +static xcb_xv_port_t xv_autodetect_port(xv_driver_t *this, + xcb_xv_adaptor_info_iterator_t *adaptor_it, + xcb_xv_port_t base) +{ + for (; adaptor_it->rem; xcb_xv_adaptor_info_next(adaptor_it)) + if (adaptor_it->data->type & XCB_XV_TYPE_IMAGE_MASK) + { + int j; + for (j = 0; j < adaptor_it->data->num_ports; ++j) + { + xcb_xv_port_t port = adaptor_it->data->base_id + j; + if (port >= base && xv_open_port (this, port)) + return port; + } + } + return 0; +} + static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *visual_gen) { xv_class_t *class = (xv_class_t *) class_gen; config_values_t *config = class->config; xv_driver_t *this; int i; xcb_visual_t *visual = (xcb_visual_t *) visual_gen; - unsigned int j; xcb_xv_port_t xv_port; const xcb_query_extension_reply_t *query_extension_reply; @@ -1146,28 +1217,21 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis } adaptor_it = xcb_xv_query_adaptors_info_iterator(query_adaptors_reply); - - xv_port = 0; - - for (; adaptor_it.rem && !xv_port; xcb_xv_adaptor_info_next(&adaptor_it)) { - - if (adaptor_it.data->type & XCB_XV_TYPE_IMAGE_MASK) { - - for (j = 0; j < adaptor_it.data->num_ports; j++) - if (!xv_check_yv12(this->connection, adaptor_it.data->base_id + j)) { - xcb_xv_grab_port_cookie_t grab_port_cookie; - xcb_xv_grab_port_reply_t *grab_port_reply; - grab_port_cookie = xcb_xv_grab_port(this->connection, adaptor_it.data->base_id + j, XCB_CURRENT_TIME); - grab_port_reply = xcb_xv_grab_port_reply(this->connection, grab_port_cookie, NULL); - if (grab_port_reply && (grab_port_reply->result == XCB_GRAB_STATUS_SUCCESS)) { - free(grab_port_reply); - xv_port = adaptor_it.data->base_id + j; - break; - } - free(grab_port_reply); - } - } + xv_port = config->register_num (config, "video.device.xv_port", 0, + VIDEO_DEVICE_XV_PORT_HELP, + 10, NULL, NULL); + + if (xv_port != 0) { + if (! xv_open_port(this, xv_port)) { + xprintf(class->xine, XINE_VERBOSITY_NONE, + _("%s: could not open Xv port %d - autodetecting\n"), + LOG_MODULE, xv_port); + xv_port = xv_autodetect_port (this, &adaptor_it, xv_port); + } else + xv_find_adaptor_by_port (xv_port, &adaptor_it); } + if (!xv_port) + xv_port = xv_autodetect_port (this, &adaptor_it, 0); if (!xv_port) { xprintf(class->xine, XINE_VERBOSITY_LOG, @@ -1192,7 +1256,7 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis this->gc = xcb_generate_id(this->connection); xcb_create_gc(this->connection, this->gc, this->window, 0, NULL); - this->capabilities = VO_CAP_CROP; + this->capabilities = VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; this->use_shm = 1; this->use_colorkey = 0; this->colorkey = 0; @@ -1245,75 +1309,72 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis for (; attribute_it.rem; xcb_xv_attribute_info_next(&attribute_it)) { if ((attribute_it.data->flags & XCB_XV_ATTRIBUTE_FLAG_SETTABLE) && (attribute_it.data->flags & XCB_XV_ATTRIBUTE_FLAG_GETTABLE)) { + const char *const name = xcb_xv_attribute_info_name(attribute_it.data); /* store initial port attribute value */ - xv_store_port_attribute(this, xcb_xv_attribute_info_name(attribute_it.data)); - - if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_HUE")) { + xv_store_port_attribute(this, name); + + if(!strcmp(name, "XV_HUE")) { if (!strncmp(xcb_xv_adaptor_info_name(adaptor_it.data), "NV", 2)) { xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards\n"); } else { + this->capabilities |= VO_CAP_HUE; xv_check_capability (this, VO_PROP_HUE, attribute_it.data, adaptor_it.data->base_id, NULL, NULL, NULL); } - } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_SATURATION")) { + } else if(!strcmp(name, "XV_SATURATION")) { + this->capabilities |= VO_CAP_SATURATION; xv_check_capability (this, VO_PROP_SATURATION, attribute_it.data, adaptor_it.data->base_id, NULL, NULL, NULL); - - } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_BRIGHTNESS")) { + } else if(!strcmp(name, "XV_BRIGHTNESS")) { + this->capabilities |= VO_CAP_BRIGHTNESS; xv_check_capability (this, VO_PROP_BRIGHTNESS, attribute_it.data, adaptor_it.data->base_id, NULL, NULL, NULL); - - } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_CONTRAST")) { + } else if(!strcmp(name, "XV_CONTRAST")) { + this->capabilities |= VO_CAP_CONTRAST; xv_check_capability (this, VO_PROP_CONTRAST, attribute_it.data, adaptor_it.data->base_id, NULL, NULL, NULL); - - } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_COLORKEY")) { + } else if(!strcmp(name, "XV_COLORKEY")) { + this->capabilities |= VO_CAP_COLORKEY; xv_check_capability (this, VO_PROP_COLORKEY, attribute_it.data, adaptor_it.data->base_id, "video.device.xv_colorkey", - _("video overlay colour key"), - _("The colour key is used to tell the graphics card where to " - "overlay the video image. Try different values, if you experience " - "windows becoming transparent.")); - - } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_AUTOPAINT_COLORKEY")) { + VIDEO_DEVICE_XV_COLORKEY_HELP); + } else if(!strcmp(name, "XV_AUTOPAINT_COLORKEY")) { + this->capabilities |= VO_CAP_AUTOPAINT_COLORKEY; xv_check_capability (this, VO_PROP_AUTOPAINT_COLORKEY, attribute_it.data, adaptor_it.data->base_id, "video.device.xv_autopaint_colorkey", - _("autopaint colour key"), - _("Make Xv autopaint its colour key.")); - - } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_FILTER")) { + VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP); + } else if(!strcmp(name, "XV_FILTER")) { int xv_filter; /* This setting is specific to Permedia 2/3 cards. */ xv_filter = config->register_range (config, "video.device.xv_filter", 0, attribute_it.data->min, attribute_it.data->max, - _("bilinear scaling mode"), - _("Selects the bilinear scaling mode for Permedia cards. " - "The individual values are:\n\n" - "Permedia 2\n" - "0 - disable bilinear filtering\n" - "1 - enable bilinear filtering\n\n" - "Permedia 3\n" - "0 - disable bilinear filtering\n" - "1 - horizontal linear filtering\n" - "2 - enable full bilinear filtering"), + VIDEO_DEVICE_XV_FILTER_HELP, 20, xv_update_XV_FILTER, this); config->update_num(config,"video.device.xv_filter",xv_filter); - } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_DOUBLE_BUFFER")) { - int xv_double_buffer; - xv_double_buffer = + } else if(!strcmp(name, "XV_DOUBLE_BUFFER")) { + int xv_double_buffer = config->register_bool (config, "video.device.xv_double_buffer", 1, - _("enable double buffering"), - _("Double buffering will synchronize the update of the video image to the " - "repainting of the entire screen (\"vertical retrace\"). This eliminates " - "flickering and tearing artifacts, but will use more graphics memory."), - 20, xv_update_XV_DOUBLE_BUFFER, this); + VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP, + 20, xv_update_XV_DOUBLE_BUFFER, this); config->update_num(config,"video.device.xv_double_buffer",xv_double_buffer); + } else if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_SYNC_TO_VBLANK")) { + int xv_sync_to_vblank; + xv_sync_to_vblank = + config->register_bool (config, "video.device.xv_sync_to_vblank", 1, + _("enable vblank sync"), + _("This option will synchronize the update of the video image to the " + "repainting of the entire screen (\"vertical retrace\"). This eliminates " + "flickering and tearing artifacts. On nvidia cards one may also " + "need to run \"nvidia-settings\" and choose which display device to " + "sync to under the XVideo Settings tab"), + 20, xv_update_XV_SYNC_TO_VBLANK, this); + config->update_num(config,"video.device.xv_sync_to_vblank",xv_sync_to_vblank); } } } @@ -1341,16 +1402,21 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis (format_it.data->format == XCB_XV_IMAGE_FORMAT_INFO_FORMAT_PACKED) ? "packed" : "planar"); - if (format_it.data->id == XINE_IMGFMT_YV12) { + switch (format_it.data->id) { + case XINE_IMGFMT_YV12: this->xv_format_yv12 = format_it.data->id; this->capabilities |= VO_CAP_YV12; xprintf(this->xine, XINE_VERBOSITY_LOG, - _("%s: this adaptor supports the yv12 format.\n"), LOG_MODULE); - } else if (format_it.data->id == XINE_IMGFMT_YUY2) { + _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YV12"); + break; + case XINE_IMGFMT_YUY2: this->xv_format_yuy2 = format_it.data->id; this->capabilities |= VO_CAP_YUY2; xprintf(this->xine, XINE_VERBOSITY_LOG, - _("%s: this adaptor supports the yuy2 format.\n"), LOG_MODULE); + _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YUY2"); + break; + default: + break; } } @@ -1358,8 +1424,7 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis this->use_pitch_alignment = config->register_bool (config, "video.device.xv_pitch_alignment", 0, - _("pitch alignment workaround"), - _("Some buggy video drivers need a workaround to function properly."), + VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP, 10, xv_update_xv_pitch_alignment, this); if(this->use_colorkey==1) { diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c index 97c879af3..0df5c2806 100644 --- a/src/video_out/video_out_xshm.c +++ b/src/video_out/video_out_xshm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2003 the xine project + * Copyright (C) 2000-2003, 2008 the xine project * * This file is part of xine, a free video player. * @@ -315,7 +315,7 @@ static void dispose_ximage (xshm_driver_t *this, static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) { xshm_driver_t *this = (xshm_driver_t *) this_gen; - uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2; + uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST | VO_CAP_SATURATION; if( this->xoverlay ) capabilities |= VO_CAP_UNSCALED_OVERLAY; @@ -829,45 +829,43 @@ static int xshm_set_property (vo_driver_t *this_gen, int property, int value) { xshm_driver_t *this = (xshm_driver_t *) this_gen; - if ( property == VO_PROP_ASPECT_RATIO) { - + switch (property) { + case VO_PROP_ASPECT_RATIO: if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->sc.user_ratio = value; xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name_table[value]); + break; - } else if (property == VO_PROP_BRIGHTNESS) { - + case VO_PROP_BRIGHTNESS: this->yuv2rgb_brightness = value; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, this->yuv2rgb_saturation); - this->sc.force_redraw = 1; + break; - } else if (property == VO_PROP_CONTRAST) { - + case VO_PROP_CONTRAST: this->yuv2rgb_contrast = value; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, this->yuv2rgb_saturation); - this->sc.force_redraw = 1; + break; - } else if (property == VO_PROP_SATURATION) { - + case VO_PROP_SATURATION: this->yuv2rgb_saturation = value; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, this->yuv2rgb_saturation); - this->sc.force_redraw = 1; + break; - } else { + default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": tried to set unsupported property %d\n", property); } diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index d6419c00b..a874e4cdf 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2004 the xine project + * Copyright (C) 2000-2004, 2008 the xine project * * This file is part of xine, a free video player. * @@ -69,6 +69,7 @@ #include <xine/xineutils.h> #include <xine/vo_scale.h> #include "x11osd.h" +#include "xv_common.h" #define LOCK_DISPLAY(this) {if(this->lock_display) this->lock_display(this->user_data); \ else XLockDisplay(this->display);} @@ -1028,14 +1029,13 @@ static int xv_check_yv12 (Display *display, XvPortID port) { /* called xlocked */ static void xv_check_capability (xv_driver_t *this, - int property, XvAttribute attr, - int base_id, + int property, XvAttribute attr, int base_id, const char *config_name, const char *config_desc, const char *config_help) { int int_default; cfg_entry_t *entry; - char *str_prop = attr.name; + const char *str_prop = attr.name; /* * some Xv drivers (Gatos ATI) report some ~0 as max values, this is confusing. @@ -1130,12 +1130,70 @@ static void xv_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) LOG_MODULE ": double buffering mode = %d\n", xv_double_buffer); } +static void xv_update_XV_SYNC_TO_VBLANK(void *this_gen, xine_cfg_entry_t *entry) { + xv_driver_t *this = (xv_driver_t *) this_gen; + Atom atom; + int xv_sync_to_vblank; + + xv_sync_to_vblank = entry->num_value; + + LOCK_DISPLAY(this); + atom = XInternAtom (this->display, "XV_SYNC_TO_VBLANK", False); + XvSetPortAttribute (this->display, this->xv_port, atom, xv_sync_to_vblank); + UNLOCK_DISPLAY(this); + + xprintf(this->xine, XINE_VERBOSITY_DEBUG, + "video_out_xv: sync to vblank = %d\n", xv_sync_to_vblank); +} + static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) { xv_driver_t *this = (xv_driver_t *) this_gen; this->use_pitch_alignment = entry->num_value; } +static int xv_open_port (xv_driver_t *this, XvPortID port) { + int ret; + x11_InstallXErrorHandler (this); + ret = ! xv_check_yv12(this->display, port) + && XvGrabPort(this->display, port, 0) == Success; + x11_DeInstallXErrorHandler (this); + return ret; +} + +static unsigned int +xv_find_adaptor_by_port (int port, unsigned int adaptors, + XvAdaptorInfo *adaptor_info) +{ + unsigned int an; + for (an = 0; an < adaptors; an++) + if (adaptor_info[an].type & XvImageMask) + if (port >= adaptor_info[an].base_id && + port < adaptor_info[an].base_id + adaptor_info[an].num_ports) + return an; + return 0; /* shouldn't happen */ +} + +static XvPortID xv_autodetect_port(xv_driver_t *this, + unsigned int adaptors, + XvAdaptorInfo *adaptor_info, + unsigned int *adaptor_num, + XvPortID base) { + unsigned int an, j; + + for (an = 0; an < adaptors; an++) + if (adaptor_info[an].type & XvImageMask) + for (j = 0; j < adaptor_info[an].num_ports; j++) { + XvPortID port = adaptor_info[an].base_id + j; + if (port >= base && xv_open_port(this, port)) { + *adaptor_num = an; + return port; + } + } + + return 0; +} + /* expects XINE_VISUAL_TYPE_X11_2 with configurable locking */ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *visual_gen) { xv_class_t *class = (xv_class_t *) class_gen; @@ -1148,7 +1206,7 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void * x11_visual_t *visual = (x11_visual_t *) visual_gen; XColor dummy; XvImage *myimage; - unsigned int adaptors, j; + unsigned int adaptors; unsigned int ver,rel,req,ev,err; XShmSegmentInfo myshminfo; XvPortID xv_port; @@ -1191,25 +1249,21 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void * return NULL; } - xv_port = 0; - - for ( adaptor_num = 0; (adaptor_num < adaptors) && !xv_port; adaptor_num++ ) { - - if (adaptor_info[adaptor_num].type & XvImageMask) { - - for (j = 0; j < adaptor_info[adaptor_num].num_ports && !xv_port; j++) - if (( !(xv_check_yv12 (this->display, - adaptor_info[adaptor_num].base_id + j))) - && (XvGrabPort (this->display, - adaptor_info[adaptor_num].base_id + j, - 0) == Success)) { - xv_port = adaptor_info[adaptor_num].base_id + j; - } - - if( xv_port ) - break; - } + xv_port = config->register_num (config, "video.device.xv_port", 0, + VIDEO_DEVICE_XV_PORT_HELP, + 10, NULL, NULL); + + if (xv_port != 0) { + if (! xv_open_port(this, xv_port)) { + xprintf(class->xine, XINE_VERBOSITY_NONE, + _("%s: could not open Xv port %d - autodetecting\n"), + LOG_MODULE, xv_port); + xv_port = xv_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, xv_port); + } else + adaptor_num = xv_find_adaptor_by_port (xv_port, adaptors, adaptor_info); } + if (!xv_port) + xv_port = xv_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0); if (!xv_port) { xprintf(class->xine, XINE_VERBOSITY_LOG, @@ -1239,7 +1293,7 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void * LOCK_DISPLAY(this); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); UNLOCK_DISPLAY(this); - this->capabilities = VO_CAP_CROP; + this->capabilities = VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; this->use_shm = 1; this->use_colorkey = 0; this->colorkey = 0; @@ -1298,75 +1352,72 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void * for(k = 0; k < nattr; k++) { if((attr[k].flags & XvSettable) && (attr[k].flags & XvGettable)) { + const char *const name = attr[k].name; /* store initial port attribute value */ - xv_store_port_attribute(this, attr[k].name); + xv_store_port_attribute(this, name); - if(!strcmp(attr[k].name, "XV_HUE")) { + if(!strcmp(name, "XV_HUE")) { if (!strncmp(adaptor_info[adaptor_num].name, "NV", 2)) { xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards\n"); } else { + this->capabilities |= VO_CAP_HUE; xv_check_capability (this, VO_PROP_HUE, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } - } else if(!strcmp(attr[k].name, "XV_SATURATION")) { + } else if(!strcmp(name, "XV_SATURATION")) { + this->capabilities |= VO_CAP_SATURATION; xv_check_capability (this, VO_PROP_SATURATION, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); - - } else if(!strcmp(attr[k].name, "XV_BRIGHTNESS")) { + } else if(!strcmp(name, "XV_BRIGHTNESS")) { + this->capabilities |= VO_CAP_BRIGHTNESS; xv_check_capability (this, VO_PROP_BRIGHTNESS, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); - - } else if(!strcmp(attr[k].name, "XV_CONTRAST")) { + } else if(!strcmp(name, "XV_CONTRAST")) { + this->capabilities |= VO_CAP_CONTRAST; xv_check_capability (this, VO_PROP_CONTRAST, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); - - } else if(!strcmp(attr[k].name, "XV_COLORKEY")) { + } else if(!strcmp(name, "XV_COLORKEY")) { + this->capabilities |= VO_CAP_COLORKEY; xv_check_capability (this, VO_PROP_COLORKEY, attr[k], adaptor_info[adaptor_num].base_id, "video.device.xv_colorkey", - _("video overlay colour key"), - _("The colour key is used to tell the graphics card where to " - "overlay the video image. Try different values, if you experience " - "windows becoming transparent.")); - - } else if(!strcmp(attr[k].name, "XV_AUTOPAINT_COLORKEY")) { + VIDEO_DEVICE_XV_COLORKEY_HELP); + } else if(!strcmp(name, "XV_AUTOPAINT_COLORKEY")) { + this->capabilities |= VO_CAP_AUTOPAINT_COLORKEY; xv_check_capability (this, VO_PROP_AUTOPAINT_COLORKEY, attr[k], adaptor_info[adaptor_num].base_id, "video.device.xv_autopaint_colorkey", - _("autopaint colour key"), - _("Make Xv autopaint its colour key.")); - - } else if(!strcmp(attr[k].name, "XV_FILTER")) { + VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP); + } else if(!strcmp(name, "XV_FILTER")) { int xv_filter; /* This setting is specific to Permedia 2/3 cards. */ xv_filter = config->register_range (config, "video.device.xv_filter", 0, attr[k].min_value, attr[k].max_value, - _("bilinear scaling mode"), - _("Selects the bilinear scaling mode for Permedia cards. " - "The individual values are:\n\n" - "Permedia 2\n" - "0 - disable bilinear filtering\n" - "1 - enable bilinear filtering\n\n" - "Permedia 3\n" - "0 - disable bilinear filtering\n" - "1 - horizontal linear filtering\n" - "2 - enable full bilinear filtering"), + VIDEO_DEVICE_XV_FILTER_HELP, 20, xv_update_XV_FILTER, this); config->update_num(config,"video.device.xv_filter",xv_filter); - } else if(!strcmp(attr[k].name, "XV_DOUBLE_BUFFER")) { - int xv_double_buffer; - xv_double_buffer = + } else if(!strcmp(name, "XV_DOUBLE_BUFFER")) { + int xv_double_buffer = config->register_bool (config, "video.device.xv_double_buffer", 1, - _("enable double buffering"), - _("Double buffering will synchronize the update of the video image to the " - "repainting of the entire screen (\"vertical retrace\"). This eliminates " - "flickering and tearing artifacts, but will use more graphics memory."), - 20, xv_update_XV_DOUBLE_BUFFER, this); + VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP, + 20, xv_update_XV_DOUBLE_BUFFER, this); config->update_num(config,"video.device.xv_double_buffer",xv_double_buffer); + } else if(!strcmp(attr[k].name, "XV_SYNC_TO_VBLANK")) { + int xv_sync_to_vblank; + xv_sync_to_vblank = + config->register_bool (config, "video.device.xv_sync_to_vblank", 1, + _("enable vblank sync"), + _("This option will synchronize the update of the video image to the " + "repainting of the entire screen (\"vertical retrace\"). This eliminates " + "flickering and tearing artifacts. On nvidia cards one may also " + "need to run \"nvidia-settings\" and choose which display device to " + "sync to under the XVideo Settings tab"), + 20, xv_update_XV_SYNC_TO_VBLANK, this); + config->update_num(config,"video.device.xv_sync_to_vblank",xv_sync_to_vblank); } } } @@ -1391,16 +1442,21 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void * fo[i].id, (char*)&fo[i].id, (fo[i].format == XvPacked) ? "packed" : "planar"); - if (fo[i].id == XINE_IMGFMT_YV12) { + switch (fo[i].id) { + case XINE_IMGFMT_YV12: this->xv_format_yv12 = fo[i].id; this->capabilities |= VO_CAP_YV12; xprintf(this->xine, XINE_VERBOSITY_LOG, - _("%s: this adaptor supports the yv12 format.\n"), LOG_MODULE); - } else if (fo[i].id == XINE_IMGFMT_YUY2) { + _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YV12"); + break; + case XINE_IMGFMT_YUY2: this->xv_format_yuy2 = fo[i].id; this->capabilities |= VO_CAP_YUY2; xprintf(this->xine, XINE_VERBOSITY_LOG, - _("%s: this adaptor supports the yuy2 format.\n"), LOG_MODULE); + _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YUY2"); + break; + default: + break; } } @@ -1422,8 +1478,7 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void * this->use_pitch_alignment = config->register_bool (config, "video.device.xv_pitch_alignment", 0, - _("pitch alignment workaround"), - _("Some buggy video drivers need a workaround to function properly."), + VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP, 10, xv_update_xv_pitch_alignment, this); LOCK_DISPLAY(this); diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c index 6aa8f430d..7f282ee53 100644 --- a/src/video_out/video_out_xvmc.c +++ b/src/video_out/video_out_xvmc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2004 the xine project + * Copyright (C) 2000-2004, 2008 the xine project * * This file is part of xine, a free video player. * @@ -72,6 +72,7 @@ #include <xine/xineutils.h> #include <xine/vo_scale.h> +#include "xv_common.h" /* #define LOG1 */ /* #define DLOG */ @@ -217,8 +218,6 @@ typedef struct { Display *display; config_values_t *config; XvPortID xv_port; - XvAdaptorInfo *adaptor_info; - unsigned int adaptor_num; int surface_type_id; unsigned int max_surface_width; @@ -1224,13 +1223,13 @@ static void xvmc_dispose (vo_driver_t *this_gen) { /* called xlocked */ static void xvmc_check_capability (xvmc_driver_t *this, - int property, XvAttribute attr, - int base_id, char *str_prop, - char *config_name, - char *config_desc, - char *config_help) { + int property, XvAttribute attr, int base_id, + const char *config_name, + const char *config_desc, + const char *config_help) { int int_default; cfg_entry_t *entry; + const char *str_prop = attr.name; /* * some Xv drivers (Gatos ATI) report some ~0 as max values, this is confusing. @@ -1253,13 +1252,13 @@ static void xvmc_check_capability (xvmc_driver_t *this, if ((attr.min_value == 0) && (attr.max_value == 1)) { this->config->register_bool (this->config, config_name, int_default, config_desc, - NULL, 20, xvmc_property_callback, &this->props[property]); + config_help, 20, xvmc_property_callback, &this->props[property]); } else { this->config->register_range (this->config, config_name, int_default, this->props[property].min, this->props[property].max, config_desc, - NULL, 20, xvmc_property_callback, &this->props[property]); + config_help, 20, xvmc_property_callback, &this->props[property]); } entry = this->config->lookup_entry (this->config, config_name); @@ -1297,7 +1296,6 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi xvmc_class_t *class = (xvmc_class_t *) class_gen; config_values_t *config = class->config; xvmc_driver_t *this = NULL; - Display *display = NULL; unsigned int i, formats; XvPortID xv_port = class->xv_port; XvAttribute *attr; @@ -1305,13 +1303,12 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi int nattr; x11_visual_t *visual = (x11_visual_t *) visual_gen; XColor dummy; + XvAdaptorInfo *adaptor_info; + unsigned int adaptor_num; /* XvImage *myimage; */ lprintf ("open_plugin\n"); - display = visual->display; - - /* TODO ??? */ this = (xvmc_driver_t *) xine_xmalloc (sizeof (xvmc_driver_t)); if (!this) @@ -1335,7 +1332,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi XLockDisplay(this->display); this->gc = XCreateGC(this->display, this->drawable, 0, NULL); XUnlockDisplay(this->display); - this->capabilities = VO_CAP_XVMC_MOCOMP | VO_CAP_CROP; + this->capabilities = VO_CAP_XVMC_MOCOMP | VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; this->surface_type_id = class->surface_type_id; this->max_surface_width = class->max_surface_width; @@ -1393,56 +1390,53 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi this->capabilities |= VO_CAP_XVMC_IDCT; XLockDisplay(this->display); - attr = XvQueryPortAttributes(display, xv_port, &nattr); + attr = XvQueryPortAttributes(this->display, xv_port, &nattr); if(attr && nattr) { int k; for(k = 0; k < nattr; k++) { if((attr[k].flags & XvSettable) && (attr[k].flags & XvGettable)) { - if(!strcmp(attr[k].name, "XV_HUE")) { - xvmc_check_capability (this, VO_PROP_HUE, attr[k], - class->adaptor_info[class->adaptor_num].base_id, "XV_HUE", - NULL, NULL, NULL); - - } else if(!strcmp(attr[k].name, "XV_SATURATION")) { + const char *const name = attr[k].name; + if(!strcmp(name, "XV_HUE")) { + if (!strncmp(adaptor_info[adaptor_num].name, "NV", 2)) { + xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards\n"); + } else { + this->capabilities |= VO_CAP_HUE; + xvmc_check_capability (this, VO_PROP_HUE, attr[k], + adaptor_info[adaptor_num].base_id, + NULL, NULL, NULL); + } + } else if(!strcmp(name, "XV_SATURATION")) { + this->capabilities |= VO_CAP_SATURATION; xvmc_check_capability (this, VO_PROP_SATURATION, attr[k], - class->adaptor_info[class->adaptor_num].base_id, "XV_SATURATION", + adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); - } else if(!strcmp(attr[k].name, "XV_BRIGHTNESS")) { + this->capabilities |= VO_CAP_BRIGHTNESS; xvmc_check_capability (this, VO_PROP_BRIGHTNESS, attr[k], - class->adaptor_info[class->adaptor_num].base_id, "XV_BRIGHTNESS", + adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); - - } else if(!strcmp(attr[k].name, "XV_CONTRAST")) { + } else if(!strcmp(name, "XV_CONTRAST")) { + this->capabilities |= VO_CAP_CONTRAST; xvmc_check_capability (this, VO_PROP_CONTRAST, attr[k], - class->adaptor_info[class->adaptor_num].base_id, "XV_CONTRAST", + adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); - - } else if(!strcmp(attr[k].name, "XV_COLORKEY")) { + } else if(!strcmp(name, "XV_COLORKEY")) { + this->capabilities |= VO_CAP_COLORKEY; xvmc_check_capability (this, VO_PROP_COLORKEY, attr[k], - class->adaptor_info[class->adaptor_num].base_id, "XV_COLORKEY", + adaptor_info[adaptor_num].base_id, "video.device.xv_colorkey", - _("video overlay colour key"), - _("The colour key is used to tell the graphics card where to " - "overlay the video image. Try different values, if you experience " - "windows becoming transparent.")); - - } else if(!strcmp(attr[k].name, "XV_AUTOPAINT_COLORKEY")) { + VIDEO_DEVICE_XV_COLORKEY_HELP); + } else if(!strcmp(name, "XV_AUTOPAINT_COLORKEY")) { + this->capabilities |= VO_CAP_AUTOPAINT_COLORKEY; xvmc_check_capability (this, VO_PROP_AUTOPAINT_COLORKEY, attr[k], - class->adaptor_info[class->adaptor_num].base_id, "XV_AUTOPAINT_COLORKEY", + adaptor_info[adaptor_num].base_id, "video.device.xv_autopaint_colorkey", - _("autopaint colour key"), - _("Make Xv autopaint its colour key.")); - - } else if(!strcmp(attr[k].name, "XV_DOUBLE_BUFFER")) { - int xvmc_double_buffer; - xvmc_double_buffer = config->register_bool (config, "video.device.xv_double_buffer", 1, - _("enable double buffering"), - _("Double buffering will synchronize the update of the video image to the " - "repainting of the entire screen (\"vertical retrace\"). This eliminates " - "flickering and tearing artifacts, but will use more graphics memory."), - 20, xvmc_update_XV_DOUBLE_BUFFER, this); + VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP); + } else if(!strcmp(name, "XV_DOUBLE_BUFFER")) { + int xvmc_double_buffer = config->register_bool (config, "video.device.xv_double_buffer", 1, + VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP, + 20, xvmc_update_XV_DOUBLE_BUFFER, this); config->update_num(config,"video.device.xv_double_buffer",xvmc_double_buffer); } } @@ -1457,7 +1451,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi /* * check supported image formats */ - fo = XvListImageFormats(display, this->xv_port, (int*)&formats); + fo = XvListImageFormats(this->display, this->xv_port, (int*)&formats); XUnlockDisplay(this->display); this->xvmc_format_yv12 = 0; @@ -1468,15 +1462,21 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi fo[i].id, (char*)&fo[i].id, (fo[i].format == XvPacked) ? "packed" : "planar"); - if (fo[i].id == XINE_IMGFMT_YV12) { + switch (fo[i].id) { + case XINE_IMGFMT_YV12: this->xvmc_format_yv12 = fo[i].id; - this->capabilities |= VO_CAP_YV12; - lprintf("this adaptor supports the yv12 format.\n"); - } - else if (fo[i].id == XINE_IMGFMT_YUY2) { + this->capabilities |= VO_CAP_YV12; + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YV12"); + break; + case XINE_IMGFMT_YUY2: this->xvmc_format_yuy2 = fo[i].id; - this->capabilities |= VO_CAP_YUY2; - lprintf("this adaptor supports the yuy2 format.\n"); + this->capabilities |= VO_CAP_YUY2; + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YUY2"); + break; + default: + break; } } @@ -1509,10 +1509,6 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi static void dispose_class (video_driver_class_t *this_gen) { xvmc_class_t *this = (xvmc_class_t *) this_gen; - XLockDisplay(this->display); - XvFreeAdaptorInfo (this->adaptor_info); - XUnlockDisplay(this->display); - free (this); } @@ -1685,8 +1681,6 @@ static void *init_class (xine_t *xine, void *visual_gen) { this->display = display; this->config = xine->config; this->xv_port = xv_port; - this->adaptor_info = adaptor_info; - this->adaptor_num = adaptor_num; this->surface_type_id = surface_type; this->max_surface_width = max_width; this->max_surface_height = max_height; diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c index 98ce99f1f..1ef3652a9 100644 --- a/src/video_out/video_out_xxmc.c +++ b/src/video_out/video_out_xxmc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2004 the xine project + * Copyright (C) 2000-2004, 2008 the xine project * Copyright (C) 2004 the Unichrome project * * This file is part of xine, a free video player. @@ -34,9 +34,9 @@ */ - #include "xxmc.h" #include <unistd.h> +#include "xv_common.h" static int gX11Fail; @@ -2101,13 +2101,13 @@ static int xxmc_check_yv12 (Display *display, XvPortID port) { /* called xlocked */ static void xxmc_check_capability (xxmc_driver_t *this, - int property, XvAttribute attr, - int base_id, char *str_prop, - char *config_name, - char *config_desc, - char *config_help) { + int property, XvAttribute attr, int base_id, + const char *config_name, + const char *config_desc, + const char *config_help) { int int_default; cfg_entry_t *entry; + const char *str_prop = attr.name; if (VO_PROP_COLORKEY && (attr.max_value == ~0)) attr.max_value = 2147483615; @@ -2237,6 +2237,48 @@ static void xxmc_update_disable_bob_for_scaled_osd(void *this_gen, xine_cfg_entr this->disable_bob_for_scaled_osd = entry->num_value; } +static int xxmc_open_port (xxmc_driver_t *this, XvPortID port) { + int ret; + x11_InstallXErrorHandler (this); + ret = ! xxmc_check_yv12(this->display, port) + && XvGrabPort(this->display, port, 0) == Success; + x11_DeInstallXErrorHandler (this); + return ret; +} + +static unsigned int +xxmc_find_adaptor_by_port (int port, unsigned int adaptors, + XvAdaptorInfo *adaptor_info) +{ + unsigned int an; + for (an = 0; an < adaptors; an++) + if (adaptor_info[an].type & XvImageMask) + if (port >= adaptor_info[an].base_id && + port < adaptor_info[an].base_id + adaptor_info[an].num_ports) + return an; + return 0; /* shouldn't happen */ +} + +static XvPortID xxmc_autodetect_port(xxmc_driver_t *this, + unsigned int adaptors, + XvAdaptorInfo *adaptor_info, + unsigned int *adaptor_num, + XvPortID base) { + unsigned int an, j; + + for (an = 0; an < adaptors; an++) + if (adaptor_info[an].type & XvImageMask) + for (j = 0; j < adaptor_info[an].num_ports; j++) { + XvPortID port = adaptor_info[an].base_id + j; + if (port >= base && xxmc_open_port(this, port)) { + *adaptor_num = an; + return port; + } + } + + return 0; +} + static void checkXvMCCap( xxmc_driver_t *this, XvPortID xv_port) { @@ -2436,25 +2478,21 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi return NULL; } - xv_port = 0; - - for ( adaptor_num = 0; (adaptor_num < adaptors) && !xv_port; adaptor_num++ ) { - - if (adaptor_info[adaptor_num].type & XvImageMask) { + xv_port = config->register_num (config, "video.device.xv_port", 0, + VIDEO_DEVICE_XV_PORT_HELP, + 10, NULL, NULL); - for (j = 0; j < adaptor_info[adaptor_num].num_ports && !xv_port; j++) - if (( !(xxmc_check_yv12 (this->display, - adaptor_info[adaptor_num].base_id + j))) - && (XvGrabPort (this->display, - adaptor_info[adaptor_num].base_id + j, - 0) == Success)) { - xv_port = adaptor_info[adaptor_num].base_id + j; - } - - if( xv_port ) - break; - } + if (xv_port != 0) { + if (! xxmc_open_port(this, xv_port)) { + xprintf(class->xine, XINE_VERBOSITY_NONE, + _("%s: could not open Xv port %d - autodetecting\n"), + LOG_MODULE, xv_port); + xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, xv_port); + } else + adaptor_num = xxmc_find_adaptor_by_port (xv_port, adaptors, adaptor_info); } + if (!xv_port) + xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0); if (!xv_port) { xprintf(class->xine, XINE_VERBOSITY_LOG, @@ -2484,7 +2522,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi XLockDisplay (this->display); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); XUnlockDisplay (this->display); - this->capabilities = VO_CAP_CROP; + this->capabilities = VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; this->use_shm = 1; this->use_colorkey = 0; this->colorkey = 0; @@ -2543,70 +2581,55 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi for(k = 0; k < nattr; k++) { if((attr[k].flags & XvSettable) && (attr[k].flags & XvGettable)) { - if(!strcmp(attr[k].name, "XV_HUE")) { + const char *const name = attr[k].name; + if(!strcmp(name, "XV_HUE")) { if (!strncmp(adaptor_info[adaptor_num].name, "NV", 2)) { xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards\n"); } else { + this->capabilities |= VO_CAP_HUE; xxmc_check_capability (this, VO_PROP_HUE, attr[k], - adaptor_info[adaptor_num].base_id, "XV_HUE", + adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } - } else if(!strcmp(attr[k].name, "XV_SATURATION")) { + } else if(!strcmp(name, "XV_SATURATION")) { + this->capabilities |= VO_CAP_SATURATION; xxmc_check_capability (this, VO_PROP_SATURATION, attr[k], - adaptor_info[adaptor_num].base_id, "XV_SATURATION", + adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); - - } else if(!strcmp(attr[k].name, "XV_BRIGHTNESS")) { + } else if(!strcmp(name, "XV_BRIGHTNESS")) { + this->capabilities |= VO_CAP_BRIGHTNESS; xxmc_check_capability (this, VO_PROP_BRIGHTNESS, attr[k], - adaptor_info[adaptor_num].base_id, "XV_BRIGHTNESS", + adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); - - } else if(!strcmp(attr[k].name, "XV_CONTRAST")) { + } else if(!strcmp(name, "XV_CONTRAST")) { + this->capabilities |= VO_CAP_CONTRAST; xxmc_check_capability (this, VO_PROP_CONTRAST, attr[k], - adaptor_info[adaptor_num].base_id, "XV_CONTRAST", + adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); - - } else if(!strcmp(attr[k].name, "XV_COLORKEY")) { + } else if(!strcmp(name, "XV_COLORKEY")) { + this->capabilities |= VO_CAP_COLORKEY; xxmc_check_capability (this, VO_PROP_COLORKEY, attr[k], - adaptor_info[adaptor_num].base_id, "XV_COLORKEY", + adaptor_info[adaptor_num].base_id, "video.device.xv_colorkey", - _("video overlay colour key"), - _("The colour key is used to tell the graphics card where to " - "overlay the video image. Try different values, if you experience " - "windows becoming transparent.")); - - } else if(!strcmp(attr[k].name, "XV_AUTOPAINT_COLORKEY")) { + VIDEO_DEVICE_XV_COLORKEY_HELP); + } else if(!strcmp(name, "XV_AUTOPAINT_COLORKEY")) { + this->capabilities |= VO_CAP_AUTOPAINT_COLORKEY; xxmc_check_capability (this, VO_PROP_AUTOPAINT_COLORKEY, attr[k], - adaptor_info[adaptor_num].base_id, "XV_AUTOPAINT_COLORKEY", + adaptor_info[adaptor_num].base_id, "video.device.xv_autopaint_colorkey", - _("autopaint colour key"), - _("Make Xv autopaint its colour key.")); - - } else if(!strcmp(attr[k].name, "XV_FILTER")) { + VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP); + } else if(!strcmp(name, "XV_FILTER")) { int xv_filter; /* This setting is specific to Permedia 2/3 cards. */ xv_filter = config->register_range (config, "video.device.xv_filter", 0, attr[k].min_value, attr[k].max_value, - _("bilinear scaling mode"), - _("Selects the bilinear scaling mode for Permedia cards. " - "The individual values are:\n\n" - "Permedia 2\n" - "0 - disable bilinear filtering\n" - "1 - enable bilinear filtering\n\n" - "Permedia 3\n" - "0 - disable bilinear filtering\n" - "1 - horizontal linear filtering\n" - "2 - enable full bilinear filtering"), + VIDEO_DEVICE_XV_FILTER_HELP, 20, xxmc_update_XV_FILTER, this); config->update_num(config,"video.device.xv_filter",xv_filter); - } else if(!strcmp(attr[k].name, "XV_DOUBLE_BUFFER")) { - int xv_double_buffer; - xv_double_buffer = + } else if(!strcmp(name, "XV_DOUBLE_BUFFER")) { + int xv_double_buffer = config->register_bool (config, "video.device.xv_double_buffer", 1, - _("enable double buffering"), - _("Double buffering will synchronize the update of the video image to the " - "repainting of the entire screen (\"vertical retrace\"). This eliminates " - "flickering and tearing artifacts, but will use more graphics memory."), + VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP, 20, xxmc_update_XV_DOUBLE_BUFFER, this); config->update_num(config,"video.device.xv_double_buffer",xv_double_buffer); } @@ -2640,16 +2663,21 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi fo[i].id, (char*)&fo[i].id, (fo[i].format == XvPacked) ? "packed" : "planar"); - if (fo[i].id == XINE_IMGFMT_YV12) { + switch (fo[i].id) { + case XINE_IMGFMT_YV12: this->xv_format_yv12 = fo[i].id; this->capabilities |= VO_CAP_YV12; xprintf(this->xine, XINE_VERBOSITY_LOG, - _("%s: this adaptor supports the yv12 format.\n"), LOG_MODULE); - } else if (fo[i].id == XINE_IMGFMT_YUY2) { + _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YV12"); + break; + case XINE_IMGFMT_YUY2: this->xv_format_yuy2 = fo[i].id; this->capabilities |= VO_CAP_YUY2; xprintf(this->xine, XINE_VERBOSITY_LOG, - _("%s: this adaptor supports the yuy2 format.\n"), LOG_MODULE); + _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YUY2"); + break; + default: + break; } } @@ -2672,8 +2700,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi this->use_pitch_alignment = config->register_bool (config, "video.device.xv_pitch_alignment", 0, - _("pitch alignment workaround"), - _("Some buggy video drivers need a workaround to function properly."), + VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP, 10, xxmc_update_xv_pitch_alignment, this); use_more_frames= diff --git a/src/video_out/xv_common.h b/src/video_out/xv_common.h new file mode 100644 index 000000000..ee2ab9a10 --- /dev/null +++ b/src/video_out/xv_common.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008 the xine project + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * xv_common.h: X11 Xv common bits + */ + +#define VIDEO_DEVICE_XV_COLORKEY_HELP \ + _("video overlay colour key"), \ + _("The colour key is used to tell the graphics card where to " \ + "overlay the video image. Try different values, if you "\ + "experience windows becoming transparent.") + +#define VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP \ + _("autopaint colour key"), \ + _("Make Xv autopaint its colour key.") + +#define VIDEO_DEVICE_XV_FILTER_HELP \ + _("bilinear scaling mode"), \ + _("Selects the bilinear scaling mode for Permedia cards. " \ + "The individual values are:\n\n" \ + "Permedia 2\n" \ + "0 - disable bilinear filtering\n" \ + "1 - enable bilinear filtering\n\n" \ + "Permedia 3\n" \ + "0 - disable bilinear filtering\n" \ + "1 - horizontal linear filtering\n" \ + "2 - enable full bilinear filtering") + +#define VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP \ + _("enable double buffering"), \ + _("Double buffering will synchronize the update of the video " \ + "image to the repainting of the entire screen (\"vertical " \ + "retrace\"). This eliminates flickering and tearing artifacts, " \ + "but will use more graphics memory.") + +#define VIDEO_DEVICE_XV_PORT_HELP \ + _("Xv port number"), \ + _("Selects the Xv port number to use (0 to autodetect).") + +#define VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP \ + _("pitch alignment workaround"), \ + _("Some buggy video drivers need a workaround to function properly.") |