From c7ea0cd68f2cd68edea2f64060c1bcb483005a50 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 21 Jan 2023 15:45:11 +0100 Subject: [PATCH] vd_lavc: add "auto" choice for vd-lavc-dr --vd-lavc-dr defaulted to "yes", which caused issues on certain hardware. Instead of disabling it, add a new "auto" value and make it the default. The "auto" choice will enable DR only when we can request host-cached buffers (as signalled by the new VO_DR_FLAG_HOST_CACHED). Co-authored-by: Nicolas F. Co-authored-by: Niklas Haas --- DOCS/interface-changes.rst | 1 + DOCS/man/options.rst | 8 ++++++-- video/decode/vd_lavc.c | 11 +++++++---- video/out/vo.h | 5 +++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index 6644638b29..6177d09a40 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -45,6 +45,7 @@ Interface changes watch-later. It is still written by default but you may need to explictly add `start` depending on how you have `--watch-later-options` configured. + - add `--vd-lavc-dr=auto` and make it the default --- mpv 0.35.0 --- - add the `--vo=gpu-next` video output driver, as well as the options `--allow-delayed-peak-detect`, `--builtin-scalers`, diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 3b2e2d1bf5..7e99b2a5d5 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -1700,8 +1700,8 @@ Video support this, then it will be treated as ``cpu``, regardless of the setting. Currently, only ``gpu-next`` supports film grain application. -``--vd-lavc-dr=`` - Enable direct rendering (default: yes). If this is set to ``yes``, the +``--vd-lavc-dr=`` + Enable direct rendering (default: auto). If this is set to ``yes``, the video will be decoded directly to GPU video memory (or staging buffers). This can speed up video upload, and may help with large resolutions or slow hardware. This works only with the following VOs: @@ -1709,6 +1709,10 @@ Video - ``gpu``: requires at least OpenGL 4.4 or Vulkan. - ``libmpv``: The libmpv render API has optional support. + The ``auto`` option will try to guess whether DR can improve performance + on your particular hardware. Currently this enables it on AMD or NVIDIA + if using OpenGL or unconditionally if using Vulkan. + Using video filters of any kind that write to the image data (or output newly allocated frames) will silently disable the DR code path. diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 86f872973f..52ee6881bc 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -120,7 +120,8 @@ const struct m_sub_options vd_lavc_conf = { {"vd-lavc-software-fallback", OPT_CHOICE(software_fallback, {"no", INT_MAX}, {"yes", 1}), M_RANGE(1, INT_MAX)}, {"vd-lavc-o", OPT_KEYVALUELIST(avopts)}, - {"vd-lavc-dr", OPT_FLAG(dr)}, + {"vd-lavc-dr", OPT_CHOICE(dr, + {"auto", -1}, {"no", 0}, {"yes", 1})}, {"hwdec", OPT_STRING(hwdec_api), .help = hwdec_opt_help, .flags = M_OPT_OPTIONAL_PARAM | UPDATE_HWDEC}, @@ -139,7 +140,7 @@ const struct m_sub_options vd_lavc_conf = { .skip_idct = AVDISCARD_DEFAULT, .skip_frame = AVDISCARD_DEFAULT, .framedrop = AVDISCARD_NONREF, - .dr = 1, + .dr = -1, .hwdec_api = "no", .hwdec_codecs = "h264,vc1,hevc,vp8,vp9,av1,prores", // Maximum number of surfaces the player wants to buffer. This number @@ -984,8 +985,10 @@ static int get_buffer2_direct(AVCodecContext *avctx, AVFrame *pic, int flags) struct mp_image *img = mp_image_pool_get_no_alloc(p->dr_pool, imgfmt, w, h); if (!img) { - MP_DBG(p, "Allocating new DR image...\n"); - img = vo_get_image(p->vo, imgfmt, w, h, stride_align, 0); + bool host_cached = p->opts->dr == -1; // auto + int dr_flags = host_cached ? VO_DR_FLAG_HOST_CACHED : 0; + MP_DBG(p, "Allocating new%s DR image...\n", host_cached ? " (host-cached)" : ""); + img = vo_get_image(p->vo, imgfmt, w, h, stride_align, dr_flags); if (!img) { MP_DBG(p, "...failed..\n"); goto fallback; diff --git a/video/out/vo.h b/video/out/vo.h index 8df825e582..a2073944b3 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -194,6 +194,11 @@ enum { VO_CAP_FILM_GRAIN = 1 << 3, }; +enum { + // Require DR buffers to be host-cached (i.e. fast readback) + VO_DR_FLAG_HOST_CACHED = 1 << 0, +}; + #define VO_MAX_REQ_FRAMES 10 struct vo;