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

The following examples show how to use com.google.android.exoplayer2.util.ParsableByteArray#readUnsignedInt() . 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 Telegram with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Parses an mdhd atom (defined in 14496-12).
 *
 * @param mdhd The mdhd atom to decode.
 * @return A pair consisting of the media timescale defined as the number of time units that pass
 * in one second, and the language code.
 */
private static Pair<Long, String> parseMdhd(ParsableByteArray mdhd) {
  mdhd.setPosition(Atom.HEADER_SIZE);
  int fullAtom = mdhd.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  mdhd.skipBytes(version == 0 ? 8 : 16);
  long timescale = mdhd.readUnsignedInt();
  mdhd.skipBytes(version == 0 ? 4 : 8);
  int languageCode = mdhd.readUnsignedShort();
  String language =
      ""
          + (char) (((languageCode >> 10) & 0x1F) + 0x60)
          + (char) (((languageCode >> 5) & 0x1F) + 0x60)
          + (char) ((languageCode & 0x1F) + 0x60);
  return Pair.create(timescale, language);
}
 
Example 2
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 3
Source File: AtomParsers.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Parses an mdhd atom (defined in 14496-12).
 *
 * @param mdhd The mdhd atom to decode.
 * @return A pair consisting of the media timescale defined as the number of time units that pass
 * in one second, and the language code.
 */
private static Pair<Long, String> parseMdhd(ParsableByteArray mdhd) {
  mdhd.setPosition(Atom.HEADER_SIZE);
  int fullAtom = mdhd.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  mdhd.skipBytes(version == 0 ? 8 : 16);
  long timescale = mdhd.readUnsignedInt();
  mdhd.skipBytes(version == 0 ? 4 : 8);
  int languageCode = mdhd.readUnsignedShort();
  String language =
      ""
          + (char) (((languageCode >> 10) & 0x1F) + 0x60)
          + (char) (((languageCode >> 5) & 0x1F) + 0x60)
          + (char) ((languageCode & 0x1F) + 0x60);
  return Pair.create(timescale, language);
}
 
Example 4
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 5
Source File: FragmentedMp4Extractor.java    From Telegram 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 6
Source File: FragmentedMp4Extractor.java    From MediaSDK with Apache License 2.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 7
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 8
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 9
Source File: AtomParsers.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses a mvhd atom (defined in 14496-12), returning the timescale for the movie.
 *
 * @param mvhd Contents of the mvhd atom to be parsed.
 * @return Timescale for the movie.
 */
private static long parseMvhd(ParsableByteArray mvhd) {
  mvhd.setPosition(Atom.HEADER_SIZE);
  int fullAtom = mvhd.readInt();
  int version = Atom.parseFullAtomVersion(fullAtom);
  mvhd.skipBytes(version == 0 ? 8 : 16);
  return mvhd.readUnsignedInt();
}
 
Example 10
Source File: EventMessageDecoder.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
@Nullable
public EventMessage decode(ParsableByteArray emsgData) {
  try {
    String schemeIdUri = Assertions.checkNotNull(emsgData.readNullTerminatedString());
    String value = Assertions.checkNotNull(emsgData.readNullTerminatedString());
    long durationMs = emsgData.readUnsignedInt();
    long id = emsgData.readUnsignedInt();
    byte[] messageData =
        Arrays.copyOfRange(emsgData.data, emsgData.getPosition(), emsgData.limit());
    return new EventMessage(schemeIdUri, value, durationMs, id, messageData);
  } catch (RuntimeException e) {
    return null;
  }
}
 
