Java 类com.google.android.exoplayer2.extractor.mp4.Atom.ContainerAtom 实例源码

项目:Exoplayer2Radio    文件:Mp4Extractor.java   
private void processAtomEnded(long atomEndPosition) throws ParserException {
  while (!containerAtoms.isEmpty() && containerAtoms.peek().endPosition == atomEndPosition) {
    Atom.ContainerAtom containerAtom = containerAtoms.pop();
    if (containerAtom.type == Atom.TYPE_moov) {
      // We've reached the end of the moov atom. Process it and prepare to read samples.
      processMoovAtom(containerAtom);
      containerAtoms.clear();
      parserState = STATE_READING_SAMPLE;
    } else if (!containerAtoms.isEmpty()) {
      containerAtoms.peek().add(containerAtom);
    }
  }
  if (parserState != STATE_READING_SAMPLE) {
    enterReadingAtomHeaderState();
  }
}
项目:K-Sonic    文件:Mp4Extractor.java   
private void processAtomEnded(long atomEndPosition) throws ParserException {
  while (!containerAtoms.isEmpty() && containerAtoms.peek().endPosition == atomEndPosition) {
    Atom.ContainerAtom containerAtom = containerAtoms.pop();
    if (containerAtom.type == Atom.TYPE_moov) {
      // We've reached the end of the moov atom. Process it and prepare to read samples.
      processMoovAtom(containerAtom);
      containerAtoms.clear();
      parserState = STATE_READING_SAMPLE;
    } else if (!containerAtoms.isEmpty()) {
      containerAtoms.peek().add(containerAtom);
    }
  }
  if (parserState != STATE_READING_SAMPLE) {
    enterReadingAtomHeaderState();
  }
}
项目:videoPickPlayer    文件:Mp4Extractor.java   
private void processAtomEnded(long atomEndPosition) throws ParserException {
  while (!containerAtoms.isEmpty() && containerAtoms.peek().endPosition == atomEndPosition) {
    Atom.ContainerAtom containerAtom = containerAtoms.pop();
    if (containerAtom.type == Atom.TYPE_moov) {
      // We've reached the end of the moov atom. Process it and prepare to read samples.
      processMoovAtom(containerAtom);
      containerAtoms.clear();
      parserState = STATE_READING_SAMPLE;
    } else if (!containerAtoms.isEmpty()) {
      containerAtoms.peek().add(containerAtom);
    }
  }
  if (parserState != STATE_READING_SAMPLE) {
    enterReadingAtomHeaderState();
  }
}
项目:transistor    文件:Mp4Extractor.java   
private void processAtomEnded(long atomEndPosition) throws ParserException {
  while (!containerAtoms.isEmpty() && containerAtoms.peek().endPosition == atomEndPosition) {
    Atom.ContainerAtom containerAtom = containerAtoms.pop();
    if (containerAtom.type == Atom.TYPE_moov) {
      // We've reached the end of the moov atom. Process it and prepare to read samples.
      processMoovAtom(containerAtom);
      containerAtoms.clear();
      parserState = STATE_READING_SAMPLE;
    } else if (!containerAtoms.isEmpty()) {
      containerAtoms.peek().add(containerAtom);
    }
  }
  if (parserState != STATE_READING_SAMPLE) {
    enterReadingAtomHeaderState();
  }
}
项目:Exoplayer2Radio    文件:FragmentedMp4Extractor.java   
private void onContainerAtomRead(ContainerAtom container) throws ParserException {
  if (container.type == Atom.TYPE_moov) {
    onMoovContainerAtomRead(container);
  } else if (container.type == Atom.TYPE_moof) {
    onMoofContainerAtomRead(container);
  } else if (!containerAtoms.isEmpty()) {
    containerAtoms.peek().add(container);
  }
}
项目:Exoplayer2Radio    文件:FragmentedMp4Extractor.java   
private void onMoofContainerAtomRead(ContainerAtom moof) throws ParserException {
  parseMoof(moof, trackBundles, flags, extendedTypeScratch);
  DrmInitData drmInitData = getDrmInitDataFromAtoms(moof.leafChildren);
  if (drmInitData != null) {
    int trackCount = trackBundles.size();
    for (int i = 0; i < trackCount; i++) {
      trackBundles.valueAt(i).updateDrmInitData(drmInitData);
    }
  }
}
项目:Exoplayer2Radio    文件:FragmentedMp4Extractor.java   
private static void parseMoof(ContainerAtom moof, SparseArray<TrackBundle> trackBundleArray,
    @Flags int flags, byte[] extendedTypeScratch) throws ParserException {
  int moofContainerChildrenSize = moof.containerChildren.size();
  for (int i = 0; i < moofContainerChildrenSize; i++) {
    Atom.ContainerAtom child = moof.containerChildren.get(i);
    // TODO: Support multiple traf boxes per track in a single moof.
    if (child.type == Atom.TYPE_traf) {
      parseTraf(child, trackBundleArray, flags, extendedTypeScratch);
    }
  }
}
项目:Exoplayer2Radio    文件:FragmentedMp4Extractor.java   
private static void parseTruns(ContainerAtom traf, TrackBundle trackBundle, long decodeTime,
    @Flags int flags) {
  int trunCount = 0;
  int totalSampleCount = 0;
  List<LeafAtom> leafChildren = traf.leafChildren;
  int leafChildrenSize = leafChildren.size();
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom atom = leafChildren.get(i);
    if (atom.type == Atom.TYPE_trun) {
      ParsableByteArray trunData = atom.data;
      trunData.setPosition(Atom.FULL_HEADER_SIZE);
      int trunSampleCount = trunData.readUnsignedIntToInt();
      if (trunSampleCount > 0) {
        totalSampleCount += trunSampleCount;
        trunCount++;
      }
    }
  }
  trackBundle.currentTrackRunIndex = 0;
  trackBundle.currentSampleInTrackRun = 0;
  trackBundle.currentSampleIndex = 0;
  trackBundle.fragment.initTables(trunCount, totalSampleCount);

  int trunIndex = 0;
  int trunStartPosition = 0;
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom trun = leafChildren.get(i);
    if (trun.type == Atom.TYPE_trun) {
      trunStartPosition = parseTrun(trackBundle, trunIndex++, decodeTime, flags, trun.data,
          trunStartPosition);
    }
  }
}
项目:K-Sonic    文件:FragmentedMp4Extractor.java   
private void onContainerAtomRead(ContainerAtom container) throws ParserException {
  if (container.type == Atom.TYPE_moov) {
    onMoovContainerAtomRead(container);
  } else if (container.type == Atom.TYPE_moof) {
    onMoofContainerAtomRead(container);
  } else if (!containerAtoms.isEmpty()) {
    containerAtoms.peek().add(container);
  }
}
项目:K-Sonic    文件:FragmentedMp4Extractor.java   
private void onMoofContainerAtomRead(ContainerAtom moof) throws ParserException {
  parseMoof(moof, trackBundles, flags, extendedTypeScratch);
  DrmInitData drmInitData = getDrmInitDataFromAtoms(moof.leafChildren);
  if (drmInitData != null) {
    int trackCount = trackBundles.size();
    for (int i = 0; i < trackCount; i++) {
      trackBundles.valueAt(i).updateDrmInitData(drmInitData);
    }
  }
}
项目:K-Sonic    文件:FragmentedMp4Extractor.java   
private static void parseMoof(ContainerAtom moof, SparseArray<TrackBundle> trackBundleArray,
    @Flags int flags, byte[] extendedTypeScratch) throws ParserException {
  int moofContainerChildrenSize = moof.containerChildren.size();
  for (int i = 0; i < moofContainerChildrenSize; i++) {
    Atom.ContainerAtom child = moof.containerChildren.get(i);
    // TODO: Support multiple traf boxes per track in a single moof.
    if (child.type == Atom.TYPE_traf) {
      parseTraf(child, trackBundleArray, flags, extendedTypeScratch);
    }
  }
}
项目:K-Sonic    文件:FragmentedMp4Extractor.java   
private static void parseTruns(ContainerAtom traf, TrackBundle trackBundle, long decodeTime,
    @Flags int flags) {
  int trunCount = 0;
  int totalSampleCount = 0;
  List<LeafAtom> leafChildren = traf.leafChildren;
  int leafChildrenSize = leafChildren.size();
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom atom = leafChildren.get(i);
    if (atom.type == Atom.TYPE_trun) {
      ParsableByteArray trunData = atom.data;
      trunData.setPosition(Atom.FULL_HEADER_SIZE);
      int trunSampleCount = trunData.readUnsignedIntToInt();
      if (trunSampleCount > 0) {
        totalSampleCount += trunSampleCount;
        trunCount++;
      }
    }
  }
  trackBundle.currentTrackRunIndex = 0;
  trackBundle.currentSampleInTrackRun = 0;
  trackBundle.currentSampleIndex = 0;
  trackBundle.fragment.initTables(trunCount, totalSampleCount);

  int trunIndex = 0;
  int trunStartPosition = 0;
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom trun = leafChildren.get(i);
    if (trun.type == Atom.TYPE_trun) {
      trunStartPosition = parseTrun(trackBundle, trunIndex++, decodeTime, flags, trun.data,
          trunStartPosition);
    }
  }
}
项目:videoPickPlayer    文件:FragmentedMp4Extractor.java   
private void onContainerAtomRead(ContainerAtom container) throws ParserException {
  if (container.type == Atom.TYPE_moov) {
    onMoovContainerAtomRead(container);
  } else if (container.type == Atom.TYPE_moof) {
    onMoofContainerAtomRead(container);
  } else if (!containerAtoms.isEmpty()) {
    containerAtoms.peek().add(container);
  }
}
项目:videoPickPlayer    文件:FragmentedMp4Extractor.java   
private void onMoofContainerAtomRead(ContainerAtom moof) throws ParserException {
  parseMoof(moof, trackBundles, flags, extendedTypeScratch);
  DrmInitData drmInitData = getDrmInitDataFromAtoms(moof.leafChildren);
  if (drmInitData != null) {
    int trackCount = trackBundles.size();
    for (int i = 0; i < trackCount; i++) {
      trackBundles.valueAt(i).updateDrmInitData(drmInitData);
    }
  }
}
项目:videoPickPlayer    文件:FragmentedMp4Extractor.java   
private static void parseMoof(ContainerAtom moof, SparseArray<TrackBundle> trackBundleArray,
    @Flags int flags, byte[] extendedTypeScratch) throws ParserException {
  int moofContainerChildrenSize = moof.containerChildren.size();
  for (int i = 0; i < moofContainerChildrenSize; i++) {
    Atom.ContainerAtom child = moof.containerChildren.get(i);
    // TODO: Support multiple traf boxes per track in a single moof.
    if (child.type == Atom.TYPE_traf) {
      parseTraf(child, trackBundleArray, flags, extendedTypeScratch);
    }
  }
}
项目:videoPickPlayer    文件:FragmentedMp4Extractor.java   
private static void parseTruns(ContainerAtom traf, TrackBundle trackBundle, long decodeTime,
    @Flags int flags) {
  int trunCount = 0;
  int totalSampleCount = 0;
  List<LeafAtom> leafChildren = traf.leafChildren;
  int leafChildrenSize = leafChildren.size();
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom atom = leafChildren.get(i);
    if (atom.type == Atom.TYPE_trun) {
      ParsableByteArray trunData = atom.data;
      trunData.setPosition(Atom.FULL_HEADER_SIZE);
      int trunSampleCount = trunData.readUnsignedIntToInt();
      if (trunSampleCount > 0) {
        totalSampleCount += trunSampleCount;
        trunCount++;
      }
    }
  }
  trackBundle.currentTrackRunIndex = 0;
  trackBundle.currentSampleInTrackRun = 0;
  trackBundle.currentSampleIndex = 0;
  trackBundle.fragment.initTables(trunCount, totalSampleCount);

  int trunIndex = 0;
  int trunStartPosition = 0;
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom trun = leafChildren.get(i);
    if (trun.type == Atom.TYPE_trun) {
      trunStartPosition = parseTrun(trackBundle, trunIndex++, decodeTime, flags, trun.data,
          trunStartPosition);
    }
  }
}
项目:transistor    文件:FragmentedMp4Extractor.java   
private void onContainerAtomRead(ContainerAtom container) throws ParserException {
  if (container.type == Atom.TYPE_moov) {
    onMoovContainerAtomRead(container);
  } else if (container.type == Atom.TYPE_moof) {
    onMoofContainerAtomRead(container);
  } else if (!containerAtoms.isEmpty()) {
    containerAtoms.peek().add(container);
  }
}
项目:transistor    文件:FragmentedMp4Extractor.java   
private void onMoofContainerAtomRead(ContainerAtom moof) throws ParserException {
  parseMoof(moof, trackBundles, flags, extendedTypeScratch);
  // If drm init data is sideloaded, we ignore pssh boxes.
  DrmInitData drmInitData = sideloadedDrmInitData != null ? null
      : getDrmInitDataFromAtoms(moof.leafChildren);
  if (drmInitData != null) {
    int trackCount = trackBundles.size();
    for (int i = 0; i < trackCount; i++) {
      trackBundles.valueAt(i).updateDrmInitData(drmInitData);
    }
  }
}
项目:transistor    文件:FragmentedMp4Extractor.java   
private static void parseMoof(ContainerAtom moof, SparseArray<TrackBundle> trackBundleArray,
    @Flags int flags, byte[] extendedTypeScratch) throws ParserException {
  int moofContainerChildrenSize = moof.containerChildren.size();
  for (int i = 0; i < moofContainerChildrenSize; i++) {
    Atom.ContainerAtom child = moof.containerChildren.get(i);
    // TODO: Support multiple traf boxes per track in a single moof.
    if (child.type == Atom.TYPE_traf) {
      parseTraf(child, trackBundleArray, flags, extendedTypeScratch);
    }
  }
}
项目:transistor    文件:FragmentedMp4Extractor.java   
private static void parseTruns(ContainerAtom traf, TrackBundle trackBundle, long decodeTime,
    @Flags int flags) {
  int trunCount = 0;
  int totalSampleCount = 0;
  List<LeafAtom> leafChildren = traf.leafChildren;
  int leafChildrenSize = leafChildren.size();
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom atom = leafChildren.get(i);
    if (atom.type == Atom.TYPE_trun) {
      ParsableByteArray trunData = atom.data;
      trunData.setPosition(Atom.FULL_HEADER_SIZE);
      int trunSampleCount = trunData.readUnsignedIntToInt();
      if (trunSampleCount > 0) {
        totalSampleCount += trunSampleCount;
        trunCount++;
      }
    }
  }
  trackBundle.currentTrackRunIndex = 0;
  trackBundle.currentSampleInTrackRun = 0;
  trackBundle.currentSampleIndex = 0;
  trackBundle.fragment.initTables(trunCount, totalSampleCount);

  int trunIndex = 0;
  int trunStartPosition = 0;
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom trun = leafChildren.get(i);
    if (trun.type == Atom.TYPE_trun) {
      trunStartPosition = parseTrun(trackBundle, trunIndex++, decodeTime, flags, trun.data,
          trunStartPosition);
    }
  }
}
项目:Exoplayer2Radio    文件:Mp4Extractor.java   
private boolean readAtomHeader(ExtractorInput input) throws IOException, InterruptedException {
  if (atomHeaderBytesRead == 0) {
    // Read the standard length atom header.
    if (!input.readFully(atomHeader.data, 0, Atom.HEADER_SIZE, true)) {
      return false;
    }
    atomHeaderBytesRead = Atom.HEADER_SIZE;
    atomHeader.setPosition(0);
    atomSize = atomHeader.readUnsignedInt();
    atomType = atomHeader.readInt();
  }

  if (atomSize == Atom.LONG_SIZE_PREFIX) {
    // Read the extended atom size.
    int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
    input.readFully(atomHeader.data, Atom.HEADER_SIZE, headerBytesRemaining);
    atomHeaderBytesRead += headerBytesRemaining;
    atomSize = atomHeader.readUnsignedLongToLong();
  }

  if (shouldParseContainerAtom(atomType)) {
    long endPosition = input.getPosition() + atomSize - atomHeaderBytesRead;
    containerAtoms.add(new ContainerAtom(atomType, endPosition));
    if (atomSize == atomHeaderBytesRead) {
      processAtomEnded(endPosition);
    } else {
      // Start reading the first child atom.
      enterReadingAtomHeaderState();
    }
  } else if (shouldParseLeafAtom(atomType)) {
    // We don't support parsing of leaf atoms that define extended atom sizes, or that have
    // lengths greater than Integer.MAX_VALUE.
    Assertions.checkState(atomHeaderBytesRead == Atom.HEADER_SIZE);
    Assertions.checkState(atomSize <= Integer.MAX_VALUE);
    atomData = new ParsableByteArray((int) atomSize);
    System.arraycopy(atomHeader.data, 0, atomData.data, 0, Atom.HEADER_SIZE);
    parserState = STATE_READING_ATOM_PAYLOAD;
  } else {
    atomData = null;
    parserState = STATE_READING_ATOM_PAYLOAD;
  }

  return true;
}
项目:Exoplayer2Radio    文件:Mp4Extractor.java   
/**
 * Updates the stored track metadata to reflect the contents of the specified moov atom.
 */
