From 165799157de1f688399356d25a7aebf695665c70 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 31 May 2019 20:11:32 +0200 Subject: [PATCH] vd_lavc: add --hwdec-extra-frames option Surprised this didn't exist before. --- DOCS/man/options.rst | 15 +++++++++++++++ video/decode/vd_lavc.c | 15 ++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 2e64966c85..8ccf3caa4f 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -1092,6 +1092,21 @@ Video barely related to this anymore, but will be somewhat compatible in some cases. +``--hwdec-extra-frames=`` + Number of GPU frames hardware decoding should preallocate (default: see + ``--list-options`` output). If this is too low, frame allocation may fail + during decoding, and video frames might get dropped and/or corrupted. + Setting it too high simply wastes GPU memory and has no advantages. + + This value is used only for hardware decoding APIs which require + preallocating surfaces (known examples include ``d3d11va`` and ``vaapi``). + For other APIs, frames are allocated as needed. The details depend on the + libavcodec implementations of the hardware decoders. + + The required number of surfaces depends on dynamic runtime situations. The + default is a fixed value that is thought to be sufficient for most uses. But + in certain situations, it may not be enough. + ``--hwdec-image-format=`` Set the internal pixel format used by hardware decoding via ``--hwdec`` (default ``no``). The special value ``no`` selects an implementation diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 97b3fa8b7d..dfc8bda804 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -67,12 +67,6 @@ static int hwdec_validate_opt(struct mp_log *log, const m_option_t *opt, #define HWDEC_DELAY_QUEUE_COUNT 2 -// Maximum number of surfaces the player wants to buffer. -// This number might require adjustment depending on whatever the player does; -// for example, if vo_gpu increases the number of reference surfaces for -// interpolation, this value has to be increased too. -#define HWDEC_EXTRA_SURFACES 6 - #define OPT_BASE_STRUCT struct vd_lavc_params struct vd_lavc_params { @@ -92,6 +86,7 @@ struct vd_lavc_params { char *hwdec_api; char *hwdec_codecs; int hwdec_image_format; + int hwdec_extra_frames; }; static const struct m_opt_choice_alternatives discard_names[] = { @@ -127,6 +122,7 @@ const struct m_sub_options vd_lavc_conf = { hwdec_validate_opt), OPT_STRING("hwdec-codecs", hwdec_codecs, 0), OPT_IMAGEFORMAT("hwdec-image-format", hwdec_image_format, 0, .min = -1), + OPT_INTRANGE("hwdec-extra-frames", hwdec_extra_frames, 0, 0, 256), {0} }, .size = sizeof(struct vd_lavc_params), @@ -141,6 +137,11 @@ const struct m_sub_options vd_lavc_conf = { .dr = 1, .hwdec_api = HAVE_RPI ? "mmal" : "no", .hwdec_codecs = "h264,vc1,hevc,vp9", + // Maximum number of surfaces the player wants to buffer. This number + // might require adjustment depending on whatever the player does; + // for example, if vo_gpu increases the number of reference surfaces for + // interpolation, this value has to be increased too. + .hwdec_extra_frames = 6, }, }; @@ -762,7 +763,7 @@ static int init_generic_hwaccel(struct mp_filter *vd, enum AVPixelFormat hw_fmt) // 1 surface is already included by libavcodec. The field is 0 if the // hwaccel supports dynamic surface allocation. if (new_fctx->initial_pool_size) - new_fctx->initial_pool_size += HWDEC_EXTRA_SURFACES - 1; + new_fctx->initial_pool_size += ctx->opts->hwdec_extra_frames - 1; const struct hwcontext_fns *fns = hwdec_get_hwcontext_fns(new_fctx->device_ctx->type);