In my previous article, I discussed good ffmpeg options for encoding MPEG-2 video. This worked great when encoding relatively low quality clips, like the 3 Mbps example in my article. When you want to encode much higher quality (like full 1920×1080 HD video at 20 Mbps or more), you start to run into some performance issues that you have to address through selection of the appropriate command line options.
- min/max rate versus bitrate tolerance: I found that the bitrate tolerance approach (specifying -b and -bt options) seems to incur a bigger performance penalty than using -minrate and -maxrate. I found that I could encode higher bitrates with min/max than with tolerance and still keep pace with the live capture. I also found that you can even specify bitrate=min=max (e.g. -b 37000k -minrate 37000k -maxrate 37000k) and not only get fairly consistent bitrates, but good performance. Giving ffmpeg a non-zero range doesn’t seem to improve performance. However, if you make the range too tight, you will see some video artifacts during periods of rapid movement onscreen. I think it is best to give ffmpeg a little “wiggle room” with a maximum rate somewhat higher (20% ?) than the desired bitrate. Note that if you use min/max instead of tolerance, you must specify an adequate -bufsize to avoid errors; I just set it to “50Mi”, which seems to work for just about any bitrate 37000k and below.
- B-frames penalty: it seems that encoding B-frames incurs a performance penalty. Removing the -bf option helped ffmpeg keep pace with live capture. And at high bitrates, I couldn’t see a visual improvement with B-frames enabled.
- GOP sizes a non-issue: I tried GOP sizes of 15 and 45 frames, with no noticeable performance differences
- Thread settings are vital: I had to set the threads to at least 4 for ffmpeg to be able to keep pace with the live capture at bitrates like 20 Mbps. Setting it to 8 was even better (note that this was on the Intel i7 quad core, hyperthreaded so it presents 8 cores to the operating system). In fact, it seemed necessary to use 8 threads to encode at very high bitrates like 37 Mbps.
With the huge bump in performance I got from using -minrate and -maxrate instead of -bt, I decided to apply this concept to all encodings, not just our high-bitrate MPEG-2 encodings.