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());
  }
Beispiel #4
0
  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
  }