summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-10-07 03:28:40 +0200
committerwm4 <wm4@nowhere>2012-10-24 21:56:33 +0200
commitb03e357c69034807c455617cdd2a5700382f4670 (patch)
tree427831d95113493b432de03492df6f41f2290315
parentfef1871d3f1f0a1477fc764e8d83a008337045f8 (diff)
downloadmpv-b03e357c69034807c455617cdd2a5700382f4670.tar.bz2
mpv-b03e357c69034807c455617cdd2a5700382f4670.tar.xz
vo_xv: use new OSD API
Aspect ratio stuff needs to be fixed later. "Fixing" the position of OSD elements outside of the screen due to panscan needs to be added back as well (what the removed fixup_osd_position() function did). The amount of data needed to "backup" an image when OSD is rendered increases. This is because we support color OSD/subtitles now. The old code rendered into the Y plane only, while the new code touches all 3 planes. For YV12, which is probably the only format supported not considering chroma-swapped and packed formats, 0.5 times more memory is copied when the OSD is used in pause 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++) {