From 6b745769b1fd15ba03edad3fe381abb745bf9907 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 28 Oct 2017 19:59:08 +0200 Subject: vd_lavc: add support for nvdec hwaccel See manpage additions. (In ffmpeg-mpv and Libav, this is still called "cuvid". Libav won't work yet, because it has no frame params support yet, but this could get fixed soon.) --- DOCS/man/options.rst | 8 ++++++++ options/options.c | 2 ++ video/decode/vd_lavc.c | 15 +++++++++++++++ video/hwdec.h | 2 ++ video/out/gpu/hwdec.c | 2 ++ video/out/opengl/hwdec_cuda.c | 18 +++++++++++++++++- 6 files changed, 46 insertions(+), 1 deletion(-) diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 5c4882883a..7cd399d4f1 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -695,6 +695,8 @@ Video :rpi-copy: copies video back to system RAM (Raspberry Pi only) :cuda: requires ``--vo=gpu`` (Any platform CUDA is available) :cuda-copy: copies video back to system RAM (Any platform CUDA is available) + :nvdec: requires ``--vo=gpu`` (Any platform CUDA is available) + :nvdec-copy: copies video back to system RAM (Any platform CUDA is available) :crystalhd: copies video back to system RAM (Any platform supported by hardware) :rkmpp: requires ``--vo=gpu`` (some RockChip devices only) @@ -723,6 +725,12 @@ Video deinterlacing. ``cuda`` should always be preferred unless the ``gpu`` vo is not being used or filters are required. + ``nvdec`` is a newer implementation of CUVID/CUDA decoding, which uses the + FFmpeg decoders for file parsing. Experimental, is known not to correctly + check whether decoding is supported by the hardware at all. Deinterlacing + is not supported. Since this uses FFmpeg's codec parsers, it is expected + that this generally causes fewer issues than ``cuda``. Requires ffmpeg-mpv. + Most video filters will not work with hardware decoding as they are primarily implemented on the CPU. Some exceptions are ``vdpaupp``, ``vdpaurb`` and ``vavpp``. See `VIDEO FILTERS`_ for more details. diff --git a/options/options.c b/options/options.c index 8e940be347..bac9b3bcaf 100644 --- a/options/options.c +++ b/options/options.c @@ -117,6 +117,8 @@ const struct m_opt_choice_alternatives mp_hwdec_names[] = { {"mediacodec-copy",HWDEC_MEDIACODEC_COPY}, {"cuda", HWDEC_CUDA}, {"cuda-copy", HWDEC_CUDA_COPY}, + {"nvdec", HWDEC_NVDEC}, + {"nvdec-copy", HWDEC_NVDEC_COPY}, {"crystalhd", HWDEC_CRYSTALHD}, {0} }; diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index c07c1590fe..6f09908090 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -158,6 +158,19 @@ static const struct vd_lavc_hwdec mp_vd_lavc_rkmpp = { }; #if HAVE_CUDA_HWACCEL +static const struct vd_lavc_hwdec mp_vd_lavc_nvdec = { + .type = HWDEC_NVDEC, + .image_format = IMGFMT_CUDA, + .generic_hwaccel = true, + .set_hwframes = true, +}; +static const struct vd_lavc_hwdec mp_vd_lavc_nvdec_copy = { + .type = HWDEC_NVDEC_COPY, + .image_format = IMGFMT_CUDA, + .generic_hwaccel = true, + .set_hwframes = true, + .copying = true, +}; static const struct vd_lavc_hwdec mp_vd_lavc_cuda = { .type = HWDEC_CUDA, .image_format = IMGFMT_CUDA, @@ -272,6 +285,8 @@ static const struct vd_lavc_hwdec *const hwdec_list[] = { &mp_vd_lavc_mediacodec_copy, #endif #if HAVE_CUDA_HWACCEL + &mp_vd_lavc_nvdec, + &mp_vd_lavc_nvdec_copy, &mp_vd_lavc_cuda, &mp_vd_lavc_cuda_copy, #endif diff --git a/video/hwdec.h b/video/hwdec.h index 81ba4794b2..2b89c3247c 100644 --- a/video/hwdec.h +++ b/video/hwdec.h @@ -26,6 +26,8 @@ enum hwdec_type { HWDEC_MEDIACODEC_COPY, HWDEC_CUDA, HWDEC_CUDA_COPY, + HWDEC_NVDEC, + HWDEC_NVDEC_COPY, HWDEC_CRYSTALHD, HWDEC_RKMPP, }; diff --git a/video/out/gpu/hwdec.c b/video/out/gpu/hwdec.c index 9eefe3e287..d88dc5e779 100644 --- a/video/out/gpu/hwdec.c +++ b/video/out/gpu/hwdec.c @@ -35,6 +35,7 @@ extern const struct ra_hwdec_driver ra_hwdec_d3d11eglrgb; extern const struct ra_hwdec_driver ra_hwdec_dxva2gldx; extern const struct ra_hwdec_driver ra_hwdec_dxva2; extern const struct ra_hwdec_driver ra_hwdec_cuda; +extern const struct ra_hwdec_driver ra_hwdec_cuda_nvdec; extern const struct ra_hwdec_driver ra_hwdec_rpi_overlay; #if HAVE_DRMPRIME && HAVE_DRM extern const struct ra_hwdec_driver ra_hwdec_drmprime_drm; @@ -65,6 +66,7 @@ static const struct ra_hwdec_driver *const mpgl_hwdec_drivers[] = { #endif #if HAVE_CUDA_HWACCEL &ra_hwdec_cuda, + &ra_hwdec_cuda_nvdec, #endif #if HAVE_RPI &ra_hwdec_rpi_overlay, diff --git a/video/out/opengl/hwdec_cuda.c b/video/out/opengl/hwdec_cuda.c index d9c4c199f1..5aefed106d 100644 --- a/video/out/opengl/hwdec_cuda.c +++ b/video/out/opengl/hwdec_cuda.c @@ -160,7 +160,7 @@ static int cuda_init(struct ra_hwdec *hw) goto error; p->hwctx = (struct mp_hwdec_ctx) { - .type = HWDEC_CUDA, + .type = hw->driver->api, .ctx = p->decode_ctx, .av_device_ref = hw_device_ctx, }; @@ -340,3 +340,19 @@ const struct ra_hwdec_driver ra_hwdec_cuda = { .unmap = mapper_unmap, }, }; + +const struct ra_hwdec_driver ra_hwdec_cuda_nvdec = { + .name = "cuda-nvdec", + .api = HWDEC_NVDEC, + .imgfmts = {IMGFMT_CUDA, 0}, + .priv_size = sizeof(struct priv_owner), + .init = cuda_init, + .uninit = cuda_uninit, + .mapper = &(const struct ra_hwdec_mapper_driver){ + .priv_size = sizeof(struct priv), + .init = mapper_init, + .uninit = mapper_uninit, + .map = mapper_map, + .unmap = mapper_unmap, + }, +}; -- cgit v1.2.3