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

The following examples show how to use com.google.android.exoplayer2.extractor.ExtractorInput#skipFully() . 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: StreamReader.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
/**
 * @see Extractor#read(ExtractorInput, PositionHolder)
 */
final int read(ExtractorInput input, PositionHolder seekPosition)
    throws IOException, InterruptedException {
  switch (state) {
    case STATE_READ_HEADERS:
      return readHeaders(input);
    case STATE_SKIP_HEADERS:
      input.skipFully((int) payloadStartPosition);
      state = STATE_READ_PAYLOAD;
      return Extractor.RESULT_CONTINUE;
    case STATE_READ_PAYLOAD:
      return readPayload(input, seekPosition);
    default:
      // Never happens.
      throw new IllegalStateException();
  }
}
 
Example 2
Source File: FlvExtractor.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Reads the body of a tag from the provided {@link ExtractorInput}.
 *
 * @param input The {@link ExtractorInput} from which to read.
 * @return True if the data was consumed by a reader. False if it was skipped.
 * @throws IOException If an error occurred reading or parsing data from the source.
 * @throws InterruptedException If the thread was interrupted.
 */
private boolean readTagData(ExtractorInput input) throws IOException, InterruptedException {
  boolean wasConsumed = true;
  if (tagType == TAG_TYPE_AUDIO && audioReader != null) {
    ensureReadyForMediaOutput();
    audioReader.consume(prepareTagData(input), mediaTagTimestampOffsetUs + tagTimestampUs);
  } else if (tagType == TAG_TYPE_VIDEO && videoReader != null) {
    ensureReadyForMediaOutput();
    videoReader.consume(prepareTagData(input), mediaTagTimestampOffsetUs + tagTimestampUs);
  } else if (tagType == TAG_TYPE_SCRIPT_DATA && !outputSeekMap) {
    metadataReader.consume(prepareTagData(input), tagTimestampUs);
    long durationUs = metadataReader.getDurationUs();
    if (durationUs != C.TIME_UNSET) {
      extractorOutput.seekMap(new SeekMap.Unseekable(durationUs));
      outputSeekMap = true;
    }
  } else {
    input.skipFully(tagDataSize);
    wasConsumed = false;
  }
  bytesToNextTagHeader = 4; // There's a 4 byte previous tag size before the next header.
  state = STATE_SKIPPING_TO_TAG_HEADER;
  return wasConsumed;
}
 
Example 3
Source File: TsExtractor.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
@Override
public boolean sniff(ExtractorInput input) throws IOException, InterruptedException {
  byte[] buffer = tsPacketBuffer.data;
  input.peekFully(buffer, 0, TS_PACKET_SIZE * SNIFF_TS_PACKET_COUNT);
  for (int startPosCandidate = 0; startPosCandidate < TS_PACKET_SIZE; startPosCandidate++) {
    // Try to identify at least SNIFF_TS_PACKET_COUNT packets starting with TS_SYNC_BYTE.
    boolean isSyncBytePatternCorrect = true;
    for (int i = 0; i < SNIFF_TS_PACKET_COUNT; i++) {
      if (buffer[startPosCandidate + i * TS_PACKET_SIZE] != TS_SYNC_BYTE) {
        isSyncBytePatternCorrect = false;
        break;
      }
    }
    if (isSyncBytePatternCorrect) {
      input.skipFully(startPosCandidate);
      return true;
    }
  }
  return false;
}
 
Example 4
Source File: FragmentedMp4Extractor.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
private void readEncryptionData(ExtractorInput input) throws IOException, InterruptedException {
  TrackBundle nextTrackBundle = null;
  long nextDataOffset = Long.MAX_VALUE;
  int trackBundlesSize = trackBundles.size();
  for (int i = 0; i < trackBundlesSize; i++) {
    TrackFragment trackFragment = trackBundles.valueAt(i).fragment;
    if (trackFragment.sampleEncryptionDataNeedsFill
        && trackFragment.auxiliaryDataPosition < nextDataOffset) {
      nextDataOffset = trackFragment.auxiliaryDataPosition;
      nextTrackBundle = trackBundles.valueAt(i);
    }
  }
  if (nextTrackBundle == null) {
    parserState = STATE_READING_SAMPLE_START;
    return;
  }
  int bytesToSkip = (int) (nextDataOffset - input.getPosition());
  if (bytesToSkip < 0) {
    throw new ParserException("Offset to encryption data was negative.");
  }
  input.skipFully(bytesToSkip);
  nextTrackBundle.fragment.fillEncryptionData(input);
}
 
