Video into H.264

Problem

Transcode a video file by using the H.264 codec for dissemination purposes.

Solution

ffmpeg \
    -i input_file \
    -c:v libx264 \
    -preset veryslow \
    -qp 18 \
    -pix_fmt yuv420p \
    -c:a copy \
    output_file

Generic command

ffmpeg \
    -i input_file \
    -c:v libx264 \
    -preset preset_value \
    -qp quantisation_parameter \
    -pix_fmt yuv420p \
    -c:a copy \
    output_file

Command syntax

ffmpeg
starts the command
-i input_file
path, name and extension of the input file
-c:v libx264
The library libx264 re-encodes the video stream using the H.264 video codec.
-preset preset_value
A slower encoding preset means a better compression rate.
-qp quantisation_parameter
A quantisation parameter of 18 means a «visually lossless» compression.
-pix_fmt yuv420p
The pixel format for «YUV» colour space with 4:2:0 chroma subsampling and planar colour alignment is chosen for best compatibility.
-c:a copy
re-encodes the audio stream using the same audio codec
output_file
path, name and extension of the output file

Discussion

The video codec is specified by -codec:video, which may be abbreviated as -c:v (or -codec:v or -c:video). We advise to avoid the alias -vcodec.

Possible -preset values for the H.264 codec include:

  • veryslow
  • slow
  • medium
  • fast
  • veryfast

Slower encoding means better compression rate.

You can use the parameter -crf 18 (constant rate factor) instead of -qp 18 (quantisation parameter) which gives a similar «visually lossless» result. The range of the quantiser scale for crf and qp is from 0 to 51, where 0 is lossless, approximately 18 is «visually lossless», 23 is the default value and 51 is worst possible. Most of the non-FFmpeg-based players cannot decode H.264 files having lossless content.

By default the library libx264 will use the chroma subsampling scheme that matches closest the input file’s chroma subsampling. This can result in the «YUV» colour space with 4:4:4 or 4:2:2 or 4:2:0 chroma subsampling. Many of the non-FFmpeg-based players cannot decode H.264 files having a different chroma subsampling than 4:2:0. Therefore, in order to allow possibly all players to read the file, we suggest use to the yuv420p pixel format for dissemination purposes. And, as usual in the computer world, «YUV» stands for the colour space Y′CBCR, not for Y′UV as used by PAL video.

The audio codec is specified by -codec:audio, which may be abbreviated as -c:a (or -codec:a or -c:audio). We advise to avoid the alias -acodec. For silent videos you can replace -c:a copy by -an, for video with sound you may choose another audio codec.

Often the MP4 container is choses for wrapping H.264, but others are possible. If the MP4 container is chosen, then the audio codec must be Advanced Audio Coding (-c:a aac).

For advanced users

yuv420p is an 8-bit pixel format, which is common among distributors. For a bit depth of 10, which is common in video post-production, the pixel format yuv420p10le may be used, yet the library libx264 must be compiled in 10-bit mode for this. By the way, in this case the range of the quantiser scale for -crf and -qp is from 0 to 63.

If ffmpeg is linked to libx264 dynamically rather than statically, then it will adapt automatically to the bit depth supported by the run-time libx264, regardless of the version used at build time. This way it’s possible to work either 8-bit or 10-bit in each ffmpeg command; however you cannot combine 8-bit and 10-bit in the same command, you need two commands.


2018–07–21