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

The following examples show how to use com.google.android.exoplayer2.util.ParsableByteArray#setLimit() . 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: ProjectionDecoder.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
private static @Nullable ArrayList<Mesh> parseProj(ParsableByteArray input) {
  input.skipBytes(8); // size and type.
  int position = input.getPosition();
  int limit = input.limit();
  while (position < limit) {
    int childEnd = position + input.readInt();
    if (childEnd <= position || childEnd > limit) {
      return null;
    }
    int childAtomType = input.readInt();
    // Some early files named the atom ytmp rather than mshp.
    if (childAtomType == TYPE_YTMP || childAtomType == TYPE_MSHP) {
      input.setLimit(childEnd);
      return parseMshp(input);
    }
    position = childEnd;
    input.setPosition(position);
  }
  return null;
}
 
Example 2
Source File: ProjectionDecoder.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
private static @Nullable ArrayList<Mesh> parseProj(ParsableByteArray input) {
  input.skipBytes(8); // size and type.
  int position = input.getPosition();
  int limit = input.limit();
  while (position < limit) {
    int childEnd = position + input.readInt();
    if (childEnd <= position || childEnd > limit) {
      return null;
    }
    int childAtomType = input.readInt();
    // Some early files named the atom ytmp rather than mshp.
    if (childAtomType == TYPE_YTMP || childAtomType == TYPE_MSHP) {
      input.setLimit(childEnd);
      return parseMshp(input);
    }
    position = childEnd;
    input.setPosition(position);
  }
  return null;
}
 
Example 3
Source File: VorbisReader.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
@VisibleForTesting
/* package */ static void appendNumberOfSamples(
    ParsableByteArray buffer, long packetSampleCount) {

  buffer.setLimit(buffer.limit() + 4);
  // The vorbis decoder expects the number of samples in the packet
  // to be appended to the audio data as an int32
  buffer.data[buffer.limit() - 4] = (byte) (packetSampleCount & 0xFF);
  buffer.data[buffer.limit() - 3] = (byte) ((packetSampleCount >>> 8) & 0xFF);
  buffer.data[buffer.limit() - 2] = (byte) ((packetSampleCount >>> 16) & 0xFF);
  buffer.data[buffer.limit() - 1] = (byte) ((packetSampleCount >>> 24) & 0xFF);
}
 
Example 4
Source File: Id3Decoder.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Decodes ID3 tags.
 *
 * @param data The bytes to decode ID3 tags from.
 * @param size Amount of bytes in {@code data} to read.
 * @return A {@link Metadata} object containing the decoded ID3 tags, or null if the data could
 *     not be decoded.
 */
@Nullable
public Metadata decode(byte[] data, int size) {
  List<Id3Frame> id3Frames = new ArrayList<>();
  ParsableByteArray id3Data = new ParsableByteArray(data, size);

  Id3Header id3Header = decodeHeader(id3Data);
  if (id3Header == null) {
    return null;
  }

  int startPosition = id3Data.getPosition();
  int frameHeaderSize = id3Header.majorVersion == 2 ? 6 : 10;
  int framesSize = id3Header.framesSize;
  if (id3Header.isUnsynchronized) {
    framesSize = removeUnsynchronization(id3Data, id3Header.framesSize);
  }
  id3Data.setLimit(startPosition + framesSize);

  boolean unsignedIntFrameSizeHack = false;
  if (!validateFrames(id3Data, id3Header.majorVersion, frameHeaderSize, false)) {
    if (id3Header.majorVersion == 4 && validateFrames(id3Data, 4, frameHeaderSize, true)) {
      unsignedIntFrameSizeHack = true;
    } else {
      Log.w(TAG, "Failed to validate ID3 tag with majorVersion=" + id3Header.majorVersion);
      return null;
    }
  }

  while (id3Data.bytesLeft() >= frameHeaderSize) {
    Id3Frame frame = decodeFrame(id3Header.majorVersion, id3Data, unsignedIntFrameSizeHack,
        frameHeaderSize, framePredicate);
    if (frame != null) {
      id3Frames.add(frame);
    }
  }

  return new Metadata(id3Frames);
}
 
