Java Code Examples for com.google.android.exoplayer2.util.ParsableByteArray#readUnsignedLongToLong()

The following examples show how to use com.google.android.exoplayer2.util.ParsableByteArray#readUnsignedLongToLong() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: AtomParsers.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * Parses the edts atom (defined in 14496-12 subsection 8.6.5).
 *
 * @param edtsAtom edts (edit box) atom to decode.
 * @return Pair of edit list durations and edit list media times, or a pair of nulls if they are
 *     not present.
 */
private static Pair<long[], long[]> parseEdts(Atom.ContainerAtom edtsAtom) {
  Atom.LeafAtom elst;
  if (edtsAtom == null || (elst = edtsAtom.getLeafAtomOfType(Atom.TYPE_elst)) == null) {
    return Pair.create(null, null);
  }
  ParsableByteArray elstData = elst.data;
  elstData.setPosition(Atom.HEADER_SIZE);
  int fullAtom = elstData.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  int entryCount = elstData.readUnsignedIntToInt();
  long[] editListDurations = new long[entryCount];
  long[] editListMediaTimes = new long[entryCount];
  for (int i = 0; i < entryCount; i++) {
    editListDurations[i] =
        version == 1 ? elstData.readUnsignedLongToLong() : elstData.readUnsignedInt();
    editListMediaTimes[i] = version == 1 ? elstData.readLong() : elstData.readInt();
    int mediaRateInteger = elstData.readShort();
    if (mediaRateInteger != 1) {
      // The extractor does not handle dwell edits (mediaRateInteger == 0).
      throw new IllegalArgumentException("Unsupported media rate.");
    }
    elstData.skipBytes(2);
  }
  return Pair.create(editListDurations, editListMediaTimes);
}
 
Example 2
Source File: FragmentedMp4Extractor.java    From K-Sonic with MIT License 6 votes vote down vote up
/**
 * Parses a saio atom (defined in 14496-12).
 *
 * @param saio The saio atom to decode.
 * @param out The {@link TrackFragment} to populate with data from the saio atom.
 */
private static void parseSaio(ParsableByteArray saio, TrackFragment out) throws ParserException {
  saio.setPosition(Atom.HEADER_SIZE);
  int fullAtom = saio.readInt();
  int flags = Atom.parseFullAtomFlags(fullAtom);
  if ((flags & 0x01) == 1) {
    saio.skipBytes(8);
  }

  int entryCount = saio.readUnsignedIntToInt();
  if (entryCount != 1) {
    // We only support one trun element currently, so always expect one entry.
    throw new ParserException("Unexpected saio entry count: " + entryCount);
  }

  int version = Atom.parseFullAtomVersion(fullAtom);
  out.auxiliaryDataPosition +=
      version == 0 ? saio.readUnsignedInt() : saio.readUnsignedLongToLong();
}
 
Example 3
Source File: FragmentedMp4Extractor.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * Parses a saio atom (defined in 14496-12).
 *
 * @param saio The saio atom to decode.
 * @param out The {@link TrackFragment} to populate with data from the saio atom.
 */
private static void parseSaio(ParsableByteArray saio, TrackFragment out) throws ParserException {
  saio.setPosition(Atom.HEADER_SIZE);
  int fullAtom = saio.readInt();
  int flags = Atom.parseFullAtomFlags(fullAtom);
  if ((flags & 0x01) == 1) {
    saio.skipBytes(8);
  }

  int entryCount = saio.readUnsignedIntToInt();
  if (entryCount != 1) {
    // We only support one trun element currently, so always expect one entry.
    throw new ParserException("Unexpected saio entry count: " + entryCount);
  }

  int version = Atom.parseFullAtomVersion(fullAtom);
  out.auxiliaryDataPosition +=
      version == 0 ? saio.readUnsignedInt() : saio.readUnsignedLongToLong();
}
 
Example 4
Source File: FragmentedMp4Extractor.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Parses a saio atom (defined in 14496-12).
 *
 * @param saio The saio atom to decode.
 * @param out The {@link TrackFragment} to populate with data from the saio atom.
 */
