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
This commit is contained in:
olly 2016-06-23 09:27:20 -07:00 committed by Oliver Woodman
parent a8883baa69
commit 494510d6ad

View file

@ -397,21 +397,27 @@ import java.util.ArrayList;
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
|| playbackInfo.durationUs <= playbackInfo.positionUs)) {
|| playbackInfo.durationUs <= playbackInfo.positionUs) && timeline.isEnded()) {
setState(ExoPlayer.STATE_ENDED);
stopRenderers();
} else if (state == ExoPlayer.STATE_BUFFERING && allRenderersReadyOrEnded
&& haveSufficientBuffer() && timelineIsReady) {
setState(ExoPlayer.STATE_READY);
if (playWhenReady) {
startRenderers();
} else if (state == ExoPlayer.STATE_BUFFERING) {
if ((enabledRenderers.length > 0 ? allRenderersReadyOrEnded : timeline.isReady())
&& haveSufficientBuffer()) {
setState(ExoPlayer.STATE_READY);
if (playWhenReady) {
startRenderers();
}
}
} else if (state == ExoPlayer.STATE_READY) {
if (enabledRenderers.length > 0 ? !allRenderersReadyOrEnded : !timeline.isReady()) {
rebuffering = playWhenReady;
setState(ExoPlayer.STATE_BUFFERING);
stopRenderers();
}
} else if (state == ExoPlayer.STATE_READY && (!allRenderersReadyOrEnded || !timelineIsReady)) {
rebuffering = playWhenReady;
setState(ExoPlayer.STATE_BUFFERING);
stopRenderers();
}
handler.removeMessages(MSG_DO_SOME_WORK);
@ -576,6 +582,21 @@ import java.util.ArrayList;
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 {
// TODO[playlists]: Let sample source providers invalidate sources that are already buffering.
@ -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 {
// Clear the timeline, but keep the requested source if it is already prepared.
Source source = playingSource;