Example 5
Source File: VorbisReader.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
@VisibleForTesting
/* package */ static void appendNumberOfSamples(
    ParsableByteArray buffer, long packetSampleCount) {

  buffer.setLimit(buffer.limit() + 4);
  // The vorbis decoder expects the number of samples in the packet
  // to be appended to the audio data as an int32
  buffer.data[buffer.limit() - 4] = (byte) (packetSampleCount & 0xFF);
  buffer.data[buffer.limit() - 3] = (byte) ((packetSampleCount >>> 8) & 0xFF);
  buffer.data[buffer.limit() - 2] = (byte) ((packetSampleCount >>> 16) & 0xFF);
  buffer.data[buffer.limit() - 1] = (byte) ((packetSampleCount >>> 24) & 0xFF);
}
 
Example 6
Source File: VorbisReader.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
static void appendNumberOfSamples(ParsableByteArray buffer,
    long packetSampleCount) {

  buffer.setLimit(buffer.limit() + 4);
  // The vorbis decoder expects the number of samples in the packet
  // to be appended to the audio data as an int32
  buffer.data[buffer.limit() - 4] = (byte) ((packetSampleCount) & 0xFF);
  buffer.data[buffer.limit() - 3] = (byte) ((packetSampleCount >>> 8) & 0xFF);
  buffer.data[buffer.limit() - 2] = (byte) ((packetSampleCount >>> 16) & 0xFF);
  buffer.data[buffer.limit() - 1] = (byte) ((packetSampleCount >>> 24) & 0xFF);
}
 
Example 7
Source File: Id3Decoder.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Decodes ID3 tags.
 *
 * @param data The bytes to decode ID3 tags from.
 * @param size Amount of bytes in {@code data} to read.
 * @return A {@link Metadata} object containing the decoded ID3 tags, or null if the data could
 *     not be decoded.
 */
public @Nullable Metadata decode(byte[] data, int size) {
  List<Id3Frame> id3Frames = new ArrayList<>();
  ParsableByteArray id3Data = new ParsableByteArray(data, size);

  Id3Header id3Header = decodeHeader(id3Data);
  if (id3Header == null) {
    return null;
  }

  int startPosition = id3Data.getPosition();
  int frameHeaderSize = id3Header.majorVersion == 2 ? 6 : 10;
  int framesSize = id3Header.framesSize;
  if (id3Header.isUnsynchronized) {
    framesSize = removeUnsynchronization(id3Data, id3Header.framesSize);
  }
  id3Data.setLimit(startPosition + framesSize);

  boolean unsignedIntFrameSizeHack = false;
  if (!validateFrames(id3Data, id3Header.majorVersion, frameHeaderSize, false)) {
    if (id3Header.majorVersion == 4 && validateFrames(id3Data, 4, frameHeaderSize, true)) {
      unsignedIntFrameSizeHack = true;
    } else {
      Log.w(TAG, "Failed to validate ID3 tag with majorVersion=" + id3Header.majorVersion);
      return null;
    }
  }

  while (id3Data.bytesLeft() >= frameHeaderSize) {
    Id3Frame frame = decodeFrame(id3Header.majorVersion, id3Data, unsignedIntFrameSizeHack,
        frameHeaderSize, framePredicate);
    if (frame != null) {
      id3Frames.add(frame);
    }
  }

  return new Metadata(id3Frames);
}
 
Example 8
Source File: Id3Decoder.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Decodes ID3 tags.
 *
 * @param data The bytes to decode ID3 tags from.
 * @param size Amount of bytes in {@code data} to read.
 * @return A {@link Metadata} object containing the decoded ID3 tags, or null if the data could
 *     not be decoded.
 */
