Java Code Examples for com.google.android.exoplayer2.extractor.ExtractorInput#getPeekPosition()

The following examples show how to use com.google.android.exoplayer2.extractor.ExtractorInput#getPeekPosition() . 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: Mp3Extractor.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Returns whether the extractor input is peeking the end of the stream. If {@code false},
 * populates the scratch buffer with the next four bytes.
 */
private boolean peekEndOfStreamOrHeader(ExtractorInput extractorInput)
    throws IOException, InterruptedException {
  if (seeker != null) {
    long dataEndPosition = seeker.getDataEndPosition();
    if (dataEndPosition != C.POSITION_UNSET
        && extractorInput.getPeekPosition() > dataEndPosition - 4) {
      return true;
    }
  }
  try {
    return !extractorInput.peekFully(
        scratch.data, /* offset= */ 0, /* length= */ 4, /* allowEndOfInput= */ true);
  } catch (EOFException e) {
    return true;
  }
}
 
Example 2
Source File: Mp3Extractor.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * Returns whether the extractor input is peeking the end of the stream. If {@code false},
 * populates the scratch buffer with the next four bytes.
 */
private boolean peekEndOfStreamOrHeader(ExtractorInput extractorInput)
    throws IOException, InterruptedException {
  if (seeker != null) {
    long dataEndPosition = seeker.getDataEndPosition();
    if (dataEndPosition != C.POSITION_UNSET
        && extractorInput.getPeekPosition() > dataEndPosition - 4) {
      return true;
    }
  }
  try {
    return !extractorInput.peekFully(
        scratch.data, /* offset= */ 0, /* length= */ 4, /* allowEndOfInput= */ true);
  } catch (EOFException e) {
    return true;
  }
}
 
Example 3
Source File: Mp3Extractor.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Returns whether the extractor input is peeking the end of the stream. If {@code false},
 * populates the scratch buffer with the next four bytes.
 */
private boolean peekEndOfStreamOrHeader(ExtractorInput extractorInput)
    throws IOException, InterruptedException {
  if (seeker != null) {
    long dataEndPosition = seeker.getDataEndPosition();
    if (dataEndPosition != C.POSITION_UNSET
        && extractorInput.getPeekPosition() > dataEndPosition - 4) {
      return true;
    }
  }
  try {
    return !extractorInput.peekFully(
        scratch.data, /* offset= */ 0, /* length= */ 4, /* allowEndOfInput= */ true);
  } catch (EOFException e) {
    return true;
  }
}
 
Example 4
Source File: Mp3Extractor.java    From K-Sonic with MIT License 4 votes vote down vote up
private boolean synchronize(ExtractorInput input, boolean sniffing)
    throws IOException, InterruptedException {
  int validFrameCount = 0;
  int candidateSynchronizedHeaderData = 0;
  int peekedId3Bytes = 0;
  int searchedBytes = 0;
  int searchLimitBytes = sniffing ? MAX_SNIFF_BYTES : MAX_SYNC_BYTES;
  input.resetPeekPosition();
  if (input.getPosition() == 0) {
    peekId3Data(input);
    peekedId3Bytes = (int) input.getPeekPosition();
    if (!sniffing) {
      input.skipFully(peekedId3Bytes);
    }
  }
  while (true) {
    if (!input.peekFully(scratch.data, 0, 4, validFrameCount > 0)) {
      // We reached the end of the stream but found at least one valid frame.
      break;
    }
    scratch.setPosition(0);
    int headerData = scratch.readInt();
    int frameSize;
    if ((candidateSynchronizedHeaderData != 0
        && (headerData & HEADER_MASK) != (candidateSynchronizedHeaderData & HEADER_MASK))
        || (frameSize = MpegAudioHeader.getFrameSize(headerData)) == C.LENGTH_UNSET) {
      // The header doesn't match the candidate header or is invalid. Try the next byte offset.
      if (searchedBytes++ == searchLimitBytes) {
        if (!sniffing) {
          throw new ParserException("Searched too many bytes.");
        }
        return false;
      }
      validFrameCount = 0;
      candidateSynchronizedHeaderData = 0;
      if (sniffing) {
        input.resetPeekPosition();
        input.advancePeekPosition(peekedId3Bytes + searchedBytes);
      } else {
        input.skipFully(1);
      }
    } else {
      // The header matches the candidate header and/or is valid.
      validFrameCount++;
      if (validFrameCount == 1) {
        MpegAudioHeader.populateHeader(headerData, synchronizedHeader);
        candidateSynchronizedHeaderData = headerData;
      } else if (validFrameCount == 4) {
        break;
      }
      input.advancePeekPosition(frameSize - 4);
    }
  }
  // Prepare to read the synchronized frame.
  if (sniffing) {
    input.skipFully(peekedId3Bytes + searchedBytes);
  } else {
    input.resetPeekPosition();
  }
  synchronizedHeaderData = candidateSynchronizedHeaderData;
  return true;
}
 