Example 11
Source File: SpliceInsertCommand.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
static SpliceInsertCommand parseFromSection(ParsableByteArray sectionData,
    long ptsAdjustment, TimestampAdjuster timestampAdjuster) {
  long spliceEventId = sectionData.readUnsignedInt();
  // splice_event_cancel_indicator(1), reserved(7).
  boolean spliceEventCancelIndicator = (sectionData.readUnsignedByte() & 0x80) != 0;
  boolean outOfNetworkIndicator = false;
  boolean programSpliceFlag = false;
  boolean spliceImmediateFlag = false;
  long programSplicePts = C.TIME_UNSET;
  List<ComponentSplice> componentSplices = Collections.emptyList();
  int uniqueProgramId = 0;
  int availNum = 0;
  int availsExpected = 0;
  boolean autoReturn = false;
  long breakDurationUs = C.TIME_UNSET;
  if (!spliceEventCancelIndicator) {
    int headerByte = sectionData.readUnsignedByte();
    outOfNetworkIndicator = (headerByte & 0x80) != 0;
    programSpliceFlag = (headerByte & 0x40) != 0;
    boolean durationFlag = (headerByte & 0x20) != 0;
    spliceImmediateFlag = (headerByte & 0x10) != 0;
    if (programSpliceFlag && !spliceImmediateFlag) {
      programSplicePts = TimeSignalCommand.parseSpliceTime(sectionData, ptsAdjustment);
    }
    if (!programSpliceFlag) {
      int componentCount = sectionData.readUnsignedByte();
      componentSplices = new ArrayList<>(componentCount);
      for (int i = 0; i < componentCount; i++) {
        int componentTag = sectionData.readUnsignedByte();
        long componentSplicePts = C.TIME_UNSET;
        if (!spliceImmediateFlag) {
          componentSplicePts = TimeSignalCommand.parseSpliceTime(sectionData, ptsAdjustment);
        }
        componentSplices.add(new ComponentSplice(componentTag, componentSplicePts,
            timestampAdjuster.adjustTsTimestamp(componentSplicePts)));
      }
    }
    if (durationFlag) {
      long firstByte = sectionData.readUnsignedByte();
      autoReturn = (firstByte & 0x80) != 0;
      long breakDuration90khz = ((firstByte & 0x01) << 32) | sectionData.readUnsignedInt();
      breakDurationUs = breakDuration90khz * 1000 / 90;
    }
    uniqueProgramId = sectionData.readUnsignedShort();
    availNum = sectionData.readUnsignedByte();
    availsExpected = sectionData.readUnsignedByte();
  }
  return new SpliceInsertCommand(spliceEventId, spliceEventCancelIndicator, outOfNetworkIndicator,
      programSpliceFlag, spliceImmediateFlag, programSplicePts,
      timestampAdjuster.adjustTsTimestamp(programSplicePts), componentSplices, autoReturn,
      breakDurationUs, uniqueProgramId, availNum, availsExpected);
}
 
