DEV Community

Mason K
Mason K

Posted on

Probing FFmpeg's av1_vulkan encoder: does your GPU actually support it?

TL;DR

FFmpeg 8.x includes av1_vulkan, the first cross-vendor GPU AV1 encoder in mainline FFmpeg. We'll probe whether your GPU + driver actually expose AV1 encode, run a first working encode, benchmark it against SVT-AV1 on your own content, and talk about which jobs deserve it.

📦 Code: github.com/USER/repo (replace before publishing)

Until FFmpeg 8.0 ("Huffman", released August 2025), GPU AV1 encoding meant picking a vendor: av1_nvenc for NVIDIA RTX 40+, av1_amf for AMD, av1_qsv for Intel Arc. Three code paths, three sets of flags, three driver stacks. The Vulkan Video encode work gives FFmpeg one encoder that reaches all three vendors through the standard VK_KHR_video_encode_av1 extension.

The catch: driver support is a lottery. Plenty of capable hardware sits behind drivers that don't expose the encode extension yet. So before any pipeline decisions, we probe.

1. Check what you're running

You want FFmpeg 8.x (8.1.2 is current as of late June 2026) built with Vulkan support, plus the vulkaninfo tool from the Vulkan SDK / vulkan-tools package.

$ ffmpeg -version | head -1
ffmpeg version 8.1.2 Copyright (c) 2000-2026 the FFmpeg developers

$ ffmpeg -hide_banner -encoders | grep vulkan
 V....D av1_vulkan           AV1 (Vulkan) (codec av1)
Enter fullscreen mode Exit fullscreen mode

If av1_vulkan doesn't appear, your build wasn't compiled with --enable-vulkan (distro packages vary; the BtbN static builds and most 8.x distro packages include it).

2. Probe the driver for AV1 encode 🔍

The encoder existing in FFmpeg means nothing if the driver doesn't expose the extension. This is the step that separates "should work" from "works":

$ vulkaninfo | grep -iE "video_encode_(av1|queue)"
    VK_KHR_video_encode_av1    : extension revision 1
    VK_KHR_video_encode_queue  : extension revision 12
Enter fullscreen mode Exit fullscreen mode
You see Meaning
Both extensions listed You can encode AV1 via Vulkan 🎉
Only video_encode_queue Driver does Vulkan encode, but not AV1 (maybe H.264/H.265 only)
Neither Driver too old, or GPU lacks an AV1-capable video engine

Rough hardware floor: the last couple of GPU generations from each vendor have AV1 encode silicon. On Linux, Mesa/RADV support for AMD has been the pacesetter; NVIDIA and Intel arrived on their own schedules, and Windows driver branches differ again. When in doubt, update the driver first and re-probe; that fixes more failures than any FFmpeg flag.

⚠️ Note: there are documented cases of reasonable hardware + wrong driver branch producing zero frames. If step 3 fails, the error message usually names the missing extension. It's a driver problem, not your command line.

3. First encode: synthetic, then real

Start with a generated source so file quirks can't confuse the diagnosis:

$ ffmpeg -init_hw_device vulkan=gpu -filter_hw_device gpu \
    -f lavfi -i testsrc2=duration=10:size=1920x1080:rate=30 \
    -vf "format=nv12,hwupload" \
    -c:v av1_vulkan -y /tmp/probe.mp4
Enter fullscreen mode Exit fullscreen mode

Expected output tail:

frame=  300 fps=142 q=-0.0 size=    1843KiB time=00:00:10.00 bitrate=1509.6kbits/s speed=4.7x
Enter fullscreen mode Exit fullscreen mode

If that works, swap in a real file. Keep the decode on the GPU too, so frames never cross the PCIe bus:

$ ffmpeg -init_hw_device vulkan=gpu -hwaccel vulkan -hwaccel_output_format vulkan \
    -i input_1080p.mp4 \
    -c:v av1_vulkan -b:v 2M -maxrate 2.5M -bufsize 4M \
    -c:a copy -y out_av1.mp4
Enter fullscreen mode Exit fullscreen mode