Example 5
Source File: Mp3Extractor.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
private boolean synchronize(ExtractorInput input, boolean sniffing)
    throws IOException, InterruptedException {
  int validFrameCount = 0;
  int candidateSynchronizedHeaderData = 0;
  int peekedId3Bytes = 0;
  int searchedBytes = 0;
  int searchLimitBytes = sniffing ? MAX_SNIFF_BYTES : MAX_SYNC_BYTES;
  input.resetPeekPosition();
  if (input.getPosition() == 0) {
    // We need to parse enough ID3 metadata to retrieve any gapless/seeking playback information
    // even if ID3 metadata parsing is disabled.
    boolean parseAllId3Frames = (flags & FLAG_DISABLE_ID3_METADATA) == 0;
    Id3Decoder.FramePredicate id3FramePredicate =
        parseAllId3Frames ? null : REQUIRED_ID3_FRAME_PREDICATE;
    metadata = id3Peeker.peekId3Data(input, id3FramePredicate);
    if (metadata != null) {
      gaplessInfoHolder.setFromMetadata(metadata);
    }
    peekedId3Bytes = (int) input.getPeekPosition();
    if (!sniffing) {
      input.skipFully(peekedId3Bytes);
    }
  }
  while (true) {
    if (peekEndOfStreamOrHeader(input)) {
      if (validFrameCount > 0) {
        // We reached the end of the stream but found at least one valid frame.
        break;
      }
      throw new EOFException();
    }
    scratch.setPosition(0);
    int headerData = scratch.readInt();
    int frameSize;
    if ((candidateSynchronizedHeaderData != 0
        && !headersMatch(headerData, candidateSynchronizedHeaderData))
        || (frameSize = MpegAudioHeader.getFrameSize(headerData)) == C.LENGTH_UNSET) {
      // The header doesn't match the candidate header or is invalid. Try the next byte offset.
      if (searchedBytes++ == searchLimitBytes) {
        if (!sniffing) {
          throw new ParserException("Searched too many bytes.");
        }
        return false;
      }
      validFrameCount = 0;
      candidateSynchronizedHeaderData = 0;
      if (sniffing) {
        input.resetPeekPosition();
        input.advancePeekPosition(peekedId3Bytes + searchedBytes);
      } else {
        input.skipFully(1);
      }
    } else {
      // The header matches the candidate header and/or is valid.
      validFrameCount++;
      if (validFrameCount == 1) {
        MpegAudioHeader.populateHeader(headerData, synchronizedHeader);
        candidateSynchronizedHeaderData = headerData;
      } else if (validFrameCount == 4) {
        break;
      }
      input.advancePeekPosition(frameSize - 4);
    }
  }
  // Prepare to read the synchronized frame.
  if (sniffing) {
    input.skipFully(peekedId3Bytes + searchedBytes);
  } else {
    input.resetPeekPosition();
  }
  synchronizedHeaderData = candidateSynchronizedHeaderData;
  return true;
}
 
