Skip to content

Vulkan Video

current

Vulkan Video exposes the fixed-function video engines of a GPU through the cross-vendor Vulkan API instead of a vendor API like NVENC, AMF or VAAPI. FFmpeg has h264_vulkan and hevc_vulkan (added in FFmpeg 7.1) and av1_vulkan (added in 8.0). The same engine is used underneath, so the quality is that of the GPU’s hardware encoder, not something new.

It is the newest and least settled hardware path. Driver support is uneven and still changing, there are fewer tuning options than in the vendor APIs, and for most people the vendor encoder on the same GPU is the better choice. It is interesting mainly where a driver offers Vulkan Video but no other encode API, or when you want the encode on the same Vulkan device as your filters (scale_vulkan, libplacebo).

The usual hardware trade-off applies: fast and efficient, but worse than x264, x265 or SVT-AV1 at slow presets in quality per bit. See NVENC: hardware or software.

The device must expose the encode extensions: VK_KHR_video_encode_queue plus VK_KHR_video_encode_h264, _h265 or _av1.

Terminal window
vulkaninfo | grep -i video_encode

FFmpeg fails at start-up with “Device does not support the VK_KHR_video_encode_queue extension” when it is missing. A Vulkan graphics device or decode support does not imply encode support. At build time FFmpeg needs Vulkan headers 1.3.277 or newer, and 1.4.317 or newer for av1_vulkan.

FFmpeg 9 also has Vulkan compute encoders for ProRes (prores_ks_vulkan) and FFV1 (ffv1_vulkan). Those run on shaders and have nothing to do with the video engine.

Terminal window
ffmpeg -init_hw_device vulkan=vk -filter_hw_device vk -i input.mkv -vf 'format=nv12,hwupload' -c:v hevc_vulkan -qp 26 -c:a copy output.mkv

-qp N (or -global_quality N) selects constant-quantizer mode, the only quality-targeted mode here. The option accepts 0–255, but H.264 and HEVC quantizers stop at 51, while AV1’s go to 255 and need values several times higher for similar quality:

Terminal window
ffmpeg -init_hw_device vulkan=vk -filter_hw_device vk -i input.mkv -vf 'format=nv12,hwupload' -c:v av1_vulkan -qp 100 -c:a copy output.mkv

For a size target give -b:v 6M -maxrate 9M; FFmpeg picks VBR if the driver has it, otherwise CBR (force either with -rc_mode vbr or -rc_mode cbr). With no rate options at all, FFmpeg falls back to a fixed QP of 18 for every codec, which for AV1 means very large files. -tune hq and -usage transcode are hints that suit offline encodes, and -quality N picks a slower, higher-quality driver preset where the driver offers more than one level.

Terminal window
ffmpeg -hwaccel vulkan -hwaccel_output_format vulkan -i input.mkv -vf scale_vulkan=w=1920:h=1080 -c:v hevc_vulkan -qp 26 output.mkv

Vulkan decode covers H.264, HEVC, AV1 and VP9 in FFmpeg. As elsewhere, a filter without a Vulkan version forces hwdownload,format=nv12.

OptionWhat it does
-rc_modeauto (CQP if a QP is set, VBR or CBR if a bitrate is), driver, cqp, cbr, vbr. FFmpeg errors out if the driver lacks the requested mode.
-qpQuantizer for cqp.
-qualityDriver-defined quality level, higher is slower. The effective range comes from the device.
-tunedefault, hq, ll, ull, lossless. A hint; drivers may ignore it.
-usage, -contentHints: transcode, stream, record, conference and camera, desktop, rendered.
-b_depth, -bfB-frame structure. Defaults 1 and 2.
-g, -idr_intervalGOP length (default 300) and IDR spacing in I-frames.
-async_depthFrames in flight.
-profile, -level, -tierAV1: main, high, professional; level names are the AV1 level numbers (40, 51).
  • Vulkan device selection matters when a machine has both hardware and software (llvmpipe) Vulkan devices. Pick the GPU with vulkan=vk:N.
  • Frames need to be in Vulkan memory; hwupload with -filter_hw_device handles that for software-decoded input.
  • The AV1 wrapper’s numeric level IDs are sequence-level indices, not Android’s flags or NVENC’s numbers. Use the names.

Every private option of av1_vulkan in FFmpeg 9.0.2; h264_vulkan and hevc_vulkan share the GOP, rate-control, quality and hint options. INT_MAX is 2147483647; rc_mode auto is stored as UINT32_MAX (4294967295).

ParameterTypeDefaultMeaningRange / named values
-idr_intervalint0Number of non-key I-frames between key frames; 0 makes every I-frame a key frame.0 to INT_MAX
-b_depthint1B-frame reference depth: 1 = flat B-frames, higher builds a hierarchy. Needs -bf.1 to INT_MAX
-async_depthint2Frames in flight on the GPU; raise it for single-stream throughput.1 to 64
-qpint-1Constant QP for all frames (selects cqp).-1 to 255
-qualityint0Driver quality level, from 0 to the driver maximum; higher is slower. Out-of-range values are rejected.0 to INT_MAX
-rc_modeintautoRate control: driver, cqp, cbr, vbr. auto uses CQP with -qp/-global_quality, VBR (or CBR) with -b:v, and otherwise CQP at QP 18.0 to UINT32_MAX; auto=4294967295, driver=0, cqp=1, cbr=2, vbr=4
-tuneintdefaultTuning hint: hq, ll, ull, lossless; default leaves it to the driver.0 to INT_MAX; default=0, hq=1, ll=2, ull=3, lossless=4
-usageflags0Usage hint (combinable): transcode, stream, record, conference.default, transcode, stream, record, conference
-contentflags0Content hint (combinable): camera, desktop, rendered.default, camera, desktop, rendered
-profileint-99AV1 profile: main, high, professional. -99 chooses from the input format.-99 to 65535; main=0, high=1, professional=2
-tierintmainAV1 tier: main or high.0 to 1; main=0, high=1
-levelint-99AV1 level; -99 chooses automatically.-99 to 255; 20=0, 21=1, 22=2, 23=3, 30=4, 31=5, 32=6, 33=7, 40=8, 41=9, 42=10, 43=11, 50=12, 51=13, 52=14, 53=15, 60=16, 61=17, 62=18, 63=19, 70=20, 71=21, 72=22, 73=23
-unitsflagshdrMetadata to write: hdr writes mastering-display and content-light-level metadata from the input.hdr

Codec-specific generic initialization overrides

Section titled “Codec-specific generic initialization overrides”

The wrapper replaces these generic FFmpeg defaults for this encoder. -b is in bits/s; -g and -bf count frames. -1, and 0 for -b and -refs, leave the value to the preset, driver or rate-control logic.

Generic parameterDefault
-b0
-bf2
-g300
-qmin1
-qmax255
-refs0