diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java index bcbeed437f..e21e15fa58 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java @@ -732,6 +732,7 @@ import java.io.IOException; setPlayingPeriodHolder(newPlayingPeriodHolder); if (playingPeriodHolder.hasEnabledTracks) { periodPositionUs = playingPeriodHolder.mediaPeriod.seekToUs(periodPositionUs); + playingPeriodHolder.mediaPeriod.discardBuffer(periodPositionUs); } resetRendererPosition(periodPositionUs); maybeContinueLoading(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java index c418c427f7..d112d5eaf1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaPeriod.java @@ -569,7 +569,6 @@ import java.util.Arrays; if (!seekInsideQueue && (trackIsAudioVideoFlags[i] || !haveAudioVideoTracks)) { return false; } - sampleQueue.discardToRead(); } return true; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java index 8a9be92d75..ca83f67c90 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java @@ -110,21 +110,17 @@ public class ChunkSampleStream implements SampleStream, S lastSeekPositionUs = positionUs; } - // TODO: Generalize this method to also discard from the primary sample queue and stop discarding - // from this queue in readData and skipData. This will cause samples to be kept in the queue until - // they've been rendered, rather than being discarded as soon as they're read by the renderer. - // This will make in-buffer seeks more likely when seeking slightly forward from the current - // position. This change will need handling with care, in particular when considering removal of - // chunks from the front of the mediaChunks list. /** - * Discards buffered media for embedded tracks, up to the specified position. + * Discards buffered media up to the specified position. * * @param positionUs The position to discard up to, in microseconds. */ - public void discardEmbeddedTracksTo(long positionUs) { + public void discardBuffer(long positionUs) { + primarySampleQueue.discardTo(positionUs, false, true); for (int i = 0; i < embeddedSampleQueues.length; i++) { embeddedSampleQueues[i].discardTo(positionUs, true, embeddedTracksSelected[i]); } + discardDownstreamMediaChunks(primarySampleQueue.getFirstIndex()); } /** @@ -189,16 +185,15 @@ public class ChunkSampleStream implements SampleStream, S */ public void seekToUs(long positionUs) { lastSeekPositionUs = positionUs; + primarySampleQueue.rewind(); // If we're not pending a reset, see if we can seek within the primary sample queue. boolean seekInsideBuffer = !isPendingReset() && (primarySampleQueue.advanceTo(positionUs, true, positionUs < getNextLoadPositionUs()) != SampleQueue.ADVANCE_FAILED); if (seekInsideBuffer) { // We succeeded. Discard samples and corresponding chunks prior to the seek position. - discardDownstreamMediaChunks(primarySampleQueue.getReadIndex()); - primarySampleQueue.discardToRead(); for (SampleQueue embeddedSampleQueue : embeddedSampleQueues) { embeddedSampleQueue.rewind(); - embeddedSampleQueue.discardTo(positionUs, true, false); + embeddedSampleQueue.advanceTo(positionUs, true, false); } } else { // We failed, and need to restart. @@ -261,13 +256,8 @@ public class ChunkSampleStream implements SampleStream, S if (isPendingReset()) { return C.RESULT_NOTHING_READ; } - discardDownstreamMediaChunks(primarySampleQueue.getReadIndex()); - int result = primarySampleQueue.read(formatHolder, buffer, formatRequired, loadingFinished, + return primarySampleQueue.read(formatHolder, buffer, formatRequired, loadingFinished, lastSeekPositionUs); - if (result == C.RESULT_BUFFER_READ) { - primarySampleQueue.discardToRead(); - } - return result; } @Override @@ -282,7 +272,6 @@ public class ChunkSampleStream implements SampleStream, S skipCount = 0; } } - primarySampleQueue.discardToRead(); return skipCount; } diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java index b5ce45b2f5..3680dac821 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java @@ -261,7 +261,7 @@ import java.util.Map; @Override public void discardBuffer(long positionUs) { for (ChunkSampleStream sampleStream : sampleStreams) { - sampleStream.discardEmbeddedTracksTo(positionUs); + sampleStream.discardBuffer(positionUs); } } diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index 0d2f758599..07b60f05b0 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -792,7 +792,6 @@ import java.util.LinkedList; if (!seekInsideQueue && (sampleQueueIsAudioVideoFlags[i] || !haveAudioVideoSampleQueues)) { return false; } - sampleQueue.discardToRead(); } return true; }