package org.jcodec.containers.mps.index; import org.jcodec.common.Assert; import org.jcodec.common.io.NIOUtils; import org.jcodec.common.io.SeekableByteChannel; import org.jcodec.containers.mps.index.MPSIndex.MPSStreamIndex; import org.jcodec.containers.mps.index.MTSIndex.MTSProgram; import java.io.IOException; import java.nio.ByteBuffer; /** * This class is part of JCodec ( www.jcodec.org ) This software is distributed * under FreeBSD License * * @author The JCodec project * */ public class MTSRandomAccessDemuxer { private MTSProgram[] programs; private SeekableByteChannel ch; public MTSRandomAccessDemuxer(SeekableByteChannel ch, MTSIndex index) { programs = index.getPrograms(); this.ch = ch; } public int[] getGuids() { int[] guids = new int[programs.length]; for (int i = 0; i < programs.length; i++) guids[i] = programs[i].getTargetGuid(); return guids; } public MPSRandomAccessDemuxer getProgramDemuxer(final int tgtGuid) throws IOException { MPSIndex index = getProgram(tgtGuid); return new MPSRandomAccessDemuxer(ch, index) { @Override protected Stream newStream(SeekableByteChannel ch, MPSStreamIndex streamIndex) throws IOException { return new Stream(this, streamIndex, ch) { @Override protected ByteBuffer fetch(int pesLen) throws IOException { ByteBuffer bb = ByteBuffer.allocate(pesLen * 188); for(int i = 0; i < pesLen; i++) { ByteBuffer tsBuf = NIOUtils.fetchFromChannel(source, 188); Assert.assertEquals(0x47, tsBuf.get() & 0xff); int guidFlags = ((tsBuf.get() & 0xff) << 8) | (tsBuf.get() & 0xff); int guid = (int) guidFlags & 0x1fff; if(guid != tgtGuid) continue; int payloadStart = (guidFlags >> 14) & 0x1; int b0 = tsBuf.get() & 0xff; int counter = b0 & 0xf; if ((b0 & 0x20) != 0) { NIOUtils.skip(tsBuf, tsBuf.get() & 0xff); } bb.put(tsBuf); } bb.flip(); return bb; } @Override protected void skip(long leadingSize) throws IOException { source.setPosition(source.position() + leadingSize * 188); } @Override protected void reset() throws IOException { source.setPosition(0); } }; } }; } private MPSIndex getProgram(int guid) { for (MTSProgram mtsProgram : programs) { if (mtsProgram.getTargetGuid() == guid) return mtsProgram; } return null; } }