Commit 494510d6 by olly Committed by Oliver Woodman

Fix ready and ended conditions.

1. The readiness of the timeline is only relevant if there
   aren't any enabled renderers. It's also only ready if
   the source after the playing source is actually prepared
   (if not, we're waiting for preparation).
2. Prevent early transition to the ENDED state when the
   playback position hits the duration, but we're not at the
   final entry in the playlist.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=125685193
parent a8883baa
...@@ -397,22 +397,28 @@ import java.util.ArrayList; ...@@ -397,22 +397,28 @@ import java.util.ArrayList;
allRenderersReadyOrEnded = allRenderersReadyOrEnded && rendererReadyOrEnded; allRenderersReadyOrEnded = allRenderersReadyOrEnded && rendererReadyOrEnded;
} }
boolean timelineIsReady = timeline.isReady(); // TODO: Have timeline.updateSources() above return whether the timeline is ready, and remove
// timeline.isReady(). This will avoid any inconsistencies that could arise due to the playback
// position update. We could probably return [ENDED|READY|BUFFERING] and get rid of isEnded too.
if (allRenderersEnded && (playbackInfo.durationUs == C.UNSET_TIME_US if (allRenderersEnded && (playbackInfo.durationUs == C.UNSET_TIME_US
|| playbackInfo.durationUs <= playbackInfo.positionUs)) { || playbackInfo.durationUs <= playbackInfo.positionUs) && timeline.isEnded()) {
setState(ExoPlayer.STATE_ENDED); setState(ExoPlayer.STATE_ENDED);
stopRenderers(); stopRenderers();
} else if (state == ExoPlayer.STATE_BUFFERING && allRenderersReadyOrEnded } else if (state == ExoPlayer.STATE_BUFFERING) {
&& haveSufficientBuffer() && timelineIsReady) { if ((enabledRenderers.length > 0 ? allRenderersReadyOrEnded : timeline.isReady())
&& haveSufficientBuffer()) {
setState(ExoPlayer.STATE_READY); setState(ExoPlayer.STATE_READY);
if (playWhenReady) { if (playWhenReady) {
startRenderers(); startRenderers();
} }
} else if (state == ExoPlayer.STATE_READY && (!allRenderersReadyOrEnded || !timelineIsReady)) { }
} else if (state == ExoPlayer.STATE_READY) {
if (enabledRenderers.length > 0 ? !allRenderersReadyOrEnded : !timeline.isReady()) {
rebuffering = playWhenReady; rebuffering = playWhenReady;
setState(ExoPlayer.STATE_BUFFERING); setState(ExoPlayer.STATE_BUFFERING);
stopRenderers(); stopRenderers();
} }
}
handler.removeMessages(MSG_DO_SOME_WORK); handler.removeMessages(MSG_DO_SOME_WORK);
if ((playWhenReady && state == ExoPlayer.STATE_READY) || state == ExoPlayer.STATE_BUFFERING) { if ((playWhenReady && state == ExoPlayer.STATE_READY) || state == ExoPlayer.STATE_BUFFERING) {
...@@ -576,6 +582,21 @@ import java.util.ArrayList; ...@@ -576,6 +582,21 @@ import java.util.ArrayList;
return playingSource == null ? null : playingSource.sampleSource; return playingSource == null ? null : playingSource.sampleSource;
} }
public boolean isEnded() {
if (playingSource == null) {
return false;
}
int sourceCount = sampleSourceProvider.getSourceCount();
return sourceCount != SampleSourceProvider.UNKNOWN_SOURCE_COUNT
&& playingSource.index == sourceCount - 1;
}
public boolean isReady() {
return playingSourceEndPositionUs == C.UNSET_TIME_US
|| internalPositionUs < playingSourceEndPositionUs
|| (playingSource.nextSource != null && playingSource.nextSource.prepared);
}
public void updateSources() throws ExoPlaybackException, IOException { public void updateSources() throws ExoPlaybackException, IOException {
// TODO[playlists]: Let sample source providers invalidate sources that are already buffering. // TODO[playlists]: Let sample source providers invalidate sources that are already buffering.
...@@ -680,11 +701,6 @@ import java.util.ArrayList; ...@@ -680,11 +701,6 @@ import java.util.ArrayList;
} }
} }
public boolean isReady() {
return playingSourceEndPositionUs == C.UNSET_TIME_US
|| internalPositionUs < playingSourceEndPositionUs || playingSource.nextSource != null;
}
public void seekToSource(int sourceIndex) throws ExoPlaybackException { public void seekToSource(int sourceIndex) throws ExoPlaybackException {
// Clear the timeline, but keep the requested source if it is already prepared. // Clear the timeline, but keep the requested source if it is already prepared.
Source source = playingSource; Source source = playingSource;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment