From 95f41134569f22e5c0fe9a058a5fec14b8c9fd1e Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Mon, 8 Aug 2016 06:55:32 -0700 Subject: [PATCH] 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 --- .../exoplayer2/ExoPlayerImplInternal.java | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java b/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java index 272e14d69e..298abdaf8c 100644 --- a/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java +++ b/library/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java @@ -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 {