Example 5
Source File: HlsMediaChunk.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Attempts to feed the given {@code dataSpec} to {@code this.extractor}. Whenever the operation
 * concludes (because of a thrown exception or because the operation finishes), the number of fed
 * bytes is written to {@code nextLoadPosition}.
 */
@RequiresNonNull("output")
private void feedDataToExtractor(
    DataSource dataSource, DataSpec dataSpec, boolean dataIsEncrypted)
    throws IOException, InterruptedException {
  // If we previously fed part of this chunk to the extractor, we need to skip it this time. For
  // encrypted content we need to skip the data by reading it through the source, so as to ensure
  // correct decryption of the remainder of the chunk. For clear content, we can request the
  // remainder of the chunk directly.
  DataSpec loadDataSpec;
  boolean skipLoadedBytes;
  if (dataIsEncrypted) {
    loadDataSpec = dataSpec;
    skipLoadedBytes = nextLoadPosition != 0;
  } else {
    loadDataSpec = dataSpec.subrange(nextLoadPosition);
    skipLoadedBytes = false;
  }
  try {
    ExtractorInput input = prepareExtraction(dataSource, loadDataSpec);
    if (skipLoadedBytes) {
      input.skipFully(nextLoadPosition);
    }
    try {
      int result = Extractor.RESULT_CONTINUE;
      while (result == Extractor.RESULT_CONTINUE && !loadCanceled) {
        result = extractor.read(input, DUMMY_POSITION_HOLDER);
      }
    } finally {
      nextLoadPosition = (int) (input.getPosition() - dataSpec.absoluteStreamPosition);
    }
  } finally {
    Util.closeQuietly(dataSource);
  }
}
 
Example 6
Source File: AmrExtractor.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Peeks the AMR header from the beginning of the input, and consumes it if it exists.
 *
 * @param input The {@link ExtractorInput} from which data should be peeked/read.
 * @return Whether the AMR header has been read.
 */
private boolean readAmrHeader(ExtractorInput input) throws IOException, InterruptedException {
  if (peekAmrSignature(input, amrSignatureNb)) {
    isWideBand = false;
    input.skipFully(amrSignatureNb.length);
    return true;
  } else if (peekAmrSignature(input, amrSignatureWb)) {
    isWideBand = true;
    input.skipFully(amrSignatureWb.length);
    return true;
  }
  return false;
}
 
Example 7
Source File: DefaultOggSeeker.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Skips to the next page. Searches for the next page header.
 *
 * @param input The {@code ExtractorInput} to skip to the next page.
 * @param limit The limit up to which the search should take place.
 * @return Whether the next page was found.
 * @throws IOException If peeking/reading from the input fails.
 * @throws InterruptedException If interrupted while peeking/reading from the input.
 */
private boolean skipToNextPage(ExtractorInput input, long limit)
    throws IOException, InterruptedException {
  limit = Math.min(limit + 3, payloadEndPosition);
  byte[] buffer = new byte[2048];
  int peekLength = buffer.length;
  while (true) {
    if (input.getPosition() + peekLength > limit) {
      // Make sure to not peek beyond the end of the input.
      peekLength = (int) (limit - input.getPosition());
      if (peekLength < 4) {
        // Not found until end.
        return false;
      }
    }
    input.peekFully(buffer, 0, peekLength, false);
    for (int i = 0; i < peekLength - 3; i++) {
      if (buffer[i] == 'O'
          && buffer[i + 1] == 'g'
          && buffer[i + 2] == 'g'
          && buffer[i + 3] == 'S') {
        // Match! Skip to the start of the pattern.
        input.skipFully(i);
        return true;
      }
    }
    // Overlap by not skipping the entire peekLength.
    input.skipFully(peekLength - 3);
  }
}
 
Example 8
Source File: FlvExtractor.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Reads the body of a tag from the provided {@link ExtractorInput}.
 *
 * @param input The {@link ExtractorInput} from which to read.
 * @return True if the data was consumed by a reader. False if it was skipped.
 * @throws IOException If an error occurred reading or parsing data from the source.
 * @throws InterruptedException If the thread was interrupted.
 */
