CBR, CRF, and Changing Resolution using FFmpeg

In this article, we will go through the process of compressing a video using the H.264/AVC codec (libx264) and discuss the following: 

  • Creating a Constant Bitrate (CBR) encoded video 
  • Using the Constant Rate Factor (CRF) option to set desired quality
  • Change the resolution of the video to 1280x720 or 720p. 

For this purpose, we would be using a sample video with a resolution = 1920x1080 that can be downloaded at this link

Creating a Constant BitRate (CBR) Video

To understand CBR, we need to understand what is bitrate. Bitrate is the amount of information or data stored per second in any media file such as audio or video. In technical terms, it is the rate of the data output of an encoder. For example, 2200 kbps as a bitrate means that 2200 kilobits of data is stored per second. For a deeper discussion on bitrate, don’t miss this article on “bitrate vs. resolution”.

If the bitrate is “constant” throughout a video, it is termed as a CBR video. However, it is not possible to have constant bitrate for all the frames because of the different frame types and encoding priorities. Hence, if the bitrate is constant over a pre-determined time-period, the video is called a CBR-encoded video.

In order to output a constant bitrate video, we would be using the following FFmpeg output options : 

  • -b:v – Specifies the average target output bitrate of the video
  • -maxrate – Specifies the maximum bitrate tolerance 
  • -minrate – Specifies the minimum bitrate tolerance 
  • -bufsize – Specifies the rate control buffer size that helps to maintain the bitrate according to the values of b:v, maxrate and minrate 

After this, we also need to specify the video encoder using the -c:v option. As mentioned earlier, we are going to use the libx264 encoder in all the three cases. 

Let’s say, we need to have a CBR of 2200 kbps for our sample video. The FFmpeg command for the CBR conversion will be as follows : 

ffmpeg -i crowdrun.mp4 -b:v 2200k -maxrate 2200k -minrate 2200k -bufsize 2200k -c:v libx264 output.mp4 

Following are the screenshots of the above command:

FFMpeg CBR Encoding
FFMpeg CBR Encoding

If we try to analyze the bitrate of the output file, we would see that the difference between the highs and the lows of the bitrates in the file is very less. Ideally in CBR mode, the bitrate should be perfectly constant during the entire video but that is the ideal case and is not possible to achieve with software encoders. 

Using the CRF option to set desired quality 

The Constant Rate Factor or CRF is an option available in the libx264 encoder to set our desired output quality. It enables us to specify a target value that maps to a specific quality by adjusting the bitrates automatically based on the input video. 

This method is better if we want to have the same output quality for different kinds of input videos as FFmpeg would automatically adjust the bitrates based on the input video properties. On the other hand, the previous method will keep the same bitrate which will result in different output qualities for different inputs. 

The CRF value ranges from 0 to 51 where, 

  • 0 is lossless (best) with highest file size 
  • 23 is the default 
  • 51 is the poorest quality with lowest file size 

With low CRF value, the bitrate and hence, the file size of the video will increase. So it is important to decide the value based on the user requirements. 

Let’s say, we need a compressed output video with lesser file size, we can go with the value of 30. The FFmpeg command for this would be: 

ffmpeg -i crowdrun.mp4 -crf 30 -c:v libx264 output.mp4 

Following are the screenshots of the above command:

FFMpeg CRF encoding

FFmpeg CRF encoding

Change the resolution of the video to 1280×720 

FFmpeg provides a huge set of filters for various purposes. One of them is the scale filter that helps to scale the input to any resolution. 

The two parameters for this filter that we would be using are: 

  • w : It specifies the output width of the video 
  • h : It specifies the output height of the video 

Here, we would also add the CRF parameter(discussed in the last point) to compress and reduce the file size of the output video. 

The FFmpeg command for this would be: 

ffmpeg -i crowdrun.mp4 -vf scale=w=1280:h=720 -crf 30 -c:v libx264 output.mp4 

Following are the screenshots of the above command:

FFmpeg changing file resolution

Conclusion

In this article, we learned how to use FFmpeg to produce a CBR-encoded video, CRF-encoded video, and how to change the resolution of a file. These three operations are very important to any video compression system and we hope you are able to use them to further your video compression using FFmpeg.

Pallycon April NAB 2024

5 thoughts on “CBR, CRF, and Changing Resolution using FFmpeg”

  1. Ricardo Henrique Inácio

    Hello OTTVerse team, well I’m using FFMpeg to change the encode from h264 to h265 and works fine for most of files, but some files has the output file (h265) bigger than input file (h264), what is the reason for this to happen? I know that there is a process to transcode h264 to raw (or close) then encode to h265 (right?), so I imagine that the h265 output in this case has a much higher visual quality (bitrate, …) than the input h264 right? Is there a way to “level” the video quality of the h264 input file with the h265 output file so that the output file is not larger than the input file?

    I’m using FFMpeg like that:

    for %%a in (*.mkv, *.mp4) do (
    ffmpeg -i “%%a” -map 0 -c:a copy -c:s copy -c:v libx265 -vtag hvc1 -crf 18 -preset medium -tune animation “Out\%%~na.mkv”
    )

    Thanks!!

    1. Hi Ricardo, as you rightly pointed out, most of the HEVC files would be smaller than the AVC files. But, if you look at your commandline, you are using crf=18. This instructs FFmpeg to produce an extremely high quality video (because of CRF = 18) and not worry about the bitrate and filesize. For simple content (animation or cartoon), this can result in a file that is very large in size but also of extremely high quality.

      But, how do you quantify quality? What is “good enough”?

      At this stage, you should consider the concept of “Just Noticeable Differences”. When do your eyes realize that there has been a change in the encoder settings? For example: if you encode with CRF = 18 and CRF = 19, do you see the difference with your eyes? If not, then you should use CRF = 19 and enjoy a smaller file size.

      If you extend this concept, you should play around with CRF values till you reach a CRF value that provides a file with similar video quality as your AVC encode. There is a high possibility that this file will be smaller than your AVC encode, but will have the same video quality.

      Hope this helps! Happy to help further 🙂

  2. Pingback: Video Bitrate vs. Resolution For Video Streaming - OTTVerse

  3. Pingback: Easy Guide to HEVC Encoding using FFmpeg - CRF, CBR, 2-Pass, and More! - OTTVerse

Leave a Comment

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

Enjoying this article? Subscribe to OTTVerse and receive exclusive news and information from the OTT Industry.