public @Nullable Metadata decode(byte[] data, int size) {
  List<Id3Frame> id3Frames = new ArrayList<>();
  ParsableByteArray id3Data = new ParsableByteArray(data, size);

  Id3Header id3Header = decodeHeader(id3Data);
  if (id3Header == null) {
    return null;
  }

  int startPosition = id3Data.getPosition();
  int frameHeaderSize = id3Header.majorVersion == 2 ? 6 : 10;
  int framesSize = id3Header.framesSize;
  if (id3Header.isUnsynchronized) {
    framesSize = removeUnsynchronization(id3Data, id3Header.framesSize);
  }
  id3Data.setLimit(startPosition + framesSize);

  boolean unsignedIntFrameSizeHack = false;
  if (!validateFrames(id3Data, id3Header.majorVersion, frameHeaderSize, false)) {
    if (id3Header.majorVersion == 4 && validateFrames(id3Data, 4, frameHeaderSize, true)) {
      unsignedIntFrameSizeHack = true;
    } else {
      Log.w(TAG, "Failed to validate ID3 tag with majorVersion=" + id3Header.majorVersion);
      return null;
    }
  }

  while (id3Data.bytesLeft() >= frameHeaderSize) {
    Id3Frame frame = decodeFrame(id3Header.majorVersion, id3Data, unsignedIntFrameSizeHack,
        frameHeaderSize, framePredicate);
    if (frame != null) {
      id3Frames.add(frame);
    }
  }

  return new Metadata(id3Frames);
}
 
Example 9
Source File: VorbisReader.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
@VisibleForTesting
/* package */ static void appendNumberOfSamples(
    ParsableByteArray buffer, long packetSampleCount) {

  buffer.setLimit(buffer.limit() + 4);
  // The vorbis decoder expects the number of samples in the packet
  // to be appended to the audio data as an int32
  buffer.data[buffer.limit() - 4] = (byte) (packetSampleCount & 0xFF);
  buffer.data[buffer.limit() - 3] = (byte) ((packetSampleCount >>> 8) & 0xFF);
  buffer.data[buffer.limit() - 2] = (byte) ((packetSampleCount >>> 16) & 0xFF);
  buffer.data[buffer.limit() - 1] = (byte) ((packetSampleCount >>> 24) & 0xFF);
}
 
Example 10
Source File: Id3Decoder.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Decodes ID3 tags.
 *
 * @param data The bytes to decode ID3 tags from.
 * @param size Amount of bytes in {@code data} to read.
 * @return A {@link Metadata} object containing the decoded ID3 tags, or null if the data could
 *     not be decoded.
 */
public @Nullable Metadata decode(byte[] data, int size) {
  List<Id3Frame> id3Frames = new ArrayList<>();
  ParsableByteArray id3Data = new ParsableByteArray(data, size);

  Id3Header id3Header = decodeHeader(id3Data);
  if (id3Header == null) {
    return null;
  }

  int startPosition = id3Data.getPosition();
  int frameHeaderSize = id3Header.majorVersion == 2 ? 6 : 10;
  int framesSize = id3Header.framesSize;
  if (id3Header.isUnsynchronized) {
    framesSize = removeUnsynchronization(id3Data, id3Header.framesSize);
  }
  id3Data.setLimit(startPosition + framesSize);

  boolean unsignedIntFrameSizeHack = false;
  if (!validateFrames(id3Data, id3Header.majorVersion, frameHeaderSize, false)) {
    if (id3Header.majorVersion == 4 && validateFrames(id3Data, 4, frameHeaderSize, true)) {
      unsignedIntFrameSizeHack = true;
    } else {
      Log.w(TAG, "Failed to validate ID3 tag with majorVersion=" + id3Header.majorVersion);
      return null;
    }
  }

  while (id3Data.bytesLeft() >= frameHeaderSize) {
    Id3Frame frame = decodeFrame(id3Header.majorVersion, id3Data, unsignedIntFrameSizeHack,
        frameHeaderSize, framePredicate);
    if (frame != null) {
      id3Frames.add(frame);
    }
  }

  return new Metadata(id3Frames);
}
 
Example 11
Source File: Id3Decoder.java    From K-Sonic with MIT License 5 votes vote down vote up
/**
 * Decodes ID3 tags.
 *
 * @param data The bytes to decode ID3 tags from.
 * @param size Amount of bytes in {@code data} to read.
 * @return A {@link Metadata} object containing the decoded ID3 tags.
 */
