summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libvo/vo_xv.c139
1 files changed, 38 insertions, 101 deletions
diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c
index 42ddde890a..7c2d3816c4 100644
--- a/libvo/vo_xv.c
+++ b/libvo/vo_xv.c
@@ -51,6 +51,7 @@
#include "x11_common.h"
#include "fastmemcpy.h"
#include "sub/sub.h"
+#include "sub/dec_sub.h"
#include "aspect.h"
#include "csputils.h"
#include "subopt-helper.h"
@@ -84,10 +85,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;
@@ -95,71 +92,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)
@@ -261,23 +193,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);
@@ -383,16 +298,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)
@@ -409,13 +340,19 @@ 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 sub_render_params subparams = {
+ .pts = osd->vo_sub_pts,
+ .dim = {.w = ctx->image_width, .h = ctx->image_height},
+ .normal_scale = 1,
+ .vsfilter_scale = 1,
+ };
+
+ if (osd_draw_on_image(osd, &img, &csp, &subparams))
ctx->unchanged_image = false;
}
@@ -553,7 +490,7 @@ static uint32_t draw_image(struct vo *vo, mp_image_t *mpi)
static int query_format(struct xvctx *ctx, uint32_t format)
{
uint32_t i;
- 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
+ int flag = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_OSD | VFCAP_EOSD | VFCAP_ACCEPT_STRIDE; // FIXME! check for DOWN
/* check image formats */
for (i = 0; i < ctx->formats; i++) {