H264
Table of contents
This is the workhorse encoder for web review, its well supported by ffmpeg, and there is a lot of support for both encoding and decoding in hardware.
There are several h264 encoders available:
- x264 - the videolan h264 open source library.
- h264_nvenc - the nvidia hardware encoder.
- videotoolbox_h264 - MacOS only apple h264 encoder.
x264
x264 is a library developed by the videolan association. It has a GPL license.
Supported pixel formats: yuv420p yuvj420p yuv422p yuvj422p yuv444p yuvj444p nv12 nv16 nv21 yuv420p10le yuv422p10le yuv444p10le nv20le gray gray10le
Note, most web browsers only support yuv420p apart from chrome.
Key flags (see https://trac.ffmpeg.org/wiki/Encode/H.264 )
Example encoding:
ffmpeg -r 24 -start_number 100 -i inputfile.%04d.png -frames:v 200 -c:v libx264 \
-pix_fmt yuv420p10le -crf 18 -preset slow \
-sws_flags spline+accurate_rnd+full_chroma_int \
-vf "scale=in_range=full:in_color_matrix=bt709:out_range=tv:out_color_matrix=bt709" \
-color_range tv -colorspace bt709 -color_primaries bt709 -color_trc iec61966-2-1 \
-movflags faststart -y outputfile.mp4
| Flag | Description |
|---|---|
| -crf 18 | This is the constant rate factor, controlling the default quality (see: https://slhck.info/video/2017/02/24/crf-guide.html ) where -crf 0 is uncompressed. By default this is set to 23, which is a little on the low quality side; using values closer to 18 is recommended, but this does come at the expense of file-size. For more on this see the CRF comparison below. |
| -qp 23 | Quantization Parameter - it is recommended that you do not use this, in preference to -crf above (see: https://slhck.info/video/2017/03/01/rate-control.html ) |
| -preset slow | https://trac.ffmpeg.org/wiki/Encode/H.264#FAQ |
| -qscale:v 9 | Generic quality scale flag: https://www.ffmpeg.org/ffmpeg.html#toc-Main-options. This is typically used for fixed-quality encoding in some codecs, but CRF is preferred for H.264. |
| -tune film | See below. |
| -movflags faststart | This re-organizes the mp4 file, so that it doesn’t have to read the whole file to start playback, useful for streaming. It can add a second or so to do this, since it does require re-writing the file. |
Tune Parameter
Optionally use the tune option to change settings based on specific inputs - https://trac.ffmpeg.org/wiki/Encode/H.264#FAQ
| Tuning | Description |
|---|---|
| -tune film | Good for live action content. |
| -tune animation | Good for animated content with areas of flat colors. |
| -tune grain | Good for live action content where you want to preserve the grain as much as possible. |
see also: https://superuser.com/questions/564402/explanation-of-x264-tune
CRF Comparison
To help pick appropriate values with the CRF flag, we have run the Test Framework through some of the reference media.
This is showing CRF values against encoding time. |
This is showing CRF values against file size. |
This is showing CRF values against VMAF harmonic mean |
libx264 preset comparisons
Below is showing a comparison of different preset values with a crf value of 18. Its showing that you really can just encode with -preset medium or -preset slow anything higher is really not gaining you anything.
This is showing preset values against encoding time. |
This is showing preset values against file size. Seeing very little variation in file size for the different presets. |
This is showing preset values against VMAF harmonic mean (quality). |
H264 Bitdepth
By default, h264 is created as a yuv420p file format. This is the recommended format for web playback and also playback with the quicktime player on MacOS and other apple devices, but the h264 codec can support other formats that are modified with the -pix_fmt flag.
Setting -pix_fmt to 10-bit or high-chroma formats usually auto-selects the appropriate H.264 profile. However, explicitly setting -profile:v is recommended for ensuring compatibility with specific hardware decoders.
| Pixel Format | Recommended Profile | Supported Features |
|---|---|---|
| yuv420p10le | high10 | 10-bit color, 4:2:0 subsampling. |
| yuv422p10le | high422 | 10-bit color, 4:2:2 subsampling. |
| yuv444p10le | high444 | 10-bit color, 4:4:4 subsampling. |
Hardware Acceleration
macOS VideoToolbox
Uses the Apple hardware encoder. Ideal for fast proxies and web review on Apple Silicon.
ffmpeg -i input.mov -c:v h264_videotoolbox -profile:v high -pix_fmt yuv420p -b:v 10M output.mp4
NVIDIA NVENC
Uses NVIDIA’s dedicated hardware encoder (available on Windows/Linux).
ffmpeg -i input.mov -c:v h264_nvenc -preset slow -rc vbr -cq 19 -pix_fmt yuv420p output.mp4
Lossless Encoding
To achieve mathematically lossless encoding with libx264, use -crf 0 or -qp 0. Note that lossless files can be extremely large and may not play back in standard web browsers.
ffmpeg -i input.exr -c:v libx264 -crf 0 -pix_fmt yuv444p output_lossless.mp4
This is showing CRF values against encoding time.
This is showing CRF values against file size.
This is showing CRF values against VMAF harmonic mean
This is showing preset values against encoding time.
This is showing preset values against file size. Seeing very little variation in file size for the different presets.
This is showing preset values against VMAF harmonic mean (quality).