瀏覽代碼

merge branch master into media-attachments

dkanada 5 年之前
父節點
當前提交
aca31457c0
共有 100 個文件被更改,包括 577 次插入7073 次删除
  1. 2 2
      .ci/azure-pipelines.yml
  2. 1 0
      .github/ISSUE_TEMPLATE/bug_report.md
  3. 7 5
      .github/stale.yml
  4. 1 1
      .vscode/launch.json
  5. 0 17
      BDInfo/BDInfo.csproj
  6. 0 33
      BDInfo/BDInfoSettings.cs
  7. 0 449
      BDInfo/BDROM.cs
  8. 0 493
      BDInfo/LanguageCodes.cs
  9. 0 21
      BDInfo/Properties/AssemblyInfo.cs
  10. 0 5
      BDInfo/ReadMe.txt
  11. 0 309
      BDInfo/TSCodecAC3.cs
  12. 0 148
      BDInfo/TSCodecAVC.cs
  13. 0 159
      BDInfo/TSCodecDTS.cs
  14. 0 246
      BDInfo/TSCodecDTSHD.cs
  15. 0 123
      BDInfo/TSCodecLPCM.cs
  16. 0 208
      BDInfo/TSCodecMPEG2.cs
  17. 0 36
      BDInfo/TSCodecMVC.cs
  18. 0 186
      BDInfo/TSCodecTrueHD.cs
  19. 0 131
      BDInfo/TSCodecVC1.cs
  20. 0 37
      BDInfo/TSInterleavedFile.cs
  21. 0 1282
      BDInfo/TSPlaylistFile.cs
  22. 0 780
      BDInfo/TSStream.cs
  23. 0 130
      BDInfo/TSStreamBuffer.cs
  24. 0 107
      BDInfo/TSStreamClip.cs
  25. 0 244
      BDInfo/TSStreamClipFile.cs
  26. 0 1555
      BDInfo/TSStreamFile.cs
  27. 2 0
      CONTRIBUTORS.md
  28. 5 5
      Dockerfile
  29. 5 5
      Dockerfile.arm
  30. 5 5
      Dockerfile.arm64
  31. 93 28
      Emby.Dlna/Api/DlnaServerService.cs
  32. 2 3
      Emby.Dlna/ContentDirectory/ContentDirectory.cs
  33. 16 15
      Emby.Dlna/ContentDirectory/ControlHandler.cs
  34. 12 24
      Emby.Dlna/Eventing/EventManager.cs
  35. 1 1
      Emby.Dlna/PlayTo/PlayToManager.cs
  36. 9 14
      Emby.Dlna/Ssdp/DeviceDiscovery.cs
  37. 3 0
      Emby.Naming/Audio/AlbumParser.cs
  38. 3 0
      Emby.Naming/Audio/AudioFileParser.cs
  39. 3 0
      Emby.Naming/Audio/MultiPartResult.cs
  40. 1 1
      Emby.Naming/AudioBook/AudioBookFileInfo.cs
  41. 3 0
      Emby.Naming/AudioBook/AudioBookFilePathParser.cs
  42. 3 0
      Emby.Naming/AudioBook/AudioBookFilePathParserResult.cs
  43. 4 1
      Emby.Naming/AudioBook/AudioBookInfo.cs
  44. 3 0
      Emby.Naming/AudioBook/AudioBookListResolver.cs
  45. 3 0
      Emby.Naming/AudioBook/AudioBookResolver.cs
  46. 3 0
      Emby.Naming/Common/EpisodeExpression.cs
  47. 3 0
      Emby.Naming/Common/MediaType.cs
  48. 24 8
      Emby.Naming/Common/NamingOptions.cs
  49. 10 6
      Emby.Naming/Emby.Naming.csproj
  50. 3 0
      Emby.Naming/Subtitles/SubtitleInfo.cs
  51. 3 0
      Emby.Naming/Subtitles/SubtitleParser.cs
  52. 3 0
      Emby.Naming/TV/EpisodeInfo.cs
  53. 3 0
      Emby.Naming/TV/EpisodePathParser.cs
  54. 3 0
      Emby.Naming/TV/EpisodePathParserResult.cs
  55. 3 0
      Emby.Naming/TV/EpisodeResolver.cs
  56. 5 2
      Emby.Naming/TV/SeasonPathParser.cs
  57. 3 0
      Emby.Naming/TV/SeasonPathParserResult.cs
  58. 4 1
      Emby.Naming/Video/CleanDateTimeParser.cs
  59. 5 0
      Emby.Naming/Video/CleanDateTimeResult.cs
  60. 3 0
      Emby.Naming/Video/CleanStringParser.cs
  61. 4 0
      Emby.Naming/Video/CleanStringResult.cs
  62. 3 0
      Emby.Naming/Video/ExtraResolver.cs
  63. 4 0
      Emby.Naming/Video/ExtraResult.cs
  64. 6 0
      Emby.Naming/Video/ExtraRule.cs
  65. 5 0
      Emby.Naming/Video/ExtraRuleType.cs
  66. 9 4
      Emby.Naming/Video/FileStack.cs
  67. 3 0
      Emby.Naming/Video/FlagParser.cs
  68. 3 0
      Emby.Naming/Video/Format3DParser.cs
  69. 3 0
      Emby.Naming/Video/Format3DResult.cs
  70. 4 0
      Emby.Naming/Video/Format3DRule.cs
  71. 3 0
      Emby.Naming/Video/StackResolver.cs
  72. 3 0
      Emby.Naming/Video/StackResult.cs
  73. 3 0
      Emby.Naming/Video/StubResolver.cs
  74. 3 0
      Emby.Naming/Video/StubResult.cs
  75. 3 0
      Emby.Naming/Video/StubTypeRule.cs
  76. 2 1
      Emby.Naming/Video/VideoFileInfo.cs
  77. 11 8
      Emby.Naming/Video/VideoInfo.cs
  78. 3 0
      Emby.Naming/Video/VideoListResolver.cs
  79. 4 1
      Emby.Naming/Video/VideoResolver.cs
  80. 6 2
      Emby.Photos/Emby.Photos.csproj
  81. 17 2
      Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs
  82. 2 0
      Emby.Server.Implementations/Activity/ActivityManager.cs
  83. 2 0
      Emby.Server.Implementations/Activity/ActivityRepository.cs
  84. 27 11
      Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
  85. 2 2
      Emby.Server.Implementations/AppBase/ConfigurationHelper.cs
  86. 84 114
      Emby.Server.Implementations/ApplicationHost.cs
  87. 1 7
      Emby.Server.Implementations/Archiving/ZipClient.cs
  88. 2 0
      Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs
  89. 2 1
      Emby.Server.Implementations/Browser/BrowserLauncher.cs
  90. 8 0
      Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs
  91. 2 0
      Emby.Server.Implementations/Channels/ChannelImageProvider.cs
  92. 9 7
      Emby.Server.Implementations/Channels/ChannelManager.cs
  93. 2 0
      Emby.Server.Implementations/Channels/ChannelPostScanTask.cs
  94. 2 0
      Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs
  95. 2 1
      Emby.Server.Implementations/Collections/CollectionImageProvider.cs
  96. 13 39
      Emby.Server.Implementations/Collections/CollectionManager.cs
  97. 23 38
      Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
  98. 5 2
      Emby.Server.Implementations/ConfigurationOptions.cs
  99. 16 7
      Emby.Server.Implementations/Cryptography/CryptographyProvider.cs
  100. 6 0
      Emby.Server.Implementations/Data/BaseSqliteRepository.cs

+ 2 - 2
.ci/azure-pipelines.yml

@@ -200,8 +200,8 @@ jobs:
       persistCredentials: true
       persistCredentials: true
 
 
     - task: CmdLine@2
     - task: CmdLine@2
-      displayName: "Check out web"
-      condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
+      displayName: "Check out web (master, release or tag)"
+      condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master'), contains(variables['Build.SourceBranch'], 'tag')) ,eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion'))
       inputs:
       inputs:
         script: 'git clone --single-branch --branch $(Build.SourceBranchName) --depth=1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web'
         script: 'git clone --single-branch --branch $(Build.SourceBranchName) --depth=1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web'
 
 

+ 1 - 0
.github/ISSUE_TEMPLATE/bug_report.md

@@ -30,6 +30,7 @@ assignees: ''
  - OS: [e.g. Docker, Debian, Windows]
  - OS: [e.g. Docker, Debian, Windows]
  - Browser: [e.g. Firefox, Chrome, Safari]
  - Browser: [e.g. Firefox, Chrome, Safari]
  - Jellyfin Version: [e.g. 10.0.1]
  - Jellyfin Version: [e.g. 10.0.1]
+ - Installed Plugins: [e.g. none, Fanart, Anime, etc.]
  - Reverse proxy: [e.g. no, nginx, apache, etc.]
  - Reverse proxy: [e.g. no, nginx, apache, etc.]
 
 
 **Additional context**
 **Additional context**

+ 7 - 5
.github/stale.yml

@@ -1,7 +1,7 @@
 # Number of days of inactivity before an issue becomes stale
 # Number of days of inactivity before an issue becomes stale
-daysUntilStale: 90
+daysUntilStale: 120
 # Number of days of inactivity before a stale issue is closed
 # Number of days of inactivity before a stale issue is closed
-daysUntilClose: 14
+daysUntilClose: 21
 # Issues with these labels will never be considered stale
 # Issues with these labels will never be considered stale
 exemptLabels:
 exemptLabels:
   - regression
   - regression
@@ -16,8 +16,10 @@ exemptLabels:
 staleLabel: stale
 staleLabel: stale
 # Comment to post when marking an issue as stale. Set to `false` to disable
 # Comment to post when marking an issue as stale. Set to `false` to disable
 markComment: >
 markComment: >
