using ErsatzTV.Core.FFmpeg; using NUnit.Framework; using Shouldly; namespace ErsatzTV.Core.Tests.FFmpeg; [TestFixture] public class ColdStartFeaturesTests { [Test] public void Should_Detect_Subtitle_BurnIn_From_Subtitles_Filter() { const string Args = "-i ep.mkv -filter_complex \"[0:0]subtitles=http://localhost:8409/media/subtitle/1.ass[v]\" " + "-c:v h264_vaapi -f hls"; ColdStartFeatures features = ColdStartFeatures.FromFFmpegArguments(Args); features.SubtitleBurnIn.ShouldBeTrue(); } [Test] public void Should_Not_Flag_Subtitle_BurnIn_For_Copy_Or_Overlay() { // subtitle stream copy (-c:s) and a watermark/image-subtitle overlay must NOT be read as burn-in const string Args = "-i ep.mkv -filter_complex \"[v][wm]overlay=10:10:format=0[vwm]\" -c:s copy -c:v libx264 -f hls"; ColdStartFeatures features = ColdStartFeatures.FromFFmpegArguments(Args); features.SubtitleBurnIn.ShouldBeFalse(); } [TestCase("-c:v h264_vaapi -f hls", "vaapi")] [TestCase("-c:v hevc_vaapi -f hls", "vaapi")] [TestCase("-c:v h264_nvenc -f hls", "nvenc")] [TestCase("-c:v h264_qsv -f hls", "qsv")] [TestCase("-c:v h264_videotoolbox -f hls", "videotoolbox")] [TestCase("-c:v h264_amf -f hls", "amf")] public void Should_Detect_Hardware_Family_From_Encoder(string args, string expected) { ColdStartFeatures features = ColdStartFeatures.FromFFmpegArguments(args); features.HardwareAcceleration.ShouldBe(expected); } [Test] public void Should_Detect_Hardware_Family_From_Vaapi_Filter_Even_Without_Encoder_Token() { // a vaapi-accelerated pipeline surfaces the family via filters (e.g. scale_vaapi) too const string Args = "-hwaccel vaapi -i ep.mkv -vf scale_vaapi=1920:1080 -f hls"; ColdStartFeatures features = ColdStartFeatures.FromFFmpegArguments(Args); features.HardwareAcceleration.ShouldBe("vaapi"); } [Test] public void Should_Fall_Back_To_Hwaccel_Flag_When_No_Hardware_Encoder_Or_Filter() { // hardware decode, software encode: attribute the decode accel const string Args = "-hwaccel cuda -i ep.mkv -c:v libx264 -f hls"; ColdStartFeatures features = ColdStartFeatures.FromFFmpegArguments(Args); features.HardwareAcceleration.ShouldBe("cuda"); } [Test] public void Should_Report_Software_When_No_Acceleration() { const string Args = "-i ep.mkv -c:v libx264 -c:a aac -f hls"; ColdStartFeatures features = ColdStartFeatures.FromFFmpegArguments(Args); features.SubtitleBurnIn.ShouldBeFalse(); features.HardwareAcceleration.ShouldBe("software"); } [TestCase("")] [TestCase(" ")] [TestCase(null)] public void Should_Report_Unknown_For_Empty_Arguments(string args) { ColdStartFeatures features = ColdStartFeatures.FromFFmpegArguments(args); features.SubtitleBurnIn.ShouldBeFalse(); features.HardwareAcceleration.ShouldBe("unknown"); } }