summaryrefslogtreecommitdiffstats
path: root/libvo/vo_xv.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvo/vo_xv.c')
-rw-r--r--libvo/vo_xv.c218
1 files changed, 69 insertions, 149 deletions
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index 922fd55cf7..de14f039f4 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"
@@ -78,14 +77,10 @@ struct xvctx {
uint32_t image_height;
uint32_t image_format;
int is_paused;
- struct vo_rect src_rect;
- struct vo_rect dst_rect;
+ struct mp_rect src_rect;
+ struct mp_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,82 +88,22 @@ 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)
{
struct xvctx *ctx = vo->priv;
- calc_src_dst_rects(vo, ctx->image_width, ctx->image_height, &ctx->src_rect,
- &ctx->dst_rect, NULL, NULL);
- struct vo_rect *dst = &ctx->dst_rect;
- vo_x11_clearwindow_part(vo, vo->x11->window, dst->width, dst->height);
- vo_xv_draw_colorkey(vo, dst->left, dst->top, dst->width, dst->height);
+ // Can't be used, because the function calculates screen-space coordinates,
+ // while we need video-space.
+ struct mp_osd_res unused;
+
+ vo_get_src_dst_rects(vo, &ctx->src_rect, &ctx->dst_rect, &unused);
+
+ struct mp_rect *dst = &ctx->dst_rect;
+ int dw = dst->x1 - dst->x0, dh = dst->y1 - dst->y0;
+ vo_x11_clearwindow_part(vo, vo->x11->window, dw, dh);
+ vo_xv_draw_colorkey(vo, dst->x0, dst->y0, dw, dh);
}
/*
@@ -257,23 +192,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);
@@ -362,33 +280,55 @@ static inline void put_xvimage(struct vo *vo, XvImage *xvi)
{
struct xvctx *ctx = vo->priv;
struct vo_x11_state *x11 = vo->x11;
- struct vo_rect *src = &ctx->src_rect;
- struct vo_rect *dst = &ctx->dst_rect;
+ struct mp_rect *src = &ctx->src_rect;
+ struct mp_rect *dst = &ctx->dst_rect;
+ int dw = dst->x1 - dst->x0, dh = dst->y1 - dst->y0;
+ int sw = src->x1 - src->x0, sh = src->y1 - src->y0;
#ifdef HAVE_SHM
if (ctx->Shmem_Flag) {
XvShmPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi,
- src->left, src->top, src->width, src->height,
- dst->left, dst->top, dst->width, dst->height,
+ src->x0, src->y0, sw, sh,
+ dst->x0, dst->y0, dw, dh,
False);
} else
#endif
{
XvPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi,
- src->left, src->top, src->width, src->height,
- dst->left, dst->top, dst->width, dst->height);
+ src->x0, src->y0, sw, sh,
+ dst->x0, dst->y0, dw, dh);
}
}
-// 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];
+ }
+
+ struct mp_csp_details csp = {0};
+ vo_control(vo, VOCTRL_GET_YUV_COLORSPACE, &csp);
+ mp_image_set_colorspace_details(&img, &csp);
- 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 +345,22 @@ 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_rect *src = &ctx->src_rect;
+ struct mp_rect *dst = &ctx->dst_rect;
+ int dw = dst->x1 - dst->x0, dh = dst->y1 - dst->y0;
+ int sw = src->x1 - src->x0, sh = src->y1 - src->y0;
+ double xvpar = (double)dw / dh * sh / sw;
+
+ 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))
ctx->unchanged_image = false;
}
@@ -481,42 +430,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.display_w = vo->aspdat.prew;
+ img.display_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 +685,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;
}
}