public Metadata decode(byte[] data, int size) {
  List<Id3Frame> id3Frames = new ArrayList<>();
  ParsableByteArray id3Data = new ParsableByteArray(data, size);

  Id3Header id3Header = decodeHeader(id3Data);
  if (id3Header == null) {
    return null;
  }

  int startPosition = id3Data.getPosition();
  int framesSize = id3Header.framesSize;
  if (id3Header.isUnsynchronized) {
    framesSize = removeUnsynchronization(id3Data, id3Header.framesSize);
  }
  id3Data.setLimit(startPosition + framesSize);

  boolean unsignedIntFrameSizeHack = false;
  if (id3Header.majorVersion == 4) {
    if (!validateV4Frames(id3Data, false)) {
      if (validateV4Frames(id3Data, true)) {
        unsignedIntFrameSizeHack = true;
      } else {
        Log.w(TAG, "Failed to validate V4 ID3 tag");
        return null;
      }
    }
  }

  int frameHeaderSize = id3Header.majorVersion == 2 ? 6 : 10;
  while (id3Data.bytesLeft() >= frameHeaderSize) {
    Id3Frame frame = decodeFrame(id3Header.majorVersion, id3Data, unsignedIntFrameSizeHack,
        frameHeaderSize, framePredicate);
    if (frame != null) {
      id3Frames.add(frame);
    }
  }

  return new Metadata(id3Frames);
}
 
Example 12
Source File: VorbisReader.java    From K-Sonic with MIT License 5 votes vote down vote up
static void appendNumberOfSamples(ParsableByteArray buffer,
    long packetSampleCount) {

  buffer.setLimit(buffer.limit() + 4);
  // The vorbis decoder expects the number of samples in the packet
  // to be appended to the audio data as an int32
  buffer.data[buffer.limit() - 4] = (byte) ((packetSampleCount) & 0xFF);
  buffer.data[buffer.limit() - 3] = (byte) ((packetSampleCount >>> 8) & 0xFF);
  buffer.data[buffer.limit() - 2] = (byte) ((packetSampleCount >>> 16) & 0xFF);
  buffer.data[buffer.limit() - 1] = (byte) ((packetSampleCount >>> 24) & 0xFF);
}
 