Example 12
Source File: SpliceInsertCommand.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
static SpliceInsertCommand parseFromSection(ParsableByteArray sectionData,
    long ptsAdjustment, TimestampAdjuster timestampAdjuster) {
  long spliceEventId = sectionData.readUnsignedInt();
  // splice_event_cancel_indicator(1), reserved(7).
  boolean spliceEventCancelIndicator = (sectionData.readUnsignedByte() & 0x80) != 0;
  boolean outOfNetworkIndicator = false;
  boolean programSpliceFlag = false;
  boolean spliceImmediateFlag = false;
  long programSplicePts = C.TIME_UNSET;
  List<ComponentSplice> componentSplices = Collections.emptyList();
  int uniqueProgramId = 0;
  int availNum = 0;
  int availsExpected = 0;
  boolean autoReturn = false;
  long breakDurationUs = C.TIME_UNSET;
  if (!spliceEventCancelIndicator) {
    int headerByte = sectionData.readUnsignedByte();
    outOfNetworkIndicator = (headerByte & 0x80) != 0;
    programSpliceFlag = (headerByte & 0x40) != 0;
    boolean durationFlag = (headerByte & 0x20) != 0;
    spliceImmediateFlag = (headerByte & 0x10) != 0;
    if (programSpliceFlag && !spliceImmediateFlag) {
      programSplicePts = TimeSignalCommand.parseSpliceTime(sectionData, ptsAdjustment);
    }
    if (!programSpliceFlag) {
      int componentCount = sectionData.readUnsignedByte();
      componentSplices = new ArrayList<>(componentCount);
      for (int i = 0; i < componentCount; i++) {
        int componentTag = sectionData.readUnsignedByte();
        long componentSplicePts = C.TIME_UNSET;
        if (!spliceImmediateFlag) {
          componentSplicePts = TimeSignalCommand.parseSpliceTime(sectionData, ptsAdjustment);
        }
        componentSplices.add(new ComponentSplice(componentTag, componentSplicePts,
            timestampAdjuster.adjustTsTimestamp(componentSplicePts)));
      }
    }
    if (durationFlag) {
      long firstByte = sectionData.readUnsignedByte();
      autoReturn = (firstByte & 0x80) != 0;
      long breakDuration90khz = ((firstByte & 0x01) << 32) | sectionData.readUnsignedInt();
      breakDurationUs = breakDuration90khz * 1000 / 90;
    }
    uniqueProgramId = sectionData.readUnsignedShort();
    availNum = sectionData.readUnsignedByte();
    availsExpected = sectionData.readUnsignedByte();
  }
  return new SpliceInsertCommand(spliceEventId, spliceEventCancelIndicator, outOfNetworkIndicator,
      programSpliceFlag, spliceImmediateFlag, programSplicePts,
      timestampAdjuster.adjustTsTimestamp(programSplicePts), componentSplices, autoReturn,
      breakDurationUs, uniqueProgramId, availNum, availsExpected);
}
 
Example 13
Source File: SpliceInsertCommand.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
static SpliceInsertCommand parseFromSection(ParsableByteArray sectionData,
    long ptsAdjustment, TimestampAdjuster timestampAdjuster) {
  long spliceEventId = sectionData.readUnsignedInt();
  // splice_event_cancel_indicator(1), reserved(7).
  boolean spliceEventCancelIndicator = (sectionData.readUnsignedByte() & 0x80) != 0;
  boolean outOfNetworkIndicator = false;
  boolean programSpliceFlag = false;
  boolean spliceImmediateFlag = false;
  long programSplicePts = C.TIME_UNSET;
  List<ComponentSplice> componentSplices = Collections.emptyList();
  int uniqueProgramId = 0;
  int availNum = 0;
  int availsExpected = 0;
  boolean autoReturn = false;
  long breakDurationUs = C.TIME_UNSET;
  if (!spliceEventCancelIndicator) {
    int headerByte = sectionData.readUnsignedByte();
    outOfNetworkIndicator = (headerByte & 0x80) != 0;
    programSpliceFlag = (headerByte & 0x40) != 0;
    boolean durationFlag = (headerByte & 0x20) != 0;
    spliceImmediateFlag = (headerByte & 0x10) != 0;
    if (programSpliceFlag && !spliceImmediateFlag) {
      programSplicePts = TimeSignalCommand.parseSpliceTime(sectionData, ptsAdjustment);
    }
    if (!programSpliceFlag) {
      int componentCount = sectionData.readUnsignedByte();
      componentSplices = new ArrayList<>(componentCount);
      for (int i = 0; i < componentCount; i++) {
        int componentTag = sectionData.readUnsignedByte();
        long componentSplicePts = C.TIME_UNSET;
        if (!spliceImmediateFlag) {
          componentSplicePts = TimeSignalCommand.parseSpliceTime(sectionData, ptsAdjustment);
        }
        componentSplices.add(new ComponentSplice(componentTag, componentSplicePts,
            timestampAdjuster.adjustTsTimestamp(componentSplicePts)));
      }
    }
    if (durationFlag) {
      long firstByte = sectionData.readUnsignedByte();
      autoReturn = (firstByte & 0x80) != 0;
      long breakDuration90khz = ((firstByte & 0x01) << 32) | sectionData.readUnsignedInt();
      breakDurationUs = breakDuration90khz * 1000 / 90;
    }
    uniqueProgramId = sectionData.readUnsignedShort();
    availNum = sectionData.readUnsignedByte();
    availsExpected = sectionData.readUnsignedByte();
  }
  return new SpliceInsertCommand(spliceEventId, spliceEventCancelIndicator, outOfNetworkIndicator,
      programSpliceFlag, spliceImmediateFlag, programSplicePts,
      timestampAdjuster.adjustTsTimestamp(programSplicePts), componentSplices, autoReturn,
      breakDurationUs, uniqueProgramId, availNum, availsExpected);
}
 
