Blog

Intel Quick Sync (VAAPI) sur un VPS Linux : les commandes ffmpeg qui marchent

Commandes ffmpeg VAAPI prêtes à copier pour un Intel UHD 770 sous Linux : vainfo, encodage H.264/HEVC (classique et low_power), HEVC 10 bits, transcodage GPU avec scale_vaapi, décodage AV1, suivi du GPU.

Intel Quick Sync (VAAPI) sur un VPS Linux : les commandes ffmpeg qui marchent

Intel Quick Sync, c’est le moteur vidéo des GPU Intel. Sous Linux, ffmpeg le pilote via VAAPI (h264_vaapi, hevc_vaapi, scale_vaapi…). Voici un aide-mémoire des commandes que nous utilisons sur un Intel UHD 770. Celles d’encodage, de transcodage et d’AV1 sont reprises de notre test de charge sur GPU partagé, où elles ont tourné 20 minutes sans un seul échec.

Sur nos VM, ffmpeg et les pilotes VAAPI sont déjà installés, et le GPU est le nœud de rendu /dev/dri/renderD128. Sur une autre machine, adaptez le chemin du périphérique.

Ce que l’UHD 770 fait en matériel

CodecDécodageEncodage
H.264ouioui (h264_vaapi)
HEVC 8 et 10 bitsouioui (hevc_vaapi, -profile:v main10 en 10 bits)
VP9ouioui
AV1ouinon : décodage seulement

1. Vérifier le périphérique

ls -l /dev/dri/                       # renderD128 doit apparaître
vainfo --display drm --device /dev/dri/renderD128

Dans la sortie de vainfo, chaque ligne associe un profil à un point d’entrée :

  • VAEntrypointVLD : décodage matériel ;
  • VAEntrypointEncSlice : encodage matériel classique ;
  • VAEntrypointEncSliceLP : encodage basse consommation (-low_power 1 dans ffmpeg).

Pour l’AV1 (VAProfileAV1Profile0), seul VAEntrypointVLD apparaît : décodage, pas d’encodage.

Si vainfo renvoie une erreur de permission avec un utilisateur normal, ajoutez-le au groupe render puis reconnectez-vous :

sudo usermod -aG render "$USER"

2. Tester sans fichier vidéo

ffmpeg sait générer une mire de test, pratique pour vérifier l’encodage avant de toucher à de vrais fichiers :

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 - jette le résultat : on ne mesure que l’encodeur. Sans -nostats, ffmpeg affiche speed=…x pendant le traitement ; au-dessus de 1x, c’est plus rapide que le temps réel.

3. Encodage H.264 matériel

L’entrée est décodée par le CPU, les images sont envoyées au GPU (hwupload), puis encodées par Quick Sync :

ffmpeg -vaapi_device /dev/dri/renderD128 -i entree.mp4 \
  -vf 'format=nv12,hwupload' \
  -c:v h264_vaapi -b:v 8M -c:a copy sortie.mp4

En mode basse consommation, qui utilise un bloc d’encodage distinct du GPU :

ffmpeg -vaapi_device /dev/dri/renderD128 -i entree.mp4 \
  -vf 'format=nv12,hwupload' \
  -c:v h264_vaapi -low_power 1 -b:v 8M -c:a copy sortie.mp4

Les deux modes fonctionnent sur nos VM. Si l’un d’eux échoue sur une autre machine, vérifiez que vainfo liste le point d’entrée correspondant (EncSlice ou EncSliceLP).

4. Encodage HEVC (H.265) matériel

Même principe, autre encodeur :

# classique
ffmpeg -vaapi_device /dev/dri/renderD128 -i entree.mp4 \
  -vf 'format=nv12,hwupload' -c:v hevc_vaapi -b:v 6M -c:a copy sortie.mkv

# basse consommation
ffmpeg -vaapi_device /dev/dri/renderD128 -i entree.mp4 \
  -vf 'format=nv12,hwupload' -c:v hevc_vaapi -low_power 1 -b:v 6M -c:a copy sortie.mkv

5. HEVC 10 bits (Main10)

Le 10 bits passe par le format de pixel p010 et le profil main10 :

ffmpeg -vaapi_device /dev/dri/renderD128 -i entree-10bits.mkv \
  -vf 'format=p010,hwupload' \
  -c:v hevc_vaapi -profile:v main10 -b:v 20M -c:a copy sortie-main10.mkv

