diff options
Diffstat (limited to 'src/video_out/video_out_xxmc.c')
-rw-r--r-- | src/video_out/video_out_xxmc.c | 171 |
1 files changed, 99 insertions, 72 deletions
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= |