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

项目:miku    文件:FragmentedMp4Extractor.java   
private void onMoovContainerAtomRead(ContainerAtom moov) {
  List<Atom.LeafAtom> moovChildren = moov.leafChildren;
  int moovChildrenSize = moovChildren.size();

  DrmInitData.Mapped drmInitData = null;
  for (int i = 0; i < moovChildrenSize; i++) {
    LeafAtom child = moovChildren.get(i);
    if (child.type == Atom.TYPE_pssh) {
      if (drmInitData == null) {
        drmInitData = new DrmInitData.Mapped(MimeTypes.VIDEO_MP4);
      }
      byte[] psshData = child.data.data;
      drmInitData.put(PsshAtomUtil.parseUuid(psshData), psshData);
    }
  }
  if (drmInitData != null) {
    extractorOutput.drmInitData(drmInitData);
  }

  ContainerAtom mvex = moov.getContainerAtomOfType(Atom.TYPE_mvex);
  extendsDefaults = parseTrex(mvex.getLeafAtomOfType(Atom.TYPE_trex).data);
  track = AtomParsers.parseTrak(moov.getContainerAtomOfType(Atom.TYPE_trak),
      moov.getLeafAtomOfType(Atom.TYPE_mvhd));
  Assertions.checkState(track != null);
  trackOutput.format(track.mediaFormat);
}
项目:ExoPlayer-Demo    文件: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();
  }
}
项目:ExoPlayer    文件:FragmentedMp4Extractor.java   
private void onMoovContainerAtomRead(ContainerAtom moov) {
  List<Atom.LeafAtom> moovChildren = moov.leafChildren;
  int moovChildrenSize = moovChildren.size();

  DrmInitData.Mapped drmInitData = null;
  for (int i = 0; i < moovChildrenSize; i++) {
    LeafAtom child = moovChildren.get(i);
    if (child.type == Atom.TYPE_pssh) {
      if (drmInitData == null) {
        drmInitData = new DrmInitData.Mapped(MimeTypes.VIDEO_MP4);
      }
      byte[] psshData = child.data.data;
      drmInitData.put(PsshAtomUtil.parseUuid(psshData), psshData);
    }
  }
  if (drmInitData != null) {
    extractorOutput.drmInitData(drmInitData);
  }

  ContainerAtom mvex = moov.getContainerAtomOfType(Atom.TYPE_mvex);
  extendsDefaults = parseTrex(mvex.getLeafAtomOfType(Atom.TYPE_trex).data);
  track = AtomParsers.parseTrak(moov.getContainerAtomOfType(Atom.TYPE_trak),
      moov.getLeafAtomOfType(Atom.TYPE_mvhd));
  Assertions.checkState(track != null);
  trackOutput.format(track.mediaFormat);
}
项目:miku    文件: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));
    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;
}
项目:miku    文件:Mp4Extractor.java   
/**
 * Processes the atom payload. If {@link #atomData} is null and the size is at or above the
 * threshold {@link #RELOAD_MINIMUM_SEEK_DISTANCE}, {@code true} is returned and the caller should
 * restart loading at the position in {@code positionHolder}. Otherwise, the atom is read/skipped.
 */
private boolean readAtomPayload(ExtractorInput input, PositionHolder positionHolder)
    throws IOException, InterruptedException {
  long atomPayloadSize = atomSize - atomHeaderBytesRead;
  long atomEndPosition = input.getPosition() + atomPayloadSize;
  boolean seekRequired = false;
  if (atomData != null) {
    input.readFully(atomData.data, atomHeaderBytesRead, (int) atomPayloadSize);
    if (!containerAtoms.isEmpty()) {
      containerAtoms.peek().add(new Atom.LeafAtom(atomType, atomData));
    }
  } else {
    // We don't need the data. Skip or seek, depending on how large the atom is.
    if (atomPayloadSize < RELOAD_MINIMUM_SEEK_DISTANCE) {
      input.skipFully((int) atomPayloadSize);
    } else {
      positionHolder.position = input.getPosition() + atomPayloadSize;
      seekRequired = true;
    }
  }

  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;
      return false;
    } else if (!containerAtoms.isEmpty()) {
      containerAtoms.peek().add(containerAtom);
    }
  }

  enterReadingAtomHeaderState();
  return seekRequired;
}
项目:miku    文件:Mp4Extractor.java   
/** Updates the stored track metadata to reflect the contents of the specified moov atom. */
private void processMoovAtom(ContainerAtom moov) {
  List<Mp4Track> tracks = new ArrayList<>();
  long earliestSampleOffset = Long.MAX_VALUE;
  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));
    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);
    if (trackSampleTable.sampleCount == 0) {
      continue;
    }

    Mp4Track mp4Track = new Mp4Track(track, trackSampleTable, extractorOutput.track(i));
    mp4Track.trackOutput.format(track.mediaFormat);
    tracks.add(mp4Track);

    long firstSampleOffset = trackSampleTable.offsets[0];
    if (firstSampleOffset < earliestSampleOffset) {
      earliestSampleOffset = firstSampleOffset;
    }
  }
  this.tracks = tracks.toArray(new Mp4Track[0]);
  extractorOutput.endTracks();
  extractorOutput.seekMap(this);
}
项目:miku    文件:FragmentedMp4Extractor.java   
private void onContainerAtomRead(ContainerAtom container) {
  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);
  }
}
项目:miku    文件:FragmentedMp4Extractor.java   
/**
 * Parses a traf atom (defined in 14496-12).
 */
