diff --git a/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java b/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java index e3ef6f9724..b5b364a327 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java @@ -301,6 +301,14 @@ public class DefaultLoadControl implements LoadControl { public boolean shouldContinueLoading(long bufferedDurationUs, float playbackSpeed) { boolean targetBufferSizeReached = allocator.getTotalBytesAllocated() >= targetBufferSize; boolean wasBuffering = isBuffering; + long minBufferUs = this.minBufferUs; + if (playbackSpeed > 1) { + // The playback speed is faster than real time, so scale up the minimum required media + // duration to keep enough media buffered for a playout duration of minBufferUs. + long mediaDurationMinBufferUs = + Util.getMediaDurationForPlayoutDuration(minBufferUs, playbackSpeed); + minBufferUs = Math.min(mediaDurationMinBufferUs, maxBufferUs); + } if (bufferedDurationUs < minBufferUs) { isBuffering = prioritizeTimeOverSizeThresholds || !targetBufferSizeReached; } else if (bufferedDurationUs > maxBufferUs || targetBufferSizeReached) { diff --git a/library/core/src/test/java/com/google/android/exoplayer2/DefaultLoadControlTest.java b/library/core/src/test/java/com/google/android/exoplayer2/DefaultLoadControlTest.java index 92993b79ca..b066cc263a 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/DefaultLoadControlTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/DefaultLoadControlTest.java @@ -85,6 +85,25 @@ public class DefaultLoadControlTest { assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US + 1, SPEED)).isFalse(); } + @Test + public void testShouldContinueLoadingWithMinBufferReached_inFastPlayback() { + createDefaultLoadControl(); + + // At normal playback speed, we stop buffering when the buffer reaches the minimum. + assertThat(loadControl.shouldContinueLoading(MIN_BUFFER_US, SPEED)).isFalse(); + + // At double playback speed, we continue loading. + assertThat(loadControl.shouldContinueLoading(MIN_BUFFER_US, /* playbackSpeed= */ 2f)).isTrue(); + } + + @Test + public void testShouldNotContinueLoadingWithMaxBufferReached_inFastPlayback() { + createDefaultLoadControl(); + + assertThat(loadControl.shouldContinueLoading(MAX_BUFFER_US + 1, /* playbackSpeed= */ 100f)) + .isFalse(); + } + @Test public void testStartsPlayback_whenMinBufferSizeReached() { createDefaultLoadControl();