[FFmpeg-devel] [PATCH]avocdec/nvenc: Reconfigure bitrate on the fly
pkv.stream
pkv.stream at gmail.com
Thu May 3 00:18:13 EEST 2018
Hello,
The patch enables dynamic bitrate through ReconfigureEncoder method from
nvenc API.
This is useful for live streaming in case of network congestion.
A similar patch for changing aspect ratio dynamically was previously
submitted by Miroslav Slugen:
https://patchwork.ffmpeg.org/patch/2523/
but apparently was forgotten.
Thanks.
-------------- next part --------------
From d0bcca0829db32cc35eb42c858013163e3fa8357 Mon Sep 17 00:00:00 2001
From: pkviet <pkv.stream at gmail.com>
Date: Wed, 2 May 2018 22:59:02 +0200
Subject: [PATCH] avcodec/nvenc: Reconfigure 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 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index c14112c366..ed5974f307 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -1920,6 +1920,35 @@ static int output_ready(AVCodecContext *avctx, int flush)
return (nb_ready > 0) && (nb_ready + nb_pending >= ctx->async_depth);
}
+static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame)
+{
+ NvencContext *ctx = avctx->priv_data;
+ NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
+ NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &(dl_fn->nvenc_funcs);
+ NV_ENC_RECONFIGURE_PARAMS rec= { 0 };
+ NVENCSTATUS nv_status;
+ BOOL bitrateChanged;
+
+ bitrateChanged = ctx->encode_config.rcParams.averageBitRate != avctx->bit_rate;
+
+ if (bitrateChanged) {
+ rec.version = NV_ENC_RECONFIGURE_PARAMS_VER;
+ rec.resetEncoder = 1;
+ rec.forceIDR = 1;
+ rec.reInitEncodeParams = ctx->init_encode_params;
+ rec.reInitEncodeParams.encodeConfig->rcParams.averageBitRate = avctx->bit_rate;
+ rec.reInitEncodeParams.encodeConfig->rcParams.maxBitRate = avctx->bit_rate;
+ rec.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize = avctx->bit_rate;
+ rec.reInitEncodeParams.encodeConfig->rcParams.vbvInitialDelay = avctx->bit_rate;
+ nv_status = p_nvenc->nvEncReconfigureEncoder(ctx->nvencoder, &rec);
+ if (nv_status != NV_ENC_SUCCESS) {
+ av_log(avctx, AV_LOG_INFO, "ReconfigureEncoder failed\n");
+ } else {
+ av_log(avctx, AV_LOG_INFO, "ReconfigureEncoder succeeded\n");
+ }
+ }
+}
+
int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
{
NVENCSTATUS nv_status;
@@ -1940,6 +1969,15 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
return AVERROR_EOF;
if (frame) {
+ res = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE);
+ if (res > 0) {
+ if (ctx->encode_config.rcParams.averageBitRate != avctx->bit_rate) {
+ av_log(avctx, AV_LOG_INFO, "Switching NVenc bitrate\n");
+ reconfig_encoder(avctx, frame);
+ }
+ } else {
+ av_log(avctx, AV_LOG_INFO, "Dynamic Encode bitrate change not supported\n");
+ }
in_surf = get_free_frame(ctx);
if (!in_surf)
return AVERROR(EAGAIN);
--
2.16.2.windows.1
More information about the ffmpeg-devel
mailing list