private static void parseTraf(Track track, DefaultSampleValues extendsDefaults,
    ContainerAtom traf, TrackFragment out, int workaroundFlags, byte[] extendedTypeScratch) {
  LeafAtom tfdtAtom = traf.getLeafAtomOfType(Atom.TYPE_tfdt);
  long decodeTime = tfdtAtom == null ? 0 : parseTfdt(traf.getLeafAtomOfType(Atom.TYPE_tfdt).data);

  LeafAtom tfhd = traf.getLeafAtomOfType(Atom.TYPE_tfhd);
  DefaultSampleValues fragmentHeader = parseTfhd(extendsDefaults, tfhd.data);
  out.sampleDescriptionIndex = fragmentHeader.sampleDescriptionIndex;

  LeafAtom trun = traf.getLeafAtomOfType(Atom.TYPE_trun);
  parseTrun(track, fragmentHeader, decodeTime, workaroundFlags, trun.data, out);

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

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

  int childrenSize = traf.leafChildren.size();
  for (int i = 0; i < childrenSize; i++) {
    LeafAtom atom = traf.leafChildren.get(i);
    if (atom.type == Atom.TYPE_uuid) {
      parseUuid(atom.data, out, extendedTypeScratch);
    }
  }
}
项目:ExoPlayer-Demo    文件: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);
  }
}
项目:ExoPlayer-Demo    文件:FragmentedMp4Extractor.java   
private static void parseMoof(ContainerAtom moof, SparseArray<TrackBundle> trackBundleArray,
    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);
    if (child.type == Atom.TYPE_traf) {
      parseTraf(child, trackBundleArray, flags, extendedTypeScratch);
    }
  }
}
项目:ExoPlayer    文件: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));
    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;
}
项目:ExoPlayer    文件:Mp4Extractor.java   
/**
 * Processes the atom payload. If {@link #atomData} is null and the size is at or above the
 * threshold {@link #RELOAD_MINIMUM_SEEK_DISTANCE}, {@code true} is returned and the caller should
 * restart loading at the position in {@code positionHolder}. Otherwise, the atom is read/skipped.
 */
private boolean readAtomPayload(ExtractorInput input, PositionHolder positionHolder)
    throws IOException, InterruptedException {
  long atomPayloadSize = atomSize - atomHeaderBytesRead;
  long atomEndPosition = input.getPosition() + atomPayloadSize;
  boolean seekRequired = false;
  if (atomData != null) {
    input.readFully(atomData.data, atomHeaderBytesRead, (int) atomPayloadSize);
    if (!containerAtoms.isEmpty()) {
      containerAtoms.peek().add(new Atom.LeafAtom(atomType, atomData));
    }
  } else {
    // We don't need the data. Skip or seek, depending on how large the atom is.
    if (atomPayloadSize < RELOAD_MINIMUM_SEEK_DISTANCE) {
      input.skipFully((int) atomPayloadSize);
    } else {
      positionHolder.position = input.getPosition() + atomPayloadSize;
      seekRequired = true;
    }
  }

  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;
      return false;
    } else if (!containerAtoms.isEmpty()) {
      containerAtoms.peek().add(containerAtom);
    }
  }

  enterReadingAtomHeaderState();
  return seekRequired;
}
项目:ExoPlayer    文件:Mp4Extractor.java   
/** Updates the stored track metadata to reflect the contents of the specified moov atom. */
private void processMoovAtom(ContainerAtom moov) {
  List<Mp4Track> tracks = new ArrayList<>();
  long earliestSampleOffset = Long.MAX_VALUE;
  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));
    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);
    if (trackSampleTable.sampleCount == 0) {
      continue;
    }

    Mp4Track mp4Track = new Mp4Track(track, trackSampleTable, extractorOutput.track(i));
    mp4Track.trackOutput.format(track.mediaFormat);
    tracks.add(mp4Track);

    long firstSampleOffset = trackSampleTable.offsets[0];
    if (firstSampleOffset < earliestSampleOffset) {
      earliestSampleOffset = firstSampleOffset;
    }
  }
  this.tracks = tracks.toArray(new Mp4Track[0]);
  extractorOutput.endTracks();
  extractorOutput.seekMap(this);
}
项目:ExoPlayer    文件:FragmentedMp4Extractor.java   
private void onContainerAtomRead(ContainerAtom container) {
  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);
  }
}
项目:ExoPlayer    文件:FragmentedMp4Extractor.java   
/**
 * Parses a traf atom (defined in 14496-12).
 */
