From 58d83a93094503992a8f717c64b636450629555c Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 30 Oct 2017 18:33:18 +0100 Subject: 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. --- video/decode/lavc.h | 4 ++++ video/decode/vd_lavc.c | 31 ++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) (limited to 'video') 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) { -- cgit v1.2.3