private boolean readTagData(ExtractorInput input) throws IOException, InterruptedException {
  boolean wasConsumed = true;
  boolean wasSampleOutput = false;
  long timestampUs = getCurrentTimestampUs();
  if (tagType == TAG_TYPE_AUDIO && audioReader != null) {
    ensureReadyForMediaOutput();
    wasSampleOutput = audioReader.consume(prepareTagData(input), timestampUs);
  } else if (tagType == TAG_TYPE_VIDEO && videoReader != null) {
    ensureReadyForMediaOutput();
    wasSampleOutput = videoReader.consume(prepareTagData(input), timestampUs);
  } else if (tagType == TAG_TYPE_SCRIPT_DATA && !outputSeekMap) {
    wasSampleOutput = metadataReader.consume(prepareTagData(input), timestampUs);
    long durationUs = metadataReader.getDurationUs();
    if (durationUs != C.TIME_UNSET) {
      extractorOutput.seekMap(new SeekMap.Unseekable(durationUs));
      outputSeekMap = true;
    }
  } else {
    input.skipFully(tagDataSize);
    wasConsumed = false;
  }
  if (!outputFirstSample && wasSampleOutput) {
    outputFirstSample = true;
    mediaTagTimestampOffsetUs =
        metadataReader.getDurationUs() == C.TIME_UNSET ? -tagTimestampUs : 0;
  }
  bytesToNextTagHeader = 4; // There's a 4 byte previous tag size before the next header.
  state = STATE_SKIPPING_TO_TAG_HEADER;
  return wasConsumed;
}
 
Example 9
Source File: AmrExtractor.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Peeks the AMR header from the beginning of the input, and consumes it if it exists.
 *
 * @param input The {@link ExtractorInput} from which data should be peeked/read.
 * @return Whether the AMR header has been read.
 */
private boolean readAmrHeader(ExtractorInput input) throws IOException, InterruptedException {
  if (peekAmrSignature(input, amrSignatureNb)) {
    isWideBand = false;
    input.skipFully(amrSignatureNb.length);
    return true;
  } else if (peekAmrSignature(input, amrSignatureWb)) {
    isWideBand = true;
    input.skipFully(amrSignatureWb.length);
    return true;
  }
  return false;
}
 
Example 10
Source File: FragmentedMp4Extractor.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
private void readAtomPayload(ExtractorInput input) throws IOException, InterruptedException {
  int atomPayloadSize = (int) atomSize - atomHeaderBytesRead;
  if (atomData != null) {
    input.readFully(atomData.data, Atom.HEADER_SIZE, atomPayloadSize);
    onLeafAtomRead(new LeafAtom(atomType, atomData), input.getPosition());
  } else {
    input.skipFully(atomPayloadSize);
  }
  processAtomEnded(input.getPosition());
}
 
Example 11
Source File: FragmentedMp4Extractor.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
private void readAtomPayload(ExtractorInput input) throws IOException, InterruptedException {
  int atomPayloadSize = (int) atomSize - atomHeaderBytesRead;
  if (atomData != null) {
    input.readFully(atomData.data, Atom.HEADER_SIZE, atomPayloadSize);
    onLeafAtomRead(new LeafAtom(atomType, atomData), input.getPosition());
  } else {
    input.skipFully(atomPayloadSize);
  }
  processAtomEnded(input.getPosition());
}
 
Example 12
Source File: Mp3Extractor.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private int readSample(ExtractorInput extractorInput) throws IOException, InterruptedException {
  if (sampleBytesRemaining == 0) {
    extractorInput.resetPeekPosition();
    if (!extractorInput.peekFully(scratch.data, 0, 4, true)) {
      return RESULT_END_OF_INPUT;
    }
    scratch.setPosition(0);
    int sampleHeaderData = scratch.readInt();
    if (!headersMatch(sampleHeaderData, synchronizedHeaderData)
        || MpegAudioHeader.getFrameSize(sampleHeaderData) == C.LENGTH_UNSET) {
      // We have lost synchronization, so attempt to resynchronize starting at the next byte.
      extractorInput.skipFully(1);
      synchronizedHeaderData = 0;
      return RESULT_CONTINUE;
    }
    MpegAudioHeader.populateHeader(sampleHeaderData, synchronizedHeader);
    if (basisTimeUs == C.TIME_UNSET) {
      basisTimeUs = seeker.getTimeUs(extractorInput.getPosition());
      if (forcedFirstSampleTimestampUs != C.TIME_UNSET) {
        long embeddedFirstSampleTimestampUs = seeker.getTimeUs(0);
        basisTimeUs += forcedFirstSampleTimestampUs - embeddedFirstSampleTimestampUs;
      }
    }
    sampleBytesRemaining = synchronizedHeader.frameSize;
  }
  int bytesAppended = trackOutput.sampleData(extractorInput, sampleBytesRemaining, true);
  if (bytesAppended == C.RESULT_END_OF_INPUT) {
    return RESULT_END_OF_INPUT;
  }
  sampleBytesRemaining -= bytesAppended;
  if (sampleBytesRemaining > 0) {
    return RESULT_CONTINUE;
  }
  long timeUs = basisTimeUs + (samplesRead * C.MICROS_PER_SECOND / synchronizedHeader.sampleRate);
  trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, synchronizedHeader.frameSize, 0,
      null);
  samplesRead += synchronizedHeader.samplesPerFrame;
  sampleBytesRemaining = 0;
  return RESULT_CONTINUE;
}
 
