From d5b63092ed1b4b6ef4da2a5cdccec472aa1c06b3 Mon Sep 17 00:00:00 2001 From: Orry Verducci Date: Thu, 24 Jun 2021 17:51:35 +0100 Subject: [PATCH 1/2] Add H.264 MBAFF interlace check Use the codec time base to determine if a MBAFF coded H.264 file is interlaced. --- .../Probing/ProbeResultNormalizer.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index bbff5dacac..dd3faf5766 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -686,11 +686,6 @@ namespace MediaBrowser.MediaEncoding.Probing stream.IsAVC = false; } - if (!string.IsNullOrWhiteSpace(streamInfo.FieldOrder) && !string.Equals(streamInfo.FieldOrder, "progressive", StringComparison.OrdinalIgnoreCase)) - { - stream.IsInterlaced = true; - } - // Filter out junk if (!string.IsNullOrWhiteSpace(streamInfo.CodecTagString) && !streamInfo.CodecTagString.Contains("[0]", StringComparison.OrdinalIgnoreCase)) { @@ -746,6 +741,19 @@ namespace MediaBrowser.MediaEncoding.Probing stream.AverageFrameRate = GetFrameRate(streamInfo.AverageFrameRate); stream.RealFrameRate = GetFrameRate(streamInfo.RFrameRate); + // 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 check if the codec timebase duration is half the reported frame rate duration 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) + && string.IsNullOrWhiteSpace(streamInfo.FieldOrder) + && 1f / (stream.AverageFrameRate * 2) == GetFrameRate(stream.CodecTimeBase); + if (videoInterlaced || h264MbaffCoded) + { + stream.IsInterlaced = true; + } + if (isAudio || string.Equals(stream.Codec, "gif", StringComparison.OrdinalIgnoreCase) || string.Equals(stream.Codec, "png", StringComparison.OrdinalIgnoreCase)) { From 9abe9e7e54cc454667ba2128b5d321631b5ece51 Mon Sep 17 00:00:00 2001 From: Orry Verducci Date: Sun, 31 Oct 2021 17:04:04 +0000 Subject: [PATCH 2/2] Add rounding to the time base check --- .../Probing/ProbeResultNormalizer.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index c9885ae76a..eb8850cd25 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -724,13 +724,17 @@ namespace MediaBrowser.MediaEncoding.Probing stream.RealFrameRate = GetFrameRate(streamInfo.RFrameRate); // 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 check if the codec timebase duration is half the reported frame rate duration to - // determine if the file is interlaced + // 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 + float roundedTimeBaseFPS = MathF.Round(1 / GetFrameRate(stream.CodecTimeBase) ?? 0); + float roundedDoubleFrameRate = MathF.Round(stream.AverageFrameRate * 2 ?? 0); + bool videoInterlaced = !string.IsNullOrWhiteSpace(streamInfo.FieldOrder) && !string.Equals(streamInfo.FieldOrder, "progressive", StringComparison.OrdinalIgnoreCase); bool h264MbaffCoded = string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(streamInfo.FieldOrder) - && 1f / (stream.AverageFrameRate * 2) == GetFrameRate(stream.CodecTimeBase); + && roundedTimeBaseFPS == roundedDoubleFrameRate; + if (videoInterlaced || h264MbaffCoded) { stream.IsInterlaced = true;