diff options
Diffstat (limited to 'libvo/vo_xv.c')
-rw-r--r-- | libvo/vo_xv.c | 815 |
1 files changed, 417 insertions, 398 deletions
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c index f84f99fb83..6dfd8a8cf4 100644 --- a/libvo/vo_xv.c +++ b/libvo/vo_xv.c @@ -19,13 +19,17 @@ Buffer allocation: #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdint.h> #include "config.h" +#include "options.h" +#include "talloc.h" #include "mp_msg.h" #include "help_mp.h" #include "video_out.h" -#include "video_out_internal.h" - +#include "libmpcodecs/vfcap.h" +#include "libmpcodecs/mp_image.h" +#include "osd.h" #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -40,6 +44,7 @@ Buffer allocation: #include "subopt-helper.h" #include "input/input.h" +#include "mp_fifo.h" #ifdef CONFIG_GUI #include "gui/interface.h" @@ -54,107 +59,115 @@ static const vo_info_t info = { "" }; -const LIBVO_EXTERN(xv) #ifdef HAVE_SHM #include <sys/ipc.h> #include <sys/shm.h> #include <X11/extensions/XShm.h> - -static XShmSegmentInfo Shminfo[NUM_BUFFERS]; -static int Shmem_Flag; #endif // Note: depends on the inclusion of X11/extensions/XShm.h #include <X11/extensions/Xv.h> #include <X11/extensions/Xvlib.h> -// FIXME: dynamically allocate this stuff -static void allocate_xvimage(int); -static unsigned int ver, rel, req, ev, err; -static unsigned int formats, adaptors, xv_format; -static XvAdaptorInfo *ai = NULL; -static XvImageFormatValues *fo=NULL; - -static int current_buf = 0; -static int current_ip_buf = 0; -static int num_buffers = 1; // default -static int visible_buf = -1; // -1 means: no buffer was drawn yet -static XvImage *xvimage[NUM_BUFFERS]; - - -static uint32_t image_width; -static uint32_t image_height; -static uint32_t image_format; -static int flip_flag; +struct xvctx { + XvAdaptorInfo *ai; + XvImageFormatValues *fo; + unsigned int formats, adaptors, xv_format; + int current_buf; + int current_ip_buf; + int num_buffers; + int visible_buf; + XvImage *xvimage[NUM_BUFFERS]; + uint32_t image_width; + uint32_t image_height; + uint32_t image_format; + int is_paused; + uint32_t drwX, drwY; + uint32_t max_width, max_height; // zero means: not set + int event_fd_registered; // for uninit called from preinit + int mode_switched; + void (*draw_alpha_fnc)(void *ctx, int x0, int y0, int w, int h, + unsigned char *src, unsigned char *srca, + int stride); +#ifdef HAVE_SHM + XShmSegmentInfo Shminfo[NUM_BUFFERS]; + int Shmem_Flag; +#endif +}; -static int int_pause; +// FIXME: dynamically allocate this stuff +static void allocate_xvimage(struct vo *, int); -static Window mRoot; -static uint32_t drwX, drwY, drwBorderWidth, drwDepth; -static uint32_t max_width = 0, max_height = 0; // zero means: not set -static void (*draw_alpha_fnc) (int x0, int y0, int w, int h, - unsigned char *src, unsigned char *srca, - int stride); -static void draw_alpha_yv12(int x0, int y0, int w, int h, +static void draw_alpha_yv12(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { - x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x); + struct vo *vo = p; + struct xvctx *ctx = vo->priv; + x0 += ctx->image_width * (vo->panscan_x >> 1) + / (vo->dwidth + vo->panscan_x); vo_draw_alpha_yv12(w, h, src, srca, stride, - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y0 + x0, - xvimage[current_buf]->pitches[0]); + ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0] + + ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + x0, + ctx->xvimage[ctx->current_buf]->pitches[0]); } -static void draw_alpha_yuy2(int x0, int y0, int w, int h, +static void draw_alpha_yuy2(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { - x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x); + struct vo *vo = p; + struct xvctx *ctx = vo->priv; + x0 += ctx->image_width * (vo->panscan_x >> 1) + / (vo->dwidth + vo->panscan_x); vo_draw_alpha_yuy2(w, h, src, srca, stride, - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y0 + 2 * x0, - xvimage[current_buf]->pitches[0]); + ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0] + + ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + 2 * x0, + ctx->xvimage[ctx->current_buf]->pitches[0]); } -static void draw_alpha_uyvy(int x0, int y0, int w, int h, +static void draw_alpha_uyvy(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { - x0 += image_width * (vo_panscan_x >> 1) / (vo_dwidth + vo_panscan_x); + struct vo *vo = p; + struct xvctx *ctx = vo->priv; + x0 += ctx->image_width * (vo->panscan_x >> 1) + / (vo->dwidth + vo->panscan_x); vo_draw_alpha_yuy2(w, h, src, srca, stride, - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y0 + 2 * x0 + 1, - xvimage[current_buf]->pitches[0]); + ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0] + + ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + 2 * x0 + 1, + ctx->xvimage[ctx->current_buf]->pitches[0]); } -static void draw_alpha_null(int x0, int y0, int w, int h, +static void draw_alpha_null(void *p, int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) { } -static void deallocate_xvimage(int foo); +static void deallocate_xvimage(struct vo *vo, int foo); -static void calc_drwXY(uint32_t *drwX, uint32_t *drwY) { +static void calc_drwXY(struct vo *vo, uint32_t *drwX, uint32_t *drwY) { + struct MPOpts *opts = vo->opts; *drwX = *drwY = 0; if (vo_fs) { - aspect(&vo_dwidth, &vo_dheight, A_ZOOM); - vo_dwidth = FFMIN(vo_dwidth, vo_screenwidth); - vo_dheight = FFMIN(vo_dheight, vo_screenheight); - *drwX = (vo_screenwidth - vo_dwidth) / 2; - *drwY = (vo_screenheight - vo_dheight) / 2; + aspect(vo, &vo->dwidth, &vo->dheight, A_ZOOM); + vo->dwidth = FFMIN(vo->dwidth, opts->vo_screenwidth); + vo->dheight = FFMIN(vo->dheight, opts->vo_screenheight); + *drwX = (opts->vo_screenwidth - vo->dwidth) / 2; + *drwY = (opts->vo_screenheight - vo->dheight) / 2; mp_msg(MSGT_VO, MSGL_V, "[xv-fs] dx: %d dy: %d dw: %d dh: %d\n", - *drwX, *drwY, vo_dwidth, vo_dheight); + *drwX, *drwY, vo->dwidth, vo->dheight); } else if (WinID == 0) { - *drwX = vo_dx; - *drwY = vo_dy; + *drwX = vo->dx; + *drwY = vo->dy; } } @@ -162,10 +175,12 @@ static void calc_drwXY(uint32_t *drwX, uint32_t *drwY) { * connect to server, create and map window, * allocate colors and (shared) memory */ -static int config(uint32_t width, uint32_t height, uint32_t d_width, - uint32_t d_height, uint32_t flags, char *title, - uint32_t format) +static int config(struct vo *vo, uint32_t width, uint32_t height, + uint32_t d_width, uint32_t d_height, uint32_t flags, + char *title, uint32_t format) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; XSizeHints hint; XVisualInfo vinfo; XGCValues xgcv; @@ -173,56 +188,38 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, XWindowAttributes attribs; unsigned long xswamask; int depth; + struct xvctx *ctx = vo->priv; + int i; -#ifdef CONFIG_XF86VM - int vm = 0; - unsigned int modeline_width, modeline_height; - static uint32_t vm_width; - static uint32_t vm_height; -#endif - - image_height = height; - image_width = width; - image_format = format; + ctx->image_height = height; + ctx->image_width = width; + ctx->image_format = format; - if ((max_width != 0 && max_height != 0) && - (image_width > max_width || image_height > max_height)) + if ((ctx->max_width != 0 && ctx->max_height != 0) && + (ctx->image_width > ctx->max_width || ctx->image_height > ctx->max_height)) { mp_msg( MSGT_VO, MSGL_ERR, MSGTR_VO_XV_ImagedimTooHigh, - image_width, image_height, max_width, max_height); + ctx->image_width, ctx->image_height, ctx->max_width, ctx->max_height); return -1; } - vo_mouse_autohide = 1; + x11->vo_mouse_autohide = 1; - int_pause = 0; - visible_buf = -1; - -#ifdef CONFIG_XF86VM - if (flags & VOFLAG_MODESWITCHING) - vm = 1; -#endif - flip_flag = flags & VOFLAG_FLIPPING; - num_buffers = - vo_doublebuffering ? (vo_directrendering ? NUM_BUFFERS : 2) : 1; + ctx->is_paused = 0; + ctx->visible_buf = -1; /* check image formats */ - { - unsigned int i; - - xv_format = 0; - for (i = 0; i < formats; i++) - { - mp_msg(MSGT_VO, MSGL_V, - "Xvideo image format: 0x%x (%4.4s) %s\n", fo[i].id, - (char *) &fo[i].id, - (fo[i].format == XvPacked) ? "packed" : "planar"); - if (fo[i].id == format) - xv_format = fo[i].id; - } - if (!xv_format) - return -1; + ctx->xv_format = 0; + for (i = 0; i < ctx->formats; i++) { + mp_msg(MSGT_VO, MSGL_V, + "Xvideo image format: 0x%x (%4.4s) %s\n", ctx->fo[i].id, + (char *) &ctx->fo[i].id, + (ctx->fo[i].format == XvPacked) ? "packed" : "planar"); + if (ctx->fo[i].id == format) + ctx->xv_format = ctx->fo[i].id; } + if (!ctx->xv_format) + return -1; #ifdef CONFIG_GUI if (use_gui) @@ -230,58 +227,64 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, else #endif { - hint.x = vo_dx; - hint.y = vo_dy; + hint.x = vo->dx; + hint.y = vo->dy; hint.width = d_width; hint.height = d_height; #ifdef CONFIG_XF86VM + unsigned int modeline_width, modeline_height; + uint32_t vm_width; + uint32_t vm_height; + int vm = flags & VOFLAG_MODESWITCHING; if (vm) { if ((d_width == 0) && (d_height == 0)) { - vm_width = image_width; - vm_height = image_height; + vm_width = ctx->image_width; + vm_height = ctx->image_height; } else { vm_width = d_width; vm_height = d_height; } - vo_vm_switch(vm_width, vm_height, &modeline_width, + vo_vm_switch(vo, vm_width, vm_height, &modeline_width, &modeline_height); - hint.x = (vo_screenwidth - modeline_width) / 2; - hint.y = (vo_screenheight - modeline_height) / 2; + ctx->mode_switched = 1; + hint.x = (opts->vo_screenwidth - modeline_width) / 2; + hint.y = (opts->vo_screenheight - modeline_height) / 2; hint.width = modeline_width; hint.height = modeline_height; - aspect_save_screenres(modeline_width, modeline_height); + aspect_save_screenres(vo, modeline_width, modeline_height); } else +#warning This "else" makes no sense #endif hint.flags = PPosition | PSize /* | PBaseSize */ ; hint.base_width = hint.width; hint.base_height = hint.height; - XGetWindowAttributes(mDisplay, DefaultRootWindow(mDisplay), + XGetWindowAttributes(x11->display, DefaultRootWindow(x11->display), &attribs); depth = attribs.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) depth = 24; - XMatchVisualInfo(mDisplay, mScreen, depth, TrueColor, &vinfo); + XMatchVisualInfo(x11->display, x11->screen, depth, TrueColor, &vinfo); xswa.background_pixel = 0; - if (xv_ck_info.method == CK_METHOD_BACKGROUND) + if (x11->xv_ck_info.method == CK_METHOD_BACKGROUND) { - xswa.background_pixel = xv_colorkey; + xswa.background_pixel = x11->xv_colorkey; } xswa.border_pixel = 0; xswamask = CWBackPixel | CWBorderPixel; if (WinID >= 0) { - vo_window = WinID ? ((Window) WinID) : mRootWin; + x11->window = WinID ? ((Window) WinID) : x11->rootwin; if (WinID) { - XUnmapWindow(mDisplay, vo_window); - XChangeWindowAttributes(mDisplay, vo_window, xswamask, + XUnmapWindow(x11->display, x11->window); + XChangeWindowAttributes(x11->display, x11->window, xswamask, &xswa); - vo_x11_selectinput_witherr(mDisplay, vo_window, + vo_x11_selectinput_witherr(x11->display, x11->window, StructureNotifyMask | KeyPressMask | PropertyChangeMask | @@ -289,267 +292,261 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width, ButtonPressMask | ButtonReleaseMask | ExposureMask); - XMapWindow(mDisplay, vo_window); - XGetGeometry(mDisplay, vo_window, &mRoot, - &drwX, &drwY, &vo_dwidth, &vo_dheight, + XMapWindow(x11->display, x11->window); + Window mRoot; + uint32_t drwBorderWidth, drwDepth; + XGetGeometry(x11->display, x11->window, &mRoot, + &ctx->drwX, &ctx->drwY, &vo->dwidth, &vo->dheight, &drwBorderWidth, &drwDepth); - if (vo_dwidth <= 0) vo_dwidth = d_width; - if (vo_dheight <= 0) vo_dheight = d_height; - aspect_save_prescale(vo_dwidth, vo_dheight); + if (vo->dwidth <= 0) vo->dwidth = d_width; + if (vo->dheight <= 0) vo->dheight = d_height; + aspect_save_prescale(vo, vo->dwidth, vo->dheight); } } else { - vo_x11_create_vo_window(&vinfo, vo_dx, vo_dy, d_width, d_height, + vo_x11_create_vo_window(vo, &vinfo, vo->dx, vo->dy, d_width, d_height, flags, CopyFromParent, "xv", title); - XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); + XChangeWindowAttributes(x11->display, x11->window, xswamask, &xswa); } - if (vo_gc != None) - XFreeGC(mDisplay, vo_gc); - vo_gc = XCreateGC(mDisplay, vo_window, 0L, &xgcv); - XSync(mDisplay, False); + if (x11->vo_gc != None) + XFreeGC(x11->display, x11->vo_gc); + x11->vo_gc = XCreateGC(x11->display, x11->window, 0L, &xgcv); + XSync(x11->display, False); #ifdef CONFIG_XF86VM if (vm) { /* Grab the mouse pointer in our window */ if (vo_grabpointer) - XGrabPointer(mDisplay, vo_window, True, 0, + XGrabPointer(x11->display, x11->window, True, 0, GrabModeAsync, GrabModeAsync, - vo_window, None, CurrentTime); - XSetInputFocus(mDisplay, vo_window, RevertToNone, CurrentTime); + x11->window, None, CurrentTime); + XSetInputFocus(x11->display, x11->window, RevertToNone, CurrentTime); } #endif } mp_msg(MSGT_VO, MSGL_V, "using Xvideo port %d for hw scaling\n", - xv_port); + x11->xv_port); - switch (xv_format) + switch (ctx->xv_format) { case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: - draw_alpha_fnc = draw_alpha_yv12; + ctx->draw_alpha_fnc = draw_alpha_yv12; break; case IMGFMT_YUY2: case IMGFMT_YVYU: - draw_alpha_fnc = draw_alpha_yuy2; + ctx->draw_alpha_fnc = draw_alpha_yuy2; break; case IMGFMT_UYVY: - draw_alpha_fnc = draw_alpha_uyvy; + ctx->draw_alpha_fnc = draw_alpha_uyvy; break; default: - draw_alpha_fnc = draw_alpha_null; + ctx->draw_alpha_fnc = draw_alpha_null; } - if (vo_config_count) - for (current_buf = 0; current_buf < num_buffers; ++current_buf) - deallocate_xvimage(current_buf); + // In case config has been called before + for (i = 0; i < ctx->num_buffers; i++) + deallocate_xvimage(vo, i); + + ctx->num_buffers = + vo_doublebuffering ? (vo_directrendering ? NUM_BUFFERS : 2) : 1; - for (current_buf = 0; current_buf < num_buffers; ++current_buf) - allocate_xvimage(current_buf); + for (i = 0; i < ctx->num_buffers; i++) + allocate_xvimage(vo, i); - current_buf = 0; - current_ip_buf = 0; + ctx->current_buf = 0; + ctx->current_ip_buf = 0; #if 0 set_gamma_correction(); #endif - aspect(&vo_dwidth, &vo_dheight, A_NOZOOM); + aspect(vo, &vo->dwidth, &vo->dheight, A_NOZOOM); if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) vo_fs = 1; - calc_drwXY(&drwX, &drwY); + calc_drwXY(vo, &ctx->drwX, &ctx->drwY); - panscan_calc(); + panscan_calc(vo); - vo_xv_draw_colorkey(drwX - (vo_panscan_x >> 1), - drwY - (vo_panscan_y >> 1), - vo_dwidth + vo_panscan_x - 1, - vo_dheight + vo_panscan_y - 1); + vo_xv_draw_colorkey(vo, ctx->drwX - (vo->panscan_x >> 1), + ctx->drwY - (vo->panscan_y >> 1), + vo->dwidth + vo->panscan_x - 1, + vo->dheight + vo->panscan_y - 1); + mp_msg(MSGT_VO, MSGL_V, "[xv] dx: %d dy: %d dw: %d dh: %d\n", ctx->drwX, + ctx->drwY, vo->dwidth, vo->dheight); -#if 0 -#ifdef HAVE_SHM - if (Shmem_Flag) - { - XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc, - xvimage[current_buf], 0, 0, image_width, - image_height, drwX, drwY, 1, 1, False); - XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc, - xvimage[current_buf], 0, 0, image_width, - image_height, drwX, drwY, vo_dwidth, - (vo_fs ? vo_dheight - 1 : vo_dheight), False); - } else -#endif - { - XvPutImage(mDisplay, xv_port, vo_window, vo_gc, - xvimage[current_buf], 0, 0, image_width, image_height, - drwX, drwY, 1, 1); - XvPutImage(mDisplay, xv_port, vo_window, vo_gc, - xvimage[current_buf], 0, 0, image_width, image_height, - drwX, drwY, vo_dwidth, - (vo_fs ? vo_dheight - 1 : vo_dheight)); - } -#endif - - mp_msg(MSGT_VO, MSGL_V, "[xv] dx: %d dy: %d dw: %d dh: %d\n", drwX, - drwY, vo_dwidth, vo_dheight); - - if (vo_ontop) - vo_x11_setlayer(mDisplay, vo_window, vo_ontop); + if (opts->vo_ontop) + vo_x11_setlayer(vo, x11->window, opts->vo_ontop); return 0; } -static void allocate_xvimage(int foo) +static void allocate_xvimage(struct vo *vo, int foo) { + struct xvctx *ctx = vo->priv; + struct vo_x11_state *x11 = vo->x11; /* * allocate XvImages. FIXME: no error checking, without * mit-shm this will bomb... trzing to fix ::atmos */ #ifdef HAVE_SHM - if (mLocalDisplay && XShmQueryExtension(mDisplay)) - Shmem_Flag = 1; + if (x11->display_is_local && XShmQueryExtension(x11->display)) + ctx->Shmem_Flag = 1; else { - Shmem_Flag = 0; + ctx->Shmem_Flag = 0; mp_msg(MSGT_VO, MSGL_INFO, MSGTR_LIBVO_XV_SharedMemoryNotSupported); } - if (Shmem_Flag) + if (ctx->Shmem_Flag) { - xvimage[foo] = - (XvImage *) XvShmCreateImage(mDisplay, xv_port, xv_format, - NULL, image_width, image_height, - &Shminfo[foo]); - - Shminfo[foo].shmid = - shmget(IPC_PRIVATE, xvimage[foo]->data_size, IPC_CREAT | 0777); - Shminfo[foo].shmaddr = (char *) shmat(Shminfo[foo].shmid, 0, 0); - Shminfo[foo].readOnly = False; - - xvimage[foo]->data = Shminfo[foo].shmaddr; - XShmAttach(mDisplay, &Shminfo[foo]); - XSync(mDisplay, False); - shmctl(Shminfo[foo].shmid, IPC_RMID, 0); + ctx->xvimage[foo] = + (XvImage *) XvShmCreateImage(x11->display, x11->xv_port, ctx->xv_format, + NULL, ctx->image_width, ctx->image_height, + &ctx->Shminfo[foo]); + + ctx->Shminfo[foo].shmid = + shmget(IPC_PRIVATE, ctx->xvimage[foo]->data_size, IPC_CREAT | 0777); + ctx->Shminfo[foo].shmaddr = (char *) shmat(ctx->Shminfo[foo].shmid, 0, 0); + ctx->Shminfo[foo].readOnly = False; + + ctx->xvimage[foo]->data = ctx->Shminfo[foo].shmaddr; + XShmAttach(x11->display, &ctx->Shminfo[foo]); + XSync(x11->display, False); + shmctl(ctx->Shminfo[foo].shmid, IPC_RMID, 0); } else #endif { - xvimage[foo] = - (XvImage *) XvCreateImage(mDisplay, xv_port, xv_format, NULL, - image_width, image_height); - xvimage[foo]->data = malloc(xvimage[foo]->data_size); - XSync(mDisplay, False); + ctx->xvimage[foo] = + (XvImage *) XvCreateImage(x11->display, x11->xv_port, ctx->xv_format, NULL, + ctx->image_width, ctx->image_height); + ctx->xvimage[foo]->data = malloc(ctx->xvimage[foo]->data_size); + XSync(x11->display, False); } - memset(xvimage[foo]->data, 128, xvimage[foo]->data_size); + memset(ctx->xvimage[foo]->data, 128, ctx->xvimage[foo]->data_size); return; } -static void deallocate_xvimage(int foo) +static void deallocate_xvimage(struct vo *vo, int foo) { + struct xvctx *ctx = vo->priv; #ifdef HAVE_SHM - if (Shmem_Flag) + if (ctx->Shmem_Flag) { - XShmDetach(mDisplay, &Shminfo[foo]); - shmdt(Shminfo[foo].shmaddr); + XShmDetach(vo->x11->display, &ctx->Shminfo[foo]); + shmdt(ctx->Shminfo[foo].shmaddr); } else #endif { - free(xvimage[foo]->data); + free(ctx->xvimage[foo]->data); } - XFree(xvimage[foo]); + XFree(ctx->xvimage[foo]); - XSync(mDisplay, False); + XSync(vo->x11->display, False); return; } -static inline void put_xvimage( XvImage * xvi ) +static inline void put_xvimage(struct vo *vo, XvImage *xvi) { + struct xvctx *ctx = vo->priv; + struct vo_x11_state *x11 = vo->x11; #ifdef HAVE_SHM - if (Shmem_Flag) + if (ctx->Shmem_Flag) { - XvShmPutImage(mDisplay, xv_port, vo_window, vo_gc, - xvi, 0, 0, image_width, - image_height, drwX - (vo_panscan_x >> 1), - drwY - (vo_panscan_y >> 1), vo_dwidth + vo_panscan_x, - vo_dheight + vo_panscan_y, + XvShmPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, + xvi, 0, 0, ctx->image_width, + ctx->image_height, ctx->drwX - (vo->panscan_x >> 1), + ctx->drwY - (vo->panscan_y >> 1), vo->dwidth + vo->panscan_x, + vo->dheight + vo->panscan_y, False); } else #endif { - XvPutImage(mDisplay, xv_port, vo_window, vo_gc, - xvi, 0, 0, image_width, image_height, - drwX - (vo_panscan_x >> 1), drwY - (vo_panscan_y >> 1), - vo_dwidth + vo_panscan_x, - vo_dheight + vo_panscan_y); + XvPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, + xvi, 0, 0, ctx->image_width, ctx->image_height, + ctx->drwX - (vo->panscan_x >> 1), ctx->drwY - (vo->panscan_y >> 1), + vo->dwidth + vo->panscan_x, + vo->dheight + vo->panscan_y); } } -static void check_events(void) +static void check_events(struct vo *vo) { - int e = vo_x11_check_events(mDisplay); + struct xvctx *ctx = vo->priv; + struct vo_x11_state *x11 = vo->x11; + int e = vo_x11_check_events(vo); if (e & VO_EVENT_RESIZE) { - XGetGeometry(mDisplay, vo_window, &mRoot, &drwX, &drwY, &vo_dwidth, - &vo_dheight, &drwBorderWidth, &drwDepth); - mp_msg(MSGT_VO, MSGL_V, "[xv] dx: %d dy: %d dw: %d dh: %d\n", drwX, - drwY, vo_dwidth, vo_dheight); - - calc_drwXY(&drwX, &drwY); + Window mRoot; + uint32_t drwBorderWidth, drwDepth; + XGetGeometry(x11->display, x11->window, &mRoot, &ctx->drwX, &ctx->drwY, + &vo->dwidth, &vo->dheight, &drwBorderWidth, &drwDepth); + mp_msg(MSGT_VO, MSGL_V, "[xv] dx: %d dy: %d dw: %d dh: %d\n", ctx->drwX, + ctx->drwY, vo->dwidth, vo->dheight); + + calc_drwXY(vo, &ctx->drwX, &ctx->drwY); } if (e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) { - vo_xv_draw_colorkey(drwX - (vo_panscan_x >> 1), - drwY - (vo_panscan_y >> 1), - vo_dwidth + vo_panscan_x - 1, - vo_dheight + vo_panscan_y - 1); + vo_xv_draw_colorkey(vo, ctx->drwX - (vo->panscan_x >> 1), + ctx->drwY - (vo->panscan_y >> 1), + vo->dwidth + vo->panscan_x - 1, + vo->dheight + vo->panscan_y - 1); } - if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && int_pause) + if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && ctx->is_paused) { /* did we already draw a buffer */ - if ( visible_buf != -1 ) + if ( ctx->visible_buf != -1 ) { /* redraw the last visible buffer */ - put_xvimage( xvimage[visible_buf] ); + put_xvimage(vo, ctx->xvimage[ctx->visible_buf]); } } } -static void draw_osd(void) +static void draw_osd(struct vo *vo, struct osd_state *osd) { - vo_draw_text(image_width - - image_width * vo_panscan_x / (vo_dwidth + vo_panscan_x), - image_height, draw_alpha_fnc); + struct xvctx *ctx = vo->priv; + + osd_draw_text(osd, ctx->image_width - + ctx->image_width * vo->panscan_x / (vo->dwidth + vo->panscan_x), + ctx->image_height, ctx->draw_alpha_fnc, vo); } -static void flip_page(void) +static void flip_page(struct vo *vo) { - put_xvimage( xvimage[current_buf] ); + struct xvctx *ctx = vo->priv; + put_xvimage(vo, ctx->xvimage[ctx->current_buf]); /* remember the currently visible buffer */ - visible_buf = current_buf; + ctx->visible_buf = ctx->current_buf; - if (num_buffers > 1) + if (ctx->num_buffers > 1) { - current_buf = - vo_directrendering ? 0 : ((current_buf + 1) % num_buffers); - XFlush(mDisplay); + ctx->current_buf = + vo_directrendering ? 0 : ((ctx->current_buf + 1) % ctx->num_buffers); + XFlush(vo->x11->display); } else - XSync(mDisplay, False); + XSync(vo->x11->display, False); return; } -static int draw_slice(uint8_t * image[], int stride[], int w, int h, - int x, int y) +static int draw_slice(struct vo *vo, uint8_t * image[], int stride[], int w, + int h, int x, int y) { + struct xvctx *ctx = vo->priv; uint8_t *dst; + XvImage *current_image = ctx->xvimage[ctx->current_buf]; - dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[0] + - xvimage[current_buf]->pitches[0] * y + x; - memcpy_pic(dst, image[0], w, h, xvimage[current_buf]->pitches[0], + dst = current_image->data + current_image->offsets[0] + + current_image->pitches[0] * y + x; + memcpy_pic(dst, image[0], w, h, current_image->pitches[0], stride[0]); x /= 2; @@ -557,95 +554,96 @@ static int draw_slice(uint8_t * image[], int stride[], int w, int h, w /= 2; h /= 2; - dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[1] + - xvimage[current_buf]->pitches[1] * y + x; - if (image_format != IMGFMT_YV12) - memcpy_pic(dst, image[1], w, h, xvimage[current_buf]->pitches[1], + dst = current_image->data + current_image->offsets[1] + + current_image->pitches[1] * y + x; + if (ctx->image_format != IMGFMT_YV12) + memcpy_pic(dst, image[1], w, h, current_image->pitches[1], stride[1]); else - memcpy_pic(dst, image[2], w, h, xvimage[current_buf]->pitches[1], + memcpy_pic(dst, image[2], w, h, current_image->pitches[1], stride[2]); - dst = xvimage[current_buf]->data + xvimage[current_buf]->offsets[2] + - xvimage[current_buf]->pitches[2] * y + x; - if (image_format == IMGFMT_YV12) - memcpy_pic(dst, image[1], w, h, xvimage[current_buf]->pitches[1], + dst = current_image->data + current_image->offsets[2] + + current_image->pitches[2] * y + x; + if (ctx->image_format == IMGFMT_YV12) + memcpy_pic(dst, image[1], w, h, current_image->pitches[1], stride[1]); else - memcpy_pic(dst, image[2], w, h, xvimage[current_buf]->pitches[1], + memcpy_pic(dst, image[2], w, h, current_image->pitches[1], stride[2]); return 0; } -static int draw_frame(uint8_t * src[]) +static int draw_frame(struct vo *vo, uint8_t * src[]) { mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_XV_DrawFrameCalled); return -1; } -static uint32_t draw_image(mp_image_t * mpi) +static uint32_t draw_image(struct vo *vo, mp_image_t * mpi) { + struct xvctx *ctx = vo->priv; if (mpi->flags & MP_IMGFLAG_DIRECT) { // direct rendering: - current_buf = (int) (mpi->priv); // hack! + ctx->current_buf = (int) (mpi->priv); // hack! return VO_TRUE; } if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK) return VO_TRUE; // done if (mpi->flags & MP_IMGFLAG_PLANAR) { - draw_slice(mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0); + draw_slice(vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0); return VO_TRUE; } if (mpi->flags & MP_IMGFLAG_YUV) { // packed YUV: - memcpy_pic(xvimage[current_buf]->data + - xvimage[current_buf]->offsets[0], mpi->planes[0], + memcpy_pic(ctx->xvimage[ctx->current_buf]->data + + ctx->xvimage[ctx->current_buf]->offsets[0], mpi->planes[0], mpi->w * (mpi->bpp / 8), mpi->h, - xvimage[current_buf]->pitches[0], mpi->stride[0]); + ctx->xvimage[ctx->current_buf]->pitches[0], mpi->stride[0]); return VO_TRUE; } return VO_FALSE; // not (yet) supported } -static uint32_t get_image(mp_image_t * mpi) +static uint32_t get_image(struct xvctx *ctx, mp_image_t * mpi) { - int buf = current_buf; // we shouldn't change current_buf unless we do DR! + int buf = ctx->current_buf; // we shouldn't change current_buf unless we do DR! - if (mpi->type == MP_IMGTYPE_STATIC && num_buffers > 1) + if (mpi->type == MP_IMGTYPE_STATIC && ctx->num_buffers > 1) return VO_FALSE; // it is not static - if (mpi->imgfmt != image_format) + if (mpi->imgfmt != ctx->image_format) return VO_FALSE; // needs conversion :( // if(mpi->flags&MP_IMGFLAG_READABLE) return VO_FALSE; // slow video ram if (mpi->flags & MP_IMGFLAG_READABLE && (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP)) { // reference (I/P) frame of IP or IPB: - if (num_buffers < 2) + if (ctx->num_buffers < 2) return VO_FALSE; // not enough - current_ip_buf ^= 1; + ctx->current_ip_buf ^= 1; // for IPB with 2 buffers we can DR only one of the 2 P frames: - if (mpi->type == MP_IMGTYPE_IPB && num_buffers < 3 - && current_ip_buf) + if (mpi->type == MP_IMGTYPE_IPB && ctx->num_buffers < 3 + && ctx->current_ip_buf) return VO_FALSE; - buf = current_ip_buf; + buf = ctx->current_ip_buf; if (mpi->type == MP_IMGTYPE_IPB) ++buf; // preserve space for B } - if (mpi->height > xvimage[buf]->height) + if (mpi->height > ctx->xvimage[buf]->height) return VO_FALSE; //buffer to small - if (mpi->width * (mpi->bpp / 8) > xvimage[buf]->pitches[0]) + if (mpi->width * (mpi->bpp / 8) > ctx->xvimage[buf]->pitches[0]) return VO_FALSE; //buffer to small if ((mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH)) - || (mpi->width * (mpi->bpp / 8) == xvimage[buf]->pitches[0])) + || (mpi->width * (mpi->bpp / 8) == ctx->xvimage[buf]->pitches[0])) { - current_buf = buf; - mpi->planes[0] = - xvimage[current_buf]->data + xvimage[current_buf]->offsets[0]; - mpi->stride[0] = xvimage[current_buf]->pitches[0]; + ctx->current_buf = buf; + XvImage *current_image = ctx->xvimage[ctx->current_buf]; + mpi->planes[0] = current_image->data + current_image->offsets[0]; + mpi->stride[0] = current_image->pitches[0]; mpi->width = mpi->stride[0] / (mpi->bpp / 8); if (mpi->flags & MP_IMGFLAG_PLANAR) { @@ -653,90 +651,103 @@ static uint32_t get_image(mp_image_t * mpi) { // I420 mpi->planes[1] = - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[1]; + current_image->data + + current_image->offsets[1]; mpi->planes[2] = - xvimage[current_buf]->data + - xvimage[current_buf]->offsets[2]; - mpi->stride[1] = xvimage[current_buf]- |