Example 13
Source File: Sniffer.java    From Telegram-FOSS 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.readLong();
    } else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
      // The atom extends to the end of the file.
      long fileEndPosition = input.getLength();
      if (fileEndPosition != C.LENGTH_UNSET) {
        atomSize = fileEndPosition - input.getPeekPosition() + headerSize;
      }
    }

    if (inputLength != C.LENGTH_UNSET && bytesSearched + atomSize > inputLength + 10) { //added small trashhold for buggy files
      // The file is invalid because the atom extends past the end of the file.
      return false;
    }
    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) {
      // We have seen the moov atom. We increase the search size to make sure we don't miss an
      // mvex atom because the moov's size exceeds the search length.
      bytesToSearch += (int) atomSize;
      if (inputLength != C.LENGTH_UNSET && bytesToSearch > inputLength) {
        // Make sure we don't exceed the file size.
        bytesToSearch = (int) inputLength;
      }
      // 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 14
Source File: PesReader.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
@Override
public final void consume(ParsableByteArray data, @Flags int flags) throws ParserException {
  if ((flags & FLAG_PAYLOAD_UNIT_START_INDICATOR) != 0) {
    switch (state) {
      case STATE_FINDING_HEADER:
      case STATE_READING_HEADER:
        // Expected.
        break;
      case STATE_READING_HEADER_EXTENSION:
        Log.w(TAG, "Unexpected start indicator reading extended header");
        break;
      case STATE_READING_BODY:
        // If payloadSize == -1 then the length of the previous packet was unspecified, and so
        // we only know that it's finished now that we've seen the start of the next one. This
        // is expected. If payloadSize != -1, then the length of the previous packet was known,
        // but we didn't receive that amount of data. This is not expected.
        if (payloadSize != -1) {
          Log.w(TAG, "Unexpected start indicator: expected " + payloadSize + " more bytes");
        }
        // Either way, notify the reader that it has now finished.
        reader.packetFinished();
        break;
      default:
        throw new IllegalStateException();
    }
    setState(STATE_READING_HEADER);
  }

  while (data.bytesLeft() > 0) {
    switch (state) {
      case STATE_FINDING_HEADER:
        data.skipBytes(data.bytesLeft());
        break;
      case STATE_READING_HEADER:
        if (continueRead(data, pesScratch.data, HEADER_SIZE)) {
          setState(parseHeader() ? STATE_READING_HEADER_EXTENSION : STATE_FINDING_HEADER);
        }
        break;
      case STATE_READING_HEADER_EXTENSION:
        int readLength = Math.min(MAX_HEADER_EXTENSION_SIZE, extendedHeaderLength);
        // Read as much of the extended header as we're interested in, and skip the rest.
        if (continueRead(data, pesScratch.data, readLength)
            && continueRead(data, null, extendedHeaderLength)) {
          parseHeaderExtension();
          flags |= dataAlignmentIndicator ? FLAG_DATA_ALIGNMENT_INDICATOR : 0;
          reader.packetStarted(timeUs, flags);
          setState(STATE_READING_BODY);
        }
        break;
      case STATE_READING_BODY:
        readLength = data.bytesLeft();
        int padding = payloadSize == -1 ? 0 : readLength - payloadSize;
        if (padding > 0) {
          readLength -= padding;
          data.setLimit(data.getPosition() + readLength);
        }
        reader.consume(data);
        if (payloadSize != -1) {
          payloadSize -= readLength;
          if (payloadSize == 0) {
            reader.packetFinished();
            setState(STATE_READING_HEADER);
          }
        }
        break;
      default:
        throw new IllegalStateException();
    }
  }
}
 
Example 15
Source File: PesReader.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
@Override
public final void consume(ParsableByteArray data, @Flags int flags) throws ParserException {
  if ((flags & FLAG_PAYLOAD_UNIT_START_INDICATOR) != 0) {
    switch (state) {
      case STATE_FINDING_HEADER:
      case STATE_READING_HEADER:
        // Expected.
        break;
      case STATE_READING_HEADER_EXTENSION:
        Log.w(TAG, "Unexpected start indicator reading extended header");
        break;
      case STATE_READING_BODY:
        // If payloadSize == -1 then the length of the previous packet was unspecified, and so
        // we only know that it's finished now that we've seen the start of the next one. This
        // is expected. If payloadSize != -1, then the length of the previous packet was known,
        // but we didn't receive that amount of data. This is not expected.
        if (payloadSize != -1) {
          Log.w(TAG, "Unexpected start indicator: expected " + payloadSize + " more bytes");
        }
        // Either way, notify the reader that it has now finished.
        reader.packetFinished();
        break;
      default:
        throw new IllegalStateException();
    }
    setState(STATE_READING_HEADER);
  }

  while (data.bytesLeft() > 0) {
    switch (state) {
      case STATE_FINDING_HEADER:
        data.skipBytes(data.bytesLeft());
        break;
      case STATE_READING_HEADER:
        if (continueRead(data, pesScratch.data, HEADER_SIZE)) {
          setState(parseHeader() ? STATE_READING_HEADER_EXTENSION : STATE_FINDING_HEADER);
        }
        break;
      case STATE_READING_HEADER_EXTENSION:
        int readLength = Math.min(MAX_HEADER_EXTENSION_SIZE, extendedHeaderLength);
        // Read as much of the extended header as we're interested in, and skip the rest.
        if (continueRead(data, pesScratch.data, readLength)
            && continueRead(data, null, extendedHeaderLength)) {
          parseHeaderExtension();
          flags |= dataAlignmentIndicator ? FLAG_DATA_ALIGNMENT_INDICATOR : 0;
          reader.packetStarted(timeUs, flags);
          setState(STATE_READING_BODY);
        }
        break;
      case STATE_READING_BODY:
        readLength = data.bytesLeft();
        int padding = payloadSize == -1 ? 0 : readLength - payloadSize;
        if (padding > 0) {
          readLength -= padding;
          data.setLimit(data.getPosition() + readLength);
        }
        reader.consume(data);
        if (payloadSize != -1) {
          payloadSize -= readLength;
          if (payloadSize == 0) {
            reader.packetFinished();
            setState(STATE_READING_HEADER);
          }
        }
        break;
      default:
        throw new IllegalStateException();
    }
  }
}
 
Example 16
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;
}
 