private static void parseSaio(ParsableByteArray saio, TrackFragment out) throws ParserException {
  saio.setPosition(Atom.HEADER_SIZE);
  int fullAtom = saio.readInt();
  int flags = Atom.parseFullAtomFlags(fullAtom);
  if ((flags & 0x01) == 1) {
    saio.skipBytes(8);
  }

  int entryCount = saio.readUnsignedIntToInt();
  if (entryCount != 1) {
    // We only support one trun element currently, so always expect one entry.
    throw new ParserException("Unexpected saio entry count: " + entryCount);
  }

  int version = Atom.parseFullAtomVersion(fullAtom);
  out.auxiliaryDataPosition +=
      version == 0 ? saio.readUnsignedInt() : saio.readUnsignedLongToLong();
}
 
Example 5
Source File: AtomParsers.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Parses the edts atom (defined in 14496-12 subsection 8.6.5).
 *
 * @param edtsAtom edts (edit box) atom to decode.
 * @return Pair of edit list durations and edit list media times, or a pair of nulls if they are
 *     not present.
 */
private static Pair<long[], long[]> parseEdts(Atom.ContainerAtom edtsAtom) {
  Atom.LeafAtom elst;
  if (edtsAtom == null || (elst = edtsAtom.getLeafAtomOfType(Atom.TYPE_elst)) == null) {
    return Pair.create(null, null);
  }
  ParsableByteArray elstData = elst.data;
  elstData.setPosition(Atom.HEADER_SIZE);
  int fullAtom = elstData.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  int entryCount = elstData.readUnsignedIntToInt();
  long[] editListDurations = new long[entryCount];
  long[] editListMediaTimes = new long[entryCount];
  for (int i = 0; i < entryCount; i++) {
    editListDurations[i] =
        version == 1 ? elstData.readUnsignedLongToLong() : elstData.readUnsignedInt();
    editListMediaTimes[i] = version == 1 ? elstData.readLong() : elstData.readInt();
    int mediaRateInteger = elstData.readShort();
    if (mediaRateInteger != 1) {
      // The extractor does not handle dwell edits (mediaRateInteger == 0).
      throw new IllegalArgumentException("Unsupported media rate.");
    }
    elstData.skipBytes(2);
  }
  return Pair.create(editListDurations, editListMediaTimes);
}
 
Example 6
Source File: AtomParsers.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Parses the edts atom (defined in 14496-12 subsection 8.6.5).
 *
 * @param edtsAtom edts (edit box) atom to decode.
 * @return Pair of edit list durations and edit list media times, or a pair of nulls if they are
 *     not present.
 */
private static Pair<long[], long[]> parseEdts(Atom.ContainerAtom edtsAtom) {
  Atom.LeafAtom elst;
  if (edtsAtom == null || (elst = edtsAtom.getLeafAtomOfType(Atom.TYPE_elst)) == null) {
    return Pair.create(null, null);
  }
  ParsableByteArray elstData = elst.data;
  elstData.setPosition(Atom.HEADER_SIZE);
  int fullAtom = elstData.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  int entryCount = elstData.readUnsignedIntToInt();
  long[] editListDurations = new long[entryCount];
  long[] editListMediaTimes = new long[entryCount];
  for (int i = 0; i < entryCount; i++) {
    editListDurations[i] =
        version == 1 ? elstData.readUnsignedLongToLong() : elstData.readUnsignedInt();
    editListMediaTimes[i] = version == 1 ? elstData.readLong() : elstData.readInt();
    int mediaRateInteger = elstData.readShort();
    if (mediaRateInteger != 1) {
      // The extractor does not handle dwell edits (mediaRateInteger == 0).
      throw new IllegalArgumentException("Unsupported media rate.");
    }
    elstData.skipBytes(2);
  }
  return Pair.create(editListDurations, editListMediaTimes);
}
 
Example 7
Source File: AtomParsers.java    From K-Sonic with MIT License 6 votes vote down vote up
/**
 * Parses the edts atom (defined in 14496-12 subsection 8.6.5).
 *
 * @param edtsAtom edts (edit box) atom to decode.
 * @return Pair of edit list durations and edit list media times, or a pair of nulls if they are
 * not present.
 */
