Fix seeking into a different period that has been prepared.

When seekToPeriodPosition found that the seek destination period was already
prepared, it would not disable/re-enable renderers. This was fine if the
playing period wasn't changing, but in other cases the renderers would be left
reading the incorrect streams (and the underlying periods may have been
released).

Also, transition to the buffering state before re-enabling renderers, so that
the renderers are not started until leaving the buffering state.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=129625632
This commit is contained in:
andrewlewis 2016-08-08 06:55:32 -07:00 committed by Oliver Woodman
parent 5783272444
commit 95f4113456

View file

@ -533,6 +533,23 @@ import java.util.ArrayList;
}
private void seekToPeriodPosition(int periodIndex, long positionUs) throws ExoPlaybackException {
if (periodIndex != playbackInfo.periodIndex) {
playbackInfo = new PlaybackInfo(periodIndex);
playbackInfo.startPositionUs = positionUs;
playbackInfo.positionUs = positionUs;
eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY, playbackInfo).sendToTarget();
} else {
playbackInfo.startPositionUs = positionUs;
playbackInfo.positionUs = positionUs;
}
if (mediaSource == null) {
if (positionUs != C.UNSET_TIME_US) {
resetInternalPosition(positionUs);
}
return;
}
stopRenderers();
rebuffering = false;
@ -553,6 +570,16 @@ import java.util.ArrayList;
period = period.nextPeriod;
}
// Disable all the renderers if the period is changing.
if (newPlayingPeriod != playingPeriod) {
for (Renderer renderer : enabledRenderers) {
renderer.disable();
}
enabledRenderers = new Renderer[0];
rendererMediaClock = null;
rendererMediaClockSource = null;
}
// Update loaded periods.
bufferAheadPeriodCount = 0;
if (newPlayingPeriod != null) {
@ -563,16 +590,12 @@ import java.util.ArrayList;
loadingPeriod = playingPeriod;
if (playingPeriod.hasEnabledTracks) {
positionUs = playingPeriod.mediaPeriod.seekToUs(positionUs);
playbackInfo.startPositionUs = positionUs;
playbackInfo.positionUs = positionUs;
}
resetInternalPosition(positionUs);
maybeContinueLoading();
} else {
for (Renderer renderer : enabledRenderers) {
renderer.disable();
}
enabledRenderers = new Renderer[0];
rendererMediaClock = null;
rendererMediaClockSource = null;
playingPeriod = null;
readingPeriod = null;
loadingPeriod = null;
@ -580,23 +603,9 @@ import java.util.ArrayList;
resetInternalPosition(positionUs);
}
}
// Update the expose playback information.
if (periodIndex != playbackInfo.periodIndex) {
playbackInfo = new PlaybackInfo(periodIndex);
playbackInfo.startPositionUs = positionUs;
playbackInfo.positionUs = positionUs;
eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY, playbackInfo).sendToTarget();
} else {
playbackInfo.startPositionUs = positionUs;
playbackInfo.positionUs = positionUs;
}
updatePlaybackPositions();
if (mediaSource != null) {
setState(ExoPlayer.STATE_BUFFERING);
handler.sendEmptyMessage(MSG_DO_SOME_WORK);
}
setState(ExoPlayer.STATE_BUFFERING);
handler.sendEmptyMessage(MSG_DO_SOME_WORK);
}
private void resetInternalPosition(long periodPositionUs) throws ExoPlaybackException {