diff --git a/ErsatzTV.Application/Streaming/Commands/StartFFmpegNextSessionHandler.cs b/ErsatzTV.Application/Streaming/Commands/StartFFmpegNextSessionHandler.cs index 81bb2eaeb..dcc8d3db2 100644 --- a/ErsatzTV.Application/Streaming/Commands/StartFFmpegNextSessionHandler.cs +++ b/ErsatzTV.Application/Streaming/Commands/StartFFmpegNextSessionHandler.cs @@ -348,6 +348,12 @@ public class StartFFmpegNextSessionHandler( Width = ffmpegProfile.Resolution.Width, BitrateKbps = ffmpegProfile.VideoBitrate, BufferKbps = ffmpegProfile.VideoBufferSize, + ScalingMode = ffmpegProfile.ScalingBehavior switch + { + ScalingBehavior.Stretch => ScalingMode.Stretch, + ScalingBehavior.Crop => ScalingMode.Crop, + _ => ScalingMode.ScaleAndPad + }, // TODO: NEXT: more tonemap algorithms TonemapAlgorithm = "linear", VaapiDevice = ffmpegProfile.VaapiDevice, diff --git a/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj b/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj index 20287e7a8..dba59bfc2 100644 --- a/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj +++ b/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj @@ -16,7 +16,7 @@ - + diff --git a/ErsatzTV.Core/Next/Config/ChannelConfig.cs b/ErsatzTV.Core/Next/Config/ChannelConfig.cs index 7b7eda95f..b9351939d 100644 --- a/ErsatzTV.Core/Next/Config/ChannelConfig.cs +++ b/ErsatzTV.Core/Next/Config/ChannelConfig.cs @@ -119,6 +119,9 @@ namespace ErsatzTV.Core.Next.Config [JsonProperty("height")] public long? Height { get; set; } + [JsonProperty("scaling_mode", NullValueHandling = NullValueHandling.Ignore)] + public ScalingMode? ScalingMode { get; set; } + [JsonProperty("tonemap_algorithm")] public string TonemapAlgorithm { get; set; } @@ -152,6 +155,8 @@ namespace ErsatzTV.Core.Next.Config public enum VideoFormat { H264, Hevc }; + public enum ScalingMode { Crop, ScaleAndPad, Stretch }; + public enum VaapiDriverEnum { I965, Ihd, Radeonsi }; public partial class ChannelConfig @@ -176,6 +181,7 @@ namespace ErsatzTV.Core.Next.Config ModeConverter.Singleton, AccelEnumConverter.Singleton, VideoFormatConverter.Singleton, + ScalingModeConverter.Singleton, VaapiDriverEnumConverter.Singleton, new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } }, @@ -361,6 +367,52 @@ namespace ErsatzTV.Core.Next.Config public static readonly VideoFormatConverter Singleton = new VideoFormatConverter(); } + internal class ScalingModeConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(ScalingMode) || t == typeof(ScalingMode?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize(reader); + switch (value) + { + case "crop": + return ScalingMode.Crop; + case "scale_and_pad": + return ScalingMode.ScaleAndPad; + case "stretch": + return ScalingMode.Stretch; + } + throw new Exception("Cannot unmarshal type ScalingMode"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (ScalingMode)untypedValue; + switch (value) + { + case ScalingMode.Crop: + serializer.Serialize(writer, "crop"); + return; + case ScalingMode.ScaleAndPad: + serializer.Serialize(writer, "scale_and_pad"); + return; + case ScalingMode.Stretch: + serializer.Serialize(writer, "stretch"); + return; + } + throw new Exception("Cannot marshal type ScalingMode"); + } + + public static readonly ScalingModeConverter Singleton = new ScalingModeConverter(); + } + internal class VaapiDriverEnumConverter : JsonConverter { public override bool CanConvert(Type t) => t == typeof(VaapiDriverEnum) || t == typeof(VaapiDriverEnum?); diff --git a/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj b/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj index 9c7508d5c..5d7dee790 100644 --- a/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj +++ b/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj b/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj index 78f7ca0a1..d89318fd2 100644 --- a/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj +++ b/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj @@ -14,7 +14,7 @@ - + diff --git a/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj b/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj index b77128c8a..6b0f7dc5e 100644 --- a/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj +++ b/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj @@ -11,9 +11,9 @@ - + - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj b/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj index 9d591d668..8bb380de5 100644 --- a/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj +++ b/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj @@ -12,9 +12,9 @@ - + - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ErsatzTV.Tests/ErsatzTV.Tests.csproj b/ErsatzTV.Tests/ErsatzTV.Tests.csproj index 4599a96c9..3d6148f94 100644 --- a/ErsatzTV.Tests/ErsatzTV.Tests.csproj +++ b/ErsatzTV.Tests/ErsatzTV.Tests.csproj @@ -11,8 +11,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ErsatzTV/ErsatzTV.csproj b/ErsatzTV/ErsatzTV.csproj index 10b7f08e1..20b03f4db 100644 --- a/ErsatzTV/ErsatzTV.csproj +++ b/ErsatzTV/ErsatzTV.csproj @@ -55,7 +55,7 @@ - +