Easy Guide to HEVC Encoding using FFmpeg – CRF, CBR, 2-Pass, and More!

encoding hevc using ffmpeg

If you want to compress your videos with high compression efficiency and high video quality, then HEVC encoding using FFMpeg is the way to go.

HEVC (High-Efficiency Video Coding), or H.265 is a video compression standard that was developed to address the limitations of its predecessor, H.264/AVC. It uses more advanced coding techniques (compared to H.264) to achieve higher compression efficiency. It can encode a video with the same quality as H.264 but at a much lower bitrate.

To understand the power of HEVC, read this article that compares the compression efficiency of HEVC vs. H.264/AVC – you can see that a 35-50% savings on bitrate is possible by switching to HEVC. Predictions by experts in transcoding also point towards a gradual move towards the HEVC codec in the years to come. 

HEVC achieves this high quality at lower bitrates by using larger blocks for motion compensation, quadtree decomposition, better prediction techniques, and more flexible coding tools such as the DST (Discrete Sine Transform), SAO, and others.

HEVC is widely used in applications requiring high-quality video at lower bitrates, such as streaming, video conferencing, and broadcasting. However, HEVC encoding & decoding requires more processing power than its predecessor and may not be supported by older devices or software.

In this article, we will explore encoding using HEVC and FFmpeg. To learn more about FFmpeg, please check out OTTVerse’s comprehensive FFmpeg tutorials. Additionally, you might find FFprobe very useful for examining your encodes and getting metadata – learn how to use FFprobe here.

Note:

  1. Click here to learn more about video encoding.
  2. Click here if you are looking for an SVT-AV1 analysis.

