ソースを参照

Add ComputeSegments test

cvium 3 年 前
コミット
64a13a5d42

+ 6 - 1
src/Jellyfin.MediaEncoding.Hls/Playlist/DynamicHlsPlaylistGenerator.cs

@@ -198,6 +198,11 @@ namespace Jellyfin.MediaEncoding.Hls.Playlist
 
         internal static IReadOnlyList<double> ComputeSegments(KeyframeData keyframeData, int desiredSegmentLengthMs)
         {
+            if (keyframeData.KeyframeTicks.Count > 0 && keyframeData.TotalDuration < keyframeData.KeyframeTicks[^1])
+            {
+                throw new ArgumentException("Invalid duration in keyframe data", nameof(keyframeData));
+            }
+
             long lastKeyframe = 0;
             var result = new List<double>();
             // Scale the segment length to ticks to match the keyframes
@@ -219,7 +224,7 @@ namespace Jellyfin.MediaEncoding.Hls.Playlist
             return result;
         }
 
-        internal static double[] ComputeEqualLengthSegments(long desiredSegmentLengthMs, long totalRuntimeTicks)
+        internal static double[] ComputeEqualLengthSegments(int desiredSegmentLengthMs, long totalRuntimeTicks)
         {
             if (desiredSegmentLengthMs == 0 || totalRuntimeTicks == 0)
             {

+ 55 - 9
tests/Jellyfin.MediaEncoding.Hls.Tests/Playlist/DynamicHlsPlaylistGeneratorTests.cs

@@ -1,14 +1,29 @@
 using System;
 using Jellyfin.MediaEncoding.Hls.Playlist;
+using Jellyfin.MediaEncoding.Keyframes;
 using Xunit;
 
 namespace Jellyfin.MediaEncoding.Hls.Tests.Playlist
 {
     public class DynamicHlsPlaylistGeneratorTests
     {
+        [Theory]
+        [MemberData(nameof(ComputeSegments_Valid_Success_Data))]
+        public void ComputeSegments_Valid_Success(KeyframeData keyframeData, int desiredSegmentLengthMs, double[] segments)
+        {
+            Assert.Equal(segments, DynamicHlsPlaylistGenerator.ComputeSegments(keyframeData, desiredSegmentLengthMs));
+        }
+
+        [Fact]
+        public void ComputeSegments_InvalidDuration_ThrowsArgumentException()
+        {
+            var keyframeData = new KeyframeData(0, new[] { MsToTicks(10000) });
+            Assert.Throws<ArgumentException>(() => DynamicHlsPlaylistGenerator.ComputeSegments(keyframeData, 6000));
+        }
+
         [Theory]
         [MemberData(nameof(ComputeEqualLengthSegments_Valid_Success_Data))]
-        public void ComputeEqualLengthSegments_Valid_Success(long desiredSegmentLengthMs, long totalRuntimeTicks, double[] segments)
+        public void ComputeEqualLengthSegments_Valid_Success(int desiredSegmentLengthMs, long totalRuntimeTicks, double[] segments)
         {
             Assert.Equal(segments, DynamicHlsPlaylistGenerator.ComputeEqualLengthSegments(desiredSegmentLengthMs, totalRuntimeTicks));
         }
@@ -16,7 +31,7 @@ namespace Jellyfin.MediaEncoding.Hls.Tests.Playlist
         [Theory]
         [InlineData(0, 1000000)]
         [InlineData(1000, 0)]
-        public void ComputeEqualLengthSegments_Invalid_ThrowsInvalidOperationException(long desiredSegmentLengthMs, long totalRuntimeTicks)
+        public void ComputeEqualLengthSegments_Invalid_ThrowsInvalidOperationException(int desiredSegmentLengthMs, long totalRuntimeTicks)
         {
             Assert.Throws<InvalidOperationException>(() => DynamicHlsPlaylistGenerator.ComputeEqualLengthSegments(desiredSegmentLengthMs, totalRuntimeTicks));
         }
@@ -38,18 +53,49 @@ namespace Jellyfin.MediaEncoding.Hls.Tests.Playlist
             Assert.False(DynamicHlsPlaylistGenerator.IsExtractionAllowedForFile(filePath, allowedExtensions));
         }
 
-        private static TheoryData<long, long, double[]> ComputeEqualLengthSegments_Valid_Success_Data()
+        private static TheoryData<int, long, double[]> ComputeEqualLengthSegments_Valid_Success_Data()
         {
-            var data = new TheoryData<long, long, double[]>
+            var data = new TheoryData<int, long, double[]>
             {
-                { 6000, TimeSpan.FromMilliseconds(13000).Ticks, new[] { 6.0, 6.0, 1.0 } },
-                { 3000, TimeSpan.FromMilliseconds(15000).Ticks, new[] { 3.0, 3.0, 3.0, 3.0, 3.0 } },
-                { 6000, TimeSpan.FromMilliseconds(25000).Ticks, new[] { 6.0, 6.0, 6.0, 6.0, 1.0 } },
-                { 6000, TimeSpan.FromMilliseconds(20123).Ticks, new[] { 6.0, 6.0, 6.0, 2.123 } },
-                { 6000, TimeSpan.FromMilliseconds(1234).Ticks, new[] { 1.234 } }
+                { 6000, MsToTicks(13000), new[] { 6.0, 6.0, 1.0 } },
+                { 3000, MsToTicks(15000), new[] { 3.0, 3.0, 3.0, 3.0, 3.0 } },
+                { 6000, MsToTicks(25000), new[] { 6.0, 6.0, 6.0, 6.0, 1.0 } },
+                { 6000, MsToTicks(20123), new[] { 6.0, 6.0, 6.0, 2.123 } },
+                { 6000, MsToTicks(1234), new[] { 1.234 } }
             };
 
             return data;
         }
+
+        private static TheoryData<KeyframeData, int, double[]> ComputeSegments_Valid_Success_Data()
+        {
+            var data = new TheoryData<KeyframeData, int, double[]>
+            {
+                {
+                    new KeyframeData(MsToTicks(35000), new[] { 0, MsToTicks(10427), MsToTicks(20854), MsToTicks(31240) }),
+                    6000,
+                    new[] { 10.427, 10.427, 10.386, 3.760 }
+                },
+                {
+                    new KeyframeData(MsToTicks(10000), new[] { 0, MsToTicks(1000), MsToTicks(2000), MsToTicks(3000), MsToTicks(4000), MsToTicks(5000) }),
+                    2000,
+                    new[] { 2.0, 2.0, 6.0 }
+                },
+                {
+                    new KeyframeData(MsToTicks(10000), new[] { 0L }),
+                    6000,
+                    new[] { 10.0 }
+                },
+                {
+                    new KeyframeData(MsToTicks(10000), Array.Empty<long>()),
+                    6000,
+                    new[] { 10.0 }
+                }
+            };
+
+            return data;
+        }
+
+        private static long MsToTicks(int value) => TimeSpan.FromMilliseconds(value).Ticks;
     }
 }