Blog

Intel Quick Sync (VAAPI) num VPS Linux: comandos ffmpeg que funcionam

Comandos ffmpeg VAAPI para Intel UHD 770 em Linux: vainfo, H.264/HEVC (clássico e low_power), HEVC 10 bits, transcodificação GPU com scale_vaapi, AV1.

Intel Quick Sync (VAAPI) num VPS Linux: comandos ffmpeg que funcionam

O Intel Quick Sync é o motor de vídeo das GPU Intel. Em Linux, o ffmpeg controla-o através do VAAPI (h264_vaapi, hevc_vaapi, scale_vaapi…). Esta página é uma cábula de comandos que usamos numa Intel UHD 770; os comandos de codificação, transcodificação e AV1 são os do nosso teste de carga da GPU partilhada, onde correram durante 20 minutos sem uma única falha.

Nas nossas VM, o ffmpeg e os controladores VAAPI vêm pré-instalados e a GPU é o render node /dev/dri/renderD128. Noutra máquina, ajuste o caminho do dispositivo.

O que a UHD 770 faz por hardware

CodecDescodificaçãoCodificação
H.264simsim (h264_vaapi)
HEVC 8 bits e 10 bitssimsim (hevc_vaapi, -profile:v main10 para 10 bits)
VP9simsim
AV1simnão: só descodificação

1. Verificar o dispositivo

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

Na saída do vainfo, cada linha associa um perfil a um entrypoint:

  • VAEntrypointVLD: descodificação por hardware;
  • VAEntrypointEncSlice: codificação clássica por hardware;
  • VAEntrypointEncSliceLP: codificação low-power (-low_power 1 no ffmpeg).

Para AV1 (VAProfileAV1Profile0) só verá VAEntrypointVLD: descodificação, sem codificação.

Se o vainfo falhar com um erro de permissões como utilizador normal, adicione-se ao grupo render e volte a iniciar sessão:

sudo usermod -aG render "$USER"

2. Testar sem ficheiro de vídeo

O ffmpeg consegue gerar um padrão de teste, útil para confirmar que a codificação funciona antes de mexer em ficheiros reais:

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 a saída: mede apenas o codificador. Sem -nostats, o ffmpeg mostra speed=…x durante a execução; acima de 1x significa mais depressa do que o tempo real.

3. Codificação H.264 por hardware

A entrada é descodificada na CPU, as imagens são enviadas para a GPU (hwupload) e depois codificadas pelo Quick Sync:

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, um bloco de codificação separado na 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

Os dois modos funcionam nas nossas VM. Se um deles der erro noutra máquina, verifique se o vainfo lista o entrypoint correspondente (EncSlice ou EncSliceLP).

4. Codificação HEVC (H.265) por hardware

O mesmo esquema, com outro codificador:

# clássico
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)

O 10 bits usa o formato de píxel p010 e o 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

O comando que usámos para criar um ficheiro de teste 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. Transcodificação inteiramente na GPU (o que fazem o Plex e o Jellyfin)

Descodificar, redimensionar e codificar, tudo na GPU: as imagens nunca voltam à memória do sistema, por isso a CPU fica quase parada.

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: descodifica na GPU e mantém lá as imagens;
  • scale_vaapi=…:format=nv12: redimensiona na GPU e converte de 10 para 8 bits, porque a saída H.264 é de 8 bits;
  • acrescente -low_power 1 depois de h264_vaapi para usar o codificador low-power.

No nosso teste de carga, este mesmo pipeline (HEVC 4K 10 bits → H.264 1080p) correu a cerca de 1,3× o tempo real por servidor com a GPU partilhada saturada. Com a GPU livre e o codificador low-power, o nosso guia Jellyfin e Plex mediu 12× o tempo real numa transcodificação 4K HDR → 1080p.

7. AV1: descodificação por hardware, saída HEVC ou H.264

A UHD 770 descodifica AV1 mas não tem codificador AV1: o av1_vaapi não funciona nesta GPU. Descodifique o AV1 na GPU e volte a codificar em HEVC ou 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

Se precisar de saída AV1, codifique-a na CPU (por exemplo com libsvtav1), que foi como criámos o nosso ficheiro de teste AV1:

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

Para medir só a velocidade de descodificação, envie as imagens para o muxer null:

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

8. Dentro do Docker

Passe o render node e o respetivo grupo ao contentor:

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

A imagem precisa do seu próprio controlador VAAPI (Intel media driver) e de um ffmpeg compilado com VAAPI.

9. Confirmar que a GPU está mesmo a trabalhar

  • O nvtop funciona dentro das nossas VM: carga da GPU para a VM e por processo.
  • O intel_gpu_top não funciona na GPU virtual de uma VM: depende dos contadores PMU do i915, que não são expostos à VM. Só funciona no anfitrião físico.
  • O gpu-check (pré-instalado nas nossas VM) testa VAAPI, Vulkan, OpenCL e OpenVINO num só comando.
  • Depois de uma tarefa pesada, procure erros de GPU no log do kernel:
journalctl -k -b | grep -iE "gpu hang|context reset|reset.*engine|guc.*fail"

Uma saída vazia significa que não foi registado nenhum hang desde o arranque.

Erros frequentes

SintomaCausa provável
vainfo ou ffmpeg: permission denied em /dev/dri/renderD128utilizador fora do grupo render (ou contentor arrancado sem --group-add)
Impossible to convert between the formatsas imagens estão na memória do sistema mas o codificador espera imagens na GPU: acrescente hwupload (com -vaapi_device)
CPU elevada durante uma transcodificação “GPU”falta -hwaccel_output_format vaapi, ou há um filtro de CPU (scale, em vez de scale_vaapi) na cadeia
A codificação AV1 falhaé normal: a UHD 770 não tem codificador AV1

Artigos relacionados

Experimente

Uma VM Linux com uma Intel UHD 770 lá dentro, alojada na Alemanha: ffmpeg, VAAPI, OpenCL e nvtop pré-instalados, SSH root, IPv6 dedicado. Planos a partir de 14,99 € s/ IVA/mês, preço fixo.