diff options
Diffstat (limited to 'src/video_out/video_out_xxmc.c')
-rw-r--r-- | src/video_out/video_out_xxmc.c | 381 |
1 files changed, 213 insertions, 168 deletions
diff --git a/src/video_out/video_out_xxmc.c b/src/video_out/video_out_xxmc.c index 28679e95d..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; @@ -162,14 +162,10 @@ static void xxmc_xvmc_surface_handler_construct(xxmc_driver_t *this) 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)*XVMC_MAX_SURFACES); + memset(handler->surfValid, 0, sizeof(*handler->surfValid)*XVMC_MAX_SURFACES); + memset(handler->subInUse, 0, sizeof(*handler->subInUse)*XVMC_MAX_SUBPICTURES); + memset(handler->subValid, 0, sizeof(*handler->subValid)*XVMC_MAX_SUBPICTURES); } static void xxmc_xvmc_destroy_surfaces(xxmc_driver_t *this) @@ -239,7 +235,7 @@ static XvMCSurface *xxmc_xvmc_alloc_surface(xxmc_driver_t *this, } XVMCUNLOCKDISPLAY( this->display ); xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: Created surface %d\n",i); + LOG_MODULE ": Created surface %d\n",i); handler->surfInUse[i] = 1; handler->surfValid[i] = 1; pthread_mutex_unlock(&handler->mutex); @@ -259,7 +255,7 @@ static void xxmc_xvmc_free_surface(xxmc_driver_t *this, XvMCSurface *surf) if (index >= XVMC_MAX_SURFACES) return; pthread_mutex_lock(&handler->mutex); xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: Disposing of surface %d\n",index); + LOG_MODULE ": Disposing of surface %d\n",index); handler->surfInUse[index]--; xxmc_xvmc_dump_surfaces(this); pthread_mutex_unlock(&handler->mutex); @@ -319,7 +315,7 @@ static XvMCSubpicture *xxmc_xvmc_alloc_subpicture } XVMCUNLOCKDISPLAY( this->display ); xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: Created subpicture %d\n",i); + LOG_MODULE ": Created subpicture %d\n",i); handler->subInUse[i] = 1; handler->subValid[i] = 1; pthread_mutex_unlock(&handler->mutex); @@ -340,7 +336,7 @@ static void xxmc_xvmc_free_subpicture(xxmc_driver_t *this, XvMCSubpicture *sub) if (index >= XVMC_MAX_SUBPICTURES) return; pthread_mutex_lock(&handler->mutex); xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: Disposing of subpicture %d\n",index); + LOG_MODULE ": Disposing of subpicture %d\n",index); handler->subInUse[index] = 0; xxmc_xvmc_dump_subpictures(this); pthread_mutex_unlock(&handler->mutex); @@ -368,15 +364,15 @@ static int xxmc_lock_and_validate_surfaces(vo_frame_t *cur_frame, switch(pc_type) { case XINE_PICT_B_TYPE: - frame = (xxmc_frame_t *) bw_frame; + frame = XXMC_FRAME(bw_frame); if (!xxmc_xvmc_surface_valid( driver, frame->xvmc_surf)) break; /* fall through */ case XINE_PICT_P_TYPE: - frame = (xxmc_frame_t *) fw_frame; + frame = XXMC_FRAME(fw_frame); if (!xxmc_xvmc_surface_valid( driver, frame->xvmc_surf)) break; /* fall through */ default: - frame = (xxmc_frame_t *) cur_frame; + frame = XXMC_FRAME(cur_frame); if (!xxmc_xvmc_surface_valid( driver, frame->xvmc_surf)) break; return 0; } @@ -407,7 +403,7 @@ static void xvmc_flush(vo_frame_t *this_gen) { xxmc_frame_t - *frame = (xxmc_frame_t *) this_gen; + *frame = XXMC_FRAME(this_gen); xxmc_driver_t *driver = (xxmc_driver_t *) this_gen->driver; @@ -455,6 +451,7 @@ static void xxmc_duplicate_frame_data(vo_frame_t *this_gen, return; } this->xxmc_data = *xxmc; + this->xxmc_data.xvmc.vo_frame = &this->vo_frame; this->width = original->width; this->height = original->height; this->format = original->format; @@ -569,6 +566,7 @@ static vo_frame_t *xxmc_alloc_frame (vo_driver_t *this_gen) { frame->vo_frame.driver = this_gen; frame->last_sw_format = 0; frame->vo_frame.accel_data = &frame->xxmc_data; + frame->xxmc_data.xvmc.vo_frame = &frame->vo_frame; frame->image = NULL; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "Allocating frame\n"); @@ -639,8 +637,9 @@ static XvImage *create_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo, if (image == NULL ) { xprintf(this->xine, XINE_VERBOSITY_LOG, - _("video_out_xxmc: XvShmCreateImage failed\n" - "video_out_xxmc: => not using MIT Shared Memory extension.\n")); + _("%s: XvShmCreateImage failed\n"), LOG_MODULE); + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } @@ -649,16 +648,18 @@ static XvImage *create_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo, if (image->data_size==0) { xprintf(this->xine, XINE_VERBOSITY_LOG, - _("video_out_xxmc: XvShmCreateImage returned a zero size\n" - "video_out_xxmc: => not using MIT Shared Memory extension.\n")); + _("%s: XvShmCreateImage returned a zero size\n"), LOG_MODULE); + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } if (shminfo->shmid < 0 ) { xprintf(this->xine, XINE_VERBOSITY_LOG, - _("video_out_xxmc: shared memory error in shmget: %s\n" - "video_out_xxmc: => not using MIT Shared Memory extension.\n"), strerror(errno)); + _("%s: shared memory error in shmget: %s\n"), LOG_MODULE, strerror(errno)); + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } @@ -667,14 +668,14 @@ static XvImage *create_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo, if (shminfo->shmaddr == NULL) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: shared memory error (address error NULL)\n"); + LOG_MODULE ": shared memory error (address error NULL)\n"); this->use_shm = 0; goto finishShmTesting; } if (shminfo->shmaddr == ((char *) -1)) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: shared memory error (address error)\n"); + LOG_MODULE ": shared memory error (address error)\n"); this->use_shm = 0; goto finishShmTesting; } @@ -688,12 +689,13 @@ static XvImage *create_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo, shmctl(shminfo->shmid, IPC_RMID, 0); if (gX11Fail) { - xprintf(this->xine, XINE_VERBOSITY_LOG, - _("video_out_xxmc: x11 error during shared memory XImage creation\n" - "video_out_xxmc: => not using MIT Shared Memory extension.\n")); shmdt (shminfo->shmaddr); shmctl (shminfo->shmid, IPC_RMID, 0); shminfo->shmid = -1; + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("%s: x11 error during shared memory XImage creation\n"), LOG_MODULE); + xprintf(this->xine, XINE_VERBOSITY_LOG, + _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } @@ -758,13 +760,13 @@ static void xxmc_dispose_context(xxmc_driver_t *driver) } xprintf(driver->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: Freeing up XvMC Surfaces and subpictures.\n"); + LOG_MODULE ": Freeing up XvMC Surfaces and subpictures.\n"); if (driver->xvmc_palette) free(driver->xvmc_palette); _x_dispose_xx44_palette( &driver->palette ); xxmc_xvmc_destroy_subpictures( driver ); xxmc_xvmc_destroy_surfaces( driver ); xprintf(driver->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: Freeing up XvMC Context.\n"); + LOG_MODULE ": Freeing up XvMC Context.\n"); XLockDisplay (driver->display); if (driver->subImage) dispose_ximage(driver, &driver->subShmInfo, driver->subImage); @@ -804,10 +806,10 @@ static int xxmc_find_context(xxmc_driver_t *driver, xine_xxmc_t *xxmc, curCap = driver->xvmc_cap; for (i =0; i < driver->xvmc_num_cap; ++i) { xprintf(driver->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: Surface type %d. Capabilities 0x%8x 0x%8x\n",i, + LOG_MODULE ": Surface type %d. Capabilities 0x%8x 0x%8x\n",i, curCap->mpeg_flags,curCap->accel_flags); xprintf(driver->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: Requests: 0x%8x 0x%8x\n", + LOG_MODULE ": Requests: 0x%8x 0x%8x\n", request_mpeg_flags,request_accel_flags); if (((curCap->mpeg_flags & request_mpeg_flags) == request_mpeg_flags) && ((curCap->accel_flags & request_accel_flags)) && @@ -838,7 +840,7 @@ static int xxmc_create_context(xxmc_driver_t *driver, unsigned width, unsigned h curCap = driver->xvmc_cap + driver->xvmc_cur_cap; xprintf(driver->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: Creating new XvMC Context %d\n",curCap->type_id); + LOG_MODULE ": Creating new XvMC Context %d\n",curCap->type_id); XVMCLOCKDISPLAY( driver->display ); if (Success == XvMCCreateContext( driver->display, driver->xv_port, curCap->type_id, width, @@ -871,7 +873,7 @@ static void xxmc_setup_subpictures(xxmc_driver_t *driver, unsigned width, unsign if ((driver->xvmc_backend_subpic = (curCap->flags & XVMC_BACKEND_SUBPICTURE))) xprintf(driver->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: Using Backend subpictures.\n"); + LOG_MODULE ": Using Backend subpictures.\n"); if (!driver->subImage) { /* @@ -887,7 +889,7 @@ static void xxmc_setup_subpictures(xxmc_driver_t *driver, unsigned width, unsign XUnlockDisplay (driver->display); if (NULL == driver->subImage) { xprintf(driver->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: Failed allocating XvImage for supbictures.\n"); + LOG_MODULE ": Failed allocating XvImage for supbictures.\n"); return; } } @@ -982,8 +984,8 @@ static int xxmc_xvmc_update_context(xxmc_driver_t *driver, xxmc_frame_t *frame, return 0; xprintf(driver->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: New format. Need to change XvMC Context.\n" - "width: %d height: %d", width, height); + LOG_MODULE ": New format. Need to change XvMC Context.\n" + LOG_MODULE ": width: %d height: %d", width, height); if (frame_format_xxmc) { xprintf(driver->xine, XINE_VERBOSITY_LOG, " mpeg: %d acceleration: %d", xxmc->mpeg, xxmc->acceleration); @@ -1003,17 +1005,17 @@ static int xxmc_xvmc_update_context(xxmc_driver_t *driver, xxmc_frame_t *frame, if ((driver->xvmc_accel & (XINE_XVMC_ACCEL_MOCOMP | XINE_XVMC_ACCEL_IDCT))) { if (!xxmc_mocomp_create_macroblocks(driver, frame, 1)) { - lprintf("video_out_xxmc: ERROR: Macroblock allocation failed\n"); + printf(LOG_MODULE ": ERROR: Macroblock allocation failed\n"); xxmc_dispose_context( driver ); } } } if (!driver->contextActive) { - printf("video_out_xxmc: Using software decoding for this stream.\n"); + printf(LOG_MODULE ": Using software decoding for this stream.\n"); driver->xvmc_accel = 0; } else { - printf("video_out_xxmc: Using hardware decoding for this stream.\n"); + printf(LOG_MODULE ": Using hardware decoding for this stream.\n"); } driver->xvmc_mpeg = xxmc->mpeg; @@ -1049,9 +1051,9 @@ static void xxmc_frame_updates(xxmc_driver_t *driver, if (frame->xvmc_surf == NULL) { if (NULL == (frame->xvmc_surf = xxmc_xvmc_alloc_surface( driver, &driver->context))) { - fprintf(stderr, "video_out_xxmc: ERROR: Accelerated surface allocation failed.\n" - "video_out_xxmc: You are probably out of framebuffer memory.\n" - "video_out_xxmc: Falling back to software decoding.\n"); + fprintf(stderr, LOG_MODULE ": ERROR: Accelerated surface allocation failed.\n" + LOG_MODULE ": You are probably out of framebuffer memory.\n" + LOG_MODULE ": Falling back to software decoding.\n"); driver->xvmc_accel = 0; xxmc_dispose_context( driver ); return; @@ -1216,10 +1218,17 @@ static void xxmc_do_update_frame(vo_driver_t *this_gen, double ratio, int format, int flags) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; - xxmc_frame_t *frame = (xxmc_frame_t *) frame_gen; + xxmc_frame_t *frame = XXMC_FRAME(frame_gen); if ( XINE_IMGFMT_XXMC == format ) { xine_xxmc_t *xxmc = &frame->xxmc_data; + vo_frame_t orig_frame_content; + + if (frame_gen != &frame->vo_frame) { + /* this is an intercepted frame, so we need to detect and propagate any + * changes on the original vo_frame to all the intercepted frames */ + xine_fast_memcpy(&orig_frame_content, &frame->vo_frame, sizeof (vo_frame_t)); + } xvmc_context_writer_lock( &this->xvmc_lock); if (xxmc_accel_update(this, this->last_accel_request, xxmc->acceleration) || @@ -1235,7 +1244,7 @@ static void xxmc_do_update_frame(vo_driver_t *this_gen, if (this->contextActive) xxmc_frame_updates(this, frame, 1); - xxmc_do_update_frame_xv(this_gen, frame_gen, width, height, ratio, + xxmc_do_update_frame_xv(this_gen, &frame->vo_frame, width, height, ratio, xxmc->fallback_format, flags); if (!this->contextActive) { @@ -1249,6 +1258,33 @@ static void xxmc_do_update_frame(vo_driver_t *this_gen, xvmc_context_writer_unlock( &this->xvmc_lock); + if (frame_gen != &frame->vo_frame) { + /* this is an intercepted frame, so we need to detect and propagate any + * changes on the original vo_frame to all the intercepted frames */ + unsigned char *p0 = (unsigned char *)&orig_frame_content; + unsigned char *p1 = (unsigned char *)&frame->vo_frame; + int i; + for (i = 0; i < sizeof (vo_frame_t); i++) { + if (*p0 != *p1) { + /* propagate the change */ + vo_frame_t *f = frame_gen; + while (f->next) { + /* serveral restrictions apply when intercepting XXMC frames. So let's check + * the intercepted frames before modifing them and fail otherwise. */ + unsigned char *p = (unsigned char *)f + i; + if (*p != *p0) { + xprintf(this->xine, XINE_VERBOSITY_DEBUG, "xxmc_do_update_frame: a post plugin violates the restrictions on intercepting XXMC frames\n"); + _x_abort(); + } + + *p = *p1; + f = f->next; + } + } + p0++; + p1++; + } + } } else { /* switch back to an unaccelerated context */ if (this->last_accel_request != 0xFFFFFFFF) { @@ -1256,7 +1292,7 @@ static void xxmc_do_update_frame(vo_driver_t *this_gen, xxmc_xvmc_update_context(this, frame, width, height, 0); } frame->vo_frame.proc_duplicate_frame_data = NULL; - xxmc_do_update_frame_xv(this_gen, frame_gen, width, height, ratio, + xxmc_do_update_frame_xv(this_gen, &frame->vo_frame, width, height, ratio, format, flags); } } @@ -1774,7 +1810,7 @@ static int xxmc_get_property (vo_driver_t *this_gen, int property) { break; } - lprintf("video_out_xxmc: property #%d = %d\n", property, this->props[property].value); + lprintf("%s: property #%d = %d\n", LOG_MODULE, property, this->props[property].value); return this->props[property].value; } @@ -1837,7 +1873,7 @@ static int xxmc_set_property (vo_driver_t *this_gen, case VO_PROP_INTERLACED: this->props[property].value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: VO_PROP_INTERLACED(%d)\n", this->props[property].value); + LOG_MODULE ": VO_PROP_INTERLACED(%d)\n", this->props[property].value); this->deinterlace_enabled = value; break; @@ -1847,7 +1883,7 @@ static int xxmc_set_property (vo_driver_t *this_gen, this->props[property].value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: VO_PROP_ASPECT_RATIO(%d)\n", this->props[property].value); + LOG_MODULE ": VO_PROP_ASPECT_RATIO(%d)\n", this->props[property].value); this->sc.user_ratio = value; xxmc_compute_ideal_size (this); @@ -1859,7 +1895,7 @@ static int xxmc_set_property (vo_driver_t *this_gen, if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: VO_PROP_ZOOM_X = %d\n", this->props[property].value); + LOG_MODULE ": VO_PROP_ZOOM_X = %d\n", this->props[property].value); this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; @@ -1873,7 +1909,7 @@ static int xxmc_set_property (vo_driver_t *this_gen, if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, - "video_out_xxmc: VO_PROP_ZOOM_Y = %d\n", this->props[property].value); + LOG_MODULE ": VO_PROP_ZOOM_Y = %d\n", this->props[property].value); this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; @@ -2020,7 +2056,7 @@ static void xxmc_dispose (vo_driver_t *this_gen) { XLockDisplay (this->display); if(XvUngrabPort (this->display, this->xv_port, CurrentTime) != Success) { - xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_xxmc: xxmc_exit: XvUngrabPort() failed.\n"); + xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": xxmc_exit: XvUngrabPort() failed.\n"); } XFreeGC(this->display, this->gc); XUnlockDisplay (this->display); @@ -2065,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; @@ -2084,7 +2120,7 @@ static void xxmc_check_capability (xxmc_driver_t *this, this->props[property].atom, &int_default); xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: port attribute %s (%d) value is %d\n", str_prop, property, int_default); + LOG_MODULE ": port attribute %s (%d) value is %d\n", str_prop, property, int_default); /* * We enable autopaint by default. @@ -2146,7 +2182,7 @@ static void xxmc_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) { XUnlockDisplay(this->display); xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: bilinear scaling mode (XV_FILTER) = %d\n",xv_filter); + LOG_MODULE ": bilinear scaling mode (XV_FILTER) = %d\n",xv_filter); } static void xxmc_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) { @@ -2162,7 +2198,7 @@ static void xxmc_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry XUnlockDisplay(this->display); xprintf(this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: double buffering mode = %d\n", xv_double_buffer); + LOG_MODULE ": double buffering mode = %d\n", xv_double_buffer); } static void xxmc_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) { @@ -2201,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) { @@ -2234,7 +2312,7 @@ static void checkXvMCCap( xxmc_driver_t *this, XvPortID xv_port) return; } xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: XvMC extension present.\n"); + LOG_MODULE ": XvMC extension present.\n"); surfaceInfo = XvMCListSurfaceTypes(this->display, xv_port, &numSurf); if (0 == surfaceInfo) { @@ -2250,7 +2328,7 @@ static void checkXvMCCap( xxmc_driver_t *this, XvPortID xv_port) curCap = this->xvmc_cap; xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: Found %d XvMC surface types\n",numSurf); + LOG_MODULE ": Found %d XvMC surface types\n", numSurf); for (i=0; i< numSurf; ++i) { curCap->mpeg_flags = 0; @@ -2274,10 +2352,10 @@ static void checkXvMCCap( xxmc_driver_t *this, XvPortID xv_port) curCap->sub_max_height = curInfo->subpicture_max_height; curCap->flags = curInfo->flags; xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: Surface type %d: Max size: %d %d.\n", + LOG_MODULE ": Surface type %d: Max size: %d %d.\n", i,curCap->max_width,curCap->max_height); xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: Surface type %d: Max subpic size: %d %d.\n", + LOG_MODULE ": Surface type %d: Max subpic size: %d %d.\n", i,curCap->sub_max_width,curCap->sub_max_height); curCap->type_id = curInfo->surface_type_id; @@ -2286,21 +2364,18 @@ static void checkXvMCCap( xxmc_driver_t *this, XvPortID xv_port) curCap->subPicType.id = 0; if (formatValues) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: Surface type %d: Found %d XvMC subpicture " - "types\n",i,numSub); + LOG_MODULE ": Surface type %d: Found %d XvMC subpicture types\n",i,numSub); for (j = 0; j<numSub; ++j) { if (formatValues[j].id == FOURCC_IA44) { curCap->subPicType = formatValues[j]; xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: Surface type %d: Detected and using " - "IA44 subpicture type.\n",i); + LOG_MODULE ": Surface type %d: Detected and using IA44 subpicture type.\n",i); /* Prefer IA44 */ break; } else if (formatValues[j].id == FOURCC_AI44) { curCap->subPicType = formatValues[j]; xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: Surface type %d: Detected AI44 " - "subpicture type.\n",i); + LOG_MODULE ": Surface type %d: Detected AI44 subpicture type.\n",i); } } } @@ -2331,9 +2406,8 @@ static void checkXvMCCap( xxmc_driver_t *this, XvPortID xv_port) free(this->xvmc_cap); this->xvmc_cap = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, - "video_out_xxmc: Apparent attempt to use a direct XvMC " - "context\nvideo_out_xxmc: on a remote display. " - "Falling back to XV.\n"); + LOG_MODULE ": Apparent attempt to use a direct XvMC context on a remote display.\n" + LOG_MODULE ": Falling back to Xv.\n"); XVMCUNLOCKDISPLAY( this->display ); xvmc_context_writer_unlock( &this->xvmc_lock ); return; @@ -2389,7 +2463,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi XLockDisplay(this->display); if (Success != XvQueryExtension(this->display, &ver,&rel, &req, &ev,&err)) { - xprintf (class->xine, XINE_VERBOSITY_LOG, _("video_out_xxmc: Xv extension not present.\n")); + xprintf (class->xine, XINE_VERBOSITY_LOG, _("%s: Xv extension not present.\n"), LOG_MODULE); XUnlockDisplay(this->display); return NULL; } @@ -2399,35 +2473,32 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi */ if (Success != XvQueryAdaptors(this->display,DefaultRootWindow(this->display), &adaptors, &adaptor_info)) { - xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_xxmc: XvQueryAdaptors failed.\n"); + xprintf(class->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": XvQueryAdaptors failed.\n"); XUnlockDisplay(this->display); return NULL; } - xv_port = 0; - - for ( adaptor_num = 0; (adaptor_num < adaptors) && !xv_port; adaptor_num++ ) { + xv_port = config->register_num (config, "video.device.xv_port", 0, + VIDEO_DEVICE_XV_PORT_HELP, + 10, NULL, NULL); - 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; - } + 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, - _("video_out_xxmc: Xv extension is present but I couldn't find a usable yuv12 port.\n" - " Looks like your graphics hardware driver doesn't support Xv?!\n")); + _("%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" + "\tLooks like your graphics hardware driver doesn't support Xv?!\n"), + LOG_MODULE); /* XvFreeAdaptorInfo (adaptor_info); this crashed on me (gb)*/ XUnlockDisplay(this->display); @@ -2435,8 +2506,8 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi } else xprintf(class->xine, XINE_VERBOSITY_LOG, - _("video_out_xxmc: using Xv port %ld from adaptor %s for hardware " - "colour space conversion and scaling.\n"), xv_port, + _("%s: using Xv port %ld from adaptor %s for hardware " + "colour space conversion and scaling.\n"), LOG_MODULE, xv_port, adaptor_info[adaptor_num].name); XUnlockDisplay(this->display); @@ -2451,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; @@ -2510,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, "video_out_xxmc: ignoring broken XV_HUE settings on NVidia cards\n"); + 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); } @@ -2582,7 +2638,7 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi XFree(attr); } else - xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_xxmc: no port attributes defined.\n"); + xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": no port attributes defined.\n"); XvFreeAdaptorInfo(adaptor_info); /* @@ -2607,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, - _("video_out_xxmc: this adaptor supports the yv12 format.\n")); - } 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, - _("video_out_xxmc: this adaptor supports the yuy2 format.\n")); + _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YUY2"); + break; + default: + break; } } @@ -2639,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= @@ -2688,10 +2748,10 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi this->cur_field = XVMC_FRAME_PICTURE; #ifdef HAVE_VLDXVMC - printf("video_out_xxmc: Unichrome CPU saving is %s.\n", + printf("%s: Unichrome CPU saving is %s.\n", LOG_MODULE, (this->cpu_save_enabled) ? "on":"off"); #else - printf("video_out_xxmc: warning - compiled with no vld extensions.\n"); + printf("%s: warning - compiled with no vld extensions.\n", LOG_MODULE); #endif this->props[VO_PROP_MAX_NUM_FRAMES].value = (use_more_frames) ? 15:8; this->cpu_saver = 0.; @@ -2728,28 +2788,13 @@ static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *vi /* * class functions */ - -static char* get_identifier (video_driver_class_t *this_gen) { - return "XxMC"; -} - -static char* get_description (video_driver_class_t *this_gen) { - return _("xine video output plugin using the MIT X video extension"); -} - -static void dispose_class (video_driver_class_t *this_gen) { - xxmc_class_t *this = (xxmc_class_t *) this_gen; - - free (this); -} - static void *init_class (xine_t *xine, void *visual_gen) { xxmc_class_t *this = (xxmc_class_t *) xine_xmalloc (sizeof (xxmc_class_t)); this->driver_class.open_plugin = open_plugin; - this->driver_class.get_identifier = get_identifier; - this->driver_class.get_description = get_description; - this->driver_class.dispose = dispose_class; + this->driver_class.identifier = "XxMC"; + this->driver_class.description = N_("xine video output plugin using the MIT X video extension"); + this->driver_class.dispose = default_video_driver_class_dispose; this->config = xine->config; this->xine = xine; @@ -2771,7 +2816,7 @@ static const vo_info_t vo_info_xxmc = { const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_VIDEO_OUT, 21, "xxmc", XINE_VERSION_CODE, &vo_info_xxmc, init_class }, + { PLUGIN_VIDEO_OUT, 22, "xxmc", XINE_VERSION_CODE, &vo_info_xxmc, init_class }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; |