diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index d71a44521a..cd14af2852 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -609,6 +609,27 @@ static void nvenc_override_rate_control(AVCodecContext *avctx) rc->rateControlMode = ctx->rc; } +static av_cold int nvenc_recalc_surfaces(AVCodecContext *avctx) +{ + NvencContext *ctx = avctx->priv_data; + int nb_surfaces = 0; + + if (ctx->rc_lookahead > 0) { + nb_surfaces = ctx->rc_lookahead + ((ctx->encode_config.frameIntervalP > 0) ? ctx->encode_config.frameIntervalP : 0) + 1 + 4; + if (ctx->nb_surfaces < nb_surfaces) { + av_log(avctx, AV_LOG_WARNING, + "Defined rc_lookahead requires more surfaces, " + "increasing used surfaces %d -> %d\n", ctx->nb_surfaces, nb_surfaces); + ctx->nb_surfaces = nb_surfaces; + } + } + + ctx->nb_surfaces = FFMAX(1, FFMIN(MAX_REGISTERED_FRAMES, ctx->nb_surfaces)); + ctx->async_depth = FFMIN(ctx->async_depth, ctx->nb_surfaces - 1); + + return 0; +} + static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) { NvencContext *ctx = avctx->priv_data; @@ -965,6 +986,8 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx) ctx->initial_pts[0] = AV_NOPTS_VALUE; ctx->initial_pts[1] = AV_NOPTS_VALUE; + nvenc_recalc_surfaces(avctx); + nvenc_setup_rate_control(avctx); if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) { @@ -1091,11 +1114,6 @@ static av_cold int nvenc_setup_surfaces(AVCodecContext *avctx) { NvencContext *ctx = avctx->priv_data; int i, res; - int num_mbs = ((avctx->width + 15) >> 4) * ((avctx->height + 15) >> 4); - ctx->nb_surfaces = FFMAX((num_mbs >= 8160) ? 32 : 48, - ctx->nb_surfaces); - ctx->async_depth = FFMIN(ctx->async_depth, ctx->nb_surfaces - 1); - ctx->surfaces = av_mallocz_array(ctx->nb_surfaces, sizeof(*ctx->surfaces)); if (!ctx->surfaces)