Example 6
Source File: Sniffer.java    From Telegram 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 7
Source File: OggPageHeader.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Peeks an Ogg page header and updates this {@link OggPageHeader}.
 *
 * @param input The {@link ExtractorInput} to read from.
 * @param quiet Whether to return {@code false} rather than throwing an exception if the header
 *     cannot be populated.
 * @return Whether the read was successful. The read fails if the end of the input is encountered
 *     without reading data.
 * @throws IOException If reading data fails or the stream is invalid.
 * @throws InterruptedException If the thread is interrupted.
 */
public boolean populate(ExtractorInput input, boolean quiet)
    throws IOException, InterruptedException {
  scratch.reset();
  reset();
  boolean hasEnoughBytes = input.getLength() == C.LENGTH_UNSET
      || input.getLength() - input.getPeekPosition() >= EMPTY_PAGE_HEADER_SIZE;
  if (!hasEnoughBytes || !input.peekFully(scratch.data, 0, EMPTY_PAGE_HEADER_SIZE, true)) {
    if (quiet) {
      return false;
    } else {
      throw new EOFException();
    }
  }
  if (scratch.readUnsignedInt() != TYPE_OGGS) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("expected OggS capture pattern at begin of page");
    }
  }

  revision = scratch.readUnsignedByte();
  if (revision != 0x00) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("unsupported bit stream revision");
    }
  }
  type = scratch.readUnsignedByte();

  granulePosition = scratch.readLittleEndianLong();
  streamSerialNumber = scratch.readLittleEndianUnsignedInt();
  pageSequenceNumber = scratch.readLittleEndianUnsignedInt();
  pageChecksum = scratch.readLittleEndianUnsignedInt();
  pageSegmentCount = scratch.readUnsignedByte();
  headerSize = EMPTY_PAGE_HEADER_SIZE + pageSegmentCount;

  // calculate total size of header including laces
  scratch.reset();
  input.peekFully(scratch.data, 0, pageSegmentCount);
  for (int i = 0; i < pageSegmentCount; i++) {
    laces[i] = scratch.readUnsignedByte();
    bodySize += laces[i];
  }

  return true;
}
 
Example 8
Source File: Mp3Extractor.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
private boolean synchronize(ExtractorInput input, boolean sniffing)
    throws IOException, InterruptedException {
  int validFrameCount = 0;
  int candidateSynchronizedHeaderData = 0;
  int peekedId3Bytes = 0;
  int searchedBytes = 0;
  int searchLimitBytes = sniffing ? MAX_SNIFF_BYTES : MAX_SYNC_BYTES;
  input.resetPeekPosition();
  if (input.getPosition() == 0) {
    // We need to parse enough ID3 metadata to retrieve any gapless/seeking playback information
    // even if ID3 metadata parsing is disabled.
    boolean parseAllId3Frames = (flags & FLAG_DISABLE_ID3_METADATA) == 0;
    Id3Decoder.FramePredicate id3FramePredicate =
        parseAllId3Frames ? null : REQUIRED_ID3_FRAME_PREDICATE;
    metadata = id3Peeker.peekId3Data(input, id3FramePredicate);
    if (metadata != null) {
      gaplessInfoHolder.setFromMetadata(metadata);
    }
    peekedId3Bytes = (int) input.getPeekPosition();
    if (!sniffing) {
      input.skipFully(peekedId3Bytes);
    }
  }
  while (true) {
    if (peekEndOfStreamOrHeader(input)) {
      if (validFrameCount > 0) {
        // We reached the end of the stream but found at least one valid frame.
        break;
      }
      throw new EOFException();
    }
    scratch.setPosition(0);
    int headerData = scratch.readInt();
    int frameSize;
    if ((candidateSynchronizedHeaderData != 0
        && !headersMatch(headerData, candidateSynchronizedHeaderData))
        || (frameSize = MpegAudioHeader.getFrameSize(headerData)) == C.LENGTH_UNSET) {
      // The header doesn't match the candidate header or is invalid. Try the next byte offset.
      if (searchedBytes++ == searchLimitBytes) {
        if (!sniffing) {
          throw new ParserException("Searched too many bytes.");
        }
        return false;
      }
      validFrameCount = 0;
      candidateSynchronizedHeaderData = 0;
      if (sniffing) {
        input.resetPeekPosition();
        input.advancePeekPosition(peekedId3Bytes + searchedBytes);
      } else {
        input.skipFully(1);
      }
    } else {
      // The header matches the candidate header and/or is valid.
      validFrameCount++;
      if (validFrameCount == 1) {
        MpegAudioHeader.populateHeader(headerData, synchronizedHeader);
        candidateSynchronizedHeaderData = headerData;
      } else if (validFrameCount == 4) {
        break;
      }
      input.advancePeekPosition(frameSize - 4);
    }
  }
  // Prepare to read the synchronized frame.
  if (sniffing) {
    input.skipFully(peekedId3Bytes + searchedBytes);
  } else {
    input.resetPeekPosition();
  }
  synchronizedHeaderData = candidateSynchronizedHeaderData;
  return true;
}
 