private void processMoovAtom(ContainerAtom moov) throws ParserException {
  long durationUs = C.TIME_UNSET;
  List<Mp4Track> tracks = new ArrayList<>();
  long earliestSampleOffset = Long.MAX_VALUE;

  Metadata metadata = null;
  GaplessInfoHolder gaplessInfoHolder = new GaplessInfoHolder();
  Atom.LeafAtom udta = moov.getLeafAtomOfType(Atom.TYPE_udta);
  if (udta != null) {
    metadata = AtomParsers.parseUdta(udta, isQuickTime);
    if (metadata != null) {
      gaplessInfoHolder.setFromMetadata(metadata);
    }
  }

  for (int i = 0; i < moov.containerChildren.size(); i++) {
    Atom.ContainerAtom atom = moov.containerChildren.get(i);
    if (atom.type != Atom.TYPE_trak) {
      continue;
    }

    Track track = AtomParsers.parseTrak(atom, moov.getLeafAtomOfType(Atom.TYPE_mvhd),
        C.TIME_UNSET, null, isQuickTime);
    if (track == null) {
      continue;
    }

    Atom.ContainerAtom stblAtom = atom.getContainerAtomOfType(Atom.TYPE_mdia)
        .getContainerAtomOfType(Atom.TYPE_minf).getContainerAtomOfType(Atom.TYPE_stbl);
    TrackSampleTable trackSampleTable = AtomParsers.parseStbl(track, stblAtom, gaplessInfoHolder);
    if (trackSampleTable.sampleCount == 0) {
      continue;
    }

    Mp4Track mp4Track = new Mp4Track(track, trackSampleTable,
        extractorOutput.track(i, track.type));
    // Each sample has up to three bytes of overhead for the start code that replaces its length.
    // Allow ten source samples per output sample, like the platform extractor.
    int maxInputSize = trackSampleTable.maximumSize + 3 * 10;
    Format format = track.format.copyWithMaxInputSize(maxInputSize);
    if (track.type == C.TRACK_TYPE_AUDIO) {
      if (gaplessInfoHolder.hasGaplessInfo()) {
        format = format.copyWithGaplessInfo(gaplessInfoHolder.encoderDelay,
            gaplessInfoHolder.encoderPadding);
      }
      if (metadata != null) {
        format = format.copyWithMetadata(metadata);
      }
    }
    mp4Track.trackOutput.format(format);

    durationUs = Math.max(durationUs, track.durationUs);
    tracks.add(mp4Track);

    long firstSampleOffset = trackSampleTable.offsets[0];
    if (firstSampleOffset < earliestSampleOffset) {
      earliestSampleOffset = firstSampleOffset;
    }
  }
  this.durationUs = durationUs;
  this.tracks = tracks.toArray(new Mp4Track[tracks.size()]);
  extractorOutput.endTracks();
  extractorOutput.seekMap(this);
}
项目:Exoplayer2Radio    文件:FragmentedMp4Extractor.java   
private boolean readAtomHeader(ExtractorInput input) throws IOException, InterruptedException {
  if (atomHeaderBytesRead == 0) {
    // Read the standard length atom header.
    if (!input.readFully(atomHeader.data, 0, Atom.HEADER_SIZE, true)) {
      return false;
    }
    atomHeaderBytesRead = Atom.HEADER_SIZE;
    atomHeader.setPosition(0);
    atomSize = atomHeader.readUnsignedInt();
    atomType = atomHeader.readInt();
  }

  if (atomSize == Atom.LONG_SIZE_PREFIX) {
    // Read the extended atom size.
    int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
    input.readFully(atomHeader.data, Atom.HEADER_SIZE, headerBytesRemaining);
    atomHeaderBytesRead += headerBytesRemaining;
    atomSize = atomHeader.readUnsignedLongToLong();
  }

  if (atomSize < atomHeaderBytesRead) {
    throw new ParserException("Atom size less than header length (unsupported).");
  }

  long atomPosition = input.getPosition() - atomHeaderBytesRead;
  if (atomType == Atom.TYPE_moof) {
    // The data positions may be updated when parsing the tfhd/trun.
    int trackCount = trackBundles.size();
    for (int i = 0; i < trackCount; i++) {
      TrackFragment fragment = trackBundles.valueAt(i).fragment;
      fragment.atomPosition = atomPosition;
      fragment.auxiliaryDataPosition = atomPosition;
      fragment.dataPosition = atomPosition;
    }
  }

  if (atomType == Atom.TYPE_mdat) {
    currentTrackBundle = null;
    endOfMdatPosition = atomPosition + atomSize;
    if (!haveOutputSeekMap) {
      extractorOutput.seekMap(new SeekMap.Unseekable(durationUs));
      haveOutputSeekMap = true;
    }
    parserState = STATE_READING_ENCRYPTION_DATA;
    return true;
  }

  if (shouldParseContainerAtom(atomType)) {
    long endPosition = input.getPosition() + atomSize - Atom.HEADER_SIZE;
    containerAtoms.add(new ContainerAtom(atomType, endPosition));
    if (atomSize == atomHeaderBytesRead) {
      processAtomEnded(endPosition);
    } else {
      // Start reading the first child atom.
      enterReadingAtomHeaderState();
    }
  } else if (shouldParseLeafAtom(atomType)) {
    if (atomHeaderBytesRead != Atom.HEADER_SIZE) {
      throw new ParserException("Leaf atom defines extended atom size (unsupported).");
    }
    if (atomSize > Integer.MAX_VALUE) {
      throw new ParserException("Leaf atom with length > 2147483647 (unsupported).");
    }
    atomData = new ParsableByteArray((int) atomSize);
    System.arraycopy(atomHeader.data, 0, atomData.data, 0, Atom.HEADER_SIZE);
    parserState = STATE_READING_ATOM_PAYLOAD;
  } else {
    if (atomSize > Integer.MAX_VALUE) {
      throw new ParserException("Skipping atom with length > 2147483647 (unsupported).");
    }
    atomData = null;
    parserState = STATE_READING_ATOM_PAYLOAD;
  }

  return true;
}
项目:Exoplayer2Radio    文件:FragmentedMp4Extractor.java   
/**
 * Parses a traf atom (defined in 14496-12).
 */
