/** * Reads a PGC structure and completes the {@link DvdTitle} with the data found there. * * @param vts random access to the VTS file * @param title {@link DvdTitle} to complete * @param offset Offset of the PGC structure to be read */ private void readVtsPgc( IfoRandomAccessFile vts, DvdTitle title, DvdTitleSet titleSet, long offset) throws IOException { vts.at(offset).skip(2); int chapters = vts.readu8(); int cellCount = vts.readu8(); LOG.debug(" chapters: %d, cells: %d", chapters, cellCount); title.setTotalTimeMs(vts.readBcdTimeMs()); vts.skip(4); for (int ix = 0; ix < 8; ix++) { int snr = vts.readu8(); if ((snr & 0x80) != 0) { DvdAudio audio = titleSet.getAudios().get(ix); int streamId = snr & 0x07; if (streamId == 0) { streamId = ix; } streamId += audio.getMode().getBaseStreamId(); audio.setStreamId(streamId); } vts.skip(1); } for (int ix = 0; ix < 32; ix++) { int snr = vts.readu8(); int sWide = vts.readu8(); int sLetterbox = vts.readu8(); int sPanScan = vts.readu8(); if ((snr & 0x80) != 0) { snr &= 0x1F; sWide &= 0x1F; sLetterbox &= 0x1F; sPanScan &= 0x1F; DvdSubtitle sub = titleSet.getSubs().get(ix); if (titleSet.getAspect() == Aspect.ASPECT_16_9) { sub.setStreamWideId((sWide > 0 ? sWide : ix) + 0x20); } else { sub.setStream43Id((snr > 0 ? snr : ix) + 0x20); } if (titleSet.isLetterboxEnabled()) { sub.setStreamLetterboxId((sLetterbox > 0 ? sLetterbox : ix) + 0x20); } if (titleSet.isPanScanEnabled()) { sub.setStreamPanScanId((sPanScan > 0 ? sPanScan : ix) + 0x20); } } } vts.skip(8); for (int ix = 0; ix < 16; ix++) { title.getColors()[ix] = (int) vts.readu32(); } vts.skip(2); int programMapOffset = vts.readu16(); int cellPlaybackOffset = vts.readu16(); int[] cells = new int[chapters]; vts.at(offset + programMapOffset); for (int ix = 0; ix < chapters; ix++) { cells[ix] = vts.readu8(); } for (int ix = 0; ix < chapters; ix++) { int current = cells[ix]; int next = (ix + 1 < chapters ? cells[ix + 1] : cellCount); long ms = 0; while (current < next) { vts.at(offset + cellPlaybackOffset + ((current - 1) * 0x18) + 4); ms += vts.readBcdTimeMs(); current++; } if (ms > 0 || next != cellCount) { title.getChapterTimeMs().add(ms); } } }