|Version 42 (modified by 8 years ago) ( diff ),|
FFmpeg and x264 Encoding Guide
x264 is a H.264/MPEG-4 AVC encoder. The goal of this guide is to inform new users how to create a high-quality H.264 video.
There are two rate control modes that are usually suggested for general use: Constant Rate Factor (CRF) or Two-Pass ABR. The rate control is a method that will decide how many bits will be used for each frame. This will determine the file size and also how quality is distributed.
If you need help compiling and installing libx264 see one of our FFmpeg and x264 compiling guides.
Constant Rate Factor (CRF)
This method allows the encoder to attempt to achieve a certain output quality for the whole file when output file size is of less importance. This provides maximum compression efficiency with a single pass. Each frame gets the bitrate it needs to keep the requested quality level. The downside is that you can't tell it to get a specific filesize or not go over a specific size or bitrate.
1. Choose a CRF value
The range of the quantizer scale is 0-51; where 0 is lossless, 23 is default, and 51 is worst possible. A lower value is a higher quality and a subjectively sane range is 18-28. Consider 18 to be visually lossless: it should look the same or nearly the same as the input but it isn't technically lossless.
Increasing the CRF value +6 is roughly half the bitrate while -6 is roughly twice the bitrate. General usage is to choose the highest CRF value that still provides an acceptable quality. If the output looks good, then try a higher value and if it looks bad then choose a lower value.
Note: The CRF quantizer scale mentioned on this page only applies to 8-bit x264 (10-bit x264 quantizer scale is 0-63). You can see what you are using with
x264 --helplisted under
Output bit depth. 8-bit is more common amongst distributors.
2. Choose a preset
A preset is a collection of options that will provide a certain encoding speed to compression ratio. A slower preset will provide better compression (compression is quality per filesize). This means that, for example, if you target a certain file size or constant bit rate, you will achieve better quality with a slower preset. Similarly, for constant quality encoding, you will simply save bitrate by choosing a slower preset.
The general guideline is to use the slowest preset that you have patience for. Current presets in descending order of speed are:
placebo. The default preset is
placebo as it is not useful (see FAQ). You can see a list of current presets with
-preset help, and what settings they apply with
You can optionally use
-tune to change settings based upon the specifics of your input. Current tunings include:
zerolatency. For example, if your input is animation then use the
animation tuning, or if you want to preserve grain then use the
grain tuning. If you are unsure of what to use or your input does not match any of tunings then omit the
-tune option. You can see a list of current tunings with
-tune help, and what settings they apply with
Another optional setting is
-profile:v which will limit the output to a specific H.264 profile. This can generally be omitted unless the target device only supports a certain profile (see Compatibility). Current profiles include:
high444. Note that usage of
-profile:v is incompatible with lossless encoding.
As a shortcut, you can also list all possible internal presets/tunes for FFmpeg by specifying no preset or tune option at all:
ffmpeg -i input -c:v libx264 -preset -tune dummy.mp4
3. Use your settings
Once you've chosen your settings, apply them for the rest of your videos if you are encoding more. This will ensure that they will all have similar quality.
The following example will encode a video with x264, using a slower than normal preset, with a slightly better quality than the default (23).
ffmpeg -i input -c:v libx264 -preset slow -crf 22 -c:a copy output.mkv
Note that in this example, the audio stream of the input file is simply copied over to the output and not re-encoded.
This method is generally used if you are targeting a specific output file size and output quality from frame to frame is of less importance. This is best explained with an example. Your video is 10 minutes (600 seconds) long and an output of 50 MB is desired. Since
bitrate = file size / duration:
(50 MB * 8192 [converts MB to kilobits]) / 600 seconds = ~683 kilobits/s total bitrate 683k - 128k (desired audio bitrate) = 555k video bitrate
ffmpeg -y -i input -c:v libx264 -preset medium -b:v 555k -pass 1 -an -f mp4 /dev/null && \ ffmpeg -i input -c:v libx264 -preset medium -b:v 555k -pass 2 -c:a libfdk_aac -b:a 128k output.mp4
Note: Windows users should use
As with CRF, choose the slowest preset you can tolerate.
Also see Making a high quality MPEG-4 ("DivX") rip of a DVD movie. It is an MEncoder guide, but it will give you an insight about how important it is to use two-pass when you want to efficiently use every bit when you're constrained with storage space.
You can use
-qp 0 or
-crf 0 to encode a lossless output. Use of
-qp is recommended over
-crf for lossless because 8-bit and 10-bit x264 use different
-crf values for lossless. Two useful presets for this are
veryslow since either a fast encoding speed or best compression are usually the most important factors. Most non-FFmpeg based players will not be able to decode lossless, so if compatibility is an issue you should not use lossless.
Lossless Example (fastest encoding)
ffmpeg -i input -c:v libx264 -preset ultrafast -qp 0 output.mkv
Lossless Example (best compression)
ffmpeg -i input -c:v libx264 -preset veryslow -qp 0 output.mkv
Overwriting default preset settings
You can overwrite default preset settings with the
x264opts option or by using the libx264 private options (see
libx264 AVOptions in
ffmpeg -h full). This is not recommended unless you know what you are doing. The presets were created by the x264 developers and tweaking values to get a better output is usually a waste of time.
ffmpeg -i input -c:v libx264 -preset slow -crf 22 -x264opts keyint=123:min-keyint=20 -c:a copy output.mkv
Additional Information & Tips
ABR (Average Bit Rate)
ffmpeg -i input -c:v libx264 -b:v 1000k ...
This provides something of a "running average" target, with the end goal that the final file match this number "overall on average" (so basically, if it gets a lot of black frames, which cost very little, it will encode them with less than the requested bitrate, but then the next few seconds of (non-black) frames it will encode at very high quality, to bring the average back in line). Using 2-pass can help this method to be more effective. You can also use this in combination with a "max bit rate" setting in order to prevent some of the swings.
CBR (Constant Bit Rate)
There is no native CBR mode, but you can "simulate" a constant bit rate setting by tuning the parameters of ABR, like
ffmpeg -i input -c:v libx264 -b:v 4000k -minrate 4000k -maxrate 4000k -bufsize 1835k out.m2v
in this example,
-bufsize is the "rate control buffer" so it will enforce your requested "average" (4000k in this case) across each 1835k worth of video. So basically it is assumed that the receiver/end player will buffer that much data so it's ok to fluctuate within that much.
Of course, if it's all just empty/black frames then it will still serve less than that many bits/s (but it will raise the quality level as much as it can, up to the crf level).
CRF with maximum bit rate
You can also also use a crf with a maximum bit rate by specifying both crf *and* maxrate settings, like
ffmpeg -i input -c:v libx264 -crf 20 -maxrate 400k -bufsize 1835k
This will effectively "target" crf 20, but if the output exceeds 400kb/s, it will degrade to something less than crf 20 in that case.
libx264 offers a
-tune zerolatency option. See the StreamingGuide.
If you want your videos to have highest compatibility with target players (for instance, with older iOS versions or all Android devices) then you'll want to specify
which disables some advanced features but provides for better compatibility. Typically you may not need this setting. Also if you do use this setting, it increases the bit rate quite a bit, compared to what's needed to achieve the same quality in higher profiles.
For a list of supported profiles and their description, run
Keep in mind that Apple Quicktime only supports YUV 420 color space for x264 encoded movies, and does not support anything higher than the "main" profile. This leaves only 2 options for quicktime compatible clips: baseline and main. All of the other profiles are currently not supported with Quicktime, although they will play back in pretty much any other player.
Pre-testing your settings
Encode a random section instead of the whole video with the
-t options to quickly get a general idea of what the output will look like.
-ss: Offset time from beginning. Value can be in seconds or HH:MM:SS format.
-t: Output duration. Value can be in seconds or HH:MM:SS format.
Will two-pass provide a better quality than CRF?
No, though it does allow you to target a file size more accurately.
placebo a waste of time?
It helps at most ~1% compared to the
veryslow preset at the cost of a much higher encoding time. It's diminishing returns:
veryslow helps about 3% compared to the
slower helps about 5% compared to the
slow preset, and
slow helps about 5-10% compared to the
Why doesn't my lossless output look lossless?
Blame the rgb->yuv conversion. If you convert to yuv444, it should still be lossless (which is the default now).
Will a graphics card make x264 encode faster?
No. libx264 doesn't use them (at least not yet). There are some proprietary encoders that utilize the GPU, but that does not mean they are well optimized, though encoding time may be faster; and they might be worse than x264 anyway, and possibly slower. Regardless, FFmpeg today doesn't support any means of gpu encoding, outside of libx264.
Encoding for QuickTime Player
You will need to use
-pix_fmt yuv420p for your output to work in QT Player. This is because Apple Quicktime only supports YUV 420 color space for H.264 encoded clips. Otherwise, depending on your source, ffmpeg may output to a pixel format that may be incompatible with QT and other players that are not based on FFmpeg.