private static void parseTraf(Track track, DefaultSampleValues extendsDefaults,
    ContainerAtom traf, TrackFragment out, int workaroundFlags, byte[] extendedTypeScratch) {
  LeafAtom tfdtAtom = traf.getLeafAtomOfType(Atom.TYPE_tfdt);
  long decodeTime = tfdtAtom == null ? 0 : parseTfdt(traf.getLeafAtomOfType(Atom.TYPE_tfdt).data);

  LeafAtom tfhd = traf.getLeafAtomOfType(Atom.TYPE_tfhd);
  DefaultSampleValues fragmentHeader = parseTfhd(extendsDefaults, tfhd.data);
  out.sampleDescriptionIndex = fragmentHeader.sampleDescriptionIndex;

  LeafAtom trun = traf.getLeafAtomOfType(Atom.TYPE_trun);
  parseTrun(track, fragmentHeader, decodeTime, workaroundFlags, trun.data, out);

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

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

  int childrenSize = traf.leafChildren.size();
  for (int i = 0; i < childrenSize; i++) {
    LeafAtom atom = traf.leafChildren.get(i);
    if (atom.type == Atom.TYPE_uuid) {
      parseUuid(atom.data, out, extendedTypeScratch);
    }
  }
}
项目:miku    文件: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 (atomType == Atom.TYPE_mdat) {
    if (!haveOutputSeekMap) {
      extractorOutput.seekMap(SeekMap.UNSEEKABLE);
      haveOutputSeekMap = true;
    }
    if (fragmentRun.sampleEncryptionDataNeedsFill) {
      parserState = STATE_READING_ENCRYPTION_DATA;
    } else {
      parserState = STATE_READING_SAMPLE_START;
    }
    return true;
  }

  if (shouldParseAtom(atomType)) {
    if (shouldParseContainerAtom(atomType)) {
      long endPosition = input.getPosition() + atomSize - Atom.HEADER_SIZE;
      containerAtoms.add(new ContainerAtom(atomType, endPosition));
      enterReadingAtomHeaderState();
    } else {
      // 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 {
    // We don't support skipping of atoms that have lengths greater than Integer.MAX_VALUE.
    Assertions.checkState(atomSize <= Integer.MAX_VALUE);
    atomData = null;
    parserState = STATE_READING_ATOM_PAYLOAD;
  }

  return true;
}
项目:miku    文件:FragmentedMp4Extractor.java   
private void onMoofContainerAtomRead(ContainerAtom moof) {
  fragmentRun.reset();
  parseMoof(track, extendsDefaults, moof, fragmentRun, workaroundFlags, extendedTypeScratch);
  sampleIndex = 0;
}
项目:miku    文件:FragmentedMp4Extractor.java   
private static void parseMoof(Track track, DefaultSampleValues extendsDefaults,
    ContainerAtom moof, TrackFragment out, int workaroundFlags, byte[] extendedTypeScratch) {
  parseTraf(track, extendsDefaults, moof.getContainerAtomOfType(Atom.TYPE_traf),
      out, workaroundFlags, extendedTypeScratch);
}
项目:ExoPlayer-Demo    文件: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;
}
项目:ExoPlayer-Demo    文件:Mp4Extractor.java   
/**
 * Updates the stored track metadata to reflect the contents of the specified moov atom.
 */
