diff -ru xine-lib.org/src/video_out/Makefile.am xine-lib/src/video_out/Makefile.am --- xine-lib.org/src/video_out/Makefile.am 2007-08-29 21:56:36.000000000 +0200 +++ xine-lib/src/video_out/Makefile.am 2008-07-11 16:29:26.000000000 +0200 @@ -116,7 +116,7 @@ xineplug_vo_out_xshm_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(MLIB_CFLAGS) -fno-strict-aliasing xineplug_vo_out_xv_la_SOURCES = $(X11OSD) deinterlace.c video_out_xv.c -xineplug_vo_out_xv_la_LIBADD = $(XV_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) +xineplug_vo_out_xv_la_LIBADD = $(XV_LIBS) $(X_LIBS) $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) -ldrm xineplug_vo_out_xv_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(XV_CFLAGS) -fno-strict-aliasing xineplug_vo_out_xvmc_la_SOURCES = deinterlace.c video_out_xvmc.c diff -ru xine-lib.org/src/video_out/video_out_xv.c xine-lib/src/video_out/video_out_xv.c --- xine-lib.org/src/video_out/video_out_xv.c 2008-02-07 18:03:12.000000000 +0100 +++ xine-lib/src/video_out/video_out_xv.c 2008-07-20 21:12:08.000000000 +0200 @@ -73,6 +73,20 @@ #include "vo_scale.h" #include "x11osd.h" +#define SYNC_FIELDS + +#ifdef SYNC_FIELDS +#define LENNY +#include +#ifdef LENNY +# include +#else +# include +#endif +#include +extern int drmOpen(); +#endif + #define LOCK_DISPLAY(this) {if(this->lock_display) this->lock_display(this->user_data); \ else XLockDisplay(this->display);} #define UNLOCK_DISPLAY(this) {if(this->unlock_display) this->unlock_display(this->user_data); \ @@ -827,6 +841,103 @@ LOCK_DISPLAY(this); start_time = timeOfDay(); if (this->use_shm) { + +#ifdef SYNC_FIELDS + static int fd; + static drm_radeon_vsync_t vsync; + + if (!fd) { + drm_radeon_setparam_t vbl_activate; + + if ((fd = drmOpen("radeon", 0)) < 0) { + printf("drmOpen: %s\n", strerror(errno)); + } + vbl_activate.param = RADEON_SETPARAM_VBLANK_CRTC; + vbl_activate.value = DRM_RADEON_VBLANK_CRTC1; + if (ioctl(fd, DRM_IOCTL_RADEON_SETPARAM, &vbl_activate)) { + printf("DRM_IOCTL_RADEON_SETPARAM: %s\n", strerror(errno)); + } + } + if (ioctl(fd, DRM_IOCTL_RADEON_VSYNC, &vsync)) { + printf("DRM_IOCTL_RADEON_VSYNC: %s\n", strerror(errno)); + } + +/* + * here we continuously monitor and correct placement of xine-lib's + * xv_display_frame() call in relation to vertical blanking intervals (VBI) + * of graphics card. + * + * to achieve maximum immunity against jitter we always center the call + * to xv_display_frame() within the middle of 2 consecutive VBIs. + * + * there are no special hysteresis requirements: + * we even can choose another vbl_trim value each adjacent call + * + * theory of operation: + * + * - a vbl_trim value of 0 yields in a slower graphics card frame rate + * + * - thus increasing the time between 2 VBIs + * + * - as a result from xv_display_frame()-call point of view the + * time distance to the last VBI decreases + * + * - dependend on value of vsync.vbl_since.tv_usec (the elapsed + * time since last VBI) we decide whether to increase + * or to decrease graphics cards framerate. + * + * - illustration of how VBI of graphics card wanders into + * the center of xines xv_display_frame() calls, if graphics card framerate + * is a little slower than xine's call to xv_display_frame() + * + * xine reference clock (calls to xv_display_frame()): + * ______ ________ ________ ________ + * |________| |________| |________| |_______ + * ^ ^ + * | | + * graphics card clock (VBLANK edges): | + * _______| _________ _________| ________ + * |_________| |_________| |_________| |__ + * | | + * out of center centered + * | | + * | <--- edge drifts into the middle ---> | + * | of xine reference clock phase | + * + * some annotations: + * + * RGB PAL runs at 50Hz resulting in cycle duration of 20000us + * so we ideally would use a SYNC_POINT value of 10000 here. + * but we also have to consider some latency until Xserver finally + * executes putimage() + * + * FIX_ME! + * we currently abuse sync mechanism to avoid tearing when + * textured XV adaptor is selected. so we at the moment place SYNC_POINT + * close to the end of active display phase. + * + * VALUES HERE ARE QUICKLY HACKED AND ARE VALID FOR MY SYSTEM. + * YOU MUST ADAPT THEM TO YOUR NEEDS UNTIL AUTOMATIC + * TIMING TRIM ALGORITHM WILL BE IMPLEMENTED. + */ + +// tinajas sync collection +//#define SYNC_POINT 16500 +//#define VBL_TRIM_UPPER 0x00c84618 /* -351 */ +//#define VBL_TRIM_LOWER 0 /* +341 */ + +// senitas sync collection +#define SYNC_POINT 15000 +#define VBL_TRIM_UPPER 0x00c84605 /* -234 */ +#define VBL_TRIM_LOWER 0x40c8460b /* +228 */ + + if (vsync.vbl_since.tv_usec < SYNC_POINT) { + vsync.vbl_trim = VBL_TRIM_UPPER; + } else { + vsync.vbl_trim = VBL_TRIM_LOWER; + } +#endif + XvShmPutImage(this->display, this->xv_port, this->drawable, this->gc, this->cur_frame->image, this->sc.displayed_xoffset, this->sc.displayed_yoffset,