La commande qui nous a servi à créer un fichier de test 4K Main10 (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. Transcodage entièrement sur le GPU (ce que font Plex et Jellyfin)

Décodage, redimensionnement et encodage sur le GPU : les images ne repassent jamais par la mémoire système, et le CPU reste presque au repos.

ffmpeg -vaapi_device /dev/dri/renderD128 \
  -hwaccel vaapi -hwaccel_output_format vaapi -i film-4k.mkv \
  -vf 'scale_vaapi=w=1920:h=1080:format=nv12' \
  -c:v h264_vaapi -b:v 8M -c:a copy film-1080p.mkv
  • -hwaccel vaapi -hwaccel_output_format vaapi : décode sur le GPU et y garde les images ;
  • scale_vaapi=…:format=nv12 : redimensionne sur le GPU et passe du 10 bits au 8 bits, car la sortie H.264 est en 8 bits ;
  • ajoutez -low_power 1 après h264_vaapi pour l’encodeur basse consommation.

Dans notre test de charge, exactement ce traitement (HEVC 10 bits 4K → H.264 1080p) tournait à environ 1,3× le temps réel par serveur alors que le GPU partagé était saturé. GPU libre et encodeur basse consommation, notre guide Jellyfin et Plex mesure 12× le temps réel en 4K HDR → 1080p.

7. AV1 : décodage matériel, sortie HEVC ou H.264

L’UHD 770 décode l’AV1 mais n’a pas d’encodeur AV1 : av1_vaapi ne fonctionnera pas sur ce GPU. On décode l’AV1 sur le GPU et on réencode en HEVC ou en H.264 :

ffmpeg -vaapi_device /dev/dri/renderD128 \
  -hwaccel vaapi -hwaccel_output_format vaapi -i entree-av1.mkv \
  -vf scale_vaapi=w=1920:h=1080 -c:v hevc_vaapi -b:v 6M -c:a copy sortie-hevc.mkv

S’il vous faut de l’AV1 en sortie, encodez-le sur le CPU (par exemple avec libsvtav1), comme pour notre fichier de test AV1 :

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

Pour mesurer la vitesse de décodage seule, envoyez les images vers la sortie nulle :

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

8. Dans Docker

Passez au conteneur le nœud de rendu et son groupe :

docker run --rm -it \
  --device /dev/dri/renderD128 \
  --group-add "$(stat -c %g /dev/dri/renderD128)" \
  -v "$PWD":/work -w /work \
  votre-image-ffmpeg ffmpeg -vaapi_device /dev/dri/renderD128 ...

L’image doit embarquer son propre pilote VAAPI (le pilote média Intel) et un ffmpeg compilé avec VAAPI.

9. Vérifier que le GPU travaille vraiment

  • nvtop fonctionne dans nos VM : charge GPU de la VM et par processus.
  • intel_gpu_top ne fonctionne pas sur le GPU virtuel d’une VM : il s’appuie sur les compteurs PMU d’i915, qui ne sont pas exposés à la VM. Il ne marche que sur l’hôte physique.
  • gpu-check (préinstallé sur nos VM) teste VAAPI, Vulkan, OpenCL et OpenVINO en une commande.
  • Après un gros traitement, cherchez les erreurs GPU dans le journal du noyau :
journalctl -k -b | grep -iE "gpu hang|context reset|reset.*engine|guc.*fail"

Une sortie vide signifie qu’aucun plantage n’a été enregistré depuis le démarrage.

Erreurs fréquentes

SymptômeCause probable
vainfo ou ffmpeg : permission refusée sur /dev/dri/renderD128utilisateur absent du groupe render (ou conteneur lancé sans --group-add)
Impossible to convert between the formatsles images sont en mémoire système alors que l’encodeur attend des images GPU : ajoutez hwupload (avec -vaapi_device)
CPU très chargé pendant un transcodage « GPU »-hwaccel_output_format vaapi oublié, ou filtre CPU (scale au lieu de scale_vaapi) dans la chaîne
L’encodage AV1 échouenormal : l’UHD 770 n’a pas d’encodeur AV1

À lire aussi

Essayer

Une VM Linux avec un Intel UHD 770 à l’intérieur, hébergée en Allemagne : ffmpeg, VAAPI, OpenCL et nvtop préinstallés, accès SSH root, IPv6 dédiée. Offres à partir de 14,99 € HT/mois, prix fixe.