aboutsummaryrefslogtreecommitdiff
path: root/tests/Jellyfin.Controller.Tests/MediaEncoding
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Jellyfin.Controller.Tests/MediaEncoding')
-rw-r--r--tests/Jellyfin.Controller.Tests/MediaEncoding/EncodingHelperTests.cs60
-rw-r--r--tests/Jellyfin.Controller.Tests/MediaEncoding/TranscodingJobTests.cs56
2 files changed, 116 insertions, 0 deletions
diff --git a/tests/Jellyfin.Controller.Tests/MediaEncoding/EncodingHelperTests.cs b/tests/Jellyfin.Controller.Tests/MediaEncoding/EncodingHelperTests.cs
index 2b009b4673..aca55fbcc1 100644
--- a/tests/Jellyfin.Controller.Tests/MediaEncoding/EncodingHelperTests.cs
+++ b/tests/Jellyfin.Controller.Tests/MediaEncoding/EncodingHelperTests.cs
@@ -261,6 +261,66 @@ public class EncodingHelperTests
Assert.Contains("-ar 48000", args, StringComparison.Ordinal);
}
+ [Fact]
+ public void GetProgressiveAudioFullCommandLine_StereoDownmix_AppliesDownMixAlgorithm()
+ {
+ // Issue #18194: -ac 2 alone drops the LFE channel, the configured downmix filter must be applied.
+ var state = BuildAudioState("aac", 48000);
+ state.AudioStream.Channels = 6;
+ state.AudioStream.ChannelLayout = "5.1";
+ state.OutputAudioChannels = 2;
+ var options = new EncodingOptions { DownMixStereoAlgorithm = DownMixStereoAlgorithms.Dave750, DownMixAudioBoost = 1 };
+ var args = CreateHelper().GetProgressiveAudioFullCommandLine(state, options, "/tmp/out");
+
+ Assert.Contains(
+ "-af \"" + DownMixAlgorithmsHelper.AlgorithmFilterStrings[(DownMixStereoAlgorithms.Dave750, "5.1")] + "\"",
+ args,
+ StringComparison.Ordinal);
+ }
+
+ [Fact]
+ public void GetProgressiveAudioFullCommandLine_NoDownmix_EmitsNoAudioFilter()
+ {
+ var state = BuildAudioState("aac", 48000);
+ state.AudioStream.Channels = 2;
+ state.OutputAudioChannels = 2;
+ var options = new EncodingOptions { DownMixStereoAlgorithm = DownMixStereoAlgorithms.Dave750 };
+ var args = CreateHelper().GetProgressiveAudioFullCommandLine(state, options, "/tmp/out");
+
+ Assert.DoesNotContain("-af", args, StringComparison.Ordinal);
+ }
+
+ [Theory]
+ [InlineData(1)]
+ [InlineData(6)]
+ public void GetProgressiveVideoAudioArguments_NonStereoOutput_KeepsChannelCount(int outputChannels)
+ {
+ // The downmix filter only applies to stereo output, so -ac must not be dropped otherwise.
+ var state = BuildAudioState("aac", 48000);
+ state.AudioStream.Channels = 6;
+ state.AudioStream.ChannelLayout = "5.1";
+ state.OutputAudioChannels = outputChannels;
+ var options = new EncodingOptions { DownMixStereoAlgorithm = DownMixStereoAlgorithms.Dave750 };
+ var args = CreateHelper().GetProgressiveVideoAudioArguments(state, options);
+
+ Assert.Contains("-ac " + outputChannels, args, StringComparison.Ordinal);
+ Assert.DoesNotContain("pan=", args, StringComparison.Ordinal);
+ }
+
+ [Fact]
+ public void GetProgressiveVideoAudioArguments_StereoDownmix_UsesFilterInsteadOfChannelCount()
+ {
+ var state = BuildAudioState("aac", 48000);
+ state.AudioStream.Channels = 6;
+ state.AudioStream.ChannelLayout = "5.1";
+ state.OutputAudioChannels = 2;
+ var options = new EncodingOptions { DownMixStereoAlgorithm = DownMixStereoAlgorithms.Dave750 };
+ var args = CreateHelper().GetProgressiveVideoAudioArguments(state, options);
+
+ Assert.DoesNotContain("-ac ", args, StringComparison.Ordinal);
+ Assert.Contains("pan=stereo", args, StringComparison.Ordinal);
+ }
+
private static EncodingJobInfo BuildAudioState(string audioCodec, int requestedSampleRate, string? outputContainer = null)
{
var audio = new MediaStream { Index = 0, Type = MediaStreamType.Audio, Codec = "flac", SampleRate = 96000 };
diff --git a/tests/Jellyfin.Controller.Tests/MediaEncoding/TranscodingJobTests.cs b/tests/Jellyfin.Controller.Tests/MediaEncoding/TranscodingJobTests.cs
new file mode 100644
index 0000000000..9dc279a5b2
--- /dev/null
+++ b/tests/Jellyfin.Controller.Tests/MediaEncoding/TranscodingJobTests.cs
@@ -0,0 +1,56 @@
+using System;
+using MediaBrowser.Controller.MediaEncoding;
+using Microsoft.Extensions.Logging.Abstractions;
+using Xunit;
+
+namespace Jellyfin.Controller.Tests.MediaEncoding;
+
+public class TranscodingJobTests
+{
+ private static TranscodingJob CreateJob()
+ => new TranscodingJob(NullLogger<TranscodingJob>.Instance);
+
+ [Fact]
+ public void GetHighestServedSegmentIndexEndingAtOrBefore_NoSegmentsServed_ReturnsNull()
+ {
+ using var job = CreateJob();
+
+ Assert.Null(job.GetHighestServedSegmentIndexEndingAtOrBefore(TimeSpan.FromHours(1).Ticks));
+ }
+
+ [Fact]
+ public void GetHighestServedSegmentIndexEndingAtOrBefore_InitSegment_IsIgnored()
+ {
+ using var job = CreateJob();
+ job.ReportSegmentDownloaded(-1, 0);
+
+ Assert.Null(job.GetHighestServedSegmentIndexEndingAtOrBefore(TimeSpan.FromHours(1).Ticks));
+ }
+
+ [Fact]
+ public void GetHighestServedSegmentIndexEndingAtOrBefore_SegmentEndingExactlyAtPosition_IsIncluded()
+ {
+ using var job = CreateJob();
+ job.ReportSegmentDownloaded(0, TimeSpan.FromSeconds(6).Ticks);
+ job.ReportSegmentDownloaded(1, TimeSpan.FromSeconds(12).Ticks);
+
+ Assert.Equal(1, job.GetHighestServedSegmentIndexEndingAtOrBefore(TimeSpan.FromSeconds(12).Ticks));
+ Assert.Equal(0, job.GetHighestServedSegmentIndexEndingAtOrBefore(TimeSpan.FromSeconds(11.9).Ticks));
+ }
+
+ [Fact]
+ public void GetHighestServedSegmentIndexEndingAtOrBefore_SegmentsLongerThanDesired_ReturnsServedIndex()
+ {
+ // Keyframe-based playlists average longer segments than the desired 6s.
+ const double SegmentSeconds = 6.6;
+ using var job = CreateJob();
+ for (var i = 0; i < 520; i++)
+ {
+ job.ReportSegmentDownloaded(i, TimeSpan.FromSeconds((i + 1) * SegmentSeconds).Ticks);
+ }
+
+ var keepFrom = TimeSpan.FromSeconds((520 * SegmentSeconds) - 120);
+
+ Assert.Equal(500, job.GetHighestServedSegmentIndexEndingAtOrBefore(keepFrom.Ticks));
+ }
+}