private static void parseTraf(ContainerAtom traf, SparseArray<TrackBundle> trackBundleArray,
    @Flags int flags, byte[] extendedTypeScratch) throws ParserException {
  LeafAtom tfhd = traf.getLeafAtomOfType(Atom.TYPE_tfhd);
  TrackBundle trackBundle = parseTfhd(tfhd.data, trackBundleArray, flags);
  if (trackBundle == null) {
    return;
  }

  TrackFragment fragment = trackBundle.fragment;
  long decodeTime = fragment.nextFragmentDecodeTime;
  trackBundle.reset();

  LeafAtom tfdtAtom = traf.getLeafAtomOfType(Atom.TYPE_tfdt);
  if (tfdtAtom != null && (flags & FLAG_WORKAROUND_IGNORE_TFDT_BOX) == 0) {
    decodeTime = parseTfdt(traf.getLeafAtomOfType(Atom.TYPE_tfdt).data);
  }

  parseTruns(traf, trackBundle, decodeTime, flags);

  LeafAtom saiz = traf.getLeafAtomOfType(Atom.TYPE_saiz);
  if (saiz != null) {
    TrackEncryptionBox trackEncryptionBox = trackBundle.track
        .sampleDescriptionEncryptionBoxes[fragment.header.sampleDescriptionIndex];
    parseSaiz(trackEncryptionBox, saiz.data, fragment);
  }

  LeafAtom saio = traf.getLeafAtomOfType(Atom.TYPE_saio);
  if (saio != null) {
    parseSaio(saio.data, fragment);
  }

  LeafAtom senc = traf.getLeafAtomOfType(Atom.TYPE_senc);
  if (senc != null) {
    parseSenc(senc.data, fragment);
  }

  LeafAtom sbgp = traf.getLeafAtomOfType(Atom.TYPE_sbgp);
  LeafAtom sgpd = traf.getLeafAtomOfType(Atom.TYPE_sgpd);
  if (sbgp != null && sgpd != null) {
    parseSgpd(sbgp.data, sgpd.data, fragment);
  }

  int leafChildrenSize = traf.leafChildren.size();
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom atom = traf.leafChildren.get(i);
    if (atom.type == Atom.TYPE_uuid) {
      parseUuid(atom.data, fragment, extendedTypeScratch);
    }
  }
}
项目:K-Sonic    文件:Mp4Extractor.java   
private boolean readAtomHeader(ExtractorInput input) throws IOException, InterruptedException {
  if (atomHeaderBytesRead == 0) {
    // Read the standard length atom header.
    if (!input.readFully(atomHeader.data, 0, Atom.HEADER_SIZE, true)) {
      return false;
    }
    atomHeaderBytesRead = Atom.HEADER_SIZE;
    atomHeader.setPosition(0);
    atomSize = atomHeader.readUnsignedInt();
    atomType = atomHeader.readInt();
  }

  if (atomSize == Atom.LONG_SIZE_PREFIX) {
    // Read the extended atom size.
    int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
    input.readFully(atomHeader.data, Atom.HEADER_SIZE, headerBytesRemaining);
    atomHeaderBytesRead += headerBytesRemaining;
    atomSize = atomHeader.readUnsignedLongToLong();
  }

  if (shouldParseContainerAtom(atomType)) {
    long endPosition = input.getPosition() + atomSize - atomHeaderBytesRead;
    containerAtoms.add(new ContainerAtom(atomType, endPosition));
    if (atomSize == atomHeaderBytesRead) {
      processAtomEnded(endPosition);
    } else {
      // Start reading the first child atom.
      enterReadingAtomHeaderState();
    }
  } else if (shouldParseLeafAtom(atomType)) {
    // We don't support parsing of leaf atoms that define extended atom sizes, or that have
    // lengths greater than Integer.MAX_VALUE.
    Assertions.checkState(atomHeaderBytesRead == Atom.HEADER_SIZE);
    Assertions.checkState(atomSize <= Integer.MAX_VALUE);
    atomData = new ParsableByteArray((int) atomSize);
    System.arraycopy(atomHeader.data, 0, atomData.data, 0, Atom.HEADER_SIZE);
    parserState = STATE_READING_ATOM_PAYLOAD;
  } else {
    atomData = null;
    parserState = STATE_READING_ATOM_PAYLOAD;
  }

  return true;
}
项目:K-Sonic    文件:Mp4Extractor.java   
/**
 * Updates the stored track metadata to reflect the contents of the specified moov atom.
 */
