more steps to make provider project portable

pull/702/head
Luke Pulverenti 8 years ago
parent 0189f4c49d
commit 3d7f75eea3

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{88AE38DF-19D7-406F-A6A9-09527719A21E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BDInfo</RootNamespace>
<AssemblyName>BDInfo</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<None Include="project.json" />
<!-- A reference to the entire .NET Framework is automatically included -->
</ItemGroup>
<ItemGroup>
<Compile Include="BDInfoSettings.cs" />
<Compile Include="BDROM.cs" />
<Compile Include="BitVector32.cs" />
<Compile Include="LanguageCodes.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TSCodecAC3.cs" />
<Compile Include="TSCodecAVC.cs" />
<Compile Include="TSCodecDTS.cs" />
<Compile Include="TSCodecDTSHD.cs" />
<Compile Include="TSCodecLPCM.cs" />
<Compile Include="TSCodecMPEG2.cs" />
<Compile Include="TSCodecMVC.cs" />
<Compile Include="TSCodecTrueHD.cs" />
<Compile Include="TSCodecVC1.cs" />
<Compile Include="TSInterleavedFile.cs" />
<Compile Include="TSPlaylistFile.cs" />
<Compile Include="TSStream.cs" />
<Compile Include="TSStreamBuffer.cs" />
<Compile Include="TSStreamClip.cs" />
<Compile Include="TSStreamClipFile.cs" />
<Compile Include="TSStreamFile.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>if $(ConfigurationName) == Release (
xcopy "$(TargetPath)" "$(SolutionDir)\Nuget\dlls\" /y /d /r /i
)</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

@ -0,0 +1,105 @@

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

@ -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;
}
}
}
}
}