private static Pair<long[], long[]> parseEdts(Atom.ContainerAtom edtsAtom) {
  Atom.LeafAtom elst;
  if (edtsAtom == null || (elst = edtsAtom.getLeafAtomOfType(Atom.TYPE_elst)) == null) {
    return Pair.create(null, null);
  }
  ParsableByteArray elstData = elst.data;
  elstData.setPosition(Atom.HEADER_SIZE);
  int fullAtom = elstData.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  int entryCount = elstData.readUnsignedIntToInt();
  long[] editListDurations = new long[entryCount];
  long[] editListMediaTimes = new long[entryCount];
  for (int i = 0; i < entryCount; i++) {
    editListDurations[i] =
        version == 1 ? elstData.readUnsignedLongToLong() : elstData.readUnsignedInt();
    editListMediaTimes[i] = version == 1 ? elstData.readLong() : elstData.readInt();
    int mediaRateInteger = elstData.readShort();
    if (mediaRateInteger != 1) {
      // The extractor does not handle dwell edits (mediaRateInteger == 0).
      throw new IllegalArgumentException("Unsupported media rate.");
    }
    elstData.skipBytes(2);
  }
  return Pair.create(editListDurations, editListMediaTimes);
}
 
Example 8
Source File: FragmentedMp4Extractor.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Parses a saio atom (defined in 14496-12).
 *
 * @param saio The saio atom to decode.
 * @param out The {@link TrackFragment} to populate with data from the saio atom.
 */
private static void parseSaio(ParsableByteArray saio, TrackFragment out) throws ParserException {
  saio.setPosition(Atom.HEADER_SIZE);
  int fullAtom = saio.readInt();
  int flags = Atom.parseFullAtomFlags(fullAtom);
  if ((flags & 0x01) == 1) {
    saio.skipBytes(8);
  }

  int entryCount = saio.readUnsignedIntToInt();
  if (entryCount != 1) {
    // We only support one trun element currently, so always expect one entry.
    throw new ParserException("Unexpected saio entry count: " + entryCount);
  }

  int version = Atom.parseFullAtomVersion(fullAtom);
  out.auxiliaryDataPosition +=
      version == 0 ? saio.readUnsignedInt() : saio.readUnsignedLongToLong();
}
 
Example 9
Source File: FragmentedMp4Extractor.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses a tfhd atom (defined in 14496-12), updates the corresponding {@link TrackFragment} and
 * returns the {@link TrackBundle} of the corresponding {@link Track}. If the tfhd does not refer
 * to any {@link TrackBundle}, {@code null} is returned and no changes are made.
 *
 * @param tfhd The tfhd atom to decode.
 * @param trackBundles The track bundles, one of which corresponds to the tfhd atom being parsed.
 * @return The {@link TrackBundle} to which the {@link TrackFragment} belongs, or null if the tfhd
 *     does not refer to any {@link TrackBundle}.
 */
