|
|
|
@ -110,51 +110,58 @@ public class TranscodingTests |
|
|
|
private class TestData |
|
|
|
private class TestData |
|
|
|
{ |
|
|
|
{ |
|
|
|
public static Watermark[] Watermarks = |
|
|
|
public static Watermark[] Watermarks = |
|
|
|
{ |
|
|
|
[ |
|
|
|
Watermark.None, |
|
|
|
Watermark.None |
|
|
|
Watermark.PermanentOpaqueScaled, |
|
|
|
//Watermark.PermanentOpaqueScaled,
|
|
|
|
// Watermark.PermanentOpaqueActualSize,
|
|
|
|
// Watermark.PermanentOpaqueActualSize,
|
|
|
|
Watermark.PermanentTransparentScaled |
|
|
|
//Watermark.PermanentTransparentScaled
|
|
|
|
// Watermark.PermanentTransparentActualSize
|
|
|
|
// Watermark.PermanentTransparentActualSize
|
|
|
|
}; |
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
public static Subtitle[] Subtitles = |
|
|
|
public static Subtitle[] Subtitles = |
|
|
|
{ |
|
|
|
[ |
|
|
|
Subtitle.None, |
|
|
|
Subtitle.None |
|
|
|
Subtitle.Picture, |
|
|
|
//Subtitle.Picture,
|
|
|
|
Subtitle.Text |
|
|
|
//Subtitle.Text
|
|
|
|
}; |
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
public static Padding[] Paddings = |
|
|
|
public static Padding[] Paddings = |
|
|
|
{ |
|
|
|
[ |
|
|
|
Padding.NoPadding, |
|
|
|
Padding.NoPadding, |
|
|
|
Padding.WithPadding |
|
|
|
Padding.WithPadding |
|
|
|
}; |
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static ScalingBehavior[] ScalingBehaviors = |
|
|
|
|
|
|
|
[ |
|
|
|
|
|
|
|
ScalingBehavior.ScaleAndPad, |
|
|
|
|
|
|
|
ScalingBehavior.Crop, |
|
|
|
|
|
|
|
//ScalingBehavior.Stretch
|
|
|
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
public static VideoScanKind[] VideoScanKinds = |
|
|
|
public static VideoScanKind[] VideoScanKinds = |
|
|
|
{ |
|
|
|
[ |
|
|
|
VideoScanKind.Progressive, |
|
|
|
VideoScanKind.Progressive |
|
|
|
VideoScanKind.Interlaced |
|
|
|
//VideoScanKind.Interlaced
|
|
|
|
}; |
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
public static InputFormat[] InputFormats = |
|
|
|
public static InputFormat[] InputFormats = |
|
|
|
{ |
|
|
|
[ |
|
|
|
// // // example format that requires colorspace filter
|
|
|
|
// // // example format that requires colorspace filter
|
|
|
|
new("libx264", "yuv420p", "tv", "smpte170m", "bt709", "smpte170m"), |
|
|
|
// new("libx264", "yuv420p", "tv", "smpte170m", "bt709", "smpte170m"),
|
|
|
|
// //
|
|
|
|
// // //
|
|
|
|
// // // example format that requires setparams filter
|
|
|
|
// // // // example format that requires setparams filter
|
|
|
|
new("libx264", "yuv420p", string.Empty, string.Empty, string.Empty, string.Empty), |
|
|
|
// new("libx264", "yuv420p", string.Empty, string.Empty, string.Empty, string.Empty),
|
|
|
|
// //
|
|
|
|
|
|
|
|
// // // new("libx264", "yuvj420p"),
|
|
|
|
|
|
|
|
new("libx264", "yuv420p10le"), |
|
|
|
|
|
|
|
// // // new("libx264", "yuv444p10le"),
|
|
|
|
|
|
|
|
// //
|
|
|
|
|
|
|
|
// // // new("mpeg1video", "yuv420p"),
|
|
|
|
|
|
|
|
// // //
|
|
|
|
// // //
|
|
|
|
new("mpeg2video", "yuv420p"), |
|
|
|
// // // // new("libx264", "yuvj420p"),
|
|
|
|
|
|
|
|
// new("libx264", "yuv420p10le"),
|
|
|
|
|
|
|
|
// // // // new("libx264", "yuv444p10le"),
|
|
|
|
|
|
|
|
// // //
|
|
|
|
|
|
|
|
// // // // new("mpeg1video", "yuv420p"),
|
|
|
|
|
|
|
|
// // // //
|
|
|
|
|
|
|
|
// new("mpeg2video", "yuv420p"),
|
|
|
|
// //
|
|
|
|
// //
|
|
|
|
new("libx265", "yuv420p"), |
|
|
|
new InputFormat("libx265", "yuv420p") |
|
|
|
new("libx265", "yuv420p10le") |
|
|
|
// new("libx265", "yuv420p10le")
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// new("mpeg4", "yuv420p"),
|
|
|
|
// new("mpeg4", "yuv420p"),
|
|
|
|
//
|
|
|
|
//
|
|
|
|
@ -168,38 +175,39 @@ public class TranscodingTests |
|
|
|
// new("msmpeg4v3", "yuv420p")
|
|
|
|
// new("msmpeg4v3", "yuv420p")
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// // wmv3 yuv420p 1
|
|
|
|
// // wmv3 yuv420p 1
|
|
|
|
}; |
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
public static Resolution[] Resolutions = |
|
|
|
public static Resolution[] Resolutions = |
|
|
|
{ |
|
|
|
[ |
|
|
|
new() { Width = 1920, Height = 1080 }, |
|
|
|
new Resolution { Width = 1920, Height = 1080 }, |
|
|
|
new() { Width = 1280, Height = 720 } |
|
|
|
new Resolution { Width = 1280, Height = 720 }, |
|
|
|
}; |
|
|
|
new Resolution { Width = 640, Height = 480 } |
|
|
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
public static FFmpegProfileBitDepth[] BitDepths = |
|
|
|
public static FFmpegProfileBitDepth[] BitDepths = |
|
|
|
{ |
|
|
|
[ |
|
|
|
FFmpegProfileBitDepth.EightBit, |
|
|
|
FFmpegProfileBitDepth.EightBit |
|
|
|
FFmpegProfileBitDepth.TenBit |
|
|
|
//FFmpegProfileBitDepth.TenBit
|
|
|
|
}; |
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
public static FFmpegProfileVideoFormat[] VideoFormats = |
|
|
|
public static FFmpegProfileVideoFormat[] VideoFormats = |
|
|
|
{ |
|
|
|
[ |
|
|
|
FFmpegProfileVideoFormat.H264, |
|
|
|
FFmpegProfileVideoFormat.H264, |
|
|
|
FFmpegProfileVideoFormat.Hevc |
|
|
|
FFmpegProfileVideoFormat.Hevc |
|
|
|
// FFmpegProfileVideoFormat.Mpeg2Video
|
|
|
|
// FFmpegProfileVideoFormat.Mpeg2Video
|
|
|
|
}; |
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
public static HardwareAccelerationKind[] TestAccelerations = |
|
|
|
public static HardwareAccelerationKind[] TestAccelerations = |
|
|
|
{ |
|
|
|
[ |
|
|
|
HardwareAccelerationKind.None, |
|
|
|
HardwareAccelerationKind.None, |
|
|
|
// HardwareAccelerationKind.Nvenc,
|
|
|
|
HardwareAccelerationKind.Nvenc, |
|
|
|
HardwareAccelerationKind.Vaapi |
|
|
|
//HardwareAccelerationKind.Vaapi,
|
|
|
|
// HardwareAccelerationKind.Qsv
|
|
|
|
HardwareAccelerationKind.Qsv, |
|
|
|
// HardwareAccelerationKind.VideoToolbox,
|
|
|
|
// HardwareAccelerationKind.VideoToolbox,
|
|
|
|
// HardwareAccelerationKind.Amf
|
|
|
|
// HardwareAccelerationKind.Amf
|
|
|
|
}; |
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
public static string[] FilesToTest => new[] { string.Empty }; |
|
|
|
public static string[] FilesToTest => [string.Empty]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
[Test] |
|
|
|
@ -388,6 +396,8 @@ public class TranscodingTests |
|
|
|
FFmpegProfileBitDepth profileBitDepth, |
|
|
|
FFmpegProfileBitDepth profileBitDepth, |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.Paddings))] |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.Paddings))] |
|
|
|
Padding padding, |
|
|
|
Padding padding, |
|
|
|
|
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.ScalingBehaviors))] |
|
|
|
|
|
|
|
ScalingBehavior scalingBehavior, |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.VideoScanKinds))] |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.VideoScanKinds))] |
|
|
|
VideoScanKind videoScanKind, |
|
|
|
VideoScanKind videoScanKind, |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.Watermarks))] |
|
|
|
[ValueSource(typeof(TestData), nameof(TestData.Watermarks))] |
|
|
|
@ -415,22 +425,19 @@ public class TranscodingTests |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
string name = GetStringSha256Hash($"{inputFormat}_{videoScanKind}_{padding}_{subtitle}"); |
|
|
|
string name = GetStringSha256Hash($"{inputFormat}_{videoScanKind}_{padding}_{scalingBehavior}_{subtitle}"); |
|
|
|
|
|
|
|
|
|
|
|
file = Path.Combine(TestContext.CurrentContext.TestDirectory, $"{name}.mkv"); |
|
|
|
file = Path.Combine(TestContext.CurrentContext.TestDirectory, $"{name}.mkv"); |
|
|
|
if (!File.Exists(file)) |
|
|
|
if (!File.Exists(file)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
await GenerateTestFile(inputFormat, padding, videoScanKind, subtitle, file); |
|
|
|
await GenerateTestFile(inputFormat, padding, scalingBehavior, videoScanKind, subtitle, file); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var v = new MediaVersion |
|
|
|
var v = new MediaVersion |
|
|
|
{ |
|
|
|
{ |
|
|
|
MediaFiles = new List<MediaFile> |
|
|
|
MediaFiles = [new MediaFile { Path = file }], |
|
|
|
{ |
|
|
|
Streams = [] |
|
|
|
new() { Path = file } |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Streams = new List<MediaStream>() |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
IMetadataRepository? metadataRepository = Substitute.For<IMetadataRepository>(); |
|
|
|
IMetadataRepository? metadataRepository = Substitute.For<IMetadataRepository>(); |
|
|
|
@ -552,7 +559,7 @@ public class TranscodingTests |
|
|
|
.Any(); |
|
|
|
.Any(); |
|
|
|
|
|
|
|
|
|
|
|
// TODO: sometimes scaling is used for pixel format, so this is harder to assert the absence
|
|
|
|
// TODO: sometimes scaling is used for pixel format, so this is harder to assert the absence
|
|
|
|
if (profileResolution.Width != 1920) |
|
|
|
if (profileResolution.Width != 1920 && profileResolution.Width != 640) |
|
|
|
{ |
|
|
|
{ |
|
|
|
hasScaling.Should().BeTrue(); |
|
|
|
hasScaling.Should().BeTrue(); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -563,11 +570,17 @@ public class TranscodingTests |
|
|
|
|
|
|
|
|
|
|
|
// TODO: optimize out padding
|
|
|
|
// TODO: optimize out padding
|
|
|
|
// hasPadding.Should().Be(padding == Padding.WithPadding);
|
|
|
|
// hasPadding.Should().Be(padding == Padding.WithPadding);
|
|
|
|
if (padding == Padding.WithPadding) |
|
|
|
if (padding is Padding.WithPadding && scalingBehavior is not ScalingBehavior.Crop) |
|
|
|
{ |
|
|
|
{ |
|
|
|
hasPadding.Should().BeTrue(); |
|
|
|
hasPadding.Should().BeTrue(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool hasCrop = filterChain.VideoFilterSteps.Any(s => s is CropFilter); |
|
|
|
|
|
|
|
if (scalingBehavior is ScalingBehavior.Crop) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
hasCrop.Should().BeTrue(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool hasSubtitleFilters = |
|
|
|
bool hasSubtitleFilters = |
|
|
|
filterChain.VideoFilterSteps.Any(s => s is SubtitlesFilter) || |
|
|
|
filterChain.VideoFilterSteps.Any(s => s is SubtitlesFilter) || |
|
|
|
filterChain.SubtitleOverlayFilterSteps.Any( |
|
|
|
filterChain.SubtitleOverlayFilterSteps.Any( |
|
|
|
@ -599,7 +612,8 @@ public class TranscodingTests |
|
|
|
VideoFormat = profileVideoFormat, |
|
|
|
VideoFormat = profileVideoFormat, |
|
|
|
AudioFormat = FFmpegProfileAudioFormat.Aac, |
|
|
|
AudioFormat = FFmpegProfileAudioFormat.Aac, |
|
|
|
DeinterlaceVideo = true, |
|
|
|
DeinterlaceVideo = true, |
|
|
|
BitDepth = profileBitDepth |
|
|
|
BitDepth = profileBitDepth, |
|
|
|
|
|
|
|
ScalingBehavior = scalingBehavior |
|
|
|
}, |
|
|
|
}, |
|
|
|
StreamingMode = StreamingMode.TransportStream, |
|
|
|
StreamingMode = StreamingMode.TransportStream, |
|
|
|
SubtitleMode = subtitleMode |
|
|
|
SubtitleMode = subtitleMode |
|
|
|
@ -711,11 +725,18 @@ public class TranscodingTests |
|
|
|
private static async Task GenerateTestFile( |
|
|
|
private static async Task GenerateTestFile( |
|
|
|
InputFormat inputFormat, |
|
|
|
InputFormat inputFormat, |
|
|
|
Padding padding, |
|
|
|
Padding padding, |
|
|
|
|
|
|
|
ScalingBehavior scalingBehavior, |
|
|
|
VideoScanKind videoScanKind, |
|
|
|
VideoScanKind videoScanKind, |
|
|
|
Subtitle subtitle, |
|
|
|
Subtitle subtitle, |
|
|
|
string file) |
|
|
|
string file) |
|
|
|
{ |
|
|
|
{ |
|
|
|
string resolution = padding == Padding.WithPadding ? "1920x1060" : "1920x1080"; |
|
|
|
string resolution = (scalingBehavior, padding) switch |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
(ScalingBehavior.Crop, Padding.NoPadding) => "1920x1080", |
|
|
|
|
|
|
|
// TODO: (ScalingBehavior.Crop, Padding.WithPadding) => "632x480",
|
|
|
|
|
|
|
|
(ScalingBehavior.Stretch or ScalingBehavior.ScaleAndPad, Padding.WithPadding) => "1920x1060", |
|
|
|
|
|
|
|
_ => "1920x1080" |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
string videoFilter = videoScanKind == VideoScanKind.Interlaced |
|
|
|
string videoFilter = videoScanKind == VideoScanKind.Interlaced |
|
|
|
? "-vf interlace=scan=tff:lowpass=complex" |
|
|
|
? "-vf interlace=scan=tff:lowpass=complex" |
|
|
|
@ -954,16 +975,13 @@ public class TranscodingTests |
|
|
|
ExecutableName("ffprobe"), |
|
|
|
ExecutableName("ffprobe"), |
|
|
|
new Movie |
|
|
|
new Movie |
|
|
|
{ |
|
|
|
{ |
|
|
|
MediaVersions = new List<MediaVersion> |
|
|
|
MediaVersions = |
|
|
|
{ |
|
|
|
[ |
|
|
|
new() |
|
|
|
new MediaVersion |
|
|
|
{ |
|
|
|
{ |
|
|
|
MediaFiles = new List<MediaFile> |
|
|
|
MediaFiles = [new MediaFile { Path = tempFile }] |
|
|
|
{ |
|
|
|
|
|
|
|
new() { Path = tempFile } |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
] |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
MediaVersion v = getFinalMediaVersion(); |
|
|
|
MediaVersion v = getFinalMediaVersion(); |
|
|
|
|