perf(video): decode HLS transcode sources on the GPU

When NVENC is available the HLS transcode encoded on the GPU but still
decoded on the CPU, since the command had no -hwaccel. Rebuilding the
4K homemade videos ran three ffmpegs at 210-240% CPU each with the
machine at 0% idle, while NVDEC sat at 0%.

Pass -hwaccel cuda when transcoding with NVENC, as generate_preview_clip
already does. Frames return to system memory, so autorotate and the
scale filter work unchanged; NVDEC-unsupported codecs fall back to
software decode.

10 s of 4K H.264 (2025-USAF-MuseumRace.mp4): 27.3 s -> 6.1 s CPU,
9.6 s -> 3.6 s wall, identical output (1920x1080, 245 frames, 3 s
segments). Also checked a 90-degree-rotated phone clip (comes out
1080x1440 upright, 233/233 frames) and ProRes (software fallback,
correct output).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Cameron CordesandClaude Opus 5.5 committed 2026-10-13 12:12:08 -04:00
1 parent 78e36d8a6c
commit be532725c8
1 file changed
+12 -2
+12 -2
View File
@@ -633,14 +633,24 @@ impl Handler<GeneratePlaylistMessage> for PlaylistGenerator {
// ffmpeg writes them next to the playlist (relative refs).
let playlist_tmp = format!("{}.tmp", playlist_file);
let nvenc = !use_copy && crate::video::ffmpeg::is_nvenc_available().await;
let mut cmd = tokio::process::Command::new("ffmpeg");
cmd.arg("-y").arg("-i").arg(&video_file);
cmd.arg("-y");
if nvenc {
// Decode on NVDEC too. Without it a 4K source is decoded on
// the CPU and only the encode runs on the GPU: ~4.5x the CPU
// time. Frames come back to system memory, so the CPU
// filters (autorotate, scale) still apply, and ffmpeg falls
// back to software decode for codecs NVDEC lacks (ProRes).
cmd.arg("-hwaccel").arg("cuda");
}
cmd.arg("-i").arg(&video_file);
if use_copy {
cmd.arg("-c:v").arg("copy");
cmd.arg("-c:a").arg("aac");
} else {
let nvenc = crate::video::ffmpeg::is_nvenc_available().await;
if nvenc {
// NVENC: no CRF, use VBR + target CQ. p1 = fastest
// preset — prioritizes encoder throughput over bitrate