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:
1 parent
78e36d8a6c
commit
be532725c8
1 file changed
+12
-2
+12
-2
@@ -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
|
||||
|
||||
Reference in new issue
Block a user