summaryrefslogtreecommitdiff
path: root/src/video_out/video_out_xxmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_out/video_out_xxmc.c')
-rw-r--r--src/video_out/video_out_xxmc.c232
1 files changed, 133 insertions, 99 deletions
diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c
index 28679e95d..61e0139e3 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,8 @@ 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);
+VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES;
+VIDEO_DEVICE_XV_DECL_PREFER_TYPES;
/*
* Acceleration level priority. Static for now. It may well turn out that IDCT
@@ -158,18 +160,13 @@ static void xxmc_xvmc_dump_subpictures(xxmc_driver_t *this)
static void xxmc_xvmc_surface_handler_construct(xxmc_driver_t *this)
{
- int i;
xvmc_surface_handler_t *handler = &this->xvmc_surf_handler;
pthread_mutex_init(&handler->mutex,NULL);
- for (i=0; i<XVMC_MAX_SURFACES; ++i) {
- handler->surfInUse[i] = 0;
- handler->surfValid[i] = 0;
- }
- for (i=0; i<XVMC_MAX_SUBPICTURES; ++i) {
- handler->subInUse[i] = 0;
- handler->subValid[i] = 0;
- }
+ memset(handler->surfInUse, 0, sizeof(handler->surfInUse));
+ memset(handler->surfValid, 0, sizeof(handler->surfValid));
+ memset(handler->subInUse, 0, sizeof(handler->subInUse));
+ memset(handler->subValid, 0, sizeof(handler->subValid));
}
static void xxmc_xvmc_destroy_surfaces(xxmc_driver_t *this)
@@ -550,7 +547,7 @@ static vo_frame_t *xxmc_alloc_frame (vo_driver_t *this_gen) {
xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
xxmc_frame_t *frame ;
- frame = (xxmc_frame_t *) xine_xmalloc (sizeof (xxmc_frame_t));
+ frame = calloc(1, sizeof (xxmc_frame_t));
if (!frame)
return NULL;
@@ -1611,8 +1608,8 @@ static void xxmc_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
* other than 100 %, so let's disable deinterlacing at all for this frame
*/
if (this->deinterlace_enabled && this->bob) {
- disable_deinterlace = this->disable_bob_for_progressive_frames && frame->vo_frame.progressive_frame
- || this->disable_bob_for_scaled_osd && this->scaled_osd_active
+ disable_deinterlace = (this->disable_bob_for_progressive_frames && frame->vo_frame.progressive_frame)
+ || (this->disable_bob_for_scaled_osd && this->scaled_osd_active)
|| !frame->vo_frame.stream
|| xine_get_param(frame->vo_frame.stream, XINE_PARAM_FINE_SPEED) != XINE_FINE_SPEED_NORMAL;
if (!disable_deinterlace) {
@@ -2065,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;
@@ -2133,36 +2130,32 @@ static void xxmc_check_capability (xxmc_driver_t *this,
this->props[property].value = int_default;
}
-static void xxmc_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+static void xxmc_update_attr (void *this_gen, xine_cfg_entry_t *entry,
+ const char *atomstr, const char *debugstr)
+{
xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
Atom atom;
- int xv_filter;
-
- xv_filter = entry->num_value;
XLockDisplay(this->display);
- atom = XInternAtom (this->display, "XV_FILTER", False);
- XvSetPortAttribute (this->display, this->xv_port, atom, xv_filter);
+ atom = XInternAtom (this->display, atomstr, False);
+ XvSetPortAttribute (this->display, this->xv_port, atom, entry->num_value);
XUnlockDisplay(this->display);
xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xxmc: bilinear scaling mode (XV_FILTER) = %d\n",xv_filter);
+ LOG_MODULE ": %s = %d\n", debugstr, entry->num_value);
}
-static void xxmc_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
- xxmc_driver_t *this = (xxmc_driver_t *) this_gen;
- Atom atom;
- int xv_double_buffer;
-
- xv_double_buffer = entry->num_value;
+static void xxmc_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) {
+ xxmc_update_attr (this_gen, entry, "XV_FILTER", "bilinear scaling mode");
+}
- XLockDisplay(this->display);
- atom = XInternAtom (this->display, "XV_DOUBLE_BUFFER", False);
- XvSetPortAttribute (this->display, this->xv_port, atom, xv_double_buffer);
- XUnlockDisplay(this->display);
+static void xxmc_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) {
+ xxmc_update_attr (this_gen, entry, "XV_DOUBLE_BUFFER", "double buffering mode");
+}
- xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "video_out_xxmc: double buffering mode = %d\n", xv_double_buffer);
+static void xxmc_update_XV_BICUBIC(void *this_gen, xine_cfg_entry_t *entry)
+{
+ xxmc_update_attr (this_gen, entry, "XV_BICUBIC", "bicubic filtering mode");
}
static void xxmc_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) {
@@ -2201,6 +2194,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_substrings[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)
{
@@ -2363,17 +2402,18 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi
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;
cfg_entry_t *entry;
int use_more_frames;
int use_unscaled;
- this = (xxmc_driver_t *) xine_xmalloc (sizeof (xxmc_driver_t));
+ this = calloc(1, sizeof (xxmc_driver_t));
if (!this)
return NULL;
@@ -2404,24 +2444,31 @@ 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) {
-
- 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;
- }
+ 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_labels, VIDEO_DEVICE_XV_PREFER_TYPE_HELP,
+ 10, NULL, NULL);
+
+ 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)
+ {
+ if (prefer_type)
+ xprintf(class->xine, XINE_VERBOSITY_NONE,
+ _("%s: no available ports of type \"%s\", defaulting...\n"),
+ LOG_MODULE, prefer_labels[prefer_type]);
+ xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, xv_prefer_none);
}
if (!xv_port) {
@@ -2510,72 +2557,60 @@ 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);
+ } else if(!strcmp(name, "XV_BICUBIC")) {
+ int xv_bicubic =
+ config->register_enum (config, "video.device.xv_bicubic", 2,
+ bicubic_types, VIDEO_DEVICE_XV_BICUBIC_HELP,
+ 20, xxmc_update_XV_BICUBIC, this);
+ config->update_num(config,"video.device.xv_bicubic",xv_bicubic);
}
}
}
@@ -2639,8 +2674,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=
@@ -2744,7 +2778,7 @@ static void dispose_class (video_driver_class_t *this_gen) {
}
static void *init_class (xine_t *xine, void *visual_gen) {
- xxmc_class_t *this = (xxmc_class_t *) xine_xmalloc (sizeof (xxmc_class_t));
+ xxmc_class_t *this = calloc(1, sizeof (xxmc_class_t));
this->driver_class.open_plugin = open_plugin;
this->driver_class.get_identifier = get_identifier;