private void processMoovAtom(ContainerAtom moov) throws ParserException {
  long durationUs = C.TIME_UNSET;
  List<Mp4Track> tracks = new ArrayList<>();
  long earliestSampleOffset = Long.MAX_VALUE;

  Metadata metadata = null;
  GaplessInfoHolder gaplessInfoHolder = new GaplessInfoHolder();
  Atom.LeafAtom udta = moov.getLeafAtomOfType(Atom.TYPE_udta);
  if (udta != null) {
    metadata = AtomParsers.parseUdta(udta, isQuickTime);
    if (metadata != null) {
      gaplessInfoHolder.setFromMetadata(metadata);
    }
  }

  for (int i = 0; i < moov.containerChildren.size(); i++) {
    Atom.ContainerAtom atom = moov.containerChildren.get(i);
    if (atom.type != Atom.TYPE_trak) {
      continue;
    }

    Track track = AtomParsers.parseTrak(atom, moov.getLeafAtomOfType(Atom.TYPE_mvhd),
        C.TIME_UNSET, null, isQuickTime);
    if (track == null) {
      continue;
    }

    Atom.ContainerAtom stblAtom = atom.getContainerAtomOfType(Atom.TYPE_mdia)
        .getContainerAtomOfType(Atom.TYPE_minf).getContainerAtomOfType(Atom.TYPE_stbl);
    TrackSampleTable trackSampleTable = AtomParsers.parseStbl(track, stblAtom, gaplessInfoHolder);
    if (trackSampleTable.sampleCount == 0) {
      continue;
    }

    Mp4Track mp4Track = new Mp4Track(track, trackSampleTable,
        extractorOutput.track(i, track.type));
    // Each sample has up to three bytes of overhead for the start code that replaces its length.
    // Allow ten source samples per output sample, like the platform extractor.
    int maxInputSize = trackSampleTable.maximumSize + 3 * 10;
    Format format = track.format.copyWithMaxInputSize(maxInputSize);
    if (track.type == C.TRACK_TYPE_AUDIO) {
      if (gaplessInfoHolder.hasGaplessInfo()) {
        format = format.copyWithGaplessInfo(gaplessInfoHolder.encoderDelay,
            gaplessInfoHolder.encoderPadding);
      }
      if (metadata != null) {
        format = format.copyWithMetadata(metadata);
      }
    }
    mp4Track.trackOutput.format(format);

    durationUs = Math.max(durationUs, track.durationUs);
    tracks.add(mp4Track);

    long firstSampleOffset = trackSampleTable.offsets[0];
    if (firstSampleOffset < earliestSampleOffset) {
      earliestSampleOffset = firstSampleOffset;
    }
  }
  this.durationUs = durationUs;
  this.tracks = tracks.toArray(new Mp4Track[tracks.size()]);
  extractorOutput.endTracks();
  extractorOutput.seekMap(this);
}
项目:K-Sonic    文件:FragmentedMp4Extractor.java   
private boolean readAtomHeader(ExtractorInput input) throws IOException, InterruptedException {
  if (atomHeaderBytesRead == 0) {
    // Read the standard length atom header.
    if (!input.readFully(atomHeader.data, 0, Atom.HEADER_SIZE, true)) {
      return false;
    }
    atomHeaderBytesRead = Atom.HEADER_SIZE;
    atomHeader.setPosition(0);
    atomSize = atomHeader.readUnsignedInt();
    atomType = atomHeader.readInt();
  }

  if (atomSize == Atom.LONG_SIZE_PREFIX) {
    // Read the extended atom size.
    int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
    input.readFully(atomHeader.data, Atom.HEADER_SIZE, headerBytesRemaining);
    atomHeaderBytesRead += headerBytesRemaining;
    atomSize = atomHeader.readUnsignedLongToLong();
  }

  if (atomSize < atomHeaderBytesRead) {
    throw new ParserException("Atom size less than header length (unsupported).");
  }

  long atomPosition = input.getPosition() - atomHeaderBytesRead;
  if (atomType == Atom.TYPE_moof) {
    // The data positions may be updated when parsing the tfhd/trun.
    int trackCount = trackBundles.size();
    for (int i = 0; i < trackCount; i++) {
      TrackFragment fragment = trackBundles.valueAt(i).fragment;
      fragment.atomPosition = atomPosition;
      fragment.auxiliaryDataPosition = atomPosition;
      fragment.dataPosition = atomPosition;
    }
  }

  if (atomType == Atom.TYPE_mdat) {
    currentTrackBundle = null;
    endOfMdatPosition = atomPosition + atomSize;
    if (!haveOutputSeekMap) {
      extractorOutput.seekMap(new SeekMap.Unseekable(durationUs));
      haveOutputSeekMap = true;
    }
    parserState = STATE_READING_ENCRYPTION_DATA;
    return true;
  }

  if (shouldParseContainerAtom(atomType)) {
    long endPosition = input.getPosition() + atomSize - Atom.HEADER_SIZE;
    containerAtoms.add(new ContainerAtom(atomType, endPosition));
    if (atomSize == atomHeaderBytesRead) {
      processAtomEnded(endPosition);
    } else {
      // Start reading the first child atom.
      enterReadingAtomHeaderState();
    }
  } else if (shouldParseLeafAtom(atomType)) {
    if (atomHeaderBytesRead != Atom.HEADER_SIZE) {
      throw new ParserException("Leaf atom defines extended atom size (unsupported).");
    }
    if (atomSize > Integer.MAX_VALUE) {
      throw new ParserException("Leaf atom with length > 2147483647 (unsupported).");
    }
    atomData = new ParsableByteArray((int) atomSize);
    System.arraycopy(atomHeader.data, 0, atomData.data, 0, Atom.HEADER_SIZE);
    parserState = STATE_READING_ATOM_PAYLOAD;
  } else {
    if (atomSize > Integer.MAX_VALUE) {
      throw new ParserException("Skipping atom with length > 2147483647 (unsupported).");
    }
    atomData = null;
    parserState = STATE_READING_ATOM_PAYLOAD;
  }

  return true;
}
项目:K-Sonic    文件:FragmentedMp4Extractor.java   
/**
 * Parses a traf atom (defined in 14496-12).
 */
