Blog

Intel Quick Sync (VAAPI) auf einem Linux-VPS: ffmpeg-Befehle, die funktionieren

ffmpeg-VAAPI-Befehle für eine Intel UHD 770 unter Linux: vainfo, H.264/HEVC (klassisch, low_power), HEVC 10 Bit, GPU-Transkodierung mit scale_vaapi, AV1.

Intel Quick Sync (VAAPI) auf einem Linux-VPS: ffmpeg-Befehle, die funktionieren

Intel Quick Sync ist die Video-Engine in Intel-GPUs. Unter Linux steuert ffmpeg sie über VAAPI an (h264_vaapi, hevc_vaapi, scale_vaapi…). Diese Seite ist ein Spickzettel mit Befehlen, die wir auf einer Intel UHD 770 nutzen; die Befehle für Kodierung, Transkodierung und AV1 stammen aus unserem Lasttest mit geteilter GPU, in dem sie 20 Minuten lang ohne einen einzigen Fehler liefen.

Auf unseren VMs sind ffmpeg und die VAAPI-Treiber vorinstalliert, und die GPU ist der Render-Node /dev/dri/renderD128. Auf einer anderen Maschine passen Sie den Gerätepfad entsprechend an.

Was die UHD 770 in Hardware kann

CodecDekodierungKodierung
H.264jaja (h264_vaapi)
HEVC 8 Bit und 10 Bitjaja (hevc_vaapi, -profile:v main10 für 10 Bit)
VP9jaja
AV1janein: nur Dekodierung

1. Gerät prüfen

ls -l /dev/dri/                       # renderD128 sollte aufgelistet sein
vainfo --display drm --device /dev/dri/renderD128

In der Ausgabe von vainfo kombiniert jede Zeile ein Profil mit einem Entrypoint:

  • VAEntrypointVLD: Hardware-Dekodierung;
  • VAEntrypointEncSlice: klassische Hardware-Kodierung;
  • VAEntrypointEncSliceLP: Low-Power-Kodierung (-low_power 1 in ffmpeg).

Für AV1 (VAProfileAV1Profile0) sehen Sie nur VAEntrypointVLD: Dekodierung, keine Kodierung.

Wenn vainfo als normaler Benutzer mit einem Berechtigungsfehler abbricht, fügen Sie sich der Gruppe render hinzu und melden Sie sich neu an:

sudo usermod -aG render "$USER"

2. Test ohne Videodatei

ffmpeg kann ein Testbild erzeugen – praktisch, um die Kodierung zu prüfen, bevor man echte Dateien anfasst:

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 - verwirft die Ausgabe: Sie messen nur den Encoder. Ohne -nostats zeigt ffmpeg während der Ausführung speed=…x an; ein Wert über 1x bedeutet schneller als Echtzeit.

3. H.264-Hardware-Kodierung

Die Eingabe wird auf der CPU dekodiert, die Frames werden auf die GPU geladen (hwupload) und dann von Quick Sync kodiert:

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, ein separater Encoder-Block auf der 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 funktionieren auf unseren VMs. Wenn einer davon auf einer anderen Maschine einen Fehler liefert, prüfen Sie, ob vainfo den passenden Entrypoint (EncSlice oder EncSliceLP) auflistet.

4. HEVC-(H.265-)Hardware-Kodierung

Gleiches Muster, anderer Encoder:

# klassisch
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. HEVC 10 Bit (Main10)

10 Bit nutzt das Pixelformat p010 und das Profil 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

