Blog

Intel Quick Sync (VAAPI) en un VPS Linux: comandos ffmpeg que funcionan

Comandos ffmpeg VAAPI listos para copiar en una Intel UHD 770: vainfo, H.264/HEVC (clásico y low_power), HEVC 10 bits, scale_vaapi, decodificación AV1.

Intel Quick Sync (VAAPI) en un VPS Linux: comandos ffmpeg que funcionan

Intel Quick Sync es el motor de vídeo de las GPU Intel. En Linux, ffmpeg lo controla a través de VAAPI (h264_vaapi, hevc_vaapi, scale_vaapi…). Esta página es una chuleta de los comandos que usamos en una Intel UHD 770; los de codificación, transcodificación y AV1 son los de nuestra prueba de carga en GPU compartida, donde funcionaron durante 20 minutos sin un solo fallo.

En nuestras VM, ffmpeg y los drivers VAAPI vienen preinstalados y la GPU es el render node /dev/dri/renderD128. En otra máquina, ajusta la ruta del dispositivo.

Qué hace la UHD 770 por hardware

CódecDecodificaciónCodificación
H.264sísí (h264_vaapi)
HEVC 8 y 10 bitssísí (hevc_vaapi, -profile:v main10 para 10 bits)
VP9sísí
AV1síno: solo decodificación

1. Comprobar el dispositivo

ls -l /dev/dri/                       # debe aparecer renderD128
vainfo --display drm --device /dev/dri/renderD128

En la salida de vainfo, cada línea asocia un perfil a un entrypoint:

  • VAEntrypointVLD: decodificación por hardware;
  • VAEntrypointEncSlice: codificación por hardware clásica;
  • VAEntrypointEncSliceLP: codificación low-power (-low_power 1 en ffmpeg).

Para AV1 (VAProfileAV1Profile0) solo verás VAEntrypointVLD: decodificación, sin codificación.

Si vainfo falla con un error de permisos como usuario normal, añádete al grupo render y vuelve a iniciar sesión:

sudo usermod -aG render "$USER"

2. Probar sin archivo de vídeo

ffmpeg puede generar un patrón de prueba, práctico para comprobar que la codificación funciona antes de tocar archivos reales:

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 - descarta la salida: solo mides el codificador. Sin -nostats, ffmpeg muestra speed=…x mientras trabaja; por encima de 1x significa más rápido que el tiempo real.

3. Codificación H.264 por hardware

La entrada se decodifica en la CPU, los fotogramas se suben a la GPU (hwupload) y Quick Sync los codifica:

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

Modo low-power, un bloque de codificación aparte en la 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

Los dos modos funcionan en nuestras VM. Si uno de ellos da error en otra máquina, comprueba que vainfo lista el entrypoint correspondiente (EncSlice o EncSliceLP).

4. Codificación HEVC (H.265) por hardware

Mismo esquema, otro codificador:

# clásico
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 bits (Main10)

El 10 bits usa el formato de píxel p010 y el perfil 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

El comando que usamos para crear un archivo de prueba 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. Transcodificación completa en la GPU (lo que hacen Plex y Jellyfin)

Decodificar, redimensionar y codificar, todo en la GPU: los fotogramas nunca vuelven a la memoria del sistema, así que la CPU queda casi en reposo.

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: decodifica en la GPU y mantiene allí los fotogramas;
  • scale_vaapi=…:format=nv12: redimensiona en la GPU y convierte de 10 a 8 bits, porque la salida H.264 es de 8 bits;
  • añade -low_power 1 después de h264_vaapi para usar el codificador low-power.

En nuestra prueba de carga, este mismo pipeline (HEVC 4K 10 bits → H.264 1080p) iba a unas 1,3× tiempo real por servidor con la GPU compartida saturada. Con la GPU libre y el codificador low-power, nuestra guía de Jellyfin y Plex midió 12× tiempo real en una transcodificación 4K HDR → 1080p.

7. AV1: decodificación por hardware, salida HEVC o H.264

La UHD 770 decodifica AV1 pero no tiene codificador AV1: av1_vaapi no funcionará en esta GPU. Decodifica el AV1 en la GPU y recodifica a HEVC o 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

Si necesitas salida AV1, codifícala en la CPU (por ejemplo con libsvtav1), que es como creamos nuestro archivo de prueba AV1:

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

Para medir solo la velocidad de decodificación, envía los fotogramas al muxer null:

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

8. Dentro de Docker

Pasa el render node y su grupo al contenedor:

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

La imagen necesita su propio driver VAAPI (Intel media driver) y un ffmpeg compilado con VAAPI.

9. Comprobar que la GPU trabaja de verdad

  • nvtop funciona dentro de nuestras VM: carga de la GPU para la VM y por proceso.
  • intel_gpu_top no funciona en la GPU virtual de una VM: depende de contadores PMU de i915 que no se exponen a la VM. Solo funciona en el host físico.
  • gpu-check (preinstalado en nuestras VM) prueba VAAPI, Vulkan, OpenCL y OpenVINO en un solo comando.
  • Después de un trabajo pesado, busca errores de GPU en el log del kernel:
journalctl -k -b | grep -iE "gpu hang|context reset|reset.*engine|guc.*fail"

Si la salida está vacía, no se ha registrado ningún hang desde el arranque.

Errores habituales

SíntomaCausa probable
vainfo o ffmpeg: permiso denegado en /dev/dri/renderD128el usuario no está en el grupo render (o el contenedor se lanzó sin --group-add)
Impossible to convert between the formatslos fotogramas están en memoria del sistema pero el codificador espera fotogramas GPU: añade hwupload (con -vaapi_device)
CPU alta durante una transcodificación «GPU»falta -hwaccel_output_format vaapi, o hay un filtro de CPU (scale, no scale_vaapi) en la cadena
La codificación AV1 fallaes lo esperado: la UHD 770 no tiene codificador AV1

Artículos relacionados

Probar

Una VM Linux con una Intel UHD 770 dentro, alojada en Alemania: ffmpeg, VAAPI, OpenCL y nvtop preinstalados, SSH root, IPv6 dedicada. Ofertas desde 14,99 €/mes sin IVA, precio fijo.