private void onMoovContainerAtomRead(ContainerAtom moov) throws ParserException {
    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();
        }
        byte[] psshData = child.data.data;
        drmInitData.put(
            PsshAtomUtil.parseUuid(psshData), new SchemeInitData(MimeTypes.VIDEO_MP4, 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),
            false);
    checkState(track != null);
    trackOutput.format(track.mediaFormat);
  }
 private static void parseMoof(
     Track track,
     DefaultSampleValues extendsDefaults,
     ContainerAtom moof,
     TrackFragment out,
     int workaroundFlags,
     byte[] extendedTypeScratch)
     throws ParserException {
   // This extractor only supports one traf per moof.
   checkState(1 == moof.getChildAtomOfTypeCount(Atom.TYPE_traf));
   parseTraf(
       track,
       extendsDefaults,
       moof.getContainerAtomOfType(Atom.TYPE_traf),
       out,
       workaroundFlags,
       extendedTypeScratch);
 }
  /** Parses a traf atom (defined in 14496-12). */
  private static void parseTraf(
      Track track,
      DefaultSampleValues extendsDefaults,
      ContainerAtom traf,
      TrackFragment out,
      int workaroundFlags,
      byte[] extendedTypeScratch)
      throws ParserException {
    // This extractor only supports one trun per traf.
    checkState(1 == traf.getChildAtomOfTypeCount(Atom.TYPE_trun));
    LeafAtom tfdtAtom = traf.getLeafAtomOfType(Atom.TYPE_tfdt);
    long decodeTime;
    if (tfdtAtom == null || (workaroundFlags & WORKAROUND_IGNORE_TFDT_BOX) != 0) {
      decodeTime = 0;
    } else {
      decodeTime = parseTfdt(traf.getLeafAtomOfType(Atom.TYPE_tfdt).data);
    }

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

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

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

    LeafAtom saio = traf.getLeafAtomOfType(Atom.TYPE_saio);
    if (saio != null) {
      parseSaio(saio.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);
      }
    }
  }