Example 9
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 10
Source File: OggPageHeader.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Peeks an Ogg page header and updates this {@link OggPageHeader}.
 *
 * @param input The {@link ExtractorInput} to read from.
 * @param quiet Whether to return {@code false} rather than throwing an exception if the header
 *     cannot be populated.
 * @return Whether the read was successful. The read fails if the end of the input is encountered
 *     without reading data.
 * @throws IOException If reading data fails or the stream is invalid.
 * @throws InterruptedException If the thread is interrupted.
 */
public boolean populate(ExtractorInput input, boolean quiet)
    throws IOException, InterruptedException {
  scratch.reset();
  reset();
  boolean hasEnoughBytes = input.getLength() == C.LENGTH_UNSET
      || input.getLength() - input.getPeekPosition() >= EMPTY_PAGE_HEADER_SIZE;
  if (!hasEnoughBytes || !input.peekFully(scratch.data, 0, EMPTY_PAGE_HEADER_SIZE, true)) {
    if (quiet) {
      return false;
    } else {
      throw new EOFException();
    }
  }
  if (scratch.readUnsignedInt() != TYPE_OGGS) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("expected OggS capture pattern at begin of page");
    }
  }

  revision = scratch.readUnsignedByte();
  if (revision != 0x00) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("unsupported bit stream revision");
    }
  }
  type = scratch.readUnsignedByte();

  granulePosition = scratch.readLittleEndianLong();
  streamSerialNumber = scratch.readLittleEndianUnsignedInt();
  pageSequenceNumber = scratch.readLittleEndianUnsignedInt();
  pageChecksum = scratch.readLittleEndianUnsignedInt();
  pageSegmentCount = scratch.readUnsignedByte();
  headerSize = EMPTY_PAGE_HEADER_SIZE + pageSegmentCount;

  // calculate total size of header including laces
  scratch.reset();
  input.peekFully(scratch.data, 0, pageSegmentCount);
  for (int i = 0; i < pageSegmentCount; i++) {
    laces[i] = scratch.readUnsignedByte();
    bodySize += laces[i];
  }

  return true;
}
 
Example 11
Source File: OggPageHeader.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
/**
 * Peeks an Ogg page header and updates this {@link OggPageHeader}.
 *
 * @param input The {@link ExtractorInput} to read from.
 * @param quiet Whether to return {@code false} rather than throwing an exception if the header
 *     cannot be populated.
 * @return Whether the read was successful. The read fails if the end of the input is encountered
 *     without reading data.
 * @throws IOException If reading data fails or the stream is invalid.
 * @throws InterruptedException If the thread is interrupted.
 */
