diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 580f5c6159..97f2c57eb0 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -647,9 +647,9 @@ namespace MediaBrowser.MediaEncoding.Encoder var videoStream = mediaInfo.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); - if (videoStream != null) + if (videoStream != null && !videoStream.IsInterlaced) { - var isInterlaced = await DetectInterlaced(mediaInfo, videoStream, inputPath, probeSizeArgument).ConfigureAwait(false); + var isInterlaced = DetectInterlaced(mediaInfo, videoStream); if (isInterlaced) { @@ -672,7 +672,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - private async Task DetectInterlaced(MediaSourceInfo video, MediaStream videoStream, string inputPath, string probeSizeArgument) + private bool DetectInterlaced(MediaSourceInfo video, MediaStream videoStream) { var formats = (video.Container ?? string.Empty).Split(',').ToList(); var enableInterlacedDection = formats.Contains("vob", StringComparer.OrdinalIgnoreCase) || @@ -698,165 +698,9 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - if (video.Protocol != MediaProtocol.File) - { - return false; - } - - var args = "{0} -i {1} -map 0:v:{2} -an -filter:v idet -frames:v 500 -an -f null /dev/null"; - - var process = _processFactory.Create(new ProcessOptions - { - CreateNoWindow = true, - UseShellExecute = false, - - // Must consume both or ffmpeg may hang due to deadlocks. See comments below. - RedirectStandardError = true, - FileName = FFMpegPath, - Arguments = string.Format(args, probeSizeArgument, inputPath, videoStream.Index.ToString(CultureInfo.InvariantCulture)).Trim(), - - IsHidden = true, - ErrorDialog = false, - EnableRaisingEvents = true - }); - - _logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); - var idetFoundInterlaced = false; - - using (var processWrapper = new ProcessWrapper(process, this, _logger)) - { - try - { - StartProcess(processWrapper); - } - catch (Exception ex) - { - _logger.ErrorException("Error starting ffprobe", ex); - - throw; - } - - try - { - //process.BeginOutputReadLine(); - - using (var reader = new StreamReader(process.StandardError.BaseStream)) - { - while (!reader.EndOfStream) - { - var line = await reader.ReadLineAsync().ConfigureAwait(false); - - if (line.StartsWith("[Parsed_idet", StringComparison.OrdinalIgnoreCase)) - { - var idetResult = AnalyzeIdetResult(line); - - if (idetResult.HasValue) - { - if (!idetResult.Value) - { - return false; - } - - idetFoundInterlaced = true; - } - } - } - } - - } - catch - { - StopProcess(processWrapper, 100); - - throw; - } - } - - return idetFoundInterlaced; - } - - private bool? AnalyzeIdetResult(string line) - { - // As you can see, the filter only guessed one frame as progressive. - // Results like this are pretty typical. So if less than 30% of the detections are in the "Undetermined" category, then I only consider the video to be interlaced if at least 65% of the identified frames are in either the TFF or BFF category. - // In this case (310 + 311)/(622) = 99.8% which is well over the 65% metric. I may refine that number with more testing but I honestly do not believe I will need to. - // http://awel.domblogger.net/videoTranscode/interlace.html - var index = line.IndexOf("detection:", StringComparison.OrdinalIgnoreCase); - - if (index == -1) - { - return null; - } - - line = line.Substring(index).Trim(); - var parts = line.Split(' ').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => i.Trim()).ToList(); - - if (parts.Count < 2) - { - return null; - } - double tff = 0; - double bff = 0; - double progressive = 0; - double undetermined = 0; - double total = 0; - - for (var i = 0; i < parts.Count - 1; i++) - { - var part = parts[i]; - - if (string.Equals(part, "tff:", StringComparison.OrdinalIgnoreCase)) - { - tff = GetNextPart(parts, i); - total += tff; - } - else if (string.Equals(part, "bff:", StringComparison.OrdinalIgnoreCase)) - { - bff = GetNextPart(parts, i); - total += tff; - } - else if (string.Equals(part, "progressive:", StringComparison.OrdinalIgnoreCase)) - { - progressive = GetNextPart(parts, i); - total += progressive; - } - else if (string.Equals(part, "undetermined:", StringComparison.OrdinalIgnoreCase)) - { - undetermined = GetNextPart(parts, i); - total += undetermined; - } - } - - if (total == 0) - { - return null; - } - - if ((undetermined / total) >= .3) - { - return false; - } - - if (((tff + bff) / total) >= .4) - { - return true; - } - return false; } - private int GetNextPart(List parts, int index) - { - var next = parts[index + 1]; - - int value; - if (int.TryParse(next, NumberStyles.Any, CultureInfo.InvariantCulture, out value)) - { - return value; - } - return 0; - } - /// /// The us culture /// diff --git a/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs b/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs index f32dd178f2..eef2732509 100644 --- a/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs +++ b/MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs @@ -264,6 +264,8 @@ namespace MediaBrowser.MediaEncoding.Probing /// The loro_surmixlev. public string loro_surmixlev { get; set; } + public string field_order { get; set; } + /// /// Gets or sets the disposition. /// diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 7927ddb6a1..8b20dca1b5 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -508,6 +508,11 @@ namespace MediaBrowser.MediaEncoding.Probing stream.IsAVC = false; } + if (!string.IsNullOrWhiteSpace(streamInfo.field_order) && !string.Equals(streamInfo.field_order, "progressive", StringComparison.OrdinalIgnoreCase)) + { + stream.IsInterlaced = true; + } + // Filter out junk if (!string.IsNullOrWhiteSpace(streamInfo.codec_tag_string) && streamInfo.codec_tag_string.IndexOf("[0]", StringComparison.OrdinalIgnoreCase) == -1) {