diff options
Diffstat (limited to 'tests/Jellyfin.Controller.Tests/MediaEncoding')
| -rw-r--r-- | tests/Jellyfin.Controller.Tests/MediaEncoding/EncodingHelperTests.cs | 60 | ||||
| -rw-r--r-- | tests/Jellyfin.Controller.Tests/MediaEncoding/TranscodingJobTests.cs | 56 |
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)); + } +} |