@ -0,0 +1,314 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BDInfo
{
using System.Diagnostics;
using System.Text;
using System;
using Microsoft.Win32;
/// <devdoc>
/// <para>Provides a simple light bit vector with easy integer or Boolean access to
/// a 32 bit storage.</para>
/// </devdoc>
public struct BitVector32
{
private uint data;
/// <devdoc>
/// <para>Initializes a new instance of the BitVector32 structure with the specified internal data.</para>
/// </devdoc>
public BitVector32(int data)
{
this.data = (uint)data;
}
/// <devdoc>
/// <para>Initializes a new instance of the BitVector32 structure with the information in the specified
/// value.</para>
/// </devdoc>
public BitVector32(BitVector32 value)
{
this.data = value.data;
}
/// <devdoc>
/// <para>Gets or sets a value indicating whether all the specified bits are set.</para>
/// </devdoc>
public bool this[int bit]
{
get
{
return (data & bit) == (uint)bit;
}
set
{
if (value)
{
data |= (uint)bit;
}
else
{
data &= ~(uint)bit;
}
}
}
/// <devdoc>
/// <para>Gets or sets the value for the specified section.</para>
/// </devdoc>
public int this[Section section]
{
get
{
return (int)((data & (uint)(section.Mask << section.Offset)) >> section.Offset);
}
set
{
#if DEBUG
if ((value & section.Mask) != value) {
Debug.Fail("Value out of bounds on BitVector32 Section Set!");
}
#endif
value <<= section.Offset;
int offsetMask = (0xFFFF & (int)section.Mask) << section.Offset;
data = (data & ~(uint)offsetMask) | ((uint)value & (uint)offsetMask);
}
}
/// <devdoc>
/// returns the raw data stored in this bit vector...
/// </devdoc>
public int Data
{
get
{
return (int)data;
}
}
private static short CountBitsSet(short mask)
{
// yes, I know there are better algorithms, however, we know the
// bits are always right aligned, with no holes (i.e. always 00000111,
// never 000100011), so this is just fine...
//
short value = 0;
while ((mask & 0x1) != 0)
{
value++;
mask >>= 1;
}
return value;
}
/// <devdoc>
/// <para> Creates the first mask in a series.</para>
/// </devdoc>
public static int CreateMask()
{
return CreateMask(0);
}
/// <devdoc>
/// Creates the next mask in a series.
/// </devdoc>
public static int CreateMask(int previous)
{
if (previous == 0)
{
return 1;
}
if (previous == unchecked((int)0x80000000))
{
throw new InvalidOperationException("Bit vector full");
}
return previous << 1;
}
/// <devdoc>
/// Given a highValue, creates the mask
/// </devdoc>
private static short CreateMaskFromHighValue(short highValue)
{
short required = 16;
while ((highValue & 0x8000) == 0)
{
required--;
highValue <<= 1;
}
ushort value = 0;
while (required > 0)
{
required--;
value <<= 1;
value |= 0x1;
}
return unchecked((short)value);
}
/// <devdoc>
/// <para>Creates the first section in a series, with the specified maximum value.</para>
/// </devdoc>
public static Section CreateSection(short maxValue)
{
return CreateSectionHelper(maxValue, 0, 0);
}
/// <devdoc>
/// <para>Creates the next section in a series, with the specified maximum value.</para>
/// </devdoc>
public static Section CreateSection(short maxValue, Section previous)
{
return CreateSectionHelper(maxValue, previous.Mask, previous.Offset);
}
private static Section CreateSectionHelper(short maxValue, short priorMask, short priorOffset)
{
if (maxValue < 1)
{
throw new ArgumentOutOfRangeException("maxValue");
}
#if DEBUG
int maskCheck = CreateMaskFromHighValue(maxValue);
int offsetCheck = priorOffset + CountBitsSet(priorMask);
Debug.Assert(maskCheck <= short.MaxValue && offsetCheck < 32, "Overflow on BitVector32");
#endif
short offset = (short)(priorOffset + CountBitsSet(priorMask));
if (offset >= 32)
{
throw new InvalidOperationException("Bit vector full");
}
return new Section(CreateMaskFromHighValue(maxValue), offset);
}
public override bool Equals(object o)
{
if (!(o is BitVector32))
{
return false;
}
return data == ((BitVector32)o).data;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
/// <devdoc>
/// </devdoc>
public static string ToString(BitVector32 value)
{
StringBuilder sb = new StringBuilder(/*"BitVector32{".Length*/12 + /*32 bits*/32 + /*"}".Length"*/1);
sb.Append("BitVector32{");
int locdata = (int)value.data;
for (int i = 0; i < 32; i++)
{
if ((locdata & 0x80000000) != 0)
{
sb.Append("1");
}
else
{
sb.Append("0");
}
locdata <<= 1;
}
sb.Append("}");
return sb.ToString();
}
/// <devdoc>
/// </devdoc>
public override string ToString()
{
return BitVector32.ToString(this);
}
/// <devdoc>
/// <para>
/// Represents an section of the vector that can contain a integer number.</para>
/// </devdoc>
public struct Section
{
private readonly short mask;
private readonly short offset;
internal Section(short mask, short offset)
{
this.mask = mask;
this.offset = offset;
}
public short Mask
{
get
{
return mask;
}
}
public short Offset
{
get
{
return offset;
}
}
public override bool Equals(object o)
{
if (o is Section)
return Equals((Section)o);
else
return false;
}
public bool Equals(Section obj)
{
return obj.mask == mask && obj.offset == offset;
}
public static bool operator ==(Section a, Section b)
{
return a.Equals(b);
}
public static bool operator !=(Section a, Section b)
{
return !(a == b);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
/// <devdoc>
/// </devdoc>
public static string ToString(Section value)
{
return "Section{0x" + Convert.ToString(value.Mask, 16) + ", 0x" + Convert.ToString(value.Offset, 16) + "}";
}
/// <devdoc>
/// </devdoc>
public override string ToString()
{
return Section.ToString(this);
}
}
}
}

@ -0,0 +1,493 @@
//============================================================================
// 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,0 +1,29 @@
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("BDInfo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BDInfo")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1")]

@ -0,0 +1,5 @@
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,0 +1,309 @@
//============================================================================
// 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,0 +1,148 @@
//============================================================================
// 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,0 +1,159 @@
//============================================================================
// 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,0 +1,246 @@
//============================================================================
// 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)
{
TSAudioStream 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,0 +1,123 @@
//============================================================================
// 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,0 +1,208 @@
//============================================================================
// 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,0 +1,36 @@
//============================================================================
// 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,0 +1,186 @@
//============================================================================
// 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,0 +1,131 @@
//============================================================================
// 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,0 +1,37 @@
//============================================================================
// 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.IO;
// TODO: Do more interesting things here...
namespace BDInfo
{
public class TSInterleavedFile
{
public FileInfo FileInfo = null;
public string Name = null;
public TSInterleavedFile(FileInfo fileInfo)
{
FileInfo = fileInfo;
Name = fileInfo.Name.ToUpper();
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,801 @@
//============================================================================
// 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()
{
TSDescriptor 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
{
get
{
return PacketCount * 192;
}
}
private string _LanguageCode;
public string LanguageCode
{
get
{
return _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
{
get
{
return "";
}
}
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 (TSDescriptor 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
{
return _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
{
return _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()
{
TSVideoStream 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()
{
TSAudioStream 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()
{
TSGraphicsStream stream = new TSGraphicsStream();
CopyTo(stream);
return stream;
}
}
public class TSTextStream : TSStream
{
public TSTextStream()
{
IsVBR = true;
IsInitialized = true;
}
public override TSStream Clone()
{
TSTextStream stream = new TSTextStream();
CopyTo(stream);
return stream;
}
}
}

@ -0,0 +1,142 @@
//============================================================================
// 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
{
get
{
return (long)BufferLength;
}
}
public long Position
{
get
{
return 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;
}
BitVector32 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,0 +1,113 @@
//============================================================================
// 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
{
get
{
return 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 (TSStream stream1 in StreamFile.Streams.Values)
{
if (clip.StreamFile.Streams.ContainsKey(stream1.PID))
{
TSStream stream2 = clip.StreamFile.Streams[stream1.PID];
if (stream1.StreamType != stream2.StreamType)
{
return false;
}
}
}
return true;
}
}
}

@ -0,0 +1,247 @@
//============================================================================
// 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;
namespace BDInfo
{
public class TSStreamClipFile
{
public FileInfo 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(
FileInfo fileInfo)
{
FileInfo = fileInfo;
Name = fileInfo.Name.ToUpper();
}
public void Scan()
{
FileStream 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 = ASCIIEncoding.ASCII.GetString(fileType);
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;
TSStreamType 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:
{
TSVideoFormat videoFormat = (TSVideoFormat)
(clipData[streamOffset + 2] >> 4);
TSFrameRate frameRate = (TSFrameRate)
(clipData[streamOffset + 2] & 0xF);
TSAspectRatio 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 =
ASCIIEncoding.ASCII.GetString(languageBytes);
TSChannelLayout channelLayout = (TSChannelLayout)
(clipData[streamOffset + 2] >> 4);
TSSampleRate 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 =
ASCIIEncoding.ASCII.GetString(languageBytes);
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 =
ASCIIEncoding.ASCII.GetString(languageBytes);
#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();
}
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,16 @@
{
"supports": {
"net46.app": {},
"uwp.10.0.app": {},
"dnxcore50.app": {}
},
"dependencies": {
"Microsoft.NETCore": "5.0.0",
"Microsoft.NETCore.Portable.Compatibility": "1.0.0"
},
"frameworks": {
"dotnet": {
"imports": "portable-net452+win81"
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace DvdLib
{
public class BigEndianBinaryReader : BinaryReader
{
public BigEndianBinaryReader(Stream input)
: base(input)
{
}
public override ushort ReadUInt16()
{
return BitConverter.ToUInt16(ReadAndReverseBytes(2), 0);
}
public override uint ReadUInt32()
{
return BitConverter.ToUInt32(ReadAndReverseBytes(4), 0);
}
private byte[] ReadAndReverseBytes(int count)
{
byte[] val = base.ReadBytes(count);
Array.Reverse(val, 0, count);
return val;
}
}
}

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{713F42B5-878E-499D-A878-E4C652B1D5E8}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DvdLib</RootNamespace>
<AssemblyName>DvdLib</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<None Include="project.json" />
<!-- A reference to the entire .NET Framework is automatically included -->
</ItemGroup>
<ItemGroup>
<Compile Include="BigEndianBinaryReader.cs" />
<Compile Include="Ifo\AudioAttributes.cs" />
<Compile Include="Ifo\Cell.cs" />
<Compile Include="Ifo\CellPlaybackInfo.cs" />
<Compile Include="Ifo\CellPositionInfo.cs" />
<Compile Include="Ifo\Chapter.cs" />
<Compile Include="Ifo\Dvd.cs" />
<Compile Include="Ifo\DvdTime.cs" />
<Compile Include="Ifo\PgcCommandTable.cs" />
<Compile Include="Ifo\Program.cs" />
<Compile Include="Ifo\ProgramChain.cs" />
<Compile Include="Ifo\Title.cs" />
<Compile Include="Ifo\UserOperation.cs" />
<Compile Include="Ifo\VideoAttributes.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
<Name>MediaBrowser.Model</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>if $(ConfigurationName) == Release (
xcopy "$(TargetPath)" "$(SolutionDir)\Nuget\dlls\" /y /d /r /i
)</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="EmitMSBuildWarning" BeforeTargets="Build">
<Warning Text="Packages containing MSBuild targets and props files cannot be fully installed in projects targeting multiple frameworks. The MSBuild targets and props files have been ignored." />
</Target>
</Project>

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DvdLib.Ifo
{
public enum AudioCodec
{
AC3 = 0,
MPEG1 = 2,
MPEG2ext = 3,
LPCM = 4,
DTS = 6,
}
public enum ApplicationMode
{
Unspecified = 0,
Karaoke = 1,
Surround = 2,
}
public class AudioAttributes
{
public readonly AudioCodec Codec;
public readonly bool MultichannelExtensionPresent;
public readonly ApplicationMode Mode;
public readonly byte QuantDRC;
public readonly byte SampleRate;
public readonly byte Channels;
public readonly ushort LanguageCode;
public readonly byte LanguageExtension;
public readonly byte CodeExtension;
}
public class MultiChannelExtension
{
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace DvdLib.Ifo
{
public class Cell
{
public CellPlaybackInfo PlaybackInfo { get; private set; }
public CellPositionInfo PositionInfo { get; private set; }
internal void ParsePlayback(BinaryReader br)
{
PlaybackInfo = new CellPlaybackInfo(br);
}
internal void ParsePosition(BinaryReader br)
{
PositionInfo = new CellPositionInfo(br);
}
}
}

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace DvdLib.Ifo
{
public enum BlockMode
{
NotInBlock = 0,
FirstCell = 1,
InBlock = 2,
LastCell = 3,
}
public enum BlockType
{
Normal = 0,
Angle = 1,
}
public enum PlaybackMode
{
Normal = 0,
StillAfterEachVOBU = 1,
}
public class CellPlaybackInfo
{
public readonly BlockMode Mode;
public readonly BlockType Type;
public readonly bool SeamlessPlay;
public readonly bool Interleaved;
public readonly bool STCDiscontinuity;
public readonly bool SeamlessAngle;
public readonly PlaybackMode PlaybackMode;
public readonly bool Restricted;
public readonly byte StillTime;
public readonly byte CommandNumber;
public readonly DvdTime PlaybackTime;
public readonly uint FirstSector;
public readonly uint FirstILVUEndSector;
public readonly uint LastVOBUStartSector;
public readonly uint LastSector;
internal CellPlaybackInfo(BinaryReader br)
{
br.BaseStream.Seek(0x4, SeekOrigin.Current);
PlaybackTime = new DvdTime(br.ReadBytes(4));
br.BaseStream.Seek(0x10, SeekOrigin.Current);
}
}
}

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace DvdLib.Ifo
{
public class CellPositionInfo
{
public readonly ushort VOBId;
public readonly byte CellId;
internal CellPositionInfo(BinaryReader br)
{
VOBId = br.ReadUInt16();
br.ReadByte();
CellId = br.ReadByte();
}
}
}

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DvdLib.Ifo
{
public class Chapter
{
public ushort ProgramChainNumber { get; private set; }
public ushort ProgramNumber { get; private set; }
public uint ChapterNumber { get; private set; }
public Chapter(ushort pgcNum, ushort programNum, uint chapterNum)
{
ProgramChainNumber = pgcNum;
ProgramNumber = programNum;
ChapterNumber = chapterNum;
}
}
}

@ -0,0 +1,161 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using MediaBrowser.Model.IO;
namespace DvdLib.Ifo
{
public class Dvd
{
private readonly ushort _titleSetCount;
public readonly List<Title> Titles;
private ushort _titleCount;
public readonly Dictionary<ushort, string> VTSPaths = new Dictionary<ushort, string>();
private readonly IFileSystem _fileSystem;
public Dvd(string path, IFileSystem fileSystem)
{
_fileSystem = fileSystem;
Titles = new List<Title>();
var allFiles = _fileSystem.GetFiles(path, true).ToList();
var vmgPath = allFiles.FirstOrDefault(i => string.Equals(i.Name, "VIDEO_TS.IFO", StringComparison.OrdinalIgnoreCase)) ??
allFiles.FirstOrDefault(i => string.Equals(i.Name, "VIDEO_TS.BUP", StringComparison.OrdinalIgnoreCase));
if (vmgPath == null)
{
var allIfos = allFiles.Where(i => string.Equals(i.Extension, ".ifo", StringComparison.OrdinalIgnoreCase));
foreach (var ifo in allIfos)
{
var num = ifo.Name.Split('_').ElementAtOrDefault(1);
ushort ifoNumber;
var numbersRead = new List<ushort>();
if (!string.IsNullOrEmpty(num) && ushort.TryParse(num, out ifoNumber) && !numbersRead.Contains(ifoNumber))
{
ReadVTS(ifoNumber, ifo.FullName);
numbersRead.Add(ifoNumber);
}
}
}
else
{
using (var vmgFs = _fileSystem.GetFileStream(vmgPath.FullName, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read))
{
using (BigEndianBinaryReader vmgRead = new BigEndianBinaryReader(vmgFs))
{
vmgFs.Seek(0x3E, SeekOrigin.Begin);
_titleSetCount = vmgRead.ReadUInt16();
// read address of TT_SRPT
vmgFs.Seek(0xC4, SeekOrigin.Begin);
uint ttSectorPtr = vmgRead.ReadUInt32();
vmgFs.Seek(ttSectorPtr * 2048, SeekOrigin.Begin);
ReadTT_SRPT(vmgRead);
}
}
for (ushort titleSetNum = 1; titleSetNum <= _titleSetCount; titleSetNum++)
{
ReadVTS(titleSetNum, allFiles);
}
}
}
private void ReadTT_SRPT(BinaryReader read)
{
_titleCount = read.ReadUInt16();
read.BaseStream.Seek(6, SeekOrigin.Current);
for (uint titleNum = 1; titleNum <= _titleCount; titleNum++)
{
Title t = new Title(titleNum);
t.ParseTT_SRPT(read);
Titles.Add(t);
}
}
private void ReadVTS(ushort vtsNum, List<FileSystemMetadata> allFiles)
{
var filename = String.Format("VTS_{0:00}_0.IFO", vtsNum);
var vtsPath = allFiles.FirstOrDefault(i => string.Equals(i.Name, filename, StringComparison.OrdinalIgnoreCase)) ??
allFiles.FirstOrDefault(i => string.Equals(i.Name, Path.ChangeExtension(filename, ".bup"), StringComparison.OrdinalIgnoreCase));
if (vtsPath == null)
{
throw new FileNotFoundException("Unable to find VTS IFO file");
}
ReadVTS(vtsNum, vtsPath.FullName);
}
private void ReadVTS(ushort vtsNum, string vtsPath)
{
VTSPaths[vtsNum] = vtsPath;
using (var vtsFs = _fileSystem.GetFileStream(vtsPath, FileOpenMode.Open, FileAccessMode.Read, FileShareMode.Read))
{
using (BigEndianBinaryReader vtsRead = new BigEndianBinaryReader(vtsFs))
{
// Read VTS_PTT_SRPT
vtsFs.Seek(0xC8, SeekOrigin.Begin);
uint vtsPttSrptSecPtr = vtsRead.ReadUInt32();
uint baseAddr = (vtsPttSrptSecPtr * 2048);
vtsFs.Seek(baseAddr, SeekOrigin.Begin);
ushort numTitles = vtsRead.ReadUInt16();
vtsRead.ReadUInt16();
uint endaddr = vtsRead.ReadUInt32();
uint[] offsets = new uint[numTitles];
for (ushort titleNum = 0; titleNum < numTitles; titleNum++)
{
offsets[titleNum] = vtsRead.ReadUInt32();
}
for (uint titleNum = 0; titleNum < numTitles; titleNum++)
{
uint chapNum = 1;
vtsFs.Seek(baseAddr + offsets[titleNum], SeekOrigin.Begin);
Title t = Titles.FirstOrDefault(vtst => vtst.IsVTSTitle(vtsNum, titleNum + 1));
if (t == null) continue;
do
{
t.Chapters.Add(new Chapter(vtsRead.ReadUInt16(), vtsRead.ReadUInt16(), chapNum));
if (titleNum + 1 < numTitles && vtsFs.Position == (baseAddr + offsets[titleNum + 1])) break;
chapNum++;
}
while (vtsFs.Position < (baseAddr + endaddr));
}
// Read VTS_PGCI
vtsFs.Seek(0xCC, SeekOrigin.Begin);
uint vtsPgciSecPtr = vtsRead.ReadUInt32();
vtsFs.Seek(vtsPgciSecPtr * 2048, SeekOrigin.Begin);
long startByte = vtsFs.Position;
ushort numPgcs = vtsRead.ReadUInt16();
vtsFs.Seek(6, SeekOrigin.Current);
for (ushort pgcNum = 1; pgcNum <= numPgcs; pgcNum++)
{
byte pgcCat = vtsRead.ReadByte();
bool entryPgc = (pgcCat & 0x80) != 0;
uint titleNum = (uint)(pgcCat & 0x7F);
vtsFs.Seek(3, SeekOrigin.Current);
uint vtsPgcOffset = vtsRead.ReadUInt32();
Title t = Titles.FirstOrDefault(vtst => vtst.IsVTSTitle(vtsNum, titleNum));
if (t != null) t.AddPgc(vtsRead, startByte + vtsPgcOffset, entryPgc, pgcNum);
}
}
}
}
}
}

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DvdLib.Ifo
{
public class DvdTime
{
public readonly byte Hour, Minute, Second, Frames, FrameRate;
public DvdTime(byte[] data)
{
Hour = GetBCDValue(data[0]);
Minute = GetBCDValue(data[1]);
Second = GetBCDValue(data[2]);
Frames = GetBCDValue((byte)(data[3] & 0x3F));
if ((data[3] & 0x80) != 0) FrameRate = 30;
else if ((data[3] & 0x40) != 0) FrameRate = 25;
}
private byte GetBCDValue(byte data)
{
return (byte)((((data & 0xF0) >> 4) * 10) + (data & 0x0F));
}
public static explicit operator TimeSpan(DvdTime time)
{
int ms = (int)(((1.0 / (double)time.FrameRate) * time.Frames) * 1000.0);
return new TimeSpan(0, time.Hour, time.Minute, time.Second, ms);
}
}
}

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DvdLib.Ifo
{
public class ProgramChainCommandTable
{
public readonly ushort LastByteAddress;
public readonly List<VirtualMachineCommand> PreCommands;
public readonly List<VirtualMachineCommand> PostCommands;
public readonly List<VirtualMachineCommand> CellCommands;
}
public class VirtualMachineCommand
{
public readonly byte[] Command;
}
}

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DvdLib.Ifo
{
public class Program
{
public readonly List<Cell> Cells;
public Program(List<Cell> cells)
{
Cells = cells;
}
}
}

@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace DvdLib.Ifo
{
public enum ProgramPlaybackMode
{
Sequential,
Random,
Shuffle
}
public class ProgramChain
{
private ushort _unknown1;
private byte _programCount;
public readonly List<Program> Programs;
private byte _cellCount;
public readonly List<Cell> Cells;
public DvdTime PlaybackTime { get; private set; }
public UserOperation ProhibitedUserOperations { get; private set; }
public byte[] AudioStreamControl { get; private set; } // 8*2 entries
public byte[] SubpictureStreamControl { get; private set; } // 32*4 entries
private ushort _nextProgramNumber;
public readonly ProgramChain Next;
private ushort _prevProgramNumber;
public readonly ProgramChain Previous;
private ushort _goupProgramNumber;
public readonly ProgramChain Goup; // ?? maybe Group
private byte _playbackMode;
public ProgramPlaybackMode PlaybackMode { get; private set; }
public uint ProgramCount { get; private set; }
public byte StillTime { get; private set; }
public byte[] Palette { get; private set; } // 16*4 entries
private ushort _commandTableOffset;
public readonly ProgramChainCommandTable CommandTable;
private ushort _programMapOffset;
private ushort _cellPlaybackOffset;
private ushort _cellPositionOffset;
public readonly uint VideoTitleSetIndex;
internal ProgramChain(uint vtsPgcNum)
{
VideoTitleSetIndex = vtsPgcNum;
Cells = new List<Cell>();
Programs = new List<Program>();
}
internal void ParseHeader(BinaryReader br)
{
long startPos = br.BaseStream.Position;
br.ReadUInt16();
_programCount = br.ReadByte();
_cellCount = br.ReadByte();
PlaybackTime = new DvdTime(br.ReadBytes(4));
ProhibitedUserOperations = (UserOperation)br.ReadUInt32();
AudioStreamControl = br.ReadBytes(16);
SubpictureStreamControl = br.ReadBytes(128);
_nextProgramNumber = br.ReadUInt16();
_prevProgramNumber = br.ReadUInt16();
_goupProgramNumber = br.ReadUInt16();
StillTime = br.ReadByte();
byte pbMode = br.ReadByte();
if (pbMode == 0) PlaybackMode = ProgramPlaybackMode.Sequential;
else PlaybackMode = ((pbMode & 0x80) == 0) ? ProgramPlaybackMode.Random : ProgramPlaybackMode.Shuffle;
ProgramCount = (uint)(pbMode & 0x7F);
Palette = br.ReadBytes(64);
_commandTableOffset = br.ReadUInt16();
_programMapOffset = br.ReadUInt16();
_cellPlaybackOffset = br.ReadUInt16();
_cellPositionOffset = br.ReadUInt16();
// read position info
br.BaseStream.Seek(startPos + _cellPositionOffset, SeekOrigin.Begin);
for (int cellNum = 0; cellNum < _cellCount; cellNum++)
{
Cell c = new Cell();
c.ParsePosition(br);
Cells.Add(c);
}
br.BaseStream.Seek(startPos + _cellPlaybackOffset, SeekOrigin.Begin);
for (int cellNum = 0; cellNum < _cellCount; cellNum++)
{
Cells[cellNum].ParsePlayback(br);
}
br.BaseStream.Seek(startPos + _programMapOffset, SeekOrigin.Begin);
List<int> cellNumbers = new List<int>();
for (int progNum = 0; progNum < _programCount; progNum++) cellNumbers.Add(br.ReadByte() - 1);
for (int i = 0; i < cellNumbers.Count; i++)
{
int max = (i + 1 == cellNumbers.Count) ? _cellCount : cellNumbers[i+1];
Programs.Add(new Program(Cells.Where((c, idx) => idx >= cellNumbers[i] && idx < max).ToList()));
}
}
}
}

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace DvdLib.Ifo
{
public class Title
{
public uint TitleNumber { get; private set; }
public uint AngleCount { get; private set; }
public ushort ChapterCount { get; private set; }
public byte VideoTitleSetNumber { get; private set; }
private ushort _parentalManagementMask;
private byte _titleNumberInVTS;
private uint _vtsStartSector; // relative to start of entire disk
public ProgramChain EntryProgramChain { get; private set; }
public readonly List<ProgramChain> ProgramChains;
public readonly List<Chapter> Chapters;
public Title(uint titleNum)
{
ProgramChains = new List<ProgramChain>();
Chapters = new List<Chapter>();
Chapters = new List<Chapter>();
TitleNumber = titleNum;
}
public bool IsVTSTitle(uint vtsNum, uint vtsTitleNum)
{
return (vtsNum == VideoTitleSetNumber && vtsTitleNum == _titleNumberInVTS);
}
internal void ParseTT_SRPT(BinaryReader br)
{
byte titleType = br.ReadByte();
// TODO parse Title Type
AngleCount = br.ReadByte();
ChapterCount = br.ReadUInt16();
_parentalManagementMask = br.ReadUInt16();
VideoTitleSetNumber = br.ReadByte();
_titleNumberInVTS = br.ReadByte();
_vtsStartSector = br.ReadUInt32();
}
internal void AddPgc(BinaryReader br, long startByte, bool entryPgc, uint pgcNum)
{
long curPos = br.BaseStream.Position;
br.BaseStream.Seek(startByte, SeekOrigin.Begin);
ProgramChain pgc = new ProgramChain(pgcNum);
pgc.ParseHeader(br);
ProgramChains.Add(pgc);
if (entryPgc) EntryProgramChain = pgc;
br.BaseStream.Seek(curPos, SeekOrigin.Begin);
}
}
}

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DvdLib.Ifo
{
[Flags]
public enum UserOperation
{
None = 0,
TitleOrTimePlay = 1,
ChapterSearchOrPlay = 2,
TitlePlay = 4,
Stop = 8,
GoUp = 16,
TimeOrChapterSearch = 32,
PrevOrTopProgramSearch = 64,
NextProgramSearch = 128,
ForwardScan = 256,
BackwardScan = 512,
TitleMenuCall = 1024,
RootMenuCall = 2048,
SubpictureMenuCall = 4096,
AudioMenuCall = 8192,
AngleMenuCall = 16384,
ChapterMenuCall = 32768,
Resume = 65536,
ButtonSelectOrActive = 131072,
StillOff = 262144,
PauseOn = 524288,
AudioStreamChange = 1048576,
SubpictureStreamChange = 2097152,
AngleChange = 4194304,
KaraokeAudioPresentationModeChange = 8388608,
VideoPresentationModeChange = 16777216,
}
}

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DvdLib.Ifo
{
public enum VideoCodec
{
MPEG1 = 0,
MPEG2 = 1,
}
public enum VideoFormat
{
NTSC = 0,
PAL = 1,
}
public enum AspectRatio
{
ar4to3 = 0,
ar16to9 = 3
}
public enum FilmMode
{
None = -1,
Camera = 0,
Film = 1,
}
public class VideoAttributes
{
public readonly VideoCodec Codec;
public readonly VideoFormat Format;
public readonly AspectRatio Aspect;
public readonly bool AutomaticPanScan;
public readonly bool AutomaticLetterBox;
public readonly bool Line21CCField1;
public readonly bool Line21CCField2;
public readonly int Width;
public readonly int Height;
public readonly bool Letterboxed;
public readonly FilmMode FilmMode;
public VideoAttributes()
{
}
}
}

@ -0,0 +1,29 @@
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DvdLib")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DvdLib")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.1")]

@ -0,0 +1,16 @@
{
"frameworks": {
"netstandard1.6": {
"dependencies": {
"NETStandard.Library": "1.6.0"
}
},
".NETPortable,Version=v4.5,Profile=Profile7": {
"buildOptions": {
"define": []
},
"frameworkAssemblies": {}
}
},
"dependencies": {}
}

File diff suppressed because it is too large Load Diff

@ -37,14 +37,6 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="BDInfo, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.1\lib\portable-net46+win10\BDInfo.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="DvdLib, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.1\lib\portable-net46+win10\DvdLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@ -91,6 +83,10 @@
<Compile Include="Subtitles\VttWriter.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\BdInfo\BDInfo\BDInfo.csproj">
<Project>{88ae38df-19d7-406f-a6a9-09527719a21e}</Project>
<Name>BDInfo</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
<Name>MediaBrowser.Common</Name>
@ -108,9 +104,6 @@
<Name>OpenSubtitlesHandler</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Probing\whitelist.txt" />
</ItemGroup>

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MediaBrowser.BdInfo" version="1.0.1" targetFramework="net46" />
</packages>

@ -42,14 +42,6 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="BDInfo, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.1\lib\portable-net46+win10\BDInfo.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="DvdLib, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.1\lib\portable-net46+win10\DvdLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net" />
@ -139,6 +131,7 @@
<Compile Include="TV\FanArt\FanArtSeasonProvider.cs" />
<Compile Include="TV\FanArt\FanartSeriesProvider.cs" />
<Compile Include="TV\MissingEpisodeProvider.cs" />
<Compile Include="TV\SeriesPostScanTask.cs" />
<Compile Include="TV\TheMovieDb\MovieDbProviderBase.cs" />
<Compile Include="TV\TheMovieDb\MovieDbEpisodeImageProvider.cs" />
<Compile Include="TV\TheMovieDb\MovieDbSeasonProvider.cs" />
@ -154,7 +147,6 @@
<Compile Include="TV\SeasonMetadataService.cs" />
<Compile Include="TV\TheTVDB\TvdbEpisodeProvider.cs" />
<Compile Include="TV\TheTVDB\TvdbSeriesProvider.cs" />
<Compile Include="TV\SeriesPostScanTask.cs" />
<Compile Include="TV\TheTVDB\TvdbPrescanTask.cs" />
<Compile Include="TV\TvExternalIds.cs" />
<Compile Include="Users\UserMetadataService.cs" />
@ -162,6 +154,10 @@
<Compile Include="Years\YearMetadataService.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DvdLib\DvdLib.csproj">
<Project>{713f42b5-878e-499d-a878-e4c652b1d5e8}</Project>
<Name>DvdLib</Name>
</ProjectReference>
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
<Project>{9142EEFA-7570-41E1-BFCC-468BB571AF2F}</Project>
<Name>MediaBrowser.Common</Name>
@ -175,9 +171,6 @@
<Name>MediaBrowser.Model</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

@ -607,7 +607,7 @@ namespace MediaBrowser.Providers.MediaInfo
private void FetchFromDvdLib(Video item, IIsoMount mount)
{
var path = mount == null ? item.Path : mount.MountedPath;
var dvd = new Dvd(path);
var dvd = new Dvd(path, _fileSystem);
var primaryTitle = dvd.Titles.OrderByDescending(GetRuntime).FirstOrDefault();

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MediaBrowser.BdInfo" version="1.0.1" targetFramework="net46" />
</packages>

@ -64,6 +64,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Nat", "Mono.Nat\Mono.N
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Emby.Photos", "Emby.Photos\Emby.Photos.csproj", "{89AB4548-770D-41FD-A891-8DAFF44F452C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DvdLib", "DvdLib\DvdLib.csproj", "{713F42B5-878E-499D-A878-E4C652B1D5E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BDInfo", "..\BdInfo\BDInfo\BDInfo.csproj", "{88AE38DF-19D7-406F-A6A9-09527719A21E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -540,6 +544,66 @@ Global
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|x64.Build.0 = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|x86.ActiveCfg = Release|Any CPU
{89AB4548-770D-41FD-A891-8DAFF44F452C}.Release|x86.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Win32.ActiveCfg = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|Win32.Build.0 = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|x64.ActiveCfg = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|x64.Build.0 = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|x86.ActiveCfg = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Debug|x86.Build.0 = Debug|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|Mixed Platforms.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|Mixed Platforms.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|Win32.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|Win32.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|x64.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|x64.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|x86.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release Mono|x86.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Any CPU.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Win32.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|Win32.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|x64.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|x64.Build.0 = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|x86.ActiveCfg = Release|Any CPU
{713F42B5-878E-499D-A878-E4C652B1D5E8}.Release|x86.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Win32.ActiveCfg = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|Win32.Build.0 = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|x64.ActiveCfg = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|x64.Build.0 = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|x86.ActiveCfg = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Debug|x86.Build.0 = Debug|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|Any CPU.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|Any CPU.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|Mixed Platforms.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|Mixed Platforms.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|Win32.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|Win32.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|x64.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|x64.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|x86.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release Mono|x86.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Any CPU.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Win32.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|Win32.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|x64.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|x64.Build.0 = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|x86.ActiveCfg = Release|Any CPU
{88AE38DF-19D7-406F-A6A9-09527719A21E}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Loading…
Cancel
Save