private static void parseTraf(ContainerAtom traf, SparseArray<TrackBundle> trackBundleArray,
    @Flags int flags, byte[] extendedTypeScratch) throws ParserException {
  LeafAtom tfhd = traf.getLeafAtomOfType(Atom.TYPE_tfhd);
  TrackBundle trackBundle = parseTfhd(tfhd.data, trackBundleArray, flags);
  if (trackBundle == null) {
    return;
  }

  TrackFragment fragment = trackBundle.fragment;
  long decodeTime = fragment.nextFragmentDecodeTime;
  trackBundle.reset();

  LeafAtom tfdtAtom = traf.getLeafAtomOfType(Atom.TYPE_tfdt);
  if (tfdtAtom != null && (flags & FLAG_WORKAROUND_IGNORE_TFDT_BOX) == 0) {
    decodeTime = parseTfdt(traf.getLeafAtomOfType(Atom.TYPE_tfdt).data);
  }

  parseTruns(traf, trackBundle, decodeTime, flags);

  LeafAtom saiz = traf.getLeafAtomOfType(Atom.TYPE_saiz);
  if (saiz != null) {
    TrackEncryptionBox trackEncryptionBox = trackBundle.track
        .sampleDescriptionEncryptionBoxes[fragment.header.sampleDescriptionIndex];
    parseSaiz(trackEncryptionBox, saiz.data, fragment);
  }

  LeafAtom saio = traf.getLeafAtomOfType(Atom.TYPE_saio);
  if (saio != null) {
    parseSaio(saio.data, fragment);
  }

  LeafAtom senc = traf.getLeafAtomOfType(Atom.TYPE_senc);
  if (senc != null) {
    parseSenc(senc.data, fragment);
  }

  LeafAtom sbgp = traf.getLeafAtomOfType(Atom.TYPE_sbgp);
  LeafAtom sgpd = traf.getLeafAtomOfType(Atom.TYPE_sgpd);
  if (sbgp != null && sgpd != null) {
    parseSgpd(sbgp.data, sgpd.data, fragment);
  }

  int leafChildrenSize = traf.leafChildren.size();
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom atom = traf.leafChildren.get(i);
    if (atom.type == Atom.TYPE_uuid) {
      parseUuid(atom.data, fragment, extendedTypeScratch);
    }
  }
}
项目:videoPickPlayer    文件:Mp4Extractor.java   
private boolean readAtomHeader(ExtractorInput input) throws IOException, InterruptedException {
  if (atomHeaderBytesRead == 0) {
    // Read the standard length atom header.
    if (!input.readFully(atomHeader.data, 0, Atom.HEADER_SIZE, true)) {
      return false;
    }
    atomHeaderBytesRead = Atom.HEADER_SIZE;
    atomHeader.setPosition(0);
    atomSize = atomHeader.readUnsignedInt();
    atomType = atomHeader.readInt();
  }

  if (atomSize == Atom.LONG_SIZE_PREFIX) {
    // Read the extended atom size.
    int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
    input.readFully(atomHeader.data, Atom.HEADER_SIZE, headerBytesRemaining);
    atomHeaderBytesRead += headerBytesRemaining;
    atomSize = atomHeader.readUnsignedLongToLong();
  }

  if (shouldParseContainerAtom(atomType)) {
    long endPosition = input.getPosition() + atomSize - atomHeaderBytesRead;
    containerAtoms.add(new ContainerAtom(atomType, endPosition));
    if (atomSize == atomHeaderBytesRead) {
      processAtomEnded(endPosition);
    } else {
      // Start reading the first child atom.
      enterReadingAtomHeaderState();
    }
  } else if (shouldParseLeafAtom(atomType)) {
    // We don't support parsing of leaf atoms that define extended atom sizes, or that have
    // lengths greater than Integer.MAX_VALUE.
    Assertions.checkState(atomHeaderBytesRead == Atom.HEADER_SIZE);
    Assertions.checkState(atomSize <= Integer.MAX_VALUE);
    atomData = new ParsableByteArray((int) atomSize);
    System.arraycopy(atomHeader.data, 0, atomData.data, 0, Atom.HEADER_SIZE);
    parserState = STATE_READING_ATOM_PAYLOAD;
  } else {
    atomData = null;
    parserState = STATE_READING_ATOM_PAYLOAD;
  }

  return true;
}
项目:videoPickPlayer    文件:Mp4Extractor.java   
/**
 * Updates the stored track metadata to reflect the contents of the specified moov atom.
 */
