From 5b145290df2998a9836a93eb925289c6c8b63af0 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Mon, 29 Jan 2018 22:18:00 +0000 Subject: [PATCH] lavc: Add support for increasing hardware frame pool sizes AVCodecContext.extra_hw_frames is added to the size of hardware frame pools created by libavcodec for APIs which require fixed-size pools. This allows the user to keep references to a greater number of frames after decode, which may be necessary for some use-cases. It is also added to the initial_pool_size value returned by avcodec_get_hw_frames_parameters() if a fixed-size pool is required. --- doc/APIchanges | 3 +++ libavcodec/avcodec.h | 14 ++++++++++++++ libavcodec/decode.c | 9 +++++++++ libavcodec/options_table.h | 1 + libavcodec/version.h | 2 +- 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 0bde3a052d..d62f7674f3 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2017-03-23 API changes, most recent first: +2018-02-xx - xxxxxxx - lavc 58.9.0 - avcodec.h + Add AVCodecContext.extra_hw_frames. + 2017-xx-xx - xxxxxxx - lavc 58.8.0 - avcodec.h Add const to AVCodecContext.hwaccel. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 7eaa0c9277..03a3d5bd6d 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2739,6 +2739,20 @@ typedef struct AVCodecContext { * AVCodecContext.get_format callback) */ int hwaccel_flags; + + /** + * Video decoding only. Sets the number of extra hardware frames which + * the decoder will allocate for use by the caller. This must be set + * before avcodec_open2() is called. + * + * Some hardware decoders require all frames that they will use for + * output to be defined in advance before decoding starts. For such + * decoders, the hardware frame pool must therefore be of a fixed size. + * The extra frames set here are on top of any number that the decoder + * needs internally in order to operate normally (for example, frames + * used as reference pictures). + */ + int extra_hw_frames; } AVCodecContext; /** diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 12a95d4221..e024a32321 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -791,6 +791,15 @@ int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, ret = hwa->frame_params(avctx, frames_ref); if (ret >= 0) { + AVHWFramesContext *frames_ctx = (AVHWFramesContext*)frames_ref->data; + + if (frames_ctx->initial_pool_size) { + // If the user has requested that extra output surfaces be + // available then add them here. + if (avctx->extra_hw_frames > 0) + frames_ctx->initial_pool_size += avctx->extra_hw_frames; + } + *out_frames_ref = frames_ref; } else { av_buffer_unref(&frames_ref); diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 925ef376f3..4b0a8344d0 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -419,6 +419,7 @@ static const AVOption avcodec_options[] = { {"side_data_only_packets", NULL, OFFSET(side_data_only_packets), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, A|V|E }, #endif {"apply_cropping", NULL, OFFSET(apply_cropping), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, V | D }, +{"extra_hw_frames", "Number of extra hardware frames to allocate for the user", OFFSET(extra_hw_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, V|D }, {NULL}, }; diff --git a/libavcodec/version.h b/libavcodec/version.h index 9b47110301..36a014959e 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 8 +#define LIBAVCODEC_VERSION_MINOR 9 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \