diff options
author | wm4 <wm4@nowhere> | 2016-10-20 16:43:02 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-10-20 16:43:02 +0200 |
commit | 6b18d4dba527301d96b810d97f774dac03c6fb46 (patch) | |
tree | c585106da88d2000a7ac67a05ac39b151b8e7afd /video/decode | |
parent | dd02369c3223fda5bcb2658b15404d43232bb38f (diff) |
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.
Diffstat (limited to 'video/decode')
-rw-r--r-- | video/decode/vd_lavc.c | 2 | ||||
-rw-r--r-- | video/decode/vdpau.c | 75 |
2 files changed, 76 insertions, 1 deletions
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, +}; |