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](https://gist.github.com/Brainiarc7/95c9338a737aa36d9bb2931bed379219), 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](https://gist.github.com/Brainiarc7/95c9338a737aa36d9bb2931bed379219) 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](https://gist.github.com/Brainiarc7/988473b79fd5c8f0db54b92ebb47387a) 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 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 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 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 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 E..V.... Number of concurrent surfaces (from 0 to INT_MAX) (default 32) -cbr E..V.... Use cbr encoding mode (default false) -2pass E..V.... Use 2pass encoding mode (default auto) -gpu 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 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 E..V.... Constant QP (for P-frames; scaled by qfactor/qoffset for I/B) (from 0 to 52) (default 20) -quality E..V.... Set encode quality (trades off against speed, higher is faster) (from 0 to 8) (default 0) -low_power E..V.... Use low-power encoding mode (experimental: only supported on some platforms, does not support all features) (from 0 to 1) (default 0)