public boolean populate(ExtractorInput input, boolean quiet)
    throws IOException, InterruptedException {
  scratch.reset();
  reset();
  boolean hasEnoughBytes = input.getLength() == C.LENGTH_UNSET
      || input.getLength() - input.getPeekPosition() >= EMPTY_PAGE_HEADER_SIZE;
  if (!hasEnoughBytes || !input.peekFully(scratch.data, 0, EMPTY_PAGE_HEADER_SIZE, true)) {
    if (quiet) {
      return false;
    } else {
      throw new EOFException();
    }
  }
  if (scratch.readUnsignedInt() != TYPE_OGGS) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("expected OggS capture pattern at begin of page");
    }
  }

  revision = scratch.readUnsignedByte();
  if (revision != 0x00) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("unsupported bit stream revision");
    }
  }
  type = scratch.readUnsignedByte();

  granulePosition = scratch.readLittleEndianLong();
  streamSerialNumber = scratch.readLittleEndianUnsignedInt();
  pageSequenceNumber = scratch.readLittleEndianUnsignedInt();
  pageChecksum = scratch.readLittleEndianUnsignedInt();
  pageSegmentCount = scratch.readUnsignedByte();
  headerSize = EMPTY_PAGE_HEADER_SIZE + pageSegmentCount;

  // calculate total size of header including laces
  scratch.reset();
  input.peekFully(scratch.data, 0, pageSegmentCount);
  for (int i = 0; i < pageSegmentCount; i++) {
    laces[i] = scratch.readUnsignedByte();
    bodySize += laces[i];
  }

  return true;
}
 
Example 12
Source File: OggPageHeader.java    From K-Sonic with MIT License 4 votes vote down vote up
/**
 * Peeks an Ogg page header and updates this {@link OggPageHeader}.
 *
 * @param input the {@link ExtractorInput} to read from.
 * @param quiet if {@code true} no Exceptions are thrown but {@code false} is return if something
 *    goes wrong.
 * @return {@code true} if the read was successful. {@code false} if the end of the input was
 *    encountered having read no data.
 * @throws IOException thrown if reading data fails or the stream is invalid.
 * @throws InterruptedException thrown if thread is interrupted when reading/peeking.
 */
public boolean populate(ExtractorInput input, boolean quiet)
    throws IOException, InterruptedException {
  scratch.reset();
  reset();
  boolean hasEnoughBytes = input.getLength() == C.LENGTH_UNSET
      || input.getLength() - input.getPeekPosition() >= EMPTY_PAGE_HEADER_SIZE;
  if (!hasEnoughBytes || !input.peekFully(scratch.data, 0, EMPTY_PAGE_HEADER_SIZE, true)) {
    if (quiet) {
      return false;
    } else {
      throw new EOFException();
    }
  }
  if (scratch.readUnsignedInt() != TYPE_OGGS) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("expected OggS capture pattern at begin of page");
    }
  }

  revision = scratch.readUnsignedByte();
  if (revision != 0x00) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("unsupported bit stream revision");
    }
  }
  type = scratch.readUnsignedByte();

  granulePosition = scratch.readLittleEndianLong();
  streamSerialNumber = scratch.readLittleEndianUnsignedInt();
  pageSequenceNumber = scratch.readLittleEndianUnsignedInt();
  pageChecksum = scratch.readLittleEndianUnsignedInt();
  pageSegmentCount = scratch.readUnsignedByte();
  headerSize = EMPTY_PAGE_HEADER_SIZE + pageSegmentCount;

  // calculate total size of header including laces
  scratch.reset();
  input.peekFully(scratch.data, 0, pageSegmentCount);
  for (int i = 0; i < pageSegmentCount; i++) {
    laces[i] = scratch.readUnsignedByte();
    bodySize += laces[i];
  }

  return true;
}
 