private void processMoovAtom(ContainerAtom moov) throws ParserException {
  long durationUs = C.TIME_UNSET;
  List<Mp4Track> tracks = new ArrayList<>();
  long earliestSampleOffset = Long.MAX_VALUE;

  GaplessInfoHolder gaplessInfoHolder = new GaplessInfoHolder();
  Atom.LeafAtom udta = moov.getLeafAtomOfType(Atom.TYPE_udta);
  if (udta != null) {
    AtomParsers.parseUdta(udta, isQuickTime, gaplessInfoHolder);
  }

  for (int i = 0; i < moov.containerChildren.size(); i++) {
    Atom.ContainerAtom atom = moov.containerChildren.get(i);
    if (atom.type != Atom.TYPE_trak) {
      continue;
    }

    Track track = AtomParsers.parseTrak(atom, moov.getLeafAtomOfType(Atom.TYPE_mvhd),
        C.TIME_UNSET, null, isQuickTime);
    if (track == null) {
      continue;
    }

    Atom.ContainerAtom stblAtom = atom.getContainerAtomOfType(Atom.TYPE_mdia)
        .getContainerAtomOfType(Atom.TYPE_minf).getContainerAtomOfType(Atom.TYPE_stbl);
    TrackSampleTable trackSampleTable = AtomParsers.parseStbl(track, stblAtom, gaplessInfoHolder);
    if (trackSampleTable.sampleCount == 0) {
      continue;
    }

    Mp4Track mp4Track = new Mp4Track(track, trackSampleTable, extractorOutput.track(i));
    // Each sample has up to three bytes of overhead for the start code that replaces its length.
    // Allow ten source samples per output sample, like the platform extractor.
    int maxInputSize = trackSampleTable.maximumSize + 3 * 10;
    Format format = track.format.copyWithMaxInputSize(maxInputSize);
    if (track.type == C.TRACK_TYPE_AUDIO && gaplessInfoHolder.hasGaplessInfo()) {
      format = format.copyWithGaplessInfo(gaplessInfoHolder.encoderDelay,
          gaplessInfoHolder.encoderPadding);
    }
    mp4Track.trackOutput.format(format);

    durationUs = Math.max(durationUs, track.durationUs);
    tracks.add(mp4Track);

    long firstSampleOffset = trackSampleTable.offsets[0];
    if (firstSampleOffset < earliestSampleOffset) {
      earliestSampleOffset = firstSampleOffset;
    }
  }
  this.durationUs = durationUs;
  this.tracks = tracks.toArray(new Mp4Track[tracks.size()]);
  extractorOutput.endTracks();
  extractorOutput.seekMap(this);
}
项目:videoPickPlayer    文件:FragmentedMp4Extractor.java   
private boolean readAtomHeader(ExtractorInput input) throws IOException, InterruptedException {
  if (atomHeaderBytesRead == 0) {
    // Read the standard length atom header.
    if (!input.readFully(atomHeader.data, 0, Atom.HEADER_SIZE, true)) {
      return false;
    }
    atomHeaderBytesRead = Atom.HEADER_SIZE;
    atomHeader.setPosition(0);
    atomSize = atomHeader.readUnsignedInt();
    atomType = atomHeader.readInt();
  }

  if (atomSize == Atom.LONG_SIZE_PREFIX) {
    // Read the extended atom size.
    int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
    input.readFully(atomHeader.data, Atom.HEADER_SIZE, headerBytesRemaining);
    atomHeaderBytesRead += headerBytesRemaining;
    atomSize = atomHeader.readUnsignedLongToLong();
  }

  long atomPosition = input.getPosition() - atomHeaderBytesRead;
  if (atomType == Atom.TYPE_moof) {
    // The data positions may be updated when parsing the tfhd/trun.
    int trackCount = trackBundles.size();
    for (int i = 0; i < trackCount; i++) {
      TrackFragment fragment = trackBundles.valueAt(i).fragment;
      fragment.atomPosition = atomPosition;
      fragment.auxiliaryDataPosition = atomPosition;
      fragment.dataPosition = atomPosition;
    }
  }

  if (atomType == Atom.TYPE_mdat) {
    currentTrackBundle = null;
    endOfMdatPosition = atomPosition + atomSize;
    if (!haveOutputSeekMap) {
      extractorOutput.seekMap(new SeekMap.Unseekable(durationUs));
      haveOutputSeekMap = true;
    }
    parserState = STATE_READING_ENCRYPTION_DATA;
    return true;
  }

  if (shouldParseContainerAtom(atomType)) {
    long endPosition = input.getPosition() + atomSize - Atom.HEADER_SIZE;
    containerAtoms.add(new ContainerAtom(atomType, endPosition));
    if (atomSize == atomHeaderBytesRead) {
      processAtomEnded(endPosition);
    } else {
      // Start reading the first child atom.
      enterReadingAtomHeaderState();
    }
  } else if (shouldParseLeafAtom(atomType)) {
    if (atomHeaderBytesRead != Atom.HEADER_SIZE) {
      throw new ParserException("Leaf atom defines extended atom size (unsupported).");
    }
    if (atomSize > Integer.MAX_VALUE) {
      throw new ParserException("Leaf atom with length > 2147483647 (unsupported).");
    }
    atomData = new ParsableByteArray((int) atomSize);
    System.arraycopy(atomHeader.data, 0, atomData.data, 0, Atom.HEADER_SIZE);
    parserState = STATE_READING_ATOM_PAYLOAD;
  } else {
    if (atomSize > Integer.MAX_VALUE) {
      throw new ParserException("Skipping atom with length > 2147483647 (unsupported).");
    }
    atomData = null;
    parserState = STATE_READING_ATOM_PAYLOAD;
  }

  return true;
}
项目:videoPickPlayer    文件:FragmentedMp4Extractor.java   
/**
 * Parses a traf atom (defined in 14496-12).
 */