Example 13
Source File: DefaultOggSeeker.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Skips to the last Ogg page in the stream and reads the header's granule field which is the
 * total number of samples per channel.
 *
 * @param input The {@link ExtractorInput} to read from.
 * @return The total number of samples of this input.
 * @throws IOException If reading from the input fails.
 * @throws InterruptedException If the thread is interrupted.
 */
@VisibleForTesting
long readGranuleOfLastPage(ExtractorInput input) throws IOException, InterruptedException {
  skipToNextPage(input);
  pageHeader.reset();
  while ((pageHeader.type & 0x04) != 0x04 && input.getPosition() < payloadEndPosition) {
    pageHeader.populate(input, /* quiet= */ false);
    input.skipFully(pageHeader.headerSize + pageHeader.bodySize);
  }
  return pageHeader.granulePosition;
}
 
Example 14
Source File: MatroskaExtractor.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
protected void handleBlockAdditionalData(
    Track track, int blockAdditionalId, ExtractorInput input, int contentSize)
    throws IOException, InterruptedException {
  if (blockAdditionalId == BLOCK_ADDITIONAL_ID_VP9_ITU_T_35
      && CODEC_ID_VP9.equals(track.codecId)) {
    blockAdditionalData.reset(contentSize);
    input.readFully(blockAdditionalData.data, 0, contentSize);
  } else {
    // Unhandled block additional data.
    input.skipFully(contentSize);
  }
}
 
Example 15
Source File: FragmentedMp4Extractor.java    From K-Sonic with MIT License 5 votes vote down vote up
private void readAtomPayload(ExtractorInput input) throws IOException, InterruptedException {
  int atomPayloadSize = (int) atomSize - atomHeaderBytesRead;
  if (atomData != null) {
    input.readFully(atomData.data, Atom.HEADER_SIZE, atomPayloadSize);
    onLeafAtomRead(new LeafAtom(atomType, atomData), input.getPosition());
  } else {
    input.skipFully(atomPayloadSize);
  }
  processAtomEnded(input.getPosition());
}
 
Example 16
Source File: WavExtractor.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
@Override
public int read(ExtractorInput input, PositionHolder seekPosition)
    throws IOException, InterruptedException {
  if (wavHeader == null) {
    wavHeader = WavHeaderReader.peek(input);
    if (wavHeader == null) {
      // Should only happen if the media wasn't sniffed.
      throw new ParserException("Unsupported or unrecognized wav header.");
    }
    Format format = Format.createAudioSampleFormat(null, MimeTypes.AUDIO_RAW, null,
        wavHeader.getBitrate(), MAX_INPUT_SIZE, wavHeader.getNumChannels(),
        wavHeader.getSampleRateHz(), wavHeader.getEncoding(), null, null, 0, null);
    trackOutput.format(format);
    bytesPerFrame = wavHeader.getBytesPerFrame();
  }

  if (!wavHeader.hasDataBounds()) {
    WavHeaderReader.skipToData(input, wavHeader);
    extractorOutput.seekMap(wavHeader);
  } else if (input.getPosition() == 0) {
    input.skipFully(wavHeader.getDataStartPosition());
  }

  long dataEndPosition = wavHeader.getDataEndPosition();
  Assertions.checkState(dataEndPosition != C.POSITION_UNSET);

  long bytesLeft = dataEndPosition - input.getPosition();
  if (bytesLeft <= 0) {
    return Extractor.RESULT_END_OF_INPUT;
  }

  int maxBytesToRead = (int) Math.min(MAX_INPUT_SIZE - pendingBytes, bytesLeft);
  int bytesAppended = trackOutput.sampleData(input, maxBytesToRead, true);
  if (bytesAppended != RESULT_END_OF_INPUT) {
    pendingBytes += bytesAppended;
  }

  // Samples must consist of a whole number of frames.
  int pendingFrames = pendingBytes / bytesPerFrame;
  if (pendingFrames > 0) {
    long timeUs = wavHeader.getTimeUs(input.getPosition() - pendingBytes);
    int size = pendingFrames * bytesPerFrame;
    pendingBytes -= size;
    trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, size, pendingBytes, null);
  }

  return bytesAppended == RESULT_END_OF_INPUT ? RESULT_END_OF_INPUT : RESULT_CONTINUE;
}
 
