Fix seeking in the last period.

When reading the last period, the readingPeriodHolder was set to null in
updatePeriods if it was the last period. (This would occur almost immediately
when playing a single-period source.) seekToPeriodPosition suppresses reusing a
loaded/prepared period if the reading period and playing period did not match,
which meant that the whole timeline was recreated when seeking in the last
period.

Leave readingPeriodHolder non-null. This means that at all times either
playingPeriodHolder == readingPeriodHolder (and they could be null or
non-null), or playingPeriodHolder and readingPeriodHolder differ and are both
non-null.

Also fix an issue where streams were never forced to be recreated during track
reselection when reading ahead.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=134774238
This commit is contained in:
andrewlewis 2016-09-30 05:46:14 -07:00 committed by Oliver Woodman
parent 7971a18a83
commit ee4d297f22

View File

@ -529,9 +529,9 @@ import java.io.IOException;
rebuffering = false;
setState(ExoPlayer.STATE_BUFFERING);
if (periodPositionUs == C.TIME_UNSET
|| (readingPeriodHolder != playingPeriodHolder && (periodIndex == playingPeriodHolder.index
|| (readingPeriodHolder != null && periodIndex == readingPeriodHolder.index)))) {
if (periodPositionUs == C.TIME_UNSET || (readingPeriodHolder != playingPeriodHolder
&& (periodIndex == playingPeriodHolder.index
|| periodIndex == readingPeriodHolder.index))) {
// Clear the timeline because either the seek position is not known, or a renderer is reading
// ahead to the next period and the seek is to either the playing or reading period.
periodIndex = C.INDEX_UNSET;
@ -690,16 +690,14 @@ import java.io.IOException;
}
if (selectionsChangedForReadPeriod) {
// Release everything after the playing period because a renderer may have read data from a
// track whose selection has now changed.
// Update streams and rebuffer for the new selection, recreating all streams if reading ahead.
boolean recreateStreams = readingPeriodHolder != playingPeriodHolder;
releasePeriodHoldersFrom(playingPeriodHolder.next);
playingPeriodHolder.next = null;
readingPeriodHolder = playingPeriodHolder;
loadingPeriodHolder = playingPeriodHolder;
bufferAheadPeriodCount = 0;
// Update streams for the new selection, recreating all streams if reading ahead.
boolean recreateStreams = readingPeriodHolder != playingPeriodHolder;
boolean[] streamResetFlags = new boolean[renderers.length];
long periodPositionUs = playingPeriodHolder.updatePeriodTrackSelection(
playbackInfo.positionUs, loadControl, recreateStreams, streamResetFlags);
@ -810,11 +808,11 @@ import java.io.IOException;
playingPeriodHolder.setIndex(timeline, timeline.getWindow(period.windowIndex, window),
index);
MediaPeriodHolder<T> previousPeriod = playingPeriodHolder;
MediaPeriodHolder<T> previousPeriodHolder = playingPeriodHolder;
boolean seenReadingPeriod = false;
bufferAheadPeriodCount = 0;
while (previousPeriod.next != null) {
MediaPeriodHolder<T> periodHolder = previousPeriod.next;
while (previousPeriodHolder.next != null) {
MediaPeriodHolder<T> periodHolder = previousPeriodHolder.next;
index++;
timeline.getPeriod(index, period, true);
if (!periodHolder.uid.equals(period.uid)) {
@ -835,7 +833,7 @@ import java.io.IOException;
}
// Update the loading period to be the latest period that is still valid.
loadingPeriodHolder = previousPeriod;
loadingPeriodHolder = previousPeriodHolder;
loadingPeriodHolder.next = null;
// Release the rest of the timeline.
@ -849,7 +847,7 @@ import java.io.IOException;
if (periodHolder == readingPeriodHolder) {
seenReadingPeriod = true;
}
previousPeriod = periodHolder;
previousPeriodHolder = periodHolder;
}
} else if (loadingPeriodHolder != null) {
Object uid = loadingPeriodHolder.uid;
@ -997,14 +995,11 @@ import java.io.IOException;
}
updateTimelineState();
if (readingPeriodHolder != null && readingPeriodHolder.isLast) {
readingPeriodHolder = null;
if (readingPeriodHolder.isLast) {
// The renderers have their final SampleStreams.
for (Renderer renderer : enabledRenderers) {
renderer.setCurrentStreamIsFinal();
}
}
if (readingPeriodHolder == null) {
// The renderers have their final SampleStreams.
return;
}