private static void parseTraf(ContainerAtom traf, SparseArray<TrackBundle> trackBundleArray,
    @Flags int flags, byte[] extendedTypeScratch) throws ParserException {
  LeafAtom tfhd = traf.getLeafAtomOfType(Atom.TYPE_tfhd);
  TrackBundle trackBundle = parseTfhd(tfhd.data, trackBundleArray, flags);
  if (trackBundle == null) {
    return;
  }

  TrackFragment fragment = trackBundle.fragment;
  long decodeTime = fragment.nextFragmentDecodeTime;
  trackBundle.reset();

  LeafAtom tfdtAtom = traf.getLeafAtomOfType(Atom.TYPE_tfdt);
  if (tfdtAtom != null && (flags & FLAG_WORKAROUND_IGNORE_TFDT_BOX) == 0) {
    decodeTime = parseTfdt(traf.getLeafAtomOfType(Atom.TYPE_tfdt).data);
  }

  parseTruns(traf, trackBundle, decodeTime, flags);

  LeafAtom saiz = traf.getLeafAtomOfType(Atom.TYPE_saiz);
  if (saiz != null) {
    TrackEncryptionBox trackEncryptionBox = trackBundle.track
        .sampleDescriptionEncryptionBoxes[fragment.header.sampleDescriptionIndex];
    parseSaiz(trackEncryptionBox, saiz.data, fragment);
  }

  LeafAtom saio = traf.getLeafAtomOfType(Atom.TYPE_saio);
  if (saio != null) {
    parseSaio(saio.data, fragment);
  }

  LeafAtom senc = traf.getLeafAtomOfType(Atom.TYPE_senc);
  if (senc != null) {
    parseSenc(senc.data, fragment);
  }

  LeafAtom sbgp = traf.getLeafAtomOfType(Atom.TYPE_sbgp);
  LeafAtom sgpd = traf.getLeafAtomOfType(Atom.TYPE_sgpd);
  if (sbgp != null && sgpd != null) {
    parseSgpd(sbgp.data, sgpd.data, fragment);
  }

  int leafChildrenSize = traf.leafChildren.size();
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom atom = traf.leafChildren.get(i);
    if (atom.type == Atom.TYPE_uuid) {
      parseUuid(atom.data, fragment, extendedTypeScratch);
    }
  }
}
项目:transistor    文件:Mp4Extractor.java   
/**
 * Updates the stored track metadata to reflect the contents of the specified moov atom.
 */
