diff options
Diffstat (limited to 'libvo/vo_xv.c')
-rw-r--r-- | libvo/vo_xv.c | 182 |
1 files changed, 46 insertions, 136 deletions
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c index 922fd55cf7..390c1753b6 100644 --- a/libvo/vo_xv.c +++ b/libvo/vo_xv.c @@ -47,7 +47,6 @@ #include "video_out.h" #include "libmpcodecs/vfcap.h" #include "libmpcodecs/mp_image.h" -#include "osd.h" #include "x11_common.h" #include "fastmemcpy.h" #include "sub/sub.h" @@ -82,10 +81,6 @@ struct xvctx { struct vo_rect dst_rect; uint32_t max_width, max_height; // zero means: not set 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); #ifdef HAVE_SHM XShmSegmentInfo Shminfo[2 + 1]; int Shmem_Flag; @@ -93,71 +88,6 @@ struct xvctx { }; static void allocate_xvimage(struct vo *, int); - - -static void fixup_osd_position(struct vo *vo, int *x0, int *y0, int *w, int *h) -{ - struct xvctx *ctx = vo->priv; - *x0 += ctx->image_width * (vo->panscan_x >> 1) - / (vo->dwidth + vo->panscan_x); - *w = av_clip(*w, 0, ctx->image_width); - *h = av_clip(*h, 0, ctx->image_height); - *x0 = FFMIN(*x0, ctx->image_width - *w); - *y0 = FFMIN(*y0, ctx->image_height - *h); -} - -static void draw_alpha_yv12(void *p, int x0, int y0, int w, int h, - unsigned char *src, unsigned char *srca, - int stride) -{ - struct vo *vo = p; - struct xvctx *ctx = vo->priv; - fixup_osd_position(vo, &x0, &y0, &w, &h); - vo_draw_alpha_yv12(w, h, src, srca, stride, - 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]); - ctx->osd_objects_drawn++; -} - -static void draw_alpha_yuy2(void *p, int x0, int y0, int w, int h, - unsigned char *src, unsigned char *srca, - int stride) -{ - struct vo *vo = p; - struct xvctx *ctx = vo->priv; - fixup_osd_position(vo, &x0, &y0, &w, &h); - vo_draw_alpha_yuy2(w, h, src, srca, stride, - 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]); - ctx->osd_objects_drawn++; -} - -static void draw_alpha_uyvy(void *p, int x0, int y0, int w, int h, - unsigned char *src, unsigned char *srca, - int stride) -{ - struct vo *vo = p; - struct xvctx *ctx = vo->priv; - fixup_osd_position(vo, &x0, &y0, &w, &h); - vo_draw_alpha_yuy2(w, h, src, srca, stride, - 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]); - ctx->osd_objects_drawn++; -} - -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(struct vo *vo, int foo); static void resize(struct vo *vo) @@ -257,23 +187,6 @@ 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; - } - // In case config has been called before for (i = 0; i < ctx->total_buffers; i++) deallocate_xvimage(vo, i); @@ -379,16 +292,32 @@ static inline void put_xvimage(struct vo *vo, XvImage *xvi) } } -// Only copies luma for planar formats as draw_alpha doesn't change others */ -static void copy_backup_image(struct vo *vo, int dest, int src) +static struct mp_image get_xv_buffer(struct vo *vo, int buf_index) { struct xvctx *ctx = vo->priv; + XvImage *xv_image = ctx->xvimage[buf_index]; + + struct mp_image img = {0}; + img.w = img.width = xv_image->width; + img.h = img.height = xv_image->height; + mp_image_setfmt(&img, ctx->image_format); + + bool swapuv = ctx->image_format == IMGFMT_YV12; + for (int n = 0; n < img.num_planes; n++) { + int sn = n > 0 && swapuv ? (n == 1 ? 2 : 1) : n; + img.planes[n] = xv_image->data + xv_image->offsets[sn]; + img.stride[n] = xv_image->pitches[sn]; + } - 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]); + return img; +} + +static void copy_backup_image(struct vo *vo, int dest, int src) +{ + struct mp_image img_dest = get_xv_buffer(vo, dest); + struct mp_image img_src = get_xv_buffer(vo, src); + + copy_mpi(&img_dest, &img_src); } static void check_events(struct vo *vo) @@ -405,13 +334,23 @@ static void draw_osd(struct vo *vo, struct osd_state *osd) { struct xvctx *ctx = vo->priv; - 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) + struct mp_image img = get_xv_buffer(vo, ctx->current_buf); + + struct mp_csp_details csp = {0}; + vo_control(vo, VOCTRL_GET_YUV_COLORSPACE, &csp); + + struct vo_rect *src = &ctx->src_rect; + struct vo_rect *dst = &ctx->dst_rect; + double xvpar = (double)dst->width / dst->height * src->height / src->width; + + struct mp_osd_res res = { + .w = ctx->image_width, + .h = ctx->image_height, + .display_par = vo->monitor_par / xvpar, + .video_par = vo->aspdat.par, + }; + + if (osd_draw_on_image(osd, res, osd->vo_pts, 0, &img, &csp)) ctx->unchanged_image = false; } @@ -481,42 +420,12 @@ static mp_image_t *get_screenshot(struct vo *vo) struct xvctx *ctx = vo->priv; // try to get an image without OSD - if (ctx->have_image_copy) - copy_backup_image(vo, ctx->visible_buf, ctx->num_buffers); - - XvImage *xv_image = ctx->xvimage[ctx->visible_buf]; - - int w = xv_image->width; - int h = xv_image->height; - - mp_image_t *image = alloc_mpi(w, h, ctx->image_format); - - int bytes = 1; - if (!(image->flags & MP_IMGFLAG_PLANAR) && (image->flags & MP_IMGFLAG_YUV)) - // packed YUV - bytes = image->bpp / 8; - - memcpy_pic(image->planes[0], xv_image->data + xv_image->offsets[0], - bytes * w, h, image->stride[0], xv_image->pitches[0]); - - if (image->flags & MP_IMGFLAG_PLANAR) { - int swap = ctx->image_format == IMGFMT_YV12; - int p1 = swap ? 2 : 1; - int p2 = swap ? 1 : 2; - - w /= 2; - h /= 2; - - memcpy_pic(image->planes[p1], xv_image->data + xv_image->offsets[1], - w, h, image->stride[p1], xv_image->pitches[1]); - memcpy_pic(image->planes[p2], xv_image->data + xv_image->offsets[2], - w, h, image->stride[p2], xv_image->pitches[2]); - } - - image->w = vo->aspdat.prew; - image->h = vo->aspdat.preh; + int id = ctx->have_image_copy ? ctx->num_buffers : ctx->visible_buf; + struct mp_image img = get_xv_buffer(vo, id); + img.w = vo->aspdat.prew; + img.h = vo->aspdat.preh; - return image; + return talloc_memdup(NULL, &img, sizeof(img)); } static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) @@ -766,6 +675,7 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_SCREENSHOT: { struct voctrl_screenshot_args *args = data; args->out_image = get_screenshot(vo); + args->has_osd = !ctx->have_image_copy; return true; } } |