Der Befehl, mit dem wir eine 4K-Main10-Testdatei erzeugt haben (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. Vollständige GPU-Transkodierung (wie bei Plex und Jellyfin)

Dekodieren, Skalieren und Kodieren laufen komplett auf der GPU: Die Frames gehen nie in den Arbeitsspeicher zurück, die CPU bleibt also fast untätig.

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: auf der GPU dekodieren und die Frames dort behalten;
  • scale_vaapi=…:format=nv12: auf der GPU skalieren und 10 Bit in 8 Bit umwandeln, da die H.264-Ausgabe 8 Bit hat;
  • für den Low-Power-Encoder -low_power 1 hinter h264_vaapi ergänzen.

In unserem Lasttest lief genau diese Pipeline (4K HEVC 10 Bit → 1080p H.264) mit etwa 1,3× Echtzeit pro Server, während die geteilte GPU voll ausgelastet war. Auf einer freien GPU mit dem Low-Power-Encoder haben wir in unserer Jellyfin-&-Plex-Anleitung 12× Echtzeit für eine Transkodierung von 4K HDR → 1080p gemessen.

7. AV1: Hardware-Dekodierung, Ausgabe in HEVC oder H.264

Die UHD 770 dekodiert AV1, hat aber keinen AV1-Encoder: av1_vaapi funktioniert auf dieser GPU nicht. Dekodieren Sie AV1 auf der GPU und kodieren Sie neu nach HEVC oder 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

Wenn Sie eine AV1-Ausgabe brauchen, kodieren Sie auf der CPU (zum Beispiel mit libsvtav1) – so haben wir auch unsere AV1-Testdatei erzeugt:

ffmpeg -f lavfi -i testsrc2=size=3840x2160:rate=30 -t 10 \
  -c:v libsvtav1 -preset 12 -y src.mkv

Um nur die Dekodiergeschwindigkeit zu messen, schicken Sie die Frames an den Null-Muxer:

ffmpeg -vaapi_device /dev/dri/renderD128 \
  -hwaccel vaapi -hwaccel_output_format vaapi -i input-av1.mkv -f null -

8. In Docker

Reichen Sie den Render-Node und seine Gruppe an den Container durch:

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 ...

Das Image braucht einen eigenen VAAPI-Treiber (Intel Media Driver) und ein ffmpeg, das mit VAAPI-Unterstützung gebaut wurde.

9. Prüfen, ob die GPU wirklich arbeitet

  • nvtop funktioniert in unseren VMs: GPU-Last der VM und pro Prozess.
  • intel_gpu_top funktioniert nicht auf der virtuellen GPU einer VM: Es stützt sich auf i915-PMU-Zähler, die der VM nicht zur Verfügung stehen. Es funktioniert nur auf dem physischen Host.
  • gpu-check (auf unseren VMs vorinstalliert) testet VAAPI, Vulkan, OpenCL und OpenVINO mit einem einzigen Befehl.
  • Suchen Sie nach einem anspruchsvollen Job im Kernel-Log nach GPU-Fehlern:
journalctl -k -b | grep -iE "gpu hang|context reset|reset.*engine|guc.*fail"

Eine leere Ausgabe bedeutet, dass seit dem Booten kein Hänger aufgezeichnet wurde.

Häufige Fehler

SymptomWahrscheinliche Ursache
vainfo oder ffmpeg: Permission denied auf /dev/dri/renderD128Benutzer nicht in der Gruppe render (oder Container ohne --group-add gestartet)
Impossible to convert between the formatsDie Frames liegen im Arbeitsspeicher, der Encoder erwartet aber GPU-Frames: hwupload ergänzen (mit -vaapi_device)
Hohe CPU-Last bei einer „GPU“-Transkodierung-hwaccel_output_format vaapi fehlt, oder ein CPU-Filter (scale statt scale_vaapi) steckt in der Kette
AV1-Kodierung schlägt fehlerwartet: Die UHD 770 hat keinen AV1-Encoder

Weiterlesen

Ausprobieren

Eine Linux-VM mit Intel UHD 770 im Inneren, gehostet in Deutschland: ffmpeg, VAAPI, OpenCL und nvtop vorinstalliert, Root-SSH, dedizierte IPv6. Angebote ab 14,99 € netto/Monat, zum Festpreis.