2
0
Эх сурвалжийг харах

ProbeResultNormalizer: fix framerate compare + tests (#7167)

Mayur Panchal 3 жил өмнө
parent
commit
96de01ce01

+ 16 - 6
MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs

@@ -612,6 +612,17 @@ namespace MediaBrowser.MediaEncoding.Probing
             return attachment;
             return attachment;
         }
         }
 
 
+        /// <summary>
+        /// Determines whether a stream code time base is double the frame rate.
+        /// </summary>
+        /// <param name="averageFrameRate">average frame rate.</param>
+        /// <param name="codecTimeBase">codec time base string.</param>
+        /// <returns>true if the codec time base is double the frame rate.</returns>
+        internal static bool IsCodecTimeBaseDoubleTheFrameRate(float? averageFrameRate, string codecTimeBase)
+        {
+            return MathF.Abs(((averageFrameRate ?? 0) * (GetFrameRate(codecTimeBase) ?? 0)) - 0.5f) <= float.Epsilon;
+        }
+
         /// <summary>
         /// <summary>
         /// Converts ffprobe stream info to our MediaStream class.
         /// Converts ffprobe stream info to our MediaStream class.
         /// </summary>
         /// </summary>
@@ -722,17 +733,16 @@ namespace MediaBrowser.MediaEncoding.Probing
                 stream.AverageFrameRate = GetFrameRate(streamInfo.AverageFrameRate);
                 stream.AverageFrameRate = GetFrameRate(streamInfo.AverageFrameRate);
                 stream.RealFrameRate = GetFrameRate(streamInfo.RFrameRate);
                 stream.RealFrameRate = GetFrameRate(streamInfo.RFrameRate);
 
 
+                bool videoInterlaced = !string.IsNullOrWhiteSpace(streamInfo.FieldOrder)
+                    && !string.Equals(streamInfo.FieldOrder, "progressive", StringComparison.OrdinalIgnoreCase);
+
                 // Some interlaced H.264 files in mp4 containers using MBAFF coding aren't flagged as being interlaced by FFprobe,
                 // Some interlaced H.264 files in mp4 containers using MBAFF coding aren't flagged as being interlaced by FFprobe,
                 // so for H.264 files we also calculate the frame rate from the codec time base and check if it is double the reported
                 // so for H.264 files we also calculate the frame rate from the codec time base and check if it is double the reported
-                // frame rate (both rounded to the nearest integer) to determine if the file is interlaced
-                int roundedTimeBaseFPS = Convert.ToInt32(1 / GetFrameRate(stream.CodecTimeBase) ?? 0);
-                int roundedDoubleFrameRate = Convert.ToInt32(stream.AverageFrameRate * 2 ?? 0);
+                // frame rate to determine if the file is interlaced
 
 
-                bool videoInterlaced = !string.IsNullOrWhiteSpace(streamInfo.FieldOrder)
-                    && !string.Equals(streamInfo.FieldOrder, "progressive", StringComparison.OrdinalIgnoreCase);
                 bool h264MbaffCoded = string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase)
                 bool h264MbaffCoded = string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase)
                     && string.IsNullOrWhiteSpace(streamInfo.FieldOrder)
                     && string.IsNullOrWhiteSpace(streamInfo.FieldOrder)
-                    && roundedTimeBaseFPS == roundedDoubleFrameRate;
+                    && IsCodecTimeBaseDoubleTheFrameRate(stream.AverageFrameRate, stream.CodecTimeBase);
 
 
                 if (videoInterlaced || h264MbaffCoded)
                 if (videoInterlaced || h264MbaffCoded)
                 {
                 {

+ 10 - 0
tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs

@@ -31,6 +31,16 @@ namespace Jellyfin.MediaEncoding.Tests.Probing
         public void GetFrameRate_Success(string value, float? expected)
         public void GetFrameRate_Success(string value, float? expected)
             => Assert.Equal(expected, ProbeResultNormalizer.GetFrameRate(value));
             => Assert.Equal(expected, ProbeResultNormalizer.GetFrameRate(value));
 
 
+        [Theory]
+        [InlineData(0.5f, "0/1", false)]
+        [InlineData(24.5f, "8/196", false)]
+        [InlineData(63.5f, "1/127", true)]
+        [InlineData(null, "1/60", false)]
+        [InlineData(30f, "2/120", true)]
+        [InlineData(59.999996f, "1563/187560", true)]
+        public void IsCodecTimeBaseDoubleTheFrameRate_Success(float? frameRate, string codecTimeBase, bool expected)
+            => Assert.Equal(expected, ProbeResultNormalizer.IsCodecTimeBaseDoubleTheFrameRate(frameRate, codecTimeBase));
+
         [Fact]
         [Fact]
         public void GetMediaInfo_MetaData_Success()
         public void GetMediaInfo_MetaData_Success()
         {
         {