private void processMoovAtom(ContainerAtom moov) throws ParserException {
  List<Mp4Track> tracks = new ArrayList<>();
  long earliestSampleOffset = Long.MAX_VALUE;
  GaplessInfo gaplessInfo = null;
  Atom.LeafAtom udta = moov.getLeafAtomOfType(Atom.TYPE_udta);
  if (udta != null) {
    gaplessInfo = AtomParsers.parseUdta(udta, isQuickTime);
  }
  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), -1,
        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);
    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;
    MediaFormat mediaFormat = track.mediaFormat.copyWithMaxInputSize(maxInputSize);
    if (gaplessInfo != null) {
      mediaFormat =
          mediaFormat.copyWithGaplessInfo(gaplessInfo.encoderDelay, gaplessInfo.encoderPadding);
    }
    mp4Track.trackOutput.format(mediaFormat);
    tracks.add(mp4Track);

    long firstSampleOffset = trackSampleTable.offsets[0];
    if (firstSampleOffset < earliestSampleOffset) {
      earliestSampleOffset = firstSampleOffset;
    }
  }
  this.tracks = tracks.toArray(new Mp4Track[0]);
  extractorOutput.endTracks();
  extractorOutput.seekMap(this);
}
项目:ExoPlayer-Demo    文件: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.auxiliaryDataPosition = atomPosition;
      fragment.dataPosition = atomPosition;
    }
  }

  if (atomType == Atom.TYPE_mdat) {
    currentTrackBundle = null;
    endOfMdatPosition = atomPosition + atomSize;
    if (!haveOutputSeekMap) {
      extractorOutput.seekMap(SeekMap.UNSEEKABLE);
      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;
}
项目:ExoPlayer-Demo    文件:FragmentedMp4Extractor.java   
private void onMoofContainerAtomRead(ContainerAtom moof) throws ParserException {
  parseMoof(moof, trackBundles, flags, extendedTypeScratch);
}
项目:ExoPlayer-Demo    文件:FragmentedMp4Extractor.java   
/**
 * Parses a traf atom (defined in 14496-12).
 */
private static void parseTraf(ContainerAtom traf, SparseArray<TrackBundle> trackBundleArray,
    int flags, byte[] extendedTypeScratch) throws ParserException {
  if (traf.getChildAtomOfTypeCount(Atom.TYPE_trun) != 1) {
    throw new ParserException("Trun count in traf != 1 (unsupported).");
  }

  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);
  }

  LeafAtom trun = traf.getLeafAtomOfType(Atom.TYPE_trun);
  parseTrun(trackBundle, decodeTime, flags, trun.data);

  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 childrenSize = traf.leafChildren.size();
  for (int i = 0; i < childrenSize; i++) {
    LeafAtom atom = traf.leafChildren.get(i);
    if (atom.type == Atom.TYPE_uuid) {
      parseUuid(atom.data, fragment, extendedTypeScratch);
    }
  }
}
项目:ExoPlayer    文件: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 (atomType == Atom.TYPE_mdat) {
    if (!haveOutputSeekMap) {
      extractorOutput.seekMap(SeekMap.UNSEEKABLE);
      haveOutputSeekMap = true;
    }
    if (fragmentRun.sampleEncryptionDataNeedsFill) {
      parserState = STATE_READING_ENCRYPTION_DATA;
    } else {
      parserState = STATE_READING_SAMPLE_START;
    }
    return true;
  }

  if (shouldParseAtom(atomType)) {
    if (shouldParseContainerAtom(atomType)) {
      long endPosition = input.getPosition() + atomSize - Atom.HEADER_SIZE;
      containerAtoms.add(new ContainerAtom(atomType, endPosition));
      enterReadingAtomHeaderState();
    } else {
      // 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 {
    // We don't support skipping of atoms that have lengths greater than Integer.MAX_VALUE.
    Assertions.checkState(atomSize <= Integer.MAX_VALUE);
    atomData = null;
    parserState = STATE_READING_ATOM_PAYLOAD;
  }

  return true;
}
项目:ExoPlayer    文件:FragmentedMp4Extractor.java   
private void onMoofContainerAtomRead(ContainerAtom moof) {
  fragmentRun.reset();
  parseMoof(track, extendsDefaults, moof, fragmentRun, workaroundFlags, extendedTypeScratch);
  sampleIndex = 0;
}
项目:ExoPlayer    文件:FragmentedMp4Extractor.java   
private static void parseMoof(Track track, DefaultSampleValues extendsDefaults,
    ContainerAtom moof, TrackFragment out, int workaroundFlags, byte[] extendedTypeScratch) {
  parseTraf(track, extendsDefaults, moof.getContainerAtomOfType(Atom.TYPE_traf),
      out, workaroundFlags, extendedTypeScratch);
}