Example 14
Source File: Sniffer.java    From TelePlus-Android with GNU General Public License v2.0 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.DEFINES_LARGE_SIZE) {
      // Read the large atom size.
      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();
    } else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
      // The atom extends to the end of the file.
      long endPosition = input.getLength();
      if (endPosition != C.LENGTH_UNSET) {
        atomSize = endPosition - input.getPosition() + headerSize;
      }
    }

    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;
}
 
Example 15
Source File: FragmentedMp4Extractor.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
private static void parseSgpd(ParsableByteArray sbgp, ParsableByteArray sgpd, String schemeType,
    TrackFragment out) throws ParserException {
  sbgp.setPosition(Atom.HEADER_SIZE);
  int sbgpFullAtom = sbgp.readInt();
  if (sbgp.readInt() != SAMPLE_GROUP_TYPE_seig) {
    // Only seig grouping type is supported.
    return;
  }
  if (Atom.parseFullAtomVersion(sbgpFullAtom) == 1) {
    sbgp.skipBytes(4); // default_length.
  }
  if (sbgp.readInt() != 1) { // entry_count.
    throw new ParserException("Entry count in sbgp != 1 (unsupported).");
  }

  sgpd.setPosition(Atom.HEADER_SIZE);
  int sgpdFullAtom = sgpd.readInt();
  if (sgpd.readInt() != SAMPLE_GROUP_TYPE_seig) {
    // Only seig grouping type is supported.
    return;
  }
  int sgpdVersion = Atom.parseFullAtomVersion(sgpdFullAtom);
  if (sgpdVersion == 1) {
    if (sgpd.readUnsignedInt() == 0) {
      throw new ParserException("Variable length description in sgpd found (unsupported)");
    }
  } else if (sgpdVersion >= 2) {
    sgpd.skipBytes(4); // default_sample_description_index.
  }
  if (sgpd.readUnsignedInt() != 1) { // entry_count.
    throw new ParserException("Entry count in sgpd != 1 (unsupported).");
  }
  // CencSampleEncryptionInformationGroupEntry
  sgpd.skipBytes(1); // reserved = 0.
  int patternByte = sgpd.readUnsignedByte();
  int cryptByteBlock = (patternByte & 0xF0) >> 4;
  int skipByteBlock = patternByte & 0x0F;
  boolean isProtected = sgpd.readUnsignedByte() == 1;
  if (!isProtected) {
    return;
  }
  int perSampleIvSize = sgpd.readUnsignedByte();
  byte[] keyId = new byte[16];
  sgpd.readBytes(keyId, 0, keyId.length);
  byte[] constantIv = null;
  if (isProtected && perSampleIvSize == 0) {
    int constantIvSize = sgpd.readUnsignedByte();
    constantIv = new byte[constantIvSize];
    sgpd.readBytes(constantIv, 0, constantIvSize);
  }
  out.definesEncryptionData = true;
  out.trackEncryptionBox = new TrackEncryptionBox(isProtected, schemeType, perSampleIvSize, keyId,
      cryptByteBlock, skipByteBlock, constantIv);
}
 
