summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-10-20 16:43:02 +0200
committerwm4 <wm4@nowhere>2016-10-20 16:43:02 +0200
commit6b18d4dba527301d96b810d97f774dac03c6fb46 (patch)
treec585106da88d2000a7ac67a05ac39b151b8e7afd /video
parentdd02369c3223fda5bcb2658b15404d43232bb38f (diff)
downloadmpv-6b18d4dba527301d96b810d97f774dac03c6fb46.tar.bz2
mpv-6b18d4dba527301d96b810d97f774dac03c6fb46.tar.xz
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')
-rw-r--r--video/decode/vd_lavc.c2
-rw-r--r--video/decode/vdpau.c75
-rw-r--r--video/hwdec.h1
3 files changed, 77 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,
+};
diff --git a/video/hwdec.h b/video/hwdec.h
index 34b65fe15c..857d07c894 100644
--- a/video/hwdec.h
+++ b/video/hwdec.h
@@ -11,6 +11,7 @@ enum hwdec_type {
HWDEC_AUTO,
HWDEC_AUTO_COPY,
HWDEC_VDPAU,
+ HWDEC_VDPAU_COPY,
HWDEC_VIDEOTOOLBOX,
HWDEC_VIDEOTOOLBOX_COPY,
HWDEC_VAAPI,