Example 17
Source File: PesReader.java    From K-Sonic with MIT License 4 votes vote down vote up
@Override
public final void consume(ParsableByteArray data, boolean payloadUnitStartIndicator) {
  if (payloadUnitStartIndicator) {
    switch (state) {
      case STATE_FINDING_HEADER:
      case STATE_READING_HEADER:
        // Expected.
        break;
      case STATE_READING_HEADER_EXTENSION:
        Log.w(TAG, "Unexpected start indicator reading extended header");
        break;
      case STATE_READING_BODY:
        // If payloadSize == -1 then the length of the previous packet was unspecified, and so
        // we only know that it's finished now that we've seen the start of the next one. This
        // is expected. If payloadSize != -1, then the length of the previous packet was known,
        // but we didn't receive that amount of data. This is not expected.
        if (payloadSize != -1) {
          Log.w(TAG, "Unexpected start indicator: expected " + payloadSize + " more bytes");
        }
        // Either way, notify the reader that it has now finished.
        reader.packetFinished();
        break;
    }
    setState(STATE_READING_HEADER);
  }

  while (data.bytesLeft() > 0) {
    switch (state) {
      case STATE_FINDING_HEADER:
        data.skipBytes(data.bytesLeft());
        break;
      case STATE_READING_HEADER:
        if (continueRead(data, pesScratch.data, HEADER_SIZE)) {
          setState(parseHeader() ? STATE_READING_HEADER_EXTENSION : STATE_FINDING_HEADER);
        }
        break;
      case STATE_READING_HEADER_EXTENSION:
        int readLength = Math.min(MAX_HEADER_EXTENSION_SIZE, extendedHeaderLength);
        // Read as much of the extended header as we're interested in, and skip the rest.
        if (continueRead(data, pesScratch.data, readLength)
            && continueRead(data, null, extendedHeaderLength)) {
          parseHeaderExtension();
          reader.packetStarted(timeUs, dataAlignmentIndicator);
          setState(STATE_READING_BODY);
        }
        break;
      case STATE_READING_BODY:
        readLength = data.bytesLeft();
        int padding = payloadSize == -1 ? 0 : readLength - payloadSize;
        if (padding > 0) {
          readLength -= padding;
          data.setLimit(data.getPosition() + readLength);
        }
        reader.consume(data);
        if (payloadSize != -1) {
          payloadSize -= readLength;
          if (payloadSize == 0) {
            reader.packetFinished();
            setState(STATE_READING_HEADER);
          }
        }
        break;
    }
  }
}
 
Example 18
Source File: PesReader.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
@Override
public final void consume(ParsableByteArray data, @Flags int flags) throws ParserException {
  if ((flags & FLAG_PAYLOAD_UNIT_START_INDICATOR) != 0) {
    switch (state) {
      case STATE_FINDING_HEADER:
      case STATE_READING_HEADER:
        // Expected.
        break;
      case STATE_READING_HEADER_EXTENSION:
        Log.w(TAG, "Unexpected start indicator reading extended header");
        break;
      case STATE_READING_BODY:
        // If payloadSize == -1 then the length of the previous packet was unspecified, and so
        // we only know that it's finished now that we've seen the start of the next one. This
        // is expected. If payloadSize != -1, then the length of the previous packet was known,
        // but we didn't receive that amount of data. This is not expected.
        if (payloadSize != -1) {
          Log.w(TAG, "Unexpected start indicator: expected " + payloadSize + " more bytes");
        }
        // Either way, notify the reader that it has now finished.
        reader.packetFinished();
        break;
      default:
        throw new IllegalStateException();
    }
    setState(STATE_READING_HEADER);
  }

  while (data.bytesLeft() > 0) {
    switch (state) {
      case STATE_FINDING_HEADER:
        data.skipBytes(data.bytesLeft());
        break;
      case STATE_READING_HEADER:
        if (continueRead(data, pesScratch.data, HEADER_SIZE)) {
          setState(parseHeader() ? STATE_READING_HEADER_EXTENSION : STATE_FINDING_HEADER);
        }
        break;
      case STATE_READING_HEADER_EXTENSION:
        int readLength = Math.min(MAX_HEADER_EXTENSION_SIZE, extendedHeaderLength);
        // Read as much of the extended header as we're interested in, and skip the rest.
        if (continueRead(data, pesScratch.data, readLength)
            && continueRead(data, null, extendedHeaderLength)) {
          parseHeaderExtension();
          flags |= dataAlignmentIndicator ? FLAG_DATA_ALIGNMENT_INDICATOR : 0;
          reader.packetStarted(timeUs, flags);
          setState(STATE_READING_BODY);
        }
        break;
      case STATE_READING_BODY:
        readLength = data.bytesLeft();
        int padding = payloadSize == -1 ? 0 : readLength - payloadSize;
        if (padding > 0) {
          readLength -= padding;
          data.setLimit(data.getPosition() + readLength);
        }
        reader.consume(data);
        if (payloadSize != -1) {
          payloadSize -= readLength;
          if (payloadSize == 0) {
            reader.packetFinished();
            setState(STATE_READING_HEADER);
          }
        }
        break;
      default:
        throw new IllegalStateException();
    }
  }
}
 
