Skip to content

fix(transcode): only pick a GPU encoder when its device is present#5

Merged
ohugonnot merged 1 commit into
masterfrom
fix/hw-encoder-detection
May 29, 2026
Merged

fix(transcode): only pick a GPU encoder when its device is present#5
ohugonnot merged 1 commit into
masterfrom
fix/hw-encoder-detection

Conversation

@ohugonnot

Copy link
Copy Markdown
Owner

Symptom

On a server without an NVIDIA GPU, transcoding fails and the player shows "invalid video source / server unreachable." The stream log shows hw=nvenc, and ffmpeg's error log:

[h264_nvenc] Cannot load libcuda.so.1
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0

Root cause

detect_hw_encoder() in auto mode picked nvenc as soon as ffmpeg -encoders listed h264_nvenc — but that encoder is compiled into many ffmpeg builds regardless of hardware. So on a GPU-less host it chose nvenc, which then failed at runtime (no libcuda.so.1). VAAPI already guarded on its device file; nvenc and v4l2m2m didn't.

Fix

  • nvenc now requires a real device: /dev/nvidia0 or /dev/nvidiactl.
  • v4l2m2m now requires /dev/video10 and the encoder (was ||).
  • auto correctly falls back to software (libx264) when no usable device exists.
  • Explicit FFMPEG_HW_ACCEL=nvenc|vaapi|v4l2m2m still forces a backend for non-standard setups (the override path is unchanged).

Added HwAccelTest::testGpuBackendChosenOnlyWhenDevicePresent — would have failed before this fix on the affected server.

phpunit 442/887 green · PHPStan level 5 clean.

🤖 Generated with Claude Code

…resent

detect_hw_encoder() in 'auto' mode picked nvenc as soon as ffmpeg *listed*
h264_nvenc — even on a host with no NVIDIA GPU. The encoder is compiled into many
ffmpeg builds, so on a GPU-less server transcoding failed at runtime with
"[h264_nvenc] Cannot load libcuda.so.1 / Error initializing output stream", and
the player showed "invalid video source". Observed in production (no GPU, ffmpeg
shipping nvenc).

Now nvenc requires a real NVIDIA device (/dev/nvidia0 or /dev/nvidiactl) and
v4l2m2m requires /dev/video10 — mirroring the device check VAAPI already does.
'auto' falls back to software (libx264) when no usable device exists. Explicit
FFMPEG_HW_ACCEL still forces a backend for non-standard setups.

Added HwAccelTest::testGpuBackendChosenOnlyWhenDevicePresent locking the invariant.
phpunit 442/887 green, PHPStan clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ohugonnot ohugonnot merged commit e9f6b49 into master May 29, 2026
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.

2 participants