From 138a8d65ca700e1d9634efd4c74a9b47169ca8f3 Mon Sep 17 00:00:00 2001 From: tonihei Date: Thu, 26 Sep 2024 10:30:42 -0700 Subject: [PATCH] Get updated buffered position when calling shouldStartPlayback The buffered position was last updated before the beginning of the renderer loop in doSomeWork. As the loading happens on a background thread, it may have progressed further already depending on how long it took to run the renderer loop. It's slightly more correct to pass in an updated value to shouldStartPlayback so that playback can start quicker if the buffering is particularly fast. PiperOrigin-RevId: 679203465 --- .../exoplayer/ExoPlayerImplInternal.java | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java index 3db0d8439b..183b718932 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java @@ -1076,7 +1076,7 @@ import java.util.concurrent.atomic.AtomicBoolean; && playbackInfo.playbackParameters.speed == 1f) { float adjustedSpeed = livePlaybackSpeedControl.getAdjustedPlaybackSpeed( - getCurrentLiveOffsetUs(), getTotalBufferedDurationUs()); + getCurrentLiveOffsetUs(), playbackInfo.totalBufferedDurationUs); if (mediaClock.getPlaybackParameters().speed != adjustedSpeed) { setMediaClockPlaybackParameters(playbackInfo.playbackParameters.withSpeed(adjustedSpeed)); handlePlaybackParameters( @@ -2015,19 +2015,22 @@ import java.util.concurrent.atomic.AtomicBoolean; // it is possible for playback to be stuck buffering waiting for this. Therefore, we start // playback regardless of buffered duration if we are waiting for an ad media period to prepare. boolean isAdPendingPreparation = loadingHolder.info.id.isAd() && !loadingHolder.prepared; - return isBufferedToEnd - || isAdPendingPreparation - || loadControl.shouldStartPlayback( - new LoadControl.Parameters( - playerId, - playbackInfo.timeline, - playingPeriodHolder.info.id, - playingPeriodHolder.toPeriodTime(rendererPositionUs), - getTotalBufferedDurationUs(), - mediaClock.getPlaybackParameters().speed, - playbackInfo.playWhenReady, - isRebuffering, - targetLiveOffsetUs)); + if (isBufferedToEnd || isAdPendingPreparation) { + return true; + } + // Get updated buffered duration as it may have changed since the start of the renderer loop. + long bufferedDurationUs = getTotalBufferedDurationUs(loadingHolder.getBufferedPositionUs()); + return loadControl.shouldStartPlayback( + new LoadControl.Parameters( + playerId, + playbackInfo.timeline, + playingPeriodHolder.info.id, + playingPeriodHolder.toPeriodTime(rendererPositionUs), + bufferedDurationUs, + mediaClock.getPlaybackParameters().speed, + playbackInfo.playWhenReady, + isRebuffering, + targetLiveOffsetUs)); } private boolean isTimelineReady() {