Intel Quick Sync (VAAPI) op een Linux VPS: ffmpeg-commando’s die werken
Intel Quick Sync is de video-engine in Intel-GPU’s. Onder Linux stuurt ffmpeg
die aan via VAAPI (h264_vaapi, hevc_vaapi, scale_vaapi…). Deze pagina
is een spiekbriefje met commando’s die we op een Intel UHD 770 gebruiken; de
commando’s voor encoding, transcoding en AV1 zijn dezelfde als in onze
belastingtest met een gedeelde GPU,
waar ze 20 minuten draaiden zonder één enkele fout.
Op onze VM’s zijn ffmpeg en de VAAPI-drivers vooraf geïnstalleerd en is de GPU
de render node /dev/dri/renderD128. Op een andere machine pas je het pad
naar het apparaat aan.
Wat de UHD 770 in hardware kan
| Codec | Decoderen | Encoderen |
|---|---|---|
| H.264 | ja | ja (h264_vaapi) |
| HEVC 8-bit en 10-bit | ja | ja (hevc_vaapi, -profile:v main10 voor 10-bit) |
| VP9 | ja | ja |
| AV1 | ja | nee: alleen decoderen |
1. Het apparaat controleren
ls -l /dev/dri/ # renderD128 moet in de lijst staan
vainfo --display drm --device /dev/dri/renderD128
In de uitvoer van vainfo koppelt elke regel een profiel aan een entrypoint:
VAEntrypointVLD: hardwarematig decoderen;VAEntrypointEncSlice: klassieke hardware-encoding;VAEntrypointEncSliceLP: low-power-encoding (-low_power 1in ffmpeg).
Voor AV1 (VAProfileAV1Profile0) zie je alleen VAEntrypointVLD: decoderen,
geen encoding.
Geeft vainfo als gewone gebruiker een toegangsfout, voeg jezelf dan toe aan
de groep render en log opnieuw in:
sudo usermod -aG render "$USER"
2. Testen zonder videobestand
ffmpeg kan een testpatroon genereren, handig om te controleren of encoding werkt voordat je echte bestanden aanraakt:
ffmpeg -vaapi_device /dev/dri/renderD128 \
-f lavfi -i testsrc2=size=1920x1080:rate=30 -t 60 \
-vf format=nv12,hwupload -c:v h264_vaapi -b:v 8M -f null -
-f null - gooit de uitvoer weg: je meet alleen de encoder. Zonder -nostats
toont ffmpeg tijdens het draaien speed=…x; boven 1x betekent sneller dan
realtime.
3. H.264-hardware-encoding
De invoer wordt op de CPU gedecodeerd, de frames worden naar de GPU geüpload
(hwupload) en vervolgens door Quick Sync geëncodeerd:
ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 \
-vf 'format=nv12,hwupload' \
-c:v h264_vaapi -b:v 8M -c:a copy output.mp4
Low-power-modus, een apart encoderblok op de GPU:
ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 \
-vf 'format=nv12,hwupload' \
-c:v h264_vaapi -low_power 1 -b:v 8M -c:a copy output.mp4
Beide modi werken op onze VM’s. Geeft een ervan op een andere machine een fout,
controleer dan of vainfo het bijbehorende entrypoint toont (EncSlice of
EncSliceLP).
4. HEVC (H.265)-hardware-encoding
Zelfde patroon, andere encoder:
# klassiek
ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 \
-vf 'format=nv12,hwupload' -c:v hevc_vaapi -b:v 6M -c:a copy output.mkv
# low power
ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 \
-vf 'format=nv12,hwupload' -c:v hevc_vaapi -low_power 1 -b:v 6M -c:a copy output.mkv
5. 10-bit HEVC (Main10)
10-bit gebruikt het pixelformaat p010 en het profiel main10:
ffmpeg -vaapi_device /dev/dri/renderD128 -i input-10bit.mkv \
-vf 'format=p010,hwupload' \
-c:v hevc_vaapi -profile:v main10 -b:v 20M -c:a copy output-main10.mkv
Het commando waarmee we een 4K Main10-testbestand maakten (30 s, 40 Mbit/s):
ffmpeg -vaapi_device /dev/dri/renderD128 \
-f lavfi -i testsrc2=size=3840x2160:rate=30 -t 30 \
-vf format=p010,hwupload -c:v hevc_vaapi -profile:v main10 -b:v 40M -y src.mkv
6. Volledige GPU-transcode (wat Plex en Jellyfin doen)
Decoderen, schalen en encoderen gebeurt allemaal op de GPU: de frames gaan nooit terug naar het systeemgeheugen, dus de CPU heeft bijna niets te doen.
ffmpeg -vaapi_device /dev/dri/renderD128 \
-hwaccel vaapi -hwaccel_output_format vaapi -i movie-4k.mkv \
-vf 'scale_vaapi=w=1920:h=1080:format=nv12' \
-c:v h264_vaapi -b:v 8M -c:a copy movie-1080p.mkv
-hwaccel vaapi -hwaccel_output_format vaapi: decoderen op de GPU en de frames daar houden;scale_vaapi=…:format=nv12: schalen op de GPU en 10-bit omzetten naar 8-bit, omdat H.264-uitvoer 8-bit is;- voeg
-low_power 1toe nah264_vaapivoor de low-power-encoder.
In onze belastingtest draaide precies deze pipeline (4K HEVC 10-bit → 1080p H.264) op ongeveer 1,3× realtime per server terwijl de gedeelde GPU verzadigd was. Op een GPU zonder andere belasting en met de low-power-encoder maten we in onze handleiding voor Jellyfin & Plex 12× realtime voor een transcode van 4K HDR → 1080p.
7. AV1: hardwarematig decoderen, uitvoer in HEVC of H.264
De UHD 770 decodeert AV1, maar heeft geen AV1-encoder: av1_vaapi werkt
niet op deze GPU. Decodeer AV1 op de GPU en encodeer opnieuw naar HEVC of H.264:
ffmpeg -vaapi_device /dev/dri/renderD128 \
-hwaccel vaapi -hwaccel_output_format vaapi -i input-av1.mkv \
-vf scale_vaapi=w=1920:h=1080 -c:v hevc_vaapi -b:v 6M -c:a copy output-hevc.mkv
Heb je AV1-uitvoer nodig, encodeer dan op de CPU (bijvoorbeeld met
libsvtav1). Zo hebben we ons AV1-testbestand gemaakt:
ffmpeg -f lavfi -i testsrc2=size=3840x2160:rate=30 -t 10 \
-c:v libsvtav1 -preset 12 -y src.mkv
Om alleen de decodeersnelheid te meten, stuur je de frames naar de null-muxer:
ffmpeg -vaapi_device /dev/dri/renderD128 \
-hwaccel vaapi -hwaccel_output_format vaapi -i input-av1.mkv -f null -
8. In Docker
Geef de render node en de bijbehorende groep door aan de container:
docker run --rm -it \
--device /dev/dri/renderD128 \
--group-add "$(stat -c %g /dev/dri/renderD128)" \
-v "$PWD":/work -w /work \
your-ffmpeg-image ffmpeg -vaapi_device /dev/dri/renderD128 ...
De image heeft een eigen VAAPI-driver nodig (Intel media driver) en een ffmpeg die met VAAPI-ondersteuning is gebouwd.
9. Controleren of de GPU echt werkt
nvtopwerkt in onze VM’s: GPU-belasting voor de VM en per proces.intel_gpu_topwerkt niet op de virtuele GPU van een VM: het steunt op i915 PMU-tellers die niet aan de VM worden doorgegeven. Het werkt alleen op de fysieke host.gpu-check(vooraf geïnstalleerd op onze VM’s) test VAAPI, Vulkan, OpenCL en OpenVINO in één commando.- Zoek na een zware job naar GPU-fouten in het kernellog:
journalctl -k -b | grep -iE "gpu hang|context reset|reset.*engine|guc.*fail"
Lege uitvoer betekent dat er sinds het opstarten geen hang is geregistreerd.
Veelgemaakte fouten
| Symptoom | Waarschijnlijke oorzaak |
|---|---|
vainfo of ffmpeg: permission denied op /dev/dri/renderD128 | gebruiker zit niet in de groep render (of container gestart zonder --group-add) |
Impossible to convert between the formats | de frames staan in het systeemgeheugen maar de encoder verwacht GPU-frames: voeg hwupload toe (met -vaapi_device) |
| Hoog CPU-gebruik tijdens een “GPU”-transcode | -hwaccel_output_format vaapi ontbreekt, of er zit een CPU-filter (scale, niet scale_vaapi) in de keten |
| AV1-encoding mislukt | normaal: de UHD 770 heeft geen AV1-encoder |
Gerelateerd
- Gedeelde Intel UHD 770 onder volle belasting: een GPU-stresstest van 20 minuten
- Versnelde videotranscodering: geen GPU van €500/maand nodig
- Benchmarks UHD 770 vs HD Graphics 530
Probeer het
Een Linux-VM met een Intel UHD 770 erin, gehost in Duitsland: ffmpeg, VAAPI,
OpenCL en nvtop vooraf geïnstalleerd, root-toegang via SSH en een eigen
IPv6-adres. Plannen vanaf €14,99 excl. btw/mnd, vaste prijs.