Example 16
Source File: FragmentedMp4Extractor.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
private static void parseSgpd(ParsableByteArray sbgp, ParsableByteArray sgpd, String schemeType,
    TrackFragment out) throws ParserException {
  sbgp.setPosition(Atom.HEADER_SIZE);
  int sbgpFullAtom = sbgp.readInt();
  if (sbgp.readInt() != SAMPLE_GROUP_TYPE_seig) {
    // Only seig grouping type is supported.
    return;
  }
  if (Atom.parseFullAtomVersion(sbgpFullAtom) == 1) {
    sbgp.skipBytes(4); // default_length.
  }
  if (sbgp.readInt() != 1) { // entry_count.
    throw new ParserException("Entry count in sbgp != 1 (unsupported).");
  }

  sgpd.setPosition(Atom.HEADER_SIZE);
  int sgpdFullAtom = sgpd.readInt();
  if (sgpd.readInt() != SAMPLE_GROUP_TYPE_seig) {
    // Only seig grouping type is supported.
    return;
  }
  int sgpdVersion = Atom.parseFullAtomVersion(sgpdFullAtom);
  if (sgpdVersion == 1) {
    if (sgpd.readUnsignedInt() == 0) {
      throw new ParserException("Variable length description in sgpd found (unsupported)");
    }
  } else if (sgpdVersion >= 2) {
    sgpd.skipBytes(4); // default_sample_description_index.
  }
  if (sgpd.readUnsignedInt() != 1) { // entry_count.
    throw new ParserException("Entry count in sgpd != 1 (unsupported).");
  }
  // CencSampleEncryptionInformationGroupEntry
  sgpd.skipBytes(1); // reserved = 0.
  int patternByte = sgpd.readUnsignedByte();
  int cryptByteBlock = (patternByte & 0xF0) >> 4;
  int skipByteBlock = patternByte & 0x0F;
  boolean isProtected = sgpd.readUnsignedByte() == 1;
  if (!isProtected) {
    return;
  }
  int perSampleIvSize = sgpd.readUnsignedByte();
  byte[] keyId = new byte[16];
  sgpd.readBytes(keyId, 0, keyId.length);
  byte[] constantIv = null;
  if (isProtected && perSampleIvSize == 0) {
    int constantIvSize = sgpd.readUnsignedByte();
    constantIv = new byte[constantIvSize];
    sgpd.readBytes(constantIv, 0, constantIvSize);
  }
  out.definesEncryptionData = true;
  out.trackEncryptionBox = new TrackEncryptionBox(isProtected, schemeType, perSampleIvSize, keyId,
      cryptByteBlock, skipByteBlock, constantIv);
}
 
Example 17
Source File: Id3Decoder.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
private static boolean validateFrames(ParsableByteArray id3Data, int majorVersion,
    int frameHeaderSize, boolean unsignedIntFrameSizeHack) {
  int startPosition = id3Data.getPosition();
  try {
    while (id3Data.bytesLeft() >= frameHeaderSize) {
      // Read the next frame header.
      int id;
      long frameSize;
      int flags;
      if (majorVersion >= 3) {
        id = id3Data.readInt();
        frameSize = id3Data.readUnsignedInt();
        flags = id3Data.readUnsignedShort();
      } else {
        id = id3Data.readUnsignedInt24();
        frameSize = id3Data.readUnsignedInt24();
        flags = 0;
      }
      // Validate the frame header and skip to the next one.
      if (id == 0 && frameSize == 0 && flags == 0) {
        // We've reached zero padding after the end of the final frame.
        return true;
      } else {
        if (majorVersion == 4 && !unsignedIntFrameSizeHack) {
          // Parse the data size as a synchsafe integer, as per the spec.
          if ((frameSize & 0x808080L) != 0) {
            return false;
          }
          frameSize = (frameSize & 0xFF) | (((frameSize >> 8) & 0xFF) << 7)
              | (((frameSize >> 16) & 0xFF) << 14) | (((frameSize >> 24) & 0xFF) << 21);
        }
        boolean hasGroupIdentifier = false;
        boolean hasDataLength = false;
        if (majorVersion == 4) {
          hasGroupIdentifier = (flags & FRAME_FLAG_V4_HAS_GROUP_IDENTIFIER) != 0;
          hasDataLength = (flags & FRAME_FLAG_V4_HAS_DATA_LENGTH) != 0;
        } else if (majorVersion == 3) {
          hasGroupIdentifier = (flags & FRAME_FLAG_V3_HAS_GROUP_IDENTIFIER) != 0;
          // A V3 frame has data length if and only if it's compressed.
          hasDataLength = (flags & FRAME_FLAG_V3_IS_COMPRESSED) != 0;
        }
        int minimumFrameSize = 0;
        if (hasGroupIdentifier) {
          minimumFrameSize++;
        }
        if (hasDataLength) {
          minimumFrameSize += 4;
        }
        if (frameSize < minimumFrameSize) {
          return false;
        }
        if (id3Data.bytesLeft() < frameSize) {
          return false;
        }
        id3Data.skipBytes((int) frameSize); // flags
      }
    }
    return true;
  } finally {
    id3Data.setPosition(startPosition);
  }
}
 
