From 9596175f7fe2a40fe2f0c20772d373aa13150a0f Mon Sep 17 00:00:00 2001 From: Valentine Briese Date: Wed, 11 Oct 2023 18:24:45 -0700 Subject: [PATCH 1/3] Add FFmpeg Apple hardware acceleration --- crunchy-cli-core/src/utils/ffmpeg.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/utils/ffmpeg.rs b/crunchy-cli-core/src/utils/ffmpeg.rs index 210b0f7..3407d91 100644 --- a/crunchy-cli-core/src/utils/ffmpeg.rs +++ b/crunchy-cli-core/src/utils/ffmpeg.rs @@ -66,7 +66,8 @@ ffmpeg_enum! { ffmpeg_enum! { enum FFmpegHwAccel { - Nvidia + Nvidia, + Apple } } @@ -275,6 +276,9 @@ impl FFmpegPreset { ]); output.extend(["-c:v", "h264_nvenc", "-c:a", "copy"]) } + FFmpegHwAccel::Apple => { + output.extend(["-c:v", "h264_videotoolbox", "-c:a", "copy"]) + } } } else { output.extend(["-c:v", "libx264", "-c:a", "copy"]) @@ -300,6 +304,9 @@ impl FFmpegPreset { ]); output.extend(["-c:v", "hevc_nvenc", "-c:a", "copy"]) } + FFmpegHwAccel::Apple => { + output.extend(["-c:v", "hevc_videotoolbox", "-c:a", "copy"]) + } } } else { output.extend(["-c:v", "libx265", "-c:a", "copy"]) From 610593a79547b577b46707f996adefa7cf27db15 Mon Sep 17 00:00:00 2001 From: Valentine Briese Date: Wed, 11 Oct 2023 18:26:51 -0700 Subject: [PATCH 2/3] Make H265 codec compatible with Apple HEVC standards --- crunchy-cli-core/src/utils/ffmpeg.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/crunchy-cli-core/src/utils/ffmpeg.rs b/crunchy-cli-core/src/utils/ffmpeg.rs index 3407d91..6145fcf 100644 --- a/crunchy-cli-core/src/utils/ffmpeg.rs +++ b/crunchy-cli-core/src/utils/ffmpeg.rs @@ -302,14 +302,26 @@ impl FFmpegPreset { "-c:v", "h264_cuvid", ]); - output.extend(["-c:v", "hevc_nvenc", "-c:a", "copy"]) - } - FFmpegHwAccel::Apple => { - output.extend(["-c:v", "hevc_videotoolbox", "-c:a", "copy"]) + output.extend([ + "-c:v", + "hevc_nvenc", + "-c:a", + "copy", + "-tag:v", + "hvc1", + ]) } + FFmpegHwAccel::Apple => output.extend([ + "-c:v", + "hevc_videotoolbox", + "-c:a", + "copy", + "-tag:v", + "hvc1", + ]), } } else { - output.extend(["-c:v", "libx265", "-c:a", "copy"]) + output.extend(["-c:v", "libx265", "-c:a", "copy", "-tag:v", "hvc1"]) } match quality { From 7095e2b8b6464edeb9d79a21540365d02133a93b Mon Sep 17 00:00:00 2001 From: Valentine Briese Date: Wed, 11 Oct 2023 18:54:47 -0700 Subject: [PATCH 3/3] Use `-q:v` FFmpeg option for Apple hardware acceleration --- crunchy-cli-core/src/utils/ffmpeg.rs | 65 +++++++++++++++++++--------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/crunchy-cli-core/src/utils/ffmpeg.rs b/crunchy-cli-core/src/utils/ffmpeg.rs index 6145fcf..af29bfd 100644 --- a/crunchy-cli-core/src/utils/ffmpeg.rs +++ b/crunchy-cli-core/src/utils/ffmpeg.rs @@ -263,6 +263,12 @@ impl FFmpegPreset { match codec { FFmpegCodec::H264 => { + let mut crf_quality = || match quality { + FFmpegQuality::Lossless => output.extend(["-crf", "18"]), + FFmpegQuality::Normal => (), + FFmpegQuality::Low => output.extend(["-crf", "35"]), + }; + if let Some(hwaccel) = hwaccel_opt { match hwaccel { FFmpegHwAccel::Nvidia => { @@ -274,23 +280,37 @@ impl FFmpegPreset { "-c:v", "h264_cuvid", ]); + crf_quality(); output.extend(["-c:v", "h264_nvenc", "-c:a", "copy"]) } FFmpegHwAccel::Apple => { + // Apple's Video Toolbox encoders ignore `-crf`, + // use `-q:v` instead. It's on a scale of 1-100, + // 100 being lossless. Just did some math + // ((-a/51+1)*99+1 where `a` is the old crf value) + // so these settings very likely need some more + // tweeking. + match quality { + FFmpegQuality::Lossless => output.extend(["-q:v", "65"]), + FFmpegQuality::Normal => (), + FFmpegQuality::Low => output.extend(["-q:v", "32"]), + } + output.extend(["-c:v", "h264_videotoolbox", "-c:a", "copy"]) } } } else { + crf_quality(); output.extend(["-c:v", "libx264", "-c:a", "copy"]) } - - match quality { - FFmpegQuality::Lossless => output.extend(["-crf", "18"]), - FFmpegQuality::Normal => (), - FFmpegQuality::Low => output.extend(["-crf", "35"]), - } } FFmpegCodec::H265 => { + let mut crf_quality = || match quality { + FFmpegQuality::Lossless => output.extend(["-crf", "20"]), + FFmpegQuality::Normal => (), + FFmpegQuality::Low => output.extend(["-crf", "35"]), + }; + if let Some(hwaccel) = hwaccel_opt { match hwaccel { FFmpegHwAccel::Nvidia => { @@ -302,6 +322,7 @@ impl FFmpegPreset { "-c:v", "h264_cuvid", ]); + crf_quality(); output.extend([ "-c:v", "hevc_nvenc", @@ -311,24 +332,28 @@ impl FFmpegPreset { "hvc1", ]) } - FFmpegHwAccel::Apple => output.extend([ - "-c:v", - "hevc_videotoolbox", - "-c:a", - "copy", - "-tag:v", - "hvc1", - ]), + FFmpegHwAccel::Apple => { + // See the comment that starts on line 287. + match quality { + FFmpegQuality::Lossless => output.extend(["-q:v", "61"]), + FFmpegQuality::Normal => (), + FFmpegQuality::Low => output.extend(["-q:v", "32"]), + } + + output.extend([ + "-c:v", + "hevc_videotoolbox", + "-c:a", + "copy", + "-tag:v", + "hvc1", + ]) + } } } else { + crf_quality(); output.extend(["-c:v", "libx265", "-c:a", "copy", "-tag:v", "hvc1"]) } - - match quality { - FFmpegQuality::Lossless => output.extend(["-crf", "20"]), - FFmpegQuality::Normal => (), - FFmpegQuality::Low => output.extend(["-crf", "35"]), - } } FFmpegCodec::Av1 => { output.extend(["-c:v", "libsvtav1", "-c:a", "copy"]);