Example 17
Source File: DefaultOggSeeker.java    From K-Sonic with MIT License 4 votes vote down vote up
/**
 * Returns a position converging to the {@code targetGranule} to which the {@link ExtractorInput}
 * has to seek and then be passed for another call until a negative number is returned. If a
 * negative number is returned the input is at a position which is before the target page and at
 * which it is sensible to just skip pages to the target granule and pre-roll instead of doing
 * another seek request.
 *
 * @param targetGranule the target granule position to seek to.
 * @param input the {@link ExtractorInput} to read from.
 * @return the position to seek the {@link ExtractorInput} to for a next call or
 *     -(currentGranule + 2) if it's close enough to skip to the target page.
 * @throws IOException thrown if reading from the input fails.
 * @throws InterruptedException thrown if interrupted while reading from the input.
 */
//@VisibleForTesting
public long getNextSeekPosition(long targetGranule, ExtractorInput input)
    throws IOException, InterruptedException {
  if (start == end) {
    return -(startGranule + 2);
  }

  long initialPosition = input.getPosition();
  if (!skipToNextPage(input, end)) {
    if (start == initialPosition) {
      throw new IOException("No ogg page can be found.");
    }
    return start;
  }

  pageHeader.populate(input, false);
  input.resetPeekPosition();

  long granuleDistance = targetGranule - pageHeader.granulePosition;
  int pageSize = pageHeader.headerSize + pageHeader.bodySize;
  if (granuleDistance < 0 || granuleDistance > MATCH_RANGE) {
    if (granuleDistance < 0) {
      end = initialPosition;
      endGranule = pageHeader.granulePosition;
    } else {
      start = input.getPosition() + pageSize;
      startGranule = pageHeader.granulePosition;
      if (end - start + pageSize < MATCH_BYTE_RANGE) {
        input.skipFully(pageSize);
        return -(startGranule + 2);
      }
    }

    if (end - start < MATCH_BYTE_RANGE) {
      end = start;
      return start;
    }

    long offset = pageSize * (granuleDistance <= 0 ? 2 : 1);
    long nextPosition = input.getPosition() - offset
        + (granuleDistance * (end - start) / (endGranule - startGranule));

    nextPosition = Math.max(nextPosition, start);
    nextPosition = Math.min(nextPosition, end - 1);
    return nextPosition;
  }

  // position accepted (before target granule and within MATCH_RANGE)
  input.skipFully(pageSize);
  return -(pageHeader.granulePosition + 2);
}
 
Example 18
Source File: FlvExtractor.java    From Telegram-FOSS with GNU General Public License v2.0 2 votes vote down vote up
/**
 * Skips over data to reach the next tag header.
 *
 * @param input The {@link ExtractorInput} from which to read.
 * @throws IOException If an error occurred skipping data from the source.
 * @throws InterruptedException If the thread was interrupted.
 */
private void skipToTagHeader(ExtractorInput input) throws IOException, InterruptedException {
  input.skipFully(bytesToNextTagHeader);
  bytesToNextTagHeader = 0;
  state = STATE_READING_TAG_HEADER;
}
 
Example 19
Source File: FlvExtractor.java    From LiveVideoBroadcaster with Apache License 2.0 2 votes vote down vote up
/**
 * Skips over data to reach the next tag header.
 *
 * @param input The {@link ExtractorInput} from which to read.
 * @throws IOException If an error occurred skipping data from the source.
 * @throws InterruptedException If the thread was interrupted.
 */
private void skipToTagHeader(ExtractorInput input) throws IOException, InterruptedException {
  input.skipFully(bytesToNextTagHeader);
  bytesToNextTagHeader = 0;
  parserState = STATE_READING_TAG_HEADER;
}
 
Example 20
Source File: FlvExtractor.java    From TelePlus-Android with GNU General Public License v2.0 2 votes vote down vote up
/**
 * Skips over data to reach the next tag header.
 *
 * @param input The {@link ExtractorInput} from which to read.
 * @throws IOException If an error occurred skipping data from the source.
 * @throws InterruptedException If the thread was interrupted.
 */
private void skipToTagHeader(ExtractorInput input) throws IOException, InterruptedException {
  input.skipFully(bytesToNextTagHeader);
  bytesToNextTagHeader = 0;
  state = STATE_READING_TAG_HEADER;
}