private static TrackBundle parseTfhd(
    ParsableByteArray tfhd, SparseArray<TrackBundle> trackBundles) {
  tfhd.setPosition(Atom.HEADER_SIZE);
  int fullAtom = tfhd.readInt();
  int atomFlags = Atom.parseFullAtomFlags(fullAtom);
  int trackId = tfhd.readInt();
  TrackBundle trackBundle = getTrackBundle(trackBundles, trackId);
  if (trackBundle == null) {
    return null;
  }
  if ((atomFlags & 0x01 /* base_data_offset_present */) != 0) {
    long baseDataPosition = tfhd.readUnsignedLongToLong();
    trackBundle.fragment.dataPosition = baseDataPosition;
    trackBundle.fragment.auxiliaryDataPosition = baseDataPosition;
  }

  DefaultSampleValues defaultSampleValues = trackBundle.defaultSampleValues;
  int defaultSampleDescriptionIndex =
      ((atomFlags & 0x02 /* default_sample_description_index_present */) != 0)
          ? tfhd.readUnsignedIntToInt() - 1 : defaultSampleValues.sampleDescriptionIndex;
  int defaultSampleDuration = ((atomFlags & 0x08 /* default_sample_duration_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.duration;
  int defaultSampleSize = ((atomFlags & 0x10 /* default_sample_size_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.size;
  int defaultSampleFlags = ((atomFlags & 0x20 /* default_sample_flags_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.flags;
  trackBundle.fragment.header = new DefaultSampleValues(defaultSampleDescriptionIndex,
      defaultSampleDuration, defaultSampleSize, defaultSampleFlags);
  return trackBundle;
}
 
Example 10
Source File: FragmentedMp4Extractor.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses a tfdt atom (defined in 14496-12).
 *
 * @return baseMediaDecodeTime The sum of the decode durations of all earlier samples in the
 *     media, expressed in the media's timescale.
 */
private static long parseTfdt(ParsableByteArray tfdt) {
  tfdt.setPosition(Atom.HEADER_SIZE);
  int fullAtom = tfdt.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  return version == 1 ? tfdt.readUnsignedLongToLong() : tfdt.readUnsignedInt();
}
 
Example 11
Source File: FragmentedMp4Extractor.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses a tfdt atom (defined in 14496-12).
 *
 * @return baseMediaDecodeTime The sum of the decode durations of all earlier samples in the
 *     media, expressed in the media's timescale.
 */
private static long parseTfdt(ParsableByteArray tfdt) {
  tfdt.setPosition(Atom.HEADER_SIZE);
  int fullAtom = tfdt.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  return version == 1 ? tfdt.readUnsignedLongToLong() : tfdt.readUnsignedInt();
}
 
Example 12
Source File: FragmentedMp4Extractor.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses an mehd atom (defined in 14496-12).
 */
private static long parseMehd(ParsableByteArray mehd) {
  mehd.setPosition(Atom.HEADER_SIZE);
  int fullAtom = mehd.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  return version == 0 ? mehd.readUnsignedInt() : mehd.readUnsignedLongToLong();
}
 
Example 13
Source File: FragmentedMp4Extractor.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses a tfhd atom (defined in 14496-12), updates the corresponding {@link TrackFragment} and
 * returns the {@link TrackBundle} of the corresponding {@link Track}. If the tfhd does not refer
 * to any {@link TrackBundle}, {@code null} is returned and no changes are made.
 *
 * @param tfhd The tfhd atom to decode.
 * @param trackBundles The track bundles, one of which corresponds to the tfhd atom being parsed.
 * @return The {@link TrackBundle} to which the {@link TrackFragment} belongs, or null if the tfhd
 *     does not refer to any {@link TrackBundle}.
 */
private static TrackBundle parseTfhd(
    ParsableByteArray tfhd, SparseArray<TrackBundle> trackBundles) {
  tfhd.setPosition(Atom.HEADER_SIZE);
  int fullAtom = tfhd.readInt();
  int atomFlags = Atom.parseFullAtomFlags(fullAtom);
  int trackId = tfhd.readInt();
  TrackBundle trackBundle = getTrackBundle(trackBundles, trackId);
  if (trackBundle == null) {
    return null;
  }
  if ((atomFlags & 0x01 /* base_data_offset_present */) != 0) {
    long baseDataPosition = tfhd.readUnsignedLongToLong();
    trackBundle.fragment.dataPosition = baseDataPosition;
    trackBundle.fragment.auxiliaryDataPosition = baseDataPosition;
  }

  DefaultSampleValues defaultSampleValues = trackBundle.defaultSampleValues;
  int defaultSampleDescriptionIndex =
      ((atomFlags & 0x02 /* default_sample_description_index_present */) != 0)
          ? tfhd.readUnsignedIntToInt() - 1 : defaultSampleValues.sampleDescriptionIndex;
  int defaultSampleDuration = ((atomFlags & 0x08 /* default_sample_duration_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.duration;
  int defaultSampleSize = ((atomFlags & 0x10 /* default_sample_size_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.size;
  int defaultSampleFlags = ((atomFlags & 0x20 /* default_sample_flags_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.flags;
  trackBundle.fragment.header = new DefaultSampleValues(defaultSampleDescriptionIndex,
      defaultSampleDuration, defaultSampleSize, defaultSampleFlags);
  return trackBundle;
}
 
Example 14
Source File: FragmentedMp4Extractor.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses a tfhd atom (defined in 14496-12), updates the corresponding {@link TrackFragment} and
 * returns the {@link TrackBundle} of the corresponding {@link Track}. If the tfhd does not refer
 * to any {@link TrackBundle}, {@code null} is returned and no changes are made.
 *
 * @param tfhd The tfhd atom to decode.
 * @param trackBundles The track bundles, one of which corresponds to the tfhd atom being parsed.
 * @return The {@link TrackBundle} to which the {@link TrackFragment} belongs, or null if the tfhd
 *     does not refer to any {@link TrackBundle}.
 */
private static TrackBundle parseTfhd(
    ParsableByteArray tfhd, SparseArray<TrackBundle> trackBundles) {
  tfhd.setPosition(Atom.HEADER_SIZE);
  int fullAtom = tfhd.readInt();
  int atomFlags = Atom.parseFullAtomFlags(fullAtom);
  int trackId = tfhd.readInt();
  TrackBundle trackBundle = getTrackBundle(trackBundles, trackId);
  if (trackBundle == null) {
    return null;
  }
  if ((atomFlags & 0x01 /* base_data_offset_present */) != 0) {
    long baseDataPosition = tfhd.readUnsignedLongToLong();
    trackBundle.fragment.dataPosition = baseDataPosition;
    trackBundle.fragment.auxiliaryDataPosition = baseDataPosition;
  }

  DefaultSampleValues defaultSampleValues = trackBundle.defaultSampleValues;
  int defaultSampleDescriptionIndex =
      ((atomFlags & 0x02 /* default_sample_description_index_present */) != 0)
          ? tfhd.readUnsignedIntToInt() - 1 : defaultSampleValues.sampleDescriptionIndex;
  int defaultSampleDuration = ((atomFlags & 0x08 /* default_sample_duration_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.duration;
  int defaultSampleSize = ((atomFlags & 0x10 /* default_sample_size_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.size;
  int defaultSampleFlags = ((atomFlags & 0x20 /* default_sample_flags_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.flags;
  trackBundle.fragment.header = new DefaultSampleValues(defaultSampleDescriptionIndex,
      defaultSampleDuration, defaultSampleSize, defaultSampleFlags);
  return trackBundle;
}
 
Example 15
Source File: FragmentedMp4Extractor.java    From K-Sonic with MIT License 5 votes vote down vote up
/**
 * Parses a tfhd atom (defined in 14496-12), updates the corresponding {@link TrackFragment} and
 * returns the {@link TrackBundle} of the corresponding {@link Track}. If the tfhd does not refer
 * to any {@link TrackBundle}, {@code null} is returned and no changes are made.
 *
 * @param tfhd The tfhd atom to decode.
 * @param trackBundles The track bundles, one of which corresponds to the tfhd atom being parsed.
 * @return The {@link TrackBundle} to which the {@link TrackFragment} belongs, or null if the tfhd
 *     does not refer to any {@link TrackBundle}.
 */
private static TrackBundle parseTfhd(ParsableByteArray tfhd,
    SparseArray<TrackBundle> trackBundles, int flags) {
  tfhd.setPosition(Atom.HEADER_SIZE);
  int fullAtom = tfhd.readInt();
  int atomFlags = Atom.parseFullAtomFlags(fullAtom);
  int trackId = tfhd.readInt();
  TrackBundle trackBundle = trackBundles.get((flags & FLAG_SIDELOADED) == 0 ? trackId : 0);
  if (trackBundle == null) {
    return null;
  }
  if ((atomFlags & 0x01 /* base_data_offset_present */) != 0) {
    long baseDataPosition = tfhd.readUnsignedLongToLong();
    trackBundle.fragment.dataPosition = baseDataPosition;
    trackBundle.fragment.auxiliaryDataPosition = baseDataPosition;
  }

  DefaultSampleValues defaultSampleValues = trackBundle.defaultSampleValues;
  int defaultSampleDescriptionIndex =
      ((atomFlags & 0x02 /* default_sample_description_index_present */) != 0)
          ? tfhd.readUnsignedIntToInt() - 1 : defaultSampleValues.sampleDescriptionIndex;
  int defaultSampleDuration = ((atomFlags & 0x08 /* default_sample_duration_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.duration;
  int defaultSampleSize = ((atomFlags & 0x10 /* default_sample_size_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.size;
  int defaultSampleFlags = ((atomFlags & 0x20 /* default_sample_flags_present */) != 0)
      ? tfhd.readUnsignedIntToInt() : defaultSampleValues.flags;
  trackBundle.fragment.header = new DefaultSampleValues(defaultSampleDescriptionIndex,
      defaultSampleDuration, defaultSampleSize, defaultSampleFlags);
  return trackBundle;
}
 
Example 16
Source File: FragmentedMp4Extractor.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Parses a tfdt atom (defined in 14496-12).
 *
 * @return baseMediaDecodeTime The sum of the decode durations of all earlier samples in the
 *     media, expressed in the media's timescale.
 */
private static long parseTfdt(ParsableByteArray tfdt) {
  tfdt.setPosition(Atom.HEADER_SIZE);
  int fullAtom = tfdt.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  return version == 1 ? tfdt.readUnsignedLongToLong() : tfdt.readUnsignedInt();
}
 
Example 17
Source File: FragmentedMp4Extractor.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses an mehd atom (defined in 14496-12).
 */
private static long parseMehd(ParsableByteArray mehd) {
  mehd.setPosition(Atom.HEADER_SIZE);
  int fullAtom = mehd.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  return version == 0 ? mehd.readUnsignedInt() : mehd.readUnsignedLongToLong();
}
 
Example 18
Source File: AtomParsers.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Parses a tkhd atom (defined in 14496-12).
 *
 * @return An object containing the parsed data.
 */
private static TkhdData parseTkhd(ParsableByteArray tkhd) {
  tkhd.setPosition(Atom.HEADER_SIZE);
  int fullAtom = tkhd.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);

  tkhd.skipBytes(version == 0 ? 8 : 16);
  int trackId = tkhd.readInt();

  tkhd.skipBytes(4);
  boolean durationUnknown = true;
  int durationPosition = tkhd.getPosition();
  int durationByteCount = version == 0 ? 4 : 8;
  for (int i = 0; i < durationByteCount; i++) {
    if (tkhd.data[durationPosition + i] != -1) {
      durationUnknown = false;
      break;
    }
  }
  long duration;
  if (durationUnknown) {
    tkhd.skipBytes(durationByteCount);
    duration = C.TIME_UNSET;
  } else {
    duration = version == 0 ? tkhd.readUnsignedInt() : tkhd.readUnsignedLongToLong();
    if (duration == 0) {
      // 0 duration normally indicates that the file is fully fragmented (i.e. all of the media
      // samples are in fragments). Treat as unknown.
      duration = C.TIME_UNSET;
    }
  }

  tkhd.skipBytes(16);
  int a00 = tkhd.readInt();
  int a01 = tkhd.readInt();
  tkhd.skipBytes(4);
  int a10 = tkhd.readInt();
  int a11 = tkhd.readInt();

  int rotationDegrees;
  int fixedOne = 65536;
  if (a00 == 0 && a01 == fixedOne && a10 == -fixedOne && a11 == 0) {
    rotationDegrees = 90;
  } else if (a00 == 0 && a01 == -fixedOne && a10 == fixedOne && a11 == 0) {
    rotationDegrees = 270;
  } else if (a00 == -fixedOne && a01 == 0 && a10 == 0 && a11 == -fixedOne) {
    rotationDegrees = 180;
  } else {
    // Only 0, 90, 180 and 270 are supported. Treat anything else as 0.
    rotationDegrees = 0;
  }

  return new TkhdData(trackId, duration, rotationDegrees);
}
 
Example 19
Source File: FragmentedMp4Extractor.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Parses a sidx atom (defined in 14496-12).
 *
 * @param atom The atom data.
 * @param inputPosition The input position of the first byte after the atom.
 * @return A pair consisting of the earliest presentation time in microseconds, and the parsed
 *     {@link ChunkIndex}.
 */
private static Pair<Long, ChunkIndex> parseSidx(ParsableByteArray atom, long inputPosition)
    throws ParserException {
  atom.setPosition(Atom.HEADER_SIZE);
  int fullAtom = atom.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);

  atom.skipBytes(4);
  long timescale = atom.readUnsignedInt();
  long earliestPresentationTime;
  long offset = inputPosition;
  if (version == 0) {
    earliestPresentationTime = atom.readUnsignedInt();
    offset += atom.readUnsignedInt();
  } else {
    earliestPresentationTime = atom.readUnsignedLongToLong();
    offset += atom.readUnsignedLongToLong();
  }
  long earliestPresentationTimeUs = Util.scaleLargeTimestamp(earliestPresentationTime,
      C.MICROS_PER_SECOND, timescale);

  atom.skipBytes(2);

  int referenceCount = atom.readUnsignedShort();
  int[] sizes = new int[referenceCount];
  long[] offsets = new long[referenceCount];
  long[] durationsUs = new long[referenceCount];
  long[] timesUs = new long[referenceCount];

  long time = earliestPresentationTime;
  long timeUs = earliestPresentationTimeUs;
  for (int i = 0; i < referenceCount; i++) {
    int firstInt = atom.readInt();

    int type = 0x80000000 & firstInt;
    if (type != 0) {
      throw new ParserException("Unhandled indirect reference");
    }
    long referenceDuration = atom.readUnsignedInt();

    sizes[i] = 0x7FFFFFFF & firstInt;
    offsets[i] = offset;

    // Calculate time and duration values such that any rounding errors are consistent. i.e. That
    // timesUs[i] + durationsUs[i] == timesUs[i + 1].
    timesUs[i] = timeUs;
    time += referenceDuration;
    timeUs = Util.scaleLargeTimestamp(time, C.MICROS_PER_SECOND, timescale);
    durationsUs[i] = timeUs - timesUs[i];

    atom.skipBytes(4);
    offset += sizes[i];
  }

  return Pair.create(earliestPresentationTimeUs,
      new ChunkIndex(sizes, offsets, durationsUs, timesUs));
}
 
Example 20
Source File: Sniffer.java    From K-Sonic with MIT License 4 votes vote down vote up
private static boolean sniffInternal(ExtractorInput input, boolean fragmented)
    throws IOException, InterruptedException {
  long inputLength = input.getLength();
  int bytesToSearch = (int) (inputLength == C.LENGTH_UNSET || inputLength > SEARCH_LENGTH
      ? SEARCH_LENGTH : inputLength);

  ParsableByteArray buffer = new ParsableByteArray(64);
  int bytesSearched = 0;
  boolean foundGoodFileType = false;
  boolean isFragmented = false;
  while (bytesSearched < bytesToSearch) {
    // Read an atom header.
    int headerSize = Atom.HEADER_SIZE;
    buffer.reset(headerSize);
    input.peekFully(buffer.data, 0, headerSize);
    long atomSize = buffer.readUnsignedInt();
    int atomType = buffer.readInt();
    if (atomSize == Atom.LONG_SIZE_PREFIX) {
      headerSize = Atom.LONG_HEADER_SIZE;
      input.peekFully(buffer.data, Atom.HEADER_SIZE, Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE);
      buffer.setLimit(Atom.LONG_HEADER_SIZE);
      atomSize = buffer.readUnsignedLongToLong();
    }

    if (atomSize < headerSize) {
      // The file is invalid because the atom size is too small for its header.
      return false;
    }
    bytesSearched += headerSize;

    if (atomType == Atom.TYPE_moov) {
      // Check for an mvex atom inside the moov atom to identify whether the file is fragmented.
      continue;
    }

    if (atomType == Atom.TYPE_moof || atomType == Atom.TYPE_mvex) {
      // The movie is fragmented. Stop searching as we must have read any ftyp atom already.
      isFragmented = true;
      break;
    }

    if (bytesSearched + atomSize - headerSize >= bytesToSearch) {
      // Stop searching as peeking this atom would exceed the search limit.
      break;
    }

    int atomDataSize = (int) (atomSize - headerSize);
    bytesSearched += atomDataSize;
    if (atomType == Atom.TYPE_ftyp) {
      // Parse the atom and check the file type/brand is compatible with the extractors.
      if (atomDataSize < 8) {
        return false;
      }
      buffer.reset(atomDataSize);
      input.peekFully(buffer.data, 0, atomDataSize);
      int brandsCount = atomDataSize / 4;
      for (int i = 0; i < brandsCount; i++) {
        if (i == 1) {
          // This index refers to the minorVersion, not a brand, so skip it.
          buffer.skipBytes(4);
        } else if (isCompatibleBrand(buffer.readInt())) {
          foundGoodFileType = true;
          break;
        }
      }
      if (!foundGoodFileType) {
        // The types were not compatible and there is only one ftyp atom, so reject the file.
        return false;
      }
    } else if (atomDataSize != 0) {
      // Skip the atom.
      input.advancePeekPosition(atomDataSize);
    }
  }
  return foundGoodFileType && fragmented == isFragmented;
}