Example 18
Source File: AtomParsers.java    From TelePlus-Android 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: Id3Decoder.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
private static boolean validateFrames(ParsableByteArray id3Data, int majorVersion,
    int frameHeaderSize, boolean unsignedIntFrameSizeHack) {
  int startPosition = id3Data.getPosition();
  try {
    while (id3Data.bytesLeft() >= frameHeaderSize) {
      // Read the next frame header.
      int id;
      long frameSize;
      int flags;
      if (majorVersion >= 3) {
        id = id3Data.readInt();
        frameSize = id3Data.readUnsignedInt();
        flags = id3Data.readUnsignedShort();
      } else {
        id = id3Data.readUnsignedInt24();
        frameSize = id3Data.readUnsignedInt24();
        flags = 0;
      }
      // Validate the frame header and skip to the next one.
      if (id == 0 && frameSize == 0 && flags == 0) {
        // We've reached zero padding after the end of the final frame.
        return true;
      } else {
        if (majorVersion == 4 && !unsignedIntFrameSizeHack) {
          // Parse the data size as a synchsafe integer, as per the spec.
          if ((frameSize & 0x808080L) != 0) {
            return false;
          }
          frameSize = (frameSize & 0xFF) | (((frameSize >> 8) & 0xFF) << 7)
              | (((frameSize >> 16) & 0xFF) << 14) | (((frameSize >> 24) & 0xFF) << 21);
        }
        boolean hasGroupIdentifier = false;
        boolean hasDataLength = false;
        if (majorVersion == 4) {
          hasGroupIdentifier = (flags & FRAME_FLAG_V4_HAS_GROUP_IDENTIFIER) != 0;
          hasDataLength = (flags & FRAME_FLAG_V4_HAS_DATA_LENGTH) != 0;
        } else if (majorVersion == 3) {
          hasGroupIdentifier = (flags & FRAME_FLAG_V3_HAS_GROUP_IDENTIFIER) != 0;
          // A V3 frame has data length if and only if it's compressed.
          hasDataLength = (flags & FRAME_FLAG_V3_IS_COMPRESSED) != 0;
        }
        int minimumFrameSize = 0;
        if (hasGroupIdentifier) {
          minimumFrameSize++;
        }
        if (hasDataLength) {
          minimumFrameSize += 4;
        }
        if (frameSize < minimumFrameSize) {
          return false;
        }
        if (id3Data.bytesLeft() < frameSize) {
          return false;
        }
        id3Data.skipBytes((int) frameSize); // flags
      }
    }
    return true;
  } finally {
    id3Data.setPosition(startPosition);
  }
}
 
Example 20
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));
}