FFmpeg and libav's playbook: Advanced encoding options with hardware-based acceleration, NVIDIA's NVENC and Intel's VAAPI-based encoder.
Hello guys,
Continuing from this guide to building ffmpeg and libav with NVENC and VAAPI enabled, this snippet will cover advanced options that you can use with ffmpeg and libav on both NVENC and VAAPI hardware-based encoders.
For ffmpeg:
As usual, we supply the usual arguments when we want to encode with VAAPi-based encoders:
ffmpeg -loglevel debug -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -i input_file -vf 'format=nv12,hwupload' -threads 8 -aspect 16:9 -y -f matroska -acodec copy -vcodec h264_vaapi -qp 19 -bf 2 "output_file"
For libav:
Libav takes its' arguments in a slightly different way. For both ffmpeg and libav, refer to this on what these arguments do. If you're already familiar with both pipelines, carry on.
avconv -v 55 -y -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -i "input_file" -c:a copy -vf 'format=nv12|vaapi,hwupload' -c:v h264_vaapi -bf 2 -b 12500k "output_file"
Trying two-pass with the h264_vaapi encoder:
ffmpeg -loglevel debug -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -i "input_file" -vf 'format=nv12,hwupload' -pass 1 -map 0:0 -map 0:1 -threads 8 -aspect 16:9 -y -f matroska -an -c:v h264_vaapi -b 7.5M "/dev/null"
ffmpeg -loglevel debug -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -i "input_file" -vf 'format=nv12,hwupload' -pass 2 -map 0:0 -map 0:1 -threads 8 -aspect 16:9 -y -f matroska -acodec copy -c:v h264_vaapi -b 7.5M "output_file"
And with NVENC:
NVENC's h264
and h265_nvenc
based encoders natively support two-pass encoding, and this should be pretty straight-forward:
ffmpeg -loglevel debug -hwaccel cuvid -i "input_file" -c:v h264_nvenc -preset llhq -profile:v high -rc ll_2pass_quality -an -b:v 2.4M -pass 1 -2pass -1 "output_file"
ffmpeg -loglevel debug -hwaccel cuvid -i "input_file" -c:v h264_nvenc -preset llhq -profile:v high -rc ll_2pass_quality -acodec copy -b:v 2.4M -pass 2 -2pass -1 -y "output_file"
Note the syntax order:
(a). The first will always be ffmpeg (the binary name in the system path or absolute path to ffmpeg depending on your deployment).
(b). The second should be an option passed directly to ffmpeg, such as a debug value (if needed).
(c). -i: Here is your input file's absolute path. If you are already in the path relative to the file's position, then use that relative path. The same applies to the output video too.
(d). -c:v : Use this to select the encoder. In the example above, we have selected h264_nvenc
.
(e). -preset: Some video and audio encoders will support the preset argument. In the case where both the video and the audio codec support the same argument, such as this, then wrap this argument with a declaration, as shown: -preset:v
would apply for the video encoder whereas -preset:a would apply for the audio encoder.
(f). Here, pass absolute options to the video encoder. In the example above, we are passing -rc
(the rate control factor) recognized by the h264_nvenc
encoder, and selecting the
low-latency, 2-pass quality rate control factor as we are doing a two-pass high quality encode. You will also notice that we have passed the -profile:v
option to the video encoder (h264_nvenc
) to select the high quality preset.
(g). -acodec: Use this to select the audio encoder to use. In our case, we are copying the audio as is and we don't re-encode.
(h). -b:v: This selects a video bitrate. In our example, we have selected a 2.4 MB/s variable bitrate by default, as the nvenc_h264
encoder uses variable rate encoding unless its' explicitly disabled (via the -cbr
option that enforces constant-rate encoding).
(i). -hwaccel: Here, you can select the hardware acceleration decode method you wish to use. If you compiled ffmpeg with NPP (Nvidia Performance Primitives) enabled under the NVIDIA Video SDK directive, you can select cuvid
here.
Optional arguments:
(a).-c:a copy copies the audio stream
(b).-f: Selects the container format to use. This can be MP4, Matroska, etc. Select whatever suits you, and take note of container restrictions.
Formats (muxers and demuxers):
List all supported formats in your ffmpeg build:
ffmpeg -formats
Display options specific to, and information about, a particular muxer:
ffmpeg -h muxer=matroska
Display options specific to, and information about, a particular demuxer:
ffmpeg -h demuxer=matroska
Codecs (encoders and decoders):
List all supported codecs in your ffmpeg build:
ffmpeg -codecs
List all supported encoders in your ffmpeg build:
ffmpeg -encoders
List all available decoders in your ffmpeg build:
ffmpeg -decoders
Display options specific to, and information about, a particular encoder:
ffmpeg -h encoder=mpeg4
Display options specific to, and information about, a particular decoder:
ffmpeg -h decoder=aac
Display information about all hardware acceleration(s) supported by your current ffmpeg build:
ffmpeg -hwaccels
Reading the results
There is a key near the top of the output that describes each letter that precedes the name of the format, encoder, decoder, or codec:
$ ffmpeg -encoders
[…]
Encoders:
V..... = Video
A..... = Audio
S..... = Subtitle
.F.... = Frame-level multithreading
..S... = Slice-level multithreading
...X.. = Codec is experimental
....B. = Supports draw_horiz_band
.....D = Supports direct rendering method 1
------
[…]
V.S... mpeg4 MPEG-4 part 2
In this example V.S... indicates that the encoder mpeg4 is a Video encoder and supports Slice-level multithreading.
Miscellaneous:
See advanced nvenc encoder options in ffmpeg:
ffmpeg -h encoder=nvenc_h264
Encoder nvenc_h264 [NVIDIA NVENC H.264 encoder]:
General capabilities: delay
Threading capabilities: none
Supported pixel formats: yuv420p nv12 yuv444p
nvenc_h264 AVOptions:
-preset <int> E..V.... Set the encoding preset (from 0 to 11) (default medium)
default E..V....
slow E..V.... hq 2 passes
medium E..V.... hq 1 pass
fast E..V.... hp 1 pass
hp E..V....
hq E..V....
bd E..V....
ll E..V.... low latency
llhq E..V.... low latency hq
llhp E..V.... low latency hp
lossless E..V....
losslesshp E..V....
-profile <int> E..V.... Set the encoding profile (from 0 to 3) (default main)
baseline E..V....
main E..V....
high E..V....
high444p E..V....
-level <int> E..V.... Set the encoding level restriction (from 0 to 51) (default auto)
auto E..V....
1 E..V....
1.0 E..V....
1b E..V....
1.0b E..V....
1.1 E..V....
1.2 E..V....
1.3 E..V....
2 E..V....
2.0 E..V....
2.1 E..V....
2.2 E..V....
3 E..V....
3.0 E..V....
3.1 E..V....
3.2 E..V....
4 E..V....
4.0 E..V....
4.1 E..V....
4.2 E..V....
5 E..V....
5.0 E..V....
5.1 E..V....
-rc <int> E..V.... Override the preset rate-control (from -1 to INT_MAX) (default -1)
constqp E..V.... Constant QP mode
vbr E..V.... Variable bitrate mode
cbr E..V.... Constant bitrate mode
vbr_minqp E..V.... Variable bitrate mode with MinQP
ll_2pass_quality E..V.... Multi-pass optimized for image quality (only for low-latency presets)
ll_2pass_size E..V.... Multi-pass optimized for constant frame size (only for low-latency presets)
vbr_2pass E..V.... Multi-pass variable bitrate mode
-surfaces <int> E..V.... Number of concurrent surfaces (from 0 to INT_MAX) (default 32)
-cbr <boolean> E..V.... Use cbr encoding mode (default false)
-2pass <boolean> E..V.... Use 2pass encoding mode (default auto)
-gpu <int> E..V.... Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from -2 to INT_MAX) (default any)
any E..V.... Pick the first device available
list E..V.... List the available devices
-delay <int> E..V.... Delay frame output by the given amount of frames (from 0 to INT_MAX) (default INT_MAX)
See advanced h264_vaapi options:
ffmpeg -h encoder=h264_vaapi
Encoder h264_vaapi [H.264/AVC (VAAPI)]:
General capabilities: delay
Threading capabilities: none
Supported pixel formats: vaapi_vld
h264_vaapi AVOptions:
-qp <int> E..V.... Constant QP (for P-frames; scaled by qfactor/qoffset for I/B) (from 0 to 52) (default 20)
-quality <int> E..V.... Set encode quality (trades off against speed, higher is faster) (from 0 to 8) (default 0)
-low_power <int> E..V.... Use low-power encoding mode (experimental: only supported on some platforms, does not support all features) (from 0 to 1) (default 0)
Thx a lot, what is difference btw cuda and cuvid encoders?