Variable bit rates with "-vb" and "minrate"/"maxrate" settings in FFmpeg

Please read the documentation for FFmpeg, and run ffmpeg -h full for the list of options. Also, have a look at this article I wrote, which shows the differences between rate control modes in encoders like x264 and x265.

Generally, here's what the options mean:

  • -b:v (or -vb, the same) specifies the target average bit rate for the encoder to use:

    -b <int> E..VA. set bitrate (in bits/s) (from 0 to INT_MAX)

  • -minrate specifies a minimum tolerance to be used:

    -minrate <int> E..VA. Set minimum bitrate tolerance (in bits/s). Most useful in setting up a CBR encode. It is of little use otherwise. (from INT_MIN to INT_MAX)

  • -maxrate specifies a maximum tolerance. However, as the documentation indicates, this is only used in conjunction with bufsize:

    -maxrate <int> E..VA. Set maximum bitrate tolerance (in bits/s). Requires bufsize to be set. (from INT_MIN to INT_MAX)

    -bufsize <int> E..VA. set ratecontrol buffer size (in bits) (from INT_MIN to INT_MAX)

    This only makes sense for variable bit rate encoding, where instead of using a constant bit rate or constant quality model, the encoder simulates a transmission with a virtual buffer at the decoder. The -minrate/-maxrate/-bufsize options control that buffer size. You typically only use this mode for streaming, since the technique will constrain the bit rate in order to not exceed a certain value which would cause the decoder buffer to over- or underflow.

To summarize, you have several options for limiting bitrate:

  1. To set up a CBR process, you have to check what the encoder offers. Typically, you cannot achieve a "perfect" constant bitrate, since the encoder will not waste bits. Setting -b:v, -minrate, and -maxrate to the same levels will achieve that, for example for libx264:

    ffmpeg -i input.mp4 -c:v libx264 -x264-params "nal-hrd=cbr" -b:v 1M -minrate 1M -maxrate 1M -bufsize 2M output.ts
    

    Warning: This might result in low quality for videos that are hard to encode, and it will waste bits. Unless you absolutely need to achieve a constant rate output, do not use this option.

  2. Set up a constrained / variable bit rate process for streaming. Use -b:v 3500K -maxrate 3500K -bufsize 1000K, for example. You'll have to adjust the rate and buffer sizes to the context obviously. The higher the buffer size, the higher the allowed bitrate variation.

  3. Use a constant quality target and limit the bitrate only to catch spikes. For example, use -c:v libx264 -crf 23 -maxrate 4M -bufsize 4M to encode at variable bitrate with a target CRF of 23, but limit the output to a maximum of 4 MBit/s.