Message ID | cf36c6f3-27df-94e0-52f3-3602cb32592c@gmail.com |
---|---|
State | New |
Headers | show |
Am 03.05.2018 um 09:51 schrieb pkv.stream: > 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 Slightly modified the approach and pushed it here: https://github.com/BtbN/FFmpeg/commit/660a137b4dad03e6b9f5f87b5ff946ced297a7f2 Will push tomorrow if no issues with it come up.
Le 03/05/2018 à 7:43 PM, Timo Rothenpieler a écrit : > Am 03.05.2018 um 09:51 schrieb pkv.stream: >> 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 > > > Slightly modified the approach and pushed it here: > https://github.com/BtbN/FFmpeg/commit/660a137b4dad03e6b9f5f87b5ff946ced297a7f2 > thanks a lot for the marked improvements ! for dynamic resolution, maybe add a check ? ctx->support_dyn_res = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_RES_CHANGE); and: if (dw != ctx->init_encode_params.darWidth || dh != ctx->init_encode_params.darHeight) ==> if ( (dw != ctx->init_encode_params.darWidth || dh != ctx->init_encode_params.darHeight) && ctx->support_dyn_res) Regards
> for dynamic resolution, maybe add a check ? > > ctx->support_dyn_res = nvenc_check_cap(avctx, > NV_ENC_CAPS_SUPPORT_DYN_RES_CHANGE); > > and: > if (dw != ctx->init_encode_params.darWidth || dh != > ctx->init_encode_params.darHeight) > > ==> > if ( (dw != ctx->init_encode_params.darWidth || dh != > ctx->init_encode_params.darHeight) && ctx->support_dyn_res) That's not a resolution change, only a dar change. I'm not sure if actual resolution changes are even supported by avcodec.
applied
2018-05-04 10:32 GMT+02:00, Timo Rothenpieler <timo@rothenpieler.org>: > I'm not sure if actual resolution changes are even supported > by avcodec. There are better (read: DVB) samples but I can't find them atm: https://trac.ffmpeg.org/raw-attachment/ticket/1507/Wrong_aspect_after_resolution_change.rmvb Carl Eugen
Am 05.05.2018 um 02:00 schrieb Carl Eugen Hoyos: > 2018-05-04 10:32 GMT+02:00, Timo Rothenpieler <timo@rothenpieler.org>: > >> I'm not sure if actual resolution changes are even supported >> by avcodec. > > There are better (read: DVB) samples but I can't find them atm: > https://trac.ffmpeg.org/raw-attachment/ticket/1507/Wrong_aspect_after_resolution_change.rmvb I was under the impression that the ones in DVB/mpegts work by ending one stream, and starting another one? So essentially spinning up an entire new de/encoder, and not by just changing the width/height in the AVCodecContext mid stream, hoping the encoder does something reasonable? At least libx264.c does not check for width/height changes in its reconfigure function.
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);