Example 13
Source File: Mp3Extractor.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
private boolean synchronize(ExtractorInput input, boolean sniffing)
    throws IOException, InterruptedException {
  int validFrameCount = 0;
  int candidateSynchronizedHeaderData = 0;
  int peekedId3Bytes = 0;
  int searchedBytes = 0;
  int searchLimitBytes = sniffing ? MAX_SNIFF_BYTES : MAX_SYNC_BYTES;
  input.resetPeekPosition();
  if (input.getPosition() == 0) {
    // We need to parse enough ID3 metadata to retrieve any gapless playback information even
    // if ID3 metadata parsing is disabled.
    boolean onlyDecodeGaplessInfoFrames = (flags & FLAG_DISABLE_ID3_METADATA) != 0;
    Id3Decoder.FramePredicate id3FramePredicate =
        onlyDecodeGaplessInfoFrames ? GaplessInfoHolder.GAPLESS_INFO_ID3_FRAME_PREDICATE : null;
    metadata = id3Peeker.peekId3Data(input, id3FramePredicate);
    if (metadata != null) {
      gaplessInfoHolder.setFromMetadata(metadata);
    }
    peekedId3Bytes = (int) input.getPeekPosition();
    if (!sniffing) {
      input.skipFully(peekedId3Bytes);
    }
  }
  while (true) {
    if (!input.peekFully(scratch.data, 0, 4, validFrameCount > 0)) {
      // We reached the end of the stream but found at least one valid frame.
      break;
    }
    scratch.setPosition(0);
    int headerData = scratch.readInt();
    int frameSize;
    if ((candidateSynchronizedHeaderData != 0
        && !headersMatch(headerData, candidateSynchronizedHeaderData))
        || (frameSize = MpegAudioHeader.getFrameSize(headerData)) == C.LENGTH_UNSET) {
      // The header doesn't match the candidate header or is invalid. Try the next byte offset.
      if (searchedBytes++ == searchLimitBytes) {
        if (!sniffing) {
          throw new ParserException("Searched too many bytes.");
        }
        return false;
      }
      validFrameCount = 0;
      candidateSynchronizedHeaderData = 0;
      if (sniffing) {
        input.resetPeekPosition();
        input.advancePeekPosition(peekedId3Bytes + searchedBytes);
      } else {
        input.skipFully(1);
      }
    } else {
      // The header matches the candidate header and/or is valid.
      validFrameCount++;
      if (validFrameCount == 1) {
        MpegAudioHeader.populateHeader(headerData, synchronizedHeader);
        candidateSynchronizedHeaderData = headerData;
      } else if (validFrameCount == 4) {
        break;
      }
      input.advancePeekPosition(frameSize - 4);
    }
  }
  // Prepare to read the synchronized frame.
  if (sniffing) {
    input.skipFully(peekedId3Bytes + searchedBytes);
  } else {
    input.resetPeekPosition();
  }
  synchronizedHeaderData = candidateSynchronizedHeaderData;
  return true;
}
 
Example 14
Source File: OggPageHeader.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Peeks an Ogg page header and updates this {@link OggPageHeader}.
 *
 * @param input the {@link ExtractorInput} to read from.
 * @param quiet if {@code true} no Exceptions are thrown but {@code false} is return if something
 *    goes wrong.
 * @return {@code true} if the read was successful. {@code false} if the end of the input was
 *    encountered having read no data.
 * @throws IOException thrown if reading data fails or the stream is invalid.
 * @throws InterruptedException thrown if thread is interrupted when reading/peeking.
 */
public boolean populate(ExtractorInput input, boolean quiet)
    throws IOException, InterruptedException {
  scratch.reset();
  reset();
  boolean hasEnoughBytes = input.getLength() == C.LENGTH_UNSET
      || input.getLength() - input.getPeekPosition() >= EMPTY_PAGE_HEADER_SIZE;
  if (!hasEnoughBytes || !input.peekFully(scratch.data, 0, EMPTY_PAGE_HEADER_SIZE, true)) {
    if (quiet) {
      return false;
    } else {
      throw new EOFException();
    }
  }
  if (scratch.readUnsignedInt() != TYPE_OGGS) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("expected OggS capture pattern at begin of page");
    }
  }

  revision = scratch.readUnsignedByte();
  if (revision != 0x00) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("unsupported bit stream revision");
    }
  }
  type = scratch.readUnsignedByte();

  granulePosition = scratch.readLittleEndianLong();
  streamSerialNumber = scratch.readLittleEndianUnsignedInt();
  pageSequenceNumber = scratch.readLittleEndianUnsignedInt();
  pageChecksum = scratch.readLittleEndianUnsignedInt();
  pageSegmentCount = scratch.readUnsignedByte();
  headerSize = EMPTY_PAGE_HEADER_SIZE + pageSegmentCount;

  // calculate total size of header including laces
  scratch.reset();
  input.peekFully(scratch.data, 0, pageSegmentCount);
  for (int i = 0; i < pageSegmentCount; i++) {
    laces[i] = scratch.readUnsignedByte();
    bodySize += laces[i];
  }

  return true;
}
 