-  Issues go stale after 90d of inactivity. Mark the issue as fresh by adding a comment or commit. Stale issues close after an additional 14d of inactivity.
-  If this issue is safe to close now please do so.
-  If you have any questions you can reach us on [Matrix or Social Media](https://docs.jellyfin.org/general/getting-help.html).
+  This issue has gone 120 days without comment. To avoid abandoned issues, it will be closed in 21 days if there are no new comments.
+  
+  If you're the original submitter of this issue, please comment confirming if this issue still affects you in the latest release or nightlies, or close the issue if it has been fixed. If you're another user also affected by this bug, please comment confirming so. Either action will remove the stale label.
+
+  This bot exists to prevent issues from becoming stale and forgotten. Jellyfin is always moving forward, and bugs are often fixed as side effects of other changes. We therefore ask that bug report authors remain vigilant about their issues to ensure they are closed if fixed, or re-confirmed - perhaps with fresh logs or reproduction examples - regularly. If you have any questions you can reach us on [Matrix or Social Media](https://docs.jellyfin.org/general/getting-help.html).
 # Comment to post when closing a stale issue. Set to `false` to disable
 # Comment to post when closing a stale issue. Set to `false` to disable
 closeComment: false
 closeComment: false

+ 1 - 1
.vscode/launch.json

@@ -10,7 +10,7 @@
             "request": "launch",
             "request": "launch",
             "preLaunchTask": "build",
             "preLaunchTask": "build",
             // If you have changed target frameworks, make sure to update the program path.
             // If you have changed target frameworks, make sure to update the program path.
-            "program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/netcoreapp3.0/jellyfin.dll",
+            "program": "${workspaceFolder}/Jellyfin.Server/bin/Debug/netcoreapp3.1/jellyfin.dll",
             "args": [],
             "args": [],
             "cwd": "${workspaceFolder}/Jellyfin.Server",
             "cwd": "${workspaceFolder}/Jellyfin.Server",
             // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
             // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window

+ 0 - 17
BDInfo/BDInfo.csproj

@@ -1,17 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <ItemGroup>
-    <Compile Include="..\SharedVersion.cs" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
-  </ItemGroup>
-
-  <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
-    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
-    <GenerateDocumentationFile>true</GenerateDocumentationFile>
-  </PropertyGroup>
-
-</Project>

+ 0 - 33
BDInfo/BDInfoSettings.cs

@@ -1,33 +0,0 @@
-
-namespace BDInfo
-{
-    class BDInfoSettings
-    {
-        public static bool GenerateStreamDiagnostics => true;
-
-        public static bool EnableSSIF => true;
-
-        public static bool AutosaveReport => false;
-
-        public static bool GenerateFrameDataFile => false;
-
-        public static bool FilterLoopingPlaylists => true;
-
-        public static bool FilterShortPlaylists => false;
-
-        public static int FilterShortPlaylistsValue => 0;
-
-        public static bool UseImagePrefix => false;
-
-        public static string UseImagePrefixValue => null;
-
-        /// <summary>
-        /// Setting this to false throws an IComparer error on some discs.
-        /// </summary>
-        public static bool KeepStreamOrder => true;
-
-        public static bool GenerateTextSummary => false;
-
-        public static string LastPath => string.Empty;
-    }
-}

+ 0 - 449
BDInfo/BDROM.cs

@@ -1,449 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using MediaBrowser.Model.IO;
-
-namespace BDInfo
-{
-    public class BDROM
-    {
-        public FileSystemMetadata DirectoryRoot = null;
-        public FileSystemMetadata DirectoryBDMV = null;
-        public FileSystemMetadata DirectoryBDJO = null;
-        public FileSystemMetadata DirectoryCLIPINF = null;
-        public FileSystemMetadata DirectoryPLAYLIST = null;
-        public FileSystemMetadata DirectorySNP = null;
-        public FileSystemMetadata DirectorySSIF = null;
-        public FileSystemMetadata DirectorySTREAM = null;
-
-        public string VolumeLabel = null;
-        public ulong Size = 0;
-        public bool IsBDPlus = false;
-        public bool IsBDJava = false;
-        public bool IsDBOX = false;
-        public bool IsPSP = false;
-        public bool Is3D = false;
-        public bool Is50Hz = false;
-
-        private readonly IFileSystem _fileSystem;
-
-        public Dictionary<string, TSPlaylistFile> PlaylistFiles =
-            new Dictionary<string, TSPlaylistFile>();
-        public Dictionary<string, TSStreamClipFile> StreamClipFiles =
-            new Dictionary<string, TSStreamClipFile>();
-        public Dictionary<string, TSStreamFile> StreamFiles =
-            new Dictionary<string, TSStreamFile>();
-        public Dictionary<string, TSInterleavedFile> InterleavedFiles =
-            new Dictionary<string, TSInterleavedFile>();
-
-        public delegate bool OnStreamClipFileScanError(
-            TSStreamClipFile streamClipFile, Exception ex);
-
-        public event OnStreamClipFileScanError StreamClipFileScanError;
-
-        public delegate bool OnStreamFileScanError(
-            TSStreamFile streamClipFile, Exception ex);
-
-        public event OnStreamFileScanError StreamFileScanError;
-
-        public delegate bool OnPlaylistFileScanError(
-            TSPlaylistFile playlistFile, Exception ex);
-
-        public event OnPlaylistFileScanError PlaylistFileScanError;
-
-        public BDROM(string path, IFileSystem fileSystem)
-        {
-            if (string.IsNullOrEmpty(path))
-            {
-                throw new ArgumentNullException(nameof(path));
-            }
-
-            _fileSystem = fileSystem;
-            //
-            // Locate BDMV directories.
-            //
-
-            DirectoryBDMV =
-                GetDirectoryBDMV(path);
-
-            if (DirectoryBDMV == null)
-            {
-                throw new Exception("Unable to locate BD structure.");
-            }
-
-            DirectoryRoot =
-                _fileSystem.GetDirectoryInfo(Path.GetDirectoryName(DirectoryBDMV.FullName));
-            DirectoryBDJO =
-                GetDirectory("BDJO", DirectoryBDMV, 0);
-            DirectoryCLIPINF =
-                GetDirectory("CLIPINF", DirectoryBDMV, 0);
-            DirectoryPLAYLIST =
-                GetDirectory("PLAYLIST", DirectoryBDMV, 0);
-            DirectorySNP =
-                GetDirectory("SNP", DirectoryRoot, 0);
-            DirectorySTREAM =
-                GetDirectory("STREAM", DirectoryBDMV, 0);
-            DirectorySSIF =
-                GetDirectory("SSIF", DirectorySTREAM, 0);
-
-            if (DirectoryCLIPINF == null
-                || DirectoryPLAYLIST == null)
-            {
-                throw new Exception("Unable to locate BD structure.");
-            }
-
-            //
-            // Initialize basic disc properties.
-            //
-
-            VolumeLabel = GetVolumeLabel(DirectoryRoot);
-            Size = (ulong)GetDirectorySize(DirectoryRoot);
-
-            if (null != GetDirectory("BDSVM", DirectoryRoot, 0))
-            {
-                IsBDPlus = true;
-            }
-            if (null != GetDirectory("SLYVM", DirectoryRoot, 0))
-            {
-                IsBDPlus = true;
-            }
-            if (null != GetDirectory("ANYVM", DirectoryRoot, 0))
-            {
-                IsBDPlus = true;
-            }
-
-            if (DirectoryBDJO != null &&
-                _fileSystem.GetFilePaths(DirectoryBDJO.FullName).Any())
-            {
-                IsBDJava = true;
-            }
-
-            if (DirectorySNP != null &&
-                GetFilePaths(DirectorySNP.FullName, ".mnv").Any())
-            {
-                IsPSP = true;
-            }
-
-            if (DirectorySSIF != null &&
-                _fileSystem.GetFilePaths(DirectorySSIF.FullName).Any())
-            {
-                Is3D = true;
-            }
-
-            if (File.Exists(Path.Combine(DirectoryRoot.FullName, "FilmIndex.xml")))
-            {
-                IsDBOX = true;
-            }
-
-            //
-            // Initialize file lists.
-            //
-
-            if (DirectoryPLAYLIST != null)
-            {
-                FileSystemMetadata[] files = GetFiles(DirectoryPLAYLIST.FullName, ".mpls").ToArray();
-                foreach (var file in files)
-                {
-                    PlaylistFiles.Add(
-                        file.Name.ToUpper(), new TSPlaylistFile(this, file));
-                }
-            }
-
-            if (DirectorySTREAM != null)
-            {
-                FileSystemMetadata[] files = GetFiles(DirectorySTREAM.FullName, ".m2ts").ToArray();
-                foreach (var file in files)
-                {
-                    StreamFiles.Add(
-                        file.Name.ToUpper(), new TSStreamFile(file, _fileSystem));
-                }
-            }
-
-            if (DirectoryCLIPINF != null)
-            {
-                FileSystemMetadata[] files = GetFiles(DirectoryCLIPINF.FullName, ".clpi").ToArray();
-                foreach (var file in files)
-                {
-                    StreamClipFiles.Add(
-                        file.Name.ToUpper(), new TSStreamClipFile(file));
-                }
-            }
-
-            if (DirectorySSIF != null)
-            {
-                FileSystemMetadata[] files = GetFiles(DirectorySSIF.FullName, ".ssif").ToArray();
-                foreach (var file in files)
-                {
-                    InterleavedFiles.Add(
-                        file.Name.ToUpper(), new TSInterleavedFile(file));
-                }
-            }
-        }
-
-        private IEnumerable<FileSystemMetadata> GetFiles(string path, string extension)
-        {
-            return _fileSystem.GetFiles(path, new[] { extension }, false, false);
-        }
-
-        private IEnumerable<string> GetFilePaths(string path, string extension)
-        {
-            return _fileSystem.GetFilePaths(path, new[] { extension }, false, false);
-        }
-
-        public void Scan()
-        {
-            foreach (var streamClipFile in StreamClipFiles.Values)
-            {
-                try
-                {
-                    streamClipFile.Scan();
-                }
-                catch (Exception ex)
-                {
-                    if (StreamClipFileScanError != null)
-                    {
-                        if (StreamClipFileScanError(streamClipFile, ex))
-                        {
-                            continue;
-                        }
-                        else
-                        {
-                            break;
-                        }
-                    }
-                    else throw;
-                }
-            }
-
-            foreach (var streamFile in StreamFiles.Values)
-            {
-                string ssifName = Path.GetFileNameWithoutExtension(streamFile.Name) + ".SSIF";
-                if (InterleavedFiles.ContainsKey(ssifName))
-                {
-                    streamFile.InterleavedFile = InterleavedFiles[ssifName];
-                }
-            }
-
-            TSStreamFile[] streamFiles = new TSStreamFile[StreamFiles.Count];
-            StreamFiles.Values.CopyTo(streamFiles, 0);
-            Array.Sort(streamFiles, CompareStreamFiles);
-
-            foreach (var playlistFile in PlaylistFiles.Values)
-            {
-                try
-                {
-                    playlistFile.Scan(StreamFiles, StreamClipFiles);
-                }
-                catch (Exception ex)
-                {
-                    if (PlaylistFileScanError != null)
-                    {
-                        if (PlaylistFileScanError(playlistFile, ex))
-                        {
-                            continue;
-                        }
-                        else
-                        {
-                            break;
-                        }
-                    }
-                    else throw;
-                }
-            }
-
-            foreach (var streamFile in streamFiles)
-            {
-                try
-                {
-                    var playlists = new List<TSPlaylistFile>();
-                    foreach (var playlist in PlaylistFiles.Values)
-                    {
-                        foreach (var streamClip in playlist.StreamClips)
-                        {
-                            if (streamClip.Name == streamFile.Name)
-                            {
-                                playlists.Add(playlist);
-                                break;
-                            }
-                        }
-                    }
-                    streamFile.Scan(playlists, false);
-                }
-                catch (Exception ex)
-                {
-                    if (StreamFileScanError != null)
-                    {
-                        if (StreamFileScanError(streamFile, ex))
-                        {
-                            continue;
-                        }
-                        else
-                        {
-                            break;
-                        }
-                    }
-                    else throw;
-                }
-            }
-
-            foreach (var playlistFile in PlaylistFiles.Values)
-            {
-                playlistFile.Initialize();
-                if (!Is50Hz)
-                {
-                    foreach (var videoStream in playlistFile.VideoStreams)
-                    {
-                        if (videoStream.FrameRate == TSFrameRate.FRAMERATE_25 ||
-                            videoStream.FrameRate == TSFrameRate.FRAMERATE_50)
-                        {
-                            Is50Hz = true;
-                        }
-                    }
-                }
-            }
-        }
-
-        private FileSystemMetadata GetDirectoryBDMV(
-            string path)
-        {
-            if (string.IsNullOrEmpty(path))
-            {
-                throw new ArgumentNullException(nameof(path));
-            }
-
-            FileSystemMetadata dir = _fileSystem.GetDirectoryInfo(path);
-
-            while (dir != null)
-            {
-                if (string.Equals(dir.Name, "BDMV", StringComparison.OrdinalIgnoreCase))
-                {
-                    return dir;
-                }
-                var parentFolder = Path.GetDirectoryName(dir.FullName);
-                if (string.IsNullOrEmpty(parentFolder))
-                {
-                    dir = null;
-                }
-                else
-                {
-                    dir = _fileSystem.GetDirectoryInfo(parentFolder);
-                }
-            }
-
-            return GetDirectory("BDMV", _fileSystem.GetDirectoryInfo(path), 0);
-        }
-
-        private FileSystemMetadata GetDirectory(
-            string name,
-            FileSystemMetadata dir,
-            int searchDepth)
-        {
-            if (dir != null)
-            {
-                FileSystemMetadata[] children = _fileSystem.GetDirectories(dir.FullName).ToArray();
-                foreach (var child in children)
-                {
-                    if (string.Equals(child.Name, name, StringComparison.OrdinalIgnoreCase))
-                    {
-                        return child;
-                    }
-                }
-                if (searchDepth > 0)
-                {
-                    foreach (var child in children)
-                    {
-                        GetDirectory(
-                            name, child, searchDepth - 1);
-                    }
-                }
-            }
-            return null;
-        }
-
-        private long GetDirectorySize(FileSystemMetadata directoryInfo)
-        {
-            long size = 0;
-
-            //if (!ExcludeDirs.Contains(directoryInfo.Name.ToUpper()))  // TODO: Keep?
-            {
-                FileSystemMetadata[] pathFiles = _fileSystem.GetFiles(directoryInfo.FullName).ToArray();
-                foreach (var pathFile in pathFiles)
-                {
-                    if (pathFile.Extension.ToUpper() == ".SSIF")
-                    {
-                        continue;
-                    }
-                    size += pathFile.Length;
-                }
-
-                FileSystemMetadata[] pathChildren = _fileSystem.GetDirectories(directoryInfo.FullName).ToArray();
-                foreach (var pathChild in pathChildren)
-                {
-                    size += GetDirectorySize(pathChild);
-                }
-            }
-
-            return size;
-        }
-
-        private string GetVolumeLabel(FileSystemMetadata dir)
-        {
-            return dir.Name;
-        }
-
-        public int CompareStreamFiles(
-            TSStreamFile x,
-            TSStreamFile y)
-        {
-            // TODO: Use interleaved file sizes
-
-            if ((x == null || x.FileInfo == null) && (y == null || y.FileInfo == null))
-            {
-                return 0;
-            }
-            else if ((x == null || x.FileInfo == null) && (y != null && y.FileInfo != null))
-            {
-                return 1;
-            }
-            else if ((x != null && x.FileInfo != null) && (y == null || y.FileInfo == null))
-            {
-                return -1;
-            }
-            else
-            {
-                if (x.FileInfo.Length > y.FileInfo.Length)
-                {
-                    return 1;
-                }
-                else if (y.FileInfo.Length > x.FileInfo.Length)
-                {
-                    return -1;
-                }
-                else
-                {
-                    return 0;
-                }
-            }
-        }
-    }
-}

+ 0 - 493
BDInfo/LanguageCodes.cs

@@ -1,493 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-
-namespace BDInfo
-{
-    public abstract class LanguageCodes
-    {
-        public static string GetName(string code)
-        {
-            switch (code)
-            {
-                case "abk": return "Abkhazian";
-                case "ace": return "Achinese";
-                case "ach": return "Acoli";
-                case "ada": return "Adangme";
-                case "aar": return "Afar";
-                case "afh": return "Afrihili";
-                case "afr": return "Afrikaans";
-                case "afa": return "Afro-Asiatic (Other)";
-                case "aka": return "Akan";
-                case "akk": return "Akkadian";
-                case "alb": return "Albanian";
-                case "sqi": return "Albanian";
-                case "ale": return "Aleut";
-                case "alg": return "Algonquian languages";
-                case "tut": return "Altaic (Other)";
-                case "amh": return "Amharic";
-                case "apa": return "Apache languages";
-                case "ara": return "Arabic";
-                case "arc": return "Aramaic";
-                case "arp": return "Arapaho";
-                case "arn": return "Araucanian";
-                case "arw": return "Arawak";
-                case "arm": return "Armenian";
-                case "hye": return "Armenian";
-                case "art": return "Artificial (Other)";
-                case "asm": return "Assamese";
-                case "ath": return "Athapascan languages";
-                case "aus": return "Australian languages";
-                case "map": return "Austronesian (Other)";
-                case "ava": return "Avaric";
-                case "ave": return "Avestan";
-                case "awa": return "Awadhi";
-                case "aym": return "Aymara";
-                case "aze": return "Azerbaijani";
-                case "ban": return "Balinese";
-                case "bat": return "Baltic (Other)";
-                case "bal": return "Baluchi";
-                case "bam": return "Bambara";
-                case "bai": return "Bamileke languages";
-                case "bad": return "Banda";
-                case "bnt": return "Bantu (Other)";
-                case "bas": return "Basa";
-                case "bak": return "Bashkir";
-                case "baq": return "Basque";
-                case "eus": return "Basque";
-                case "btk": return "Batak (Indonesia)";
-                case "bej": return "Beja";
-                case "bel": return "Belarusian";
-                case "bem": return "Bemba";
-                case "ben": return "Bengali";
-                case "ber": return "Berber (Other)";
-                case "bho": return "Bhojpuri";
-                case "bih": return "Bihari";
-                case "bik": return "Bikol";
-                case "bin": return "Bini";
-                case "bis": return "Bislama";
-                case "bos": return "Bosnian";
-                case "bra": return "Braj";
-                case "bre": return "Breton";
-                case "bug": return "Buginese";
-                case "bul": return "Bulgarian";
-                case "bua": return "Buriat";
-                case "bur": return "Burmese";
-                case "mya": return "Burmese";
-                case "cad": return "Caddo";
-                case "car": return "Carib";
-                case "cat": return "Catalan";
-                case "cau": return "Caucasian (Other)";
-                case "ceb": return "Cebuano";
-                case "cel": return "Celtic (Other)";
-                case "cai": return "Central American Indian (Other)";
-                case "chg": return "Chagatai";
-                case "cmc": return "Chamic languages";
-                case "cha": return "Chamorro";
-                case "che": return "Chechen";
-                case "chr": return "Cherokee";
-                case "chy": return "Cheyenne";
-                case "chb": return "Chibcha";
-                case "chi": return "Chinese";
-                case "zho": return "Chinese";
-                case "chn": return "Chinook jargon";
-                case "chp": return "Chipewyan";
-                case "cho": return "Choctaw";
-                case "chu": return "Church Slavic";
-                case "chk": return "Chuukese";
-                case "chv": return "Chuvash";
-                case "cop": return "Coptic";
-                case "cor": return "Cornish";
-                case "cos": return "Corsican";
-                case "cre": return "Cree";
-                case "mus": return "Creek";
-                case "crp": return "Creoles and pidgins (Other)";
-                case "cpe": return "Creoles and pidgins,";
-                case "cpf": return "Creoles and pidgins,";
-                case "cpp": return "Creoles and pidgins,";
-                case "scr": return "Croatian";
-                case "hrv": return "Croatian";
-                case "cus": return "Cushitic (Other)";
-                case "cze": return "Czech";
-                case "ces": return "Czech";
-                case "dak": return "Dakota";
-                case "dan": return "Danish";
-                case "day": return "Dayak";
-                case "del": return "Delaware";
-                case "din": return "Dinka";
-                case "div": return "Divehi";
-                case "doi": return "Dogri";
-                case "dgr": return "Dogrib";
-                case "dra": return "Dravidian (Other)";
-                case "dua": return "Duala";
-                case "dut": return "Dutch";
-                case "nld": return "Dutch";
-                case "dum": return "Dutch, Middle (ca. 1050-1350)";
-                case "dyu": return "Dyula";
-                case "dzo": return "Dzongkha";
-                case "efi": return "Efik";
-                case "egy": return "Egyptian (Ancient)";
-                case "eka": return "Ekajuk";
-                case "elx": return "Elamite";
-                case "eng": return "English";
-                case "enm": return "English, Middle (1100-1500)";
-                case "ang": return "English, Old (ca.450-1100)";
-                case "epo": return "Esperanto";
-                case "est": return "Estonian";
-                case "ewe": return "Ewe";
-                case "ewo": return "Ewondo";
-                case "fan": return "Fang";
-                case "fat": return "Fanti";
-                case "fao": return "Faroese";
-                case "fij": return "Fijian";
-                case "fin": return "Finnish";
-                case "fiu": return "Finno-Ugrian (Other)";
-                case "fon": return "Fon";
-                case "fre": return "French";
-                case "fra": return "French";
-                case "frm": return "French, Middle (ca.1400-1600)";
-                case "fro": return "French, Old (842-ca.1400)";
-                case "fry": return "Frisian";
-                case "fur": return "Friulian";
-                case "ful": return "Fulah";
-                case "gaa": return "Ga";
-                case "glg": return "Gallegan";
-                case "lug": return "Ganda";
-                case "gay": return "Gayo";
-                case "gba": return "Gbaya";
-                case "gez": return "Geez";
-                case "geo": return "Georgian";
-                case "kat": return "Georgian";
-                case "ger": return "German";
-                case "deu": return "German";
-                case "nds": return "Saxon";
-                case "gmh": return "German, Middle High (ca.1050-1500)";
-                case "goh": return "German, Old High (ca.750-1050)";
-                case "gem": return "Germanic (Other)";
-                case "gil": return "Gilbertese";
-                case "gon": return "Gondi";
-                case "gor": return "Gorontalo";
-                case "got": return "Gothic";
-                case "grb": return "Grebo";
-                case "grc": return "Greek, Ancient (to 1453)";
-                case "gre": return "Greek";
-                case "ell": return "Greek";
-                case "grn": return "Guarani";
-                case "guj": return "Gujarati";
-                case "gwi": return "Gwich´in";
-                case "hai": return "Haida";
-                case "hau": return "Hausa";
-                case "haw": return "Hawaiian";
-                case "heb": return "Hebrew";
-                case "her": return "Herero";
-                case "hil": return "Hiligaynon";
-                case "him": return "Himachali";
-                case "hin": return "Hindi";
-                case "hmo": return "Hiri Motu";
-                case "hit": return "Hittite";
-                case "hmn": return "Hmong";
-                case "hun": return "Hungarian";
-                case "hup": return "Hupa";
-                case "iba": return "Iban";
-                case "ice": return "Icelandic";
-                case "isl": return "Icelandic";
-                case "ibo": return "Igbo";
-                case "ijo": return "Ijo";
-                case "ilo": return "Iloko";
-                case "inc": return "Indic (Other)";
-                case "ine": return "Indo-European (Other)";
-                case "ind": return "Indonesian";
-                case "ina": return "Interlingua (International";
-                case "ile": return "Interlingue";
-                case "iku": return "Inuktitut";
-                case "ipk": return "Inupiaq";
-                case "ira": return "Iranian (Other)";
-                case "gle": return "Irish";
-                case "mga": return "Irish, Middle (900-1200)";
-                case "sga": return "Irish, Old (to 900)";
-                case "iro": return "Iroquoian languages";
-                case "ita": return "Italian";
-                case "jpn": return "Japanese";
-                case "jav": return "Javanese";
-                case "jrb": return "Judeo-Arabic";
-                case "jpr": return "Judeo-Persian";
-                case "kab": return "Kabyle";
-                case "kac": return "Kachin";
-                case "kal": return "Kalaallisut";
-                case "kam": return "Kamba";
-                case "kan": return "Kannada";
-                case "kau": return "Kanuri";
-                case "kaa": return "Kara-Kalpak";
-                case "kar": return "Karen";
-                case "kas": return "Kashmiri";
-                case "kaw": return "Kawi";
-                case "kaz": return "Kazakh";
-                case "kha": return "Khasi";
-                case "khm": return "Khmer";
-                case "khi": return "Khoisan (Other)";
-                case "kho": return "Khotanese";
-                case "kik": return "Kikuyu";
-                case "kmb": return "Kimbundu";
-                case "kin": return "Kinyarwanda";
-                case "kir": return "Kirghiz";
-                case "kom": return "Komi";
-                case "kon": return "Kongo";
-                case "kok": return "Konkani";
-                case "kor": return "Korean";
-                case "kos": return "Kosraean";
-                case "kpe": return "Kpelle";
-                case "kro": return "Kru";
-                case "kua": return "Kuanyama";
-                case "kum": return "Kumyk";
-                case "kur": return "Kurdish";
-                case "kru": return "Kurukh";
-                case "kut": return "Kutenai";
-                case "lad": return "Ladino";
-                case "lah": return "Lahnda";
-                case "lam": return "Lamba";
-                case "lao": return "Lao";
-                case "lat": return "Latin";
-                case "lav": return "Latvian";
-                case "ltz": return "Letzeburgesch";
-                case "lez": return "Lezghian";
-                case "lin": return "Lingala";
-                case "lit": return "Lithuanian";
-                case "loz": return "Lozi";
-                case "lub": return "Luba-Katanga";
-                case "lua": return "Luba-Lulua";
-                case "lui": return "Luiseno";
-                case "lun": return "Lunda";
-                case "luo": return "Luo (Kenya and Tanzania)";
-                case "lus": return "Lushai";
-                case "mac": return "Macedonian";
-                case "mkd": return "Macedonian";
-                case "mad": return "Madurese";
-                case "mag": return "Magahi";
-                case "mai": return "Maithili";
-                case "mak": return "Makasar";
-                case "mlg": return "Malagasy";
-                case "may": return "Malay";
-                case "msa": return "Malay";
-                case "mal": return "Malayalam";
-                case "mlt": return "Maltese";
-                case "mnc": return "Manchu";
-                case "mdr": return "Mandar";
-                case "man": return "Mandingo";
-                case "mni": return "Manipuri";
-                case "mno": return "Manobo languages";
-                case "glv": return "Manx";
-                case "mao": return "Maori";
-                case "mri": return "Maori";
-                case "mar": return "Marathi";
-                case "chm": return "Mari";
-                case "mah": return "Marshall";
-                case "mwr": return "Marwari";
-                case "mas": return "Masai";
-                case "myn": return "Mayan languages";
-                case "men": return "Mende";
-                case "mic": return "Micmac";
-                case "min": return "Minangkabau";
-                case "mis": return "Miscellaneous languages";
-                case "moh": return "Mohawk";
-                case "mol": return "Moldavian";
-                case "mkh": return "Mon-Khmer (Other)";
-                case "lol": return "Mongo";
-                case "mon": return "Mongolian";
-                case "mos": return "Mossi";
-                case "mul": return "Multiple languages";
-                case "mun": return "Munda languages";
-                case "nah": return "Nahuatl";
-                case "nau": return "Nauru";
-                case "nav": return "Navajo";
-                case "nde": return "Ndebele, North";
-                case "nbl": return "Ndebele, South";
-                case "ndo": return "Ndonga";
-                case "nep": return "Nepali";
-                case "new": return "Newari";
-                case "nia": return "Nias";
-                case "nic": return "Niger-Kordofanian (Other)";
-                case "ssa": return "Nilo-Saharan (Other)";
-                case "niu": return "Niuean";
-                case "non": return "Norse, Old";
-                case "nai": return "North American Indian (Other)";
-                case "sme": return "Northern Sami";
-                case "nor": return "Norwegian";
-                case "nob": return "Norwegian Bokmål";
-                case "nno": return "Norwegian Nynorsk";
-                case "nub": return "Nubian languages";
-                case "nym": return "Nyamwezi";
-                case "nya": return "Nyanja";
-                case "nyn": return "Nyankole";
-                case "nyo": return "Nyoro";
-                case "nzi": return "Nzima";
-                case "oci": return "Occitan";
-                case "oji": return "Ojibwa";
-                case "ori": return "Oriya";
-                case "orm": return "Oromo";
-                case "osa": return "Osage";
-                case "oss": return "Ossetian";
-                case "oto": return "Otomian languages";
-                case "pal": return "Pahlavi";
-                case "pau": return "Palauan";
-                case "pli": return "Pali";
-                case "pam": return "Pampanga";
-                case "pag": return "Pangasinan";
-                case "pan": return "Panjabi";
-                case "pap": return "Papiamento";
-                case "paa": return "Papuan (Other)";
-                case "per": return "Persian";
-                case "fas": return "Persian";
-                case "peo": return "Persian, Old (ca.600-400 B.C.)";
-                case "phi": return "Philippine (Other)";
-                case "phn": return "Phoenician";
-                case "pon": return "Pohnpeian";
-                case "pol": return "Polish";
-                case "por": return "Portuguese";
-                case "pra": return "Prakrit languages";
-                case "pro": return "Provençal";
-                case "pus": return "Pushto";
-                case "que": return "Quechua";
-                case "roh": return "Raeto-Romance";
-                case "raj": return "Rajasthani";
-                case "rap": return "Rapanui";
-                case "rar": return "Rarotongan";
-                case "roa": return "Romance (Other)";
-                case "rum": return "Romanian";
-                case "ron": return "Romanian";
-                case "rom": return "Romany";
-                case "run": return "Rundi";
-                case "rus": return "Russian";
-                case "sal": return "Salishan languages";
-                case "sam": return "Samaritan Aramaic";
-                case "smi": return "Sami languages (Other)";
-                case "smo": return "Samoan";
-                case "sad": return "Sandawe";
-                case "sag": return "Sango";
-                case "san": return "Sanskrit";
-                case "sat": return "Santali";
-                case "srd": return "Sardinian";
-                case "sas": return "Sasak";
-                case "sco": return "Scots";
-                case "gla": return "Gaelic";
-                case "sel": return "Selkup";
-                case "sem": return "Semitic (Other)";
-                case "scc": return "Serbian";
-                case "srp": return "Serbian";
-                case "srr": return "Serer";
-                case "shn": return "Shan";
-                case "sna": return "Shona";
-                case "sid": return "Sidamo";
-                case "sgn": return "Sign languages";
-                case "bla": return "Siksika";
-                case "snd": return "Sindhi";
-                case "sin": return "Sinhalese";
-                case "sit": return "Sino-Tibetan (Other)";
-                case "sio": return "Siouan languages";
-                case "den": return "Slave (Athapascan)";
-                case "sla": return "Slavic (Other)";
-                case "slo": return "Slovak";
-                case "slk": return "Slovak";
-                case "slv": return "Slovenian";
-                case "sog": return "Sogdian";
-                case "som": return "Somali";
-                case "son": return "Songhai";
-                case "snk": return "Soninke";
-                case "wen": return "Sorbian languages";
-                case "nso": return "Sotho, Northern";
-                case "sot": return "Sotho, Southern";
-                case "sai": return "South American Indian (Other)";
-                case "spa": return "Spanish";
-                case "suk": return "Sukuma";
-                case "sux": return "Sumerian";
-                case "sun": return "Sundanese";
-                case "sus": return "Susu";
-                case "swa": return "Swahili";
-                case "ssw": return "Swati";
-                case "swe": return "Swedish";
-                case "syr": return "Syriac";
-                case "tgl": return "Tagalog";
-                case "tah": return "Tahitian";
-                case "tai": return "Tai (Other)";
-                case "tgk": return "Tajik";
-                case "tmh": return "Tamashek";
-                case "tam": return "Tamil";
-                case "tat": return "Tatar";
-                case "tel": return "Telugu";
-                case "ter": return "Tereno";
-                case "tet": return "Tetum";
-                case "tha": return "Thai";
-                case "tib": return "Tibetan";
-                case "bod": return "Tibetan";
-                case "tig": return "Tigre";
-                case "tir": return "Tigrinya";
-                case "tem": return "Timne";
-                case "tiv": return "Tiv";
-                case "tli": return "Tlingit";
-                case "tpi": return "Tok Pisin";
-                case "tkl": return "Tokelau";
-                case "tog": return "Tonga (Nyasa)";
-                case "ton": return "Tonga (Tonga Islands)";
-                case "tsi": return "Tsimshian";
-                case "tso": return "Tsonga";
-                case "tsn": return "Tswana";
-                case "tum": return "Tumbuka";
-                case "tur": return "Turkish";
-                case "ota": return "Turkish, Ottoman (1500-1928)";
-                case "tuk": return "Turkmen";
-                case "tvl": return "Tuvalu";
-                case "tyv": return "Tuvinian";
-                case "twi": return "Twi";
-                case "uga": return "Ugaritic";
-                case "uig": return "Uighur";
-                case "ukr": return "Ukrainian";
-                case "umb": return "Umbundu";
-                case "und": return "Undetermined";
-                case "urd": return "Urdu";
-                case "uzb": return "Uzbek";
-                case "vai": return "Vai";
-                case "ven": return "Venda";
-                case "vie": return "Vietnamese";
-                case "vol": return "Volapük";
-                case "vot": return "Votic";
-                case "wak": return "Wakashan languages";
-                case "wal": return "Walamo";
-                case "war": return "Waray";
-                case "was": return "Washo";
-                case "wel": return "Welsh";
-                case "cym": return "Welsh";
-                case "wol": return "Wolof";
-                case "xho": return "Xhosa";
-                case "sah": return "Yakut";
-                case "yao": return "Yao";
-                case "yap": return "Yapese";
-                case "yid": return "Yiddish";
-                case "yor": return "Yoruba";
-                case "ypk": return "Yupik languages";
-                case "znd": return "Zande";
-                case "zap": return "Zapotec";
-                case "zen": return "Zenaga";
-                case "zha": return "Zhuang";
-                case "zul": return "Zulu";
-                case "zun": return "Zuni";
-
-                default: return code;
-            }
-        }
-    }
-}

+ 0 - 21
BDInfo/Properties/AssemblyInfo.cs

@@ -1,21 +0,0 @@
-using System.Reflection;
-using System.Resources;
-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("BDInfo")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Jellyfin Project")]
-[assembly: AssemblyProduct("Jellyfin Server")]
-[assembly: AssemblyCopyright("Copyright ©  2016 CinemaSquid. Copyright ©  2019 Jellyfin Contributors. Code released under the GNU General Public License")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: NeutralResourcesLanguage("en")]
-
-// 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)]

+ 0 - 5
BDInfo/ReadMe.txt

@@ -1,5 +0,0 @@
-The source is taken from the BDRom folder of this project:
-
-http://www.cinemasquid.com/blu-ray/tools/bdinfo
-
-BDInfoSettings was taken from the FormSettings class, and changed so that the settings all return defaults.

+ 0 - 309
BDInfo/TSCodecAC3.cs

@@ -1,309 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-#undef DEBUG
-using System.IO;
-
-namespace BDInfo
-{
-    public abstract class TSCodecAC3
-    {
-        private static byte[] eac3_blocks = new byte[] { 1, 2, 3, 6 };
-
-        public static void Scan(
-            TSAudioStream stream,
-            TSStreamBuffer buffer,
-            ref string tag)
-        {
-            if (stream.IsInitialized) return;
-
-            byte[] sync = buffer.ReadBytes(2);
-            if (sync == null ||
-                sync[0] != 0x0B ||
-                sync[1] != 0x77)
-            {
-                return;
-            }
-
-            int sr_code = 0;
-            int frame_size = 0;
-            int frame_size_code = 0;
-            int channel_mode = 0;
-            int lfe_on = 0;
-            int dial_norm = 0;
-            int num_blocks = 0;
-
-            byte[] hdr = buffer.ReadBytes(4);
-            int bsid = (hdr[3] & 0xF8) >> 3;
-            buffer.Seek(-4, SeekOrigin.Current);
-            if (bsid <= 10)
-            {
-                byte[] crc = buffer.ReadBytes(2);
-                sr_code = buffer.ReadBits(2);
-                frame_size_code = buffer.ReadBits(6);
-                bsid = buffer.ReadBits(5);
-                int bsmod = buffer.ReadBits(3);
-
-                channel_mode = buffer.ReadBits(3);
-                int cmixlev = 0;
-                if (((channel_mode & 0x1) > 0) && (channel_mode != 0x1))
-                {
-                    cmixlev = buffer.ReadBits(2);
-                }
-                int surmixlev = 0;
-                if ((channel_mode & 0x4) > 0)
-                {
-                    surmixlev = buffer.ReadBits(2);
-                }
-                int dsurmod = 0;
-                if (channel_mode == 0x2)
-                {
-                    dsurmod = buffer.ReadBits(2);
-                    if (dsurmod == 0x2)
-                    {
-                        stream.AudioMode = TSAudioMode.Surround;
-                    }
-                }
-                lfe_on = buffer.ReadBits(1);
-                dial_norm = buffer.ReadBits(5);
-                int compr = 0;
-                if (1 == buffer.ReadBits(1))
-                {
-                    compr = buffer.ReadBits(8);
-                }
-                int langcod = 0;
-                if (1 == buffer.ReadBits(1))
-                {
-                    langcod = buffer.ReadBits(8);
-                }
-                int mixlevel = 0;
-                int roomtyp = 0;
-                if (1 == buffer.ReadBits(1))
-                {
-                    mixlevel = buffer.ReadBits(5);
-                    roomtyp = buffer.ReadBits(2);
-                }
-                if (channel_mode == 0)
-                {
-                    int dialnorm2 = buffer.ReadBits(5);
-                    int compr2 = 0;
-                    if (1 == buffer.ReadBits(1))
-                    {
-                        compr2 = buffer.ReadBits(8);
-                    }
-                    int langcod2 = 0;
-                    if (1 == buffer.ReadBits(1))
-                    {
-                        langcod2 = buffer.ReadBits(8);
-                    }
-                    int mixlevel2 = 0;
-                    int roomtyp2 = 0;
-                    if (1 == buffer.ReadBits(1))
-                    {
-                        mixlevel2 = buffer.ReadBits(5);
-                        roomtyp2 = buffer.ReadBits(2);
-                    }
-                }
-                int copyrightb = buffer.ReadBits(1);
-                int origbs = buffer.ReadBits(1);
-                if (bsid == 6)
-                {
-                    if (1 == buffer.ReadBits(1))
-                    {
-                        int dmixmod = buffer.ReadBits(2);
-                        int ltrtcmixlev = buffer.ReadBits(3);
-                        int ltrtsurmixlev = buffer.ReadBits(3);
-                        int lorocmixlev = buffer.ReadBits(3);
-                        int lorosurmixlev = buffer.ReadBits(3);
-                    }
-                    if (1 == buffer.ReadBits(1))
-                    {
-                        int dsurexmod = buffer.ReadBits(2);
-                        int dheadphonmod = buffer.ReadBits(2);
-                        if (dheadphonmod == 0x2)
-                        {
-                            // TODO
-                        }
-                        int adconvtyp = buffer.ReadBits(1);
-                        int xbsi2 = buffer.ReadBits(8);
-                        int encinfo = buffer.ReadBits(1);
-                        if (dsurexmod == 2)
-                        {
-                            stream.AudioMode = TSAudioMode.Extended;
-                        }
-                    }
-                }
-            }
-            else
-            {
-                int frame_type = buffer.ReadBits(2);
-                int substreamid = buffer.ReadBits(3);
-                frame_size = (buffer.ReadBits(11) + 1) << 1;
-
-                sr_code = buffer.ReadBits(2);
-                if (sr_code == 3)
-                {
-                    sr_code = buffer.ReadBits(2);
-                }
-                else
-                {
-                    num_blocks = buffer.ReadBits(2);
-                }
-                channel_mode = buffer.ReadBits(3);
-                lfe_on = buffer.ReadBits(1);
-            }
-
-            switch (channel_mode)
-            {
-                case 0: // 1+1
-                    stream.ChannelCount = 2;
-                    if (stream.AudioMode == TSAudioMode.Unknown)
-                    {
-                        stream.AudioMode = TSAudioMode.DualMono;
-                    }
-                    break;
-                case 1: // 1/0
-                    stream.ChannelCount = 1;
-                    break;
-                case 2: // 2/0
-                    stream.ChannelCount = 2;
-                    if (stream.AudioMode == TSAudioMode.Unknown)
-                    {
-                        stream.AudioMode = TSAudioMode.Stereo;
-                    }
-                    break;
-                case 3: // 3/0
-                    stream.ChannelCount = 3;
-                    break;
-                case 4: // 2/1
-                    stream.ChannelCount = 3;
-                    break;
-                case 5: // 3/1
-                    stream.ChannelCount = 4;
-                    break;
-                case 6: // 2/2
-                    stream.ChannelCount = 4;
-                    break;
-                case 7: // 3/2
-                    stream.ChannelCount = 5;
-                    break;
-                default:
-                    stream.ChannelCount = 0;
-                    break;
-            }
-
-            switch (sr_code)
-            {
-                case 0:
-                    stream.SampleRate = 48000;
-                    break;
-                case 1:
-                    stream.SampleRate = 44100;
-                    break;
-                case 2:
-                    stream.SampleRate = 32000;
-                    break;
-                default:
-                    stream.SampleRate = 0;
-                    break;
-            }
-
-            if (bsid <= 10)
-            {
-                switch (frame_size_code >> 1)
-                {
-                    case 18:
-                        stream.BitRate = 640000;
-                        break;
-                    case 17:
-                        stream.BitRate = 576000;
-                        break;
-                    case 16:
-                        stream.BitRate = 512000;
-                        break;
-                    case 15:
-                        stream.BitRate = 448000;
-                        break;
-                    case 14:
-                        stream.BitRate = 384000;
-                        break;
-                    case 13:
-                        stream.BitRate = 320000;
-                        break;
-                    case 12:
-                        stream.BitRate = 256000;
-                        break;
-                    case 11:
-                        stream.BitRate = 224000;
-                        break;
-                    case 10:
-                        stream.BitRate = 192000;
-                        break;
-                    case 9:
-                        stream.BitRate = 160000;
-                        break;
-                    case 8:
-                        stream.BitRate = 128000;
-                        break;
-                    case 7:
-                        stream.BitRate = 112000;
-                        break;
-                    case 6:
-                        stream.BitRate = 96000;
-                        break;
-                    case 5:
-                        stream.BitRate = 80000;
-                        break;
-                    case 4:
-                        stream.BitRate = 64000;
-                        break;
-                    case 3:
-                        stream.BitRate = 56000;
-                        break;
-                    case 2:
-                        stream.BitRate = 48000;
-                        break;
-                    case 1:
-                        stream.BitRate = 40000;
-                        break;
-                    case 0:
-                        stream.BitRate = 32000;
-                        break;
-                    default:
-                        stream.BitRate = 0;
-                        break;
-                }
-            }
-            else
-            {
-                stream.BitRate = (long)
-                    (4.0 * frame_size * stream.SampleRate / (num_blocks * 256));
-            }
-
-            stream.LFE = lfe_on;
-            if (stream.StreamType != TSStreamType.AC3_PLUS_AUDIO &&
-                stream.StreamType != TSStreamType.AC3_PLUS_SECONDARY_AUDIO)
-            {
-                stream.DialNorm = dial_norm - 31;
-            }
-            stream.IsVBR = false;
-            stream.IsInitialized = true;
-        }
-    }
-}

+ 0 - 148
BDInfo/TSCodecAVC.cs

@@ -1,148 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-
-namespace BDInfo
-{
-    public abstract class TSCodecAVC
-    {
-        public static void Scan(
-            TSVideoStream stream,
-            TSStreamBuffer buffer,
-            ref string tag)
-        {
-            uint parse = 0;
-            byte accessUnitDelimiterParse = 0;
-            byte sequenceParameterSetParse = 0;
-            string profile = null;
-            string level = null;
-            byte constraintSet0Flag = 0;
-            byte constraintSet1Flag = 0;
-            byte constraintSet2Flag = 0;
-            byte constraintSet3Flag = 0;
-
-            for (int i = 0; i < buffer.Length; i++)
-            {
-                parse = (parse << 8) + buffer.ReadByte();
-
-                if (parse == 0x00000109)
-                {
-                    accessUnitDelimiterParse = 1;
-                }
-                else if (accessUnitDelimiterParse > 0)
-                {
-                    --accessUnitDelimiterParse;
-                    if (accessUnitDelimiterParse == 0)
-                    {
-                        switch ((parse & 0xFF) >> 5)
-                        {
-                            case 0: // I
-                            case 3: // SI
-                            case 5: // I, SI
-                                tag = "I";
-                                break;
-
-                            case 1: // I, P
-                            case 4: // SI, SP
-                            case 6: // I, SI, P, SP
-                                tag = "P";
-                                break;
-
-                            case 2: // I, P, B
-                            case 7: // I, SI, P, SP, B
-                                tag = "B";
-                                break;
-                        }
-                        if (stream.IsInitialized) return;
-                    }
-                }
-                else if (parse == 0x00000127 || parse == 0x00000167)
-                {
-                    sequenceParameterSetParse = 3;
-                }
-                else if (sequenceParameterSetParse > 0)
-                {
-                    --sequenceParameterSetParse;
-                    switch (sequenceParameterSetParse)
-                    {
-                        case 2:
-                            switch (parse & 0xFF)
-                            {
-                                case 66:
-                                    profile = "Baseline Profile";
-                                    break;
-                                case 77:
-                                    profile = "Main Profile";
-                                    break;
-                                case 88:
-                                    profile = "Extended Profile";
-                                    break;
-                                case 100:
-                                    profile = "High Profile";
-                                    break;
-                                case 110:
-                                    profile = "High 10 Profile";
-                                    break;
-                                case 122:
-                                    profile = "High 4:2:2 Profile";
-                                    break;
-                                case 144:
-                                    profile = "High 4:4:4 Profile";
-                                    break;
-                                default:
-                                    profile = "Unknown Profile";
-                                    break;
-                            }
-                            break;
-
-                        case 1:
-                            constraintSet0Flag = (byte)
-                                ((parse & 0x80) >> 7);
-                            constraintSet1Flag = (byte)
-                                ((parse & 0x40) >> 6);
-                            constraintSet2Flag = (byte)
-                                ((parse & 0x20) >> 5);
-                            constraintSet3Flag = (byte)
-                                ((parse & 0x10) >> 4);
-                            break;
-
-                        case 0:
-                            byte b = (byte)(parse & 0xFF);
-                            if (b == 11 && constraintSet3Flag == 1)
-                            {
-                                level = "1b";
-                            }
-                            else
-                            {
-                                level = string.Format(
-                                    "{0:D}.{1:D}",
-                                    b / 10, (b - ((b / 10) * 10)));
-                            }
-                            stream.EncodingProfile = string.Format(
-                                "{0} {1}", profile, level);
-                            stream.IsVBR = true;
-                            stream.IsInitialized = true;
-                            break;
-                    }
-                }
-            }
-            return;
-        }
-    }
-}

+ 0 - 159
BDInfo/TSCodecDTS.cs

@@ -1,159 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-
-namespace BDInfo
-{
-    public abstract class TSCodecDTS
-    {
-        private static int[] dca_sample_rates =
-        {
-            0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
-            12000, 24000, 48000, 96000, 192000
-        };
-
-        private static int[] dca_bit_rates =
-        {
-            32000, 56000, 64000, 96000, 112000, 128000,
-            192000, 224000, 256000, 320000, 384000,
-            448000, 512000, 576000, 640000, 768000,
-            896000, 1024000, 1152000, 1280000, 1344000,
-            1408000, 1411200, 1472000, 1509000, 1920000,
-            2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/
-        };
-
-        private static int[] dca_channels =
-        {
-            1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8
-        };
-
-        private static int[] dca_bits_per_sample =
-        {
-            16, 16, 20, 20, 0, 24, 24
-        };
-
-        public static void Scan(
-            TSAudioStream stream,
-            TSStreamBuffer buffer,
-            long bitrate,
-            ref string tag)
-        {
-            if (stream.IsInitialized) return;
-
-            bool syncFound = false;
-            uint sync = 0;
-            for (int i = 0; i < buffer.Length; i++)
-            {
-                sync = (sync << 8) + buffer.ReadByte();
-                if (sync == 0x7FFE8001)
-                {
-                    syncFound = true;
-                    break;
-                }
-            }
-            if (!syncFound) return;
-
-            int frame_type = buffer.ReadBits(1);
-            int samples_deficit = buffer.ReadBits(5);
-            int crc_present = buffer.ReadBits(1);
-            int sample_blocks = buffer.ReadBits(7);
-            int frame_size = buffer.ReadBits(14);
-            if (frame_size < 95)
-            {
-                return;
-            }
-            int amode = buffer.ReadBits(6);
-            int sample_rate = buffer.ReadBits(4);
-            if (sample_rate < 0 || sample_rate >= dca_sample_rates.Length)
-            {
-                return;
-            }
-            int bit_rate = buffer.ReadBits(5);
-            if (bit_rate < 0 || bit_rate >= dca_bit_rates.Length)
-            {
-                return;
-            }
-            int downmix = buffer.ReadBits(1);
-            int dynrange = buffer.ReadBits(1);
-            int timestamp = buffer.ReadBits(1);
-            int aux_data = buffer.ReadBits(1);
-            int hdcd = buffer.ReadBits(1);
-            int ext_descr = buffer.ReadBits(3);
-            int ext_coding = buffer.ReadBits(1);
-            int aspf = buffer.ReadBits(1);
-            int lfe = buffer.ReadBits(2);
-            int predictor_history = buffer.ReadBits(1);
-            if (crc_present == 1)
-            {
-                int crc = buffer.ReadBits(16);
-            }
-            int multirate_inter = buffer.ReadBits(1);
-            int version = buffer.ReadBits(4);
-            int copy_history = buffer.ReadBits(2);
-            int source_pcm_res = buffer.ReadBits(3);
-            int front_sum = buffer.ReadBits(1);
-            int surround_sum = buffer.ReadBits(1);
-            int dialog_norm = buffer.ReadBits(4);
-            if (source_pcm_res < 0 || source_pcm_res >= dca_bits_per_sample.Length)
-            {
-                return;
-            }
-            int subframes = buffer.ReadBits(4);
-            int total_channels = buffer.ReadBits(3) + 1 + ext_coding;
-
-            stream.SampleRate = dca_sample_rates[sample_rate];
-            stream.ChannelCount = total_channels;
-            stream.LFE = (lfe > 0 ? 1 : 0);
-            stream.BitDepth = dca_bits_per_sample[source_pcm_res];
-            stream.DialNorm = -dialog_norm;
-            if ((source_pcm_res & 0x1) == 0x1)
-            {
-                stream.AudioMode = TSAudioMode.Extended;
-            }
-
-            stream.BitRate = (uint)dca_bit_rates[bit_rate];
-            switch (stream.BitRate)
-            {
-                case 1:
-                    if (bitrate > 0)
-                    {
-                        stream.BitRate = bitrate;
-                        stream.IsVBR = false;
-                        stream.IsInitialized = true;
-                    }
-                    else
-                    {
-                        stream.BitRate = 0;
-                    }
-                    break;
-
-                case 2:
-                case 3:
-                    stream.IsVBR = true;
-                    stream.IsInitialized = true;
-                    break;
-
-                default:
-                    stream.IsVBR = false;
-                    stream.IsInitialized = true;
-                    break;
-            }
-        }
-    }
-}

+ 0 - 246
BDInfo/TSCodecDTSHD.cs

@@ -1,246 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-
-namespace BDInfo
-{
-    public abstract class TSCodecDTSHD
-    {
-        private static int[] SampleRates = new int[]
-        { 0x1F40, 0x3E80, 0x7D00, 0x0FA00, 0x1F400, 0x5622, 0x0AC44, 0x15888, 0x2B110, 0x56220, 0x2EE0, 0x5DC0, 0x0BB80, 0x17700, 0x2EE00, 0x5DC00 };
-
-        public static void Scan(
-            TSAudioStream stream,
-            TSStreamBuffer buffer,
-            long bitrate,
-            ref string tag)
-        {
-            if (stream.IsInitialized &&
-                (stream.StreamType == TSStreamType.DTS_HD_SECONDARY_AUDIO ||
-                (stream.CoreStream != null &&
-                 stream.CoreStream.IsInitialized))) return;
-
-            bool syncFound = false;
-            uint sync = 0;
-            for (int i = 0; i < buffer.Length; i++)
-            {
-                sync = (sync << 8) + buffer.ReadByte();
-                if (sync == 0x64582025)
-                {
-                    syncFound = true;
-                    break;
-                }
-            }
-
-            if (!syncFound)
-            {
-                tag = "CORE";
-                if (stream.CoreStream == null)
-                {
-                    stream.CoreStream = new TSAudioStream();
-                    stream.CoreStream.StreamType = TSStreamType.DTS_AUDIO;
-                }
-                if (!stream.CoreStream.IsInitialized)
-                {
-                    buffer.BeginRead();
-                    TSCodecDTS.Scan(stream.CoreStream, buffer, bitrate, ref tag);
-                }
-                return;
-            }
-
-            tag = "HD";
-            int temp1 = buffer.ReadBits(8);
-            int nuSubStreamIndex = buffer.ReadBits(2);
-            int nuExtSSHeaderSize = 0;
-            int nuExtSSFSize = 0;
-            int bBlownUpHeader = buffer.ReadBits(1);
-            if (1 == bBlownUpHeader)
-            {
-                nuExtSSHeaderSize = buffer.ReadBits(12) + 1;
-                nuExtSSFSize = buffer.ReadBits(20) + 1;
-            }
-            else
-            {
-                nuExtSSHeaderSize = buffer.ReadBits(8) + 1;
-                nuExtSSFSize = buffer.ReadBits(16) + 1;
-            }
-            int nuNumAudioPresent = 1;
-            int nuNumAssets = 1;
-            int bStaticFieldsPresent = buffer.ReadBits(1);
-            if (1 == bStaticFieldsPresent)
-            {
-                int nuRefClockCode = buffer.ReadBits(2);
-                int nuExSSFrameDurationCode = buffer.ReadBits(3) + 1;
-                long nuTimeStamp = 0;
-                if (1 == buffer.ReadBits(1))
-                {
-                    nuTimeStamp = (buffer.ReadBits(18) << 18) + buffer.ReadBits(18);
-                }
-                nuNumAudioPresent = buffer.ReadBits(3) + 1;
-                nuNumAssets = buffer.ReadBits(3) + 1;
-                int[] nuActiveExSSMask = new int[nuNumAudioPresent];
-                for (int i = 0; i < nuNumAudioPresent; i++)
-                {
-                    nuActiveExSSMask[i] = buffer.ReadBits(nuSubStreamIndex + 1); //?
-                }
-                for (int i = 0; i < nuNumAudioPresent; i++)
-                {
-                    for (int j = 0; j < nuSubStreamIndex + 1; j++)
-                    {
-                        if (((j + 1) % 2) == 1)
-                        {
-                            int mask = buffer.ReadBits(8);
-                        }
-                    }
-                }
-                if (1 == buffer.ReadBits(1))
-                {
-                    int nuMixMetadataAdjLevel = buffer.ReadBits(2);
-                    int nuBits4MixOutMask = buffer.ReadBits(2) * 4 + 4;
-                    int nuNumMixOutConfigs = buffer.ReadBits(2) + 1;
-                    int[] nuMixOutChMask = new int[nuNumMixOutConfigs];
-                    for (int i = 0; i < nuNumMixOutConfigs; i++)
-                    {
-                        nuMixOutChMask[i] = buffer.ReadBits(nuBits4MixOutMask);
-                    }
-                }
-            }
-            int[] AssetSizes = new int[nuNumAssets];
-            for (int i = 0; i < nuNumAssets; i++)
-            {
-                if (1 == bBlownUpHeader)
-                {
-                    AssetSizes[i] = buffer.ReadBits(20) + 1;
-                }
-                else
-                {
-                    AssetSizes[i] = buffer.ReadBits(16) + 1;
-                }
-            }
-            for (int i = 0; i < nuNumAssets; i++)
-            {
-                long bufferPosition = buffer.Position;
-                int nuAssetDescriptorFSIZE = buffer.ReadBits(9) + 1;
-                int DescriptorDataForAssetIndex = buffer.ReadBits(3);
-                if (1 == bStaticFieldsPresent)
-                {
-                    int AssetTypeDescrPresent = buffer.ReadBits(1);
-                    if (1 == AssetTypeDescrPresent)
-                    {
-                        int AssetTypeDescriptor = buffer.ReadBits(4);
-                    }
-                    int LanguageDescrPresent = buffer.ReadBits(1);
-                    if (1 == LanguageDescrPresent)
-                    {
-                        int LanguageDescriptor = buffer.ReadBits(24);
-                    }
-                    int bInfoTextPresent = buffer.ReadBits(1);
-                    if (1 == bInfoTextPresent)
-                    {
-                        int nuInfoTextByteSize = buffer.ReadBits(10) + 1;
-                        int[] InfoText = new int[nuInfoTextByteSize];
-                        for (int j = 0; j < nuInfoTextByteSize; j++)
-                        {
-                            InfoText[j] = buffer.ReadBits(8);
-                        }
-                    }
-                    int nuBitResolution = buffer.ReadBits(5) + 1;
-                    int nuMaxSampleRate = buffer.ReadBits(4);
-                    int nuTotalNumChs = buffer.ReadBits(8) + 1;
-                    int bOne2OneMapChannels2Speakers = buffer.ReadBits(1);
-                    int nuSpkrActivityMask = 0;
-                    if (1 == bOne2OneMapChannels2Speakers)
-                    {
-                        int bEmbeddedStereoFlag = 0;
-                        if (nuTotalNumChs > 2)
-                        {
-                            bEmbeddedStereoFlag = buffer.ReadBits(1);
-                        }
-                        int bEmbeddedSixChFlag = 0;
-                        if (nuTotalNumChs > 6)
-                        {
-                            bEmbeddedSixChFlag = buffer.ReadBits(1);
-                        }
-                        int bSpkrMaskEnabled = buffer.ReadBits(1);
-                        int nuNumBits4SAMask = 0;
-                        if (1 == bSpkrMaskEnabled)
-                        {
-                            nuNumBits4SAMask = buffer.ReadBits(2);
-                            nuNumBits4SAMask = nuNumBits4SAMask * 4 + 4;
-                            nuSpkrActivityMask = buffer.ReadBits(nuNumBits4SAMask);
-                        }
-                        // TODO...
-                    }
-                    stream.SampleRate = SampleRates[nuMaxSampleRate];
-                    stream.BitDepth = nuBitResolution;
-
-                    stream.LFE = 0;
-                    if ((nuSpkrActivityMask & 0x8) == 0x8)
-                    {
-                        ++stream.LFE;
-                    }
-                    if ((nuSpkrActivityMask & 0x1000) == 0x1000)
-                    {
-                        ++stream.LFE;
-                    }
-                    stream.ChannelCount = nuTotalNumChs - stream.LFE;
-                }
-                if (nuNumAssets > 1)
-                {
-                    // TODO...
-                    break;
-                }
-            }
-
-            // TODO
-            if (stream.CoreStream != null)
-            {
-                var coreStream = (TSAudioStream)stream.CoreStream;
-                if (coreStream.AudioMode == TSAudioMode.Extended &&
-                    stream.ChannelCount == 5)
-                {
-                    stream.AudioMode = TSAudioMode.Extended;
-                }
-                /*
-                if (coreStream.DialNorm != 0)
-                {
-                    stream.DialNorm = coreStream.DialNorm;
-                }
-                */
-            }
-
-            if (stream.StreamType == TSStreamType.DTS_HD_MASTER_AUDIO)
-            {
-                stream.IsVBR = true;
-                stream.IsInitialized = true;
-            }
-            else if (bitrate > 0)
-            {
-                stream.IsVBR = false;
-                stream.BitRate = bitrate;
-                if (stream.CoreStream != null)
-                {
-                    stream.BitRate += stream.CoreStream.BitRate;
-                    stream.IsInitialized = true;
-                }
-                stream.IsInitialized = (stream.BitRate > 0 ? true : false);
-            }
-        }
-    }
-}

+ 0 - 123
BDInfo/TSCodecLPCM.cs

@@ -1,123 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-
-namespace BDInfo
-{
-    public abstract class TSCodecLPCM
-    {
-        public static void Scan(
-            TSAudioStream stream,
-            TSStreamBuffer buffer,
-            ref string tag)
-        {
-            if (stream.IsInitialized) return;
-
-            byte[] header = buffer.ReadBytes(4);
-            int flags = (header[2] << 8) + header[3];
-
-            switch ((flags & 0xF000) >> 12)
-            {
-                case 1: // 1/0/0
-                    stream.ChannelCount = 1;
-                    stream.LFE = 0;
-                    break;
-                case 3: // 2/0/0
-                    stream.ChannelCount = 2;
-                    stream.LFE = 0;
-                    break;
-                case 4: // 3/0/0
-                    stream.ChannelCount = 3;
-                    stream.LFE = 0;
-                    break;
-                case 5: // 2/1/0
-                    stream.ChannelCount = 3;
-                    stream.LFE = 0;
-                    break;
-                case 6: // 3/1/0
-                    stream.ChannelCount = 4;
-                    stream.LFE = 0;
-                    break;
-                case 7: // 2/2/0
-                    stream.ChannelCount = 4;
-                    stream.LFE = 0;
-                    break;
-                case 8: // 3/2/0
-                    stream.ChannelCount = 5;
-                    stream.LFE = 0;
-                    break;
-                case 9: // 3/2/1
-                    stream.ChannelCount = 5;
-                    stream.LFE = 1;
-                    break;
-                case 10: // 3/4/0
-                    stream.ChannelCount = 7;
-                    stream.LFE = 0;
-                    break;
-                case 11: // 3/4/1
-                    stream.ChannelCount = 7;
-                    stream.LFE = 1;
-                    break;
-                default:
-                    stream.ChannelCount = 0;
-                    stream.LFE = 0;
-                    break;
-            }
-
-            switch ((flags & 0xC0) >> 6)
-            {
-                case 1:
-                    stream.BitDepth = 16;
-                    break;
-                case 2:
-                    stream.BitDepth = 20;
-                    break;
-                case 3:
-                    stream.BitDepth = 24;
-                    break;
-                default:
-                    stream.BitDepth = 0;
-                    break;
-            }
-
-            switch ((flags & 0xF00) >> 8)
-            {
-                case 1:
-                    stream.SampleRate = 48000;
-                    break;
-                case 4:
-                    stream.SampleRate = 96000;
-                    break;
-                case 5:
-                    stream.SampleRate = 192000;
-                    break;
-                default:
-                    stream.SampleRate = 0;
-                    break;
-            }
-
-            stream.BitRate = (uint)
-                (stream.SampleRate * stream.BitDepth *
-                 (stream.ChannelCount + stream.LFE));
-
-            stream.IsVBR = false;
-            stream.IsInitialized = true;
-        }
-    }
-}

+ 0 - 208
BDInfo/TSCodecMPEG2.cs

@@ -1,208 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-#undef DEBUG
-
-
-namespace BDInfo
-{
-    public abstract class TSCodecMPEG2
-    {
-        public static void Scan(
-            TSVideoStream stream,
-            TSStreamBuffer buffer,
-            ref string tag)
-        {
-            int parse = 0;
-            int pictureParse = 0;
-            int sequenceHeaderParse = 0;
-            int extensionParse = 0;
-            int sequenceExtensionParse = 0;
-
-            for (int i = 0; i < buffer.Length; i++)
-            {
-                parse = (parse << 8) + buffer.ReadByte();
-
-                if (parse == 0x00000100)
-                {
-                    pictureParse = 2;
-                }
-                else if (parse == 0x000001B3)
-                {
-                    sequenceHeaderParse = 7;
-                }
-                else if (sequenceHeaderParse > 0)
-                {
-                    --sequenceHeaderParse;
-                    switch (sequenceHeaderParse)
-                    {
-#if DEBUG
-                        case 6:
-                            break;
-
-                        case 5:
-                            break;
-
-                        case 4:
-                            stream.Width =
-                                (int)((parse & 0xFFF000) >> 12);
-                            stream.Height =
-                                (int)(parse & 0xFFF);
-                            break;
-
-                        case 3:
-                            stream.AspectRatio =
-                                (TSAspectRatio)((parse & 0xF0) >> 4);
-
-                            switch ((parse & 0xF0) >> 4)
-                            {
-                                case 0: // Forbidden
-                                    break;
-                                case 1: // Square
-                                    break;
-                                case 2: // 4:3
-                                    break;
-                                case 3: // 16:9
-                                    break;
-                                case 4: // 2.21:1
-                                    break;
-                                default: // Reserved
-                                    break;
-                            }
-
-                            switch (parse & 0xF)
-                            {
-                                case 0: // Forbidden
-                                    break;
-                                case 1: // 23.976
-                                    stream.FrameRateEnumerator = 24000;
-                                    stream.FrameRateDenominator = 1001;
-                                    break;
-                                case 2: // 24
-                                    stream.FrameRateEnumerator = 24000;
-                                    stream.FrameRateDenominator = 1000;
-                                    break;
-                                case 3: // 25
-                                    stream.FrameRateEnumerator = 25000;
-                                    stream.FrameRateDenominator = 1000;
-                                    break;
-                                case 4: // 29.97
-                                    stream.FrameRateEnumerator = 30000;
-                                    stream.FrameRateDenominator = 1001;
-                                    break;
-                                case 5: // 30
-                                    stream.FrameRateEnumerator = 30000;
-                                    stream.FrameRateDenominator = 1000;
-                                    break;
-                                case 6: // 50
-                                    stream.FrameRateEnumerator = 50000;
-                                    stream.FrameRateDenominator = 1000;
-                                    break;
-                                case 7: // 59.94
-                                    stream.FrameRateEnumerator = 60000;
-                                    stream.FrameRateDenominator = 1001;
-                                    break;
-                                case 8: // 60
-                                    stream.FrameRateEnumerator = 60000;
-                                    stream.FrameRateDenominator = 1000;
-                                    break;
-                                default: // Reserved
-                                    stream.FrameRateEnumerator = 0;
-                                    stream.FrameRateDenominator = 0;
-                                    break;
-                            }
-                            break;
-
-                        case 2:
-                            break;
-
-                        case 1:
-                            break;
-#endif
-
-                        case 0:
-#if DEBUG
-                            stream.BitRate =
-                                (((parse & 0xFFFFC0) >> 6) * 200);
-#endif
-                            stream.IsVBR = true;
-                            stream.IsInitialized = true;
-                            break;
-                    }
-                }
-                else if (pictureParse > 0)
-                {
-                    --pictureParse;
-                    if (pictureParse == 0)
-                    {
-                        switch ((parse & 0x38) >> 3)
-                        {
-                            case 1:
-                                tag = "I";
-                                break;
-                            case 2:
-                                tag = "P";
-                                break;
-                            case 3:
-                                tag = "B";
-                                break;
-                            default:
-                                break;
-                        }
-                        if (stream.IsInitialized) return;
-                    }
-                }
-                else if (parse == 0x000001B5)
-                {
-                    extensionParse = 1;
-                }
-                else if (extensionParse > 0)
-                {
-                    --extensionParse;
-                    if (extensionParse == 0)
-                    {
-                        if ((parse & 0xF0) == 0x10)
-                        {
-                            sequenceExtensionParse = 1;
-                        }
-                    }
-                }
-                else if (sequenceExtensionParse > 0)
-                {
-                    --sequenceExtensionParse;
-#if DEBUG
-                    if (sequenceExtensionParse == 0)
-                    {
-                        uint sequenceExtension =
-                            ((parse & 0x8) >> 3);
-                        if (sequenceExtension == 0)
-                        {
-                            stream.IsInterlaced = true;
-                        }
-                        else
-                        {
-                            stream.IsInterlaced = false;
-                        }
-                    }
-#endif
-                }
-            }
-        }
-    }
-}

+ 0 - 36
BDInfo/TSCodecMVC.cs

@@ -1,36 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-
-namespace BDInfo
-{
-    // TODO: Do something more interesting here...
-
-    public abstract class TSCodecMVC
-    {
-        public static void Scan(
-            TSVideoStream stream,
-            TSStreamBuffer buffer,
-            ref string tag)
-        {
-            stream.IsVBR = true;
-            stream.IsInitialized = true;
-        }
-    }
-}

+ 0 - 186
BDInfo/TSCodecTrueHD.cs

@@ -1,186 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-
-namespace BDInfo
-{
-    public abstract class TSCodecTrueHD
-    {
-        public static void Scan(
-            TSAudioStream stream,
-            TSStreamBuffer buffer,
-            ref string tag)
-        {
-            if (stream.IsInitialized &&
-                stream.CoreStream != null &&
-                stream.CoreStream.IsInitialized) return;
-
-            bool syncFound = false;
-            uint sync = 0;
-            for (int i = 0; i < buffer.Length; i++)
-            {
-                sync = (sync << 8) + buffer.ReadByte();
-                if (sync == 0xF8726FBA)
-                {
-                    syncFound = true;
-                    break;
-                }
-            }
-
-            if (!syncFound)
-            {
-                tag = "CORE";
-                if (stream.CoreStream == null)
-                {
-                    stream.CoreStream = new TSAudioStream();
-                    stream.CoreStream.StreamType = TSStreamType.AC3_AUDIO;
-                }
-                if (!stream.CoreStream.IsInitialized)
-                {
-                    buffer.BeginRead();
-                    TSCodecAC3.Scan(stream.CoreStream, buffer, ref tag);
-                }
-                return;
-            }
-
-            tag = "HD";
-            int ratebits = buffer.ReadBits(4);
-            if (ratebits != 0xF)
-            {
-                stream.SampleRate =
-                    (((ratebits & 8) > 0 ? 44100 : 48000) << (ratebits & 7));
-            }
-            int temp1 = buffer.ReadBits(8);
-            int channels_thd_stream1 = buffer.ReadBits(5);
-            int temp2 = buffer.ReadBits(2);
-
-            stream.ChannelCount = 0;
-            stream.LFE = 0;
-            int c_LFE2 = buffer.ReadBits(1);
-            if (c_LFE2 == 1)
-            {
-                stream.LFE += 1;
-            }
-            int c_Cvh = buffer.ReadBits(1);
-            if (c_Cvh == 1)
-            {
-                stream.ChannelCount += 1;
-            }
-            int c_LRw = buffer.ReadBits(1);
-            if (c_LRw == 1)
-            {
-                stream.ChannelCount += 2;
-            }
-            int c_LRsd = buffer.ReadBits(1);
-            if (c_LRsd == 1)
-            {
-                stream.ChannelCount += 2;
-            }
-            int c_Ts = buffer.ReadBits(1);
-            if (c_Ts == 1)
-            {
-                stream.ChannelCount += 1;
-            }
-            int c_Cs = buffer.ReadBits(1);
-            if (c_Cs == 1)
-            {
-                stream.ChannelCount += 1;
-            }
-            int c_LRrs = buffer.ReadBits(1);
-            if (c_LRrs == 1)
-            {
-                stream.ChannelCount += 2;
-            }
-            int c_LRc = buffer.ReadBits(1);
-            if (c_LRc == 1)
-            {
-                stream.ChannelCount += 2;
-            }
-            int c_LRvh = buffer.ReadBits(1);
-            if (c_LRvh == 1)
-            {
-                stream.ChannelCount += 2;
-            }
-            int c_LRs = buffer.ReadBits(1);
-            if (c_LRs == 1)
-            {
-                stream.ChannelCount += 2;
-            }
-            int c_LFE = buffer.ReadBits(1);
-            if (c_LFE == 1)
-            {
-                stream.LFE += 1;
-            }
-            int c_C = buffer.ReadBits(1);
-            if (c_C == 1)
-            {
-                stream.ChannelCount += 1;
-            }
-            int c_LR = buffer.ReadBits(1);
-            if (c_LR == 1)
-            {
-                stream.ChannelCount += 2;
-            }
-
-            int access_unit_size = 40 << (ratebits & 7);
-            int access_unit_size_pow2 = 64 << (ratebits & 7);
-
-            int a1 = buffer.ReadBits(16);
-            int a2 = buffer.ReadBits(16);
-            int a3 = buffer.ReadBits(16);
-
-            int is_vbr = buffer.ReadBits(1);
-            int peak_bitrate = buffer.ReadBits(15);
-            peak_bitrate = (peak_bitrate * stream.SampleRate) >> 4;
-
-            double peak_bitdepth =
-                (double)peak_bitrate /
-                (stream.ChannelCount + stream.LFE) /
-                stream.SampleRate;
-            if (peak_bitdepth > 14)
-            {
-                stream.BitDepth = 24;
-            }
-            else
-            {
-                stream.BitDepth = 16;
-            }
-
-#if DEBUG
-            System.Diagnostics.Debug.WriteLine(string.Format(
-                "{0}\t{1}\t{2:F2}",
-                stream.PID, peak_bitrate, peak_bitdepth));
-#endif
-            /*
-            // TODO: Get THD dialnorm from metadata
-            if (stream.CoreStream != null)
-            {
-                TSAudioStream coreStream = (TSAudioStream)stream.CoreStream;
-                if (coreStream.DialNorm != 0)
-                {
-                    stream.DialNorm = coreStream.DialNorm;
-                }
-            }
-            */
-
-            stream.IsVBR = true;
-            stream.IsInitialized = true;
-        }
-    }
-}

+ 0 - 131
BDInfo/TSCodecVC1.cs

@@ -1,131 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-
-namespace BDInfo
-{
-    public abstract class TSCodecVC1
-    {
-        public static void Scan(
-            TSVideoStream stream,
-            TSStreamBuffer buffer,
-            ref string tag)
-        {
-            int parse = 0;
-            byte frameHeaderParse = 0;
-            byte sequenceHeaderParse = 0;
-            bool isInterlaced = false;
-
-            for (int i = 0; i < buffer.Length; i++)
-            {
-                parse = (parse << 8) + buffer.ReadByte();
-
-                if (parse == 0x0000010D)
-                {
-                    frameHeaderParse = 4;
-                }
-                else if (frameHeaderParse > 0)
-                {
-                    --frameHeaderParse;
-                    if (frameHeaderParse == 0)
-                    {
-                        uint pictureType = 0;
-                        if (isInterlaced)
-                        {
-                            if ((parse & 0x80000000) == 0)
-                            {
-                                pictureType =
-                                    (uint)((parse & 0x78000000) >> 13);
-                            }
-                            else
-                            {
-                                pictureType =
-                                    (uint)((parse & 0x3c000000) >> 12);
-                            }
-                        }
-                        else
-                        {
-                            pictureType =
-                                (uint)((parse & 0xf0000000) >> 14);
-                        }
-
-                        if ((pictureType & 0x20000) == 0)
-                        {
-                            tag = "P";
-                        }
-                        else if ((pictureType & 0x10000) == 0)
-                        {
-                            tag = "B";
-                        }
-                        else if ((pictureType & 0x8000) == 0)
-                        {
-                            tag = "I";
-                        }
-                        else if ((pictureType & 0x4000) == 0)
-                        {
-                            tag = "BI";
-                        }
-                        else
-                        {
-                            tag = null;
-                        }
-                        if (stream.IsInitialized) return;
-                    }
-                }
-                else if (parse == 0x0000010F)
-                {
-                    sequenceHeaderParse = 6;
-                }
-                else if (sequenceHeaderParse > 0)
-                {
-                    --sequenceHeaderParse;
-                    switch (sequenceHeaderParse)
-                    {
-                        case 5:
-                            int profileLevel = ((parse & 0x38) >> 3);
-                            if (((parse & 0xC0) >> 6) == 3)
-                            {
-                                stream.EncodingProfile = string.Format(
-                                    "Advanced Profile {0}", profileLevel);
-                            }
-                            else
-                            {
-                                stream.EncodingProfile = string.Format(
-                                    "Main Profile {0}", profileLevel);
-                            }
-                            break;
-
-                        case 0:
-                            if (((parse & 0x40) >> 6) > 0)
-                            {
-                                isInterlaced = true;
-                            }
-                            else
-                            {
-                                isInterlaced = false;
-                            }
-                            break;
-                    }
-                    stream.IsVBR = true;
-                    stream.IsInitialized = true;
-                }
-            }
-        }
-    }
-}

+ 0 - 37
BDInfo/TSInterleavedFile.cs

@@ -1,37 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-using MediaBrowser.Model.IO;
-
-// TODO: Do more interesting things here...
-
-namespace BDInfo
-{
-    public class TSInterleavedFile
-    {
-        public FileSystemMetadata FileInfo = null;
-        public string Name = null;
-
-        public TSInterleavedFile(FileSystemMetadata fileInfo)
-        {
-            FileInfo = fileInfo;
-            Name = fileInfo.Name.ToUpper();
-        }
-    }
-}

+ 0 - 1282
BDInfo/TSPlaylistFile.cs

@@ -1,1282 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-#undef DEBUG
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using MediaBrowser.Model.IO;
-
-namespace BDInfo
-{
-    public class TSPlaylistFile
-    {
-        private FileSystemMetadata FileInfo = null;
-        public string FileType = null;
-        public bool IsInitialized = false;
-        public string Name = null;
-        public BDROM BDROM = null;
-        public bool HasHiddenTracks = false;
-        public bool HasLoops = false;
-        public bool IsCustom = false;
-
-        public List<double> Chapters = new List<double>();
-
-        public Dictionary<ushort, TSStream> Streams =
-            new Dictionary<ushort, TSStream>();
-        public Dictionary<ushort, TSStream> PlaylistStreams =
-            new Dictionary<ushort, TSStream>();
-        public List<TSStreamClip> StreamClips =
-            new List<TSStreamClip>();
-        public List<Dictionary<ushort, TSStream>> AngleStreams =
-            new List<Dictionary<ushort, TSStream>>();
-        public List<Dictionary<double, TSStreamClip>> AngleClips =
-            new List<Dictionary<double, TSStreamClip>>();
-        public int AngleCount = 0;
-
-        public List<TSStream> SortedStreams =
-            new List<TSStream>();
-        public List<TSVideoStream> VideoStreams =
-            new List<TSVideoStream>();
-        public List<TSAudioStream> AudioStreams =
-            new List<TSAudioStream>();
-        public List<TSTextStream> TextStreams =
-            new List<TSTextStream>();
-        public List<TSGraphicsStream> GraphicsStreams =
-            new List<TSGraphicsStream>();
-
-        public TSPlaylistFile(BDROM bdrom,
-            FileSystemMetadata fileInfo)
-        {
-            BDROM = bdrom;
-            FileInfo = fileInfo;
-            Name = fileInfo.Name.ToUpper();
-        }
-
-        public TSPlaylistFile(BDROM bdrom,
-            string name,
-            List<TSStreamClip> clips)
-        {
-            BDROM = bdrom;
-            Name = name;
-            IsCustom = true;
-            foreach (var clip in clips)
-            {
-                var newClip = new TSStreamClip(
-                    clip.StreamFile, clip.StreamClipFile);
-
-                newClip.Name = clip.Name;
-                newClip.TimeIn = clip.TimeIn;
-                newClip.TimeOut = clip.TimeOut;
-                newClip.Length = newClip.TimeOut - newClip.TimeIn;
-                newClip.RelativeTimeIn = TotalLength;
-                newClip.RelativeTimeOut = newClip.RelativeTimeIn + newClip.Length;
-                newClip.AngleIndex = clip.AngleIndex;
-                newClip.Chapters.Add(clip.TimeIn);
-                StreamClips.Add(newClip);
-
-                if (newClip.AngleIndex > AngleCount)
-                {
-                    AngleCount = newClip.AngleIndex;
-                }
-                if (newClip.AngleIndex == 0)
-                {
-                    Chapters.Add(newClip.RelativeTimeIn);
-                }
-            }
-            LoadStreamClips();
-            IsInitialized = true;
-        }
-
-        public override string ToString()
-        {
-            return Name;
-        }
-
-        public ulong InterleavedFileSize
-        {
-            get
-            {
-                ulong size = 0;
-                foreach (var clip in StreamClips)
-                {
-                    size += clip.InterleavedFileSize;
-                }
-                return size;
-            }
-        }
-        public ulong FileSize
-        {
-            get
-            {
-                ulong size = 0;
-                foreach (var clip in StreamClips)
-                {
-                    size += clip.FileSize;
-                }
-                return size;
-            }
-        }
-        public double TotalLength
-        {
-            get
-            {
-                double length = 0;
-                foreach (var clip in StreamClips)
-                {
-                    if (clip.AngleIndex == 0)
-                    {
-                        length += clip.Length;
-                    }
-                }
-                return length;
-            }
-        }
-
-        public double TotalAngleLength
-        {
-            get
-            {
-                double length = 0;
-                foreach (var clip in StreamClips)
-                {
-                    length += clip.Length;
-                }
-                return length;
-            }
-        }
-
-        public ulong TotalSize
-        {
-            get
-            {
-                ulong size = 0;
-                foreach (var clip in StreamClips)
-                {
-                    if (clip.AngleIndex == 0)
-                    {
-                        size += clip.PacketSize;
-                    }
-                }
-                return size;
-            }
-        }
-
-        public ulong TotalAngleSize
-        {
-            get
-            {
-                ulong size = 0;
-                foreach (var clip in StreamClips)
-                {
-                    size += clip.PacketSize;
-                }
-                return size;
-            }
-        }
-
-        public ulong TotalBitRate
-        {
-            get
-            {
-                if (TotalLength > 0)
-                {
-                    return (ulong)Math.Round(((TotalSize * 8.0) / TotalLength));
-                }
-                return 0;
-            }
-        }
-
-        public ulong TotalAngleBitRate
-        {
-            get
-            {
-                if (TotalAngleLength > 0)
-                {
-                    return (ulong)Math.Round(((TotalAngleSize * 8.0) / TotalAngleLength));
-                }
-                return 0;
-            }
-        }
-
-        public void Scan(
-            Dictionary<string, TSStreamFile> streamFiles,
-            Dictionary<string, TSStreamClipFile> streamClipFiles)
-        {
-            Stream fileStream = null;
-            BinaryReader fileReader = null;
-
-            try
-            {
-                Streams.Clear();
-                StreamClips.Clear();
-
-                fileStream = File.OpenRead(FileInfo.FullName);
-                fileReader = new BinaryReader(fileStream);
-
-                byte[] data = new byte[fileStream.Length];
-                int dataLength = fileReader.Read(data, 0, data.Length);
-
-                int pos = 0;
-
-                FileType = ReadString(data, 8, ref pos);
-                if (FileType != "MPLS0100" && FileType != "MPLS0200")
-                {
-                    throw new Exception(string.Format(
-                        "Playlist {0} has an unknown file type {1}.",
-                        FileInfo.Name, FileType));
-                }
-
-                int playlistOffset = ReadInt32(data, ref pos);
-                int chaptersOffset = ReadInt32(data, ref pos);
-                int extensionsOffset = ReadInt32(data, ref pos);
-
-                pos = playlistOffset;
-
-                int playlistLength = ReadInt32(data, ref pos);
-                int playlistReserved = ReadInt16(data, ref pos);
-                int itemCount = ReadInt16(data, ref pos);
-                int subitemCount = ReadInt16(data, ref pos);
-
-                var chapterClips = new List<TSStreamClip>();
-                for (int itemIndex = 0; itemIndex < itemCount; itemIndex++)
-                {
-                    int itemStart = pos;
-                    int itemLength = ReadInt16(data, ref pos);
-                    string itemName = ReadString(data, 5, ref pos);
-                    string itemType = ReadString(data, 4, ref pos);
-
-                    TSStreamFile streamFile = null;
-                    string streamFileName = string.Format(
-                        "{0}.M2TS", itemName);
-                    if (streamFiles.ContainsKey(streamFileName))
-                    {
-                        streamFile = streamFiles[streamFileName];
-                    }
-                    if (streamFile == null)
-                    {
-                        // Error condition
-                    }
-
-                    TSStreamClipFile streamClipFile = null;
-                    string streamClipFileName = string.Format(
-                        "{0}.CLPI", itemName);
-                    if (streamClipFiles.ContainsKey(streamClipFileName))
-                    {
-                        streamClipFile = streamClipFiles[streamClipFileName];
-                    }
-                    if (streamClipFile == null)
-                    {
-                        throw new Exception(string.Format(
-                            "Playlist {0} referenced missing file {1}.",
-                            FileInfo.Name, streamFileName));
-                    }
-
-                    pos += 1;
-                    int multiangle = (data[pos] >> 4) & 0x01;
-                    int condition = data[pos] & 0x0F;
-                    pos += 2;
-
-                    int inTime = ReadInt32(data, ref pos);
-                    if (inTime < 0) inTime &= 0x7FFFFFFF;
-                    double timeIn = (double)inTime / 45000;
-
-                    int outTime = ReadInt32(data, ref pos);
-                    if (outTime < 0) outTime &= 0x7FFFFFFF;
-                    double timeOut = (double)outTime / 45000;
-
-                    var streamClip = new TSStreamClip(
-                        streamFile, streamClipFile);
-
-                    streamClip.Name = streamFileName; //TODO
-                    streamClip.TimeIn = timeIn;
-                    streamClip.TimeOut = timeOut;
-                    streamClip.Length = streamClip.TimeOut - streamClip.TimeIn;
-                    streamClip.RelativeTimeIn = TotalLength;
-                    streamClip.RelativeTimeOut = streamClip.RelativeTimeIn + streamClip.Length;
-                    StreamClips.Add(streamClip);
-                    chapterClips.Add(streamClip);
-
-                    pos += 12;
-                    if (multiangle > 0)
-                    {
-                        int angles = data[pos];
-                        pos += 2;
-                        for (int angle = 0; angle < angles - 1; angle++)
-                        {
-                            string angleName = ReadString(data, 5, ref pos);
-                            string angleType = ReadString(data, 4, ref pos);
-                            pos += 1;
-
-                            TSStreamFile angleFile = null;
-                            string angleFileName = string.Format(
-                                "{0}.M2TS", angleName);
-                            if (streamFiles.ContainsKey(angleFileName))
-                            {
-                                angleFile = streamFiles[angleFileName];
-                            }
-                            if (angleFile == null)
-                            {
-                                throw new Exception(string.Format(
-                                    "Playlist {0} referenced missing angle file {1}.",
-                                    FileInfo.Name, angleFileName));
-                            }
-
-                            TSStreamClipFile angleClipFile = null;
-                            string angleClipFileName = string.Format(
-                                "{0}.CLPI", angleName);
-                            if (streamClipFiles.ContainsKey(angleClipFileName))
-                            {
-                                angleClipFile = streamClipFiles[angleClipFileName];
-                            }
-                            if (angleClipFile == null)
-                            {
-                                throw new Exception(string.Format(
-                                    "Playlist {0} referenced missing angle file {1}.",
-                                    FileInfo.Name, angleClipFileName));
-                            }
-
-                            var angleClip =
-                                new TSStreamClip(angleFile, angleClipFile);
-                            angleClip.AngleIndex = angle + 1;
-                            angleClip.TimeIn = streamClip.TimeIn;
-                            angleClip.TimeOut = streamClip.TimeOut;
-                            angleClip.RelativeTimeIn = streamClip.RelativeTimeIn;
-                            angleClip.RelativeTimeOut = streamClip.RelativeTimeOut;
-                            angleClip.Length = streamClip.Length;
-                            StreamClips.Add(angleClip);
-                        }
-                        if (angles - 1 > AngleCount) AngleCount = angles - 1;
-                    }
-
-                    int streamInfoLength = ReadInt16(data, ref pos);
-                    pos += 2;
-                    int streamCountVideo = data[pos++];
-                    int streamCountAudio = data[pos++];
-                    int streamCountPG = data[pos++];
-                    int streamCountIG = data[pos++];
-                    int streamCountSecondaryAudio = data[pos++];
-                    int streamCountSecondaryVideo = data[pos++];
-                    int streamCountPIP = data[pos++];
-                    pos += 5;
-
-#if DEBUG
-                    Debug.WriteLine(string.Format(
-                        "{0} : {1} -> V:{2} A:{3} PG:{4} IG:{5} 2A:{6} 2V:{7} PIP:{8}",
-                        Name, streamFileName, streamCountVideo, streamCountAudio, streamCountPG, streamCountIG,
-                        streamCountSecondaryAudio, streamCountSecondaryVideo, streamCountPIP));
-#endif
-
-                    for (int i = 0; i < streamCountVideo; i++)
-                    {
-                        var stream = CreatePlaylistStream(data, ref pos);
-                        if (stream != null) PlaylistStreams[stream.PID] = stream;
-                    }
-                    for (int i = 0; i < streamCountAudio; i++)
-                    {
-                        var stream = CreatePlaylistStream(data, ref pos);
-                        if (stream != null) PlaylistStreams[stream.PID] = stream;
-                    }
-                    for (int i = 0; i < streamCountPG; i++)
-                    {
-                        var stream = CreatePlaylistStream(data, ref pos);
-                        if (stream != null) PlaylistStreams[stream.PID] = stream;
-                    }
-                    for (int i = 0; i < streamCountIG; i++)
-                    {
-                        var stream = CreatePlaylistStream(data, ref pos);
-                        if (stream != null) PlaylistStreams[stream.PID] = stream;
-                    }
-                    for (int i = 0; i < streamCountSecondaryAudio; i++)
-                    {
-                        var stream = CreatePlaylistStream(data, ref pos);
-                        if (stream != null) PlaylistStreams[stream.PID] = stream;
-                        pos += 2;
-                    }
-                    for (int i = 0; i < streamCountSecondaryVideo; i++)
-                    {
-                        var stream = CreatePlaylistStream(data, ref pos);
-                        if (stream != null) PlaylistStreams[stream.PID] = stream;
-                        pos += 6;
-                    }
-                    /*
-                     * TODO
-                     *
-                    for (int i = 0; i < streamCountPIP; i++)
-                    {
-                        TSStream stream = CreatePlaylistStream(data, ref pos);
-                        if (stream != null) PlaylistStreams[stream.PID] = stream;
-                    }
-                    */
-
-                    pos += itemLength - (pos - itemStart) + 2;
-                }
-
-                pos = chaptersOffset + 4;
-
-                int chapterCount = ReadInt16(data, ref pos);
-
-                for (int chapterIndex = 0;
-                    chapterIndex < chapterCount;
-                    chapterIndex++)
-                {
-                    int chapterType = data[pos + 1];
-
-                    if (chapterType == 1)
-                    {
-                        int streamFileIndex =
-                            ((int)data[pos + 2] << 8) + data[pos + 3];
-
-                        long chapterTime =
-                            ((long)data[pos + 4] << 24) +
-                            ((long)data[pos + 5] << 16) +
-                            ((long)data[pos + 6] << 8) +
-                            ((long)data[pos + 7]);
-
-                        var streamClip = chapterClips[streamFileIndex];
-
-                        double chapterSeconds = (double)chapterTime / 45000;
-
-                        double relativeSeconds =
-                            chapterSeconds -
-                            streamClip.TimeIn +
-                            streamClip.RelativeTimeIn;
-
-                        // TODO: Ignore short last chapter?
-                        if (TotalLength - relativeSeconds > 1.0)
-                        {
-                            streamClip.Chapters.Add(chapterSeconds);
-                            this.Chapters.Add(relativeSeconds);
-                        }
-                    }
-                    else
-                    {
-                        // TODO: Handle other chapter types?
-                    }
-                    pos += 14;
-                }
-            }
-            finally
-            {
-                if (fileReader != null)
-                {
-                    fileReader.Dispose();
-                }
-                if (fileStream != null)
-                {
-                    fileStream.Dispose();
-                }
-            }
-        }
-
-        public void Initialize()
-        {
-            LoadStreamClips();
-
-            var clipTimes = new Dictionary<string, List<double>>();
-            foreach (var clip in StreamClips)
-            {
-                if (clip.AngleIndex == 0)
-                {
-                    if (clipTimes.ContainsKey(clip.Name))
-                    {
-                        if (clipTimes[clip.Name].Contains(clip.TimeIn))
-                        {
-                            HasLoops = true;
-                            break;
-                        }
-                        else
-                        {
-                            clipTimes[clip.Name].Add(clip.TimeIn);
-                        }
-                    }
-                    else
-                    {
-                        clipTimes[clip.Name] = new List<double> { clip.TimeIn };
-                    }
-                }
-            }
-            ClearBitrates();
-            IsInitialized = true;
-        }
-
-        protected TSStream CreatePlaylistStream(byte[] data, ref int pos)
-        {
-            TSStream stream = null;
-
-            int start = pos;
-
-            int headerLength = data[pos++];
-            int headerPos = pos;
-            int headerType = data[pos++];
-
-            int pid = 0;
-            int subpathid = 0;
-            int subclipid = 0;
-
-            switch (headerType)
-            {
-                case 1:
-                    pid = ReadInt16(data, ref pos);
-                    break;
-                case 2:
-                    subpathid = data[pos++];
-                    subclipid = data[pos++];
-                    pid = ReadInt16(data, ref pos);
-                    break;
-                case 3:
-                    subpathid = data[pos++];
-                    pid = ReadInt16(data, ref pos);
-                    break;
-                case 4:
-                    subpathid = data[pos++];
-                    subclipid = data[pos++];
-                    pid = ReadInt16(data, ref pos);
-                    break;
-                default:
-                    break;
-            }
-
-            pos = headerPos + headerLength;
-
-            int streamLength = data[pos++];
-            int streamPos = pos;
-
-            var streamType = (TSStreamType)data[pos++];
-            switch (streamType)
-            {
-                case TSStreamType.MVC_VIDEO:
-                    // TODO
-                    break;
-
-                case TSStreamType.AVC_VIDEO:
-                case TSStreamType.MPEG1_VIDEO:
-                case TSStreamType.MPEG2_VIDEO:
-                case TSStreamType.VC1_VIDEO:
-
-                    var videoFormat = (TSVideoFormat)
-                        (data[pos] >> 4);
-                    var frameRate = (TSFrameRate)
-                        (data[pos] & 0xF);
-                    var aspectRatio = (TSAspectRatio)
-                        (data[pos + 1] >> 4);
-
-                    stream = new TSVideoStream();
-                    ((TSVideoStream)stream).VideoFormat = videoFormat;
-                    ((TSVideoStream)stream).AspectRatio = aspectRatio;
-                    ((TSVideoStream)stream).FrameRate = frameRate;
-
-#if DEBUG
-                            Debug.WriteLine(string.Format(
-                                "\t{0} {1} {2} {3} {4}",
-                                pid,
-                                streamType,
-                                videoFormat,
-                                frameRate,
-                                aspectRatio));
-#endif
-
-                    break;
-
-                case TSStreamType.AC3_AUDIO:
-                case TSStreamType.AC3_PLUS_AUDIO:
-                case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
-                case TSStreamType.AC3_TRUE_HD_AUDIO:
-                case TSStreamType.DTS_AUDIO:
-                case TSStreamType.DTS_HD_AUDIO:
-                case TSStreamType.DTS_HD_MASTER_AUDIO:
-                case TSStreamType.DTS_HD_SECONDARY_AUDIO:
-                case TSStreamType.LPCM_AUDIO:
-                case TSStreamType.MPEG1_AUDIO:
-                case TSStreamType.MPEG2_AUDIO:
-
-                    int audioFormat = ReadByte(data, ref pos);
-
-                    var channelLayout = (TSChannelLayout)
-                        (audioFormat >> 4);
-                    var sampleRate = (TSSampleRate)
-                        (audioFormat & 0xF);
-
-                    string audioLanguage = ReadString(data, 3, ref pos);
-
-                    stream = new TSAudioStream();
-                    ((TSAudioStream)stream).ChannelLayout = channelLayout;
-                    ((TSAudioStream)stream).SampleRate = TSAudioStream.ConvertSampleRate(sampleRate);
-                    ((TSAudioStream)stream).LanguageCode = audioLanguage;
-
-#if DEBUG
-                    Debug.WriteLine(string.Format(
-                        "\t{0} {1} {2} {3} {4}",
-                        pid,
-                        streamType,
-                        audioLanguage,
-                        channelLayout,
-                        sampleRate));
-#endif
-
-                    break;
-
-                case TSStreamType.INTERACTIVE_GRAPHICS:
-                case TSStreamType.PRESENTATION_GRAPHICS:
-
-                    string graphicsLanguage = ReadString(data, 3, ref pos);
-
-                    stream = new TSGraphicsStream();
-                    ((TSGraphicsStream)stream).LanguageCode = graphicsLanguage;
-
-                    if (data[pos] != 0)
-                    {
-                    }
-
-#if DEBUG
-                    Debug.WriteLine(string.Format(
-                        "\t{0} {1} {2}",
-                        pid,
-                        streamType,
-                        graphicsLanguage));
-#endif
-
-                    break;
-
-                case TSStreamType.SUBTITLE:
-
-                    int code = ReadByte(data, ref pos); // TODO
-                    string textLanguage = ReadString(data, 3, ref pos);
-
-                    stream = new TSTextStream();
-                    ((TSTextStream)stream).LanguageCode = textLanguage;
-
-#if DEBUG
-                    Debug.WriteLine(string.Format(
-                        "\t{0} {1} {2}",
-                        pid,
-                        streamType,
-                        textLanguage));
-#endif
-
-                    break;
-
-                default:
-                    break;
-            }
-
-            pos = streamPos + streamLength;
-
-            if (stream != null)
-            {
-                stream.PID = (ushort)pid;
-                stream.StreamType = streamType;
-            }
-
-            return stream;
-        }
-
-        private void LoadStreamClips()
-        {
-            AngleClips.Clear();
-            if (AngleCount > 0)
-            {
-                for (int angleIndex = 0; angleIndex < AngleCount; angleIndex++)
-                {
-                    AngleClips.Add(new Dictionary<double, TSStreamClip>());
-                }
-            }
-
-            TSStreamClip referenceClip = null;
-            if (StreamClips.Count > 0)
-            {
-                referenceClip = StreamClips[0];
-            }
-            foreach (var clip in StreamClips)
-            {
-                if (clip.StreamClipFile.Streams.Count > referenceClip.StreamClipFile.Streams.Count)
-                {
-                    referenceClip = clip;
-                }
-                else if (clip.Length > referenceClip.Length)
-                {
-                    referenceClip = clip;
-                }
-                if (AngleCount > 0)
-                {
-                    if (clip.AngleIndex == 0)
-                    {
-                        for (int angleIndex = 0; angleIndex < AngleCount; angleIndex++)
-                        {
-                            AngleClips[angleIndex][clip.RelativeTimeIn] = clip;
-                        }
-                    }
-                    else
-                    {
-                        AngleClips[clip.AngleIndex - 1][clip.RelativeTimeIn] = clip;
-                    }
-                }
-            }
-
-            foreach (var clipStream
-                in referenceClip.StreamClipFile.Streams.Values)
-            {
-                if (!Streams.ContainsKey(clipStream.PID))
-                {
-                    var stream = clipStream.Clone();
-                    Streams[clipStream.PID] = stream;
-
-                    if (!IsCustom && !PlaylistStreams.ContainsKey(stream.PID))
-                    {
-                        stream.IsHidden = true;
-                        HasHiddenTracks = true;
-                    }
-
-                    if (stream.IsVideoStream)
-                    {
-                        VideoStreams.Add((TSVideoStream)stream);
-                    }
-                    else if (stream.IsAudioStream)
-                    {
-                        AudioStreams.Add((TSAudioStream)stream);
-                    }
-                    else if (stream.IsGraphicsStream)
-                    {
-                        GraphicsStreams.Add((TSGraphicsStream)stream);
-                    }
-                    else if (stream.IsTextStream)
-                    {
-                        TextStreams.Add((TSTextStream)stream);
-                    }
-                }
-            }
-
-            if (referenceClip.StreamFile != null)
-            {
-                // TODO: Better way to add this in?
-                if (BDInfoSettings.EnableSSIF &&
-                    referenceClip.StreamFile.InterleavedFile != null &&
-                    referenceClip.StreamFile.Streams.ContainsKey(4114) &&
-                    !Streams.ContainsKey(4114))
-                {
-                    var stream = referenceClip.StreamFile.Streams[4114].Clone();
-                    Streams[4114] = stream;
-                    if (stream.IsVideoStream)
-                    {
-                        VideoStreams.Add((TSVideoStream)stream);
-                    }
-                }
-
-                foreach (var clipStream
-                    in referenceClip.StreamFile.Streams.Values)
-                {
-                    if (Streams.ContainsKey(clipStream.PID))
-                    {
-                        var stream = Streams[clipStream.PID];
-
-                        if (stream.StreamType != clipStream.StreamType) continue;
-
-                        if (clipStream.BitRate > stream.BitRate)
-                        {
-                            stream.BitRate = clipStream.BitRate;
-                        }
-                        stream.IsVBR = clipStream.IsVBR;
-
-                        if (stream.IsVideoStream &&
-                            clipStream.IsVideoStream)
-                        {
-                            ((TSVideoStream)stream).EncodingProfile =
-                                ((TSVideoStream)clipStream).EncodingProfile;
-                        }
-                        else if (stream.IsAudioStream &&
-                            clipStream.IsAudioStream)
-                        {
-                            var audioStream = (TSAudioStream)stream;
-                            var clipAudioStream = (TSAudioStream)clipStream;
-
-                            if (clipAudioStream.ChannelCount > audioStream.ChannelCount)
-                            {
-                                audioStream.ChannelCount = clipAudioStream.ChannelCount;
-                            }
-                            if (clipAudioStream.LFE > audioStream.LFE)
-                            {
-                                audioStream.LFE = clipAudioStream.LFE;
-                            }
-                            if (clipAudioStream.SampleRate > audioStream.SampleRate)
-                            {
-                                audioStream.SampleRate = clipAudioStream.SampleRate;
-                            }
-                            if (clipAudioStream.BitDepth > audioStream.BitDepth)
-                            {
-                                audioStream.BitDepth = clipAudioStream.BitDepth;
-                            }
-                            if (clipAudioStream.DialNorm < audioStream.DialNorm)
-                            {
-                                audioStream.DialNorm = clipAudioStream.DialNorm;
-                            }
-                            if (clipAudioStream.AudioMode != TSAudioMode.Unknown)
-                            {
-                                audioStream.AudioMode = clipAudioStream.AudioMode;
-                            }
-                            if (clipAudioStream.CoreStream != null &&
-                                audioStream.CoreStream == null)
-                            {
-                                audioStream.CoreStream = (TSAudioStream)
-                                    clipAudioStream.CoreStream.Clone();
-                            }
-                        }
-                    }
-                }
-            }
-
-            for (int i = 0; i < AngleCount; i++)
-            {
-                AngleStreams.Add(new Dictionary<ushort, TSStream>());
-            }
-
-            if (!BDInfoSettings.KeepStreamOrder)
-            {
-                VideoStreams.Sort(CompareVideoStreams);
-            }
-            foreach (TSStream stream in VideoStreams)
-            {
-                SortedStreams.Add(stream);
-                for (int i = 0; i < AngleCount; i++)
-                {
-                    var angleStream = stream.Clone();
-                    angleStream.AngleIndex = i + 1;
-                    AngleStreams[i][angleStream.PID] = angleStream;
-                    SortedStreams.Add(angleStream);
-                }
-            }
-
-            if (!BDInfoSettings.KeepStreamOrder)
-            {
-                AudioStreams.Sort(CompareAudioStreams);
-            }
-            foreach (TSStream stream in AudioStreams)
-            {
-                SortedStreams.Add(stream);
-            }
-
-            if (!BDInfoSettings.KeepStreamOrder)
-            {
-                GraphicsStreams.Sort(CompareGraphicsStreams);
-            }
-            foreach (TSStream stream in GraphicsStreams)
-            {
-                SortedStreams.Add(stream);
-            }
-
-            if (!BDInfoSettings.KeepStreamOrder)
-            {
-                TextStreams.Sort(CompareTextStreams);
-            }
-            foreach (TSStream stream in TextStreams)
-            {
-                SortedStreams.Add(stream);
-            }
-        }
-
-        public void ClearBitrates()
-        {
-            foreach (var clip in StreamClips)
-            {
-                clip.PayloadBytes = 0;
-                clip.PacketCount = 0;
-                clip.PacketSeconds = 0;
-
-                if (clip.StreamFile != null)
-                {
-                    foreach (var stream in clip.StreamFile.Streams.Values)
-                    {
-                        stream.PayloadBytes = 0;
-                        stream.PacketCount = 0;
-                        stream.PacketSeconds = 0;
-                    }
-
-                    if (clip.StreamFile != null &&
-                        clip.StreamFile.StreamDiagnostics != null)
-                    {
-                        clip.StreamFile.StreamDiagnostics.Clear();
-                    }
-                }
-            }
-
-            foreach (var stream in SortedStreams)
-            {
-                stream.PayloadBytes = 0;
-                stream.PacketCount = 0;
-                stream.PacketSeconds = 0;
-            }
-        }
-
-        public bool IsValid
-        {
-            get
-            {
-                if (!IsInitialized) return false;
-
-                if (BDInfoSettings.FilterShortPlaylists &&
-                    TotalLength < BDInfoSettings.FilterShortPlaylistsValue)
-                {
-                    return false;
-                }
-
-                if (HasLoops &&
-                    BDInfoSettings.FilterLoopingPlaylists)
-                {
-                    return false;
-                }
-
-                return true;
-            }
-        }
-
-        public int CompareVideoStreams(
-            TSVideoStream x,
-            TSVideoStream y)
-        {
-            if (x == null && y == null)
-            {
-                return 0;
-            }
-            else if (x == null && y != null)
-            {
-                return 1;
-            }
-            else if (x != null && y == null)
-            {
-                return -1;
-            }
-            else
-            {
-                if (x.Height > y.Height)
-                {
-                    return -1;
-                }
-                else if (y.Height > x.Height)
-                {
-                    return 1;
-                }
-                else if (x.PID > y.PID)
-                {
-                    return 1;
-                }
-                else if (y.PID > x.PID)
-                {
-                    return -1;
-                }
-                else
-                {
-                    return 0;
-                }
-            }
-        }
-
-        public int CompareAudioStreams(
-            TSAudioStream x,
-            TSAudioStream y)
-        {
-            if (x == y)
-            {
-                return 0;
-            }
-            else if (x == null && y == null)
-            {
-                return 0;
-            }
-            else if (x == null && y != null)
-            {
-                return -1;
-            }
-            else if (x != null && y == null)
-            {
-                return 1;
-            }
-            else
-            {
-                if (x.ChannelCount > y.ChannelCount)
-                {
-                    return -1;
-                }
-                else if (y.ChannelCount > x.ChannelCount)
-                {
-                    return 1;
-                }
-                else
-                {
-                    int sortX = GetStreamTypeSortIndex(x.StreamType);
-                    int sortY = GetStreamTypeSortIndex(y.StreamType);
-
-                    if (sortX > sortY)
-                    {
-                        return -1;
-                    }
-                    else if (sortY > sortX)
-                    {
-                        return 1;
-                    }
-                    else
-                    {
-                        if (x.LanguageCode == "eng")
-                        {
-                            return -1;
-                        }
-                        else if (y.LanguageCode == "eng")
-                        {
-                            return 1;
-                        }
-                        else if (x.LanguageCode != y.LanguageCode)
-                        {
-                            return string.Compare(
-                                x.LanguageName, y.LanguageName);
-                        }
-                        else if (x.PID < y.PID)
-                        {
-                            return -1;
-                        }
-                        else if (y.PID < x.PID)
-                        {
-                            return 1;
-                        }
-                        return 0;
-                    }
-                }
-            }
-        }
-
-        public int CompareTextStreams(
-            TSTextStream x,
-            TSTextStream y)
-        {
-            if (x == y)
-            {
-                return 0;
-            }
-            else if (x == null && y == null)
-            {
-                return 0;
-            }
-            else if (x == null && y != null)
-            {
-                return -1;
-            }
-            else if (x != null && y == null)
-            {
-                return 1;
-            }
-            else
-            {
-                if (x.LanguageCode == "eng")
-                {
-                    return -1;
-                }
-                else if (y.LanguageCode == "eng")
-                {
-                    return 1;
-                }
-                else
-                {
-                    if (x.LanguageCode == y.LanguageCode)
-                    {
-                        if (x.PID > y.PID)
-                        {
-                            return 1;
-                        }
-                        else if (y.PID > x.PID)
-                        {
-                            return -1;
-                        }
-                        else
-                        {
-                            return 0;
-                        }
-                    }
-                    else
-                    {
-                        return string.Compare(
-                            x.LanguageName, y.LanguageName);
-                    }
-                }
-            }
-        }
-
-        private int CompareGraphicsStreams(
-            TSGraphicsStream x,
-            TSGraphicsStream y)
-        {
-            if (x == y)
-            {
-                return 0;
-            }
-            else if (x == null && y == null)
-            {
-                return 0;
-            }
-            else if (x == null && y != null)
-            {
-                return -1;
-            }
-            else if (x != null && y == null)
-            {
-                return 1;
-            }
-            else
-            {
-                int sortX = GetStreamTypeSortIndex(x.StreamType);
-                int sortY = GetStreamTypeSortIndex(y.StreamType);
-
-                if (sortX > sortY)
-                {
-                    return -1;
-                }
-                else if (sortY > sortX)
-                {
-                    return 1;
-                }
-                else if (x.LanguageCode == "eng")
-                {
-                    return -1;
-                }
-                else if (y.LanguageCode == "eng")
-                {
-                    return 1;
-                }
-                else
-                {
-                    if (x.LanguageCode == y.LanguageCode)
-                    {
-                        if (x.PID > y.PID)
-                        {
-                            return 1;
-                        }
-                        else if (y.PID > x.PID)
-                        {
-                            return -1;
-                        }
-                        else
-                        {
-                            return 0;
-                        }
-                    }
-                    else
-                    {
-                        return string.Compare(x.LanguageName, y.LanguageName);
-                    }
-                }
-            }
-        }
-
-        private int GetStreamTypeSortIndex(TSStreamType streamType)
-        {
-            switch (streamType)
-            {
-                case TSStreamType.Unknown:
-                    return 0;
-                case TSStreamType.MPEG1_VIDEO:
-                    return 1;
-                case TSStreamType.MPEG2_VIDEO:
-                    return 2;
-                case TSStreamType.AVC_VIDEO:
-                    return 3;
-                case TSStreamType.VC1_VIDEO:
-                    return 4;
-                case TSStreamType.MVC_VIDEO:
-                    return 5;
-
-                case TSStreamType.MPEG1_AUDIO:
-                    return 1;
-                case TSStreamType.MPEG2_AUDIO:
-                    return 2;
-                case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
-                    return 3;
-                case TSStreamType.DTS_HD_SECONDARY_AUDIO:
-                    return 4;
-                case TSStreamType.AC3_AUDIO:
-                    return 5;
-                case TSStreamType.DTS_AUDIO:
-                    return 6;
-                case TSStreamType.AC3_PLUS_AUDIO:
-                    return 7;
-                case TSStreamType.DTS_HD_AUDIO:
-                    return 8;
-                case TSStreamType.AC3_TRUE_HD_AUDIO:
-                    return 9;
-                case TSStreamType.DTS_HD_MASTER_AUDIO:
-                    return 10;
-                case TSStreamType.LPCM_AUDIO:
-                    return 11;
-
-                case TSStreamType.SUBTITLE:
-                    return 1;
-                case TSStreamType.INTERACTIVE_GRAPHICS:
-                    return 2;
-                case TSStreamType.PRESENTATION_GRAPHICS:
-                    return 3;
-
-                default:
-                    return 0;
-            }
-        }
-
-        protected string ReadString(
-            byte[] data,
-            int count,
-            ref int pos)
-        {
-            string val = Encoding.ASCII.GetString(data, pos, count);
-
-            pos += count;
-
-            return val;
-        }
-
-        protected int ReadInt32(
-            byte[] data,
-            ref int pos)
-        {
-            int val =
-                ((int)data[pos] << 24) +
-                ((int)data[pos + 1] << 16) +
-                ((int)data[pos + 2] << 8) +
-                ((int)data[pos + 3]);
-
-            pos += 4;
-
-            return val;
-        }
-
-        protected int ReadInt16(
-            byte[] data,
-            ref int pos)
-        {
-            int val =
-                ((int)data[pos] << 8) +
-                ((int)data[pos + 1]);
-
-            pos += 2;
-
-            return val;
-        }
-
-        protected byte ReadByte(
-            byte[] data,
-            ref int pos)
-        {
-            return data[pos++];
-        }
-    }
-}

+ 0 - 780
BDInfo/TSStream.cs

@@ -1,780 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-using System;
-using System.Collections.Generic;
-
-namespace BDInfo
-{
-    public enum TSStreamType : byte
-    {
-        Unknown = 0,
-        MPEG1_VIDEO = 0x01,
-        MPEG2_VIDEO = 0x02,
-        AVC_VIDEO = 0x1b,
-        MVC_VIDEO = 0x20,
-        VC1_VIDEO = 0xea,
-        MPEG1_AUDIO = 0x03,
-        MPEG2_AUDIO = 0x04,
-        LPCM_AUDIO = 0x80,
-        AC3_AUDIO = 0x81,
-        AC3_PLUS_AUDIO = 0x84,
-        AC3_PLUS_SECONDARY_AUDIO = 0xA1,
-        AC3_TRUE_HD_AUDIO = 0x83,
-        DTS_AUDIO = 0x82,
-        DTS_HD_AUDIO = 0x85,
-        DTS_HD_SECONDARY_AUDIO = 0xA2,
-        DTS_HD_MASTER_AUDIO = 0x86,
-        PRESENTATION_GRAPHICS = 0x90,
-        INTERACTIVE_GRAPHICS = 0x91,
-        SUBTITLE = 0x92
-    }
-
-    public enum TSVideoFormat : byte
-    {
-        Unknown = 0,
-        VIDEOFORMAT_480i = 1,
-        VIDEOFORMAT_576i = 2,
-        VIDEOFORMAT_480p = 3,
-        VIDEOFORMAT_1080i = 4,
-        VIDEOFORMAT_720p = 5,
-        VIDEOFORMAT_1080p = 6,
-        VIDEOFORMAT_576p = 7,
-    }
-
-    public enum TSFrameRate : byte
-    {
-        Unknown = 0,
-        FRAMERATE_23_976 = 1,
-        FRAMERATE_24 = 2,
-        FRAMERATE_25 = 3,
-        FRAMERATE_29_97 = 4,
-        FRAMERATE_50 = 6,
-        FRAMERATE_59_94 = 7
-    }
-
-    public enum TSChannelLayout : byte
-    {
-        Unknown = 0,
-        CHANNELLAYOUT_MONO = 1,
-        CHANNELLAYOUT_STEREO = 3,
-        CHANNELLAYOUT_MULTI = 6,
-        CHANNELLAYOUT_COMBO = 12
-    }
-
-    public enum TSSampleRate : byte
-    {
-        Unknown = 0,
-        SAMPLERATE_48 = 1,
-        SAMPLERATE_96 = 4,
-        SAMPLERATE_192 = 5,
-        SAMPLERATE_48_192 = 12,
-        SAMPLERATE_48_96 = 14
-    }
-
-    public enum TSAspectRatio
-    {
-        Unknown = 0,
-        ASPECT_4_3 = 2,
-        ASPECT_16_9 = 3,
-        ASPECT_2_21 = 4
-    }
-
-    public class TSDescriptor
-    {
-        public byte Name;
-        public byte[] Value;
-
-        public TSDescriptor(byte name, byte length)
-        {
-            Name = name;
-            Value = new byte[length];
-        }
-
-        public TSDescriptor Clone()
-        {
-            var descriptor =
-                new TSDescriptor(Name, (byte)Value.Length);
-            Value.CopyTo(descriptor.Value, 0);
-            return descriptor;
-        }
-    }
-
-    public abstract class TSStream
-    {
-        public TSStream()
-        {
-        }
-
-        public override string ToString()
-        {
-            return string.Format("{0} ({1})", CodecShortName, PID);
-        }
-
-        public ushort PID;
-        public TSStreamType StreamType;
-        public List<TSDescriptor> Descriptors = null;
-        public long BitRate = 0;
-        public long ActiveBitRate = 0;
-        public bool IsVBR = false;
-        public bool IsInitialized = false;
-        public string LanguageName;
-        public bool IsHidden = false;
-
-        public ulong PayloadBytes = 0;
-        public ulong PacketCount = 0;
-        public double PacketSeconds = 0;
-        public int AngleIndex = 0;
-
-        public ulong PacketSize => PacketCount * 192;
-
-        private string _LanguageCode;
-        public string LanguageCode
-        {
-            get => _LanguageCode;
-            set
-            {
-                _LanguageCode = value;
-                LanguageName = LanguageCodes.GetName(value);
-            }
-        }
-
-        public bool IsVideoStream
-        {
-            get
-            {
-                switch (StreamType)
-                {
-                    case TSStreamType.MPEG1_VIDEO:
-                    case TSStreamType.MPEG2_VIDEO:
-                    case TSStreamType.AVC_VIDEO:
-                    case TSStreamType.MVC_VIDEO:
-                    case TSStreamType.VC1_VIDEO:
-                        return true;
-
-                    default:
-                        return false;
-                }
-            }
-        }
-
-        public bool IsAudioStream
-        {
-            get
-            {
-                switch (StreamType)
-                {
-                    case TSStreamType.MPEG1_AUDIO:
-                    case TSStreamType.MPEG2_AUDIO:
-                    case TSStreamType.LPCM_AUDIO:
-                    case TSStreamType.AC3_AUDIO:
-                    case TSStreamType.AC3_PLUS_AUDIO:
-                    case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
-                    case TSStreamType.AC3_TRUE_HD_AUDIO:
-                    case TSStreamType.DTS_AUDIO:
-                    case TSStreamType.DTS_HD_AUDIO:
-                    case TSStreamType.DTS_HD_SECONDARY_AUDIO:
-                    case TSStreamType.DTS_HD_MASTER_AUDIO:
-                        return true;
-
-                    default:
-                        return false;
-                }
-            }
-        }
-
-        public bool IsGraphicsStream
-        {
-            get
-            {
-                switch (StreamType)
-                {
-                    case TSStreamType.PRESENTATION_GRAPHICS:
-                    case TSStreamType.INTERACTIVE_GRAPHICS:
-                        return true;
-
-                    default:
-                        return false;
-                }
-            }
-        }
-
-        public bool IsTextStream
-        {
-            get
-            {
-                switch (StreamType)
-                {
-                    case TSStreamType.SUBTITLE:
-                        return true;
-
-                    default:
-                        return false;
-                }
-            }
-        }
-
-        public string CodecName
-        {
-            get
-            {
-                switch (StreamType)
-                {
-                    case TSStreamType.MPEG1_VIDEO:
-                        return "MPEG-1 Video";
-                    case TSStreamType.MPEG2_VIDEO:
-                        return "MPEG-2 Video";
-                    case TSStreamType.AVC_VIDEO:
-                        return "MPEG-4 AVC Video";
-                    case TSStreamType.MVC_VIDEO:
-                        return "MPEG-4 MVC Video";
-                    case TSStreamType.VC1_VIDEO:
-                        return "VC-1 Video";
-                    case TSStreamType.MPEG1_AUDIO:
-                        return "MP1 Audio";
-                    case TSStreamType.MPEG2_AUDIO:
-                        return "MP2 Audio";
-                    case TSStreamType.LPCM_AUDIO:
-                        return "LPCM Audio";
-                    case TSStreamType.AC3_AUDIO:
-                        if (((TSAudioStream)this).AudioMode == TSAudioMode.Extended)
-                            return "Dolby Digital EX Audio";
-                        else
-                            return "Dolby Digital Audio";
-                    case TSStreamType.AC3_PLUS_AUDIO:
-                    case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
-                        return "Dolby Digital Plus Audio";
-                    case TSStreamType.AC3_TRUE_HD_AUDIO:
-                        return "Dolby TrueHD Audio";
-                    case TSStreamType.DTS_AUDIO:
-                        if (((TSAudioStream)this).AudioMode == TSAudioMode.Extended)
-                            return "DTS-ES Audio";
-                        else
-                            return "DTS Audio";
-                    case TSStreamType.DTS_HD_AUDIO:
-                        return "DTS-HD High-Res Audio";
-                    case TSStreamType.DTS_HD_SECONDARY_AUDIO:
-                        return "DTS Express";
-                    case TSStreamType.DTS_HD_MASTER_AUDIO:
-                        return "DTS-HD Master Audio";
-                    case TSStreamType.PRESENTATION_GRAPHICS:
-                        return "Presentation Graphics";
-                    case TSStreamType.INTERACTIVE_GRAPHICS:
-                        return "Interactive Graphics";
-                    case TSStreamType.SUBTITLE:
-                        return "Subtitle";
-                    default:
-                        return "UNKNOWN";
-                }
-            }
-        }
-
-        public string CodecAltName
-        {
-            get
-            {
-                switch (StreamType)
-                {
-                    case TSStreamType.MPEG1_VIDEO:
-                        return "MPEG-1";
-                    case TSStreamType.MPEG2_VIDEO:
-                        return "MPEG-2";
-                    case TSStreamType.AVC_VIDEO:
-                        return "AVC";
-                    case TSStreamType.MVC_VIDEO:
-                        return "MVC";
-                    case TSStreamType.VC1_VIDEO:
-                        return "VC-1";
-                    case TSStreamType.MPEG1_AUDIO:
-                        return "MP1";
-                    case TSStreamType.MPEG2_AUDIO:
-                        return "MP2";
-                    case TSStreamType.LPCM_AUDIO:
-                        return "LPCM";
-                    case TSStreamType.AC3_AUDIO:
-                        return "DD AC3";
-                    case TSStreamType.AC3_PLUS_AUDIO:
-                    case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
-                        return "DD AC3+";
-                    case TSStreamType.AC3_TRUE_HD_AUDIO:
-                        return "Dolby TrueHD";
-                    case TSStreamType.DTS_AUDIO:
-                        return "DTS";
-                    case TSStreamType.DTS_HD_AUDIO:
-                        return "DTS-HD Hi-Res";
-                    case TSStreamType.DTS_HD_SECONDARY_AUDIO:
-                        return "DTS Express";
-                    case TSStreamType.DTS_HD_MASTER_AUDIO:
-                        return "DTS-HD Master";
-                    case TSStreamType.PRESENTATION_GRAPHICS:
-                        return "PGS";
-                    case TSStreamType.INTERACTIVE_GRAPHICS:
-                        return "IGS";
-                    case TSStreamType.SUBTITLE:
-                        return "SUB";
-                    default:
-                        return "UNKNOWN";
-                }
-            }
-        }
-
-        public string CodecShortName
-        {
-            get
-            {
-                switch (StreamType)
-                {
-                    case TSStreamType.MPEG1_VIDEO:
-                        return "MPEG-1";
-                    case TSStreamType.MPEG2_VIDEO:
-                        return "MPEG-2";
-                    case TSStreamType.AVC_VIDEO:
-                        return "AVC";
-                    case TSStreamType.MVC_VIDEO:
-                        return "MVC";
-                    case TSStreamType.VC1_VIDEO:
-                        return "VC-1";
-                    case TSStreamType.MPEG1_AUDIO:
-                        return "MP1";
-                    case TSStreamType.MPEG2_AUDIO:
-                        return "MP2";
-                    case TSStreamType.LPCM_AUDIO:
-                        return "LPCM";
-                    case TSStreamType.AC3_AUDIO:
-                        if (((TSAudioStream)this).AudioMode == TSAudioMode.Extended)
-                            return "AC3-EX";
-                        else
-                            return "AC3";
-                    case TSStreamType.AC3_PLUS_AUDIO:
-                    case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
-                        return "AC3+";
-                    case TSStreamType.AC3_TRUE_HD_AUDIO:
-                        return "TrueHD";
-                    case TSStreamType.DTS_AUDIO:
-                        if (((TSAudioStream)this).AudioMode == TSAudioMode.Extended)
-                            return "DTS-ES";
-                        else
-                            return "DTS";
-                    case TSStreamType.DTS_HD_AUDIO:
-                        return "DTS-HD HR";
-                    case TSStreamType.DTS_HD_SECONDARY_AUDIO:
-                        return "DTS Express";
-                    case TSStreamType.DTS_HD_MASTER_AUDIO:
-                        return "DTS-HD MA";
-                    case TSStreamType.PRESENTATION_GRAPHICS:
-                        return "PGS";
-                    case TSStreamType.INTERACTIVE_GRAPHICS:
-                        return "IGS";
-                    case TSStreamType.SUBTITLE:
-                        return "SUB";
-                    default:
-                        return "UNKNOWN";
-                }
-            }
-        }
-
-        public virtual string Description => "";
-
-        public abstract TSStream Clone();
-
-        protected void CopyTo(TSStream stream)
-        {
-            stream.PID = PID;
-            stream.StreamType = StreamType;
-            stream.IsVBR = IsVBR;
-            stream.BitRate = BitRate;
-            stream.IsInitialized = IsInitialized;
-            stream.LanguageCode = _LanguageCode;
-            if (Descriptors != null)
-            {
-                stream.Descriptors = new List<TSDescriptor>();
-                foreach (var descriptor in Descriptors)
-                {
-                    stream.Descriptors.Add(descriptor.Clone());
-                }
-            }
-        }
-    }
-
-    public class TSVideoStream : TSStream
-    {
-        public TSVideoStream()
-        {
-        }
-
-        public int Width;
-        public int Height;
-        public bool IsInterlaced;
-        public int FrameRateEnumerator;
-        public int FrameRateDenominator;
-        public TSAspectRatio AspectRatio;
-        public string EncodingProfile;
-
-        private TSVideoFormat _VideoFormat;
-        public TSVideoFormat VideoFormat
-        {
-            get => _VideoFormat;
-            set
-            {
-                _VideoFormat = value;
-                switch (value)
-                {
-                    case TSVideoFormat.VIDEOFORMAT_480i:
-                        Height = 480;
-                        IsInterlaced = true;
-                        break;
-                    case TSVideoFormat.VIDEOFORMAT_480p:
-                        Height = 480;
-                        IsInterlaced = false;
-                        break;
-                    case TSVideoFormat.VIDEOFORMAT_576i:
-                        Height = 576;
-                        IsInterlaced = true;
-                        break;
-                    case TSVideoFormat.VIDEOFORMAT_576p:
-                        Height = 576;
-                        IsInterlaced = false;
-                        break;
-                    case TSVideoFormat.VIDEOFORMAT_720p:
-                        Height = 720;
-                        IsInterlaced = false;
-                        break;
-                    case TSVideoFormat.VIDEOFORMAT_1080i:
-                        Height = 1080;
-                        IsInterlaced = true;
-                        break;
-                    case TSVideoFormat.VIDEOFORMAT_1080p:
-                        Height = 1080;
-                        IsInterlaced = false;
-                        break;
-                }
-            }
-        }
-
-        private TSFrameRate _FrameRate;
-        public TSFrameRate FrameRate
-        {
-            get => _FrameRate;
-            set
-            {
-                _FrameRate = value;
-                switch (value)
-                {
-                    case TSFrameRate.FRAMERATE_23_976:
-                        FrameRateEnumerator = 24000;
-                        FrameRateDenominator = 1001;
-                        break;
-                    case TSFrameRate.FRAMERATE_24:
-                        FrameRateEnumerator = 24000;
-                        FrameRateDenominator = 1000;
-                        break;
-                    case TSFrameRate.FRAMERATE_25:
-                        FrameRateEnumerator = 25000;
-                        FrameRateDenominator = 1000;
-                        break;
-                    case TSFrameRate.FRAMERATE_29_97:
-                        FrameRateEnumerator = 30000;
-                        FrameRateDenominator = 1001;
-                        break;
-                    case TSFrameRate.FRAMERATE_50:
-                        FrameRateEnumerator = 50000;
-                        FrameRateDenominator = 1000;
-                        break;
-                    case TSFrameRate.FRAMERATE_59_94:
-                        FrameRateEnumerator = 60000;
-                        FrameRateDenominator = 1001;
-                        break;
-                }
-            }
-        }
-
-        public override string Description
-        {
-            get
-            {
-                string description = "";
-
-                if (Height > 0)
-                {
-                    description += string.Format("{0:D}{1} / ",
-                        Height,
-                        IsInterlaced ? "i" : "p");
-                }
-                if (FrameRateEnumerator > 0 &&
-                    FrameRateDenominator > 0)
-                {
-                    if (FrameRateEnumerator % FrameRateDenominator == 0)
-                    {
-                        description += string.Format("{0:D} fps / ",
-                            FrameRateEnumerator / FrameRateDenominator);
-                    }
-                    else
-                    {
-                        description += string.Format("{0:F3} fps / ",
-                            (double)FrameRateEnumerator / FrameRateDenominator);
-                    }
-
-                }
-                if (AspectRatio == TSAspectRatio.ASPECT_4_3)
-                {
-                    description += "4:3 / ";
-                }
-                else if (AspectRatio == TSAspectRatio.ASPECT_16_9)
-                {
-                    description += "16:9 / ";
-                }
-                if (EncodingProfile != null)
-                {
-                    description += EncodingProfile + " / ";
-                }
-                if (description.EndsWith(" / "))
-                {
-                    description = description.Substring(0, description.Length - 3);
-                }
-                return description;
-            }
-        }
-
-        public override TSStream Clone()
-        {
-            var stream = new TSVideoStream();
-            CopyTo(stream);
-
-            stream.VideoFormat = _VideoFormat;
-            stream.FrameRate = _FrameRate;
-            stream.Width = Width;
-            stream.Height = Height;
-            stream.IsInterlaced = IsInterlaced;
-            stream.FrameRateEnumerator = FrameRateEnumerator;
-            stream.FrameRateDenominator = FrameRateDenominator;
-            stream.AspectRatio = AspectRatio;
-            stream.EncodingProfile = EncodingProfile;
-
-            return stream;
-        }
-    }
-
-    public enum TSAudioMode
-    {
-        Unknown,
-        DualMono,
-        Stereo,
-        Surround,
-        Extended
-    }
-
-    public class TSAudioStream : TSStream
-    {
-        public TSAudioStream()
-        {
-        }
-
-        public int SampleRate;
-        public int ChannelCount;
-        public int BitDepth;
-        public int LFE;
-        public int DialNorm;
-        public TSAudioMode AudioMode;
-        public TSAudioStream CoreStream;
-        public TSChannelLayout ChannelLayout;
-
-        public static int ConvertSampleRate(
-            TSSampleRate sampleRate)
-        {
-            switch (sampleRate)
-            {
-                case TSSampleRate.SAMPLERATE_48:
-                    return 48000;
-
-                case TSSampleRate.SAMPLERATE_96:
-                case TSSampleRate.SAMPLERATE_48_96:
-                    return 96000;
-
-                case TSSampleRate.SAMPLERATE_192:
-                case TSSampleRate.SAMPLERATE_48_192:
-                    return 192000;
-            }
-            return 0;
-        }
-
-        public string ChannelDescription
-        {
-            get
-            {
-                if (ChannelLayout == TSChannelLayout.CHANNELLAYOUT_MONO &&
-                    ChannelCount == 2)
-                {
-                }
-
-                string description = "";
-                if (ChannelCount > 0)
-                {
-                    description += string.Format(
-                        "{0:D}.{1:D}",
-                        ChannelCount, LFE);
-                }
-                else
-                {
-                    switch (ChannelLayout)
-                    {
-                        case TSChannelLayout.CHANNELLAYOUT_MONO:
-                            description += "1.0";
-                            break;
-                        case TSChannelLayout.CHANNELLAYOUT_STEREO:
-                            description += "2.0";
-                            break;
-                        case TSChannelLayout.CHANNELLAYOUT_MULTI:
-                            description += "5.1";
-                            break;
-                    }
-                }
-                if (AudioMode == TSAudioMode.Extended)
-                {
-                    if (StreamType == TSStreamType.AC3_AUDIO)
-                    {
-                        description += "-EX";
-                    }
-                    if (StreamType == TSStreamType.DTS_AUDIO ||
-                        StreamType == TSStreamType.DTS_HD_AUDIO ||
-                        StreamType == TSStreamType.DTS_HD_MASTER_AUDIO)
-                    {
-                        description += "-ES";
-                    }
-                }
-                return description;
-            }
-        }
-
-        public override string Description
-        {
-            get
-            {
-                string description = ChannelDescription;
-
-                if (SampleRate > 0)
-                {
-                    description += string.Format(
-                        " / {0:D} kHz", SampleRate / 1000);
-                }
-                if (BitRate > 0)
-                {
-                    description += string.Format(
-                        " / {0:D} kbps", (uint)Math.Round((double)BitRate / 1000));
-                }
-                if (BitDepth > 0)
-                {
-                    description += string.Format(
-                        " / {0:D}-bit", BitDepth);
-                }
-                if (DialNorm != 0)
-                {
-                    description += string.Format(
-                        " / DN {0}dB", DialNorm);
-                }
-                if (ChannelCount == 2)
-                {
-                    switch (AudioMode)
-                    {
-                        case TSAudioMode.DualMono:
-                            description += " / Dual Mono";
-                            break;
-
-                        case TSAudioMode.Surround:
-                            description += " / Dolby Surround";
-                            break;
-                    }
-                }
-                if (description.EndsWith(" / "))
-                {
-                    description = description.Substring(0, description.Length - 3);
-                }
-                if (CoreStream != null)
-                {
-                    string codec = "";
-                    switch (CoreStream.StreamType)
-                    {
-                        case TSStreamType.AC3_AUDIO:
-                            codec = "AC3 Embedded";
-                            break;
-                        case TSStreamType.DTS_AUDIO:
-                            codec = "DTS Core";
-                            break;
-                    }
-                    description += string.Format(
-                        " ({0}: {1})",
-                        codec,
-                        CoreStream.Description);
-                }
-                return description;
-            }
-        }
-
-        public override TSStream Clone()
-        {
-            var stream = new TSAudioStream();
-            CopyTo(stream);
-
-            stream.SampleRate = SampleRate;
-            stream.ChannelLayout = ChannelLayout;
-            stream.ChannelCount = ChannelCount;
-            stream.BitDepth = BitDepth;
-            stream.LFE = LFE;
-            stream.DialNorm = DialNorm;
-            stream.AudioMode = AudioMode;
-            if (CoreStream != null)
-            {
-                stream.CoreStream = (TSAudioStream)CoreStream.Clone();
-            }
-
-            return stream;
-        }
-    }
-
-    public class TSGraphicsStream : TSStream
-    {
-        public TSGraphicsStream()
-        {
-            IsVBR = true;
-            IsInitialized = true;
-        }
-
-        public override TSStream Clone()
-        {
-            var stream = new TSGraphicsStream();
-            CopyTo(stream);
-            return stream;
-        }
-    }
-
-    public class TSTextStream : TSStream
-    {
-        public TSTextStream()
-        {
-            IsVBR = true;
-            IsInitialized = true;
-        }
-
-        public override TSStream Clone()
-        {
-            var stream = new TSTextStream();
-            CopyTo(stream);
-            return stream;
-        }
-    }
-}

+ 0 - 130
BDInfo/TSStreamBuffer.cs

@@ -1,130 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-using System;
-using System.Collections.Specialized;
-using System.IO;
-
-namespace BDInfo
-{
-    public class TSStreamBuffer
-    {
-        private MemoryStream Stream = new MemoryStream();
-        private int SkipBits = 0;
-        private byte[] Buffer;
-        private int BufferLength = 0;
-        public int TransferLength = 0;
-
-        public TSStreamBuffer()
-        {
-            Buffer = new byte[4096];
-            Stream = new MemoryStream(Buffer);
-        }
-
-        public long Length => (long)BufferLength;
-
-        public long Position => Stream.Position;
-
-        public void Add(
-            byte[] buffer,
-            int offset,
-            int length)
-        {
-            TransferLength += length;
-
-            if (BufferLength + length >= Buffer.Length)
-            {
-                length = Buffer.Length - BufferLength;
-            }
-            if (length > 0)
-            {
-                Array.Copy(buffer, offset, Buffer, BufferLength, length);
-                BufferLength += length;
-            }
-        }
-
-        public void Seek(
-            long offset,
-            SeekOrigin loc)
-        {
-            Stream.Seek(offset, loc);
-        }
-
-        public void Reset()
-        {
-            BufferLength = 0;
-            TransferLength = 0;
-        }
-
-        public void BeginRead()
-        {
-            SkipBits = 0;
-            Stream.Seek(0, SeekOrigin.Begin);
-        }
-
-        public void EndRead()
-        {
-        }
-
-        public byte[] ReadBytes(int bytes)
-        {
-            if (Stream.Position + bytes >= BufferLength)
-            {
-                return null;
-            }
-
-            byte[] value = new byte[bytes];
-            Stream.Read(value, 0, bytes);
-            return value;
-        }
-
-        public byte ReadByte()
-        {
-            return (byte)Stream.ReadByte();
-        }
-
-        public int ReadBits(int bits)
-        {
-            long pos = Stream.Position;
-
-            int shift = 24;
-            int data = 0;
-            for (int i = 0; i < 4; i++)
-            {
-                if (pos + i >= BufferLength) break;
-                data += (Stream.ReadByte() << shift);
-                shift -= 8;
-            }
-            var vector = new BitVector32(data);
-
-            int value = 0;
-            for (int i = SkipBits; i < SkipBits + bits; i++)
-            {
-                value <<= 1;
-                value += (vector[1 << (32 - i - 1)] ? 1 : 0);
-            }
-
-            SkipBits += bits;
-            Stream.Seek(pos + (SkipBits >> 3), SeekOrigin.Begin);
-            SkipBits = SkipBits % 8;
-
-            return value;
-        }
-    }
-}

+ 0 - 107
BDInfo/TSStreamClip.cs

@@ -1,107 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-using System;
-using System.Collections.Generic;
-
-namespace BDInfo
-{
-    public class TSStreamClip
-    {
-        public int AngleIndex = 0;
-        public string Name;
-        public double TimeIn;
-        public double TimeOut;
-        public double RelativeTimeIn;
-        public double RelativeTimeOut;
-        public double Length;
-
-        public ulong FileSize = 0;
-        public ulong InterleavedFileSize = 0;
-        public ulong PayloadBytes = 0;
-        public ulong PacketCount = 0;
-        public double PacketSeconds = 0;
-
-        public List<double> Chapters = new List<double>();
-
-        public TSStreamFile StreamFile = null;
-        public TSStreamClipFile StreamClipFile = null;
-
-        public TSStreamClip(
-            TSStreamFile streamFile,
-            TSStreamClipFile streamClipFile)
-        {
-            if (streamFile != null)
-            {
-                Name = streamFile.Name;
-                StreamFile = streamFile;
-                FileSize = (ulong)StreamFile.FileInfo.Length;
-                if (StreamFile.InterleavedFile != null)
-                {
-                    InterleavedFileSize = (ulong)StreamFile.InterleavedFile.FileInfo.Length;
-                }
-            }
-            StreamClipFile = streamClipFile;
-        }
-
-        public string DisplayName
-        {
-            get
-            {
-                if (StreamFile != null &&
-                    StreamFile.InterleavedFile != null &&
-                    BDInfoSettings.EnableSSIF)
-                {
-                    return StreamFile.InterleavedFile.Name;
-                }
-                return Name;
-            }
-        }
-
-        public ulong PacketSize => PacketCount * 192;
-
-        public ulong PacketBitRate
-        {
-            get
-            {
-                if (PacketSeconds > 0)
-                {
-                    return (ulong)Math.Round(((PacketSize * 8.0) / PacketSeconds));
-                }
-                return 0;
-            }
-        }
-
-        public bool IsCompatible(TSStreamClip clip)
-        {
-            foreach (var stream1 in StreamFile.Streams.Values)
-            {
-                if (clip.StreamFile.Streams.ContainsKey(stream1.PID))
-                {
-                    var stream2 = clip.StreamFile.Streams[stream1.PID];
-                    if (stream1.StreamType != stream2.StreamType)
-                    {
-                        return false;
-                    }
-                }
-            }
-            return true;
-        }
-    }
-}

+ 0 - 244
BDInfo/TSStreamClipFile.cs

@@ -1,244 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-#undef DEBUG
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using MediaBrowser.Model.IO;
-
-namespace BDInfo
-{
-    public class TSStreamClipFile
-    {
-        public FileSystemMetadata FileInfo = null;
-        public string FileType = null;
-        public bool IsValid = false;
-        public string Name = null;
-
-        public Dictionary<ushort, TSStream> Streams =
-            new Dictionary<ushort, TSStream>();
-
-        public TSStreamClipFile(FileSystemMetadata fileInfo)
-        {
-            FileInfo = fileInfo;
-            Name = fileInfo.Name.ToUpper();
-        }
-
-        public void Scan()
-        {
-            Stream fileStream = null;
-            BinaryReader fileReader = null;
-
-            try
-            {
-#if DEBUG
-                Debug.WriteLine(string.Format(
-                    "Scanning {0}...", Name));
-#endif
-                Streams.Clear();
-
-                fileStream = File.OpenRead(FileInfo.FullName);
-                fileReader = new BinaryReader(fileStream);
-
-                byte[] data = new byte[fileStream.Length];
-                fileReader.Read(data, 0, data.Length);
-
-                byte[] fileType = new byte[8];
-                Array.Copy(data, 0, fileType, 0, fileType.Length);
-
-                FileType = Encoding.ASCII.GetString(fileType, 0, fileType.Length);
-                if (FileType != "HDMV0100" &&
-                    FileType != "HDMV0200")
-                {
-                    throw new Exception(string.Format(
-                        "Clip info file {0} has an unknown file type {1}.",
-                        FileInfo.Name, FileType));
-                }
-#if DEBUG
-                Debug.WriteLine(string.Format(
-                    "\tFileType: {0}", FileType));
-#endif
-                int clipIndex =
-                    ((int)data[12] << 24) +
-                    ((int)data[13] << 16) +
-                    ((int)data[14] << 8) +
-                    ((int)data[15]);
-
-                int clipLength =
-                    ((int)data[clipIndex] << 24) +
-                    ((int)data[clipIndex + 1] << 16) +
-                    ((int)data[clipIndex + 2] << 8) +
-                    ((int)data[clipIndex + 3]);
-
-                byte[] clipData = new byte[clipLength];
-                Array.Copy(data, clipIndex + 4, clipData, 0, clipData.Length);
-
-                int streamCount = clipData[8];
-#if DEBUG
-                Debug.WriteLine(string.Format(
-                    "\tStreamCount: {0}", streamCount));
-#endif
-                int streamOffset = 10;
-                for (int streamIndex = 0;
-                    streamIndex < streamCount;
-                    streamIndex++)
-                {
-                    TSStream stream = null;
-
-                    ushort PID = (ushort)
-                        ((clipData[streamOffset] << 8) +
-                          clipData[streamOffset + 1]);
-
-                    streamOffset += 2;
-
-                    var streamType = (TSStreamType)
-                        clipData[streamOffset + 1];
-                    switch (streamType)
-                    {
-                        case TSStreamType.MVC_VIDEO:
-                            // TODO
-                            break;
-
-                        case TSStreamType.AVC_VIDEO:
-                        case TSStreamType.MPEG1_VIDEO:
-                        case TSStreamType.MPEG2_VIDEO:
-                        case TSStreamType.VC1_VIDEO:
-                            {
-                                var videoFormat = (TSVideoFormat)
-                                    (clipData[streamOffset + 2] >> 4);
-                                var frameRate = (TSFrameRate)
-                                    (clipData[streamOffset + 2] & 0xF);
-                                var aspectRatio = (TSAspectRatio)
-                                    (clipData[streamOffset + 3] >> 4);
-
-                                stream = new TSVideoStream();
-                                ((TSVideoStream)stream).VideoFormat = videoFormat;
-                                ((TSVideoStream)stream).AspectRatio = aspectRatio;
-                                ((TSVideoStream)stream).FrameRate = frameRate;
-#if DEBUG
-                            Debug.WriteLine(string.Format(
-                                "\t{0} {1} {2} {3} {4}",
-                                PID,
-                                streamType,
-                                videoFormat,
-                                frameRate,
-                                aspectRatio));
-#endif
-                            }
-                            break;
-
-                        case TSStreamType.AC3_AUDIO:
-                        case TSStreamType.AC3_PLUS_AUDIO:
-                        case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
-                        case TSStreamType.AC3_TRUE_HD_AUDIO:
-                        case TSStreamType.DTS_AUDIO:
-                        case TSStreamType.DTS_HD_AUDIO:
-                        case TSStreamType.DTS_HD_MASTER_AUDIO:
-                        case TSStreamType.DTS_HD_SECONDARY_AUDIO:
-                        case TSStreamType.LPCM_AUDIO:
-                        case TSStreamType.MPEG1_AUDIO:
-                        case TSStreamType.MPEG2_AUDIO:
-                            {
-                                byte[] languageBytes = new byte[3];
-                                Array.Copy(clipData, streamOffset + 3,
-                                    languageBytes, 0, languageBytes.Length);
-                                string languageCode = Encoding.ASCII.GetString(languageBytes, 0, languageBytes.Length);
-
-                                var channelLayout = (TSChannelLayout)
-                                    (clipData[streamOffset + 2] >> 4);
-                                var sampleRate = (TSSampleRate)
-                                    (clipData[streamOffset + 2] & 0xF);
-
-                                stream = new TSAudioStream();
-                                ((TSAudioStream)stream).LanguageCode = languageCode;
-                                ((TSAudioStream)stream).ChannelLayout = channelLayout;
-                                ((TSAudioStream)stream).SampleRate = TSAudioStream.ConvertSampleRate(sampleRate);
-                                ((TSAudioStream)stream).LanguageCode = languageCode;
-#if DEBUG
-                            Debug.WriteLine(string.Format(
-                                "\t{0} {1} {2} {3} {4}",
-                                PID,
-                                streamType,
-                                languageCode,
-                                channelLayout,
-                                sampleRate));
-#endif
-                            }
-                            break;
-
-                        case TSStreamType.INTERACTIVE_GRAPHICS:
-                        case TSStreamType.PRESENTATION_GRAPHICS:
-                            {
-                                byte[] languageBytes = new byte[3];
-                                Array.Copy(clipData, streamOffset + 2,
-                                    languageBytes, 0, languageBytes.Length);
-                                string languageCode = Encoding.ASCII.GetString(languageBytes, 0, languageBytes.Length);
-
-                                stream = new TSGraphicsStream();
-                                stream.LanguageCode = languageCode;
-#if DEBUG
-                            Debug.WriteLine(string.Format(
-                                "\t{0} {1} {2}",
-                                PID,
-                                streamType,
-                                languageCode));
-#endif
-                            }
-                            break;
-
-                        case TSStreamType.SUBTITLE:
-                            {
-                                byte[] languageBytes = new byte[3];
-                                Array.Copy(clipData, streamOffset + 3,
-                                    languageBytes, 0, languageBytes.Length);
-                                string languageCode = Encoding.ASCII.GetString(languageBytes, 0, languageBytes.Length);
-#if DEBUG
-                            Debug.WriteLine(string.Format(
-                                "\t{0} {1} {2}",
-                                PID,
-                                streamType,
-                                languageCode));
-#endif
-                                stream = new TSTextStream();
-                                stream.LanguageCode = languageCode;
-                            }
-                            break;
-                    }
-
-                    if (stream != null)
-                    {
-                        stream.PID = PID;
-                        stream.StreamType = streamType;
-                        Streams.Add(PID, stream);
-                    }
-
-                    streamOffset += clipData[streamOffset] + 1;
-                }
-                IsValid = true;
-            }
-            finally
-            {
-                if (fileReader != null) fileReader.Dispose();
-                if (fileStream != null) fileStream.Dispose();
-            }
-        }
-    }
-}

+ 0 - 1555
BDInfo/TSStreamFile.cs

@@ -1,1555 +0,0 @@
-//============================================================================
-// BDInfo - Blu-ray Video and Audio Analysis Tool
-// Copyright © 2010 Cinema Squid
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//=============================================================================
-
-#undef DEBUG
-using System;
-using System.Collections.Generic;
-using System.IO;
-using MediaBrowser.Model.IO;
-
-namespace BDInfo
-{
-    public class TSStreamState
-    {
-        public ulong TransferCount = 0;
-
-        public string StreamTag = null;
-
-        public ulong TotalPackets = 0;
-        public ulong WindowPackets = 0;
-
-        public ulong TotalBytes = 0;
-        public ulong WindowBytes = 0;
-
-        public long PeakTransferLength = 0;
-        public long PeakTransferRate = 0;
-
-        public double TransferMarker = 0;
-        public double TransferInterval = 0;
-
-        public TSStreamBuffer StreamBuffer = new TSStreamBuffer();
-
-        public uint Parse = 0;
-        public bool TransferState = false;
-        public int TransferLength = 0;
-        public int PacketLength = 0;
-        public byte PacketLengthParse = 0;
-        public byte PacketParse = 0;
-
-        public byte PTSParse = 0;
-        public ulong PTS = 0;
-        public ulong PTSTemp = 0;
-        public ulong PTSLast = 0;
-        public ulong PTSPrev = 0;
-        public ulong PTSDiff = 0;
-        public ulong PTSCount = 0;
-        public ulong PTSTransfer = 0;
-
-        public byte DTSParse = 0;
-        public ulong DTSTemp = 0;
-        public ulong DTSPrev = 0;
-
-        public byte PESHeaderLength = 0;
-        public byte PESHeaderFlags = 0;
-#if DEBUG
-        public byte PESHeaderIndex = 0;
-        public byte[] PESHeader = new byte[256 + 9];
-#endif
-    }
-
-    public class TSPacketParser
-    {
-        public bool SyncState = false;
-        public byte TimeCodeParse = 4;
-        public byte PacketLength = 0;
-        public byte HeaderParse = 0;
-
-        public uint TimeCode;
-        public byte TransportErrorIndicator;
-        public byte PayloadUnitStartIndicator;
-        public byte TransportPriority;
-        public ushort PID;
-        public byte TransportScramblingControl;
-        public byte AdaptionFieldControl;
-
-        public bool AdaptionFieldState = false;
-        public byte AdaptionFieldParse = 0;
-        public byte AdaptionFieldLength = 0;
-
-        public ushort PCRPID = 0xFFFF;
-        public byte PCRParse = 0;
-        public ulong PreviousPCR = 0;
-        public ulong PCR = 0;
-        public ulong PCRCount = 0;
-        public ulong PTSFirst = ulong.MaxValue;
-        public ulong PTSLast = ulong.MinValue;
-        public ulong PTSDiff = 0;
-
-        public byte[] PAT = new byte[1024];
-        public bool PATSectionStart = false;
-        public byte PATPointerField = 0;
-        public uint PATOffset = 0;
-        public byte PATSectionLengthParse = 0;
-        public ushort PATSectionLength = 0;
-        public uint PATSectionParse = 0;
-        public bool PATTransferState = false;
-        public byte PATSectionNumber = 0;
-        public byte PATLastSectionNumber = 0;
-
-        public ushort TransportStreamId = 0xFFFF;
-
-        public List<TSDescriptor> PMTProgramDescriptors = new List<TSDescriptor>();
-        public ushort PMTPID = 0xFFFF;
-        public Dictionary<ushort, byte[]> PMT = new Dictionary<ushort, byte[]>();
-        public bool PMTSectionStart = false;
-        public ushort PMTProgramInfoLength = 0;
-        public byte PMTProgramDescriptor = 0;
-        public byte PMTProgramDescriptorLengthParse = 0;
-        public byte PMTProgramDescriptorLength = 0;
-        public ushort PMTStreamInfoLength = 0;
-        public uint PMTStreamDescriptorLengthParse = 0;
-        public uint PMTStreamDescriptorLength = 0;
-        public byte PMTPointerField = 0;
-        public uint PMTOffset = 0;
-        public uint PMTSectionLengthParse = 0;
-        public ushort PMTSectionLength = 0;
-        public uint PMTSectionParse = 0;
-        public bool PMTTransferState = false;
-        public byte PMTSectionNumber = 0;
-        public byte PMTLastSectionNumber = 0;
-
-        public byte PMTTemp = 0;
-
-        public TSStream Stream = null;
-        public TSStreamState StreamState = null;
-
-        public ulong TotalPackets = 0;
-    }
-
-    public class TSStreamDiagnostics
-    {
-        public ulong Bytes = 0;
-        public ulong Packets = 0;
-        public double Marker = 0;
-        public double Interval = 0;
-        public string Tag = null;
-    }
-
-    public class TSStreamFile
-    {
-        public FileSystemMetadata FileInfo = null;
-        public string Name = null;
-        public long Size = 0;
-        public double Length = 0;
-
-        public TSInterleavedFile InterleavedFile = null;
-
-        private Dictionary<ushort, TSStreamState> StreamStates =
-            new Dictionary<ushort, TSStreamState>();
-
-        public Dictionary<ushort, TSStream> Streams =
-            new Dictionary<ushort, TSStream>();
-
-        public Dictionary<ushort, List<TSStreamDiagnostics>> StreamDiagnostics =
-            new Dictionary<ushort, List<TSStreamDiagnostics>>();
-
-        private List<TSPlaylistFile> Playlists = null;
-
-        private readonly IFileSystem _fileSystem;
-
-        public TSStreamFile(FileSystemMetadata fileInfo, IFileSystem fileSystem)
-        {
-            FileInfo = fileInfo;
-            _fileSystem = fileSystem;
-            Name = fileInfo.Name.ToUpper();
-        }
-
-        public string DisplayName
-        {
-            get
-            {
-                if (BDInfoSettings.EnableSSIF &&
-                    InterleavedFile != null)
-                {
-                    return InterleavedFile.Name;
-                }
-                return Name;
-            }
-        }
-
-        private bool ScanStream(
-            TSStream stream,
-            TSStreamState streamState,
-            TSStreamBuffer buffer)
-        {
-            streamState.StreamTag = null;
-
-            long bitrate = 0;
-            if (stream.IsAudioStream &&
-                streamState.PTSTransfer > 0)
-            {
-                bitrate = (long)Math.Round(
-                    (buffer.TransferLength * 8.0) /
-                    ((double)streamState.PTSTransfer / 90000));
-
-                if (bitrate > streamState.PeakTransferRate)
-                {
-                    streamState.PeakTransferRate = bitrate;
-                }
-            }
-            if (buffer.TransferLength > streamState.PeakTransferLength)
-            {
-                streamState.PeakTransferLength = buffer.TransferLength;
-            }
-
-            buffer.BeginRead();
-            switch (stream.StreamType)
-            {
-                case TSStreamType.MPEG2_VIDEO:
-                    TSCodecMPEG2.Scan(
-                        (TSVideoStream)stream, buffer, ref streamState.StreamTag);
-                    break;
-
-                case TSStreamType.AVC_VIDEO:
-                    TSCodecAVC.Scan(
-                        (TSVideoStream)stream, buffer, ref streamState.StreamTag);
-                    break;
-
-                case TSStreamType.MVC_VIDEO:
-                    TSCodecMVC.Scan(
-                        (TSVideoStream)stream, buffer, ref streamState.StreamTag);
-                    break;
-
-                case TSStreamType.VC1_VIDEO:
-                    TSCodecVC1.Scan(
-                        (TSVideoStream)stream, buffer, ref streamState.StreamTag);
-                    break;
-
-                case TSStreamType.AC3_AUDIO:
-                    TSCodecAC3.Scan(
-                        (TSAudioStream)stream, buffer, ref streamState.StreamTag);
-                    break;
-
-                case TSStreamType.AC3_PLUS_AUDIO:
-                case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
-                    TSCodecAC3.Scan(
-                        (TSAudioStream)stream, buffer, ref streamState.StreamTag);
-                    break;
-
-                case TSStreamType.AC3_TRUE_HD_AUDIO:
-                    TSCodecTrueHD.Scan(
-                        (TSAudioStream)stream, buffer, ref streamState.StreamTag);
-                    break;
-
-                case TSStreamType.LPCM_AUDIO:
-                    TSCodecLPCM.Scan(
-                        (TSAudioStream)stream, buffer, ref streamState.StreamTag);
-                    break;
-
-                case TSStreamType.DTS_AUDIO:
-                    TSCodecDTS.Scan(
-                        (TSAudioStream)stream, buffer, bitrate, ref streamState.StreamTag);
-                    break;
-
-                case TSStreamType.DTS_HD_AUDIO:
-                case TSStreamType.DTS_HD_MASTER_AUDIO:
-                case TSStreamType.DTS_HD_SECONDARY_AUDIO:
-                    TSCodecDTSHD.Scan(
-                        (TSAudioStream)stream, buffer, bitrate, ref streamState.StreamTag);
-                    break;
-
-                default:
-                    stream.IsInitialized = true;
-                    break;
-            }
-            buffer.EndRead();
-            streamState.StreamBuffer.Reset();
-
-            bool isAVC = false;
-            bool isMVC = false;
-            foreach (var finishedStream in Streams.Values)
-            {
-                if (!finishedStream.IsInitialized)
-                {
-                    return false;
-                }
-                if (finishedStream.StreamType == TSStreamType.AVC_VIDEO)
-                {
-                    isAVC = true;
-                }
-                if (finishedStream.StreamType == TSStreamType.MVC_VIDEO)
-                {
-                    isMVC = true;
-                }
-            }
-            if (isMVC && !isAVC)
-            {
-                return false;
-            }
-            return true;
-        }
-
-        private void UpdateStreamBitrates(
-            ushort PTSPID,
-            ulong PTS,
-            ulong PTSDiff)
-        {
-            if (Playlists == null) return;
-
-            foreach (ushort PID in StreamStates.Keys)
-            {
-                if (Streams.ContainsKey(PID) &&
-                    Streams[PID].IsVideoStream &&
-                    PID != PTSPID)
-                {
-                    continue;
-                }
-                if (StreamStates[PID].WindowPackets == 0)
-                {
-                    continue;
-                }
-                UpdateStreamBitrate(PID, PTSPID, PTS, PTSDiff);
-            }
-
-            foreach (var playlist in Playlists)
-            {
-                double packetSeconds = 0;
-                foreach (var clip in playlist.StreamClips)
-                {
-                    if (clip.AngleIndex == 0)
-                    {
-                        packetSeconds += clip.PacketSeconds;
-                    }
-                }
-                if (packetSeconds > 0)
-                {
-                    foreach (var playlistStream in playlist.SortedStreams)
-                    {
-                        if (playlistStream.IsVBR)
-                        {
-                            playlistStream.BitRate = (long)Math.Round(
-                                ((playlistStream.PayloadBytes * 8.0) / packetSeconds));
-
-                            if (playlistStream.StreamType == TSStreamType.AC3_TRUE_HD_AUDIO &&
-                                ((TSAudioStream)playlistStream).CoreStream != null)
-                            {
-                                playlistStream.BitRate -=
-                                    ((TSAudioStream)playlistStream).CoreStream.BitRate;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        private void UpdateStreamBitrate(
-            ushort PID,
-            ushort PTSPID,
-            ulong PTS,
-            ulong PTSDiff)
-        {
-            if (Playlists == null) return;
-
-            var streamState = StreamStates[PID];
-            double streamTime = (double)PTS / 90000;
-            double streamInterval = (double)PTSDiff / 90000;
-            double streamOffset = streamTime + streamInterval;
-
-            foreach (var playlist in Playlists)
-            {
-                foreach (var clip in playlist.StreamClips)
-                {
-                    if (clip.Name != this.Name) continue;
-
-                    if (streamTime == 0 ||
-                        (streamTime >= clip.TimeIn &&
-                         streamTime <= clip.TimeOut))
-                    {
-                        clip.PayloadBytes += streamState.WindowBytes;
-                        clip.PacketCount += streamState.WindowPackets;
-
-                        if (streamOffset > clip.TimeIn &&
-                            streamOffset - clip.TimeIn > clip.PacketSeconds)
-                        {
-                            clip.PacketSeconds = streamOffset - clip.TimeIn;
-                        }
-
-                        var playlistStreams = playlist.Streams;
-                        if (clip.AngleIndex > 0 &&
-                            clip.AngleIndex < playlist.AngleStreams.Count + 1)
-                        {
-                            playlistStreams = playlist.AngleStreams[clip.AngleIndex - 1];
-                        }
-                        if (playlistStreams.ContainsKey(PID))
-                        {
-                            var stream = playlistStreams[PID];
-
-                            stream.PayloadBytes += streamState.WindowBytes;
-                            stream.PacketCount += streamState.WindowPackets;
-
-                            if (stream.IsVideoStream)
-                            {
-                                stream.PacketSeconds += streamInterval;
-
-                                stream.ActiveBitRate = (long)Math.Round(
-                                    ((stream.PayloadBytes * 8.0) /
-                                    stream.PacketSeconds));
-                            }
-
-                            if (stream.StreamType == TSStreamType.AC3_TRUE_HD_AUDIO &&
-                                ((TSAudioStream)stream).CoreStream != null)
-                            {
-                                stream.ActiveBitRate -=
-                                    ((TSAudioStream)stream).CoreStream.BitRate;
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (Streams.ContainsKey(PID))
-            {
-                var stream = Streams[PID];
-                stream.PayloadBytes += streamState.WindowBytes;
-                stream.PacketCount += streamState.WindowPackets;
-
-                if (stream.IsVideoStream)
-                {
-                    var diag = new TSStreamDiagnostics();
-                    diag.Marker = (double)PTS / 90000;
-                    diag.Interval = (double)PTSDiff / 90000;
-                    diag.Bytes = streamState.WindowBytes;
-                    diag.Packets = streamState.WindowPackets;
-                    diag.Tag = streamState.StreamTag;
-                    StreamDiagnostics[PID].Add(diag);
-
-                    stream.PacketSeconds += streamInterval;
-                }
-            }
-            streamState.WindowPackets = 0;
-            streamState.WindowBytes = 0;
-        }
-
-        public void Scan(List<TSPlaylistFile> playlists, bool isFullScan)
-        {
-            if (playlists == null || playlists.Count == 0)
-            {
-                return;
-            }
-
-            Playlists = playlists;
-            int dataSize = 16384;
-            Stream fileStream = null;
-            try
-            {
-                string fileName;
-                if (BDInfoSettings.EnableSSIF &&
-                    InterleavedFile != null)
-                {
-                    fileName = InterleavedFile.FileInfo.FullName;
-                }
-                else
-                {
-                    fileName = FileInfo.FullName;
-                }
-                fileStream = _fileSystem.GetFileStream(
-                    fileName,
-                    FileOpenMode.Open,
-                    FileAccessMode.Read,
-                    FileShareMode.Read,
-                    false);
-
-                Size = 0;
-                Length = 0;
-
-                Streams.Clear();
-                StreamStates.Clear();
-                StreamDiagnostics.Clear();
-
-                var parser =
-                    new TSPacketParser();
-
-                long fileLength = (uint)fileStream.Length;
-                byte[] buffer = new byte[dataSize];
-                int bufferLength = 0;
-                while ((bufferLength =
-                    fileStream.Read(buffer, 0, buffer.Length)) > 0)
-                {
-                    int offset = 0;
-                    for (int i = 0; i < bufferLength; i++)
-                    {
-                        if (parser.SyncState == false)
-                        {
-                            if (parser.TimeCodeParse > 0)
-                            {
-                                parser.TimeCodeParse--;
-                                switch (parser.TimeCodeParse)
-                                {
-                                    case 3:
-                                        parser.TimeCode = 0;
-                                        parser.TimeCode |=
-                                            ((uint)buffer[i] & 0x3F) << 24;
-                                        break;
-                                    case 2:
-                                        parser.TimeCode |=
-                                            ((uint)buffer[i] & 0xFF) << 16;
-                                        break;
-                                    case 1:
-                                        parser.TimeCode |=
-                                            ((uint)buffer[i] & 0xFF) << 8;
-                                        break;
-                                    case 0:
-                                        parser.TimeCode |=
-                                            ((uint)buffer[i] & 0xFF);
-                                        break;
-                                }
-                            }
-                            else if (buffer[i] == 0x47)
-                            {
-                                parser.SyncState = true;
-                                parser.PacketLength = 187;
-                                parser.TimeCodeParse = 4;
-                                parser.HeaderParse = 3;
-                            }
-                        }
-                        else if (parser.HeaderParse > 0)
-                        {
-                            parser.PacketLength--;
-                            parser.HeaderParse--;
-
-                            switch (parser.HeaderParse)
-                            {
-                                case 2:
-                                    {
-                                        parser.TransportErrorIndicator =
-                                            (byte)((buffer[i] >> 7) & 0x1);
-                                        parser.PayloadUnitStartIndicator =
-                                            (byte)((buffer[i] >> 6) & 0x1);
-                                        parser.TransportPriority =
-                                            (byte)((buffer[i] >> 5) & 0x1);
-                                        parser.PID =
-                                            (ushort)((buffer[i] & 0x1f) << 8);
-                                    }
-                                    break;
-
-                                case 1:
-                                    {
-                                        parser.PID |= (ushort)buffer[i];
-                                        if (Streams.ContainsKey(parser.PID))
-                                        {
-                                            parser.Stream = Streams[parser.PID];
-                                        }
-                                        else
-                                        {
-                                            parser.Stream = null;
-                                        }
-                                        if (!StreamStates.ContainsKey(parser.PID))
-                                        {
-                                            StreamStates[parser.PID] = new TSStreamState();
-                                        }
-                                        parser.StreamState = StreamStates[parser.PID];
-                                        parser.StreamState.TotalPackets++;
-                                        parser.StreamState.WindowPackets++;
-                                        parser.TotalPackets++;
-                                    }
-                                    break;
-
-                                case 0:
-                                    {
-                                        parser.TransportScramblingControl =
-                                            (byte)((buffer[i] >> 6) & 0x3);
-                                        parser.AdaptionFieldControl =
-                                            (byte)((buffer[i] >> 4) & 0x3);
-
-                                        if ((parser.AdaptionFieldControl & 0x2) == 0x2)
-                                        {
-                                            parser.AdaptionFieldState = true;
-                                        }
-                                        if (parser.PayloadUnitStartIndicator == 1)
-                                        {
-                                            if (parser.PID == 0)
-                                            {
-                                                parser.PATSectionStart = true;
-                                            }
-                                            else if (parser.PID == parser.PMTPID)
-                                            {
-                                                parser.PMTSectionStart = true;
-                                            }
-                                            else if (parser.StreamState != null &&
-                                                parser.StreamState.TransferState)
-                                            {
-                                                parser.StreamState.TransferState = false;
-                                                parser.StreamState.TransferCount++;
-
-                                                bool isFinished = ScanStream(
-                                                    parser.Stream,
-                                                    parser.StreamState,
-                                                    parser.StreamState.StreamBuffer);
-
-                                                if (!isFullScan && isFinished)
-                                                {
-                                                    return;
-                                                }
-                                            }
-                                        }
-                                    }
-                                    break;
-                            }
-                        }
-                        else if (parser.AdaptionFieldState)
-                        {
-                            parser.PacketLength--;
-                            parser.AdaptionFieldParse = buffer[i];
-                            parser.AdaptionFieldLength = buffer[i];
-                            parser.AdaptionFieldState = false;
-                        }
-                        else if (parser.AdaptionFieldParse > 0)
-                        {
-                            parser.PacketLength--;
-                            parser.AdaptionFieldParse--;
-                            if ((parser.AdaptionFieldLength - parser.AdaptionFieldParse) == 1)
-                            {
-                                if ((buffer[i] & 0x10) == 0x10)
-                                {
-                                    parser.PCRParse = 6;
-                                    parser.PCR = 0;
-                                }
-                            }
-                            else if (parser.PCRParse > 0)
-                            {
-                                parser.PCRParse--;
-                                parser.PCR = (parser.PCR << 8) + (ulong)buffer[i];
-                                if (parser.PCRParse == 0)
-                                {
-                                    parser.PreviousPCR = parser.PCR;
-                                    parser.PCR = (parser.PCR & 0x1FF) +
-                                        ((parser.PCR >> 15) * 300);
-                                }
-                                parser.PCRCount++;
-                            }
-                            if (parser.PacketLength == 0)
-                            {
-                                parser.SyncState = false;
-                            }
-                        }
-                        else if (parser.PID == 0)
-                        {
-                            if (parser.PATTransferState)
-                            {
-                                if ((bufferLength - i) > parser.PATSectionLength)
-                                {
-                                    offset = parser.PATSectionLength;
-                                }
-                                else
-                                {
-                                    offset = (bufferLength - i);
-                                }
-                                if (parser.PacketLength <= offset)
-                                {
-                                    offset = parser.PacketLength;
-                                }
-
-                                for (int k = 0; k < offset; k++)
-                                {
-                                    parser.PAT[parser.PATOffset++] = buffer[i++];
-                                    parser.PATSectionLength--;
-                                    parser.PacketLength--;
-                                }
-                                --i;
-
-                                if (parser.PATSectionLength == 0)
-                                {
-                                    parser.PATTransferState = false;
-                                    if (parser.PATSectionNumber == parser.PATLastSectionNumber)
-                                    {
-                                        for (int k = 0; k < (parser.PATOffset - 4); k += 4)
-                                        {
-                                            uint programNumber = (uint)
-                                                ((parser.PAT[k] << 8) +
-                                                  parser.PAT[k + 1]);
-
-                                            ushort programPID = (ushort)
-                                                (((parser.PAT[k + 2] & 0x1F) << 8) +
-                                                   parser.PAT[k + 3]);
-
-                                            if (programNumber == 1)
-                                            {
-                                                parser.PMTPID = programPID;
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                            else
-                            {
-                                --parser.PacketLength;
-                                if (parser.PATSectionStart)
-                                {
-                                    parser.PATPointerField = buffer[i];
-                                    if (parser.PATPointerField == 0)
-                                    {
-                                        parser.PATSectionLengthParse = 3;
-                                    }
-                                    parser.PATSectionStart = false;
-                                }
-                                else if (parser.PATPointerField > 0)
-                                {
-                                    --parser.PATPointerField;
-                                    if (parser.PATPointerField == 0)
-                                    {
-                                        parser.PATSectionLengthParse = 3;
-                                    }
-                                }
-                                else if (parser.PATSectionLengthParse > 0)
-                                {
-                                    --parser.PATSectionLengthParse;
-                                    switch (parser.PATSectionLengthParse)
-                                    {
-                                        case 2:
-                                            break;
-                                        case 1:
-                                            parser.PATSectionLength = (ushort)
-                                                ((buffer[i] & 0xF) << 8);
-                                            break;
-                                        case 0:
-                                            parser.PATSectionLength |= buffer[i];
-                                            if (parser.PATSectionLength > 1021)
-                                            {
-                                                parser.PATSectionLength = 0;
-                                            }
-                                            else
-                                            {
-                                                parser.PATSectionParse = 5;
-                                            }
-                                            break;
-                                    }
-                                }
-                                else if (parser.PATSectionParse > 0)
-                                {
-                                    --parser.PATSectionLength;
-                                    --parser.PATSectionParse;
-
-                                    switch (parser.PATSectionParse)
-                                    {
-                                        case 4:
-                                            parser.TransportStreamId = (ushort)
-                                                (buffer[i] << 8);
-                                            break;
-                                        case 3:
-                                            parser.TransportStreamId |= buffer[i];
-                                            break;
-                                        case 2:
-                                            break;
-                                        case 1:
-                                            parser.PATSectionNumber = buffer[i];
-                                            if (parser.PATSectionNumber == 0)
-                                            {
-                                                parser.PATOffset = 0;
-                                            }
-                                            break;
-                                        case 0:
-                                            parser.PATLastSectionNumber = buffer[i];
-                                            parser.PATTransferState = true;
-                                            break;
-                                    }
-                                }
-                            }
-                            if (parser.PacketLength == 0)
-                            {
-                                parser.SyncState = false;
-                            }
-                        }
-                        else if (parser.PID == parser.PMTPID)
-                        {
-                            if (parser.PMTTransferState)
-                            {
-                                if ((bufferLength - i) >= parser.PMTSectionLength)
-                                {
-                                    offset = parser.PMTSectionLength;
-                                }
-                                else
-                                {
-                                    offset = (bufferLength - i);
-                                }
-                                if (parser.PacketLength <= offset)
-                                {
-                                    offset = parser.PacketLength;
-                                }
-                                if (!parser.PMT.ContainsKey(parser.PID))
-                                {
-                                    parser.PMT[parser.PID] = new byte[1024];
-                                }
-
-                                byte[] PMT = parser.PMT[parser.PID];
-                                for (int k = 0; k < offset; k++)
-                                {
-                                    PMT[parser.PMTOffset++] = buffer[i++];
-                                    --parser.PMTSectionLength;
-                                    --parser.PacketLength;
-                                }
-                                --i;
-
-                                if (parser.PMTSectionLength == 0)
-                                {
-                                    parser.PMTTransferState = false;
-                                    if (parser.PMTSectionNumber == parser.PMTLastSectionNumber)
-                                    {
-                                        //Console.WriteLine("PMT Start: " + parser.PMTTemp);
-                                        try
-                                        {
-                                            for (int k = 0; k < (parser.PMTOffset - 4); k += 5)
-                                            {
-                                                byte streamType = PMT[k];
-
-                                                ushort streamPID = (ushort)
-                                                    (((PMT[k + 1] & 0x1F) << 8) +
-                                                       PMT[k + 2]);
-
-                                                ushort streamInfoLength = (ushort)
-                                                    (((PMT[k + 3] & 0xF) << 8) +
-                                                       PMT[k + 4]);
-
-                                                /*
-                                                if (streamInfoLength == 2)
-                                                {
-                                                    // TODO: Cleanup
-                                                    //streamInfoLength = 0;
-                                                }
-
-                                                Console.WriteLine(string.Format(
-                                                    "Type: {0} PID: {1} Length: {2}",
-                                                    streamType, streamPID, streamInfoLength));
-                                                 */
-
-                                                if (!Streams.ContainsKey(streamPID))
-                                                {
-                                                    var streamDescriptors =
-                                                        new List<TSDescriptor>();
-
-                                                    /*
-                                                     * TODO: Getting bad streamInfoLength
-                                                    if (streamInfoLength > 0)
-                                                    {
-                                                        for (int d = 0; d < streamInfoLength; d++)
-                                                        {
-                                                            byte name = PMT[k + d + 5];
-                                                            byte length = PMT[k + d + 6];
-                                                            TSDescriptor descriptor =
-                                                                new TSDescriptor(name, length);
-                                                            for (int v = 0; v < length; v++)
-                                                            {
-                                                                descriptor.Value[v] =
-                                                                    PMT[k + d + v + 7];
-                                                            }
-                                                            streamDescriptors.Add(descriptor);
-                                                            d += (length + 1);
-                                                        }
-                                                    }
-                                                    */
-                                                    CreateStream(streamPID, streamType, streamDescriptors);
-                                                }
-                                                k += streamInfoLength;
-                                            }
-                                        }
-                                        catch
-                                        {
-                                            // TODO
-                                            //Console.WriteLine(ex.Message);
-                                        }
-                                    }
-                                }
-                            }
-                            else
-                            {
-                                --parser.PacketLength;
-                                if (parser.PMTSectionStart)
-                                {
-                                    parser.PMTPointerField = buffer[i];
-                                    if (parser.PMTPointerField == 0)
-                                    {
-                                        parser.PMTSectionLengthParse = 3;
-                                    }
-                                    parser.PMTSectionStart = false;
-                                }
-                                else if (parser.PMTPointerField > 0)
-                                {
-                                    --parser.PMTPointerField;
-                                    if (parser.PMTPointerField == 0)
-                                    {
-                                        parser.PMTSectionLengthParse = 3;
-                                    }
-                                }
-                                else if (parser.PMTSectionLengthParse > 0)
-                                {
-                                    --parser.PMTSectionLengthParse;
-                                    switch (parser.PMTSectionLengthParse)
-                                    {
-                                        case 2:
-                                            if (buffer[i] != 0x2)
-                                            {
-                                                parser.PMTSectionLengthParse = 0;
-                                            }
-                                            break;
-                                        case 1:
-                                            parser.PMTSectionLength = (ushort)
-                                                ((buffer[i] & 0xF) << 8);
-                                            break;
-                                        case 0:
-                                            parser.PMTSectionLength |= buffer[i];
-                                            if (parser.PMTSectionLength > 1021)
-                                            {
-                                                parser.PMTSectionLength = 0;
-                                            }
-                                            else
-                                            {
-                                                parser.PMTSectionParse = 9;
-                                            }
-                                            break;
-                                    }
-                                }
-                                else if (parser.PMTSectionParse > 0)
-                                {
-                                    --parser.PMTSectionLength;
-                                    --parser.PMTSectionParse;
-
-                                    switch (parser.PMTSectionParse)
-                                    {
-                                        case 8:
-                                        case 7:
-                                            break;
-                                        case 6:
-                                            parser.PMTTemp = buffer[i];
-                                            break;
-                                        case 5:
-                                            parser.PMTSectionNumber = buffer[i];
-                                            if (parser.PMTSectionNumber == 0)
-                                            {
-                                                parser.PMTOffset = 0;
-                                            }
-                                            break;
-                                        case 4:
-                                            parser.PMTLastSectionNumber = buffer[i];
-                                            break;
-                                        case 3:
-                                            parser.PCRPID = (ushort)
-                                                ((buffer[i] & 0x1F) << 8);
-                                            break;
-                                        case 2:
-                                            parser.PCRPID |= buffer[i];
-                                            break;
-                                        case 1:
-                                            parser.PMTProgramInfoLength = (ushort)
-                                                ((buffer[i] & 0xF) << 8);
-                                            break;
-                                        case 0:
-                                            parser.PMTProgramInfoLength |= buffer[i];
-                                            if (parser.PMTProgramInfoLength == 0)
-                                            {
-                                                parser.PMTTransferState = true;
-                                            }
-                                            else
-                                            {
-                                                parser.PMTProgramDescriptorLengthParse = 2;
-                                            }
-                                            break;
-                                    }
-                                }
-                                else if (parser.PMTProgramInfoLength > 0)
-                                {
-                                    --parser.PMTSectionLength;
-                                    --parser.PMTProgramInfoLength;
-
-                                    if (parser.PMTProgramDescriptorLengthParse > 0)
-                                    {
-                                        --parser.PMTProgramDescriptorLengthParse;
-                                        switch (parser.PMTProgramDescriptorLengthParse)
-                                        {
-                                            case 1:
-                                                parser.PMTProgramDescriptor = buffer[i];
-                                                break;
-                                            case 0:
-                                                parser.PMTProgramDescriptorLength = buffer[i];
-                                                parser.PMTProgramDescriptors.Add(
-                                                    new TSDescriptor(
-                                                        parser.PMTProgramDescriptor,
-                                                        parser.PMTProgramDescriptorLength));
-                                                break;
-                                        }
-                                    }
-                                    else if (parser.PMTProgramDescriptorLength > 0)
-                                    {
-                                        --parser.PMTProgramDescriptorLength;
-
-                                        var descriptor = parser.PMTProgramDescriptors[
-                                            parser.PMTProgramDescriptors.Count - 1];
-
-                                        int valueIndex =
-                                            descriptor.Value.Length -
-                                            parser.PMTProgramDescriptorLength - 1;
-
-                                        descriptor.Value[valueIndex] = buffer[i];
-
-                                        if (parser.PMTProgramDescriptorLength == 0 &&
-                                            parser.PMTProgramInfoLength > 0)
-                                        {
-                                            parser.PMTProgramDescriptorLengthParse = 2;
-                                        }
-                                    }
-                                    if (parser.PMTProgramInfoLength == 0)
-                                    {
-                                        parser.PMTTransferState = true;
-                                    }
-                                }
-                            }
-                            if (parser.PacketLength == 0)
-                            {
-                                parser.SyncState = false;
-                            }
-                        }
-                        else if (parser.Stream != null &&
-                            parser.StreamState != null &&
-                            parser.TransportScramblingControl == 0)
-                        {
-                            var stream = parser.Stream;
-                            var streamState = parser.StreamState;
-
-                            streamState.Parse =
-                                (streamState.Parse << 8) + buffer[i];
-
-                            if (streamState.TransferState)
-                            {
-                                if ((bufferLength - i) >= streamState.PacketLength &&
-                                    streamState.PacketLength > 0)
-                                {
-                                    offset = streamState.PacketLength;
-                                }
-                                else
-                                {
-                                    offset = (bufferLength - i);
-                                }
-                                if (parser.PacketLength <= offset)
-                                {
-                                    offset = parser.PacketLength;
-                                }
-                                streamState.TransferLength = offset;
-
-                                if (!stream.IsInitialized ||
-                                    stream.IsVideoStream)
-                                {
-                                    streamState.StreamBuffer.Add(
-                                        buffer, i, offset);
-                                }
-                                else
-                                {
-                                    streamState.StreamBuffer.TransferLength += offset;
-                                }
-
-                                i += (int)(streamState.TransferLength - 1);
-                                streamState.PacketLength -= streamState.TransferLength;
-                                parser.PacketLength -= (byte)streamState.TransferLength;
-
-                                streamState.TotalBytes += (ulong)streamState.TransferLength;
-                                streamState.WindowBytes += (ulong)streamState.TransferLength;
-
-                                if (streamState.PacketLength == 0)
-                                {
-                                    streamState.TransferState = false;
-                                    streamState.TransferCount++;
-                                    bool isFinished = ScanStream(
-                                        stream,
-                                        streamState,
-                                        streamState.StreamBuffer);
-
-                                    if (!isFullScan && isFinished)
-                                    {
-                                        return;
-                                    }
-                                }
-                            }
-                            else
-                            {
-                                --parser.PacketLength;
-
-                                bool headerFound = false;
-                                if (stream.IsVideoStream &&
-                                    streamState.Parse == 0x000001FD)
-                                {
-                                    headerFound = true;
-                                }
-                                if (stream.IsVideoStream &&
-                                    streamState.Parse >= 0x000001E0 &&
-                                    streamState.Parse <= 0x000001EF)
-                                {
-                                    headerFound = true;
-                                }
-                                if (stream.IsAudioStream &&
-                                    streamState.Parse == 0x000001BD)
-                                {
-                                    headerFound = true;
-                                }
-                                if (stream.IsAudioStream &&
-                                    (streamState.Parse == 0x000001FA ||
-                                     streamState.Parse == 0x000001FD))
-                                {
-                                    headerFound = true;
-                                }
-
-                                if (!stream.IsVideoStream &&
-                                    !stream.IsAudioStream &&
-                                    (streamState.Parse == 0x000001FA ||
-                                     streamState.Parse == 0x000001FD ||
-                                     streamState.Parse == 0x000001BD ||
-                                     (streamState.Parse >= 0x000001E0 &&
-                                      streamState.Parse <= 0x000001EF)))
-                                {
-                                    headerFound = true;
-                                }
-
-                                if (headerFound)
-                                {
-                                    streamState.PacketLengthParse = 2;
-#if DEBUG
-                                    streamState.PESHeaderIndex = 0;
-                                    streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                        (byte)((streamState.Parse >> 24) & 0xFF);
-                                    streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                        (byte)((streamState.Parse >> 16) & 0xFF);
-                                    streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                        (byte)((streamState.Parse >> 8) & 0xFF);
-                                    streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                        (byte)(streamState.Parse & 0xFF);
-#endif
-                                }
-                                else if (streamState.PacketLengthParse > 0)
-                                {
-                                    --streamState.PacketLengthParse;
-                                    switch (streamState.PacketLengthParse)
-                                    {
-                                        case 1:
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            break;
-
-                                        case 0:
-                                            streamState.PacketLength =
-                                                (int)(streamState.Parse & 0xFFFF);
-                                            streamState.PacketParse = 3;
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            break;
-                                    }
-                                }
-                                else if (streamState.PacketParse > 0)
-                                {
-                                    --streamState.PacketLength;
-                                    --streamState.PacketParse;
-
-                                    switch (streamState.PacketParse)
-                                    {
-                                        case 2:
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            break;
-
-                                        case 1:
-                                            streamState.PESHeaderFlags =
-                                                (byte)(streamState.Parse & 0xFF);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            break;
-
-                                        case 0:
-                                            streamState.PESHeaderLength =
-                                                (byte)(streamState.Parse & 0xFF);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            if ((streamState.PESHeaderFlags & 0xC0) == 0x80)
-                                            {
-                                                streamState.PTSParse = 5;
-                                            }
-                                            else if ((streamState.PESHeaderFlags & 0xC0) == 0xC0)
-                                            {
-                                                streamState.DTSParse = 10;
-                                            }
-                                            if (streamState.PESHeaderLength == 0)
-                                            {
-                                                streamState.TransferState = true;
-                                            }
-                                            break;
-                                    }
-                                }
-                                else if (streamState.PTSParse > 0)
-                                {
-                                    --streamState.PacketLength;
-                                    --streamState.PESHeaderLength;
-                                    --streamState.PTSParse;
-
-                                    switch (streamState.PTSParse)
-                                    {
-                                        case 4:
-                                            streamState.PTSTemp =
-                                                ((streamState.Parse & 0xE) << 29);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xff);
-#endif
-                                            break;
-
-                                        case 3:
-                                            streamState.PTSTemp |=
-                                                ((streamState.Parse & 0xFF) << 22);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            break;
-
-                                        case 2:
-                                            streamState.PTSTemp |=
-                                                ((streamState.Parse & 0xFE) << 14);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            break;
-
-                                        case 1:
-                                            streamState.PTSTemp |=
-                                                ((streamState.Parse & 0xFF) << 7);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            break;
-
-                                        case 0:
-                                            streamState.PTSTemp |=
-                                                ((streamState.Parse & 0xFE) >> 1);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xff);
-#endif
-                                            streamState.PTS = streamState.PTSTemp;
-
-                                            if (streamState.PTS > streamState.PTSLast)
-                                            {
-                                                if (streamState.PTSLast > 0)
-                                                {
-                                                    streamState.PTSTransfer = (streamState.PTS - streamState.PTSLast);
-                                                }
-                                                streamState.PTSLast = streamState.PTS;
-                                            }
-
-                                            streamState.PTSDiff = streamState.PTS - streamState.DTSPrev;
-
-                                            if (streamState.PTSCount > 0 &&
-                                                stream.IsVideoStream)
-                                            {
-                                                UpdateStreamBitrates(stream.PID, streamState.PTS, streamState.PTSDiff);
-                                                if (streamState.DTSTemp < parser.PTSFirst)
-                                                {
-                                                    parser.PTSFirst = streamState.DTSTemp;
-                                                }
-                                                if (streamState.DTSTemp > parser.PTSLast)
-                                                {
-                                                    parser.PTSLast = streamState.DTSTemp;
-                                                }
-                                                Length = (double)(parser.PTSLast - parser.PTSFirst) / 90000;
-                                            }
-
-                                            streamState.DTSPrev = streamState.PTS;
-                                            streamState.PTSCount++;
-                                            if (streamState.PESHeaderLength == 0)
-                                            {
-                                                streamState.TransferState = true;
-                                            }
-                                            break;
-                                    }
-                                }
-                                else if (streamState.DTSParse > 0)
-                                {
-                                    --streamState.PacketLength;
-                                    --streamState.PESHeaderLength;
-                                    --streamState.DTSParse;
-
-                                    switch (streamState.DTSParse)
-                                    {
-                                        case 9:
-                                            streamState.PTSTemp =
-                                                ((streamState.Parse & 0xE) << 29);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            break;
-
-                                        case 8:
-                                            streamState.PTSTemp |=
-                                                ((streamState.Parse & 0xFF) << 22);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            break;
-
-                                        case 7:
-                                            streamState.PTSTemp |=
-                                                ((streamState.Parse & 0xFE) << 14);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xff);
-#endif
-                                            break;
-
-                                        case 6:
-                                            streamState.PTSTemp |=
-                                                ((streamState.Parse & 0xFF) << 7);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            break;
-
-                                        case 5:
-                                            streamState.PTSTemp |=
-                                                ((streamState.Parse & 0xFE) >> 1);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xff);
-#endif
-                                            streamState.PTS = streamState.PTSTemp;
-                                            if (streamState.PTS > streamState.PTSLast)
-                                            {
-                                                streamState.PTSLast = streamState.PTS;
-                                            }
-                                            break;
-
-                                        case 4:
-                                            streamState.DTSTemp =
-                                                ((streamState.Parse & 0xE) << 29);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xff);
-#endif
-                                            break;
-
-                                        case 3:
-                                            streamState.DTSTemp |=
-                                                ((streamState.Parse & 0xFF) << 22);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xff);
-#endif
-                                            break;
-
-                                        case 2:
-                                            streamState.DTSTemp |=
-                                                ((streamState.Parse & 0xFE) << 14);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xff);
-#endif
-                                            break;
-
-                                        case 1:
-                                            streamState.DTSTemp |=
-                                                ((streamState.Parse & 0xFF) << 7);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xFF);
-#endif
-                                            break;
-
-                                        case 0:
-                                            streamState.DTSTemp |=
-                                                ((streamState.Parse & 0xFE) >> 1);
-#if DEBUG
-                                            streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                                (byte)(streamState.Parse & 0xff);
-#endif
-                                            streamState.PTSDiff = streamState.DTSTemp - streamState.DTSPrev;
-
-                                            if (streamState.PTSCount > 0 &&
-                                                stream.IsVideoStream)
-                                            {
-                                                UpdateStreamBitrates(stream.PID, streamState.DTSTemp, streamState.PTSDiff);
-                                                if (streamState.DTSTemp < parser.PTSFirst)
-                                                {
-                                                    parser.PTSFirst = streamState.DTSTemp;
-                                                }
-                                                if (streamState.DTSTemp > parser.PTSLast)
-                                                {
-                                                    parser.PTSLast = streamState.DTSTemp;
-                                                }
-                                                Length = (double)(parser.PTSLast - parser.PTSFirst) / 90000;
-                                            }
-                                            streamState.DTSPrev = streamState.DTSTemp;
-                                            streamState.PTSCount++;
-                                            if (streamState.PESHeaderLength == 0)
-                                            {
-                                                streamState.TransferState = true;
-                                            }
-                                            break;
-                                    }
-                                }
-                                else if (streamState.PESHeaderLength > 0)
-                                {
-                                    --streamState.PacketLength;
-                                    --streamState.PESHeaderLength;
-#if DEBUG
-                                    streamState.PESHeader[streamState.PESHeaderIndex++] =
-                                        (byte)(streamState.Parse & 0xFF);
-#endif
-                                    if (streamState.PESHeaderLength == 0)
-                                    {
-                                        streamState.TransferState = true;
-                                    }
-                                }
-                            }
-                            if (parser.PacketLength == 0)
-                            {
-                                parser.SyncState = false;
-                            }
-                        }
-                        else
-                        {
-                            parser.PacketLength--;
-                            if ((bufferLength - i) >= parser.PacketLength)
-                            {
-                                i = i + parser.PacketLength;
-                                parser.PacketLength = 0;
-                            }
-                            else
-                            {
-                                parser.PacketLength -= (byte)((bufferLength - i) + 1);
-                                i = bufferLength;
-                            }
-                            if (parser.PacketLength == 0)
-                            {
-                                parser.SyncState = false;
-                            }
-                        }
-                    }
-                    Size += bufferLength;
-                }
-
-                ulong PTSLast = 0;
-                ulong PTSDiff = 0;
-                foreach (var stream in Streams.Values)
-                {
-                    if (!stream.IsVideoStream) continue;
-
-                    if (StreamStates.ContainsKey(stream.PID) &&
-                        StreamStates[stream.PID].PTSLast > PTSLast)
-                    {
-                        PTSLast = StreamStates[stream.PID].PTSLast;
-                        PTSDiff = PTSLast - StreamStates[stream.PID].DTSPrev;
-                    }
-                    UpdateStreamBitrates(stream.PID, PTSLast, PTSDiff);
-                }
-            }
-            finally
-            {
-                if (fileStream != null)
-                {
-                    fileStream.Dispose();
-                }
-            }
-        }
-
-        private TSStream CreateStream(
-            ushort streamPID,
-            byte streamType,
-            List<TSDescriptor> streamDescriptors)
-        {
-            TSStream stream = null;
-
-            switch ((TSStreamType)streamType)
-            {
-                case TSStreamType.MVC_VIDEO:
-                case TSStreamType.AVC_VIDEO:
-                case TSStreamType.MPEG1_VIDEO:
-                case TSStreamType.MPEG2_VIDEO:
-                case TSStreamType.VC1_VIDEO:
-                    {
-                        stream = new TSVideoStream();
-                    }
-                    break;
-
-                case TSStreamType.AC3_AUDIO:
-                case TSStreamType.AC3_PLUS_AUDIO:
-                case TSStreamType.AC3_PLUS_SECONDARY_AUDIO:
-                case TSStreamType.AC3_TRUE_HD_AUDIO:
-                case TSStreamType.DTS_AUDIO:
-                case TSStreamType.DTS_HD_AUDIO:
-                case TSStreamType.DTS_HD_MASTER_AUDIO:
-                case TSStreamType.DTS_HD_SECONDARY_AUDIO:
-                case TSStreamType.LPCM_AUDIO:
-                case TSStreamType.MPEG1_AUDIO:
-                case TSStreamType.MPEG2_AUDIO:
-                    {
-                        stream = new TSAudioStream();
-                    }
-                    break;
-
-                case TSStreamType.INTERACTIVE_GRAPHICS:
-                case TSStreamType.PRESENTATION_GRAPHICS:
-                    {
-                        stream = new TSGraphicsStream();
-                    }
-                    break;
-
-                case TSStreamType.SUBTITLE:
-                    {
-                        stream = new TSTextStream();
-                    }
-                    break;
-
-                default:
-                    break;
-            }
-
-            if (stream != null &&
-                !Streams.ContainsKey(streamPID))
-            {
-                stream.PID = streamPID;
-                stream.StreamType = (TSStreamType)streamType;
-                stream.Descriptors = streamDescriptors;
-                Streams[stream.PID] = stream;
-            }
-            if (!StreamDiagnostics.ContainsKey(streamPID))
-            {
-                StreamDiagnostics[streamPID] =
-                    new List<TSStreamDiagnostics>();
-            }
-
-            return stream;
-        }
-    }
-}

+ 2 - 0
CONTRIBUTORS.md

@@ -30,6 +30,8 @@
  - [Khinenw](https://github.com/HelloWorld017)
  - [Khinenw](https://github.com/HelloWorld017)
  - [fhriley](https://github.com/fhriley)
  - [fhriley](https://github.com/fhriley)
  - [nevado](https://github.com/nevado)
  - [nevado](https://github.com/nevado)
+ - [mark-monteiro](https://github.com/mark-monteiro)
+ - [ullmie02](https://github.com/ullmie02)
 
 
 # Emby Contributors
 # Emby Contributors
 
 

+ 5 - 5
Dockerfile

@@ -1,4 +1,4 @@
-ARG DOTNET_VERSION=3.0
+ARG DOTNET_VERSION=3.1
 ARG FFMPEG_VERSION=latest
 ARG FFMPEG_VERSION=latest
 
 
 FROM node:alpine as web-builder
 FROM node:alpine as web-builder
@@ -42,7 +42,7 @@ ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
 
 
 EXPOSE 8096
 EXPOSE 8096
 VOLUME /cache /config /media
 VOLUME /cache /config /media
-ENTRYPOINT ./jellyfin/jellyfin \
-    --datadir /config \
-    --cachedir /cache \
-    --ffmpeg /usr/local/bin/ffmpeg
+ENTRYPOINT ["./jellyfin/jellyfin", \
+    "--datadir", "/config", \
+    "--cachedir", "/cache", \
+    "--ffmpeg", "/usr/local/bin/ffmpeg"]

+ 5 - 5
Dockerfile.arm

@@ -1,6 +1,6 @@
 # Requires binfm_misc registration
 # Requires binfm_misc registration
 # https://github.com/multiarch/qemu-user-static#binfmt_misc-register
 # https://github.com/multiarch/qemu-user-static#binfmt_misc-register
-ARG DOTNET_VERSION=3.0
+ARG DOTNET_VERSION=3.1
 
 
 
 
 FROM node:alpine as web-builder
 FROM node:alpine as web-builder
@@ -38,7 +38,7 @@ ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
 
 
 EXPOSE 8096
 EXPOSE 8096
 VOLUME /cache /config /media
 VOLUME /cache /config /media
-ENTRYPOINT ./jellyfin/jellyfin \
-    --datadir /config \
-    --cachedir /cache \
-    --ffmpeg /usr/bin/ffmpeg
+ENTRYPOINT ["./jellyfin/jellyfin", \
+    "--datadir", "/config", \
+    "--cachedir", "/cache", \
+    "--ffmpeg", "/usr/bin/ffmpeg"]

+ 5 - 5
Dockerfile.arm64

@@ -1,6 +1,6 @@
 # Requires binfm_misc registration
 # Requires binfm_misc registration
 # https://github.com/multiarch/qemu-user-static#binfmt_misc-register
 # https://github.com/multiarch/qemu-user-static#binfmt_misc-register
-ARG DOTNET_VERSION=3.0
+ARG DOTNET_VERSION=3.1
 
 
 
 
 FROM node:alpine as web-builder
 FROM node:alpine as web-builder
@@ -38,7 +38,7 @@ ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
 
 
 EXPOSE 8096
 EXPOSE 8096
 VOLUME /cache /config /media
 VOLUME /cache /config /media
-ENTRYPOINT ./jellyfin/jellyfin \
-    --datadir /config \
-    --cachedir /cache \
-    --ffmpeg /usr/bin/ffmpeg
+ENTRYPOINT ["./jellyfin/jellyfin", \
+    "--datadir", "/config", \
+    "--cachedir", "/cache", \
+    "--ffmpeg", "/usr/bin/ffmpeg"]

+ 93 - 28
Emby.Dlna/Api/DlnaServerService.cs

@@ -1,11 +1,10 @@
 using System;
 using System;
-using System.Collections.Generic;
 using System.IO;
 using System.IO;
-using System.Linq;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using Emby.Dlna.Main;
 using Emby.Dlna.Main;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Dlna;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Services;
 using MediaBrowser.Model.Services;
@@ -108,12 +107,13 @@ namespace Emby.Dlna.Api
 
 
     public class DlnaServerService : IService, IRequiresRequest
     public class DlnaServerService : IService, IRequiresRequest
     {
     {
-        private readonly IDlnaManager _dlnaManager;
-
         private const string XMLContentType = "text/xml; charset=UTF-8";
         private const string XMLContentType = "text/xml; charset=UTF-8";
 
 
+        private readonly IDlnaManager _dlnaManager;
+        private readonly IHttpResultFactory _resultFactory;
+        private readonly IServerConfigurationManager _configurationManager;
+
         public IRequest Request { get; set; }
         public IRequest Request { get; set; }
-        private IHttpResultFactory _resultFactory;
 
 
         private IContentDirectory ContentDirectory => DlnaEntryPoint.Current.ContentDirectory;
         private IContentDirectory ContentDirectory => DlnaEntryPoint.Current.ContentDirectory;
 
 
@@ -121,10 +121,14 @@ namespace Emby.Dlna.Api
 
 
         private IMediaReceiverRegistrar MediaReceiverRegistrar => DlnaEntryPoint.Current.MediaReceiverRegistrar;
         private IMediaReceiverRegistrar MediaReceiverRegistrar => DlnaEntryPoint.Current.MediaReceiverRegistrar;
 
 
-        public DlnaServerService(IDlnaManager dlnaManager, IHttpResultFactory httpResultFactory)
+        public DlnaServerService(
+            IDlnaManager dlnaManager,
+            IHttpResultFactory httpResultFactory,
+            IServerConfigurationManager configurationManager)
         {
         {
             _dlnaManager = dlnaManager;
             _dlnaManager = dlnaManager;
             _resultFactory = httpResultFactory;
             _resultFactory = httpResultFactory;
+            _configurationManager = configurationManager;
         }
         }
 
 
         private string GetHeader(string name)
         private string GetHeader(string name)
@@ -189,7 +193,7 @@ namespace Emby.Dlna.Api
 
 
         private ControlResponse PostAsync(Stream requestStream, IUpnpService service)
         private ControlResponse PostAsync(Stream requestStream, IUpnpService service)
         {
         {
-            var id = GetPathValue(2);
+            var id = GetPathValue(2).ToString();
 
 
             return service.ProcessControlRequest(new ControlRequest
             return service.ProcessControlRequest(new ControlRequest
             {
             {
@@ -200,38 +204,99 @@ namespace Emby.Dlna.Api
             });
             });
         }
         }
 
 
-        protected string GetPathValue(int index)
+        // Copied from MediaBrowser.Api/BaseApiService.cs
+        // TODO: Remove code duplication
+        /// <summary>
+        /// Gets the path segment at the specified index.
+        /// </summary>
+        /// <param name="index">The index of the path segment.</param>
+        /// <returns>The path segment at the specified index.</returns>
+        /// <exception cref="IndexOutOfRangeException" >Path doesn't contain enough segments.</exception>
+        /// <exception cref="InvalidDataException" >Path doesn't start with the base url.</exception>
+        protected internal ReadOnlySpan<char> GetPathValue(int index)
         {
         {
-            var pathInfo = Parse(Request.PathInfo);
-            var first = pathInfo[0];
-
-            // backwards compatibility
-            // TODO: Work out what this is doing.
-            if (string.Equals(first, "mediabrowser", StringComparison.OrdinalIgnoreCase) ||
-                string.Equals(first, "emby", StringComparison.OrdinalIgnoreCase) ||
-                string.Equals(first, "jellyfin", StringComparison.OrdinalIgnoreCase))
+            static void ThrowIndexOutOfRangeException()
+                => throw new IndexOutOfRangeException("Path doesn't contain enough segments.");
+
+            static void ThrowInvalidDataException()
+                => throw new InvalidDataException("Path doesn't start with the base url.");
+
+            ReadOnlySpan<char> path = Request.PathInfo;
+
+            // Remove the protocol part from the url
+            int pos = path.LastIndexOf("://");
+            if (pos != -1)
             {
             {
-                index++;
+                path = path.Slice(pos + 3);
             }
             }
 
 
-            return pathInfo[index];
-        }
+            // Remove the query string
+            pos = path.LastIndexOf('?');
+            if (pos != -1)
+            {
+                path = path.Slice(0, pos);
+            }
 
 
-        private List<string> Parse(string pathUri)
-        {
-            var actionParts = pathUri.Split(new[] { "://" }, StringSplitOptions.None);
+            // Remove the domain
+            pos = path.IndexOf('/');
+            if (pos != -1)
+            {
+                path = path.Slice(pos);
+            }
 
 
-            var pathInfo = actionParts[actionParts.Length - 1];
+            // Remove base url
+            string baseUrl = _configurationManager.Configuration.BaseUrl;
+            int baseUrlLen = baseUrl.Length;
+            if (baseUrlLen != 0)
+            {
+                if (path.StartsWith(baseUrl, StringComparison.OrdinalIgnoreCase))
+                {
+                    path = path.Slice(baseUrlLen);
+                }
+                else
+                {
+                    // The path doesn't start with the base url,
+                    // how did we get here?
+                    ThrowInvalidDataException();
+                }
+            }
+
+            // Remove leading /
+            path = path.Slice(1);
 
 
-            var optionsPos = pathInfo.LastIndexOf('?');
-            if (optionsPos != -1)
+            // Backwards compatibility
+            const string Emby = "emby/";
+            if (path.StartsWith(Emby, StringComparison.OrdinalIgnoreCase))
             {
             {
-                pathInfo = pathInfo.Substring(0, optionsPos);
+                path = path.Slice(Emby.Length);
             }
             }
 
 
-            var args = pathInfo.Split('/');
+            const string MediaBrowser = "mediabrowser/";
+            if (path.StartsWith(MediaBrowser, StringComparison.OrdinalIgnoreCase))
+            {
+                path = path.Slice(MediaBrowser.Length);
+            }
+
+            // Skip segments until we are at the right index
+            for (int i = 0; i < index; i++)
+            {
+                pos = path.IndexOf('/');
+                if (pos == -1)
+                {
+                    ThrowIndexOutOfRangeException();
+                }
+
+                path = path.Slice(pos + 1);
+            }
+
+            // Remove the rest
+            pos = path.IndexOf('/');
+            if (pos != -1)
+            {
+                path = path.Slice(0, pos);
+            }
 
 
-            return args.Skip(1).ToList();
+            return path;
         }
         }
 
 
         public object Get(GetIcon request)
         public object Get(GetIcon request)

+ 2 - 3
Emby.Dlna/ContentDirectory/ContentDirectory.cs

@@ -1,5 +1,4 @@
 using System;
 using System;
-using System.Collections.Generic;
 using Emby.Dlna.Service;
 using Emby.Dlna.Service;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
@@ -104,7 +103,7 @@ namespace Emby.Dlna.ContentDirectory
         {
         {
             if (!string.IsNullOrEmpty(profile.UserId))
             if (!string.IsNullOrEmpty(profile.UserId))
             {
             {
-                var user = _userManager.GetUserById(profile.UserId);
+                var user = _userManager.GetUserById(Guid.Parse(profile.UserId));
 
 
                 if (user != null)
                 if (user != null)
                 {
                 {
@@ -116,7 +115,7 @@ namespace Emby.Dlna.ContentDirectory
 
 
             if (!string.IsNullOrEmpty(userId))
             if (!string.IsNullOrEmpty(userId))
             {
             {
-                var user = _userManager.GetUserById(userId);
+                var user = _userManager.GetUserById(Guid.Parse(userId));
 
 
                 if (user != null)
                 if (user != null)
                 {
                 {

+ 16 - 15
Emby.Dlna/ContentDirectory/ControlHandler.cs

@@ -425,10 +425,10 @@ namespace Emby.Dlna.ContentDirectory
         {
         {
             var folder = (Folder)item;
             var folder = (Folder)item;
 
 
-            var sortOrders = new List<string>();
+            var sortOrders = new List<(string, SortOrder)>();
             if (!folder.IsPreSorted)
             if (!folder.IsPreSorted)
             {
             {
-                sortOrders.Add(ItemSortBy.SortName);
+                sortOrders.Add((ItemSortBy.SortName, sort.SortOrder));
             }
             }
 
 
             var mediaTypes = new List<string>();
             var mediaTypes = new List<string>();
@@ -464,7 +464,7 @@ namespace Emby.Dlna.ContentDirectory
             {
             {
                 Limit = limit,
                 Limit = limit,
                 StartIndex = startIndex,
                 StartIndex = startIndex,
-                OrderBy = sortOrders.Select(i => new ValueTuple<string, SortOrder>(i, sort.SortOrder)).ToArray(),
+                OrderBy = sortOrders,
                 User = user,
                 User = user,
                 Recursive = true,
                 Recursive = true,
                 IsMissing = false,
                 IsMissing = false,
@@ -872,10 +872,10 @@ namespace Emby.Dlna.ContentDirectory
             query.Parent = parent;
             query.Parent = parent;
             query.SetUser(user);
             query.SetUser(user);
 
 
-            query.OrderBy = new ValueTuple<string, SortOrder>[]
+            query.OrderBy = new[]
             {
             {
-                new ValueTuple<string, SortOrder> (ItemSortBy.DatePlayed, SortOrder.Descending),
-                new ValueTuple<string, SortOrder> (ItemSortBy.SortName, SortOrder.Ascending)
+                (ItemSortBy.DatePlayed, SortOrder.Descending),
+                (ItemSortBy.SortName, SortOrder.Ascending)
             };
             };
 
 
             query.IsResumable = true;
             query.IsResumable = true;
@@ -1121,7 +1121,7 @@ namespace Emby.Dlna.ContentDirectory
 
 
         private QueryResult<ServerItem> GetMusicLatest(BaseItem parent, User user, InternalItemsQuery query)
         private QueryResult<ServerItem> GetMusicLatest(BaseItem parent, User user, InternalItemsQuery query)
         {
         {
-            query.OrderBy = new ValueTuple<string, SortOrder>[] { };
+            query.OrderBy = Array.Empty<(string, SortOrder)>();
 
 
             var items = _userViewManager.GetLatestItems(new LatestItemsQuery
             var items = _userViewManager.GetLatestItems(new LatestItemsQuery
             {
             {
@@ -1138,7 +1138,7 @@ namespace Emby.Dlna.ContentDirectory
 
 
         private QueryResult<ServerItem> GetNextUp(BaseItem parent, User user, InternalItemsQuery query)
         private QueryResult<ServerItem> GetNextUp(BaseItem parent, User user, InternalItemsQuery query)
         {
         {
-            query.OrderBy = new ValueTuple<string, SortOrder>[] { };
+            query.OrderBy = Array.Empty<(string, SortOrder)>();
 
 
             var result = _tvSeriesManager.GetNextUp(new NextUpQuery
             var result = _tvSeriesManager.GetNextUp(new NextUpQuery
             {
             {
@@ -1153,7 +1153,7 @@ namespace Emby.Dlna.ContentDirectory
 
 
         private QueryResult<ServerItem> GetTvLatest(BaseItem parent, User user, InternalItemsQuery query)
         private QueryResult<ServerItem> GetTvLatest(BaseItem parent, User user, InternalItemsQuery query)
         {
         {
-            query.OrderBy = new ValueTuple<string, SortOrder>[] { };
+            query.OrderBy = Array.Empty<(string, SortOrder)>();
 
 
             var items = _userViewManager.GetLatestItems(new LatestItemsQuery
             var items = _userViewManager.GetLatestItems(new LatestItemsQuery
             {
             {
@@ -1170,7 +1170,7 @@ namespace Emby.Dlna.ContentDirectory
 
 
         private QueryResult<ServerItem> GetMovieLatest(BaseItem parent, User user, InternalItemsQuery query)
         private QueryResult<ServerItem> GetMovieLatest(BaseItem parent, User user, InternalItemsQuery query)
         {
         {
-            query.OrderBy = new ValueTuple<string, SortOrder>[] { };
+            query.OrderBy = Array.Empty<(string, SortOrder)>();
 
 
             var items = _userViewManager.GetLatestItems(new LatestItemsQuery
             var items = _userViewManager.GetLatestItems(new LatestItemsQuery
             {
             {
@@ -1274,13 +1274,14 @@ namespace Emby.Dlna.ContentDirectory
 
 
         private void SetSorting(InternalItemsQuery query, SortCriteria sort, bool isPreSorted)
         private void SetSorting(InternalItemsQuery query, SortCriteria sort, bool isPreSorted)
         {
         {
-            var sortOrders = new List<string>();
-            if (!isPreSorted)
+            if (isPreSorted)
             {
             {
-                sortOrders.Add(ItemSortBy.SortName);
+                query.OrderBy = Array.Empty<(string, SortOrder)>();
+            }
+            else
+            {
+                query.OrderBy = new[] { (ItemSortBy.SortName, sort.SortOrder) };
             }
             }
-
-            query.OrderBy = sortOrders.Select(i => new ValueTuple<string, SortOrder>(i, sort.SortOrder)).ToArray();
         }
         }
 
 
         private QueryResult<ServerItem> ApplyPaging(QueryResult<ServerItem> result, int? startIndex, int? limit)
         private QueryResult<ServerItem> ApplyPaging(QueryResult<ServerItem> result, int? startIndex, int? limit)

+ 12 - 24
Emby.Dlna/Eventing/EventManager.cs

@@ -29,25 +29,15 @@ namespace Emby.Dlna.Eventing
         {
         {
             var subscription = GetSubscription(subscriptionId, false);
             var subscription = GetSubscription(subscriptionId, false);
 
 
-            int timeoutSeconds;
+            subscription.TimeoutSeconds = ParseTimeout(requestedTimeoutString) ?? 300;
+            int timeoutSeconds = subscription.TimeoutSeconds;
+            subscription.SubscriptionTime = DateTime.UtcNow;
 
 
-            // Remove logging for now because some devices are sending this very frequently
-            // TODO re-enable with dlna debug logging setting
-            //_logger.LogDebug("Renewing event subscription for {0} with timeout of {1} to {2}",
-            //    subscription.NotificationType,
-            //    timeout,
-            //    subscription.CallbackUrl);
-
-            if (subscription != null)
-            {
-                subscription.TimeoutSeconds = ParseTimeout(requestedTimeoutString) ?? 300;
-                timeoutSeconds = subscription.TimeoutSeconds;
-                subscription.SubscriptionTime = DateTime.UtcNow;
-            }
-            else
-            {
-                timeoutSeconds = 300;
-            }
+            _logger.LogDebug(
+                "Renewing event subscription for {0} with timeout of {1} to {2}",
+                subscription.NotificationType,
+                timeoutSeconds,
+                subscription.CallbackUrl);
 
 
             return GetEventSubscriptionResponse(subscriptionId, requestedTimeoutString, timeoutSeconds);
             return GetEventSubscriptionResponse(subscriptionId, requestedTimeoutString, timeoutSeconds);
         }
         }
@@ -57,12 +47,10 @@ namespace Emby.Dlna.Eventing
             var timeout = ParseTimeout(requestedTimeoutString) ?? 300;
             var timeout = ParseTimeout(requestedTimeoutString) ?? 300;
             var id = "uuid:" + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
             var id = "uuid:" + Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
 
 
-            // Remove logging for now because some devices are sending this very frequently
-            // TODO re-enable with dlna debug logging setting
-            //_logger.LogDebug("Creating event subscription for {0} with timeout of {1} to {2}",
-            //    notificationType,
-            //    timeout,
-            //    callbackUrl);
+            _logger.LogDebug("Creating event subscription for {0} with timeout of {1} to {2}",
+                notificationType,
+                timeout,
+                callbackUrl);
 
 
             _subscriptions.TryAdd(id, new EventSubscription
             _subscriptions.TryAdd(id, new EventSubscription
             {
             {

+ 1 - 1
Emby.Dlna/PlayTo/PlayToManager.cs

@@ -160,7 +160,7 @@ namespace Emby.Dlna.PlayTo
                 uuid = location.GetMD5().ToString("N", CultureInfo.InvariantCulture);
                 uuid = location.GetMD5().ToString("N", CultureInfo.InvariantCulture);
             }
             }
 
 
-            var sessionInfo = _sessionManager.LogSessionActivity("DLNA", _appHost.ApplicationVersion, uuid, null, uri.OriginalString, null);
+            var sessionInfo = _sessionManager.LogSessionActivity("DLNA", _appHost.ApplicationVersionString, uuid, null, uri.OriginalString, null);
 
 
             var controller = sessionInfo.SessionControllers.OfType<PlayToController>().FirstOrDefault();
             var controller = sessionInfo.SessionControllers.OfType<PlayToController>().FirstOrDefault();
 
 

+ 9 - 14
Emby.Dlna/Ssdp/DeviceDiscovery.cs

@@ -4,8 +4,6 @@ using System.Linq;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Events;
 using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Net;
-using Microsoft.Extensions.Logging;
 using Rssdp;
 using Rssdp;
 using Rssdp.Infrastructure;
 using Rssdp.Infrastructure;
 
 
@@ -15,13 +13,14 @@ namespace Emby.Dlna.Ssdp
     {
     {
         private bool _disposed;
         private bool _disposed;
 
 
-        private readonly ILogger _logger;
         private readonly IServerConfigurationManager _config;
         private readonly IServerConfigurationManager _config;
 
 
         private event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscoveredInternal;
         private event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscoveredInternal;
 
 
         private int _listenerCount;
         private int _listenerCount;
         private object _syncLock = new object();
         private object _syncLock = new object();
+
+        /// <inheritdoc />
         public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscovered
         public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscovered
         {
         {
             add
             add
@@ -31,6 +30,7 @@ namespace Emby.Dlna.Ssdp
                     _listenerCount++;
                     _listenerCount++;
                     DeviceDiscoveredInternal += value;
                     DeviceDiscoveredInternal += value;
                 }
                 }
+
                 StartInternal();
                 StartInternal();
             }
             }
             remove
             remove
@@ -43,21 +43,16 @@ namespace Emby.Dlna.Ssdp
             }
             }
         }
         }
 
 
+        /// <inheritdoc />
         public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceLeft;
         public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceLeft;
 
 
         private SsdpDeviceLocator _deviceLocator;
         private SsdpDeviceLocator _deviceLocator;
 
 
-        private readonly ISocketFactory _socketFactory;
         private ISsdpCommunicationsServer _commsServer;
         private ISsdpCommunicationsServer _commsServer;
 
 
-        public DeviceDiscovery(
-            ILoggerFactory loggerFactory,
-            IServerConfigurationManager config,
-            ISocketFactory socketFactory)
+        public DeviceDiscovery(IServerConfigurationManager config)
         {
         {
-            _logger = loggerFactory.CreateLogger(nameof(DeviceDiscovery));
             _config = config;
             _config = config;
-            _socketFactory = socketFactory;
         }
         }
 
 
         // Call this method from somewhere in your code to start the search.
         // Call this method from somewhere in your code to start the search.
@@ -82,8 +77,8 @@ namespace Emby.Dlna.Ssdp
                     //_DeviceLocator.NotificationFilter = "upnp:rootdevice";
                     //_DeviceLocator.NotificationFilter = "upnp:rootdevice";
 
 
                     // Connect our event handler so we process devices as they are found
                     // Connect our event handler so we process devices as they are found
-                    _deviceLocator.DeviceAvailable += deviceLocator_DeviceAvailable;
-                    _deviceLocator.DeviceUnavailable += _DeviceLocator_DeviceUnavailable;
+                    _deviceLocator.DeviceAvailable += OnDeviceLocatorDeviceAvailable;
+                    _deviceLocator.DeviceUnavailable += OnDeviceLocatorDeviceUnavailable;
 
 
                     var dueTime = TimeSpan.FromSeconds(5);
                     var dueTime = TimeSpan.FromSeconds(5);
                     var interval = TimeSpan.FromSeconds(_config.GetDlnaConfiguration().ClientDiscoveryIntervalSeconds);
                     var interval = TimeSpan.FromSeconds(_config.GetDlnaConfiguration().ClientDiscoveryIntervalSeconds);
@@ -94,7 +89,7 @@ namespace Emby.Dlna.Ssdp
         }
         }
 
 
         // Process each found device in the event handler
         // Process each found device in the event handler
-        void deviceLocator_DeviceAvailable(object sender, DeviceAvailableEventArgs e)
+        private void OnDeviceLocatorDeviceAvailable(object sender, DeviceAvailableEventArgs e)
         {
         {
             var originalHeaders = e.DiscoveredDevice.ResponseHeaders;
             var originalHeaders = e.DiscoveredDevice.ResponseHeaders;
 
 
@@ -115,7 +110,7 @@ namespace Emby.Dlna.Ssdp
             DeviceDiscoveredInternal?.Invoke(this, args);
             DeviceDiscoveredInternal?.Invoke(this, args);
         }
         }
 
 
-        private void _DeviceLocator_DeviceUnavailable(object sender, DeviceUnavailableEventArgs e)
+        private void OnDeviceLocatorDeviceUnavailable(object sender, DeviceUnavailableEventArgs e)
         {
         {
             var originalHeaders = e.DiscoveredDevice.ResponseHeaders;
             var originalHeaders = e.DiscoveredDevice.ResponseHeaders;
 
 

+ 3 - 0
Emby.Naming/Audio/AlbumParser.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.Globalization;
 using System.Globalization;
 using System.IO;
 using System.IO;

+ 3 - 0
Emby.Naming/Audio/AudioFileParser.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;

+ 3 - 0
Emby.Naming/Audio/MultiPartResult.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.Audio
 namespace Emby.Naming.Audio
 {
 {
     public class MultiPartResult
     public class MultiPartResult

+ 1 - 1
Emby.Naming/AudioBook/AudioBookFileInfo.cs

@@ -3,7 +3,7 @@ using System;
 namespace Emby.Naming.AudioBook
 namespace Emby.Naming.AudioBook
 {
 {
     /// <summary>
     /// <summary>
-    /// Represents a single video file
+    /// Represents a single video file.
     /// </summary>
     /// </summary>
     public class AudioBookFileInfo : IComparable<AudioBookFileInfo>
     public class AudioBookFileInfo : IComparable<AudioBookFileInfo>
     {
     {

+ 3 - 0
Emby.Naming/AudioBook/AudioBookFilePathParser.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.Globalization;
 using System.Globalization;
 using System.IO;
 using System.IO;

+ 3 - 0
Emby.Naming/AudioBook/AudioBookFilePathParserResult.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.AudioBook
 namespace Emby.Naming.AudioBook
 {
 {
     public class AudioBookFilePathParserResult
     public class AudioBookFilePathParserResult

+ 4 - 1
Emby.Naming/AudioBook/AudioBookInfo.cs

@@ -3,10 +3,13 @@ using System.Collections.Generic;
 namespace Emby.Naming.AudioBook
 namespace Emby.Naming.AudioBook
 {
 {
     /// <summary>
     /// <summary>
-    /// Represents a complete video, including all parts and subtitles
+    /// Represents a complete video, including all parts and subtitles.
     /// </summary>
     /// </summary>
     public class AudioBookInfo
     public class AudioBookInfo
     {
     {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="AudioBookInfo" /> class.
+        /// </summary>
         public AudioBookInfo()
         public AudioBookInfo()
         {
         {
             Files = new List<AudioBookFileInfo>();
             Files = new List<AudioBookFileInfo>();

+ 3 - 0
Emby.Naming/AudioBook/AudioBookListResolver.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using Emby.Naming.Common;
 using Emby.Naming.Common;

+ 3 - 0
Emby.Naming/AudioBook/AudioBookResolver.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;

+ 3 - 0
Emby.Naming/Common/EpisodeExpression.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
 
 

+ 3 - 0
Emby.Naming/Common/MediaType.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.Common
 namespace Emby.Naming.Common
 {
 {
     public enum MediaType
     public enum MediaType

+ 24 - 8
Emby.Naming/Common/NamingOptions.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.Linq;
 using System.Linq;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
@@ -311,6 +314,14 @@ namespace Emby.Naming.Common
                     }
                     }
                 },
                 },
 
 
+                // This isn't a Kodi naming rule, but the expression below causes false positives,
+                // so we make sure this one gets tested first.
+                // "Foo Bar 889"
+                new EpisodeExpression(@".*[\\\/](?![Ee]pisode)(?<seriesname>[\w\s]+?)\s(?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*[^\\\/]*$")
+                {
+                    IsNamed = true
+                },
+
                 new EpisodeExpression("[\\\\/\\._ \\[\\(-]([0-9]+)x([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)([^\\\\/]*)$")
                 new EpisodeExpression("[\\\\/\\._ \\[\\(-]([0-9]+)x([0-9]+(?:(?:[a-i]|\\.[1-9])(?![0-9]))?)([^\\\\/]*)$")
                 {
                 {
                     SupportsAbsoluteEpisodeNumbers = true
                     SupportsAbsoluteEpisodeNumbers = true
@@ -328,28 +339,33 @@ namespace Emby.Naming.Common
 
 
                 // *** End Kodi Standard Naming
                 // *** End Kodi Standard Naming
 
 
-                new EpisodeExpression(@".*(\\|\/)[sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3})[^\\\/]*$")
+                // [bar] Foo - 1 [baz]
+                new EpisodeExpression(@".*?(\[.*?\])+.*?(?<seriesname>[\w\s]+?)[-\s_]+(?<epnumber>\d+).*$")
+                {
+                    IsNamed = true
+                },
+                new EpisodeExpression(@".*(\\|\/)[sS]?(?<seasonnumber>\d+)[xX](?<epnumber>\d+)[^\\\/]*$")
                 {
                 {
                     IsNamed = true
                     IsNamed = true
                 },
                 },
 
 
-                new EpisodeExpression(@".*(\\|\/)[sS](?<seasonnumber>\d{1,4})[x,X]?[eE](?<epnumber>\d{1,3})[^\\\/]*$")
+                new EpisodeExpression(@".*(\\|\/)[sS](?<seasonnumber>\d+)[x,X]?[eE](?<epnumber>\d+)[^\\\/]*$")
                 {
                 {
                     IsNamed = true
                     IsNamed = true
                 },
                 },
 
 
-                new EpisodeExpression(@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d{1,3}))[^\\\/]*$")
+                new EpisodeExpression(@".*(\\|\/)(?<seriesname>((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?<seasonnumber>\d{1,4})[xX](?<epnumber>\d+))[^\\\/]*$")
                 {
                 {
                     IsNamed = true
                     IsNamed = true
                 },
                 },
 
 
-                new EpisodeExpression(@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})[^\\\/]*$")
+                new EpisodeExpression(@".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d+)[^\\\/]*$")
                 {
                 {
                     IsNamed = true
                     IsNamed = true
                 },
                 },
 
 
                 // "01.avi"
                 // "01.avi"
-                new EpisodeExpression(@".*[\\\/](?<epnumber>\d{1,3})(-(?<endingepnumber>\d{2,3}))*\.\w+$")
+                new EpisodeExpression(@".*[\\\/](?<epnumber>\d+)(-(?<endingepnumber>\d+))*\.\w+$")
                 {
                 {
                     IsOptimistic = true,
                     IsOptimistic = true,
                     IsNamed = true
                     IsNamed = true
@@ -654,9 +670,9 @@ namespace Emby.Naming.Common
                 @".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})((-| - )?[xXeE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
                 @".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})((-| - )?[xXeE](?<endingepnumber>\d{1,3}))+[^\\\/]*$",
                 @".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})(-[xX]?[eE]?(?<endingepnumber>\d{1,3}))+[^\\\/]*$"
                 @".*(\\|\/)(?<seriesname>[^\\\/]*)[sS](?<seasonnumber>\d{1,4})[xX\.]?[eE](?<epnumber>\d{1,3})(-[xX]?[eE]?(?<endingepnumber>\d{1,3}))+[^\\\/]*$"
             }.Select(i => new EpisodeExpression(i)
             }.Select(i => new EpisodeExpression(i)
-                {
-                    IsNamed = true
-                }).ToArray();
+            {
+                IsNamed = true
+            }).ToArray();
 
 
             VideoFileExtensions = extensions
             VideoFileExtensions = extensions
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Distinct(StringComparer.OrdinalIgnoreCase)

+ 10 - 6
Emby.Naming/Emby.Naming.csproj

@@ -3,6 +3,11 @@
   <PropertyGroup>
   <PropertyGroup>
     <TargetFramework>netstandard2.1</TargetFramework>
     <TargetFramework>netstandard2.1</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+    <GenerateDocumentationFile>true</GenerateDocumentationFile>
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>
@@ -18,15 +23,14 @@
     <PackageId>Jellyfin.Naming</PackageId>
     <PackageId>Jellyfin.Naming</PackageId>
     <PackageLicenseUrl>https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt</PackageLicenseUrl>
     <PackageLicenseUrl>https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt</PackageLicenseUrl>
     <RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
     <RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
-    <GenerateDocumentationFile>true</GenerateDocumentationFile>
   </PropertyGroup>
   </PropertyGroup>
 
 
-  <!-- Code analysers-->
+  <!-- Code Analyzers-->
   <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
   <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
-    <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.4" />
-    <PackageReference Include="SerilogAnalyzer" Version="0.15.0" />
-    <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
-    <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" />
+    <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.7" PrivateAssets="All" />
+    <PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
+    <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
+    <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
   </ItemGroup>
   </ItemGroup>
 
 
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

+ 3 - 0
Emby.Naming/Subtitles/SubtitleInfo.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.Subtitles
 namespace Emby.Naming.Subtitles
 {
 {
     public class SubtitleInfo
     public class SubtitleInfo

+ 3 - 0
Emby.Naming/Subtitles/SubtitleParser.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;

+ 3 - 0
Emby.Naming/TV/EpisodeInfo.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.TV
 namespace Emby.Naming.TV
 {
 {
     public class EpisodeInfo
     public class EpisodeInfo

+ 3 - 0
Emby.Naming/TV/EpisodePathParser.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Globalization;

+ 3 - 0
Emby.Naming/TV/EpisodePathParserResult.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.TV
 namespace Emby.Naming.TV
 {
 {
     public class EpisodePathParserResult
     public class EpisodePathParserResult

+ 3 - 0
Emby.Naming/TV/EpisodeResolver.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;

+ 5 - 2
Emby.Naming/TV/SeasonPathParser.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.Globalization;
 using System.Globalization;
 using System.IO;
 using System.IO;
@@ -25,7 +28,7 @@ namespace Emby.Naming.TV
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// A season folder must contain one of these somewhere in the name
+        /// A season folder must contain one of these somewhere in the name.
         /// </summary>
         /// </summary>
         private static readonly string[] _seasonFolderNames =
         private static readonly string[] _seasonFolderNames =
         {
         {
@@ -124,7 +127,7 @@ namespace Emby.Naming.TV
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// Extracts the season number from the second half of the Season folder name (everything after "Season", or "Staffel")
+        /// Extracts the season number from the second half of the Season folder name (everything after "Season", or "Staffel").
         /// </summary>
         /// </summary>
         /// <param name="path">The path.</param>
         /// <param name="path">The path.</param>
         /// <returns>System.Nullable{System.Int32}.</returns>
         /// <returns>System.Nullable{System.Int32}.</returns>

+ 3 - 0
Emby.Naming/TV/SeasonPathParserResult.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.TV
 namespace Emby.Naming.TV
 {
 {
     public class SeasonPathParserResult
     public class SeasonPathParserResult

+ 4 - 1
Emby.Naming/Video/CleanDateTimeParser.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.Globalization;
 using System.Globalization;
 using System.IO;
 using System.IO;
@@ -8,7 +11,7 @@ using Emby.Naming.Common;
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video
 {
 {
     /// <summary>
     /// <summary>
-    /// http://kodi.wiki/view/Advancedsettings.xml#video
+    /// <see href="http://kodi.wiki/view/Advancedsettings.xml#video" />.
     /// </summary>
     /// </summary>
     public class CleanDateTimeParser
     public class CleanDateTimeParser
     {
     {

+ 5 - 0
Emby.Naming/Video/CleanDateTimeResult.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video
 {
 {
     public class CleanDateTimeResult
     public class CleanDateTimeResult
@@ -7,11 +10,13 @@ namespace Emby.Naming.Video
         /// </summary>
         /// </summary>
         /// <value>The name.</value>
         /// <value>The name.</value>
         public string Name { get; set; }
         public string Name { get; set; }
+
         /// <summary>
         /// <summary>
         /// Gets or sets the year.
         /// Gets or sets the year.
         /// </summary>
         /// </summary>
         /// <value>The year.</value>
         /// <value>The year.</value>
         public int? Year { get; set; }
         public int? Year { get; set; }
+
         /// <summary>
         /// <summary>
         /// Gets or sets a value indicating whether this instance has changed.
         /// Gets or sets a value indicating whether this instance has changed.
         /// </summary>
         /// </summary>

+ 3 - 0
Emby.Naming/Video/CleanStringParser.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
 
 

+ 4 - 0
Emby.Naming/Video/CleanStringResult.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video
 {
 {
     public class CleanStringResult
     public class CleanStringResult
@@ -7,6 +10,7 @@ namespace Emby.Naming.Video
         /// </summary>
         /// </summary>
         /// <value>The name.</value>
         /// <value>The name.</value>
         public string Name { get; set; }
         public string Name { get; set; }
+
         /// <summary>
         /// <summary>
         /// Gets or sets a value indicating whether this instance has changed.
         /// Gets or sets a value indicating whether this instance has changed.
         /// </summary>
         /// </summary>

+ 3 - 0
Emby.Naming/Video/ExtraResolver.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;

+ 4 - 0
Emby.Naming/Video/ExtraResult.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video
 {
 {
     public class ExtraResult
     public class ExtraResult
@@ -7,6 +10,7 @@ namespace Emby.Naming.Video
         /// </summary>
         /// </summary>
         /// <value>The type of the extra.</value>
         /// <value>The type of the extra.</value>
         public string ExtraType { get; set; }
         public string ExtraType { get; set; }
+
         /// <summary>
         /// <summary>
         /// Gets or sets the rule.
         /// Gets or sets the rule.
         /// </summary>
         /// </summary>

+ 6 - 0
Emby.Naming/Video/ExtraRule.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using Emby.Naming.Common;
 using Emby.Naming.Common;
 
 
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video
@@ -9,16 +12,19 @@ namespace Emby.Naming.Video
         /// </summary>
         /// </summary>
         /// <value>The token.</value>
         /// <value>The token.</value>
         public string Token { get; set; }
         public string Token { get; set; }
+
         /// <summary>
         /// <summary>
         /// Gets or sets the type of the extra.
         /// Gets or sets the type of the extra.
         /// </summary>
         /// </summary>
         /// <value>The type of the extra.</value>
         /// <value>The type of the extra.</value>
         public string ExtraType { get; set; }
         public string ExtraType { get; set; }
+
         /// <summary>
         /// <summary>
         /// Gets or sets the type of the rule.
         /// Gets or sets the type of the rule.
         /// </summary>
         /// </summary>
         /// <value>The type of the rule.</value>
         /// <value>The type of the rule.</value>
         public ExtraRuleType RuleType { get; set; }
         public ExtraRuleType RuleType { get; set; }
+
         /// <summary>
         /// <summary>
         /// Gets or sets the type of the media.
         /// Gets or sets the type of the media.
         /// </summary>
         /// </summary>

+ 5 - 0
Emby.Naming/Video/ExtraRuleType.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video
 {
 {
     public enum ExtraRuleType
     public enum ExtraRuleType
@@ -6,10 +9,12 @@ namespace Emby.Naming.Video
         /// The suffix
         /// The suffix
         /// </summary>
         /// </summary>
         Suffix = 0,
         Suffix = 0,
+
         /// <summary>
         /// <summary>
         /// The filename
         /// The filename
         /// </summary>
         /// </summary>
         Filename = 1,
         Filename = 1,
+
         /// <summary>
         /// <summary>
         /// The regex
         /// The regex
         /// </summary>
         /// </summary>

+ 9 - 4
Emby.Naming/Video/FileStack.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
@@ -6,15 +9,17 @@ namespace Emby.Naming.Video
 {
 {
     public class FileStack
     public class FileStack
     {
     {
-        public string Name { get; set; }
-        public List<string> Files { get; set; }
-        public bool IsDirectoryStack { get; set; }
-
         public FileStack()
         public FileStack()
         {
         {
             Files = new List<string>();
             Files = new List<string>();
         }
         }
 
 
+        public string Name { get; set; }
+
+        public List<string> Files { get; set; }
+
+        public bool IsDirectoryStack { get; set; }
+
         public bool ContainsFile(string file, bool isDirectory)
         public bool ContainsFile(string file, bool isDirectory)
         {
         {
             if (IsDirectoryStack == isDirectory)
             if (IsDirectoryStack == isDirectory)

+ 3 - 0
Emby.Naming/Video/FlagParser.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.IO;
 using System.IO;
 using Emby.Naming.Common;
 using Emby.Naming.Common;

+ 3 - 0
Emby.Naming/Video/Format3DParser.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.Linq;
 using System.Linq;
 using Emby.Naming.Common;
 using Emby.Naming.Common;

+ 3 - 0
Emby.Naming/Video/Format3DResult.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System.Collections.Generic;
 using System.Collections.Generic;
 
 
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video

+ 4 - 0
Emby.Naming/Video/Format3DRule.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video
 {
 {
     public class Format3DRule
     public class Format3DRule
@@ -7,6 +10,7 @@ namespace Emby.Naming.Video
         /// </summary>
         /// </summary>
         /// <value>The token.</value>
         /// <value>The token.</value>
         public string Token { get; set; }
         public string Token { get; set; }
+
         /// <summary>
         /// <summary>
         /// Gets or sets the preceeding token.
         /// Gets or sets the preceeding token.
         /// </summary>
         /// </summary>

+ 3 - 0
Emby.Naming/Video/StackResolver.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.IO;
 using System.IO;

+ 3 - 0
Emby.Naming/Video/StackResult.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System.Collections.Generic;
 using System.Collections.Generic;
 
 
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video

+ 3 - 0
Emby.Naming/Video/StubResolver.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;

+ 3 - 0
Emby.Naming/Video/StubResult.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video
 {
 {
     public struct StubResult
     public struct StubResult

+ 3 - 0
Emby.Naming/Video/StubTypeRule.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video
 {
 {
     public class StubTypeRule
     public class StubTypeRule

+ 2 - 1
Emby.Naming/Video/VideoFileInfo.cs

@@ -1,7 +1,7 @@
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video
 {
 {
     /// <summary>
     /// <summary>
-    /// Represents a single video file
+    /// Represents a single video file.
     /// </summary>
     /// </summary>
     public class VideoFileInfo
     public class VideoFileInfo
     {
     {
@@ -77,6 +77,7 @@ namespace Emby.Naming.Video
         /// <value>The file name without extension.</value>
         /// <value>The file name without extension.</value>
         public string FileNameWithoutExtension => !IsDirectory ? System.IO.Path.GetFileNameWithoutExtension(Path) : System.IO.Path.GetFileName(Path);
         public string FileNameWithoutExtension => !IsDirectory ? System.IO.Path.GetFileNameWithoutExtension(Path) : System.IO.Path.GetFileName(Path);
 
 
+        /// <inheritdoc />
         public override string ToString()
         public override string ToString()
         {
         {
             // Makes debugging easier
             // Makes debugging easier

+ 11 - 8
Emby.Naming/Video/VideoInfo.cs

@@ -3,10 +3,20 @@ using System.Collections.Generic;
 namespace Emby.Naming.Video
 namespace Emby.Naming.Video
 {
 {
     /// <summary>
     /// <summary>
-    /// Represents a complete video, including all parts and subtitles
+    /// Represents a complete video, including all parts and subtitles.
     /// </summary>
     /// </summary>
     public class VideoInfo
     public class VideoInfo
     {
     {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="VideoInfo" /> class.
+        /// </summary>
+        public VideoInfo()
+        {
+            Files = new List<VideoFileInfo>();
+            Extras = new List<VideoFileInfo>();
+            AlternateVersions = new List<VideoFileInfo>();
+        }
+
         /// <summary>
         /// <summary>
         /// Gets or sets the name.
         /// Gets or sets the name.
         /// </summary>
         /// </summary>
@@ -36,12 +46,5 @@ namespace Emby.Naming.Video
         /// </summary>
         /// </summary>
         /// <value>The alternate versions.</value>
         /// <value>The alternate versions.</value>
         public List<VideoFileInfo> AlternateVersions { get; set; }
         public List<VideoFileInfo> AlternateVersions { get; set; }
-
-        public VideoInfo()
-        {
-            Files = new List<VideoFileInfo>();
-            Extras = new List<VideoFileInfo>();
-            AlternateVersions = new List<VideoFileInfo>();
-        }
     }
     }
 }
 }

+ 3 - 0
Emby.Naming/Video/VideoListResolver.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.IO;
 using System.IO;

+ 4 - 1
Emby.Naming/Video/VideoResolver.cs

@@ -1,3 +1,6 @@
+#pragma warning disable CS1591
+#pragma warning disable SA1600
+
 using System;
 using System;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
@@ -41,7 +44,7 @@ namespace Emby.Naming.Video
         /// <param name="isDirectory">if set to <c>true</c> [is folder].</param>
         /// <param name="isDirectory">if set to <c>true</c> [is folder].</param>
         /// <param name="parseName">Whether or not the name should be parsed for info</param>
         /// <param name="parseName">Whether or not the name should be parsed for info</param>
         /// <returns>VideoFileInfo.</returns>
         /// <returns>VideoFileInfo.</returns>
-        /// <exception cref="ArgumentNullException">path</exception>
+        /// <exception cref="ArgumentNullException"><c>path</c> is <c>null</c>.</exception>
         public VideoFileInfo Resolve(string path, bool isDirectory, bool parseName = true)
         public VideoFileInfo Resolve(string path, bool isDirectory, bool parseName = true)
         {
         {
             if (string.IsNullOrEmpty(path))
             if (string.IsNullOrEmpty(path))

+ 6 - 2
Emby.Photos/Emby.Photos.csproj

@@ -1,5 +1,9 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
 
 
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+  </PropertyGroup>
+
   <ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
     <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
     <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
     <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
@@ -20,9 +24,9 @@
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
   </PropertyGroup>
   </PropertyGroup>
 
 
-  <!-- Code analysers-->
+  <!-- Code Analyzers-->
   <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
   <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
-    <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.4" />
+    <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.7" />
     <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
     <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
     <PackageReference Include="SerilogAnalyzer" Version="0.15.0" />
     <PackageReference Include="SerilogAnalyzer" Version="0.15.0" />
   </ItemGroup>
   </ItemGroup>

+ 17 - 2
Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Globalization;
@@ -39,6 +41,19 @@ namespace Emby.Server.Implementations.Activity
         private readonly IServerApplicationHost _appHost;
         private readonly IServerApplicationHost _appHost;
         private readonly IDeviceManager _deviceManager;
         private readonly IDeviceManager _deviceManager;
 
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ActivityLogEntryPoint"/> class.
+        /// </summary>
+        /// <param name="logger"></param>
+        /// <param name="sessionManager"></param>
+        /// <param name="deviceManager"></param>
+        /// <param name="taskManager"></param>
+        /// <param name="activityManager"></param>
+        /// <param name="localization"></param>
+        /// <param name="installationManager"></param>
+        /// <param name="subManager"></param>
+        /// <param name="userManager"></param>
+        /// <param name="appHost"></param>
         public ActivityLogEntryPoint(
         public ActivityLogEntryPoint(
             ILogger<ActivityLogEntryPoint> logger,
             ILogger<ActivityLogEntryPoint> logger,
             ISessionManager sessionManager,
             ISessionManager sessionManager,
@@ -616,8 +631,8 @@ namespace Emby.Server.Implementations.Activity
         /// <summary>
         /// <summary>
         /// Constructs a string description of a time-span value.
         /// Constructs a string description of a time-span value.
         /// </summary>
         /// </summary>
-        /// <param name="value">The value of this item</param>
-        /// <param name="description">The name of this item (singular form)</param>
+        /// <param name="value">The value of this item.</param>
+        /// <param name="description">The name of this item (singular form).</param>
         private static string CreateValueString(int value, string description)
         private static string CreateValueString(int value, string description)
         {
         {
             return string.Format(
             return string.Format(

+ 2 - 0
Emby.Server.Implementations/Activity/ActivityManager.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 using System;
 using System.Linq;
 using System.Linq;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;

+ 2 - 0
Emby.Server.Implementations/Activity/ActivityRepository.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Globalization;

+ 27 - 11
Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs

@@ -4,7 +4,6 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.Globalization;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
-using System.Threading;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Events;
 using MediaBrowser.Common.Events;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
@@ -16,7 +15,7 @@ using Microsoft.Extensions.Logging;
 namespace Emby.Server.Implementations.AppBase
 namespace Emby.Server.Implementations.AppBase
 {
 {
     /// <summary>
     /// <summary>
-    /// Class BaseConfigurationManager
+    /// Class BaseConfigurationManager.
     /// </summary>
     /// </summary>
     public abstract class BaseConfigurationManager : IConfigurationManager
     public abstract class BaseConfigurationManager : IConfigurationManager
     {
     {
@@ -48,7 +47,7 @@ namespace Emby.Server.Implementations.AppBase
         /// <param name="applicationPaths">The application paths.</param>
         /// <param name="applicationPaths">The application paths.</param>
         /// <param name="loggerFactory">The logger factory.</param>
         /// <param name="loggerFactory">The logger factory.</param>
         /// <param name="xmlSerializer">The XML serializer.</param>
         /// <param name="xmlSerializer">The XML serializer.</param>
-        /// <param name="fileSystem">The file system</param>
+        /// <param name="fileSystem">The file system.</param>
         protected BaseConfigurationManager(IApplicationPaths applicationPaths, ILoggerFactory loggerFactory, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
         protected BaseConfigurationManager(IApplicationPaths applicationPaths, ILoggerFactory loggerFactory, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
         {
         {
             CommonApplicationPaths = applicationPaths;
             CommonApplicationPaths = applicationPaths;
@@ -85,6 +84,7 @@ namespace Emby.Server.Implementations.AppBase
         /// </summary>
         /// </summary>
         /// <value>The logger.</value>
         /// <value>The logger.</value>
         protected ILogger Logger { get; private set; }
         protected ILogger Logger { get; private set; }
+
         /// <summary>
         /// <summary>
         /// Gets the XML serializer.
         /// Gets the XML serializer.
         /// </summary>
         /// </summary>
@@ -92,13 +92,13 @@ namespace Emby.Server.Implementations.AppBase
         protected IXmlSerializer XmlSerializer { get; private set; }
         protected IXmlSerializer XmlSerializer { get; private set; }
 
 
         /// <summary>
         /// <summary>
-        /// Gets or sets the application paths.
+        /// Gets the application paths.
         /// </summary>
         /// </summary>
         /// <value>The application paths.</value>
         /// <value>The application paths.</value>
         public IApplicationPaths CommonApplicationPaths { get; private set; }
         public IApplicationPaths CommonApplicationPaths { get; private set; }
 
 
         /// <summary>
         /// <summary>
-        /// Gets the system configuration.
+        /// Gets or sets the system configuration.
         /// </summary>
         /// </summary>
         /// <value>The configuration.</value>
         /// <value>The configuration.</value>
         public BaseApplicationConfiguration CommonConfiguration
         public BaseApplicationConfiguration CommonConfiguration
@@ -124,6 +124,7 @@ namespace Emby.Server.Implementations.AppBase
                     return _configuration;
                     return _configuration;
                 }
                 }
             }
             }
+
             protected set
             protected set
             {
             {
                 _configuration = value;
                 _configuration = value;
@@ -132,6 +133,10 @@ namespace Emby.Server.Implementations.AppBase
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// Adds parts.
+        /// </summary>
+        /// <param name="factories">The configuration factories.</param>
         public virtual void AddParts(IEnumerable<IConfigurationFactory> factories)
         public virtual void AddParts(IEnumerable<IConfigurationFactory> factories)
         {
         {
             _configurationFactories = factories.ToArray();
             _configurationFactories = factories.ToArray();
@@ -173,7 +178,7 @@ namespace Emby.Server.Implementations.AppBase
         /// Replaces the configuration.
         /// Replaces the configuration.
         /// </summary>
         /// </summary>
         /// <param name="newConfiguration">The new configuration.</param>
         /// <param name="newConfiguration">The new configuration.</param>
-        /// <exception cref="ArgumentNullException">newConfiguration</exception>
+        /// <exception cref="ArgumentNullException"><c>newConfiguration</c> is <c>null</c>.</exception>
         public virtual void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration)
         public virtual void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration)
         {
         {
             if (newConfiguration == null)
             if (newConfiguration == null)
@@ -216,7 +221,7 @@ namespace Emby.Server.Implementations.AppBase
                 cachePath = CommonConfiguration.CachePath;
                 cachePath = CommonConfiguration.CachePath;
             }
             }
 
 
-            Logger.LogInformation("Setting cache path to " + cachePath);
+            Logger.LogInformation("Setting cache path: {Path}", cachePath);
             ((BaseApplicationPaths)CommonApplicationPaths).CachePath = cachePath;
             ((BaseApplicationPaths)CommonApplicationPaths).CachePath = cachePath;
         }
         }
 
 
@@ -224,7 +229,7 @@ namespace Emby.Server.Implementations.AppBase
         /// Replaces the cache path.
         /// Replaces the cache path.
         /// </summary>
         /// </summary>
         /// <param name="newConfig">The new configuration.</param>
         /// <param name="newConfig">The new configuration.</param>
-        /// <exception cref="DirectoryNotFoundException"></exception>
+        /// <exception cref="DirectoryNotFoundException">The new cache path doesn't exist.</exception>
         private void ValidateCachePath(BaseApplicationConfiguration newConfig)
         private void ValidateCachePath(BaseApplicationConfiguration newConfig)
         {
         {
             var newPath = newConfig.CachePath;
             var newPath = newConfig.CachePath;
@@ -235,7 +240,7 @@ namespace Emby.Server.Implementations.AppBase
                 // Validate
                 // Validate
                 if (!Directory.Exists(newPath))
                 if (!Directory.Exists(newPath))
                 {
                 {
-                    throw new FileNotFoundException(
+                    throw new DirectoryNotFoundException(
                         string.Format(
                         string.Format(
                             CultureInfo.InvariantCulture,
                             CultureInfo.InvariantCulture,
                             "{0} does not exist.",
                             "{0} does not exist.",
@@ -246,6 +251,10 @@ namespace Emby.Server.Implementations.AppBase
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// Ensures that we have write access to the path.
+        /// </summary>
+        /// <param name="path">The path.</param>
         protected void EnsureWriteAccess(string path)
         protected void EnsureWriteAccess(string path)
         {
         {
             var file = Path.Combine(path, Guid.NewGuid().ToString());
             var file = Path.Combine(path, Guid.NewGuid().ToString());
@@ -258,6 +267,7 @@ namespace Emby.Server.Implementations.AppBase
             return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLowerInvariant() + ".xml");
             return Path.Combine(CommonApplicationPaths.ConfigurationDirectoryPath, key.ToLowerInvariant() + ".xml");
         }
         }
 
 
+        /// <inheritdoc />
         public object GetConfiguration(string key)
         public object GetConfiguration(string key)
         {
         {
             return _configurations.GetOrAdd(key, k =>
             return _configurations.GetOrAdd(key, k =>
@@ -304,6 +314,7 @@ namespace Emby.Server.Implementations.AppBase
             }
             }
         }
         }
 
 
+        /// <inheritdoc />
         public void SaveConfiguration(string key, object configuration)
         public void SaveConfiguration(string key, object configuration)
         {
         {
             var configurationStore = GetConfigurationStore(key);
             var configurationStore = GetConfigurationStore(key);
@@ -314,8 +325,7 @@ namespace Emby.Server.Implementations.AppBase
                 throw new ArgumentException("Expected configuration type is " + configurationType.Name);
                 throw new ArgumentException("Expected configuration type is " + configurationType.Name);
             }
             }
 
 
-            var validatingStore = configurationStore as IValidatingConfiguration;
-            if (validatingStore != null)
+            if (configurationStore is IValidatingConfiguration validatingStore)
             {
             {
                 var currentConfiguration = GetConfiguration(key);
                 var currentConfiguration = GetConfiguration(key);
 
 
@@ -341,6 +351,11 @@ namespace Emby.Server.Implementations.AppBase
             OnNamedConfigurationUpdated(key, configuration);
             OnNamedConfigurationUpdated(key, configuration);
         }
         }
 
 
+        /// <summary>
+        /// Event handler for when a named configuration has been updated.
+        /// </summary>
+        /// <param name="key">The key of the configuration.</param>
+        /// <param name="configuration">The old configuration.</param>
         protected virtual void OnNamedConfigurationUpdated(string key, object configuration)
         protected virtual void OnNamedConfigurationUpdated(string key, object configuration)
         {
         {
             NamedConfigurationUpdated?.Invoke(this, new ConfigurationUpdateEventArgs
             NamedConfigurationUpdated?.Invoke(this, new ConfigurationUpdateEventArgs
@@ -350,6 +365,7 @@ namespace Emby.Server.Implementations.AppBase
             });
             });
         }
         }
 
 
+        /// <inheritdoc />
         public Type GetConfigurationType(string key)
         public Type GetConfigurationType(string key)
         {
         {
             return GetConfigurationStore(key)
             return GetConfigurationStore(key)

+ 2 - 2
Emby.Server.Implementations/AppBase/ConfigurationHelper.cs

@@ -6,13 +6,13 @@ using MediaBrowser.Model.Serialization;
 namespace Emby.Server.Implementations.AppBase
 namespace Emby.Server.Implementations.AppBase
 {
 {
     /// <summary>
     /// <summary>
-    /// Class ConfigurationHelper
+    /// Class ConfigurationHelper.
     /// </summary>
     /// </summary>
     public static class ConfigurationHelper
     public static class ConfigurationHelper
     {
     {
         /// <summary>
         /// <summary>
         /// Reads an xml configuration file from the file system
         /// Reads an xml configuration file from the file system
-        /// It will immediately re-serialize and save if new serialization data is available due to property changes
+        /// It will immediately re-serialize and save if new serialization data is available due to property changes.
         /// </summary>
         /// </summary>
         /// <param name="type">The type.</param>
         /// <param name="type">The type.</param>
         /// <param name="path">The path.</param>
         /// <param name="path">The path.</param>

+ 84 - 114
Emby.Server.Implementations/ApplicationHost.cs

@@ -88,7 +88,6 @@ using MediaBrowser.Model.Cryptography;
 using MediaBrowser.Model.Diagnostics;
 using MediaBrowser.Model.Diagnostics;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Dlna;
 using MediaBrowser.Model.Events;
 using MediaBrowser.Model.Events;
-using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.Globalization;
 using MediaBrowser.Model.Globalization;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.MediaInfo;
@@ -110,9 +109,8 @@ using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http.Extensions;
 using Microsoft.AspNetCore.Http.Extensions;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.DependencyInjection.Extensions;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
-using ServiceStack;
+using Microsoft.OpenApi.Models;
 using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
 using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
 
 
 namespace Emby.Server.Implementations
 namespace Emby.Server.Implementations
@@ -232,7 +230,25 @@ namespace Emby.Server.Implementations
             }
             }
         }
         }
 
 
-        protected IServiceProvider _serviceProvider;
+        /// <summary>
+        /// Gets or sets the service provider.
+        /// </summary>
+        public IServiceProvider ServiceProvider { get; set; }
+
+        /// <summary>
+        /// Gets the http port for the webhost.
+        /// </summary>
+        public int HttpPort { get; private set; }
+
+        /// <summary>
+        /// Gets the https port for the webhost.
+        /// </summary>
+        public int HttpsPort { get; private set; }
+
+        /// <summary>
+        /// Gets the content root for the webhost.
+        /// </summary>
+        public string ContentRoot { get; private set; }
 
 
         /// <summary>
         /// <summary>
         /// Gets the server configuration manager.
         /// Gets the server configuration manager.
@@ -321,7 +337,7 @@ namespace Emby.Server.Implementations
         private readonly IConfiguration _configuration;
         private readonly IConfiguration _configuration;
 
 
         /// <summary>
         /// <summary>
-        /// Gets or sets the installation manager.
+        /// Gets the installation manager.
         /// </summary>
         /// </summary>
         /// <value>The installation manager.</value>
         /// <value>The installation manager.</value>
         protected IInstallationManager InstallationManager { get; private set; }
         protected IInstallationManager InstallationManager { get; private set; }
@@ -410,13 +426,17 @@ namespace Emby.Server.Implementations
             _validAddressResults.Clear();
             _validAddressResults.Clear();
         }
         }
 
 
-        public string ApplicationVersion { get; } = typeof(ApplicationHost).Assembly.GetName().Version.ToString(3);
+        /// <inheritdoc />
+        public Version ApplicationVersion { get; } = typeof(ApplicationHost).Assembly.GetName().Version;
+
+        /// <inheritdoc />
+        public string ApplicationVersionString { get; } = typeof(ApplicationHost).Assembly.GetName().Version.ToString(3);
 
 
         /// <summary>
         /// <summary>
         /// Gets the current application user agent.
         /// Gets the current application user agent.
         /// </summary>
         /// </summary>
         /// <value>The application user agent.</value>
         /// <value>The application user agent.</value>
-        public string ApplicationUserAgent => Name.Replace(' ', '-') + "/" + ApplicationVersion;
+        public string ApplicationUserAgent => Name.Replace(' ', '-') + "/" + ApplicationVersionString;
 
 
         /// <summary>
         /// <summary>
         /// Gets the email address for use within a comment section of a user agent field.
         /// Gets the email address for use within a comment section of a user agent field.
@@ -452,20 +472,20 @@ namespace Emby.Server.Implementations
         public string Name => ApplicationProductName;
         public string Name => ApplicationProductName;
 
 
         /// <summary>
         /// <summary>
-        /// Creates an instance of type and resolves all constructor dependencies
+        /// Creates an instance of type and resolves all constructor dependencies.
         /// </summary>
         /// </summary>
         /// <param name="type">The type.</param>
         /// <param name="type">The type.</param>
         /// <returns>System.Object.</returns>
         /// <returns>System.Object.</returns>
         public object CreateInstance(Type type)
         public object CreateInstance(Type type)
-            => ActivatorUtilities.CreateInstance(_serviceProvider, type);
+            => ActivatorUtilities.CreateInstance(ServiceProvider, type);
 
 
         /// <summary>
         /// <summary>
-        /// Creates an instance of type and resolves all constructor dependencies
+        /// Creates an instance of type and resolves all constructor dependencies.
         /// </summary>
         /// </summary>
         /// /// <typeparam name="T">The type.</typeparam>
         /// /// <typeparam name="T">The type.</typeparam>
         /// <returns>T.</returns>
         /// <returns>T.</returns>
         public T CreateInstance<T>()
         public T CreateInstance<T>()
-            => ActivatorUtilities.CreateInstance<T>(_serviceProvider);
+            => ActivatorUtilities.CreateInstance<T>(ServiceProvider);
 
 
         /// <summary>
         /// <summary>
         /// Creates the instance safe.
         /// Creates the instance safe.
@@ -477,7 +497,7 @@ namespace Emby.Server.Implementations
             try
             try
             {
             {
                 Logger.LogDebug("Creating instance of {Type}", type);
                 Logger.LogDebug("Creating instance of {Type}", type);
-                return ActivatorUtilities.CreateInstance(_serviceProvider, type);
+                return ActivatorUtilities.CreateInstance(ServiceProvider, type);
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
@@ -491,12 +511,12 @@ namespace Emby.Server.Implementations
         /// </summary>
         /// </summary>
         /// <typeparam name="T">The type</typeparam>
         /// <typeparam name="T">The type</typeparam>
         /// <returns>``0.</returns>
         /// <returns>``0.</returns>
-        public T Resolve<T>() => _serviceProvider.GetService<T>();
+        public T Resolve<T>() => ServiceProvider.GetService<T>();
 
 
         /// <summary>
         /// <summary>
         /// Gets the export types.
         /// Gets the export types.
         /// </summary>
         /// </summary>
-        /// <typeparam name="T">The type</typeparam>
+        /// <typeparam name="T">The type.</typeparam>
         /// <returns>IEnumerable{Type}.</returns>
         /// <returns>IEnumerable{Type}.</returns>
         public IEnumerable<Type> GetExportTypes<T>()
         public IEnumerable<Type> GetExportTypes<T>()
         {
         {
@@ -508,11 +528,12 @@ namespace Emby.Server.Implementations
         /// <inheritdoc />
         /// <inheritdoc />
         public IReadOnlyCollection<T> GetExports<T>(bool manageLifetime = true)
         public IReadOnlyCollection<T> GetExports<T>(bool manageLifetime = true)
         {
         {
+            // Convert to list so this isn't executed for each iteration
             var parts = GetExportTypes<T>()
             var parts = GetExportTypes<T>()
                 .Select(CreateInstanceSafe)
                 .Select(CreateInstanceSafe)
                 .Where(i => i != null)
                 .Where(i => i != null)
                 .Cast<T>()
                 .Cast<T>()
-                .ToList(); // Convert to list so this isn't executed for each iteration
+                .ToList();
 
 
             if (manageLifetime)
             if (manageLifetime)
             {
             {
@@ -607,77 +628,14 @@ namespace Emby.Server.Implementations
 
 
             await RegisterResources(serviceCollection).ConfigureAwait(false);
             await RegisterResources(serviceCollection).ConfigureAwait(false);
 
 
-            FindParts();
-
-            string contentRoot = ServerConfigurationManager.Configuration.DashboardSourcePath;
-            if (string.IsNullOrEmpty(contentRoot))
+            ContentRoot = ServerConfigurationManager.Configuration.DashboardSourcePath;
+            if (string.IsNullOrEmpty(ContentRoot))
             {
             {
-                contentRoot = ServerConfigurationManager.ApplicationPaths.WebPath;
-            }
-
-            var host = new WebHostBuilder()
-                .UseKestrel(options =>
-                {
-                    var addresses = ServerConfigurationManager
-                        .Configuration
-                        .LocalNetworkAddresses
-                        .Select(NormalizeConfiguredLocalAddress)
-                        .Where(i => i != null)
-                        .ToList();
-                    if (addresses.Any())
-                    {
-                        foreach (var address in addresses)
-                        {
-                            Logger.LogInformation("Kestrel listening on {ipaddr}", address);
-                            options.Listen(address, HttpPort);
-
-                            if (EnableHttps && Certificate != null)
-                            {
-                                options.Listen(address, HttpsPort, listenOptions => listenOptions.UseHttps(Certificate));
-                            }
-                        }
-                    }
-                    else
-                    {
-                        Logger.LogInformation("Kestrel listening on all interfaces");
-                        options.ListenAnyIP(HttpPort);
-
-                        if (EnableHttps && Certificate != null)
-                        {
-                            options.ListenAnyIP(HttpsPort, listenOptions => listenOptions.UseHttps(Certificate));
-                        }
-                    }
-                })
-                .UseContentRoot(contentRoot)
-                .ConfigureServices(services =>
-                {
-                    services.AddResponseCompression();
-                    services.AddHttpContextAccessor();
-                })
-                .Configure(app =>
-                {
-                    app.UseWebSockets();
-
-                    app.UseResponseCompression();
-
-                    // TODO app.UseMiddleware<WebSocketMiddleware>();
-                    app.Use(ExecuteWebsocketHandlerAsync);
-                    app.Use(ExecuteHttpHandlerAsync);
-                })
-                .Build();
-
-            try
-            {
-                await host.StartAsync().ConfigureAwait(false);
-            }
-            catch
-            {
-                Logger.LogError("Kestrel failed to start! This is most likely due to an invalid address or port bind - correct your bind configuration in system.xml and try again.");
-                throw;
+                ContentRoot = ServerConfigurationManager.ApplicationPaths.WebPath;
             }
             }
         }
         }
 
 
-        private async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func<Task> next)
+        public async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func<Task> next)
         {
         {
             if (!context.WebSockets.IsWebSocketRequest)
             if (!context.WebSockets.IsWebSocketRequest)
             {
             {
@@ -688,7 +646,7 @@ namespace Emby.Server.Implementations
             await HttpServer.ProcessWebSocketRequest(context).ConfigureAwait(false);
             await HttpServer.ProcessWebSocketRequest(context).ConfigureAwait(false);
         }
         }
 
 
-        private async Task ExecuteHttpHandlerAsync(HttpContext context, Func<Task> next)
+        public async Task ExecuteHttpHandlerAsync(HttpContext context, Func<Task> next)
         {
         {
             if (context.WebSockets.IsWebSocketRequest)
             if (context.WebSockets.IsWebSocketRequest)
             {
             {
@@ -749,7 +707,8 @@ namespace Emby.Server.Implementations
 
 
             serviceCollection.AddSingleton(typeof(IStreamHelper), typeof(StreamHelper));
             serviceCollection.AddSingleton(typeof(IStreamHelper), typeof(StreamHelper));
 
 
-            serviceCollection.AddSingleton(typeof(ICryptoProvider), typeof(CryptographyProvider));
+            var cryptoProvider = new CryptographyProvider();
+            serviceCollection.AddSingleton<ICryptoProvider>(cryptoProvider);
 
 
             SocketFactory = new SocketFactory();
             SocketFactory = new SocketFactory();
             serviceCollection.AddSingleton(SocketFactory);
             serviceCollection.AddSingleton(SocketFactory);
@@ -788,16 +747,25 @@ namespace Emby.Server.Implementations
 
 
             _userRepository = GetUserRepository();
             _userRepository = GetUserRepository();
 
 
-            UserManager = new UserManager(LoggerFactory.CreateLogger<UserManager>(), _userRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, this, JsonSerializer, FileSystemManager);
+            UserManager = new UserManager(
+                LoggerFactory.CreateLogger<UserManager>(),
+                _userRepository,
+                XmlSerializer,
+                NetworkManager,
+                () => ImageProcessor,
+                () => DtoService,
+                this,
+                JsonSerializer,
+                FileSystemManager,
+                cryptoProvider);
 
 
             serviceCollection.AddSingleton(UserManager);
             serviceCollection.AddSingleton(UserManager);
 
 
             LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager);
             LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager);
             serviceCollection.AddSingleton(LibraryManager);
             serviceCollection.AddSingleton(LibraryManager);
 
 
-            // TODO wtaylor: investigate use of second music manager
             var musicManager = new MusicManager(LibraryManager);
             var musicManager = new MusicManager(LibraryManager);
-            serviceCollection.AddSingleton<IMusicManager>(new MusicManager(LibraryManager));
+            serviceCollection.AddSingleton<IMusicManager>(musicManager);
 
 
             LibraryMonitor = new LibraryMonitor(LoggerFactory, LibraryManager, ServerConfigurationManager, FileSystemManager);
             LibraryMonitor = new LibraryMonitor(LoggerFactory, LibraryManager, ServerConfigurationManager, FileSystemManager);
             serviceCollection.AddSingleton(LibraryMonitor);
             serviceCollection.AddSingleton(LibraryMonitor);
@@ -866,23 +834,20 @@ namespace Emby.Server.Implementations
             NotificationManager = new NotificationManager(LoggerFactory, UserManager, ServerConfigurationManager);
             NotificationManager = new NotificationManager(LoggerFactory, UserManager, ServerConfigurationManager);
             serviceCollection.AddSingleton(NotificationManager);
             serviceCollection.AddSingleton(NotificationManager);
 
 
-            serviceCollection.AddSingleton<IDeviceDiscovery>(
-                new DeviceDiscovery(LoggerFactory, ServerConfigurationManager, SocketFactory));
+            serviceCollection.AddSingleton<IDeviceDiscovery>(new DeviceDiscovery(ServerConfigurationManager));
 
 
             ChapterManager = new ChapterManager(LibraryManager, LoggerFactory, ServerConfigurationManager, ItemRepository);
             ChapterManager = new ChapterManager(LibraryManager, LoggerFactory, ServerConfigurationManager, ItemRepository);
             serviceCollection.AddSingleton(ChapterManager);
             serviceCollection.AddSingleton(ChapterManager);
 
 
             MediaEncoder = new MediaBrowser.MediaEncoding.Encoder.MediaEncoder(
             MediaEncoder = new MediaBrowser.MediaEncoding.Encoder.MediaEncoder(
-                LoggerFactory,
-                JsonSerializer,
-                StartupOptions.FFmpegPath,
+                LoggerFactory.CreateLogger<MediaBrowser.MediaEncoding.Encoder.MediaEncoder>(),
                 ServerConfigurationManager,
                 ServerConfigurationManager,
                 FileSystemManager,
                 FileSystemManager,
-                () => SubtitleEncoder,
-                () => MediaSourceManager,
                 ProcessFactory,
                 ProcessFactory,
-                5000,
-                LocalizationManager);
+                LocalizationManager,
+                () => SubtitleEncoder,
+                _configuration,
+                StartupOptions.FFmpegPath);
             serviceCollection.AddSingleton(MediaEncoder);
             serviceCollection.AddSingleton(MediaEncoder);
 
 
             EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager);
             EncodingManager = new MediaEncoder.EncodingManager(FileSystemManager, LoggerFactory, MediaEncoder, ChapterManager, LibraryManager);
@@ -896,13 +861,22 @@ namespace Emby.Server.Implementations
             serviceCollection.AddSingleton<IAuthorizationContext>(authContext);
             serviceCollection.AddSingleton<IAuthorizationContext>(authContext);
             serviceCollection.AddSingleton<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
             serviceCollection.AddSingleton<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
 
 
-            AuthService = new AuthService(authContext, ServerConfigurationManager, SessionManager, NetworkManager);
+            AuthService = new AuthService(LoggerFactory.CreateLogger<AuthService>(), authContext, ServerConfigurationManager, SessionManager, NetworkManager);
             serviceCollection.AddSingleton(AuthService);
             serviceCollection.AddSingleton(AuthService);
 
 
-            SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(LibraryManager, LoggerFactory, ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer, HttpClient, MediaSourceManager, ProcessFactory);
+            SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(
+                LibraryManager,
+                LoggerFactory.CreateLogger<MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder>(),
+                ApplicationPaths,
+                FileSystemManager,
+                MediaEncoder,
+                HttpClient,
+                MediaSourceManager,
+                ProcessFactory);
             serviceCollection.AddSingleton(SubtitleEncoder);
             serviceCollection.AddSingleton(SubtitleEncoder);
 
 
             serviceCollection.AddSingleton(typeof(IResourceFileManager), typeof(ResourceFileManager));
             serviceCollection.AddSingleton(typeof(IResourceFileManager), typeof(ResourceFileManager));
+            serviceCollection.AddSingleton<EncodingHelper>();
 
 
             serviceCollection.AddSingleton(typeof(MediaBrowser.Controller.MediaEncoding.IAttachmentExtractor),typeof(MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor));
             serviceCollection.AddSingleton(typeof(MediaBrowser.Controller.MediaEncoding.IAttachmentExtractor),typeof(MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor));
 
 
@@ -917,8 +891,6 @@ namespace Emby.Server.Implementations
             ((UserDataManager)UserDataManager).Repository = userDataRepo;
             ((UserDataManager)UserDataManager).Repository = userDataRepo;
             ItemRepository.Initialize(userDataRepo, UserManager);
             ItemRepository.Initialize(userDataRepo, UserManager);
             ((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
             ((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
-
-            _serviceProvider = serviceCollection.BuildServiceProvider();
         }
         }
 
 
         public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths)
         public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths)
@@ -1009,7 +981,7 @@ namespace Emby.Server.Implementations
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// Dirty hacks
+        /// Dirty hacks.
         /// </summary>
         /// </summary>
         private void SetStaticProperties()
         private void SetStaticProperties()
         {
         {
@@ -1075,9 +1047,9 @@ namespace Emby.Server.Implementations
         /// <summary>
         /// <summary>
         /// Finds the parts.
         /// Finds the parts.
         /// </summary>
         /// </summary>
-        protected void FindParts()
+        public void FindParts()
         {
         {
-            InstallationManager = _serviceProvider.GetService<IInstallationManager>();
+            InstallationManager = ServiceProvider.GetService<IInstallationManager>();
             InstallationManager.PluginInstalled += PluginInstalled;
             InstallationManager.PluginInstalled += PluginInstalled;
 
 
             if (!ServerConfigurationManager.Configuration.IsPortAuthorized)
             if (!ServerConfigurationManager.Configuration.IsPortAuthorized)
@@ -1206,7 +1178,7 @@ namespace Emby.Server.Implementations
 
 
         private CertificateInfo CertificateInfo { get; set; }
         private CertificateInfo CertificateInfo { get; set; }
 
 
-        protected X509Certificate2 Certificate { get; private set; }
+        public X509Certificate2 Certificate { get; private set; }
 
 
         private IEnumerable<string> GetUrlPrefixes()
         private IEnumerable<string> GetUrlPrefixes()
         {
         {
@@ -1417,17 +1389,18 @@ namespace Emby.Server.Implementations
         /// <summary>
         /// <summary>
         /// Gets the system status.
         /// Gets the system status.
         /// </summary>
         /// </summary>
-        /// <param name="cancellationToken">The cancellation token</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>SystemInfo.</returns>
         /// <returns>SystemInfo.</returns>
         public async Task<SystemInfo> GetSystemInfo(CancellationToken cancellationToken)
         public async Task<SystemInfo> GetSystemInfo(CancellationToken cancellationToken)
         {
         {
             var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
             var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
+            var transcodingTempPath = ConfigurationManager.GetTranscodePath();
 
 
             return new SystemInfo
             return new SystemInfo
             {
             {
                 HasPendingRestart = HasPendingRestart,
                 HasPendingRestart = HasPendingRestart,
                 IsShuttingDown = IsShuttingDown,
                 IsShuttingDown = IsShuttingDown,
-                Version = ApplicationVersion,
+                Version = ApplicationVersionString,
                 WebSocketPortNumber = HttpPort,
                 WebSocketPortNumber = HttpPort,
                 CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(),
                 CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(),
                 Id = SystemId,
                 Id = SystemId,
@@ -1445,7 +1418,7 @@ namespace Emby.Server.Implementations
                 CanSelfRestart = CanSelfRestart,
                 CanSelfRestart = CanSelfRestart,
                 CanLaunchWebBrowser = CanLaunchWebBrowser,
                 CanLaunchWebBrowser = CanLaunchWebBrowser,
                 HasUpdateAvailable = HasUpdateAvailable,
                 HasUpdateAvailable = HasUpdateAvailable,
-                TranscodingTempPath = ApplicationPaths.TranscodingTempPath,
+                TranscodingTempPath = transcodingTempPath,
                 ServerName = FriendlyName,
                 ServerName = FriendlyName,
                 LocalAddress = localAddress,
                 LocalAddress = localAddress,
                 SupportsLibraryMonitor = true,
                 SupportsLibraryMonitor = true,
@@ -1467,7 +1440,7 @@ namespace Emby.Server.Implementations
 
 
             return new PublicSystemInfo
             return new PublicSystemInfo
             {
             {
-                Version = ApplicationVersion,
+                Version = ApplicationVersionString,
                 ProductName = ApplicationProductName,
                 ProductName = ApplicationProductName,
                 Id = SystemId,
                 Id = SystemId,
                 OperatingSystem = OperatingSystem.Id.ToString(),
                 OperatingSystem = OperatingSystem.Id.ToString(),
@@ -1590,7 +1563,7 @@ namespace Emby.Server.Implementations
             return resultList;
             return resultList;
         }
         }
 
 
-        private IPAddress NormalizeConfiguredLocalAddress(string address)
+        public IPAddress NormalizeConfiguredLocalAddress(string address)
         {
         {
             var index = address.Trim('/').IndexOf('/');
             var index = address.Trim('/').IndexOf('/');
 
 
@@ -1666,10 +1639,6 @@ namespace Emby.Server.Implementations
                 ? Environment.MachineName
                 ? Environment.MachineName
                 : ServerConfigurationManager.Configuration.ServerName;
                 : ServerConfigurationManager.Configuration.ServerName;
 
 
-        public int HttpPort { get; private set; }
-
-        public int HttpsPort { get; private set; }
-
         /// <summary>
         /// <summary>
         /// Shuts down.
         /// Shuts down.
         /// </summary>
         /// </summary>
@@ -1732,7 +1701,7 @@ namespace Emby.Server.Implementations
         /// dns is prefixed with a valid Uri prefix.
         /// dns is prefixed with a valid Uri prefix.
         /// </summary>
         /// </summary>
         /// <param name="externalDns">The external dns prefix to get the hostname of.</param>
         /// <param name="externalDns">The external dns prefix to get the hostname of.</param>
-        /// <returns>The hostname in <paramref name="externalDns"/></returns>
+        /// <returns>The hostname in <paramref name="externalDns"/>.</returns>
         private static string GetHostnameFromExternalDns(string externalDns)
         private static string GetHostnameFromExternalDns(string externalDns)
         {
         {
             if (string.IsNullOrEmpty(externalDns))
             if (string.IsNullOrEmpty(externalDns))
@@ -1846,6 +1815,7 @@ namespace Emby.Server.Implementations
     internal class CertificateInfo
     internal class CertificateInfo
     {
     {
         public string Path { get; set; }
         public string Path { get; set; }
+
         public string Password { get; set; }
         public string Password { get; set; }
     }
     }
 }
 }

+ 1 - 7
Emby.Server.Implementations/Archiving/ZipClient.cs

@@ -10,15 +10,10 @@ using SharpCompress.Readers.Zip;
 namespace Emby.Server.Implementations.Archiving
 namespace Emby.Server.Implementations.Archiving
 {
 {
     /// <summary>
     /// <summary>
-    /// Class DotNetZipClient
+    /// Class DotNetZipClient.
     /// </summary>
     /// </summary>
     public class ZipClient : IZipClient
     public class ZipClient : IZipClient
     {
     {
-        public ZipClient()
-        {
-
-        }
-
         /// <summary>
         /// <summary>
         /// Extracts all.
         /// Extracts all.
         /// </summary>
         /// </summary>
@@ -144,7 +139,6 @@ namespace Emby.Server.Implementations.Archiving
             }
             }
         }
         }
 
 
-
         /// <summary>
         /// <summary>
         /// Extracts all from tar.
         /// Extracts all from tar.
         /// </summary>
         /// </summary>

+ 2 - 0
Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System.Collections.Generic;
 using System.Collections.Generic;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Model.Branding;
 using MediaBrowser.Model.Branding;

+ 2 - 1
Emby.Server.Implementations/Browser/BrowserLauncher.cs

@@ -4,7 +4,7 @@ using MediaBrowser.Controller;
 namespace Emby.Server.Implementations.Browser
 namespace Emby.Server.Implementations.Browser
 {
 {
     /// <summary>
     /// <summary>
-    /// Class BrowserLauncher
+    /// Class BrowserLauncher.
     /// </summary>
     /// </summary>
     public static class BrowserLauncher
     public static class BrowserLauncher
     {
     {
@@ -32,6 +32,7 @@ namespace Emby.Server.Implementations.Browser
         /// <summary>
         /// <summary>
         /// Opens the URL.
         /// Opens the URL.
         /// </summary>
         /// </summary>
+        /// <param name="appHost">The application host instance.</param>
         /// <param name="url">The URL.</param>
         /// <param name="url">The URL.</param>
         private static void OpenUrl(IServerApplicationHost appHost, string url)
         private static void OpenUrl(IServerApplicationHost appHost, string url)
         {
         {

+ 8 - 0
Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Threading;
 using System.Threading;
@@ -13,11 +15,16 @@ namespace Emby.Server.Implementations.Channels
     {
     {
         private readonly ChannelManager _channelManager;
         private readonly ChannelManager _channelManager;
 
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ChannelDynamicMediaSourceProvider"/> class.
+        /// </summary>
+        /// <param name="channelManager">The channel manager.</param>
         public ChannelDynamicMediaSourceProvider(IChannelManager channelManager)
         public ChannelDynamicMediaSourceProvider(IChannelManager channelManager)
         {
         {
             _channelManager = (ChannelManager)channelManager;
             _channelManager = (ChannelManager)channelManager;
         }
         }
 
 
+        /// <inheritdoc />
         public Task<IEnumerable<MediaSourceInfo>> GetMediaSources(BaseItem item, CancellationToken cancellationToken)
         public Task<IEnumerable<MediaSourceInfo>> GetMediaSources(BaseItem item, CancellationToken cancellationToken)
         {
         {
             if (item.SourceType == SourceType.Channel)
             if (item.SourceType == SourceType.Channel)
@@ -28,6 +35,7 @@ namespace Emby.Server.Implementations.Channels
             return Task.FromResult<IEnumerable<MediaSourceInfo>>(new List<MediaSourceInfo>());
             return Task.FromResult<IEnumerable<MediaSourceInfo>>(new List<MediaSourceInfo>());
         }
         }
 
 
+        /// <inheritdoc />
         public Task<ILiveStream> OpenMediaSource(string openToken, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
         public Task<ILiveStream> OpenMediaSource(string openToken, List<ILiveStream> currentLiveStreams, CancellationToken cancellationToken)
         {
         {
             throw new NotImplementedException();
             throw new NotImplementedException();

+ 2 - 0
Emby.Server.Implementations/Channels/ChannelImageProvider.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Threading;
 using System.Threading;

+ 9 - 7
Emby.Server.Implementations/Channels/ChannelManager.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -473,7 +475,7 @@ namespace Emby.Server.Implementations.Channels
             await item.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem))
             await item.RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(_fileSystem))
             {
             {
                 ForceSave = !isNew && forceUpdate
                 ForceSave = !isNew && forceUpdate
-            }, cancellationToken);
+            }, cancellationToken).ConfigureAwait(false);
 
 
             return item;
             return item;
         }
         }
@@ -510,7 +512,7 @@ namespace Emby.Server.Implementations.Channels
             return _libraryManager.GetItemIds(new InternalItemsQuery
             return _libraryManager.GetItemIds(new InternalItemsQuery
             {
             {
                 IncludeItemTypes = new[] { typeof(Channel).Name },
                 IncludeItemTypes = new[] { typeof(Channel).Name },
-                OrderBy = new ValueTuple<string, SortOrder>[] { new ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) }
+                OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) }
 
 
             }).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
             }).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray();
         }
         }
@@ -618,16 +620,16 @@ namespace Emby.Server.Implementations.Channels
             {
             {
                 query.OrderBy = new[]
                 query.OrderBy = new[]
                 {
                 {
-                    new ValueTuple<string, SortOrder>(ItemSortBy.PremiereDate, SortOrder.Descending),
-                    new ValueTuple<string, SortOrder>(ItemSortBy.ProductionYear, SortOrder.Descending),
-                    new ValueTuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending)
+                    (ItemSortBy.PremiereDate, SortOrder.Descending),
+                    (ItemSortBy.ProductionYear, SortOrder.Descending),
+                    (ItemSortBy.DateCreated, SortOrder.Descending)
                 };
                 };
             }
             }
             else
             else
             {
             {
                 query.OrderBy = new[]
                 query.OrderBy = new[]
                 {
                 {
-                    new ValueTuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending)
+                    (ItemSortBy.DateCreated, SortOrder.Descending)
                 };
                 };
             }
             }
 
 
@@ -636,7 +638,7 @@ namespace Emby.Server.Implementations.Channels
 
 
         private async Task RefreshLatestChannelItems(IChannel channel, CancellationToken cancellationToken)
         private async Task RefreshLatestChannelItems(IChannel channel, CancellationToken cancellationToken)
         {
         {
-            var internalChannel = await GetChannel(channel, cancellationToken);
+            var internalChannel = await GetChannel(channel, cancellationToken).ConfigureAwait(false);
 
 
             var query = new InternalItemsQuery();
             var query = new InternalItemsQuery();
             query.Parent = internalChannel;
             query.Parent = internalChannel;

+ 2 - 0
Emby.Server.Implementations/Channels/ChannelPostScanTask.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 using System;
 using System.Linq;
 using System.Linq;
 using System.Threading;
 using System.Threading;

+ 2 - 0
Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Threading;
 using System.Threading;

+ 2 - 1
Emby.Server.Implementations/Collections/CollectionImageProvider.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
@@ -76,7 +78,6 @@ namespace Emby.Server.Implementations.Collections
                 .Where(i => i != null)
                 .Where(i => i != null)
                 .GroupBy(x => x.Id)
                 .GroupBy(x => x.Id)
                 .Select(x => x.First())
                 .Select(x => x.First())
-                .OrderBy(i => Guid.NewGuid())
                 .ToList();
                 .ToList();
         }
         }
 
 

+ 13 - 39
Emby.Server.Implementations/Collections/CollectionManager.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Globalization;
@@ -29,11 +31,7 @@ namespace Emby.Server.Implementations.Collections
         private readonly ILogger _logger;
         private readonly ILogger _logger;
         private readonly IProviderManager _providerManager;
         private readonly IProviderManager _providerManager;
         private readonly ILocalizationManager _localizationManager;
         private readonly ILocalizationManager _localizationManager;
-        private IApplicationPaths _appPaths;
-
-        public event EventHandler<CollectionCreatedEventArgs> CollectionCreated;
-        public event EventHandler<CollectionModifiedEventArgs> ItemsAddedToCollection;
-        public event EventHandler<CollectionModifiedEventArgs> ItemsRemovedFromCollection;
+        private readonly IApplicationPaths _appPaths;
 
 
         public CollectionManager(
         public CollectionManager(
             ILibraryManager libraryManager,
             ILibraryManager libraryManager,
@@ -53,6 +51,10 @@ namespace Emby.Server.Implementations.Collections
             _appPaths = appPaths;
             _appPaths = appPaths;
         }
         }
 
 
+        public event EventHandler<CollectionCreatedEventArgs> CollectionCreated;
+        public event EventHandler<CollectionModifiedEventArgs> ItemsAddedToCollection;
+        public event EventHandler<CollectionModifiedEventArgs> ItemsRemovedFromCollection;
+
         private IEnumerable<Folder> FindFolders(string path)
         private IEnumerable<Folder> FindFolders(string path)
         {
         {
             return _libraryManager
             return _libraryManager
@@ -121,7 +123,7 @@ namespace Emby.Server.Implementations.Collections
             // This could cause it to get re-resolved as a plain folder
             // This could cause it to get re-resolved as a plain folder
             var folderName = _fileSystem.GetValidFilename(name) + " [boxset]";
             var folderName = _fileSystem.GetValidFilename(name) + " [boxset]";
 
 
-            var parentFolder = GetCollectionsFolder(true).Result;
+            var parentFolder = GetCollectionsFolder(true).GetAwaiter().GetResult();
 
 
             if (parentFolder == null)
             if (parentFolder == null)
             {
             {
@@ -339,11 +341,11 @@ namespace Emby.Server.Implementations.Collections
         }
         }
     }
     }
 
 
-    public class CollectionManagerEntryPoint : IServerEntryPoint
+    public sealed class CollectionManagerEntryPoint : IServerEntryPoint
     {
     {
         private readonly CollectionManager _collectionManager;
         private readonly CollectionManager _collectionManager;
         private readonly IServerConfigurationManager _config;
         private readonly IServerConfigurationManager _config;
-        private ILogger _logger;
+        private readonly ILogger _logger;
 
 
         public CollectionManagerEntryPoint(ICollectionManager collectionManager, IServerConfigurationManager config, ILogger logger)
         public CollectionManagerEntryPoint(ICollectionManager collectionManager, IServerConfigurationManager config, ILogger logger)
         {
         {
@@ -352,6 +354,7 @@ namespace Emby.Server.Implementations.Collections
             _logger = logger;
             _logger = logger;
         }
         }
 
 
+        /// <inheritdoc />
         public async Task RunAsync()
         public async Task RunAsync()
         {
         {
             if (!_config.Configuration.CollectionsUpgraded && _config.Configuration.IsStartupWizardCompleted)
             if (!_config.Configuration.CollectionsUpgraded && _config.Configuration.IsStartupWizardCompleted)
@@ -375,39 +378,10 @@ namespace Emby.Server.Implementations.Collections
             }
             }
         }
         }
 
 
-        #region IDisposable Support
-        private bool disposedValue = false; // To detect redundant calls
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (!disposedValue)
-            {
-                if (disposing)
-                {
-                    // TODO: dispose managed state (managed objects).
-                }
-
-                // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
-                // TODO: set large fields to null.
-
-                disposedValue = true;
-            }
-        }
-
-        // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
-        // ~CollectionManagerEntryPoint() {
-        //   // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
-        //   Dispose(false);
-        // }
-
-        // This code added to correctly implement the disposable pattern.
+        /// <inheritdoc />
         public void Dispose()
         public void Dispose()
         {
         {
-            // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
-            Dispose(true);
-            // TODO: uncomment the following line if the finalizer is overridden above.
-            // GC.SuppressFinalize(this);
+            // Nothing to dispose
         }
         }
-        #endregion
     }
     }
 }
 }

+ 23 - 38
Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs

@@ -1,5 +1,6 @@
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
+using System.Globalization;
 using System.IO;
 using System.IO;
 using Emby.Server.Implementations.AppBase;
 using Emby.Server.Implementations.AppBase;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Configuration;
@@ -14,11 +15,10 @@ using Microsoft.Extensions.Logging;
 namespace Emby.Server.Implementations.Configuration
 namespace Emby.Server.Implementations.Configuration
 {
 {
     /// <summary>
     /// <summary>
-    /// Class ServerConfigurationManager
+    /// Class ServerConfigurationManager.
     /// </summary>
     /// </summary>
     public class ServerConfigurationManager : BaseConfigurationManager, IServerConfigurationManager
     public class ServerConfigurationManager : BaseConfigurationManager, IServerConfigurationManager
     {
     {
-
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="ServerConfigurationManager" /> class.
         /// Initializes a new instance of the <see cref="ServerConfigurationManager" /> class.
         /// </summary>
         /// </summary>
@@ -32,6 +32,9 @@ namespace Emby.Server.Implementations.Configuration
             UpdateMetadataPath();
             UpdateMetadataPath();
         }
         }
 
 
+        /// <summary>
+        /// Configuration updating event.
+        /// </summary>
         public event EventHandler<GenericEventArgs<ServerConfiguration>> ConfigurationUpdating;
         public event EventHandler<GenericEventArgs<ServerConfiguration>> ConfigurationUpdating;
 
 
         /// <summary>
         /// <summary>
@@ -62,13 +65,6 @@ namespace Emby.Server.Implementations.Configuration
             base.OnConfigurationUpdated();
             base.OnConfigurationUpdated();
         }
         }
 
 
-        public override void AddParts(IEnumerable<IConfigurationFactory> factories)
-        {
-            base.AddParts(factories);
-
-            UpdateTranscodePath();
-        }
-
         /// <summary>
         /// <summary>
         /// Updates the metadata path.
         /// Updates the metadata path.
         /// </summary>
         /// </summary>
@@ -84,28 +80,6 @@ namespace Emby.Server.Implementations.Configuration
             }
             }
         }
         }
 
 
-        /// <summary>
-        /// Updates the transcoding temporary path.
-        /// </summary>
-        private void UpdateTranscodePath()
-        {
-            var encodingConfig = this.GetConfiguration<EncodingOptions>("encoding");
-
-            ((ServerApplicationPaths)ApplicationPaths).TranscodingTempPath = string.IsNullOrEmpty(encodingConfig.TranscodingTempPath) ?
-                null :
-                Path.Combine(encodingConfig.TranscodingTempPath, "transcodes");
-        }
-
-        protected override void OnNamedConfigurationUpdated(string key, object configuration)
-        {
-            base.OnNamedConfigurationUpdated(key, configuration);
-
-            if (string.Equals(key, "encoding", StringComparison.OrdinalIgnoreCase))
-            {
-                UpdateTranscodePath();
-            }
-        }
-
         /// <summary>
         /// <summary>
         /// Replaces the configuration.
         /// Replaces the configuration.
         /// </summary>
         /// </summary>
@@ -123,12 +97,11 @@ namespace Emby.Server.Implementations.Configuration
             base.ReplaceConfiguration(newConfiguration);
             base.ReplaceConfiguration(newConfiguration);
         }
         }
 
 
-
         /// <summary>
         /// <summary>
         /// Validates the SSL certificate.
         /// Validates the SSL certificate.
         /// </summary>
         /// </summary>
         /// <param name="newConfig">The new configuration.</param>
         /// <param name="newConfig">The new configuration.</param>
-        /// <exception cref="DirectoryNotFoundException"></exception>
+        /// <exception cref="FileNotFoundException">The certificate path doesn't exist.</exception>
         private void ValidateSslCertificate(BaseApplicationConfiguration newConfig)
         private void ValidateSslCertificate(BaseApplicationConfiguration newConfig)
         {
         {
             var serverConfig = (ServerConfiguration)newConfig;
             var serverConfig = (ServerConfiguration)newConfig;
@@ -136,12 +109,16 @@ namespace Emby.Server.Implementations.Configuration
             var newPath = serverConfig.CertificatePath;
             var newPath = serverConfig.CertificatePath;
 
 
             if (!string.IsNullOrWhiteSpace(newPath)
             if (!string.IsNullOrWhiteSpace(newPath)
-                && !string.Equals(Configuration.CertificatePath ?? string.Empty, newPath))
+                && !string.Equals(Configuration.CertificatePath, newPath, StringComparison.Ordinal))
             {
             {
                 // Validate
                 // Validate
                 if (!File.Exists(newPath))
                 if (!File.Exists(newPath))
                 {
                 {
-                    throw new FileNotFoundException(string.Format("Certificate file '{0}' does not exist.", newPath));
+                    throw new FileNotFoundException(
+                        string.Format(
+                            CultureInfo.InvariantCulture,
+                            "Certificate file '{0}' does not exist.",
+                            newPath));
                 }
                 }
             }
             }
         }
         }
@@ -150,24 +127,32 @@ namespace Emby.Server.Implementations.Configuration
         /// Validates the metadata path.
         /// Validates the metadata path.
         /// </summary>
         /// </summary>
         /// <param name="newConfig">The new configuration.</param>
         /// <param name="newConfig">The new configuration.</param>
-        /// <exception cref="DirectoryNotFoundException"></exception>
+        /// <exception cref="DirectoryNotFoundException">The new config path doesn't exist.</exception>
         private void ValidateMetadataPath(ServerConfiguration newConfig)
         private void ValidateMetadataPath(ServerConfiguration newConfig)
         {
         {
             var newPath = newConfig.MetadataPath;
             var newPath = newConfig.MetadataPath;
 
 
             if (!string.IsNullOrWhiteSpace(newPath)
             if (!string.IsNullOrWhiteSpace(newPath)
-                && !string.Equals(Configuration.MetadataPath ?? string.Empty, newPath))
+                && !string.Equals(Configuration.MetadataPath, newPath,  StringComparison.Ordinal))
             {
             {
                 // Validate
                 // Validate
                 if (!Directory.Exists(newPath))
                 if (!Directory.Exists(newPath))
                 {
                 {
-                    throw new FileNotFoundException(string.Format("{0} does not exist.", newPath));
+                    throw new DirectoryNotFoundException(
+                        string.Format(
+                            CultureInfo.InvariantCulture,
+                            "{0} does not exist.",
+                            newPath));
                 }
                 }
 
 
                 EnsureWriteAccess(newPath);
                 EnsureWriteAccess(newPath);
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// Sets all configuration values to their optimal values.
+        /// </summary>
+        /// <returns>If the configuration changed.</returns>
         public bool SetOptimalValues()
         public bool SetOptimalValues()
         {
         {
             var config = Configuration;
             var config = Configuration;

+ 5 - 2
Emby.Server.Implementations/ConfigurationOptions.cs

@@ -1,13 +1,16 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
+using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
 
 
 namespace Emby.Server.Implementations
 namespace Emby.Server.Implementations
 {
 {
     public static class ConfigurationOptions
     public static class ConfigurationOptions
     {
     {
-        public static readonly Dictionary<string, string> Configuration = new Dictionary<string, string>
+        public static Dictionary<string, string> Configuration => new Dictionary<string, string>
         {
         {
             { "HttpListenerHost:DefaultRedirectPath", "web/index.html" },
             { "HttpListenerHost:DefaultRedirectPath", "web/index.html" },
-            { "MusicBrainz:BaseUrl", "https://www.musicbrainz.org" }
+            { "MusicBrainz:BaseUrl", "https://www.musicbrainz.org" },
+            { FfmpegProbeSizeKey, "1G" },
+            { FfmpegAnalyzeDurationKey, "200M" }
         };
         };
     }
     }
 }
 }

+ 16 - 7
Emby.Server.Implementations/Cryptography/CryptographyProvider.cs

@@ -6,6 +6,9 @@ using static MediaBrowser.Common.Cryptography.Constants;
 
 
 namespace Emby.Server.Implementations.Cryptography
 namespace Emby.Server.Implementations.Cryptography
 {
 {
+    /// <summary>
+    /// Class providing abstractions over cryptographic functions.
+    /// </summary>
     public class CryptographyProvider : ICryptoProvider, IDisposable
     public class CryptographyProvider : ICryptoProvider, IDisposable
     {
     {
         private static readonly HashSet<string> _supportedHashMethods = new HashSet<string>()
         private static readonly HashSet<string> _supportedHashMethods = new HashSet<string>()
@@ -30,6 +33,9 @@ namespace Emby.Server.Implementations.Cryptography
 
 
         private bool _disposed = false;
         private bool _disposed = false;
 
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CryptographyProvider"/> class.
+        /// </summary>
         public CryptographyProvider()
         public CryptographyProvider()
         {
         {
             // FIXME: When we get DotNet Standard 2.1 we need to revisit how we do the crypto
             // FIXME: When we get DotNet Standard 2.1 we need to revisit how we do the crypto
@@ -39,8 +45,10 @@ namespace Emby.Server.Implementations.Cryptography
             _randomNumberGenerator = RandomNumberGenerator.Create();
             _randomNumberGenerator = RandomNumberGenerator.Create();
         }
         }
 
 
+        /// <inheritdoc />
         public string DefaultHashMethod => "PBKDF2";
         public string DefaultHashMethod => "PBKDF2";
 
 
+        /// <inheritdoc />
         public IEnumerable<string> GetSupportedHashMethods()
         public IEnumerable<string> GetSupportedHashMethods()
             => _supportedHashMethods;
             => _supportedHashMethods;
 
 
@@ -59,12 +67,7 @@ namespace Emby.Server.Implementations.Cryptography
             throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}");
             throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}");
         }
         }
 
 
-        public byte[] ComputeHash(string hashMethod, byte[] bytes)
-            => ComputeHash(hashMethod, bytes, Array.Empty<byte>());
-
-        public byte[] ComputeHashWithDefaultMethod(byte[] bytes)
-            => ComputeHash(DefaultHashMethod, bytes);
-
+        /// <inheritdoc />
         public byte[] ComputeHash(string hashMethod, byte[] bytes, byte[] salt)
         public byte[] ComputeHash(string hashMethod, byte[] bytes, byte[] salt)
         {
         {
             if (hashMethod == DefaultHashMethod)
             if (hashMethod == DefaultHashMethod)
@@ -90,15 +93,17 @@ namespace Emby.Server.Implementations.Cryptography
             }
             }
 
 
             throw new CryptographicException($"Requested hash method is not supported: {hashMethod}");
             throw new CryptographicException($"Requested hash method is not supported: {hashMethod}");
-
         }
         }
 
 
+        /// <inheritdoc />
         public byte[] ComputeHashWithDefaultMethod(byte[] bytes, byte[] salt)
         public byte[] ComputeHashWithDefaultMethod(byte[] bytes, byte[] salt)
             => PBKDF2(DefaultHashMethod, bytes, salt, DefaultIterations);
             => PBKDF2(DefaultHashMethod, bytes, salt, DefaultIterations);
 
 
+        /// <inheritdoc />
         public byte[] GenerateSalt()
         public byte[] GenerateSalt()
             => GenerateSalt(DefaultSaltLength);
             => GenerateSalt(DefaultSaltLength);
 
 
+        /// <inheritdoc />
         public byte[] GenerateSalt(int length)
         public byte[] GenerateSalt(int length)
         {
         {
             byte[] salt = new byte[length];
             byte[] salt = new byte[length];
@@ -113,6 +118,10 @@ namespace Emby.Server.Implementations.Cryptography
             GC.SuppressFinalize(this);
             GC.SuppressFinalize(this);
         }
         }
 
 
+        /// <summary>
+        /// Releases unmanaged and - optionally - managed resources.
+        /// </summary>
+        /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
         protected virtual void Dispose(bool disposing)
         protected virtual void Dispose(bool disposing)
         {
         {
             if (_disposed)
             if (_disposed)

+ 6 - 0
Emby.Server.Implementations/Data/BaseSqliteRepository.cs

@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
@@ -11,6 +13,10 @@ namespace Emby.Server.Implementations.Data
     {
     {
         private bool _disposed = false;
         private bool _disposed = false;
 
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BaseSqliteRepository"/> class.
+        /// </summary>
+        /// <param name="logger">The logger.</param>
         protected BaseSqliteRepository(ILogger logger)
         protected BaseSqliteRepository(ILogger logger)
         {
         {
             Logger = logger;
             Logger = logger;

Some files were not shown because too many files changed in this diff