diff options
Diffstat (limited to 'BDInfo/BDROM.cs')
| -rw-r--r-- | BDInfo/BDROM.cs | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/BDInfo/BDROM.cs b/BDInfo/BDROM.cs new file mode 100644 index 000000000..26d721268 --- /dev/null +++ b/BDInfo/BDROM.cs @@ -0,0 +1,442 @@ +//============================================================================ +// 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; + +namespace BDInfo +{ + public class BDROM + { + public DirectoryInfo DirectoryRoot = null; + public DirectoryInfo DirectoryBDMV = null; + public DirectoryInfo DirectoryBDJO = null; + public DirectoryInfo DirectoryCLIPINF = null; + public DirectoryInfo DirectoryPLAYLIST = null; + public DirectoryInfo DirectorySNP = null; + public DirectoryInfo DirectorySSIF = null; + public DirectoryInfo 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; + + 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>(); + + private static List<string> ExcludeDirs = new List<string> { "ANY!", "AACS", "BDSVM", "ANYVM", "SLYVM" }; + + 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) + { + // + // Locate BDMV directories. + // + + DirectoryBDMV = + GetDirectoryBDMV(path); + + if (DirectoryBDMV == null) + { + throw new Exception("Unable to locate BD structure."); + } + + DirectoryRoot = + DirectoryBDMV.Parent; + 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 && + DirectoryBDJO.GetFiles().Length > 0) + { + IsBDJava = true; + } + + if (DirectorySNP != null && + (DirectorySNP.GetFiles("*.mnv").Length > 0 || DirectorySNP.GetFiles("*.MNV").Length > 0)) + { + IsPSP = true; + } + + if (DirectorySSIF != null && + DirectorySSIF.GetFiles().Length > 0) + { + Is3D = true; + } + + if (File.Exists(Path.Combine(DirectoryRoot.FullName, "FilmIndex.xml"))) + { + IsDBOX = true; + } + + // + // Initialize file lists. + // + + if (DirectoryPLAYLIST != null) + { + FileInfo[] files = DirectoryPLAYLIST.GetFiles("*.mpls"); + if (files.Length == 0) + { + files = DirectoryPLAYLIST.GetFiles("*.MPLS"); + } + foreach (FileInfo file in files) + { + PlaylistFiles.Add( + file.Name.ToUpper(), new TSPlaylistFile(this, file)); + } + } + + if (DirectorySTREAM != null) + { + FileInfo[] files = DirectorySTREAM.GetFiles("*.m2ts"); + if (files.Length == 0) + { + files = DirectoryPLAYLIST.GetFiles("*.M2TS"); + } + foreach (FileInfo file in files) + { + StreamFiles.Add( + file.Name.ToUpper(), new TSStreamFile(file)); + } + } + + if (DirectoryCLIPINF != null) + { + FileInfo[] files = DirectoryCLIPINF.GetFiles("*.clpi"); + if (files.Length == 0) + { + files = DirectoryPLAYLIST.GetFiles("*.CLPI"); + } + foreach (FileInfo file in files) + { + StreamClipFiles.Add( + file.Name.ToUpper(), new TSStreamClipFile(file)); + } + } + + if (DirectorySSIF != null) + { + FileInfo[] files = DirectorySSIF.GetFiles("*.ssif"); + if (files.Length == 0) + { + files = DirectorySSIF.GetFiles("*.SSIF"); + } + foreach (FileInfo file in files) + { + InterleavedFiles.Add( + file.Name.ToUpper(), new TSInterleavedFile(file)); + } + } + } + + public void Scan() + { + List<TSStreamClipFile> errorStreamClipFiles = new List<TSStreamClipFile>(); + foreach (TSStreamClipFile streamClipFile in StreamClipFiles.Values) + { + try + { + streamClipFile.Scan(); + } + catch (Exception ex) + { + errorStreamClipFiles.Add(streamClipFile); + if (StreamClipFileScanError != null) + { + if (StreamClipFileScanError(streamClipFile, ex)) + { + continue; + } + else + { + break; + } + } + else throw ex; + } + } + + foreach (TSStreamFile 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); + + List<TSPlaylistFile> errorPlaylistFiles = new List<TSPlaylistFile>(); + foreach (TSPlaylistFile playlistFile in PlaylistFiles.Values) + { + try + { + playlistFile.Scan(StreamFiles, StreamClipFiles); + } + catch (Exception ex) + { + errorPlaylistFiles.Add(playlistFile); + if (PlaylistFileScanError != null) + { + if (PlaylistFileScanError(playlistFile, ex)) + { + continue; + } + else + { + break; + } + } + else throw ex; + } + } + + List<TSStreamFile> errorStreamFiles = new List<TSStreamFile>(); + foreach (TSStreamFile streamFile in streamFiles) + { + try + { + List<TSPlaylistFile> playlists = new List<TSPlaylistFile>(); + foreach (TSPlaylistFile playlist in PlaylistFiles.Values) + { + foreach (TSStreamClip streamClip in playlist.StreamClips) + { + if (streamClip.Name == streamFile.Name) + { + playlists.Add(playlist); + break; + } + } + } + streamFile.Scan(playlists, false); + } + catch (Exception ex) + { + errorStreamFiles.Add(streamFile); + if (StreamFileScanError != null) + { + if (StreamFileScanError(streamFile, ex)) + { + continue; + } + else + { + break; + } + } + else throw ex; + } + } + + foreach (TSPlaylistFile playlistFile in PlaylistFiles.Values) + { + playlistFile.Initialize(); + if (!Is50Hz) + { + foreach (TSVideoStream videoStream in playlistFile.VideoStreams) + { + if (videoStream.FrameRate == TSFrameRate.FRAMERATE_25 || + videoStream.FrameRate == TSFrameRate.FRAMERATE_50) + { + Is50Hz = true; + } + } + } + } + } + + private DirectoryInfo GetDirectoryBDMV( + string path) + { + DirectoryInfo dir = new DirectoryInfo(path); + + while (dir != null) + { + if (dir.Name == "BDMV") + { + return dir; + } + dir = dir.Parent; + } + + return GetDirectory("BDMV", new DirectoryInfo(path), 0); + } + + private DirectoryInfo GetDirectory( + string name, + DirectoryInfo dir, + int searchDepth) + { + if (dir != null) + { + DirectoryInfo[] children = dir.GetDirectories(); + foreach (DirectoryInfo child in children) + { + if (child.Name == name) + { + return child; + } + } + if (searchDepth > 0) + { + foreach (DirectoryInfo child in children) + { + GetDirectory( + name, child, searchDepth - 1); + } + } + } + return null; + } + + private long GetDirectorySize(DirectoryInfo directoryInfo) + { + long size = 0; + + //if (!ExcludeDirs.Contains(directoryInfo.Name.ToUpper())) // TODO: Keep? + { + FileInfo[] pathFiles = directoryInfo.GetFiles(); + foreach (FileInfo pathFile in pathFiles) + { + if (pathFile.Extension.ToUpper() == ".SSIF") + { + continue; + } + size += pathFile.Length; + } + + DirectoryInfo[] pathChildren = directoryInfo.GetDirectories(); + foreach (DirectoryInfo pathChild in pathChildren) + { + size += GetDirectorySize(pathChild); + } + } + + return size; + } + + private string GetVolumeLabel(DirectoryInfo dir) + { + return dir.Name; + } + + public static 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; + } + } + } + + } +} |
