Hardware video decode
What the GPU's decoder can do, what it cannot, and how to find out on your machine.
How hardware video decoding works, what silicon can do it, and — the part people keep rediscovering painfully — what it cannot do even when it works.
Two different claims
These get conflated, and conflating them costs real time.
| "Hardware video decode works" | The GPU's fixed-function decoder runs a codec it supports. |
| "YouTube decodes on the GPU" | That, and the site is serving a codec the GPU supports. |
On older Intel graphics these are not the same thing, because those chips cannot hardware-decode VP9 or AV1 at all — and VP9 and AV1 are what YouTube serves by default. Achieving the first does not give you the second.
The stack
application — Firefox, ffmpeg
libva the dispatcher; decodes nothing itself
i965 backend all the codec work is here
libdrm (Intel)
the kernel's i915 GEM driver
the GPU
libva itself decodes nothing. It is a dispatcher that loads a backend, and every codec decision belongs to the backend it loads.
Which backend
Intel ships two, and picking the wrong one loses a day.
intel-vaapi-driver— covers Gen 4 through Gen 9. This is the one used here, for both the Haswell and the Kaby Lake machines in the lab.intel-media-driver— Broadwell and newer only.
Kaby Lake would also be covered by the newer driver, but it is an enormous C++ code base with its own buffer manager and dependencies, none of it ported, while the older driver is already built, packaged and on the image. So the older one is used on both.
You will see libva try the newer driver first and log a failure before finding the one that works. That is normal and is not an error.
Checking a machine
vaprobe ships with the stack, so it is on any machine that has it. Run it with
no arguments and it reports which backend loaded, which profiles the chip
advertises, and which entry points each profile supports.
That output is the authority for what your machine can do. Everything below is context for reading it.
The ceiling
Fixed-function decoders support a fixed list of codecs, decided when the chip was made. No driver work changes that list.
Haswell-era graphics decode H.264, MPEG-2, VC-1 and JPEG. They do not decode VP9 or AV1 — not slowly, not partially. Those codecs fall back to the CPU.
Kaby Lake-era graphics add HEVC at 8 and 10 bits, VP8, and VP9 profiles 0 and 2 in fixed function.
This is why a machine can pass every hardware-decode test and still play YouTube on the CPU: the tests use a codec the chip supports, and the site serves one it does not.
What to do about it
If the goal is smooth video on an older chip, the lever is codec selection, not driver tuning:
- Ask the site for H.264 where it offers a choice. Some browsers expose this; some extensions force it.
- For local files, check what the file actually is before assuming the decoder
is at fault.
ffmpegwill tell you, and it will also tell you whether it chose a hardware path.
ffmpeg
The ported ffmpeg is built with VA-API support, so it can both decode and probe through the same stack the browser uses. It is the quickest way to tell a codec problem from a driver problem: if ffmpeg reports hardware decode for a file and the browser does not, the difference is the browser's codec choice, not the hardware.
More documentation
- Booting the live image
- Installing to disk
- Packages and the filesystem
- How it boots
- The syscall ABI
- Hardware support
- ACPI
- UEFI boot entries
- NetBooting a Mac
- The AO toolkit
- Grafika — the graphics API
- The display protocol
- Desktop effects
- The level bezel
- Notifications
- Rastinis — the file manager
- File operations
- Audio — Garsas
- Networking — Tinklas
- Network shares — SMB and NFS
- Remote control
- The Win32 subsystem
- DirectX and OpenGL for Win32 programs
- Ports and packaging