diff --git a/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj b/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj
index 430312c3b..46d72c573 100644
--- a/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj
+++ b/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj
@@ -16,7 +16,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/ErsatzTV.Core.Tests/FFmpeg/TranscodingTests.cs b/ErsatzTV.Core.Tests/FFmpeg/TranscodingTests.cs
index 000e3ccad..aa44bea8b 100644
--- a/ErsatzTV.Core.Tests/FFmpeg/TranscodingTests.cs
+++ b/ErsatzTV.Core.Tests/FFmpeg/TranscodingTests.cs
@@ -35,7 +35,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg;
public class TranscodingTests
{
private static readonly ILoggerFactory LoggerFactory;
- private static readonly MemoryCache _memoryCache;
+ private static readonly MemoryCache MemoryCache;
static TranscodingTests()
{
@@ -46,7 +46,7 @@ public class TranscodingTests
LoggerFactory = new LoggerFactory().AddSerilog(Log.Logger);
- _memoryCache = new MemoryCache(new MemoryCacheOptions());
+ MemoryCache = new MemoryCache(new MemoryCacheOptions());
}
[Test]
@@ -61,7 +61,13 @@ public class TranscodingTests
Assert.Pass();
}
- public record InputFormat(string Encoder, string PixelFormat);
+ public record InputFormat(
+ string Encoder,
+ string PixelFormat,
+ string ColorRange = "tv",
+ string ColorSpace = "bt709",
+ string ColorTransfer = "bt709",
+ string ColorPrimaries = "bt709");
public enum Padding
{
@@ -93,45 +99,47 @@ public class TranscodingTests
{
public static Watermark[] Watermarks =
{
- Watermark.None,
+ // Watermark.None,
Watermark.PermanentOpaqueScaled,
- Watermark.PermanentOpaqueActualSize,
- Watermark.PermanentTransparentScaled,
- Watermark.PermanentTransparentActualSize
+ // Watermark.PermanentOpaqueActualSize,
+ // Watermark.PermanentTransparentScaled,
+ // Watermark.PermanentTransparentActualSize
};
public static Subtitle[] Subtitles =
{
- Subtitle.None,
- Subtitle.Picture,
+ // Subtitle.None,
+ // Subtitle.Picture,
Subtitle.Text
};
public static Padding[] Paddings =
{
- Padding.NoPadding,
+ // Padding.NoPadding,
Padding.WithPadding
};
public static VideoScanKind[] VideoScanKinds =
{
VideoScanKind.Progressive,
- VideoScanKind.Interlaced
+ // VideoScanKind.Interlaced
};
public static InputFormat[] InputFormats =
{
- new("libx264", "yuv420p"),
+ // example format that requires colorspace filter
+ new("libx264", "yuv420p", "tv", "smpte170m", "bt709", "smpte170m"),
+
// new("libx264", "yuvj420p"),
- new("libx264", "yuv420p10le"),
+ // new("libx264", "yuv420p10le"),
// new("libx264", "yuv444p10le"),
// new("mpeg1video", "yuv420p"),
//
// new("mpeg2video", "yuv420p"),
- new("libx265", "yuv420p"),
- new("libx265", "yuv420p10le"),
+ // new("libx265", "yuv420p"),
+ // new("libx265", "yuv420p10le"),
// new("mpeg4", "yuv420p"),
//
@@ -148,14 +156,14 @@ public class TranscodingTests
public static Resolution[] Resolutions =
{
- new() { Width = 1920, Height = 1080 },
+ // new() { Width = 1920, Height = 1080 },
new() { Width = 1280, Height = 720 }
};
public static FFmpegProfileBitDepth[] BitDepths =
{
FFmpegProfileBitDepth.EightBit,
- FFmpegProfileBitDepth.TenBit
+ // FFmpegProfileBitDepth.TenBit
};
public static HardwareAccelerationKind[] NoAcceleration =
@@ -166,7 +174,7 @@ public class TranscodingTests
public static FFmpegProfileVideoFormat[] VideoFormats =
{
FFmpegProfileVideoFormat.H264,
- FFmpegProfileVideoFormat.Hevc
+ // FFmpegProfileVideoFormat.Hevc
};
public static HardwareAccelerationKind[] NvidiaAcceleration =
@@ -215,8 +223,8 @@ public class TranscodingTests
[ValueSource(typeof(TestData), nameof(TestData.VideoFormats))]
FFmpegProfileVideoFormat profileVideoFormat,
// [ValueSource(typeof(TestData), nameof(TestData.NoAcceleration))] HardwareAccelerationKind profileAcceleration)
- // [ValueSource(typeof(TestData), nameof(TestData.NvidiaAcceleration))] HardwareAccelerationKind profileAcceleration)
- [ValueSource(typeof(TestData), nameof(TestData.VaapiAcceleration))] HardwareAccelerationKind profileAcceleration)
+ [ValueSource(typeof(TestData), nameof(TestData.NvidiaAcceleration))] HardwareAccelerationKind profileAcceleration)
+ // [ValueSource(typeof(TestData), nameof(TestData.VaapiAcceleration))] HardwareAccelerationKind profileAcceleration)
// [ValueSource(typeof(TestData), nameof(TestData.QsvAcceleration))] HardwareAccelerationKind profileAcceleration)
// [ValueSource(typeof(TestData), nameof(TestData.VideoToolboxAcceleration))] HardwareAccelerationKind profileAcceleration)
// [ValueSource(typeof(TestData), nameof(TestData.AmfAcceleration))] HardwareAccelerationKind profileAcceleration)
@@ -230,7 +238,7 @@ public class TranscodingTests
}
}
- string name = GetStringSha256Hash($"{inputFormat.Encoder}_{inputFormat.PixelFormat}_{videoScanKind}_{padding}_{subtitle}");
+ string name = GetStringSha256Hash($"{inputFormat}_{videoScanKind}_{padding}_{subtitle}");
string file = Path.Combine(TestContext.CurrentContext.TestDirectory, $"{name}.mkv");
if (!File.Exists(file))
@@ -242,8 +250,24 @@ public class TranscodingTests
: string.Empty;
string flags = videoScanKind == VideoScanKind.Interlaced ? "-field_order tt -flags +ildct+ilme" : string.Empty;
+ string colorRange = !string.IsNullOrWhiteSpace(inputFormat.ColorRange)
+ ? $" -color_range {inputFormat.ColorRange}"
+ : string.Empty;
+
+ string colorSpace = !string.IsNullOrWhiteSpace(inputFormat.ColorSpace)
+ ? $" -colorspace {inputFormat.ColorSpace}"
+ : string.Empty;
+
+ string colorTransfer = !string.IsNullOrWhiteSpace(inputFormat.ColorTransfer)
+ ? $" -color_trc {inputFormat.ColorTransfer}"
+ : string.Empty;
+
+ string colorPrimaries = !string.IsNullOrWhiteSpace(inputFormat.ColorPrimaries)
+ ? $" -color_primaries {inputFormat.ColorPrimaries}"
+ : string.Empty;
+
string args =
- $"-y -f lavfi -i anoisesrc=color=brown -f lavfi -i testsrc=duration=1:size={resolution}:rate=30 {videoFilter} -c:a aac -c:v {inputFormat.Encoder} -shortest -pix_fmt {inputFormat.PixelFormat} -strict -2 {flags} {file}";
+ $"-y -f lavfi -i anoisesrc=color=brown -f lavfi -i testsrc=duration=1:size={resolution}:rate=30 {videoFilter} -c:a aac -c:v {inputFormat.Encoder}{colorRange}{colorSpace}{colorTransfer}{colorPrimaries} -shortest -pix_fmt {inputFormat.PixelFormat} -strict -2 {flags} {file}";
var p1 = new Process
{
StartInfo = new ProcessStartInfo
@@ -321,7 +345,7 @@ public class TranscodingTests
imageCache.Object,
new Mock().Object,
new Mock().Object,
- _memoryCache,
+ MemoryCache,
LoggerFactory.CreateLogger());
var service = new FFmpegLibraryProcessService(
@@ -333,7 +357,7 @@ public class TranscodingTests
new RuntimeInfo(),
//new FakeNvidiaCapabilitiesFactory(),
new HardwareCapabilitiesFactory(
- _memoryCache,
+ MemoryCache,
LoggerFactory.CreateLogger()),
LoggerFactory.CreateLogger()),
LoggerFactory.CreateLogger());
diff --git a/ErsatzTV.Core/ErsatzTV.Core.csproj b/ErsatzTV.Core/ErsatzTV.Core.csproj
index 0f7a6ce1b..cbf78ae95 100644
--- a/ErsatzTV.Core/ErsatzTV.Core.csproj
+++ b/ErsatzTV.Core/ErsatzTV.Core.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj b/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj
index e83c35dd6..4d350c09c 100644
--- a/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj
+++ b/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/ErsatzTV.FFmpeg/Filter/ColorspaceFilter.cs b/ErsatzTV.FFmpeg/Filter/ColorspaceFilter.cs
index 7973cf0de..0e6c855d7 100644
--- a/ErsatzTV.FFmpeg/Filter/ColorspaceFilter.cs
+++ b/ErsatzTV.FFmpeg/Filter/ColorspaceFilter.cs
@@ -4,17 +4,20 @@ namespace ErsatzTV.FFmpeg.Filter;
public class ColorspaceFilter : BaseFilter
{
+ private readonly FrameState _currentState;
private readonly VideoStream _videoStream;
private readonly IPixelFormat _desiredPixelFormat;
private readonly bool _forceInputOverrides;
private readonly FrameDataLocation _nextDataLocation;
public ColorspaceFilter(
+ FrameState currentState,
VideoStream videoStream,
IPixelFormat desiredPixelFormat,
bool forceInputOverrides = false,
FrameDataLocation nextDataLocation = FrameDataLocation.Software)
{
+ _currentState = currentState;
_videoStream = videoStream;
_desiredPixelFormat = desiredPixelFormat;
_forceInputOverrides = forceInputOverrides;
@@ -37,21 +40,33 @@ public class ColorspaceFilter : BaseFilter
{
get
{
+ string hwdownload = string.Empty;
+ if (_currentState.FrameDataLocation == FrameDataLocation.Hardware)
+ {
+ hwdownload = "hwdownload";
+ }
+
string inputOverrides = string.Empty;
ColorParams cp = _videoStream.ColorParams;
if (cp.IsMixed || _forceInputOverrides)
{
string range = string.IsNullOrWhiteSpace(cp.ColorRange) ? "tv" : cp.ColorRange;
+ string transfer = string.IsNullOrWhiteSpace(cp.ColorTransfer)
+ ? "bt709"
+ : cp.ColorTransfer;
+ string primaries = string.IsNullOrWhiteSpace(cp.ColorPrimaries)
+ ? "bt709"
+ : cp.ColorPrimaries;
inputOverrides =
- $"irange={range}:ispace={cp.ColorSpace}:itrc={cp.ColorTransfer}:iprimaries={cp.ColorPrimaries}:";
+ $"irange={range}:ispace={cp.ColorSpace}:itrc={transfer}:iprimaries={primaries}:";
}
string colorspace = _desiredPixelFormat.BitDepth switch
{
_ when cp.IsUnknown => "setparams=range=tv:colorspace=bt709:color_trc=bt709:color_primaries=bt709",
10 or 8 when !cp.IsUnknown =>
- $"colorspace={inputOverrides}all=bt709:format={_desiredPixelFormat.FFmpegName}",
+ $"{hwdownload},colorspace={inputOverrides}all=bt709:format={_desiredPixelFormat.FFmpegName}",
_ => string.Empty
};
diff --git a/ErsatzTV.FFmpeg/Filter/ComplexFilter.cs b/ErsatzTV.FFmpeg/Filter/ComplexFilter.cs
index cd607ff34..519279d67 100644
--- a/ErsatzTV.FFmpeg/Filter/ComplexFilter.cs
+++ b/ErsatzTV.FFmpeg/Filter/ComplexFilter.cs
@@ -317,7 +317,7 @@ public class ComplexFilter : IPipelineStep
if (!videoStream.ColorParams.IsBt709)
{
_logger.LogDebug("Adding colorspace filter");
- var colorspace = new ColorspaceFilter(videoStream, pixelFormat);
+ var colorspace = new ColorspaceFilter(_currentState, videoStream, pixelFormat);
_pipelineSteps.Add(colorspace);
filter = colorspace.Filter;
}
diff --git a/ErsatzTV.FFmpeg/Pipeline/AmfPipelineBuilder.cs b/ErsatzTV.FFmpeg/Pipeline/AmfPipelineBuilder.cs
index 2503ef563..bed01b179 100644
--- a/ErsatzTV.FFmpeg/Pipeline/AmfPipelineBuilder.cs
+++ b/ErsatzTV.FFmpeg/Pipeline/AmfPipelineBuilder.cs
@@ -93,7 +93,7 @@ public class AmfPipelineBuilder : SoftwarePipelineBuilder
if (!videoStream.ColorParams.IsBt709)
{
_logger.LogDebug("Adding colorspace filter");
- var colorspace = new ColorspaceFilter(videoStream, pixelFormat);
+ var colorspace = new ColorspaceFilter(currentState, videoStream, pixelFormat);
currentState = colorspace.NextState(currentState);
result.Add(colorspace);
}
diff --git a/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs b/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs
index 3c85d18da..8c5718d84 100644
--- a/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs
+++ b/ErsatzTV.FFmpeg/Pipeline/NvidiaPipelineBuilder.cs
@@ -181,7 +181,8 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder
// need to upload for any sort of overlay
if (currentState.FrameDataLocation == FrameDataLocation.Software &&
- currentState.BitDepth == 8 && (context.HasSubtitleOverlay || context.HasWatermark))
+ currentState.BitDepth == 8 && context.HasSubtitleText == false
+ && (context.HasSubtitleOverlay || context.HasWatermark))
{
var hardwareUpload = new HardwareUploadCudaFilter(currentState);
currentState = hardwareUpload.NextState(currentState);
@@ -268,7 +269,7 @@ public class NvidiaPipelineBuilder : SoftwarePipelineBuilder
if (!videoStream.ColorParams.IsBt709)
{
_logger.LogDebug("Adding colorspace filter");
- var colorspace = new ColorspaceFilter(videoStream, format, false, currentState.FrameDataLocation);
+ var colorspace = new ColorspaceFilter(currentState, videoStream, format, false, currentState.FrameDataLocation);
currentState = colorspace.NextState(currentState);
result.Add(colorspace);
diff --git a/ErsatzTV.FFmpeg/Pipeline/QsvPipelineBuilder.cs b/ErsatzTV.FFmpeg/Pipeline/QsvPipelineBuilder.cs
index 92e74972f..44fe515e4 100644
--- a/ErsatzTV.FFmpeg/Pipeline/QsvPipelineBuilder.cs
+++ b/ErsatzTV.FFmpeg/Pipeline/QsvPipelineBuilder.cs
@@ -246,6 +246,7 @@ public class QsvPipelineBuilder : SoftwarePipelineBuilder
bool forceInputOverrides = videoInputFile.FilterSteps.Any(f => f is QsvFormatFilter or ScaleQsvFilter);
var colorspace = new ColorspaceFilter(
+ currentState,
videoStream,
format,
forceInputOverrides,
diff --git a/ErsatzTV.FFmpeg/Pipeline/SoftwarePipelineBuilder.cs b/ErsatzTV.FFmpeg/Pipeline/SoftwarePipelineBuilder.cs
index 9db0f84f1..e98d48fc9 100644
--- a/ErsatzTV.FFmpeg/Pipeline/SoftwarePipelineBuilder.cs
+++ b/ErsatzTV.FFmpeg/Pipeline/SoftwarePipelineBuilder.cs
@@ -140,7 +140,7 @@ public class SoftwarePipelineBuilder : PipelineBuilderBase
if (!videoStream.ColorParams.IsBt709)
{
_logger.LogDebug("Adding colorspace filter");
- var colorspace = new ColorspaceFilter(videoStream, pixelFormat);
+ var colorspace = new ColorspaceFilter(currentState, videoStream, pixelFormat);
currentState = colorspace.NextState(currentState);
result.Add(colorspace);
}
diff --git a/ErsatzTV.FFmpeg/Pipeline/VaapiPipelineBuilder.cs b/ErsatzTV.FFmpeg/Pipeline/VaapiPipelineBuilder.cs
index 3ac365c0c..8f61decae 100644
--- a/ErsatzTV.FFmpeg/Pipeline/VaapiPipelineBuilder.cs
+++ b/ErsatzTV.FFmpeg/Pipeline/VaapiPipelineBuilder.cs
@@ -246,7 +246,12 @@ public class VaapiPipelineBuilder : SoftwarePipelineBuilder
if (!videoStream.ColorParams.IsBt709)
{
_logger.LogDebug("Adding colorspace filter");
- var colorspace = new ColorspaceFilter(videoStream, format, false, currentState.FrameDataLocation);
+ var colorspace = new ColorspaceFilter(
+ currentState,
+ videoStream,
+ format,
+ false,
+ currentState.FrameDataLocation);
currentState = colorspace.NextState(currentState);
result.Add(colorspace);
}
diff --git a/ErsatzTV.FFmpeg/Pipeline/VideoToolboxPipelineBuilder.cs b/ErsatzTV.FFmpeg/Pipeline/VideoToolboxPipelineBuilder.cs
index fc1de86d1..d51889cd2 100644
--- a/ErsatzTV.FFmpeg/Pipeline/VideoToolboxPipelineBuilder.cs
+++ b/ErsatzTV.FFmpeg/Pipeline/VideoToolboxPipelineBuilder.cs
@@ -114,7 +114,7 @@ public class VideoToolboxPipelineBuilder : SoftwarePipelineBuilder
if (!videoStream.ColorParams.IsBt709)
{
_logger.LogDebug("Adding colorspace filter");
- var colorspace = new ColorspaceFilter(videoStream, pixelFormat);
+ var colorspace = new ColorspaceFilter(currentState, videoStream, pixelFormat);
currentState = colorspace.NextState(currentState);
result.Add(colorspace);
}
diff --git a/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj b/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj
index b6bac8ad8..0c147cdca 100644
--- a/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj
+++ b/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/ErsatzTV/ErsatzTV.csproj b/ErsatzTV/ErsatzTV.csproj
index 3ed5475b1..52af8ea5d 100644
--- a/ErsatzTV/ErsatzTV.csproj
+++ b/ErsatzTV/ErsatzTV.csproj
@@ -70,7 +70,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+