High bitrate real-time MPEG-2 encoding with ffmpeg

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.



Join the Conversation

1 Comment

  1. I’m trying to live capture to mpeg-2 so that I can immediately create DVDs to deliver to client, to be played back in court (they only have DVD players in most courts hilariously enough). I’m using a Magewell HDMI to usb 3.0 box, which allows me to bring the camera feed in using ffmpeg/avfoundation on a Mac. I’m having trouble keeping the audio/video in sync (even with the code you have in this article and the earlier article that links here), and I was hoping you might have some suggestions. Here’s my code:

    ffmpeg -thread_queue_size 32 -f avfoundation -copyts -start_at_zero -i “none:XI100” -f avfoundation -video_size 960×540 -pixel_format uyvy422 -framerate ntsc -vsync 0 -copyts -start_at_zero -thread_queue_size 32 -i “XI100:none” -vf crop=iw-240:ih:120:0 -vcodec mpeg2video -pix_fmt yuv420p -threads 16 -b:v 4500k -minrate 4500k -maxrate 4500k -bufsize 4500k -aspect 4:3 -r ntsc -s 720×480 -acodec ac3 -ac 2 -ab 256k -ar 44100 -f dvd /Users/Lapaki/Desktop/FF\ Test/date +%F\ date +%H_%M_%S.mpg

Leave a comment

Your email address will not be published. Required fields are marked *