public void testSimpleRoundWithEntriesTrip( int baseOffsetSize, int indexSize, int lengthSize, int offsetSize) throws IOException { ItemLocationBox ilocOrig = new ItemLocationBox(); ilocOrig.setVersion(1); ilocOrig.setBaseOffsetSize(baseOffsetSize); ilocOrig.setIndexSize(indexSize); ilocOrig.setLengthSize(lengthSize); ilocOrig.setOffsetSize(offsetSize); ItemLocationBox.Item item = ilocOrig.createItem(12, 0, 13, 123, Collections.<ItemLocationBox.Extent>emptyList()); ilocOrig.setItems(Collections.singletonList(item)); ByteBuffer bb = ByteBuffer.allocate(l2i(ilocOrig.getSize())); ilocOrig.getBox(new ByteBufferByteChannel(bb)); bb.rewind(); IsoFile isoFile = new IsoFile(new ByteBufferByteChannel(bb)); ItemLocationBox iloc = (ItemLocationBox) isoFile.getBoxes().get(0); Assert.assertEquals(ilocOrig.getBaseOffsetSize(), iloc.getBaseOffsetSize()); Assert.assertEquals(ilocOrig.getContentSize(), iloc.getContentSize()); Assert.assertEquals(ilocOrig.getIndexSize(), iloc.getIndexSize()); Assert.assertEquals(ilocOrig.getLengthSize(), iloc.getLengthSize()); Assert.assertEquals(ilocOrig.getOffsetSize(), iloc.getOffsetSize()); Assert.assertEquals(ilocOrig.getItems(), iloc.getItems()); }
public void simpleRoundTrip( boolean isSampleSizePresent, boolean isSampleDurationPresent, boolean isSampleCompositionTimeOffsetPresent, int dataOffset, SampleFlags sf) throws IOException { TrackRunBox trun = new TrackRunBox(); trun.setFirstSampleFlags(sf); trun.setSampleSizePresent(!isSampleSizePresent); trun.setSampleSizePresent(isSampleSizePresent); trun.setSampleDurationPresent(!isSampleDurationPresent); trun.setSampleDurationPresent(isSampleDurationPresent); trun.setSampleCompositionTimeOffsetPresent(!isSampleCompositionTimeOffsetPresent); trun.setSampleCompositionTimeOffsetPresent(isSampleCompositionTimeOffsetPresent); trun.setDataOffset(dataOffset); List<TrackRunBox.Entry> entries = new LinkedList<TrackRunBox.Entry>(); entries.add(new TrackRunBox.Entry(1000, 2000, new SampleFlags(), 3000)); entries.add(new TrackRunBox.Entry(1001, 2001, new SampleFlags(), 3001)); trun.setEntries(entries); File f = File.createTempFile(this.getClass().getSimpleName(), ""); FileChannel fc = new FileOutputStream(f).getChannel(); trun.getBox(fc); fc.close(); IsoFile isoFile = new IsoFile(f.getAbsolutePath()); TrackRunBox trun2 = (TrackRunBox) isoFile.getBoxes().get(0); Assert.assertEquals(trun.isDataOffsetPresent(), trun2.isDataOffsetPresent()); Assert.assertEquals( trun.isSampleCompositionTimeOffsetPresent(), trun2.isSampleCompositionTimeOffsetPresent()); Assert.assertEquals(trun.isSampleDurationPresent(), trun2.isSampleDurationPresent()); Assert.assertEquals(trun.isSampleFlagsPresent(), trun2.isSampleFlagsPresent()); Assert.assertEquals(trun.isSampleSizePresent(), trun2.isSampleSizePresent()); Assert.assertEquals(trun.getDataOffset(), trun2.getDataOffset()); Assert.assertEquals(trun.getDataOffset(), trun2.getDataOffset()); Assert.assertEquals(trun.getFirstSampleFlags(), trun2.getFirstSampleFlags()); }
public void testSimpleRoundTrip(int baseOffsetSize, int indexSize, int lengthSize, int offsetSize) throws IOException { ItemLocationBox ilocOrig = new ItemLocationBox(); ilocOrig.setVersion(1); ilocOrig.setBaseOffsetSize(baseOffsetSize); ilocOrig.setIndexSize(indexSize); ilocOrig.setLengthSize(lengthSize); ilocOrig.setOffsetSize(offsetSize); ByteBuffer bb = ByteBuffer.allocate(l2i(ilocOrig.getSize())); ilocOrig.getBox(new ByteBufferByteChannel(bb)); Assert.assertTrue(bb.remaining() == 0); bb.rewind(); IsoFile isoFile = new IsoFile(new ByteBufferByteChannel(bb)); ItemLocationBox iloc = (ItemLocationBox) isoFile.getBoxes().get(0); Assert.assertEquals(ilocOrig.getBaseOffsetSize(), iloc.getBaseOffsetSize()); Assert.assertEquals(ilocOrig.getContentSize(), iloc.getContentSize()); Assert.assertEquals(ilocOrig.getIndexSize(), iloc.getIndexSize()); Assert.assertEquals(ilocOrig.getLengthSize(), iloc.getLengthSize()); Assert.assertEquals(ilocOrig.getOffsetSize(), iloc.getOffsetSize()); Assert.assertEquals(ilocOrig.getItems(), iloc.getItems()); }
public SampleList(TrackBox trackBox) { this.isoFile = trackBox.getIsoFile(); // where are we? offsets2Sizes = new HashMap<Long, Long>(); // find all mdats first to be able to use them later with explicitly looking them up long currentOffset = 0; for (Box b : isoFile.getBoxes()) { long currentSize = b.getSize(); if ("mdat".equals(b.getType())) { if (b instanceof MediaDataBox) { long contentOffset = currentOffset + ((MediaDataBox) b).getHeader().limit(); mdatStartCache.put((MediaDataBox) b, contentOffset); mdatEndCache.put((MediaDataBox) b, contentOffset + currentSize); mdats.add((MediaDataBox) b); } else { throw new RuntimeException( "Sample need to be in mdats and mdats need to be instanceof MediaDataBox"); } } currentOffset += currentSize; } // first we get all sample from the 'normal' MP4 part. // if there are none - no problem. SampleSizeBox sampleSizeBox = trackBox.getSampleTableBox().getSampleSizeBox(); ChunkOffsetBox chunkOffsetBox = trackBox.getSampleTableBox().getChunkOffsetBox(); SampleToChunkBox sampleToChunkBox = trackBox.getSampleTableBox().getSampleToChunkBox(); if (sampleToChunkBox != null && sampleToChunkBox.getEntries().size() > 0 && chunkOffsetBox != null && chunkOffsetBox.getChunkOffsets().length > 0 && sampleSizeBox != null && sampleSizeBox.getSampleCount() > 0) { long[] numberOfSamplesInChunk = sampleToChunkBox.blowup(chunkOffsetBox.getChunkOffsets().length); if (sampleSizeBox.getSampleSize() > 0) { // Every sample has the same size! // no need to store each size separately // this happens when people use raw audio formats in MP4 (are you stupid guys???) offsets2Sizes = new DummyMap<Long, Long>(sampleSizeBox.getSampleSize()); long sampleSize = sampleSizeBox.getSampleSize(); for (int i = 0; i < numberOfSamplesInChunk.length; i++) { long thisChunksNumberOfSamples = numberOfSamplesInChunk[i]; long sampleOffset = chunkOffsetBox.getChunkOffsets()[i]; for (int j = 0; j < thisChunksNumberOfSamples; j++) { offsets2Sizes.put(sampleOffset, sampleSize); sampleOffset += sampleSize; } } } else { // the normal case where all samples have different sizes int sampleIndex = 0; long sampleSizes[] = sampleSizeBox.getSampleSizes(); for (int i = 0; i < numberOfSamplesInChunk.length; i++) { long thisChunksNumberOfSamples = numberOfSamplesInChunk[i]; long sampleOffset = chunkOffsetBox.getChunkOffsets()[i]; for (int j = 0; j < thisChunksNumberOfSamples; j++) { long sampleSize = sampleSizes[sampleIndex]; offsets2Sizes.put(sampleOffset, sampleSize); sampleOffset += sampleSize; sampleIndex++; } } } } // Next we add all samples from the fragments // in most cases - I've never seen it different it's either normal or fragmented. List<MovieExtendsBox> movieExtendsBoxes = trackBox.getParent().getBoxes(MovieExtendsBox.class); if (movieExtendsBoxes.size() > 0) { List<TrackExtendsBox> trackExtendsBoxes = movieExtendsBoxes.get(0).getBoxes(TrackExtendsBox.class); for (TrackExtendsBox trackExtendsBox : trackExtendsBoxes) { if (trackExtendsBox.getTrackId() == trackBox.getTrackHeaderBox().getTrackId()) { for (MovieFragmentBox movieFragmentBox : trackBox.getIsoFile().getBoxes(MovieFragmentBox.class)) { offsets2Sizes.putAll( getOffsets(movieFragmentBox, trackBox.getTrackHeaderBox().getTrackId())); } } } } // We have now a map from all sample offsets to their sizes }