From 6b18d4dba527301d96b810d97f774dac03c6fb46 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 20 Oct 2016 16:43:02 +0200 Subject: video: add --hwdec=vdpau-copy mode At this point, all other hwaccels provide -copy modes, and vdpau is the exception with not having one. Although there is vf_vdpaurb, it's less convenient in certain situations, and exposes some issues with the filter chain code as well. --- video/decode/vd_lavc.c | 2 ++ video/decode/vdpau.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) (limited to 'video/decode') diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 12e60483ee..72209f5048 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -125,6 +125,7 @@ const struct m_sub_options vd_lavc_conf = { }; extern const struct vd_lavc_hwdec mp_vd_lavc_vdpau; +extern const struct vd_lavc_hwdec mp_vd_lavc_vdpau_copy; extern const struct vd_lavc_hwdec mp_vd_lavc_videotoolbox; extern const struct vd_lavc_hwdec mp_vd_lavc_videotoolbox_copy; extern const struct vd_lavc_hwdec mp_vd_lavc_vaapi; @@ -177,6 +178,7 @@ static const struct vd_lavc_hwdec *const hwdec_list[] = { #endif #if HAVE_VDPAU_HWACCEL &mp_vd_lavc_vdpau, + &mp_vd_lavc_vdpau_copy, #endif #if HAVE_VIDEOTOOLBOX_HWACCEL &mp_vd_lavc_videotoolbox, diff --git a/video/decode/vdpau.c b/video/decode/vdpau.c index 0003182dcb..a86f5d1edf 100644 --- a/video/decode/vdpau.c +++ b/video/decode/vdpau.c @@ -21,6 +21,7 @@ #include "lavc.h" #include "common/common.h" +#include "video/mp_image_pool.h" #include "video/vdpau.h" #include "video/hwdec.h" @@ -28,6 +29,9 @@ struct priv { struct mp_log *log; struct mp_vdpau_ctx *mpvdp; uint64_t preemption_counter; + // vdpau-copy + Display *display; + struct mp_image_pool *sw_pool; }; static int init_decoder(struct lavc_ctx *ctx, int w, int h) @@ -76,9 +80,16 @@ static void uninit(struct lavc_ctx *ctx) { struct priv *p = ctx->hwdec_priv; + if (p->display) { + // for copy path: we own this stuff + mp_vdpau_destroy(p->mpvdp); + XCloseDisplay(p->display); + } + talloc_free(p); - av_freep(&ctx->avctx->hwaccel_context); + if (ctx->avctx) + av_freep(&ctx->avctx->hwaccel_context); } static int init(struct lavc_ctx *ctx) @@ -102,6 +113,56 @@ static int probe(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec, return 0; } +static int init_copy(struct lavc_ctx *ctx) +{ + struct priv *p = talloc_ptrtype(NULL, p); + *p = (struct priv) { + .log = mp_log_new(p, ctx->log, "vdpau"), + }; + + p->display = XOpenDisplay(NULL); + if (!p->display) + goto error; + + p->mpvdp = mp_vdpau_create_device_x11(p->log, p->display, true); + if (!p->mpvdp) + goto error; + + p->sw_pool = talloc_steal(p, mp_image_pool_new(17)); + + ctx->hwdec_priv = p; + + mp_vdpau_handle_preemption(p->mpvdp, &p->preemption_counter); + return 0; + +error: + if (p->display) + XCloseDisplay(p->display); + talloc_free(p); + return -1; +} + +static int probe_copy(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec, + const char *codec) +{ + assert(!ctx->hwdec_priv); + int r = init_copy(ctx); + if (ctx->hwdec_priv) + uninit(ctx); + ctx->hwdec_priv = NULL; + + return r < 0 ? HWDEC_ERR_NO_CTX : 0; +} + +static struct mp_image *copy_image(struct lavc_ctx *ctx, struct mp_image *img) +{ + struct priv *p = ctx->hwdec_priv; + struct mp_hwdec_ctx *hwctx = &p->mpvdp->hwctx; + struct mp_image *out = hwctx->download_image(hwctx, img, p->sw_pool); + talloc_free(img); + return out; +} + const struct vd_lavc_hwdec mp_vd_lavc_vdpau = { .type = HWDEC_VDPAU, .image_format = IMGFMT_VDPAU, @@ -112,3 +173,15 @@ const struct vd_lavc_hwdec mp_vd_lavc_vdpau = { .allocate_image = allocate_image, .process_image = update_format, }; + +const struct vd_lavc_hwdec mp_vd_lavc_vdpau_copy = { + .type = HWDEC_VDPAU_COPY, + .copying = true, + .image_format = IMGFMT_VDPAU, + .probe = probe_copy, + .init = init_copy, + .uninit = uninit, + .init_decoder = init_decoder, + .allocate_image = allocate_image, + .process_image = copy_image, +}; -- cgit v1.2.3