summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-10-30 18:33:18 +0100
committerwm4 <wm4@nowhere>2017-10-30 18:34:49 +0100
commit58d83a93094503992a8f717c64b636450629555c (patch)
treec923d5f99958264bd66ec5466fe681324215ad4d /video
parentb7ce3ac44575d82b5b23f10477b1158b84394b8f (diff)
downloadmpv-58d83a93094503992a8f717c64b636450629555c.tar.bz2
mpv-58d83a93094503992a8f717c64b636450629555c.tar.xz
vd_lavc: make --hwdec=nvdec-copy actually work
This simply didn't work. Unlike cuda-copy, this is a true hwaccel, and obviously we need to provide it a device. Implement this in a relatively generic way, which can probably reused directly by videotoolbox (not doing this yet because it would require testing on OSX). Like with cuda-copy, --cuda-decode-device is ignored. We might be able to provide a more general way to select devices at some later point.
Diffstat (limited to 'video')
-rw-r--r--video/decode/lavc.h4
-rw-r--r--video/decode/vd_lavc.c31
2 files changed, 32 insertions, 3 deletions
diff --git a/video/decode/lavc.h b/video/decode/lavc.h
index 6287dc8577..810d7e393c 100644
--- a/video/decode/lavc.h
+++ b/video/decode/lavc.h
@@ -87,6 +87,10 @@ struct vd_lavc_hwdec {
enum hwdec_type type;
// If non-0, get this hwdec type from the VO (for the AVHWDeviceContext).
enum hwdec_type interop_type;
+ // If true, create a AVHWDeviceContext with default parameters. In this
+ // case, create_standalone_dev_type is set to a valid value.
+ bool create_standalone_dev;
+ enum AVHWDeviceType create_standalone_dev_type;
// If not-0: the IMGFMT_ format that should be accepted in the libavcodec
// get_format callback.
int image_format;
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 6422346d31..c584482340 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -167,7 +167,8 @@ static const struct vd_lavc_hwdec mp_vd_lavc_nvdec = {
};
static const struct vd_lavc_hwdec mp_vd_lavc_nvdec_copy = {
.type = HWDEC_NVDEC_COPY,
- .image_format = IMGFMT_CUDA,
+ .create_standalone_dev = true,
+ .create_standalone_dev_type = AV_HWDEVICE_TYPE_CUDA,
.generic_hwaccel = true,
.set_hwframes = true,
.copying = true,
@@ -363,10 +364,31 @@ static bool hwdec_is_wrapper(struct vd_lavc_hwdec *hwdec, const char *decoder)
return bstr_endswith0(bstr0(decoder), hwdec->lavc_suffix);
}
+static void standalone_dev_destroy(struct mp_hwdec_ctx *ctx)
+{
+ av_buffer_unref(&ctx->av_device_ref);
+ talloc_free(ctx);
+}
+
static struct mp_hwdec_ctx *hwdec_create_dev(struct dec_video *vd,
struct vd_lavc_hwdec *hwdec,
bool autoprobe)
{
+ if (hwdec->create_standalone_dev) {
+ struct mp_hwdec_ctx *ctx = talloc_ptrtype(NULL, ctx);
+ *ctx = (struct mp_hwdec_ctx) {
+ .type = hwdec->type,
+ .ctx = NULL,
+ .destroy = standalone_dev_destroy,
+ };
+ if (av_hwdevice_ctx_create(&ctx->av_device_ref,
+ hwdec->create_standalone_dev_type, NULL, NULL, 0) < 0)
+ {
+ standalone_dev_destroy(ctx);
+ ctx = NULL;
+ }
+ return ctx;
+ }
if (hwdec->create_dev)
return hwdec->create_dev(vd->global, vd->log, autoprobe);
if (vd->hwdec_devs) {
@@ -392,7 +414,9 @@ static int hwdec_probe(struct dec_video *vd, struct vd_lavc_hwdec *hwdec,
return hwdec->copying ? -1 : HWDEC_ERR_NO_CTX;
if (dev->emulated)
r = HWDEC_ERR_EMULATED;
- if (hwdec->create_dev && dev->destroy)
+ bool owns_hwdec_dev = !!hwdec->create_dev ||
+ hwdec->create_standalone_dev;
+ if (owns_hwdec_dev && dev->destroy)
dev->destroy(dev);
}
if (r >= 0) {
@@ -603,7 +627,8 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
ctx->hwdec_dev = hwdec_create_dev(vd, ctx->hwdec, false);
if (!ctx->hwdec_dev)
goto error;
- ctx->owns_hwdec_dev = !!ctx->hwdec->create_dev;
+ ctx->owns_hwdec_dev = !!ctx->hwdec->create_dev ||
+ ctx->hwdec->create_standalone_dev;
if (ctx->hwdec_dev->restore_device)
ctx->hwdec_dev->restore_device(ctx->hwdec_dev);
if (!ctx->hwdec->set_hwframes) {