Example 15
Source File: Mp3Extractor.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
private boolean synchronize(ExtractorInput input, boolean sniffing)
    throws IOException, InterruptedException {
  int validFrameCount = 0;
  int candidateSynchronizedHeaderData = 0;
  int peekedId3Bytes = 0;
  int searchedBytes = 0;
  int searchLimitBytes = sniffing ? MAX_SNIFF_BYTES : MAX_SYNC_BYTES;
  input.resetPeekPosition();
  if (input.getPosition() == 0) {
    // We need to parse enough ID3 metadata to retrieve any gapless playback information even
    // if ID3 metadata parsing is disabled.
    boolean onlyDecodeGaplessInfoFrames = (flags & FLAG_DISABLE_ID3_METADATA) != 0;
    Id3Decoder.FramePredicate id3FramePredicate =
        onlyDecodeGaplessInfoFrames ? GaplessInfoHolder.GAPLESS_INFO_ID3_FRAME_PREDICATE : null;
    metadata = id3Peeker.peekId3Data(input, id3FramePredicate);
    if (metadata != null) {
      gaplessInfoHolder.setFromMetadata(metadata);
    }
    peekedId3Bytes = (int) input.getPeekPosition();
    if (!sniffing) {
      input.skipFully(peekedId3Bytes);
    }
  }
  while (true) {
    if (!input.peekFully(scratch.data, 0, 4, validFrameCount > 0)) {
      // We reached the end of the stream but found at least one valid frame.
      break;
    }
    scratch.setPosition(0);
    int headerData = scratch.readInt();
    int frameSize;
    if ((candidateSynchronizedHeaderData != 0
        && !headersMatch(headerData, candidateSynchronizedHeaderData))
        || (frameSize = MpegAudioHeader.getFrameSize(headerData)) == C.LENGTH_UNSET) {
      // The header doesn't match the candidate header or is invalid. Try the next byte offset.
      if (searchedBytes++ == searchLimitBytes) {
        if (!sniffing) {
          throw new ParserException("Searched too many bytes.");
        }
        return false;
      }
      validFrameCount = 0;
      candidateSynchronizedHeaderData = 0;
      if (sniffing) {
        input.resetPeekPosition();
        input.advancePeekPosition(peekedId3Bytes + searchedBytes);
      } else {
        input.skipFully(1);
      }
    } else {
      // The header matches the candidate header and/or is valid.
      validFrameCount++;
      if (validFrameCount == 1) {
        MpegAudioHeader.populateHeader(headerData, synchronizedHeader);
        candidateSynchronizedHeaderData = headerData;
      } else if (validFrameCount == 4) {
        break;
      }
      input.advancePeekPosition(frameSize - 4);
    }
  }
  // Prepare to read the synchronized frame.
  if (sniffing) {
    input.skipFully(peekedId3Bytes + searchedBytes);
  } else {
    input.resetPeekPosition();
  }
  synchronizedHeaderData = candidateSynchronizedHeaderData;
  return true;
}
 
Example 16
Source File: OggPageHeader.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Peeks an Ogg page header and updates this {@link OggPageHeader}.
 *
 * @param input the {@link ExtractorInput} to read from.
 * @param quiet if {@code true} no Exceptions are thrown but {@code false} is return if something
 *    goes wrong.
 * @return {@code true} if the read was successful. {@code false} if the end of the input was
 *    encountered having read no data.
 * @throws IOException thrown if reading data fails or the stream is invalid.
 * @throws InterruptedException thrown if thread is interrupted when reading/peeking.
 */
