diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ffdfc1c1e7..2bae8256fe 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -2,6 +2,10 @@ ### dev-v2 (not yet released) +* Core library: + * Fix bug where streams with highly uneven durations may get stuck in a + buffering state + ([#7943](https://github.com/google/ExoPlayer/issues/7943)). * Track selection: * Add option to specify multiple preferred audio or text languages. * Data sources: 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 9739680e79..e33b93ac0e 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 @@ -897,10 +897,7 @@ import java.util.concurrent.atomic.AtomicBoolean; // tracks in the current period have uneven durations and are still being read by another // renderer. See: https://github.com/google/ExoPlayer/issues/1874. boolean isReadingAhead = playingPeriodHolder.sampleStreams[i] != renderer.getStream(); - boolean isWaitingForNextStream = - !isReadingAhead - && playingPeriodHolder.getNext() != null - && renderer.hasReadStreamToEnd(); + boolean isWaitingForNextStream = !isReadingAhead && renderer.hasReadStreamToEnd(); boolean allowsPlayback = isReadingAhead || isWaitingForNextStream || renderer.isReady() || renderer.isEnded(); renderersAllowPlayback = renderersAllowPlayback && allowsPlayback; diff --git a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java index 444640256f..7934298df0 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java @@ -7334,6 +7334,8 @@ public final class ExoPlayerTest { new DefaultLoadControl.Builder() .setTargetBufferBytes(10 * C.DEFAULT_BUFFER_SEGMENT_SIZE) .build(); + // Return no end of stream signal to prevent playback from ending. + FakeMediaPeriod.TrackDataFactory trackDataWithoutEos = (format, periodId) -> ImmutableList.of(); MediaSource continuouslyAllocatingMediaSource = new FakeMediaSource( new FakeTimeline(/* windowCount= */ 1), ExoPlayerTestRunner.VIDEO_FORMAT) { @@ -7348,8 +7350,11 @@ public final class ExoPlayerTest { @Nullable TransferListener transferListener) { return new FakeMediaPeriod( trackGroupArray, - TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US, - mediaSourceEventDispatcher) { + trackDataWithoutEos, + mediaSourceEventDispatcher, + drmSessionManager, + drmEventDispatcher, + /* deferOnPrepared= */ false) { private final List allocations = new ArrayList<>(); @@ -7382,14 +7387,8 @@ public final class ExoPlayerTest { }; } }; - ActionSchedule actionSchedule = - new ActionSchedule.Builder(TAG) - // Prevent player from ever assuming it finished playing. - .setRepeatMode(Player.REPEAT_MODE_ALL) - .build(); ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder(context) - .setActionSchedule(actionSchedule) .setMediaSources(continuouslyAllocatingMediaSource) .setLoadControl(loadControl) .build();