[FFmpeg-devel] [PATCH v4]avocdec/nvenc: Reconfigure bitrate on the fly
pkv.stream
pkv.stream at gmail.com
Thu May 3 10:51:05 EEST 2018
Hi,
in previous versions ReconfigureEncoder was called at each frame once
bitrate was changed.
Fixed that.
The patch was rebased against
https://github.com/BtbN/FFmpeg/commit/4e8265e3a63a71a40730e8eb575d8aa760bdcddc
Sorry about the back and forth.
Regards
-------------- next part --------------
From 7c9653faabfe5a9413b2fdcdb7e218991c25ef46 Mon Sep 17 00:00:00 2001
From: pkviet <pkv.stream at gmail.com>
Date: Thu, 3 May 2018 02:15:52 +0200
Subject: [PATCH] avcodec/nvenc: Change bitrate on the fly
The patch enables dynamic bitrate through ReconfigureEncoder method
from nvenc API.
This is useful for live streaming in case of network congestion.
Signed-off-by: pkviet <pkv.stream at gmail.com>
---
libavcodec/nvenc.c | 38 ++++++++++++++++++++++++++++----------
libavcodec/nvenc.h | 1 +
2 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 3313c376fe..c19b600c4c 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -457,6 +457,8 @@ static av_cold int nvenc_check_device(AVCodecContext *avctx, int idx)
if ((ret = nvenc_check_capabilities(avctx)) < 0)
goto fail3;
+ ctx->dynamic_bitrate = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE);
+
av_log(avctx, loglevel, "supports NVENC\n");
dl_fn->nvenc_device_count++;
@@ -550,6 +552,8 @@ static av_cold int nvenc_setup_device(AVCodecContext *avctx)
av_log(avctx, AV_LOG_FATAL, "Provided device doesn't support required NVENC features\n");
return ret;
}
+ ctx->dynamic_bitrate = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE);
+
} else {
int i, nb_devices = 0;
@@ -1935,36 +1939,50 @@ static int reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame)
NVENCSTATUS ret;
NV_ENC_RECONFIGURE_PARAMS params = { 0 };
- int needs_reconfig = 0;
- int needs_encode_config = 0;
int dw, dh;
+ int reconfig_dar, reconfig_bitrate;
params.version = NV_ENC_RECONFIGURE_PARAMS_VER;
params.reInitEncodeParams = ctx->init_encode_params;
compute_dar(avctx, &dw, &dh);
- if (dw != ctx->init_encode_params.darWidth || dh != ctx->init_encode_params.darHeight) {
+ reconfig_dar = dw != ctx->init_encode_params.darWidth || dh != ctx->init_encode_params.darHeight;
+ if (reconfig_dar) {
av_log(avctx, AV_LOG_VERBOSE,
"aspect ratio change (DAR): %d:%d -> %d:%d\n",
ctx->init_encode_params.darWidth,
ctx->init_encode_params.darHeight, dw, dh);
-
params.reInitEncodeParams.darHeight = dh;
params.reInitEncodeParams.darWidth = dw;
-
- needs_reconfig = 1;
+ }
+ reconfig_bitrate = ctx->dynamic_bitrate > 0 && ctx->rc != NV_ENC_PARAMS_RC_CONSTQP
+ && ctx->encode_config.rcParams.averageBitRate != avctx->bit_rate;
+ if (reconfig_bitrate) {
+ params.version = NV_ENC_RECONFIGURE_PARAMS_VER;
+ params.resetEncoder = 1;
+ params.forceIDR = 1;
+ params.reInitEncodeParams = ctx->init_encode_params;
+ params.reInitEncodeParams.encodeConfig->rcParams.averageBitRate = avctx->bit_rate;
}
- if (!needs_encode_config)
+ if (!reconfig_bitrate)
params.reInitEncodeParams.encodeConfig = NULL;
- if (needs_reconfig) {
+ if (reconfig_dar || reconfig_bitrate) {
ret = p_nvenc->nvEncReconfigureEncoder(ctx->nvencoder, ¶ms);
if (ret != NV_ENC_SUCCESS) {
nvenc_print_error(avctx, ret, "failed to reconfigure nvenc");
} else {
- ctx->init_encode_params.darHeight = dh;
- ctx->init_encode_params.darWidth = dw;
+ if (reconfig_dar) {
+ ctx->init_encode_params.darHeight = dh;
+ ctx->init_encode_params.darWidth = dw;
+ av_log(avctx, AV_LOG_VERBOSE, "dar reconfigured\n");
+ }
+ if (reconfig_bitrate) {
+ ctx->encode_config.rcParams.averageBitRate = avctx->bit_rate;
+ av_log(avctx, AV_LOG_VERBOSE, "bitrate reconfigured\n");
+ }
+
}
}
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index c7506d6a15..fd2350aaa6 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -184,6 +184,7 @@ typedef struct NvencContext
int weighted_pred;
int coder;
int b_ref_mode;
+ int dynamic_bitrate;
} NvencContext;
int ff_nvenc_encode_init(AVCodecContext *avctx);
--
2.16.2.windows.1
More information about the ffmpeg-devel
mailing list