parent
3d4b2f840a
commit
626bb24bdd
@ -1,25 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Buffers.Binary;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace DvdLib
|
|
||||||
{
|
|
||||||
public class BigEndianBinaryReader : BinaryReader
|
|
||||||
{
|
|
||||||
public BigEndianBinaryReader(Stream input)
|
|
||||||
: base(input)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override ushort ReadUInt16()
|
|
||||||
{
|
|
||||||
return BinaryPrimitives.ReadUInt16BigEndian(base.ReadBytes(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override uint ReadUInt32()
|
|
||||||
{
|
|
||||||
return BinaryPrimitives.ReadUInt32BigEndian(base.ReadBytes(4));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<!-- ProjectGuid is only included as a requirement for SonarQube analysis -->
|
|
||||||
<PropertyGroup>
|
|
||||||
<ProjectGuid>{713F42B5-878E-499D-A878-E4C652B1D5E8}</ProjectGuid>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="..\SharedVersion.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
|
||||||
<AnalysisMode>AllDisabledByDefault</AnalysisMode>
|
|
||||||
<Nullable>disable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
@ -1,23 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,167 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
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>();
|
|
||||||
public Dvd(string path)
|
|
||||||
{
|
|
||||||
Titles = new List<Title>();
|
|
||||||
var allFiles = new DirectoryInfo(path).GetFiles(path, SearchOption.AllDirectories);
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
foreach (var ifo in allFiles)
|
|
||||||
{
|
|
||||||
if (!string.Equals(ifo.Extension, ".ifo", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var nums = ifo.Name.Split('_', StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
if (nums.Length >= 2 && ushort.TryParse(nums[1], out var ifoNumber))
|
|
||||||
{
|
|
||||||
ReadVTS(ifoNumber, ifo.FullName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
using (var vmgFs = new FileStream(vmgPath.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
|
||||||
{
|
|
||||||
using (var 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++)
|
|
||||||
{
|
|
||||||
var t = new Title(titleNum);
|
|
||||||
t.ParseTT_SRPT(read);
|
|
||||||
Titles.Add(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ReadVTS(ushort vtsNum, IReadOnlyList<FileInfo> allFiles)
|
|
||||||
{
|
|
||||||
var filename = string.Format(CultureInfo.InvariantCulture, "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 = new FileStream(vtsPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
|
||||||
{
|
|
||||||
using (var 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);
|
|
||||||
var 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();
|
|
||||||
|
|
||||||
var t = Titles.FirstOrDefault(vtst => vtst.IsVTSTitle(vtsNum, titleNum));
|
|
||||||
if (t != null)
|
|
||||||
{
|
|
||||||
t.AddPgc(vtsRead, startByte + vtsPgcOffset, entryPgc, pgcNum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
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 static 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace DvdLib.Ifo
|
|
||||||
{
|
|
||||||
public class Program
|
|
||||||
{
|
|
||||||
public IReadOnlyList<Cell> Cells { get; }
|
|
||||||
|
|
||||||
public Program(List<Cell> cells)
|
|
||||||
{
|
|
||||||
Cells = cells;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,121 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace DvdLib.Ifo
|
|
||||||
{
|
|
||||||
public enum ProgramPlaybackMode
|
|
||||||
{
|
|
||||||
Sequential,
|
|
||||||
Random,
|
|
||||||
Shuffle
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ProgramChain
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
private ushort _prevProgramNumber;
|
|
||||||
|
|
||||||
private ushort _goupProgramNumber;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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++)
|
|
||||||
{
|
|
||||||
var 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);
|
|
||||||
var 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()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
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);
|
|
||||||
|
|
||||||
var pgc = new ProgramChain(pgcNum);
|
|
||||||
pgc.ParseHeader(br);
|
|
||||||
ProgramChains.Add(pgc);
|
|
||||||
if (entryPgc)
|
|
||||||
{
|
|
||||||
EntryProgramChain = pgc;
|
|
||||||
}
|
|
||||||
|
|
||||||
br.BaseStream.Seek(curPos, SeekOrigin.Begin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
|
||||||
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using System.Resources;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("DvdLib")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("Jellyfin Project")]
|
|
||||||
[assembly: AssemblyProduct("Jellyfin Server")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
[assembly: NeutralResourcesLanguage("en")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
Loading…
Reference in new issue