Skip to content

feat(transcode): add Intel VA-API (Arc) GPU backend#30

Open
Pon-node wants to merge 1 commit into
livepeer:rs/av1-transcodefrom
Pon-node:feat/transcode-intel-vaapi
Open

feat(transcode): add Intel VA-API (Arc) GPU backend#30
Pon-node wants to merge 1 commit into
livepeer:rs/av1-transcodefrom
Pon-node:feat/transcode-intel-vaapi

Conversation

@Pon-node

@Pon-node Pon-node commented Jul 15, 2026

Copy link
Copy Markdown

Adds a full-GPU Intel VA-API backend to the transcode app, alongside the existing NVENC / CPU paths. Motivated by running the transcoder on an Intel Arc A770.

What

  • profiles.pyh264_vaapi / hevc_vaapi / av1_vaapi support in video_args: CQP rate control (-rc_mode CQP -qp), nv12 VA-surface pixel format, chroma clamp to 4:2:0. Selected through the existing --h264/h265/av1-encoder flags.
  • engine.py-vaapi_device for GPU encode, plus an optional HWACCEL_DECODE path (-hwaccel vaapi -hwaccel_output_format vaapi + scale_vaapi) that keeps decode + scale + encode all on the GPU. FFMPEG_BIN lets the image choose the ffmpeg build.
  • Dockerfile.intel — built on jellyfin-ffmpeg7. Distro ffmpeg's scale_vaapi and av1_qsv are broken on Arc (Cannot allocate memory / Invalid FrameType); the jellyfin build ships the patched iHD + oneVPL stack that fixes both. docker-compose.intel.yml wires it up with --device /dev/dri.
  • Dockerfile.gpu — NVENC CUDA base, realizing the README's existing "CUDA base" note (no functional change to the CPU/NVENC code paths).
  • runner.py — advertises a non-NVIDIA GPU to orchestrator discovery via RUNNER_GPU_* env, since register_runner auto-detects NVIDIA only (Intel runners otherwise show with no gpu field).

NVENC / CPU behavior is unchanged; VA-API is purely additive and opt-in via the encoder flags + Dockerfile.intel.

Test plan

Built Dockerfile.intel and ran the batch surface on an Intel Arc A770 (renderD129):

  • POST /transcode with an H264 + HEVC + AV1 ladder → all three renditions encode on the GPU, valid output (ffprobe confirms h264 / hevc / av1).
  • Full-GPU AV1, 60s 1080p source, 3-rendition ladder: 1 session 17.9x realtime; 10 concurrent sessions hold 2.7x realtime each (26.9x aggregate).
  • CPU: ~92% lower than the sw-decode path (decode + scale move onto the GPU), and faster wall-clock.

Notes

  • The Intel path uses VA-API for every codec (one consistent scale_vaapi + *_vaapi pipeline). scale_qsv + *_qsv is an alternative that also works on jellyfin-ffmpeg, but a single VA-API pipeline is simpler and covers H264/HEVC/AV1 uniformly. On distro ffmpeg both scale_vaapi and av1_qsv fail on Arc, which is why Dockerfile.intel uses jellyfin-ffmpeg.
  • No secrets or deployment-specific config included.

Adds a full-GPU Intel VA-API path alongside the existing NVENC / CPU
backends:

- h264_vaapi / hevc_vaapi / av1_vaapi encoders in profiles.py (CQP rate
  control; VA-surface pixel format), selected via the existing
  --h264/h265/av1-encoder flags.
- engine.py: -vaapi_device for GPU encode, and an optional HWACCEL_DECODE
  path (-hwaccel vaapi + scale_vaapi) that keeps decode + scale + encode
  all on the GPU. FFMPEG_BIN lets the image pick the ffmpeg build.
- Dockerfile.intel on jellyfin-ffmpeg — distro ffmpeg's scale_vaapi /
  av1_qsv are broken on Arc; the jellyfin build ships the patched iHD +
  oneVPL stack. docker-compose.intel.yml wires it up with --device /dev/dri.
- Dockerfile.gpu (NVENC CUDA base) to realize the README's "CUDA base" note.
- runner.py advertises a non-NVIDIA GPU to discovery via RUNNER_GPU_* env,
  since register_runner auto-detects only NVIDIA.

Verified on an Intel Arc A770: h264/hevc/av1 renditions all encode on the
GPU; 10 concurrent AV1 sessions hold 2.7x realtime with ~92% less CPU than
the sw-decode path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant