Blog

Intel Quick Sync (VAAPI) op een Linux VPS: ffmpeg-commando's die werken

Kant-en-klare ffmpeg VAAPI-commando's voor een Intel UHD 770 onder Linux: vainfo, H.264/HEVC (klassiek en low_power), 10-bit HEVC, scale_vaapi, AV1, monitoring.

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

CodecDecoderenEncoderen
H.264jaja (h264_vaapi)
HEVC 8-bit en 10-bitjaja (hevc_vaapi, -profile:v main10 voor 10-bit)
VP9jaja
AV1janee: 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 1 in 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 1 toe na h264_vaapi voor 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

  • nvtop werkt in onze VM’s: GPU-belasting voor de VM en per proces.
  • intel_gpu_top werkt 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

SymptoomWaarschijnlijke oorzaak
vainfo of ffmpeg: permission denied op /dev/dri/renderD128gebruiker zit niet in de groep render (of container gestart zonder --group-add)
Impossible to convert between the formatsde 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 misluktnormaal: de UHD 770 heeft geen AV1-encoder

Gerelateerd

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.