That decode → encode residency is half the point of Vulkan here: FFmpeg 8's Vulkan work includes GPU-side processing, so a multi-rendition transcode can stay on-device instead of bouncing frames to system RAM for every filter.

4. Benchmark against SVT-AV1 on YOUR content 📊

Codec verdicts on someone else's clips are astrology. Take a representative sample of your real content and run a three-way bake-off at matched bitrates:

# software baseline
$ time ffmpeg -i sample.mp4 -c:v libsvtav1 -preset 8 -b:v 2M -y svt.mp4

# vulkan hardware path
$ time ffmpeg -init_hw_device vulkan=gpu -hwaccel vulkan -hwaccel_output_format vulkan \
    -i sample.mp4 -c:v av1_vulkan -b:v 2M -y vk.mp4

# score both with VMAF
$ ffmpeg -i vk.mp4 -i sample.mp4 -lavfi libvmaf -f null -
Enter fullscreen mode Exit fullscreen mode

What you should expect, without me inventing numbers for hardware I'm not running: the software encoder wins quality-per-bit, the hardware path wins throughput and watts. That's been the hardware-encoder trade since forever and Vulkan routes to the same silicon through a standard door. The decision input is your VMAF delta at your target bitrate versus your compute bill, so measure both on your content and your GPUs.

5. Which ladder rungs actually move

Workload Recommended path Why
Archival VOD top renditions SVT-AV1 (CPU) Every saved kilobit multiplies across storage + delivery
Live transcode ladders av1_vulkan / hw Realtime throughput is the constraint
UGC bulk ingest av1_vulkan / hw Most uploads get few views; economics favor throughput
Previews, proxies, scrub assets av1_vulkan / hw Nobody A/Bs the grain on a preview
Vendor-mixed fleet av1_vulkan One code path across NVIDIA/AMD/Intel is the whole pitch

The cross-vendor part is easy to underrate. If your pipeline speaks Vulkan instead of NVENC, the day cheaper spot capacity shows up on a different vendor's silicon, you follow the price with a config change instead of a rewrite.

Running it in containers 🐳

Your workstation probe passing means little if production is containerized. Vulkan in a container needs three things: the GPU device passed through, the vendor ICD (installable client driver) JSON present in the image, and a userspace driver that matches the host kernel driver.

# NVIDIA (with nvidia-container-toolkit)
$ docker run --rm --gpus all \
    -e NVIDIA_DRIVER_CAPABILITIES=all \
    my-ffmpeg:8.1 vulkaninfo | grep -i encode_av1

# AMD/Intel (Mesa): pass the render node
$ docker run --rm --device /dev/dri \
    my-ffmpeg:8.1 vulkaninfo | grep -i encode_av1
Enter fullscreen mode Exit fullscreen mode

💡 Tip: NVIDIA_DRIVER_CAPABILITIES=all (or at least video,compute,graphics) matters; the default capability set doesn't expose the video engines, and the resulting "No Vulkan device found" error looks identical to missing hardware.

Run the same probe inside the exact image your orchestrator schedules. Host/image driver mismatches produce failures that no amount of FFmpeg flag-tweaking fixes.

Common failures and fixes

# "Device does not support the requested video codec profile"
→ driver exposes encode_queue but not encode_av1; update driver or use av1_nvenc/amf/qsv

# "No Vulkan device found"
→ missing ICD loader or running in a container without --device/gpu passthrough

# encode runs but output is garbage/black
→ pixel format mismatch; force format=nv12 before hwupload
Enter fullscreen mode Exit fullscreen mode

What's next

  • Wire the probe into CI: a nightly vulkaninfo | grep + testsrc encode across your fleet tells you when a driver update flips a machine from software to hardware eligible.
  • Re-run your bake-off quarterly. The 8.1.x cycle has been landing driver-facing fixes steadily, and results from January are stale by summer.
  • If you want the decode-side story (Vulkan AV1/H.264/HEVC decode is much further along), that pairs well with this as the other half of a GPU-resident pipeline.

Top comments (0)