Example 19
Source File: PesReader.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
@Override
public final void consume(ParsableByteArray data, boolean payloadUnitStartIndicator)
    throws ParserException {
  if (payloadUnitStartIndicator) {
    switch (state) {
      case STATE_FINDING_HEADER:
      case STATE_READING_HEADER:
        // Expected.
        break;
      case STATE_READING_HEADER_EXTENSION:
        Log.w(TAG, "Unexpected start indicator reading extended header");
        break;
      case STATE_READING_BODY:
        // If payloadSize == -1 then the length of the previous packet was unspecified, and so
        // we only know that it's finished now that we've seen the start of the next one. This
        // is expected. If payloadSize != -1, then the length of the previous packet was known,
        // but we didn't receive that amount of data. This is not expected.
        if (payloadSize != -1) {
          Log.w(TAG, "Unexpected start indicator: expected " + payloadSize + " more bytes");
        }
        // Either way, notify the reader that it has now finished.
        reader.packetFinished();
        break;
    }
    setState(STATE_READING_HEADER);
  }

  while (data.bytesLeft() > 0) {
    switch (state) {
      case STATE_FINDING_HEADER:
        data.skipBytes(data.bytesLeft());
        break;
      case STATE_READING_HEADER:
        if (continueRead(data, pesScratch.data, HEADER_SIZE)) {
          setState(parseHeader() ? STATE_READING_HEADER_EXTENSION : STATE_FINDING_HEADER);
        }
        break;
      case STATE_READING_HEADER_EXTENSION:
        int readLength = Math.min(MAX_HEADER_EXTENSION_SIZE, extendedHeaderLength);
        // Read as much of the extended header as we're interested in, and skip the rest.
        if (continueRead(data, pesScratch.data, readLength)
            && continueRead(data, null, extendedHeaderLength)) {
          parseHeaderExtension();
          reader.packetStarted(timeUs, dataAlignmentIndicator);
          setState(STATE_READING_BODY);
        }
        break;
      case STATE_READING_BODY:
        readLength = data.bytesLeft();
        int padding = payloadSize == -1 ? 0 : readLength - payloadSize;
        if (padding > 0) {
          readLength -= padding;
          data.setLimit(data.getPosition() + readLength);
        }
        reader.consume(data);
        if (payloadSize != -1) {
          payloadSize -= readLength;
          if (payloadSize == 0) {
            reader.packetFinished();
            setState(STATE_READING_HEADER);
          }
        }
        break;
    }
  }
}
 
Example 20
Source File: Sniffer.java    From MediaSDK with Apache License 2.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.readLong();
    } else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
      // The atom extends to the end of the file.
      long fileEndPosition = input.getLength();
      if (fileEndPosition != C.LENGTH_UNSET) {
        atomSize = fileEndPosition - input.getPeekPosition() + 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) {
      // We have seen the moov atom. We increase the search size to make sure we don't miss an
      // mvex atom because the moov's size exceeds the search length.
      bytesToSearch += (int) atomSize;
      if (inputLength != C.LENGTH_UNSET && bytesToSearch > inputLength) {
        // Make sure we don't exceed the file size.
        bytesToSearch = (int) inputLength;
      }
      // 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;
}