public boolean populate(ExtractorInput input, boolean quiet)
    throws IOException, InterruptedException {
  scratch.reset();
  reset();
  boolean hasEnoughBytes = input.getLength() == C.LENGTH_UNSET
      || input.getLength() - input.getPeekPosition() >= EMPTY_PAGE_HEADER_SIZE;
  if (!hasEnoughBytes || !input.peekFully(scratch.data, 0, EMPTY_PAGE_HEADER_SIZE, true)) {
    if (quiet) {
      return false;
    } else {
      throw new EOFException();
    }
  }
  if (scratch.readUnsignedInt() != TYPE_OGGS) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("expected OggS capture pattern at begin of page");
    }
  }

  revision = scratch.readUnsignedByte();
  if (revision != 0x00) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("unsupported bit stream revision");
    }
  }
  type = scratch.readUnsignedByte();

  granulePosition = scratch.readLittleEndianLong();
  streamSerialNumber = scratch.readLittleEndianUnsignedInt();
  pageSequenceNumber = scratch.readLittleEndianUnsignedInt();
  pageChecksum = scratch.readLittleEndianUnsignedInt();
  pageSegmentCount = scratch.readUnsignedByte();
  headerSize = EMPTY_PAGE_HEADER_SIZE + pageSegmentCount;

  // calculate total size of header including laces
  scratch.reset();
  input.peekFully(scratch.data, 0, pageSegmentCount);
  for (int i = 0; i < pageSegmentCount; i++) {
    laces[i] = scratch.readUnsignedByte();
    bodySize += laces[i];
  }

  return true;
}
 
Example 17
Source File: Mp3Extractor.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
private boolean synchronize(ExtractorInput input, boolean sniffing)
    throws IOException, InterruptedException {
  int validFrameCount = 0;
  int candidateSynchronizedHeaderData = 0;
  int peekedId3Bytes = 0;
  int searchedBytes = 0;
  int searchLimitBytes = sniffing ? MAX_SNIFF_BYTES : MAX_SYNC_BYTES;
  input.resetPeekPosition();
  if (input.getPosition() == 0) {
    // We need to parse enough ID3 metadata to retrieve any gapless/seeking playback information
    // even if ID3 metadata parsing is disabled.
    boolean parseAllId3Frames = (flags & FLAG_DISABLE_ID3_METADATA) == 0;
    FramePredicate id3FramePredicate =
        parseAllId3Frames ? null : REQUIRED_ID3_FRAME_PREDICATE;
    metadata = id3Peeker.peekId3Data(input, id3FramePredicate);
    if (metadata != null) {
      gaplessInfoHolder.setFromMetadata(metadata);
    }
    peekedId3Bytes = (int) input.getPeekPosition();
    if (!sniffing) {
      input.skipFully(peekedId3Bytes);
    }
  }
  while (true) {
    if (peekEndOfStreamOrHeader(input)) {
      if (validFrameCount > 0) {
        // We reached the end of the stream but found at least one valid frame.
        break;
      }
      throw new EOFException();
    }
    scratch.setPosition(0);
    int headerData = scratch.readInt();
    int frameSize;
    if ((candidateSynchronizedHeaderData != 0
        && !headersMatch(headerData, candidateSynchronizedHeaderData))
        || (frameSize = MpegAudioHeader.getFrameSize(headerData)) == C.LENGTH_UNSET) {
      // The header doesn't match the candidate header or is invalid. Try the next byte offset.
      if (searchedBytes++ == searchLimitBytes) {
        if (!sniffing) {
          throw new ParserException("Searched too many bytes.");
        }
        return false;
      }
      validFrameCount = 0;
      candidateSynchronizedHeaderData = 0;
      if (sniffing) {
        input.resetPeekPosition();
        input.advancePeekPosition(peekedId3Bytes + searchedBytes);
      } else {
        input.skipFully(1);
      }
    } else {
      // The header matches the candidate header and/or is valid.
      validFrameCount++;
      if (validFrameCount == 1) {
        MpegAudioHeader.populateHeader(headerData, synchronizedHeader);
        candidateSynchronizedHeaderData = headerData;
      } else if (validFrameCount == 4) {
        break;
      }
      input.advancePeekPosition(frameSize - 4);
    }
  }
  // Prepare to read the synchronized frame.
  if (sniffing) {
    input.skipFully(peekedId3Bytes + searchedBytes);
  } else {
    input.resetPeekPosition();
  }
  synchronizedHeaderData = candidateSynchronizedHeaderData;
  return true;
}
 
Example 18
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;
}