private void processMoovAtom(ContainerAtom moov) throws ParserException {
  long durationUs = C.TIME_UNSET;
  List<Mp4Track> tracks = new ArrayList<>();
  long earliestSampleOffset = Long.MAX_VALUE;

  Metadata metadata = null;
  GaplessInfoHolder gaplessInfoHolder = new GaplessInfoHolder();
  Atom.LeafAtom udta = moov.getLeafAtomOfType(Atom.TYPE_udta);
  if (udta != null) {
    metadata = AtomParsers.parseUdta(udta, isQuickTime);
    if (metadata != null) {
      gaplessInfoHolder.setFromMetadata(metadata);
    }
  }

  for (int i = 0; i < moov.containerChildren.size(); i++) {
    Atom.ContainerAtom atom = moov.containerChildren.get(i);
    if (atom.type != Atom.TYPE_trak) {
      continue;
    }

    Track track = AtomParsers.parseTrak(atom, moov.getLeafAtomOfType(Atom.TYPE_mvhd),
        C.TIME_UNSET, null, (flags & FLAG_WORKAROUND_IGNORE_EDIT_LISTS) != 0, isQuickTime);
    if (track == null) {
      continue;
    }

    Atom.ContainerAtom stblAtom = atom.getContainerAtomOfType(Atom.TYPE_mdia)
        .getContainerAtomOfType(Atom.TYPE_minf).getContainerAtomOfType(Atom.TYPE_stbl);
    TrackSampleTable trackSampleTable = AtomParsers.parseStbl(track, stblAtom, gaplessInfoHolder);
    if (trackSampleTable.sampleCount == 0) {
      continue;
    }

    Mp4Track mp4Track = new Mp4Track(track, trackSampleTable,
        extractorOutput.track(i, track.type));
    // Each sample has up to three bytes of overhead for the start code that replaces its length.
    // Allow ten source samples per output sample, like the platform extractor.
    int maxInputSize = trackSampleTable.maximumSize + 3 * 10;
    Format format = track.format.copyWithMaxInputSize(maxInputSize);
    if (track.type == C.TRACK_TYPE_AUDIO) {
      if (gaplessInfoHolder.hasGaplessInfo()) {
        format = format.copyWithGaplessInfo(gaplessInfoHolder.encoderDelay,
            gaplessInfoHolder.encoderPadding);
      }
      if (metadata != null) {
        format = format.copyWithMetadata(metadata);
      }
    }
    mp4Track.trackOutput.format(format);

    durationUs = Math.max(durationUs, track.durationUs);
    tracks.add(mp4Track);

    long firstSampleOffset = trackSampleTable.offsets[0];
    if (firstSampleOffset < earliestSampleOffset) {
      earliestSampleOffset = firstSampleOffset;
    }
  }
  this.durationUs = durationUs;
  this.tracks = tracks.toArray(new Mp4Track[tracks.size()]);
  extractorOutput.endTracks();
  extractorOutput.seekMap(this);
}
项目:transistor    文件:FragmentedMp4Extractor.java   
/**
 * Parses a traf atom (defined in 14496-12).
 */
private static void parseTraf(ContainerAtom traf, SparseArray<TrackBundle> trackBundleArray,
    @Flags int flags, byte[] extendedTypeScratch) throws ParserException {
  LeafAtom tfhd = traf.getLeafAtomOfType(Atom.TYPE_tfhd);
  TrackBundle trackBundle = parseTfhd(tfhd.data, trackBundleArray, flags);
  if (trackBundle == null) {
    return;
  }

  TrackFragment fragment = trackBundle.fragment;
  long decodeTime = fragment.nextFragmentDecodeTime;
  trackBundle.reset();

  LeafAtom tfdtAtom = traf.getLeafAtomOfType(Atom.TYPE_tfdt);
  if (tfdtAtom != null && (flags & FLAG_WORKAROUND_IGNORE_TFDT_BOX) == 0) {
    decodeTime = parseTfdt(traf.getLeafAtomOfType(Atom.TYPE_tfdt).data);
  }

  parseTruns(traf, trackBundle, decodeTime, flags);

  TrackEncryptionBox encryptionBox = trackBundle.track
      .getSampleDescriptionEncryptionBox(fragment.header.sampleDescriptionIndex);

  LeafAtom saiz = traf.getLeafAtomOfType(Atom.TYPE_saiz);
  if (saiz != null) {
    parseSaiz(encryptionBox, saiz.data, fragment);
  }

  LeafAtom saio = traf.getLeafAtomOfType(Atom.TYPE_saio);
  if (saio != null) {
    parseSaio(saio.data, fragment);
  }

  LeafAtom senc = traf.getLeafAtomOfType(Atom.TYPE_senc);
  if (senc != null) {
    parseSenc(senc.data, fragment);
  }

  LeafAtom sbgp = traf.getLeafAtomOfType(Atom.TYPE_sbgp);
  LeafAtom sgpd = traf.getLeafAtomOfType(Atom.TYPE_sgpd);
  if (sbgp != null && sgpd != null) {
    parseSgpd(sbgp.data, sgpd.data, encryptionBox != null ? encryptionBox.schemeType : null,
        fragment);
  }

  int leafChildrenSize = traf.leafChildren.size();
  for (int i = 0; i < leafChildrenSize; i++) {
    LeafAtom atom = traf.leafChildren.get(i);
    if (atom.type == Atom.TYPE_uuid) {
      parseUuid(atom.data, fragment, extendedTypeScratch);
    }
  }
}