summaryrefslogtreecommitdiff
path: root/src/video_out
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_out')
-rw-r--r--src/video_out/Makefile.am2
-rw-r--r--src/video_out/video_out_xcbxv.c162
-rw-r--r--src/video_out/video_out_xv.c152
-rw-r--r--src/video_out/video_out_xvmc.c92
-rw-r--r--src/video_out/video_out_xxmc.c158
-rw-r--r--src/video_out/xv_common.h69
6 files changed, 389 insertions, 246 deletions
diff --git a/src/video_out/Makefile.am b/src/video_out/Makefile.am
index 28aca041b..80dd1e92c 100644
--- a/src/video_out/Makefile.am
+++ b/src/video_out/Makefile.am
@@ -206,4 +206,4 @@ xineplug_vo_out_macosx_la_LDFLAGS = $(AM_LDFLAGS) \
-Wl,-framework -Wl,Cocoa -framework Cocoa -framework OpenGL
noinst_HEADERS = deinterlace.h video_out_syncfb.h \
- yuv2rgb.h x11osd.h xcbosd.h
+ yuv2rgb.h x11osd.h xcbosd.h xv_common.h
diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c
index a4a3c3812..b6e5544c3 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.
*
@@ -65,6 +65,7 @@
#include "xineutils.h"
#include "vo_scale.h"
#include "xcbosd.h"
+#include "xv_common.h"
typedef struct xv_driver_s xv_driver_t;
@@ -155,6 +156,8 @@ typedef struct {
xine_t *xine;
} xv_class_t;
+static const char *const prefer_types[] = VIDEO_DEVICE_XV_PREFER_TYPES;
+
static uint32_t xv_get_capabilities (vo_driver_t *this_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
@@ -1101,6 +1104,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))
@@ -1122,7 +1127,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;
@@ -1274,14 +1279,67 @@ static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry
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,
+ xv_prefertype prefer_type)
+{
+ xcb_xv_adaptor_info_iterator_t *start = adaptor_it;
+
+ for (; adaptor_it->rem; xcb_xv_adaptor_info_next(adaptor_it))
+ if (adaptor_it->data->type & XCB_XV_TYPE_IMAGE_MASK &&
+ (prefer_type == xv_prefer_none ||
+ strcasestr (xcb_xv_adaptor_info_name (adaptor_it->data), prefer_types[prefer_type])))
+ {
+ 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;
+ xv_prefertype prefer_type;
const xcb_query_extension_reply_t *query_extension_reply;
@@ -1331,28 +1389,26 @@ 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,
+ 20, NULL, NULL);
+ prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0,
+ prefer_types, VIDEO_DEVICE_XV_PREFER_TYPE_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, prefer_type);
+ } else
+ xv_find_adaptor_by_port (xv_port, &adaptor_it);
}
+ if (!xv_port)
+ xv_port = xv_autodetect_port (this, &adaptor_it, 0, prefer_type);
+ if (!xv_port)
+ xv_port = xv_autodetect_port (this, &adaptor_it, 0, xv_prefer_none);
if (!xv_port) {
xprintf(class->xine, XINE_VERBOSITY_LOG,
@@ -1432,10 +1488,11 @@ 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, "video_out_xcbxv: ignoring broken XV_HUE settings on NVidia cards\n");
} else {
@@ -1443,63 +1500,41 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
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")) {
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")) {
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")) {
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")) {
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")) {
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;
@@ -1557,8 +1592,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);
this->deinterlace_method =
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index e1f6d0de0..8f5da8ea0 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.
*
@@ -70,6 +70,7 @@
#include "xineutils.h"
#include "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);}
@@ -168,6 +169,8 @@ typedef struct {
static int gX11Fail;
+static const char *const prefer_types[] = VIDEO_DEVICE_XV_PREFER_TYPES;
+
static uint32_t xv_get_capabilities (vo_driver_t *this_gen) {
xv_driver_t *this = (xv_driver_t *) this_gen;
@@ -1190,14 +1193,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,
char *config_name,
char *config_desc,
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.
@@ -1321,6 +1323,52 @@ static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry
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,
+ xv_prefertype prefer_type)
+{
+ unsigned int an, j;
+
+ for (an = 0; an < adaptors; an++)
+ if (adaptor_info[an].type & XvImageMask &&
+ (prefer_type == xv_prefer_none ||
+ strcasestr (adaptor_info[an].name, prefer_types[prefer_type])))
+ 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;
@@ -1333,12 +1381,13 @@ 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;
XvAdaptorInfo *adaptor_info;
unsigned int adaptor_num;
+ xv_prefertype prefer_type;
this = (xv_driver_t *) calloc(1, sizeof(xv_driver_t));
if (!this)
@@ -1376,25 +1425,26 @@ 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,
+ 20, NULL, NULL);
+ prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0,
+ prefer_types, VIDEO_DEVICE_XV_PREFER_TYPE_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, prefer_type);
+ } 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, prefer_type);
+ if (!xv_port)
+ xv_port = xv_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, xv_prefer_none);
if (!xv_port) {
xprintf(class->xine, XINE_VERBOSITY_LOG,
@@ -1485,10 +1535,11 @@ 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, "video_out_xv: ignoring broken XV_HUE settings on NVidia cards\n");
} else {
@@ -1496,63 +1547,41 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
adaptor_info[adaptor_num].base_id,
NULL, NULL, NULL);
}
- } else if(!strcmp(attr[k].name, "XV_SATURATION")) {
+ } else if(!strcmp(name, "XV_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")) {
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")) {
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")) {
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")) {
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;
@@ -1621,8 +1650,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);
this->deinterlace_method =
diff --git a/src/video_out/video_out_xvmc.c b/src/video_out/video_out_xvmc.c
index 79c2a80a3..366a03859 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.
*
@@ -75,6 +75,7 @@
#include "xineutils.h"
#include "vo_scale.h"
+#include "xv_common.h"
/* #define LOG1 */
/* #define DLOG */
@@ -225,8 +226,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;
@@ -1252,13 +1251,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.
@@ -1281,13 +1280,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);
@@ -1333,7 +1332,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;
@@ -1341,13 +1339,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 = calloc(1, sizeof (xvmc_driver_t));
if (!this)
@@ -1430,56 +1427,47 @@ 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 {
+ xvmc_check_capability (this, VO_PROP_HUE, attr[k],
+ adaptor_info[adaptor_num].base_id,
+ NULL, NULL, NULL);
+ }
+ } else if(!strcmp(name, "XV_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")) {
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")) {
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")) {
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")) {
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);
}
}
@@ -1494,7 +1482,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;
@@ -1613,10 +1601,6 @@ static char* get_description (video_driver_class_t *this_gen) {
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);
}
@@ -1789,8 +1773,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 b016a8bd1..b8d6abf83 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;
@@ -45,6 +45,7 @@ static void xxmc_frame_updates(xxmc_driver_t *driver, xxmc_frame_t *frame,
static void dispose_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo,
XvImage *myimage);
+static const char *const prefer_types[] = VIDEO_DEVICE_XV_PREFER_TYPES;
/*
* Acceleration level priority. Static for now. It may well turn out that IDCT
@@ -2061,13 +2062,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;
@@ -2197,6 +2198,52 @@ 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,
+ xv_prefertype prefer_type)
+{
+ unsigned int an, j;
+
+ for (an = 0; an < adaptors; an++)
+ if (adaptor_info[an].type & XvImageMask &&
+ (prefer_type == xv_prefer_none ||
+ strcasestr (adaptor_info[an].name, prefer_types[prefer_type])))
+ 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)
{
@@ -2365,6 +2412,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
XvPortID xv_port;
XvAdaptorInfo *adaptor_info;
unsigned int adaptor_num;
+ xv_prefertype prefer_type;
cfg_entry_t *entry;
int use_more_frames;
int use_unscaled;
@@ -2400,25 +2448,26 @@ 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,
+ 20, NULL, NULL);
+ prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0,
+ prefer_types, VIDEO_DEVICE_XV_PREFER_TYPE_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, prefer_type);
+ } 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, prefer_type);
+ if (!xv_port)
+ xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, xv_prefer_none);
if (!xv_port) {
xprintf(class->xine, XINE_VERBOSITY_LOG,
@@ -2506,70 +2555,52 @@ 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, "video_out_xxmc: ignoring broken XV_HUE settings on NVidia cards\n");
} else {
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")) {
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")) {
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")) {
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")) {
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")) {
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);
}
@@ -2635,8 +2666,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..259afe616
--- /dev/null
+++ b/src/video_out/xv_common.h
@@ -0,0 +1,69 @@
+/*
+ * 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.")
+
+typedef enum {
+ xv_prefer_none, xv_prefer_overlay, xv_prefer_textured
+} xv_prefertype;
+#define VIDEO_DEVICE_XV_PREFER_TYPES \
+ { "Any", "Overlay", "Textured Video", NULL }
+#define VIDEO_DEVICE_XV_PREFER_TYPE_HELP \
+ _("video display method preference"), \
+ _("Selects which video output method is preferred. " \
+ "Detection is done using the reported Xv adaptor names.\n" \
+ "(Only applies when auto-detecting which Xv port to use.)")