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

The following examples show how to use com.google.android.exoplayer2.util.ParsableByteArray#readUnsignedShort() . 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: MetadataUtil.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
@Nullable
private static TextInformationFrame parseIndexAndCountAttribute(
    int type, String attributeName, ParsableByteArray data) {
  int atomSize = data.readInt();
  int atomType = data.readInt();
  if (atomType == Atom.TYPE_data && atomSize >= 22) {
    data.skipBytes(10); // version (1), flags (3), empty (4), empty (2)
    int index = data.readUnsignedShort();
    if (index > 0) {
      String value = "" + index;
      int count = data.readUnsignedShort();
      if (count > 0) {
        value += "/" + count;
      }
      return new TextInformationFrame(attributeName, /* description= */ null, value);
    }
  }
  Log.w(TAG, "Failed to parse index/count attribute: " + Atom.getAtomTypeString(type));
  return null;
}
 
Example 2
Source File: MetadataUtil.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
@Nullable
private static TextInformationFrame parseIndexAndCountAttribute(
    int type, String attributeName, ParsableByteArray data) {
  int atomSize = data.readInt();
  int atomType = data.readInt();
  if (atomType == Atom.TYPE_data && atomSize >= 22) {
    data.skipBytes(10); // version (1), flags (3), empty (4), empty (2)
    int index = data.readUnsignedShort();
    if (index > 0) {
      String value = "" + index;
      int count = data.readUnsignedShort();
      if (count > 0) {
        value += "/" + count;
      }
      return new TextInformationFrame(attributeName, /* description= */ null, value);
    }
  }
  Log.w(TAG, "Failed to parse index/count attribute: " + Atom.getAtomTypeString(type));
  return null;
}
 
Example 3
Source File: Tx3gDecoder.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
private static String readSubtitleText(ParsableByteArray parsableByteArray)
    throws SubtitleDecoderException {
  assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
  int textLength = parsableByteArray.readUnsignedShort();
  if (textLength == 0) {
    return "";
  }
  if (parsableByteArray.bytesLeft() >= SIZE_BOM_UTF16) {
    char firstChar = parsableByteArray.peekChar();
    if (firstChar == BOM_UTF16_BE || firstChar == BOM_UTF16_LE) {
      return parsableByteArray.readString(textLength, Charset.forName(C.UTF16_NAME));
    }
  }
  return parsableByteArray.readString(textLength, Charset.forName(C.UTF8_NAME));
}
 
Example 4
Source File: ScriptTagPayloadReader.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Read a string from an AMF encoded buffer.
 *
 * @param data The buffer from which to read.
 * @return The value read from the buffer.
 */
private static String readAmfString(ParsableByteArray data) {
  int size = data.readUnsignedShort();
  int position = data.getPosition();
  data.skipBytes(size);
  return new String(data.data, position, size);
}
 
Example 5
Source File: Id3Decoder.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
private static MlltFrame decodeMlltFrame(ParsableByteArray id3Data, int frameSize) {
  // See ID3v2.4.0 native frames subsection 4.6.
  int mpegFramesBetweenReference = id3Data.readUnsignedShort();
  int bytesBetweenReference = id3Data.readUnsignedInt24();
  int millisecondsBetweenReference = id3Data.readUnsignedInt24();
  int bitsForBytesDeviation = id3Data.readUnsignedByte();
  int bitsForMillisecondsDeviation = id3Data.readUnsignedByte();

  ParsableBitArray references = new ParsableBitArray();
  references.reset(id3Data);
  int referencesBits = 8 * (frameSize - 10);
  int bitsPerReference = bitsForBytesDeviation + bitsForMillisecondsDeviation;
  int referencesCount = referencesBits / bitsPerReference;
  int[] bytesDeviations = new int[referencesCount];
  int[] millisecondsDeviations = new int[referencesCount];
  for (int i = 0; i < referencesCount; i++) {
    int bytesDeviation = references.readBits(bitsForBytesDeviation);
    int millisecondsDeviation = references.readBits(bitsForMillisecondsDeviation);
    bytesDeviations[i] = bytesDeviation;
    millisecondsDeviations[i] = millisecondsDeviation;
  }

  return new MlltFrame(
      mpegFramesBetweenReference,
      bytesBetweenReference,
      millisecondsBetweenReference,
      bytesDeviations,
      millisecondsDeviations);
}
 
