Commit ee4d297f by andrewlewis Committed by Oliver Woodman

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