Message ID | bf521666-0053-22e6-9485-da7bc961fef4@gmail.com |
---|---|
State | Superseded |
Headers | show |
Am 02.05.2018 um 23:18 schrieb pkv.stream: > 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. > I indeed forgot that old patch. I will rebase and apply it first, so this patch will need some rebasing as well. One note about the patch: doing the capability check on every single frame seems wasteful. I'm not sure how slow it is, but I'd expect it to be not free. So doing that check once in the beginning with all the other cap checks and storing it somewhere would be better.
Le 02/05/2018 à 11:58 PM, Timo Rothenpieler a écrit : > Am 02.05.2018 um 23:18 schrieb pkv.stream: >> 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. >> > > I indeed forgot that old patch. I will rebase and apply it first, so > this patch will need some rebasing as well. > > One note about the patch: doing the capability check on every single > frame seems wasteful. I'm not sure how slow it is, but I'd expect it > to be not free. > > So doing that check once in the beginning with all the other cap > checks and storing it somewhere would be better. Hi thanks for your feedback. I was not sure of whether to put the capability check with the others in nvenc_check_capabilities because if the cap is missing this would remove the encoder altogether: ex: ln. 453 : if ((ret = nvenc_check_capabilities(avctx)) < 0) goto fail3; I'll move it there then or if you think it's preferrable, I can move it to ff_nvenc_encode_init and store it. Which option do you prefer ? I'll resubmit and rebase once the other patch is committed. thanks > > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Am 02.05.2018 um 23:58 schrieb Timo Rothenpieler: > Am 02.05.2018 um 23:18 schrieb pkv.stream: >> 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. >> > > I indeed forgot that old patch. I will rebase and apply it first, so > this patch will need some rebasing as well. > > One note about the patch: doing the capability check on every single > frame seems wasteful. I'm not sure how slow it is, but I'd expect it to > be not free. > > So doing that check once in the beginning with all the other cap checks > and storing it somewhere would be better. > Also, the bitrate changes seem a bit static and don't match up with any of the rc modes, setting all the bitrate settings to the same avctx->bit_rate. Ideally this would use the same rate-control logic the main init uses.
Le 03/05/2018 à 12:14 AM, Timo Rothenpieler a écrit : > Am 02.05.2018 um 23:58 schrieb Timo Rothenpieler: >> Am 02.05.2018 um 23:18 schrieb pkv.stream: >>> 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. >>> >> >> I indeed forgot that old patch. I will rebase and apply it first, so >> this patch will need some rebasing as well. >> >> One note about the patch: doing the capability check on every single >> frame seems wasteful. I'm not sure how slow it is, but I'd expect it >> to be not free. >> >> So doing that check once in the beginning with all the other cap >> checks and storing it somewhere would be better. >> > > Also, the bitrate changes seem a bit static and don't match up with > any of the rc modes, setting all the bitrate settings to the same > avctx->bit_rate. Ideally this would use the same rate-control logic > the main init uses. > sure will fix that Thanks again > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> Hi > thanks for your feedback. > I was not sure of whether to put the capability check with the others in > nvenc_check_capabilities because if the cap is missing this would remove > the encoder altogether: > > ex: ln. 453 : if ((ret = nvenc_check_capabilities(avctx)) < 0) > goto fail3; > > I'll move it there then or if you think it's preferrable, I can move it > to ff_nvenc_encode_init and store it. > Which option do you prefer ? I'll resubmit and rebase once the other > patch is committed. Just add a new field to the struct NvencContext. And there is no need to fail on this check, store its result and go on, unless it's < 0, which indicates an actual error. There's also no need to check for a changed bitrate outside of the call to reconfig_encoder, when making the same check inside of it again.
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);