Example 6
Source File: AtomParsers.java    From K-Sonic with MIT License 5 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 7
Source File: PgsDecoder.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
private void parseIdentifierSection(ParsableByteArray buffer, int sectionLength) {
  if (sectionLength < 19) {
    return;
  }
  planeWidth = buffer.readUnsignedShort();
  planeHeight = buffer.readUnsignedShort();
  buffer.skipBytes(11);
  bitmapX = buffer.readUnsignedShort();
  bitmapY = buffer.readUnsignedShort();
}
 
Example 8
Source File: Tx3gDecoder.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private void applyStyleRecord(ParsableByteArray parsableByteArray,
    SpannableStringBuilder cueText) throws SubtitleDecoderException {
  assertTrue(parsableByteArray.bytesLeft() >= SIZE_STYLE_RECORD);
  int start = parsableByteArray.readUnsignedShort();
  int end = parsableByteArray.readUnsignedShort();
  parsableByteArray.skipBytes(2); // font identifier
  int fontFace = parsableByteArray.readUnsignedByte();
  parsableByteArray.skipBytes(1); // font size
  int colorRgba = parsableByteArray.readInt();
  attachFontFace(cueText, fontFace, defaultFontFace, start, end, SPAN_PRIORITY_HIGH);
  attachColor(cueText, colorRgba, defaultColorRgba, start, end, SPAN_PRIORITY_HIGH);
}
 
Example 9
Source File: Tx3gDecoder.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private static String readSubtitleText(ParsableByteArray parsableByteArray)
    throws SubtitleDecoderException {
  assertTrue(parsableByteArray.bytesLeft() >= SIZE_SHORT);
  int textLength = parsableByteArray.readUnsignedShort();
  if (textLength == 0) {
    return "";
  }
  if (parsableByteArray.bytesLeft() >= SIZE_BOM_UTF16) {
    char firstChar = parsableByteArray.peekChar();
    if (firstChar == BOM_UTF16_BE || firstChar == BOM_UTF16_LE) {
      return parsableByteArray.readString(textLength, Charset.forName(C.UTF16_NAME));
    }
  }
  return parsableByteArray.readString(textLength, Charset.forName(C.UTF8_NAME));
}
 
Example 10
Source File: SpliceInsertCommand.java    From Telegram-FOSS 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 11
Source File: SpliceScheduleCommand.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
private static Event parseFromSection(ParsableByteArray sectionData) {
  long spliceEventId = sectionData.readUnsignedInt();
  // splice_event_cancel_indicator(1), reserved(7).
  boolean spliceEventCancelIndicator = (sectionData.readUnsignedByte() & 0x80) != 0;
  boolean outOfNetworkIndicator = false;
  boolean programSpliceFlag = false;
  long utcSpliceTime = C.TIME_UNSET;
  ArrayList<ComponentSplice> componentSplices = new ArrayList<>();
  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;
    if (programSpliceFlag) {
      utcSpliceTime = sectionData.readUnsignedInt();
    }
    if (!programSpliceFlag) {
      int componentCount = sectionData.readUnsignedByte();
      componentSplices = new ArrayList<>(componentCount);
      for (int i = 0; i < componentCount; i++) {
        int componentTag = sectionData.readUnsignedByte();
        long componentUtcSpliceTime = sectionData.readUnsignedInt();
        componentSplices.add(new ComponentSplice(componentTag, componentUtcSpliceTime));
      }
    }
    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 Event(spliceEventId, spliceEventCancelIndicator, outOfNetworkIndicator,
      programSpliceFlag, componentSplices, utcSpliceTime, autoReturn, breakDurationUs,
      uniqueProgramId, availNum, availsExpected);
}
 
