diff --git a/ErsatzTV.FFmpeg/Capabilities/NvidiaHardwareCapabilities.cs b/ErsatzTV.FFmpeg/Capabilities/NvidiaHardwareCapabilities.cs index 05867efcb..79a5e218c 100644 --- a/ErsatzTV.FFmpeg/Capabilities/NvidiaHardwareCapabilities.cs +++ b/ErsatzTV.FFmpeg/Capabilities/NvidiaHardwareCapabilities.cs @@ -95,6 +95,8 @@ public class NvidiaHardwareCapabilities : IHardwareCapabilities return isHardware ? FFmpegCapability.Hardware : FFmpegCapability.Software; } + public bool HevcBFrames => _architecture >= 75; + private FFmpegCapability CheckHardwareCodec(string codec, Func check) { if (check(codec)) diff --git a/ErsatzTV.FFmpeg/Encoder/Nvenc/EncoderHevcNvenc.cs b/ErsatzTV.FFmpeg/Encoder/Nvenc/EncoderHevcNvenc.cs index 83273abbc..0d88e74ec 100644 --- a/ErsatzTV.FFmpeg/Encoder/Nvenc/EncoderHevcNvenc.cs +++ b/ErsatzTV.FFmpeg/Encoder/Nvenc/EncoderHevcNvenc.cs @@ -1,13 +1,27 @@ -using ErsatzTV.FFmpeg.Format; +using ErsatzTV.FFmpeg.Capabilities; +using ErsatzTV.FFmpeg.Format; namespace ErsatzTV.FFmpeg.Encoder.Nvenc; public class EncoderHevcNvenc : EncoderBase { + private readonly bool _bFrames; + + public EncoderHevcNvenc(IHardwareCapabilities hardwareCapabilities) + { + if (hardwareCapabilities is NvidiaHardwareCapabilities nvidia) + { + _bFrames = nvidia.HevcBFrames; + } + } + public override string Name => "hevc_nvenc"; public override StreamKind Kind => StreamKind.Video; public override FrameState NextState(FrameState currentState) => currentState with { VideoFormat = VideoFormat.Hevc }; + + public override IList OutputOptions => + new[] { "-c:v", "hevc_nvenc", "-b_ref_mode", _bFrames ? "1" : "0" }; } diff --git a/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs b/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs index 17cdc88a7..093c4e57d 100644 --- a/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs +++ b/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs @@ -223,7 +223,7 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder Option maybeEncoder = (ffmpegState.EncoderHardwareAccelerationMode, desiredState.VideoFormat) switch { - (HardwareAccelerationMode.Nvenc, VideoFormat.Hevc) => new EncoderHevcNvenc(), + (HardwareAccelerationMode.Nvenc, VideoFormat.Hevc) => new EncoderHevcNvenc(_hardwareCapabilities), (HardwareAccelerationMode.Nvenc, VideoFormat.H264) => new EncoderH264Nvenc(), (_, _) => GetSoftwareEncoder(currentState, desiredState)