summaryrefslogtreecommitdiffstats
path: root/libvo
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2009-01-15 00:29:51 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2009-01-15 00:29:51 +0200
commit02bc48b67dd88c974c8f9298a0c50cbfcd51af41 (patch)
tree9e826e3d0494ce20cc115d85866f3e7472e21d60 /libvo
parentc1b80dcbbb34d63df65c0f52c0bede66dfa225e8 (diff)
parent38a76f7fdf5c03bc49072b693d7c53b343f2994a (diff)
downloadmpv-02bc48b67dd88c974c8f9298a0c50cbfcd51af41.tar.bz2
mpv-02bc48b67dd88c974c8f9298a0c50cbfcd51af41.tar.xz
Merge branch 'pause'
Diffstat (limited to 'libvo')
-rw-r--r--libvo/video_out.h2
-rw-r--r--libvo/vo_gl.c6
-rw-r--r--libvo/vo_xv.c571
3 files changed, 300 insertions, 279 deletions
diff --git a/libvo/video_out.h b/libvo/video_out.h
index 465697927f..e0bc79976e 100644
--- a/libvo/video_out.h
+++ b/libvo/video_out.h
@@ -87,6 +87,8 @@ typedef struct {
} mp_colorkey_t;
#define VOCTRL_XOVERLAY_SET_WIN 23
+#define VOCTRL_REDRAW_OSD 24
+
typedef struct {
int x,y;
int w,h;
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index 4178daff9c..340b32b5a5 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -1147,6 +1147,12 @@ static int control(uint32_t request, void *data)
case VOCTRL_UPDATE_SCREENINFO:
update_xinerama_info();
return VO_TRUE;
+ case VOCTRL_REDRAW_OSD:
+ if (vo_doublebuffering)
+ do_render();
+ draw_osd();
+ flip_page();
+ return VO_TRUE;
}
return VO_NOTIMPL;
}
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index f95ea82b53..9c4dd391df 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -20,6 +20,7 @@ Buffer allocation:
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
+#include <stdbool.h>
#include "config.h"
#include "options.h"
@@ -76,8 +77,13 @@ struct xvctx {
int current_buf;
int current_ip_buf;
int num_buffers;
+ int total_buffers;
+ int have_visible_image_copy;
+ int have_next_image_copy;
+ int unchanged_visible_image;
+ int unchanged_next_image;
int visible_buf;
- XvImage *xvimage[NUM_BUFFERS];
+ XvImage *xvimage[NUM_BUFFERS + 1];
uint32_t image_width;
uint32_t image_height;
uint32_t image_format;
@@ -86,6 +92,7 @@ struct xvctx {
uint32_t max_width, max_height; // zero means: not set
int event_fd_registered; // for uninit called from preinit
int mode_switched;
+ int osd_objects_drawn;
void (*draw_alpha_fnc)(void *ctx, int x0, int y0, int w, int h,
unsigned char *src, unsigned char *srca,
int stride);
@@ -95,11 +102,9 @@ struct xvctx {
#endif
};
-// FIXME: dynamically allocate this stuff
static void allocate_xvimage(struct vo *, int);
-
static void draw_alpha_yv12(void *p, int x0, int y0, int w, int h,
unsigned char *src, unsigned char *srca,
int stride)
@@ -113,6 +118,7 @@ static void draw_alpha_yv12(void *p, int x0, int y0, int w, int h,
ctx->xvimage[ctx->current_buf]->offsets[0] +
ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + x0,
ctx->xvimage[ctx->current_buf]->pitches[0]);
+ ctx->osd_objects_drawn++;
}
static void draw_alpha_yuy2(void *p, int x0, int y0, int w, int h,
@@ -128,6 +134,7 @@ static void draw_alpha_yuy2(void *p, int x0, int y0, int w, int h,
ctx->xvimage[ctx->current_buf]->offsets[0] +
ctx->xvimage[ctx->current_buf]->pitches[0] * y0 + 2 * x0,
ctx->xvimage[ctx->current_buf]->pitches[0]);
+ ctx->osd_objects_drawn++;
}
static void draw_alpha_uyvy(void *p, int x0, int y0, int w, int h,
@@ -143,6 +150,7 @@ static void draw_alpha_uyvy(void *p, int x0, int y0, int w, int h,
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]);
+ ctx->osd_objects_drawn++;
}
static void draw_alpha_null(void *p, int x0, int y0, int w, int h,
@@ -154,21 +162,22 @@ static void draw_alpha_null(void *p, int x0, int y0, int w, int h,
static void deallocate_xvimage(struct vo *vo, int foo);
-static void calc_drwXY(struct vo *vo, 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, &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);
- } else if (WinID == 0) {
- *drwX = vo->dx;
- *drwY = vo->dy;
- }
+ *drwX = *drwY = 0;
+ if (vo_fs) {
+ 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);
+ } else if (WinID == 0) {
+ *drwX = vo->dx;
+ *drwY = vo->dy;
+ }
}
/*
@@ -193,23 +202,25 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
ctx->image_width = width;
ctx->image_format = format;
- 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,
- ctx->image_width, ctx->image_height, ctx->max_width, ctx->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,
+ ctx->image_width, ctx->image_height, ctx->max_width,
+ ctx->max_height);
return -1;
}
ctx->is_paused = 0;
ctx->visible_buf = -1;
+ ctx->have_visible_image_copy = false;
+ ctx->have_next_image_copy = false;
/* check image formats */
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,
+ 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;
@@ -225,8 +236,7 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
{
#ifdef CONFIG_XF86VM
int vm = flags & VOFLAG_MODESWITCHING;
- if (vm)
- {
+ if (vm) {
vo_vm_switch(vo);
ctx->mode_switched = 1;
}
@@ -240,25 +250,23 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
xswa.background_pixel = 0;
if (x11->xv_ck_info.method == CK_METHOD_BACKGROUND)
- {
- xswa.background_pixel = x11->xv_colorkey;
- }
+ xswa.background_pixel = x11->xv_colorkey;
xswa.border_pixel = 0;
xswamask = CWBackPixel | CWBorderPixel;
- vo_x11_create_vo_window(vo, &vinfo, vo->dx, vo->dy, vo->dwidth, vo->dheight,
- flags, CopyFromParent, "xv", title);
- XChangeWindowAttributes(x11->display, x11->window, xswamask, &xswa);
+ vo_x11_create_vo_window(vo, &vinfo, vo->dx, vo->dy, vo->dwidth,
+ vo->dheight, flags, CopyFromParent, "xv",
+ title);
+ XChangeWindowAttributes(x11->display, x11->window, xswamask, &xswa);
#ifdef CONFIG_XF86VM
- if (vm)
- {
+ if (vm) {
/* Grab the mouse pointer in our window */
if (vo_grabpointer)
- XGrabPointer(x11->display, x11->window, True, 0,
- GrabModeAsync, GrabModeAsync,
- x11->window, None, CurrentTime);
- XSetInputFocus(x11->display, x11->window, RevertToNone, CurrentTime);
+ XGrabPointer(x11->display, x11->window, True, 0, GrabModeAsync,
+ GrabModeAsync, x11->window, None, CurrentTime);
+ XSetInputFocus(x11->display, x11->window, RevertToNone,
+ CurrentTime);
}
#endif
}
@@ -266,42 +274,43 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
mp_msg(MSGT_VO, MSGL_V, "using Xvideo port %d for hw scaling\n",
x11->xv_port);
- switch (ctx->xv_format)
- {
- case IMGFMT_YV12:
- case IMGFMT_I420:
- case IMGFMT_IYUV:
- ctx->draw_alpha_fnc = draw_alpha_yv12;
- break;
- case IMGFMT_YUY2:
- case IMGFMT_YVYU:
- ctx->draw_alpha_fnc = draw_alpha_yuy2;
- break;
- case IMGFMT_UYVY:
- ctx->draw_alpha_fnc = draw_alpha_uyvy;
- break;
- default:
- ctx->draw_alpha_fnc = draw_alpha_null;
+ switch (ctx->xv_format) {
+ case IMGFMT_YV12:
+ case IMGFMT_I420:
+ case IMGFMT_IYUV:
+ ctx->draw_alpha_fnc = draw_alpha_yv12;
+ break;
+ case IMGFMT_YUY2:
+ case IMGFMT_YVYU:
+ ctx->draw_alpha_fnc = draw_alpha_yuy2;
+ break;
+ case IMGFMT_UYVY:
+ ctx->draw_alpha_fnc = draw_alpha_uyvy;
+ break;
+ default:
+ ctx->draw_alpha_fnc = draw_alpha_null;
}
// In case config has been called before
- for (i = 0; i < ctx->num_buffers; i++)
+ for (i = 0; i < ctx->total_buffers; i++)
deallocate_xvimage(vo, i);
ctx->num_buffers =
vo_doublebuffering ? (vo_directrendering ? NUM_BUFFERS : 2) : 1;
+ ctx->total_buffers = ctx->num_buffers + 1;
- for (i = 0; i < ctx->num_buffers; i++)
+ for (i = 0; i < ctx->total_buffers; i++)
allocate_xvimage(vo, i);
ctx->current_buf = 0;
ctx->current_ip_buf = 0;
- if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0) vo_fs = 1;
+ if ((flags & VOFLAG_FULLSCREEN) && WinID <= 0)
+ vo_fs = 1;
calc_drwXY(vo, &ctx->drwX, &ctx->drwY);
panscan_calc(vo);
-
+
vo_xv_draw_colorkey(vo, ctx->drwX - (vo->panscan_x >> 1),
ctx->drwY - (vo->panscan_y >> 1),
vo->dwidth + vo->panscan_x - 1,
@@ -324,22 +333,22 @@ static void allocate_xvimage(struct vo *vo, int foo)
#ifdef HAVE_SHM
if (x11->display_is_local && XShmQueryExtension(x11->display))
ctx->Shmem_Flag = 1;
- else
- {
+ else {
ctx->Shmem_Flag = 0;
- mp_msg(MSGT_VO, MSGL_INFO,
- MSGTR_LIBVO_XV_SharedMemoryNotSupported);
+ mp_msg(MSGT_VO, MSGL_INFO, MSGTR_LIBVO_XV_SharedMemoryNotSupported);
}
- if (ctx->Shmem_Flag)
- {
+ if (ctx->Shmem_Flag) {
ctx->xvimage[foo] =
- (XvImage *) XvShmCreateImage(x11->display, x11->xv_port, ctx->xv_format,
- NULL, ctx->image_width, ctx->image_height,
+ (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].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;
@@ -350,8 +359,9 @@ static void allocate_xvimage(struct vo *vo, int foo)
#endif
{
ctx->xvimage[foo] =
- (XvImage *) XvCreateImage(x11->display, x11->xv_port, ctx->xv_format, NULL,
- ctx->image_width, ctx->image_height);
+ (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);
}
@@ -363,8 +373,7 @@ static void deallocate_xvimage(struct vo *vo, int foo)
{
struct xvctx *ctx = vo->priv;
#ifdef HAVE_SHM
- if (ctx->Shmem_Flag)
- {
+ if (ctx->Shmem_Flag) {
XShmDetach(vo->x11->display, &ctx->Shminfo[foo]);
shmdt(ctx->Shminfo[foo].shmaddr);
} else
@@ -383,25 +392,36 @@ 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 (ctx->Shmem_Flag)
- {
- 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,
+ if (ctx->Shmem_Flag) {
+ 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(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);
+ 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);
}
}
+// Only copies luma for planar formats as draw_alpha doesn't change others */
+void copy_backup_image(struct vo *vo, int dest, int src)
+{
+ struct xvctx *ctx = vo->priv;
+
+ XvImage *vb = ctx->xvimage[dest];
+ XvImage *cp = ctx->xvimage[src];
+ memcpy_pic(vb->data + vb->offsets[0], cp->data + cp->offsets[0],
+ vb->width, vb->height,
+ vb->pitches[0], cp->pitches[0]);
+}
+
static void check_events(struct vo *vo)
{
struct xvctx *ctx = vo->priv;
@@ -411,21 +431,18 @@ static void check_events(struct vo *vo)
if (e & VO_EVENT_RESIZE)
calc_drwXY(vo, &ctx->drwX, &ctx->drwY);
- if (e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE)
- {
- 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) {
+ 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) && ctx->is_paused)
- {
+ if ((e & VO_EVENT_EXPOSE || e & VO_EVENT_RESIZE) && ctx->is_paused) {
/* did we already draw a buffer */
- if ( ctx->visible_buf != -1 )
- {
- /* redraw the last visible buffer */
- put_xvimage(vo, ctx->xvimage[ctx->visible_buf]);
+ if (ctx->visible_buf != -1) {
+ /* redraw the last visible buffer */
+ put_xvimage(vo, ctx->xvimage[ctx->visible_buf]);
}
}
}
@@ -434,9 +451,34 @@ static void draw_osd(struct vo *vo, struct osd_state *osd)
{
struct xvctx *ctx = vo->priv;
- osd_draw_text(osd, ctx->image_width -
- ctx->image_width * vo->panscan_x / (vo->dwidth + vo->panscan_x),
+ ctx->osd_objects_drawn = 0;
+ 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);
+ if (ctx->osd_objects_drawn)
+ ctx->unchanged_next_image = false;
+}
+
+static int redraw_osd(struct vo *vo, struct osd_state *osd)
+{
+ struct xvctx *ctx = vo->priv;
+
+ if (ctx->have_visible_image_copy)
+ copy_backup_image(vo, ctx->visible_buf, ctx->num_buffers);
+ else if (ctx->unchanged_visible_image) {
+ copy_backup_image(vo, ctx->num_buffers, ctx->visible_buf);
+ ctx->have_visible_image_copy = true;
+ }
+ else
+ return false;
+ int temp = ctx->current_buf;
+ ctx->current_buf = ctx->visible_buf;
+ draw_osd(vo, osd);
+ ctx->current_buf = temp;
+ put_xvimage(vo, ctx->xvimage[ctx->visible_buf]);
+ return true;
}
static void flip_page(struct vo *vo)
@@ -447,99 +489,99 @@ static void flip_page(struct vo *vo)
/* remember the currently visible buffer */
ctx->visible_buf = ctx->current_buf;
- if (ctx->num_buffers > 1)
- {
- ctx->current_buf =
- vo_directrendering ? 0 : ((ctx->current_buf + 1) % ctx->num_buffers);
+ ctx->have_visible_image_copy = ctx->have_next_image_copy;
+ ctx->have_next_image_copy = false;
+ ctx->unchanged_visible_image = ctx->unchanged_next_image;
+ ctx->unchanged_next_image = false;
+
+ if (ctx->num_buffers > 1) {
+ ctx->current_buf = vo_directrendering ? 0 : ((ctx->current_buf + 1) %
+ ctx->num_buffers);
XFlush(vo->x11->display);
} else
XSync(vo->x11->display, False);
return;
}
-static int draw_slice(struct vo *vo, uint8_t * image[], int stride[], int w,
+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 = 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]);
+ 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;
y /= 2;
w /= 2;
h /= 2;
- dst = current_image->data + current_image->offsets[1] +
- current_image->pitches[1] * y + x;
+ 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]);
+ memcpy_pic(dst, image[1], w, h, current_image->pitches[1], stride[1]);
else
- memcpy_pic(dst, image[2], w, h, current_image->pitches[1],
- stride[2]);
+ memcpy_pic(dst, image[2], w, h, current_image->pitches[1], stride[2]);
- dst = current_image->data + current_image->offsets[2] +
- current_image->pitches[2] * y + x;
+ 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]);
+ memcpy_pic(dst, image[1], w, h, current_image->pitches[1], stride[1]);
else
- memcpy_pic(dst, image[2], w, h, current_image->pitches[1],
- stride[2]);
+ memcpy_pic(dst, image[2], w, h, current_image->pitches[1], stride[2]);
return 0;
}
-static int draw_frame(struct vo *vo, uint8_t * src[])
+static int draw_frame(struct vo *vo, uint8_t *src[])
{
return VO_ERROR;
}
-static uint32_t draw_image(struct vo *vo, mp_image_t * mpi)
+static uint32_t draw_image(struct vo *vo, mp_image_t *mpi)
{
struct xvctx *ctx = vo->priv;
+
+ ctx->have_next_image_copy = false;
+
if (mpi->flags & MP_IMGFLAG_DIRECT)
- {
// direct rendering:
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)
- {
+ else if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
+ ; // done
+ else if (mpi->flags & MP_IMGFLAG_PLANAR)
draw_slice(vo, mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
- return VO_TRUE;
- }
- if (mpi->flags & MP_IMGFLAG_YUV)
- {
+ else if (mpi->flags & MP_IMGFLAG_YUV)
// packed YUV:
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,
ctx->xvimage[ctx->current_buf]->pitches[0], mpi->stride[0]);
- return VO_TRUE;
+ else
+ return false;
+
+ if (ctx->is_paused) {
+ copy_backup_image(vo, ctx->num_buffers, ctx->current_buf);
+ ctx->have_next_image_copy = true;
}
- return VO_FALSE; // not (yet) supported
+ ctx->unchanged_next_image = true;
+ return true;
}
-static uint32_t get_image(struct xvctx *ctx, mp_image_t * mpi)
+static uint32_t get_image(struct xvctx *ctx, mp_image_t *mpi)
{
- int buf = ctx->current_buf; // we shouldn't change current_buf unless we do DR!
+ // we shouldn't change current_buf unless we do DR!
+ int buf = ctx->current_buf;
if (mpi->type == MP_IMGTYPE_STATIC && ctx->num_buffers > 1)
return VO_FALSE; // it is not static
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))
- {
+ 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 (ctx->num_buffers < 2)
return VO_FALSE; // not enough
@@ -557,42 +599,33 @@ static uint32_t get_image(struct xvctx *ctx, mp_image_t * mpi)
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) == ctx->xvimage[buf]->pitches[0]))
- {
+ || (mpi->width * (mpi->bpp / 8) == ctx->xvimage[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)
- {
- if (mpi->flags & MP_IMGFLAG_SWAPPED)
- {
+ if (mpi->flags & MP_IMGFLAG_PLANAR) {
+ if (mpi->flags & MP_IMGFLAG_SWAPPED) {
// I420
- mpi->planes[1] =
- current_image->data +
- current_image->offsets[1];
- mpi->planes[2] =
- current_image->data +
- current_image->offsets[2];
+ mpi->planes[1] = current_image->data
+ + current_image->offsets[1];
+ mpi->planes[2] = current_image->data
+ + current_image->offsets[2];
mpi->stride[1] = current_image->pitches[1];
mpi->stride[2] = current_image->pitches[2];
- } else
- {
+ } else {
// YV12
- mpi->planes[1] =
- current_image->data +
- current_image->offsets[2];
- mpi->planes[2] =
- current_image->data +
- current_image->offsets[1];
+ mpi->planes[1] = current_image->data
+ + current_image->offsets[2];
+ mpi->planes[2] = current_image->data
+ + current_image->offsets[1];
mpi->stride[1] = current_image->pitches[2];
mpi->stride[2] = current_image->pitches[1];
}
}
mpi->flags |= MP_IMGFLAG_DIRECT;
mpi->priv = (void *) ctx->current_buf;
-// printf("mga: get_image() SUCCESS -> Direct Rendering ENABLED\n");
return VO_TRUE;
}
return VO_FALSE;
@@ -604,8 +637,7 @@ static int query_format(struct xvctx *ctx, uint32_t format)
int flag = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_OSD | VFCAP_ACCEPT_STRIDE; // FIXME! check for DOWN
/* check image formats */
- for (i = 0; i < ctx->formats; i++)
- {
+ for (i = 0; i < ctx->formats; i++) {
if (ctx->fo[i].id == format)
return flag; //xv_format = fo[i].id;
}
@@ -625,7 +657,7 @@ static void uninit(struct vo *vo)
XFree(ctx->fo);
ctx->fo = NULL;
}
- for (i = 0; i < ctx->num_buffers; i++)
+ for (i = 0; i < ctx->total_buffers; i++)
deallocate_xvimage(vo, i);
#ifdef CONFIG_XF86VM
if (ctx->mode_switched)
@@ -656,22 +688,20 @@ static int preinit(struct vo *vo, const char *arg)
struct vo_x11_state *x11 = vo->x11;
int xv_adaptor = -1;
- opt_t subopts[] =
- {
- /* name arg type arg var test */
- { "port", OPT_ARG_INT, &x11->xv_port, (opt_test_f)int_pos },
- { "adaptor", OPT_ARG_INT, &xv_adaptor, (opt_test_f)int_non_neg },
- { "ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck },
- { "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm },
- { NULL }
+ opt_t subopts[] = {
+ /* name arg type arg var test */
+ {"port", OPT_ARG_INT, &x11->xv_port, (opt_test_f) int_pos},
+ {"adaptor", OPT_ARG_INT, &xv_adaptor, (opt_test_f) int_non_neg},
+ {"ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck},
+ {"ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm},
+ {NULL}
};
x11->xv_port = 0;
/* parse suboptions */
- if ( subopt_parse( arg, subopts ) != 0 )
- {
- return -1;
+ if (subopt_parse(arg, subopts) != 0) {
+ return -1;
}
/* modify colorkey settings according to the given options */
@@ -682,105 +712,90 @@ static int preinit(struct vo *vo, const char *arg)
/* check for Xvideo extension */
unsigned int ver, rel, req, ev, err;
- if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err))
- {
- mp_msg(MSGT_VO, MSGL_ERR,
- MSGTR_LIBVO_XV_XvNotSupportedByX11);
+ if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err)) {
+ mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_XvNotSupportedByX11);
goto error;
}
/* check for Xvideo support */
if (Success !=
- XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display), &ctx->adaptors,
- &ctx->ai))
- {
+ XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display),
+ &ctx->adaptors, &ctx->ai)) {
mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_XvQueryAdaptorsFailed);
goto error;
}
/* check adaptors */
- if (x11->xv_port)
- {
+ if (x11->xv_port) {
int port_found;
- for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++)
- {
- if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask))
- {
+ for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) {
+ if ((ctx->ai[i].type & XvInputMask)
+ && (ctx->ai[i].type & XvImageMask)) {
for (xv_p = ctx->ai[i].base_id;
- xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p)
- {
- if (xv_p == x11->xv_port)
- {
+ xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports;
+ ++xv_p) {
+ if (xv_p == x11->xv_port) {
port_found = 1;
break;
}
}
}
}
- if (port_found)
- {
+ if (port_found) {
if (XvGrabPort(x11->display, x11->xv_port, CurrentTime))
x11->xv_port = 0;
- } else
- {
- mp_msg(MSGT_VO, MSGL_WARN,
- MSGTR_LIBVO_XV_InvalidPortParameter);
+ } else {
+ mp_msg(MSGT_VO, MSGL_WARN, MSGTR_LIBVO_XV_InvalidPortParameter);
x11->xv_port = 0;
}
}
- for (i = 0; i < ctx->adaptors && x11->xv_port == 0; i++)
- {
+ for (i = 0; i < ctx->adaptors && x11->xv_port == 0; i++) {
/* check if adaptor number has been specified */
if (xv_adaptor != -1 && xv_adaptor != i)
- continue;
+ continue;
- if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask))
- {
+ if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) {
for (xv_p = ctx->ai[i].base_id;
xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p)
- if (!XvGrabPort(x11->display, xv_p, CurrentTime))
- {
+ if (!XvGrabPort(x11->display, xv_p, CurrentTime)) {
x11->xv_port = xv_p;
mp_msg(MSGT_VO, MSGL_V,
"[VO_XV] Using Xv Adapter #%d (%s)\n",
i, ctx->ai[i].name);
break;
- } else
- {
- mp_msg(MSGT_VO, MSGL_WARN,
- MSGTR_LIBVO_XV_CouldNotGrabPort, (int) xv_p);
+ } else {
+ mp_msg(MSGT_VO, MSGL_WARN, MSGTR_LIBVO_XV_CouldNotGrabPort,
+ (int) xv_p);
++busy_ports;
}
}
}
- if (!x11->xv_port)
- {
+ if (!x11->xv_port) {
if (busy_ports)
- mp_msg(MSGT_VO, MSGL_ERR,
- MSGTR_LIBVO_XV_CouldNotFindFreePort);
+ mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_CouldNotFindFreePort);
else
- mp_msg(MSGT_VO, MSGL_ERR,
- MSGTR_LIBVO_XV_NoXvideoSupport);
+ mp_msg(MSGT_VO, MSGL_ERR, MSGTR_LIBVO_XV_NoXvideoSupport);
goto error;
}
if (!vo_xv_init_colorkey(vo)) {
- goto error; // bail out, colorkey setup failed
+ goto error; // bail out, colorkey setup failed
}
vo_xv_enable_vsync(vo);
vo_xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height);
- ctx->fo = XvListImageFormats(x11->display, x11->xv_port, (int *) &ctx->formats);
+ ctx->fo = XvListImageFormats(x11->display, x11->xv_port,
+ (int *) &ctx->formats);
mp_input_add_key_fd(vo->input_ctx, ConnectionNumber(x11->display), 1,
x11_fd_callback, NULL, vo);
ctx->event_fd_registered = 1;
return 0;
- error:
- uninit(vo); // free resources
+ error:
+ uninit(vo); // free resources
return -1;
}
@@ -788,65 +803,63 @@ static int control(struct vo *vo, uint32_t request, void *data)
{
struct xvctx *ctx = vo->priv;
struct vo_x11_state *x11 = vo->x11;
- switch (request)
- {
- case VOCTRL_PAUSE:
- return (ctx->is_paused = 1);
- case VOCTRL_RESUME:
- return (ctx->is_paused = 0);
- case VOCTRL_QUERY_FORMAT:
- return query_format(ctx, *((uint32_t *) data));
- case VOCTRL_GET_IMAGE:
- return get_image(ctx, data);
- case VOCTRL_DRAW_IMAGE:
- return draw_image(vo, data);
- case VOCTRL_GUISUPPORT:
- return VO_TRUE;
- case VOCTRL_GET_PANSCAN:
- if (!vo->config_ok || !vo_fs)
- return VO_FALSE;
- return VO_TRUE;
- case VOCTRL_FULLSCREEN:
- vo_x11_fullscreen(vo);
- /* indended, fallthrough to update panscan on fullscreen/windowed switch */
- case VOCTRL_SET_PANSCAN:
- if ((vo_fs && (vo_panscan != vo->panscan_amount))
- || (!vo_fs && vo->panscan_amount))
- {
- int old_y = vo->panscan_y;
-
- panscan_calc(vo);
-
- if (old_y != vo->panscan_y)
- {
- vo_x11_clearwindow_part(vo, x11->window,
- vo->dwidth + vo->panscan_x - 1,
- vo->dheight + vo->panscan_y - 1,
- 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);
- flip_page(vo);
- }
- }
- return VO_TRUE;
- case VOCTRL_