Example 12
Source File: FragmentedMp4Extractor.java    From MediaSDK with Apache License 2.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 13
Source File: VbriSeeker.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Returns a {@link VbriSeeker} for seeking in the stream, if required information is present.
 * Returns {@code null} if not. On returning, {@code frame}'s position is not specified so the
 * caller should reset it.
 *
 * @param inputLength The length of the stream in bytes, or {@link C#LENGTH_UNSET} if unknown.
 * @param position The position of the start of this frame in the stream.
 * @param mpegAudioHeader The MPEG audio header associated with the frame.
 * @param frame The data in this audio frame, with its position set to immediately after the
 *     'VBRI' tag.
 * @return A {@link VbriSeeker} for seeking in the stream, or {@code null} if the required
 *     information is not present.
 */
public static VbriSeeker create(long inputLength, long position, MpegAudioHeader mpegAudioHeader,
    ParsableByteArray frame) {
  frame.skipBytes(10);
  int numFrames = frame.readInt();
  if (numFrames <= 0) {
    return null;
  }
  int sampleRate = mpegAudioHeader.sampleRate;
  long durationUs = Util.scaleLargeTimestamp(numFrames,
      C.MICROS_PER_SECOND * (sampleRate >= 32000 ? 1152 : 576), sampleRate);
  int entryCount = frame.readUnsignedShort();
  int scale = frame.readUnsignedShort();
  int entrySize = frame.readUnsignedShort();
  frame.skipBytes(2);

  long minPosition = position + mpegAudioHeader.frameSize;
  // Read table of contents entries.
  long[] timesUs = new long[entryCount];
  long[] positions = new long[entryCount];
  for (int index = 0; index < entryCount; index++) {
    timesUs[index] = (index * durationUs) / entryCount;
    // Ensure positions do not fall within the frame containing the VBRI header. This constraint
    // will normally only apply to the first entry in the table.
    positions[index] = Math.max(position, minPosition);
    int segmentSize;
    switch (entrySize) {
      case 1:
        segmentSize = frame.readUnsignedByte();
        break;
      case 2:
        segmentSize = frame.readUnsignedShort();
        break;
      case 3:
        segmentSize = frame.readUnsignedInt24();
        break;
      case 4:
        segmentSize = frame.readUnsignedIntToInt();
        break;
      default:
        return null;
    }
    position += segmentSize * scale;
  }
  if (inputLength != C.LENGTH_UNSET && inputLength != position) {
    Log.w(TAG, "VBRI data size mismatch: " + inputLength + ", " + position);
  }
  return new VbriSeeker(timesUs, positions, durationUs);
}
 
Example 14
Source File: Ac3Extractor.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
@Override
public boolean sniff(ExtractorInput input) throws IOException, InterruptedException {
  // Skip any ID3 headers.
  ParsableByteArray scratch = new ParsableByteArray(10);
  int startPosition = 0;
  while (true) {
    input.peekFully(scratch.data, 0, 10);
    scratch.setPosition(0);
    if (scratch.readUnsignedInt24() != ID3_TAG) {
      break;
    }
    scratch.skipBytes(3); // version, flags
    int length = scratch.readSynchSafeInt();
    startPosition += 10 + length;
    input.advancePeekPosition(length);
  }
  input.resetPeekPosition();
  input.advancePeekPosition(startPosition);

  int headerPosition = startPosition;
  int validFramesCount = 0;
  while (true) {
    input.peekFully(scratch.data, 0, 6);
    scratch.setPosition(0);
    int syncBytes = scratch.readUnsignedShort();
    if (syncBytes != AC3_SYNC_WORD) {
      validFramesCount = 0;
      input.resetPeekPosition();
      if (++headerPosition - startPosition >= MAX_SNIFF_BYTES) {
        return false;
      }
      input.advancePeekPosition(headerPosition);
    } else {
      if (++validFramesCount >= 4) {
        return true;
      }
      int frameSize = Ac3Util.parseAc3SyncframeSize(scratch.data);
      if (frameSize == C.LENGTH_UNSET) {
        return false;
      }
      input.advancePeekPosition(frameSize - 6);
    }
  }
}
 
Example 15
Source File: AvcConfig.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
private static byte[] buildNalUnitForChild(ParsableByteArray data) {
  int length = data.readUnsignedShort();
  int offset = data.getPosition();
  data.skipBytes(length);
  return CodecSpecificDataUtil.buildNalUnit(data.data, offset, length);
}
 
Example 16
Source File: SpliceInsertCommand.java    From Telegram 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 17
Source File: VbriSeeker.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Returns a {@link VbriSeeker} for seeking in the stream, if required information is present.
 * Returns {@code null} if not. On returning, {@code frame}'s position is not specified so the
 * caller should reset it.
 *
 * @param inputLength The length of the stream in bytes, or {@link C#LENGTH_UNSET} if unknown.
 * @param position The position of the start of this frame in the stream.
 * @param mpegAudioHeader The MPEG audio header associated with the frame.
 * @param frame The data in this audio frame, with its position set to immediately after the
 *     'VBRI' tag.
 * @return A {@link VbriSeeker} for seeking in the stream, or {@code null} if the required
 *     information is not present.
 */
public static @Nullable VbriSeeker create(
    long inputLength, long position, MpegAudioHeader mpegAudioHeader, ParsableByteArray frame) {
  frame.skipBytes(10);
  int numFrames = frame.readInt();
  if (numFrames <= 0) {
    return null;
  }
  int sampleRate = mpegAudioHeader.sampleRate;
  long durationUs = Util.scaleLargeTimestamp(numFrames,
      C.MICROS_PER_SECOND * (sampleRate >= 32000 ? 1152 : 576), sampleRate);
  int entryCount = frame.readUnsignedShort();
  int scale = frame.readUnsignedShort();
  int entrySize = frame.readUnsignedShort();
  frame.skipBytes(2);

  long minPosition = position + mpegAudioHeader.frameSize;
  // Read table of contents entries.
  long[] timesUs = new long[entryCount];
  long[] positions = new long[entryCount];
  for (int index = 0; index < entryCount; index++) {
    timesUs[index] = (index * durationUs) / entryCount;
    // Ensure positions do not fall within the frame containing the VBRI header. This constraint
    // will normally only apply to the first entry in the table.
    positions[index] = Math.max(position, minPosition);
    int segmentSize;
    switch (entrySize) {
      case 1:
        segmentSize = frame.readUnsignedByte();
        break;
      case 2:
        segmentSize = frame.readUnsignedShort();
        break;
      case 3:
        segmentSize = frame.readUnsignedInt24();
        break;
      case 4:
        segmentSize = frame.readUnsignedIntToInt();
        break;
      default:
        return null;
    }
    position += segmentSize * scale;
  }
  if (inputLength != C.LENGTH_UNSET && inputLength != position) {
    Log.w(TAG, "VBRI data size mismatch: " + inputLength + ", " + position);
  }
  return new VbriSeeker(timesUs, positions, durationUs, /* dataEndPosition= */ position);
}
 
Example 18
Source File: Id3Decoder.java    From MediaSDK with Apache License 2.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 19
Source File: PsBinarySearchSeeker.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
/**
 * Skips the buffer position to the position after the end of the current PS pack in the buffer,
 * given the byte position right after the {@link PsExtractor#PACK_START_CODE} of the pack in
 * the buffer. If the pack ends after the end of the buffer, skips to the end of the buffer.
 */
private static void skipToEndOfCurrentPack(ParsableByteArray packetBuffer) {
  int limit = packetBuffer.limit();

  if (packetBuffer.bytesLeft() < 10) {
    // We require at least 9 bytes for pack header to read SCR value + 1 byte for pack_stuffing
    // length.
    packetBuffer.setPosition(limit);
    return;
  }
  packetBuffer.skipBytes(9);

  int packStuffingLength = packetBuffer.readUnsignedByte() & 0x07;
  if (packetBuffer.bytesLeft() < packStuffingLength) {
    packetBuffer.setPosition(limit);
    return;
  }
  packetBuffer.skipBytes(packStuffingLength);

  if (packetBuffer.bytesLeft() < 4) {
    packetBuffer.setPosition(limit);
    return;
  }

  int nextStartCode = peekIntAtPosition(packetBuffer.data, packetBuffer.getPosition());
  if (nextStartCode == PsExtractor.SYSTEM_HEADER_START_CODE) {
    packetBuffer.skipBytes(4);
    int systemHeaderLength = packetBuffer.readUnsignedShort();
    if (packetBuffer.bytesLeft() < systemHeaderLength) {
      packetBuffer.setPosition(limit);
      return;
    }
    packetBuffer.skipBytes(systemHeaderLength);
  }

  // Find the position of the next PACK_START_CODE or MPEG_PROGRAM_END_CODE, which is right
  // after the end position of this pack.
  // If we couldn't find these codes within the buffer, return the buffer limit, or return
  // the first position which PES packets pattern does not match (some malformed packets).
  while (packetBuffer.bytesLeft() >= 4) {
    nextStartCode = peekIntAtPosition(packetBuffer.data, packetBuffer.getPosition());
    if (nextStartCode == PsExtractor.PACK_START_CODE
        || nextStartCode == PsExtractor.MPEG_PROGRAM_END_CODE) {
      break;
    }
    if (nextStartCode >>> 8 != PsExtractor.PACKET_START_CODE_PREFIX) {
      break;
    }
    packetBuffer.skipBytes(4);

    if (packetBuffer.bytesLeft() < 2) {
      // 2 bytes for PES_packet length.
      packetBuffer.setPosition(limit);
      return;
    }
    int pesPacketLength = packetBuffer.readUnsignedShort();
    packetBuffer.setPosition(
        Math.min(packetBuffer.limit(), packetBuffer.getPosition() + pesPacketLength));
  }
}
 
Example 20
Source File: AvcConfig.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
private static byte[] buildNalUnitForChild(ParsableByteArray data) {
  int length = data.readUnsignedShort();
  int offset = data.getPosition();
  data.skipBytes(length);
  return CodecSpecificDataUtil.buildNalUnit(data.data, offset, length);
}