Nvenc ffmpeg plugin CBR options


Since a couple of days I’m playing with a Tesla P4 card and transcoding live 4k contents with ffmpeg (which works perfectly fine). The only thing that puzzles me is how to generate the “most CBR” output…here is an example command used, it generates an output that is mostly CBR, but it varies +/- 1Mbit around my target value. ffmpeg was never good at generating a true CBR output, one usually tries to micmic it (https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate).

ffmpeg -hwaccel nvdec -i INPUT_MCAST -c:a aac -c:v hevc_nvenc -profile:v main10 -rc cbr -b:v 10M -minrate 10M -maxrate 10M -bufsize 512k -r 50 -g 100 -f OUTPUT_MCAST

In the NVDEC codec documentation, I see 2 options related to CBR:

-rc cbr 
-cbr 1

Does anyone know what the difference is? Setting “-cbr 1” doesn’t seem to make any difference compared to "-rc cbr "?

For reference, the codec options available:

ffmpeg -h encoder=hevc_nvenc
ffmpeg version n4.2-60-g3de33c6 Copyright (c) 2000-2019 the FFmpeg developers
hevc_nvenc AVOptions:
  -preset            <int>        E..V..... Set the encoding preset (from 0 to 11) (default medium)
     default                      E..V.....
     slow                         E..V..... hq 2 passes
     medium                       E..V..... hq 1 pass
     fast                         E..V..... hp 1 pass
     hp                           E..V.....
     hq                           E..V.....
     bd                           E..V.....
     ll                           E..V..... low latency
     llhq                         E..V..... low latency hq
     llhp                         E..V..... low latency hp
     lossless                     E..V..... lossless
     losslesshp                   E..V..... lossless hp
  -profile           <int>        E..V..... Set the encoding profile (from 0 to 4) (default main)
     main                         E..V.....
     main10                       E..V.....
     rext                         E..V.....
  -level             <int>        E..V..... Set the encoding level restriction (from 0 to 186) (default auto)
     auto                         E..V.....
     1                            E..V.....
     1.0                          E..V.....
     2                            E..V.....
     2.0                          E..V.....
     2.1                          E..V.....
     3                            E..V.....
     3.0                          E..V.....
     3.1                          E..V.....
     4                            E..V.....
     4.0                          E..V.....
     4.1                          E..V.....
     5                            E..V.....
     5.0                          E..V.....
     5.1                          E..V.....
     5.2                          E..V.....
     6                            E..V.....
     6.0                          E..V.....
     6.1                          E..V.....
     6.2                          E..V.....
  -tier              <int>        E..V..... Set the encoding tier (from 0 to 1) (default main)
     main                         E..V.....
     high                         E..V.....
  -rc                <int>        E..V..... Override the preset rate-control (from -1 to INT_MAX) (default -1)
     constqp                      E..V..... Constant QP mode
     vbr                          E..V..... Variable bitrate mode
     cbr                          E..V..... Constant bitrate mode
     vbr_minqp                    E..V..... Variable bitrate mode with MinQP (deprecated)
     ll_2pass_quality              E..V..... Multi-pass optimized for image quality (deprecated)
     ll_2pass_size                E..V..... Multi-pass optimized for constant frame size (deprecated)
     vbr_2pass                    E..V..... Multi-pass variable bitrate mode (deprecated)
     cbr_ld_hq                    E..V..... Constant bitrate low delay high quality mode
     cbr_hq                       E..V..... Constant bitrate high quality mode
     vbr_hq                       E..V..... Variable bitrate high quality mode
  -rc-lookahead      <int>        E..V..... Number of frames to look ahead for rate-control (from 0 to INT_MAX) (default 0)
  -surfaces          <int>        E..V..... Number of concurrent surfaces (from 0 to 64) (default 0)
  -cbr               <boolean>    E..V..... Use cbr encoding mode (default false)
  -2pass             <boolean>    E..V..... Use 2pass encoding mode (default auto)
  -gpu               <int>        E..V..... Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from -2 to INT_MAX) (default any)
     any                          E..V..... Pick the first device available
     list                         E..V..... List the available devices
  -delay             <int>        E..V..... Delay frame output by the given amount of frames (from 0 to INT_MAX) (default INT_MAX)
  -no-scenecut       <boolean>    E..V..... When lookahead is enabled, set this to 1 to disable adaptive I-frame insertion at scene cuts (default false)
  -forced-idr        <boolean>    E..V..... If forcing keyframes, force them as IDR frames. (default false)
  -spatial_aq        <boolean>    E..V..... set to 1 to enable Spatial AQ (default false)
  -temporal_aq       <boolean>    E..V..... set to 1 to enable Temporal AQ (default false)
  -zerolatency       <boolean>    E..V..... Set 1 to indicate zero latency operation (no reordering delay) (default false)
  -nonref_p          <boolean>    E..V..... Set this to 1 to enable automatic insertion of non-reference P-frames (default false)
  -strict_gop        <boolean>    E..V..... Set 1 to minimize GOP-to-GOP rate fluctuations (default false)
  -aq-strength       <int>        E..V..... When Spatial AQ is enabled, this field is used to specify AQ strength. AQ strength scale is from 1 (low) - 15 (aggressive) (from 1 to 15) (default 8)
  -cq                <float>      E..V..... Set target quality level (0 to 51, 0 means automatic) for constant quality mode in VBR rate control (from 0 to 51) (default 0)
  -aud               <boolean>    E..V..... Use access unit delimiters (default false)
  -bluray-compat     <boolean>    E..V..... Bluray compatibility workarounds (default false)
  -init_qpP          <int>        E..V..... Initial QP value for P frame (from -1 to 51) (default -1)
  -init_qpB          <int>        E..V..... Initial QP value for B frame (from -1 to 51) (default -1)
  -init_qpI          <int>        E..V..... Initial QP value for I frame (from -1 to 51) (default -1)
  -qp                <int>        E..V..... Constant quantization parameter rate control method (from -1 to 51) (default -1)
  -weighted_pred     <int>        E..V..... Set 1 to enable weighted prediction (from 0 to 1) (default 0)
  -b_ref_mode        <int>        E..V..... Use B frames as references (from 0 to 2) (default disabled)
     disabled                     E..V..... B frames will not be used for reference
     each                         E..V..... Each B frame will be used for reference
     middle                       E..V..... Only (number of B frames)/2 will be used for reference

My setup:
CentOS 7
Tesla P4
Driver Version: 418.87.00
CUDA Version: 10.1

1 Like

From reading the code in nvenc.c it looks like they are exactly the same.

    if (ctx->rc < 0) {
        if (ctx->flags & NVENC_ONE_PASS)
            ctx->twopass = 0;
        if (ctx->flags & NVENC_TWO_PASSES)
            ctx->twopass = 1;

        if (ctx->twopass < 0)
            ctx->twopass = (ctx->flags & NVENC_LOWLATENCY) != 0;

        if (ctx->cbr) {
            if (ctx->twopass) {
                ctx->rc = NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ;
            } else {
                ctx->rc = NV_ENC_PARAMS_RC_CBR;
        } else if (ctx->cqp >= 0) {
            ctx->rc = NV_ENC_PARAMS_RC_CONSTQP;
        } else if (ctx->twopass) {
            ctx->rc = NV_ENC_PARAMS_RC_VBR_HQ;
        } else if (avctx->qmin >= 0 && avctx->qmax >= 0) {
            ctx->rc = NV_ENC_PARAMS_RC_VBR_MINQP;