System Parameters and Test Sequences 

  • I ran these tests using FFmpeg 6.0 on an M1 MacBook Pro (M1 Pro Chip with 8 cores, 16 GB RAM, and 512 GB SSD).
  • The test sequence I used is a 1080p version of the Big Buck Bunny downloadable from here (https://test-videos.co.uk/bigbuckbunny/mp4-h264). 
  • I use the benchmark parameter in FFmpeg in all my command lines. It shows the real, system, and user time used; and the encoding speed (in fps).

HEVC Encoding using FFmpeg – the Basic Commands

Let’s start with a simple example and build up from there. You need to use the implementation to use FFmpeg to transcode videos using the HEVC codec. To access all the parameters available in the x265 library, please read the official docs.

Let’s start this quick tutorial by trying out a simple FFmpeg command line and encoding a video using HEVC. 

./ffmpeg -i input_file -c:v libx265 -preset [preset] -crf [crf] -x265-params [params] -c:a copy output_file

Here’s what each parameter does:

  • -i input_file: Specifies the input video file.
  • -c:v libx265: Specifies that the video codec for encoding is HEVC or H.265.
  • -preset [preset]: Specifies the preset for the HEVC encoder. The available presets are ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, and placebo. The slower the preset, the higher the compression and the better the quality.
  • -crf [crf]: Specifies the Constant Rate Factor (CRF) for the HEVC encoder. The CRF ranges from 0-51, with 0 being lossless and 51 being the worst quality possible. A lower CRF value will result in a higher quality and larger file size, while a higher CRF value will result in a lower quality and smaller file size. The default value is 28.
  • -x265-params [params]: Specifies additional HEVC encoder parameters. This can be used to fine-tune the encoding process.
  • -c:a copy: Specifies that the audio stream should be copied as-is without any re-encoding.
  • output_file: Specifies the output file name and location.

Using this command line and changing the parameters, you can produce HEVC encodes of varying quality and size. I repeat the following –

  • I ran these tests using FFmpeg 6.0 on an M1 MacBook Pro (M1 Pro Chip with 8 cores, 16 GB RAM, and 512 GB SSD).
  • The test sequence I used is a 1080p version of the Big Buck Bunny downloadable from here (https://test-videos.co.uk/bigbuckbunny/mp4-h264). 

Let’s try tests using a CRF value 20 and varying the presets. 

HEVC encoding with the “slow” preset and a CRF value of 20.

./ffmpeg -benchmark -i Big_Buck_Bunny_1080_10s_30MB.mp4 -c:v libx265 -preset slow -crf 20 -c:a copy output_slow_crf20.mp4

This produces a file that’s 12 MB in size and has a PSNR of 43.15 dB, taking 32.62s (9.20 fps).

HEVC encoding with the “medium” preset and a CRF value of 20.

./ffmpeg -benchmark -i Big_Buck_Bunny_1080_10s_30MB.mp4 -c:v libx265 -preset medium -crf 20 -c:a copy output_medium_crf20.mp4

This produces a file that’s 11 MB and has a PSNR of 42.20 dB, taking 12.93s (23.20 fps).

HEVC encoding with the “fast” preset and a CRF value 20.

./ffmpeg -benchmark -i Big_Buck_Bunny_1080_10s_30MB.mp4 -c:v libx265 -preset fast -crf 20 -c:a copy output_fast_crf20.mp4

This produces a file that’s 9.7 MB in size and has a PSNR of 41.53 dB, taking 11.93s (25.14 fps).

HEVC encoding with the “ultrafast” preset and a CRF value of 20.

./ffmpeg -benchmark -i Big_Buck_Bunny_1080_10s_30MB.mp4 -c:v libx265 -preset ultrafast -crf 20 -c:a copy output_ultrafast_crf20.mp4

This produces a file that’s 7.8 MB in size and has a PSNR of 38.68 dB, taking 4.23s (71.00 fps). 

As you can see, by changing the preset, you can alter the transcoding process by turning on & off coding tools. This results in a change in the transcoding speed, and, consequently, the quality and size of the video. 

PresetFilesize (MB)PSNR (dB) Time taken (sec) 
Slow1243.1532.62
Medium1142.2012.93
Fast9.741.5311.93
Ultrafast7.838.684.23
Table 1: Variation of Presets leading to variation in the file-size, PSNR, and the time taken to encode.

To understand what tools are enabled in each of the presets, please visit the table on this page.

HEVC (x265)’s Additional Parameters

x265 is a fabulous codec implementation with hundreds of parameters you can use to tune the performance of the codec – both in terms of video quality and performance. For the complete list of parameters, go here – you can use these parameters to control the SAO strength, quantization parameters, motion estimation (half-pel and quarter-pel), frame-level parallelism, and much more.

In this example, we run an encode using and set the quantization parameter (QP) to 23 and set the Adaptive Quantization (AQ) (aq-mode) to 2. In AQ, the QP of every block is varied in a tradeoff between quality and bitrate.

./ffmpeg -benchmark -i Big_Buck_Bunny_1080_10s_30MB.mp4 -c:v libx265 -preset medium -crf 23 -x265-params qp=22:aq-mode=2 -c:a copy output.mp4

In this example, we’re using the medium preset with a CRF of 23, and adding the qp and aq-mode parameters to further fine-tune the encoding process.

CBR Encoding using HEVC and FFmpeg

We used FFmpeg’s CRF mode to encode the videos in all the examples. In this example, let’s use the CBR encoding mode. If you are new to encoding, learn more about CBR, CRF, and VBR here.

Related:  What is Video Transcoding and Why is it Critical to Video Streaming

To encode with FFmpeg and HEVC using Constant Bitrate (CBR) mode, you can use the following command:

./ffmpeg -benchmark -i input.mp4 -c:v libx265 -b:v [bitrate] -minrate [bitrate] -maxrate [bitrate] -bufsize [buffer size] -preset medium -c:a copy output.mp4

Here’s a breakdown of the command:

  • -i input.mp4: Specifies the input video file.
  • -c:v libx265: Specifies the video codec to be used for encoding is HEVC or H.265.
  • -b:v [bitrate]: Specifies the bitrate for the video stream. The bitrate is specified in bits per second (bps). This value will be the same throughout the video.
  • -minrate [bitrate]: Specifies the minimum bitrate for the video stream. This value is used to control the quality of the video in sections with complex content.
  • -maxrate [bitrate]: Specifies the maximum bitrate for the video stream. This value is used to control the quality of the video in sections with simple content.
  • -bufsize [buffer size]: Specifies the size of the buffer used to store the video data. This value is used to control the amount of data that can be stored in the buffer before it is written to the output file.
  • -preset medium: Specifies the medium preset for the HEVC encoder. This preset provides a balance between file size and quality.
  • -c:a copy: Copies the audio stream as-is without re-encoding.
  • output.mp4: Specifies the output file name and location.

You should replace the [bitrate] and [buffer size] with the desired values.

For example, to encode a 1080p HEVC video with a CBR of 5 Mbps and a buffer size of 10 Mbps, you can use the following command:

ffmpeg -benchmark -i input.mp4 -c:v libx265 -b:v 5M -minrate 5M -maxrate 5M -bufsize 10M -preset medium -c:a copy output.mp4

This command will produce a 1080p HEVC-encoded video with a CBR of 5 Mbps and a buffer size of 10 Mbps, while keeping the audio stream unchanged. Note that using CBR can result in a larger file size than CRF, but it provides more consistent quality throughout the video.

Here is an interesting article on CBR vs. VBR if you want to learn more.

2-Pass Encoding using HEVC and FFmpeg

It is very straightforward to do 2-pass encoding using HEVC and FFmpeg. While running a 2-pass encode, FFmpeg will analyze the video stream in the first pass to determine the optimal bitrate and other encoding parameters for the second pass. This can improve compression efficiency and quality compared to a single-pass encoding process.

Word of caution: A 2-pass encode can result in better compression efficiency and quality than a single-pass encode, but, it may be excessive in some situations – i.e., not a lot of quality improvement despite spending a lot of time and resources. This is easily observable in simple cartoon content with piecewise-linear regions (e.g., Simpsons).

Okay – let’s get coding. Here are the steps to perform 2-pass encoding using HEVC and FFmpeg:

First Pass

First, run the first pass of the encoding process using the following command

./ffmpeg -benchmark -y -i input.mp4 -c:v libx265 -preset [preset] -b:v [bitrate] -pass 1 -f mp4 /dev/null

In this command,

  • -y is used to overwrite the output file if it already exists.
  • -i input.mp4 specifies the input H.264 video file. -c:v libx265 specifies the HEVC codec to be used for encoding.
  • -b:v [bitrate] sets the target bitrate for the video stream.
  • The value of [bitrate] is in bits per second (bps).
  • -pass 1 specifies that this is the first pass of the two-pass encoding process. Finally, /dev/null is used as the output file, as the actual output file is not generated in the first pass.

Second Pass

After the first pass is complete, run the second pass of the encoding process using the following command:

./ffmpeg -benchmark -i input.mp4 -c:v libx265 -preset [preset] -b:v [bitrate] -pass 2 -c:a copy output.mp4

In this command, the

  • -i input.mp4 option specifies the input H.264 video file.
  • -c:v libx265 specifies the HEVC codec to be used for encoding.
  • -b:v [bitrate] sets the target bitrate for the video stream. The value of [bitrate] should be the same as in the first pass.
  • -pass 2 specifies that this is the second pass of the two-pass encoding process.
  • Finally, -c:a copy is used to copy the audio stream from the input file without any re-encoding.
  • The output video file is specified with the extension .mp4.

Converting from HEVC to H.264/AVC using FFmpeg

Finally, let’s end this tutorial with the opposite and convert HEVC to H.264/AVC using FFmpeg! Again, it’s very simple and can be done with a simple commandline.

./ffmpeg -benchmark -i input.hevc -c:v libx264 -preset [preset] -crf [crf] -c:a copy output.mp4

Here’s what each parameter does:

  • -i input.hevc: Specifies the input HEVC-encoded file.
  • -c:v libx264: Specifies the video codec to be used for encoding is H.264.
  • -crf [crf]: Specifies the Constant Rate Factor (CRF) for the H.264 encoder. The CRF ranges from 0-51, with 0 being lossless and 51 being the worst quality possible. A lower CRF value will result in a higher quality and larger file size, while a higher CRF value will result in a lower quality and smaller file size.
  • -c:a copy: Specifies that the audio stream should be copied as-is without any re-encoding.
  • output.mp4: Specifies the output file name and location.

Change 1080p video to 720p video using FFmpeg and HEVC

To convert a 1080p video to a 720p video using FFmpeg and HEVC, you can use the following command:

./ffmpeg -benchmark -i Big_Buck_Bunny_1080_10s_30MB.mp4 -c:v libx265 -preset medium -crf 23 -vf scale=1280x720 -c:a copy output_1080_to_720.mp4

Here’s a breakdown of the command:

  • -i input.mp4: Specifies the input video file.
  • -c:v libx265: Specifies the video codec to be used for encoding is HEVC or H.265.
  • -preset medium: Specifies the medium preset for the HEVC encoder. This preset provides a balance between file size and quality.
  • -crf 23: Specifies the Constant Rate Factor (CRF) for the HEVC encoder. The lower the CRF value, the higher the quality and larger the file size.
  • -vf scale=1280×720: Rescales the video to 720p by specifying the new resolution of 1280×720 using the scale filter.
  • -c:a copy: Copies the audio stream as-is without re-encoding.
  • output.mp4: Specifies the output file name and location.

This command will produce a 720p HEVC-encoded video with a medium preset and a CRF of 23, while keeping the audio stream unchanged.

Conclusion

That’s it – we’ve concluded our article on encoding basics using HEVC and FFmpeg. I hope you found it helpful and will be able to use some of the ideas and command lines in your workflow. In future articles, we shall explore HDR encoding using FFmpeg.

Stay tuned!

Until next time, happy streaming!

krishna rao vijayanagar
Krishna Rao Vijayanagar

Krishna Rao Vijayanagar, Ph.D., is the Editor-in-Chief of OTTVerse, a news portal covering tech and business news in the OTT industry.

With extensive experience in video encoding, streaming, analytics, monetization, end-to-end streaming, and more, Krishna has held multiple leadership roles in R&D, Engineering, and Product at companies such as Harmonic Inc., MediaMelon, and Airtel Digital. Krishna has published numerous articles and research papers and speaks at industry events to share his insights and perspectives on the fundamentals and the future of OTT streaming.

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.