예제 #1
0
        public static IEnumerable <ChapterInfo> GetStreams(string ifoFile)
        {
            var pgcCount = IfoParser.GetPGCnb(ifoFile);

            for (var i = 1; i <= pgcCount; i++)
            {
                yield return(GetChapterInfo(ifoFile, i));
            }
        }
예제 #2
0
        private static List <Chapter> GetChapters(string ifoFile, int programChain, out IfoTimeSpan duration, out decimal fps)
        {
            var chapters = new List <Chapter>();

            duration = IfoTimeSpan.Zero;
            fps      = 0;

            var stream = new FileStream(ifoFile, FileMode.Open, FileAccess.Read, FileShare.Read);

            var     pcgItPosition        = stream.GetPCGIP_Position();
            var     programChainPrograms = -1;
            var     programTime          = TimeSpan.Zero;
            decimal fpsLocal;

            if (programChain >= 0)
            {
                var chainOffset = stream.GetChainOffset(pcgItPosition, programChain);
                programTime          = stream.ReadTimeSpan(pcgItPosition, chainOffset, out fpsLocal) ?? TimeSpan.Zero;
                programChainPrograms = stream.GetNumberOfPrograms(pcgItPosition, chainOffset);
            }
            else
            {
                var programChains = stream.GetProgramChains(pcgItPosition);
                for (var curChain = 1; curChain <= programChains; curChain++)
                {
                    var chainOffset = stream.GetChainOffset(pcgItPosition, curChain);
                    var time        = stream.ReadTimeSpan(pcgItPosition, chainOffset, out fpsLocal);
                    if (time == null)
                    {
                        break;
                    }

                    if (time.Value <= programTime)
                    {
                        continue;
                    }
                    programChain         = curChain;
                    programChainPrograms = stream.GetNumberOfPrograms(pcgItPosition, chainOffset);
                    programTime          = time.Value;
                }
            }
            if (programChain < 0)
            {
                return(null);
            }

            chapters.Add(new Chapter {
                Name = "Chapter 01", Time = TimeSpan.Zero
            });

            var longestChainOffset = stream.GetChainOffset(pcgItPosition, programChain);
            int programMapOffset   = IfoParser.ToInt16(stream.GetFileBlock((pcgItPosition + longestChainOffset) + 230, 2));
            int cellTableOffset    = IfoParser.ToInt16(stream.GetFileBlock((pcgItPosition + longestChainOffset) + 0xE8, 2));

            for (var currentProgram = 0; currentProgram < programChainPrograms; ++currentProgram)
            {
                int entryCell = stream.GetFileBlock(((pcgItPosition + longestChainOffset) + programMapOffset) + currentProgram, 1)[0];
                var exitCell  = entryCell;
                if (currentProgram < (programChainPrograms - 1))
                {
                    exitCell = stream.GetFileBlock(((pcgItPosition + longestChainOffset) + programMapOffset) + (currentProgram + 1), 1)[0] - 1;
                }

                var totalTime = IfoTimeSpan.Zero;
                for (var currentCell = entryCell; currentCell <= exitCell; currentCell++)
                {
                    var cellStart = cellTableOffset + ((currentCell - 1) * 0x18);
                    var bytes     = stream.GetFileBlock((pcgItPosition + longestChainOffset) + cellStart, 4);
                    var cellType  = bytes[0] >> 6;
                    if (cellType == 0x00 || cellType == 0x01)
                    {
                        bytes = stream.GetFileBlock(((pcgItPosition + longestChainOffset) + cellStart) + 4, 4);
                        var ret = IfoParser.ReadTimeSpan(bytes, out fps) ?? IfoTimeSpan.Zero;
                        totalTime.IsNTSC = ret.IsNTSC;
                        totalTime       += ret;
                    }
                }

                duration.IsNTSC = totalTime.IsNTSC;
                duration       += totalTime;
                if (currentProgram + 1 < programChainPrograms)
                {
                    chapters.Add(new Chapter {
                        Name = $"Chapter {currentProgram + 2:D2}", Time = duration
                    });
                }
            }
            stream.Dispose();
            return(chapters);
        }