/** * Whether samples are available for reading from {@link #getSample(int, SampleHolder)} for the * specified track. * <p> * This method must only be called after the extractor has been prepared. * * @return True if samples are available for reading from {@link #getSample(int, SampleHolder)} * for the specified track. False otherwise. */ public boolean hasSamples(int track) { Assertions.checkState(isPrepared()); return !sampleQueues.valueAt(track).isEmpty(); }
@Override public boolean continueBuffering(int track, long positionUs) { Assertions.checkState(state == STATE_ENABLED); downstreamPositionUs = positionUs; chunkSource.continueBuffering(positionUs); updateLoadControl(); return loadingFinished || !sampleQueue.isEmpty(); }
@Override public void seekToUs(long positionUs) { Assertions.checkState(state == STATE_ENABLED); long currentPositionUs = isPendingReset() ? pendingResetPositionUs : downstreamPositionUs; downstreamPositionUs = positionUs; lastSeekPositionUs = positionUs; if (currentPositionUs == positionUs) { return; } // If we're not pending a reset, see if we can seek within the sample queue. boolean seekInsideBuffer = !isPendingReset() && sampleQueue.skipToKeyframeBefore(positionUs); if (seekInsideBuffer) { // We succeeded. All we need to do is discard any chunks that we've moved past. boolean haveSamples = !sampleQueue.isEmpty(); while (haveSamples && mediaChunks.size() > 1 && mediaChunks.get(1).getFirstSampleIndex() <= sampleQueue.getReadIndex()) { mediaChunks.removeFirst(); } } else { // We failed, and need to restart. restartFrom(positionUs); } // Either way, we need to send a discontinuity to the downstream components. pendingDiscontinuity = true; }
boolean haveSamples = !sampleQueue.isEmpty(); BaseMediaChunk currentChunk = mediaChunks.getFirst(); while (haveSamples && mediaChunks.size() > 1