From 6414fc9486a56dbf49de9dc42251c33acb10b148 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 19 Dec 2015 10:51:38 -0500 Subject: [PATCH 1/4] remove MediaInfo --- .../MediaBrowser.MediaEncoding.csproj | 4 - .../Probing/ProbeResultNormalizer.cs | 34 +-- .../MediaBrowser.MediaInfo.csproj | 58 ---- MediaBrowser.MediaInfo/MediaInfoLib.cs | 65 ----- MediaBrowser.MediaInfo/Native.cs | 275 ------------------ .../Properties/AssemblyInfo.cs | 31 -- .../MediaBrowser.MediaInfo.dll.config | 4 - .../MediaBrowser.Server.Mono.csproj | 7 - .../MediaBrowser.ServerApplication.csproj | 4 - MediaBrowser.sln | 23 -- 10 files changed, 11 insertions(+), 494 deletions(-) delete mode 100644 MediaBrowser.MediaInfo/MediaBrowser.MediaInfo.csproj delete mode 100644 MediaBrowser.MediaInfo/MediaInfoLib.cs delete mode 100644 MediaBrowser.MediaInfo/Native.cs delete mode 100644 MediaBrowser.MediaInfo/Properties/AssemblyInfo.cs delete mode 100644 MediaBrowser.Server.Mono/MediaBrowser.MediaInfo.dll.config diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index 1f74994e5..df5ab4651 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -99,10 +99,6 @@ {17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2} MediaBrowser.Controller - - {6e4145e4-c6d4-4e4d-94f2-87188db6e239} - MediaBrowser.MediaInfo - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} MediaBrowser.Model diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index d4df19af2..55b3398bb 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.IO; -using MediaBrowser.MediaInfo; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Extensions; @@ -26,7 +25,7 @@ namespace MediaBrowser.MediaEncoding.Probing _fileSystem = fileSystem; } - public Model.MediaInfo.MediaInfo GetMediaInfo(InternalMediaInfoResult data, VideoType videoType, bool isAudio, string path, MediaProtocol protocol) + public MediaInfo GetMediaInfo(InternalMediaInfoResult data, VideoType videoType, bool isAudio, string path, MediaProtocol protocol) { var info = new Model.MediaInfo.MediaInfo { @@ -109,7 +108,7 @@ namespace MediaBrowser.MediaEncoding.Probing if (videoStream != null && videoType == VideoType.VideoFile) { - UpdateFromMediaInfo(info, videoStream); + DetectInterlaced(info, videoStream); } } @@ -934,29 +933,18 @@ namespace MediaBrowser.MediaEncoding.Probing return TransportStreamTimestamp.None; } - private void UpdateFromMediaInfo(MediaSourceInfo video, MediaStream videoStream) + private void DetectInterlaced(MediaSourceInfo video, MediaStream videoStream) { - if (video.Protocol == MediaProtocol.File && videoStream != null) + if (video.Protocol != MediaProtocol.File || videoStream == null) { - try - { - _logger.Debug("Running MediaInfo against {0}", video.Path); + return; + } - var result = new MediaInfoLib().GetVideoInfo(video.Path); - - videoStream.IsCabac = result.IsCabac ?? videoStream.IsCabac; - videoStream.IsInterlaced = result.IsInterlaced ?? videoStream.IsInterlaced; - videoStream.BitDepth = result.BitDepth ?? videoStream.BitDepth; - videoStream.RefFrames = result.RefFrames ?? videoStream.RefFrames; - } - catch (TypeLoadException) - { - // This is non-essential. Don't spam the log - } - catch (Exception ex) - { - _logger.ErrorException("Error running MediaInfo on {0}", ex, video.Path); - } + // Take a shortcut and limit this to containers that are likely to have interlaced content + if (!string.Equals(video.Container, "ts", StringComparison.OrdinalIgnoreCase) && + !string.Equals(video.Container, "wtv", StringComparison.OrdinalIgnoreCase)) + { + return; } } } diff --git a/MediaBrowser.MediaInfo/MediaBrowser.MediaInfo.csproj b/MediaBrowser.MediaInfo/MediaBrowser.MediaInfo.csproj deleted file mode 100644 index 024098cb9..000000000 --- a/MediaBrowser.MediaInfo/MediaBrowser.MediaInfo.csproj +++ /dev/null @@ -1,58 +0,0 @@ - - - - - Debug - AnyCPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239} - Library - Properties - MediaBrowser.MediaInfo - MediaBrowser.MediaInfo - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - none - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - Properties\SharedVersion.cs - - - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.MediaInfo/MediaInfoLib.cs b/MediaBrowser.MediaInfo/MediaInfoLib.cs deleted file mode 100644 index fa644aee0..000000000 --- a/MediaBrowser.MediaInfo/MediaInfoLib.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; - -namespace MediaBrowser.MediaInfo -{ - public class MediaInfoLib - { - public MediaInfoResult GetVideoInfo(string path) - { - var lib = new MediaInfo(); - - lib.Open(path); - - var result = new MediaInfoResult(); - - // TODO: Don't hardcode - var videoStreamIndex = 0; - - var text = GetValue(lib, videoStreamIndex, new[] { "ScanType", "Scan type", "ScanType/String" }); - if (!string.IsNullOrWhiteSpace(text)) - { - result.IsInterlaced = text.IndexOf("interlac", StringComparison.OrdinalIgnoreCase) != -1; - } - - text = GetValue(lib, videoStreamIndex, new[] { "Format_Settings_CABAC", "Format_Settings_CABAC/String" }); - if (!string.IsNullOrWhiteSpace(text)) - { - result.IsCabac = string.Equals(text, "yes", StringComparison.OrdinalIgnoreCase); - } - - int bitDepth; - text = GetValue(lib, videoStreamIndex, new[] { "BitDepth", "BitDepth/String" }); - - if (!string.IsNullOrWhiteSpace(text) && int.TryParse(text.Split(' ').First(), NumberStyles.Any, CultureInfo.InvariantCulture, out bitDepth)) - { - result.BitDepth = bitDepth; - } - - int refFrames; - text = GetValue(lib, videoStreamIndex, new[] { "Format_Settings_RefFrames", "Format_Settings_RefFrames/String" }); - - if (!string.IsNullOrWhiteSpace(text) && int.TryParse(text.Split(' ').First(), NumberStyles.Any, CultureInfo.InvariantCulture, out refFrames)) - { - result.RefFrames = refFrames; - } - - return result; - } - - private string GetValue(MediaInfo lib, int index, IEnumerable names) - { - return names.Select(i => lib.Get(StreamKind.Video, index, i)).FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); - } - } - - public class MediaInfoResult - { - public bool? IsCabac { get; set; } - public bool? IsInterlaced { get; set; } - public int? BitDepth { get; set; } - public int? RefFrames { get; set; } - } -} diff --git a/MediaBrowser.MediaInfo/Native.cs b/MediaBrowser.MediaInfo/Native.cs deleted file mode 100644 index 5bc7ae368..000000000 --- a/MediaBrowser.MediaInfo/Native.cs +++ /dev/null @@ -1,275 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace MediaBrowser.MediaInfo -{ - public enum StreamKind - { - General, - Video, - Audio, - Text, - Other, - Image, - Menu, - } - - public enum InfoKind - { - Name, - Text, - Measure, - Options, - NameText, - MeasureText, - Info, - HowTo - } - - public enum InfoOptions - { - ShowInInform, - Support, - ShowInSupported, - TypeOfValue - } - - public enum InfoFileOptions - { - FileOption_Nothing = 0x00, - FileOption_NoRecursive = 0x01, - FileOption_CloseAll = 0x02, - FileOption_Max = 0x04 - }; - - public enum Status - { - None = 0x00, - Accepted = 0x01, - Filled = 0x02, - Updated = 0x04, - Finalized = 0x08, - } - - public class MediaInfo - { - //Import of DLL functions. DO NOT USE until you know what you do (MediaInfo DLL do NOT use CoTaskMemAlloc to allocate memory) - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfo_New(); - [DllImport("MediaInfo")] - private static extern void MediaInfo_Delete(IntPtr Handle); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfo_Open(IntPtr Handle, [MarshalAs(UnmanagedType.LPWStr)] string FileName); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoA_Open(IntPtr Handle, IntPtr FileName); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfo_Open_Buffer_Init(IntPtr Handle, Int64 File_Size, Int64 File_Offset); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoA_Open(IntPtr Handle, Int64 File_Size, Int64 File_Offset); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfo_Open_Buffer_Continue(IntPtr Handle, IntPtr Buffer, IntPtr Buffer_Size); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoA_Open_Buffer_Continue(IntPtr Handle, Int64 File_Size, byte[] Buffer, IntPtr Buffer_Size); - [DllImport("MediaInfo")] - private static extern Int64 MediaInfo_Open_Buffer_Continue_GoTo_Get(IntPtr Handle); - [DllImport("MediaInfo")] - private static extern Int64 MediaInfoA_Open_Buffer_Continue_GoTo_Get(IntPtr Handle); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfo_Open_Buffer_Finalize(IntPtr Handle); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoA_Open_Buffer_Finalize(IntPtr Handle); - [DllImport("MediaInfo")] - private static extern void MediaInfo_Close(IntPtr Handle); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfo_Inform(IntPtr Handle, IntPtr Reserved); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoA_Inform(IntPtr Handle, IntPtr Reserved); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfo_GetI(IntPtr Handle, IntPtr StreamKind, IntPtr StreamNumber, IntPtr Parameter, IntPtr KindOfInfo); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoA_GetI(IntPtr Handle, IntPtr StreamKind, IntPtr StreamNumber, IntPtr Parameter, IntPtr KindOfInfo); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfo_Get(IntPtr Handle, IntPtr StreamKind, IntPtr StreamNumber, [MarshalAs(UnmanagedType.LPWStr)] string Parameter, IntPtr KindOfInfo, IntPtr KindOfSearch); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoA_Get(IntPtr Handle, IntPtr StreamKind, IntPtr StreamNumber, IntPtr Parameter, IntPtr KindOfInfo, IntPtr KindOfSearch); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfo_Option(IntPtr Handle, [MarshalAs(UnmanagedType.LPWStr)] string Option, [MarshalAs(UnmanagedType.LPWStr)] string Value); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoA_Option(IntPtr Handle, IntPtr Option, IntPtr Value); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfo_State_Get(IntPtr Handle); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfo_Count_Get(IntPtr Handle, IntPtr StreamKind, IntPtr StreamNumber); - - //MediaInfo class - public MediaInfo() - { - try - { - Handle = MediaInfo_New(); - } - catch - { - Handle = (IntPtr)0; - } - if (Environment.OSVersion.ToString().IndexOf("Windows") == -1) - MustUseAnsi = true; - else - MustUseAnsi = false; - } - ~MediaInfo() { if (Handle == (IntPtr)0) return; MediaInfo_Delete(Handle); } - public int Open(String FileName) - { - if (Handle == (IntPtr)0) - return 0; - if (MustUseAnsi) - { - IntPtr FileName_Ptr = Marshal.StringToHGlobalAnsi(FileName); - int ToReturn = (int)MediaInfoA_Open(Handle, FileName_Ptr); - Marshal.FreeHGlobal(FileName_Ptr); - return ToReturn; - } - else - return (int)MediaInfo_Open(Handle, FileName); - } - public int Open_Buffer_Init(Int64 File_Size, Int64 File_Offset) - { - if (Handle == (IntPtr)0) return 0; return (int)MediaInfo_Open_Buffer_Init(Handle, File_Size, File_Offset); - } - public int Open_Buffer_Continue(IntPtr Buffer, IntPtr Buffer_Size) - { - if (Handle == (IntPtr)0) return 0; return (int)MediaInfo_Open_Buffer_Continue(Handle, Buffer, Buffer_Size); - } - public Int64 Open_Buffer_Continue_GoTo_Get() - { - if (Handle == (IntPtr)0) return 0; return (Int64)MediaInfo_Open_Buffer_Continue_GoTo_Get(Handle); - } - public int Open_Buffer_Finalize() - { - if (Handle == (IntPtr)0) return 0; return (int)MediaInfo_Open_Buffer_Finalize(Handle); - } - public void Close() { if (Handle == (IntPtr)0) return; MediaInfo_Close(Handle); } - public String Inform() - { - if (Handle == (IntPtr)0) - return "Unable to load MediaInfo library"; - if (MustUseAnsi) - return Marshal.PtrToStringAnsi(MediaInfoA_Inform(Handle, (IntPtr)0)); - else - return Marshal.PtrToStringUni(MediaInfo_Inform(Handle, (IntPtr)0)); - } - public String Get(StreamKind StreamKind, int StreamNumber, String Parameter, InfoKind KindOfInfo, InfoKind KindOfSearch) - { - if (Handle == (IntPtr)0) - return "Unable to load MediaInfo library"; - if (MustUseAnsi) - { - IntPtr Parameter_Ptr = Marshal.StringToHGlobalAnsi(Parameter); - String ToReturn = Marshal.PtrToStringAnsi(MediaInfoA_Get(Handle, (IntPtr)StreamKind, (IntPtr)StreamNumber, Parameter_Ptr, (IntPtr)KindOfInfo, (IntPtr)KindOfSearch)); - Marshal.FreeHGlobal(Parameter_Ptr); - return ToReturn; - } - else - return Marshal.PtrToStringUni(MediaInfo_Get(Handle, (IntPtr)StreamKind, (IntPtr)StreamNumber, Parameter, (IntPtr)KindOfInfo, (IntPtr)KindOfSearch)); - } - public String Get(StreamKind StreamKind, int StreamNumber, int Parameter, InfoKind KindOfInfo) - { - if (Handle == (IntPtr)0) - return "Unable to load MediaInfo library"; - if (MustUseAnsi) - return Marshal.PtrToStringAnsi(MediaInfoA_GetI(Handle, (IntPtr)StreamKind, (IntPtr)StreamNumber, (IntPtr)Parameter, (IntPtr)KindOfInfo)); - else - return Marshal.PtrToStringUni(MediaInfo_GetI(Handle, (IntPtr)StreamKind, (IntPtr)StreamNumber, (IntPtr)Parameter, (IntPtr)KindOfInfo)); - } - public String Option(String Option, String Value) - { - if (Handle == (IntPtr)0) - return "Unable to load MediaInfo library"; - if (MustUseAnsi) - { - IntPtr Option_Ptr = Marshal.StringToHGlobalAnsi(Option); - IntPtr Value_Ptr = Marshal.StringToHGlobalAnsi(Value); - String ToReturn = Marshal.PtrToStringAnsi(MediaInfoA_Option(Handle, Option_Ptr, Value_Ptr)); - Marshal.FreeHGlobal(Option_Ptr); - Marshal.FreeHGlobal(Value_Ptr); - return ToReturn; - } - else - return Marshal.PtrToStringUni(MediaInfo_Option(Handle, Option, Value)); - } - public int State_Get() { if (Handle == (IntPtr)0) return 0; return (int)MediaInfo_State_Get(Handle); } - public int Count_Get(StreamKind StreamKind, int StreamNumber) { if (Handle == (IntPtr)0) return 0; return (int)MediaInfo_Count_Get(Handle, (IntPtr)StreamKind, (IntPtr)StreamNumber); } - private IntPtr Handle; - private bool MustUseAnsi; - - //Default values, if you know how to set default values in C#, say me - public String Get(StreamKind StreamKind, int StreamNumber, String Parameter, InfoKind KindOfInfo) { return Get(StreamKind, StreamNumber, Parameter, KindOfInfo, InfoKind.Name); } - public String Get(StreamKind StreamKind, int StreamNumber, String Parameter) { return Get(StreamKind, StreamNumber, Parameter, InfoKind.Text, InfoKind.Name); } - public String Get(StreamKind StreamKind, int StreamNumber, int Parameter) { return Get(StreamKind, StreamNumber, Parameter, InfoKind.Text); } - public String Option(String Option_) { return Option(Option_, ""); } - public int Count_Get(StreamKind StreamKind) { return Count_Get(StreamKind, -1); } - } - - - - - - - - - - - - - - - - - - public class MediaInfoList - { - //Import of DLL functions. DO NOT USE until you know what you do (MediaInfo DLL do NOT use CoTaskMemAlloc to allocate memory) - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoList_New(); - [DllImport("MediaInfo")] - private static extern void MediaInfoList_Delete(IntPtr Handle); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoList_Open(IntPtr Handle, [MarshalAs(UnmanagedType.LPWStr)] string FileName, IntPtr Options); - [DllImport("MediaInfo")] - private static extern void MediaInfoList_Close(IntPtr Handle, IntPtr FilePos); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoList_Inform(IntPtr Handle, IntPtr FilePos, IntPtr Reserved); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoList_GetI(IntPtr Handle, IntPtr FilePos, IntPtr StreamKind, IntPtr StreamNumber, IntPtr Parameter, IntPtr KindOfInfo); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoList_Get(IntPtr Handle, IntPtr FilePos, IntPtr StreamKind, IntPtr StreamNumber, [MarshalAs(UnmanagedType.LPWStr)] string Parameter, IntPtr KindOfInfo, IntPtr KindOfSearch); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoList_Option(IntPtr Handle, [MarshalAs(UnmanagedType.LPWStr)] string Option, [MarshalAs(UnmanagedType.LPWStr)] string Value); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoList_State_Get(IntPtr Handle); - [DllImport("MediaInfo")] - private static extern IntPtr MediaInfoList_Count_Get(IntPtr Handle, IntPtr FilePos, IntPtr StreamKind, IntPtr StreamNumber); - - //MediaInfo class - public MediaInfoList() { Handle = MediaInfoList_New(); } - ~MediaInfoList() { MediaInfoList_Delete(Handle); } - public int Open(String FileName, InfoFileOptions Options) { return (int)MediaInfoList_Open(Handle, FileName, (IntPtr)Options); } - public void Close(int FilePos) { MediaInfoList_Close(Handle, (IntPtr)FilePos); } - public String Inform(int FilePos) { return Marshal.PtrToStringUni(MediaInfoList_Inform(Handle, (IntPtr)FilePos, (IntPtr)0)); } - public String Get(int FilePos, StreamKind StreamKind, int StreamNumber, String Parameter, InfoKind KindOfInfo, InfoKind KindOfSearch) { return Marshal.PtrToStringUni(MediaInfoList_Get(Handle, (IntPtr)FilePos, (IntPtr)StreamKind, (IntPtr)StreamNumber, Parameter, (IntPtr)KindOfInfo, (IntPtr)KindOfSearch)); } - public String Get(int FilePos, StreamKind StreamKind, int StreamNumber, int Parameter, InfoKind KindOfInfo) { return Marshal.PtrToStringUni(MediaInfoList_GetI(Handle, (IntPtr)FilePos, (IntPtr)StreamKind, (IntPtr)StreamNumber, (IntPtr)Parameter, (IntPtr)KindOfInfo)); } - public String Option(String Option, String Value) { return Marshal.PtrToStringUni(MediaInfoList_Option(Handle, Option, Value)); } - public int State_Get() { return (int)MediaInfoList_State_Get(Handle); } - public int Count_Get(int FilePos, StreamKind StreamKind, int StreamNumber) { return (int)MediaInfoList_Count_Get(Handle, (IntPtr)FilePos, (IntPtr)StreamKind, (IntPtr)StreamNumber); } - private IntPtr Handle; - - //Default values, if you know how to set default values in C#, say me - public void Open(String FileName) { Open(FileName, 0); } - public void Close() { Close(-1); } - public String Get(int FilePos, StreamKind StreamKind, int StreamNumber, String Parameter, InfoKind KindOfInfo) { return Get(FilePos, StreamKind, StreamNumber, Parameter, KindOfInfo, InfoKind.Name); } - public String Get(int FilePos, StreamKind StreamKind, int StreamNumber, String Parameter) { return Get(FilePos, StreamKind, StreamNumber, Parameter, InfoKind.Text, InfoKind.Name); } - public String Get(int FilePos, StreamKind StreamKind, int StreamNumber, int Parameter) { return Get(FilePos, StreamKind, StreamNumber, Parameter, InfoKind.Text); } - public String Option(String Option_) { return Option(Option_, ""); } - public int Count_Get(int FilePos, StreamKind StreamKind) { return Count_Get(FilePos, StreamKind, -1); } - } -} diff --git a/MediaBrowser.MediaInfo/Properties/AssemblyInfo.cs b/MediaBrowser.MediaInfo/Properties/AssemblyInfo.cs deleted file mode 100644 index 8249bd33c..000000000 --- a/MediaBrowser.MediaInfo/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("MediaBrowser.MediaInfo")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("MediaBrowser.MediaInfo")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("8ef5ed2a-0460-4fb4-ba3f-fc2ba057f009")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// \ No newline at end of file diff --git a/MediaBrowser.Server.Mono/MediaBrowser.MediaInfo.dll.config b/MediaBrowser.Server.Mono/MediaBrowser.MediaInfo.dll.config deleted file mode 100644 index 6d63633aa..000000000 --- a/MediaBrowser.Server.Mono/MediaBrowser.MediaInfo.dll.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index ecb89b78c..e9f631bf3 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -144,10 +144,6 @@ - - MediaInfo\osx\libmediainfo.dylib - PreserveNewest - libsqlite3.0.dylib PreserveNewest @@ -160,9 +156,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 3b4b52af3..5813dcac5 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -176,10 +176,6 @@ x86\SQLite.Interop.dll PreserveNewest - - MediaInfo.dll - PreserveNewest - PreserveNewest diff --git a/MediaBrowser.sln b/MediaBrowser.sln index 3fc5e3f33..d0fbd743e 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -55,8 +55,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.XbmcMetadata", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.LocalMetadata", "MediaBrowser.LocalMetadata\MediaBrowser.LocalMetadata.csproj", "{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.MediaInfo", "MediaBrowser.MediaInfo\MediaBrowser.MediaInfo.csproj", "{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Mono", "MediaBrowser.Server.Mono\MediaBrowser.Server.Mono.csproj", "{175A9388-F352-4586-A6B4-070DED62B644}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Startup.Common", "MediaBrowser.Server.Startup.Common\MediaBrowser.Server.Startup.Common.csproj", "{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}" @@ -450,27 +448,6 @@ Global {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Win32.ActiveCfg = Release|Any CPU {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|x64.ActiveCfg = Release|Any CPU {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|x86.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Win32.ActiveCfg = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|x64.ActiveCfg = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|x86.ActiveCfg = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|Any CPU.Build.0 = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|Mixed Platforms.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|Mixed Platforms.Build.0 = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|Win32.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|x64.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|x86.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Any CPU.Build.0 = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Win32.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|x64.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|x86.ActiveCfg = Release|Any CPU {175A9388-F352-4586-A6B4-070DED62B644}.Debug|Any CPU.ActiveCfg = Debug|x86 {175A9388-F352-4586-A6B4-070DED62B644}.Debug|Any CPU.Build.0 = Debug|x86 {175A9388-F352-4586-A6B4-070DED62B644}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 From 940702aa0b0927f8826a3eaddbedf0ed6524ad25 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 19 Dec 2015 11:02:47 -0500 Subject: [PATCH 2/4] update solution files --- MediaBrowser.Mono.sln | 11 ----------- MediaBrowser.Server.Mac.sln | 16 ---------------- 2 files changed, 27 deletions(-) diff --git a/MediaBrowser.Mono.sln b/MediaBrowser.Mono.sln index 2e720d095..3d9677fa8 100644 --- a/MediaBrowser.Mono.sln +++ b/MediaBrowser.Mono.sln @@ -31,8 +31,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.LocalMetadata" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.XbmcMetadata", "MediaBrowser.XbmcMetadata\MediaBrowser.XbmcMetadata.csproj", "{23499896-B135-4527-8574-C26E926EA99E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.MediaInfo", "MediaBrowser.MediaInfo\MediaBrowser.MediaInfo.csproj", "{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Startup.Common", "MediaBrowser.Server.Startup.Common\MediaBrowser.Server.Startup.Common.csproj", "{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Drawing", "Emby.Drawing\Emby.Drawing.csproj", "{08FFF49B-F175-4807-A2B5-73B0EBD9F716}" @@ -187,15 +185,6 @@ Global {23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.Build.0 = Release|Any CPU {23499896-B135-4527-8574-C26E926EA99E}.Release|x86.ActiveCfg = Release|Any CPU {23499896-B135-4527-8574-C26E926EA99E}.Release|x86.Build.0 = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|x86.ActiveCfg = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|Any CPU.Build.0 = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|x86.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Any CPU.Build.0 = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|x86.ActiveCfg = Release|Any CPU {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|Any CPU.Build.0 = Debug|Any CPU {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|x86.ActiveCfg = Debug|Any CPU diff --git a/MediaBrowser.Server.Mac.sln b/MediaBrowser.Server.Mac.sln index 3167aa65f..8a60fc6c1 100644 --- a/MediaBrowser.Server.Mac.sln +++ b/MediaBrowser.Server.Mac.sln @@ -17,8 +17,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.LocalMetadata" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.MediaEncoding", "MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj", "{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.MediaInfo", "MediaBrowser.MediaInfo\MediaBrowser.MediaInfo.csproj", "{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Model", "MediaBrowser.Model\MediaBrowser.Model.csproj", "{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Providers", "MediaBrowser.Providers\MediaBrowser.Providers.csproj", "{442B5058-DCAF-4263-BB6A-F21E31120A1B}" @@ -172,20 +170,6 @@ Global {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.Build.0 = Release|Any CPU {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.ActiveCfg = Release|Any CPU {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.Build.0 = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.AppStore|Any CPU.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.AppStore|Any CPU.Build.0 = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|x86.ActiveCfg = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|x86.Build.0 = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|Any CPU.ActiveCfg = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|Any CPU.Build.0 = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|x86.ActiveCfg = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|x86.Build.0 = Debug|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Any CPU.Build.0 = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|x86.ActiveCfg = Release|Any CPU - {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|x86.Build.0 = Release|Any CPU {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.AppStore|Any CPU.ActiveCfg = Release|Any CPU {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.AppStore|Any CPU.Build.0 = Release|Any CPU {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU From 5c610d71f61f4f834a07102e9947d847f6a4efbf Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 19 Dec 2015 11:46:32 -0500 Subject: [PATCH 3/4] remove call from probe result normalizer --- .../Encoder/MediaEncoder.cs | 77 +++++++++++++++++++ .../Probing/ProbeResultNormalizer.cs | 22 ------ 2 files changed, 77 insertions(+), 22 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index c8361ea04..d4a626da0 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -262,6 +262,8 @@ namespace MediaBrowser.MediaEncoding.Encoder var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol); + await DetectInterlaced(mediaInfo, inputPath, probeSizeArgument).ConfigureAwait(false); + if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue) { if (ConfigurationManager.Configuration.EnableVideoFrameByFrameAnalysis && mediaInfo.Size.HasValue) @@ -304,6 +306,81 @@ namespace MediaBrowser.MediaEncoding.Encoder throw new ApplicationException(string.Format("FFProbe failed for {0}", inputPath)); } + private async Task DetectInterlaced(MediaSourceInfo video, string inputPath, string probeSizeArgument) + { + var videoStream = video.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); + + if (video.Protocol != MediaProtocol.File || videoStream == null) + { + return; + } + + // Take a shortcut and limit this to containers that are likely to have interlaced content + if (!string.Equals(video.Container, "ts", StringComparison.OrdinalIgnoreCase) && + !string.Equals(video.Container, "wtv", StringComparison.OrdinalIgnoreCase)) + { + //return; + } + + var args = "{0} -i {1} -map 0:v:{2} -filter:v idet -frames:v 500 -an -f null /dev/null"; + + var process = new Process + { + StartInfo = new ProcessStartInfo + { + CreateNoWindow = true, + UseShellExecute = false, + + // Must consume both or ffmpeg may hang due to deadlocks. See comments below. + RedirectStandardOutput = true, + RedirectStandardError = true, + RedirectStandardInput = true, + FileName = FFMpegPath, + Arguments = string.Format(args, probeSizeArgument, inputPath, videoStream.Index.ToString(CultureInfo.InvariantCulture)).Trim(), + + WindowStyle = ProcessWindowStyle.Hidden, + ErrorDialog = false + }, + + EnableRaisingEvents = true + }; + + _logger.Info("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); + + 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)) + { + var result = await reader.ReadToEndAsync().ConfigureAwait(false); + + File.WriteAllText("D:\\\\1.txt", result); + } + + } + catch + { + StopProcess(processWrapper, 100, true); + + throw; + } + } + } + private bool EnableKeyframeExtraction(MediaSourceInfo mediaSource, MediaStream videoStream) { if (videoStream.Type == MediaStreamType.Video && string.Equals(videoStream.Codec, "h264", StringComparison.OrdinalIgnoreCase) && diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 55b3398bb..d9fda220d 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -103,13 +103,6 @@ namespace MediaBrowser.MediaEncoding.Probing } ExtractTimestamp(info); - - var videoStream = info.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); - - if (videoStream != null && videoType == VideoType.VideoFile) - { - DetectInterlaced(info, videoStream); - } } return info; @@ -932,20 +925,5 @@ namespace MediaBrowser.MediaEncoding.Probing return TransportStreamTimestamp.None; } - - private void DetectInterlaced(MediaSourceInfo video, MediaStream videoStream) - { - if (video.Protocol != MediaProtocol.File || videoStream == null) - { - return; - } - - // Take a shortcut and limit this to containers that are likely to have interlaced content - if (!string.Equals(video.Container, "ts", StringComparison.OrdinalIgnoreCase) && - !string.Equals(video.Container, "wtv", StringComparison.OrdinalIgnoreCase)) - { - return; - } - } } } From 5fffd38963e83aec92bd74a172be8dd38bdaba35 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 19 Dec 2015 12:44:38 -0500 Subject: [PATCH 4/4] detect interlaced --- .../Encoder/MediaEncoder.cs | 136 ++++++++++++++++-- 1 file changed, 124 insertions(+), 12 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index d4a626da0..1dc1a4215 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -262,7 +262,17 @@ namespace MediaBrowser.MediaEncoding.Encoder var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol); - await DetectInterlaced(mediaInfo, inputPath, probeSizeArgument).ConfigureAwait(false); + var videoStream = mediaInfo.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); + + if (videoStream != null) + { + var isInterlaced = await DetectInterlaced(mediaInfo, videoStream, inputPath, probeSizeArgument).ConfigureAwait(false); + + if (isInterlaced) + { + videoStream.IsInterlaced = true; + } + } if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue) { @@ -306,20 +316,21 @@ namespace MediaBrowser.MediaEncoding.Encoder throw new ApplicationException(string.Format("FFProbe failed for {0}", inputPath)); } - private async Task DetectInterlaced(MediaSourceInfo video, string inputPath, string probeSizeArgument) + private async Task DetectInterlaced(MediaSourceInfo video, MediaStream videoStream, string inputPath, string probeSizeArgument) { - var videoStream = video.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); - - if (video.Protocol != MediaProtocol.File || videoStream == null) + if (video.Protocol != MediaProtocol.File) { - return; + return false; } + var formats = (video.Container ?? string.Empty).Split(',').ToList(); + // Take a shortcut and limit this to containers that are likely to have interlaced content - if (!string.Equals(video.Container, "ts", StringComparison.OrdinalIgnoreCase) && - !string.Equals(video.Container, "wtv", StringComparison.OrdinalIgnoreCase)) + if (!formats.Contains("ts", StringComparer.OrdinalIgnoreCase) && + !formats.Contains("mpegts", StringComparer.OrdinalIgnoreCase) && + !formats.Contains("wtv", StringComparer.OrdinalIgnoreCase)) { - //return; + return false; } var args = "{0} -i {1} -map 0:v:{2} -filter:v idet -frames:v 500 -an -f null /dev/null"; @@ -346,6 +357,7 @@ namespace MediaBrowser.MediaEncoding.Encoder }; _logger.Info("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); + var idetFoundInterlaced = false; using (var processWrapper = new ProcessWrapper(process, this, _logger)) { @@ -366,11 +378,27 @@ namespace MediaBrowser.MediaEncoding.Encoder using (var reader = new StreamReader(process.StandardError.BaseStream)) { - var result = await reader.ReadToEndAsync().ConfigureAwait(false); + while (!reader.EndOfStream) + { + var line = await reader.ReadLineAsync().ConfigureAwait(false); - File.WriteAllText("D:\\\\1.txt", result); + if (line.StartsWith("[Parsed_idet", StringComparison.OrdinalIgnoreCase)) + { + var idetResult = AnalyzeIdetResult(line); + + if (idetResult.HasValue) + { + if (!idetResult.Value) + { + return false; + } + + idetFoundInterlaced = true; + } + } + } } - + } catch { @@ -379,6 +407,90 @@ namespace MediaBrowser.MediaEncoding.Encoder 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) >= .65) + { + 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; } private bool EnableKeyframeExtraction(MediaSourceInfo mediaSource, MediaStream videoStream)