Commit 21c76b01 by tonihei Committed by Ian Baker

No-op restructure of playlist update handling.

This restructure moves all the position resolving code to a static method and
removes the dependency of the MediaPeriodQueue on having an up-to-date timeline.

Both steps allow simplified reasoning about the code as the static method can't change
the state of the player, and there is no risk the queue can use the wrong timeline.

These propoerties allow to fix a bug causing inconsistent states in a follow-up step.

PiperOrigin-RevId: 290616395
parent df41ae3f
......@@ -839,7 +839,7 @@ import java.util.concurrent.TimeoutException;
long startPositionUs = playbackInfo.positionUs;
if (clearPlaylist) {
timeline = Timeline.EMPTY;
mediaPeriodId = playbackInfo.getDummyPeriodForEmptyTimeline();
mediaPeriodId = PlaybackInfo.getDummyPeriodForEmptyTimeline();
contentPositionUs = C.TIME_UNSET;
startPositionUs = C.TIME_UNSET;
}
......
......@@ -151,35 +151,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
this.positionUs = positionUs;
}
/**
* Returns dummy media period id for the first-to-be-played period of the current timeline.
*
* @param shuffleModeEnabled Whether shuffle mode is enabled.
* @param window A writable {@link Timeline.Window}.
* @param period A writable {@link Timeline.Period}.
* @return A dummy media period id for the first-to-be-played period of the current timeline.
*/
public MediaPeriodId getDummyFirstMediaPeriodId(
boolean shuffleModeEnabled, Timeline.Window window, Timeline.Period period) {
if (timeline.isEmpty()) {
return getDummyPeriodForEmptyTimeline();
}
int firstWindowIndex = timeline.getFirstWindowIndex(shuffleModeEnabled);
int firstPeriodIndex = timeline.getWindow(firstWindowIndex, window).firstPeriodIndex;
int currentPeriodIndex = timeline.getIndexOfPeriod(periodId.periodUid);
long windowSequenceNumber = C.INDEX_UNSET;
if (currentPeriodIndex != C.INDEX_UNSET) {
int currentWindowIndex = timeline.getPeriod(currentPeriodIndex, period).windowIndex;
if (firstWindowIndex == currentWindowIndex) {
// Keep window sequence number if the new position is still in the same window.
windowSequenceNumber = periodId.windowSequenceNumber;
}
}
return new MediaPeriodId(timeline.getUidOfPeriod(firstPeriodIndex), windowSequenceNumber);
}
/** Returns dummy period id for an empty timeline. */
public MediaPeriodId getDummyPeriodForEmptyTimeline() {
public static MediaPeriodId getDummyPeriodForEmptyTimeline() {
return DUMMY_MEDIA_PERIOD_ID;
}
......
......@@ -202,7 +202,7 @@ public final class MediaPeriodQueueTest {
setAdGroupLoaded(/* adGroupIndex= */ 1);
boolean changeHandled =
mediaPeriodQueue.updateQueuedPeriods(
/* rendererPositionUs= */ 0, /* maxRendererReadPositionUs= */ 0);
playbackInfo.timeline, /* rendererPositionUs= */ 0, /* maxRendererReadPositionUs= */ 0);
assertThat(changeHandled).isTrue();
assertThat(getQueueLength()).isEqualTo(3);
......@@ -228,7 +228,9 @@ public final class MediaPeriodQueueTest {
setAdGroupLoaded(/* adGroupIndex= */ 1);
boolean changeHandled =
mediaPeriodQueue.updateQueuedPeriods(
/* rendererPositionUs= */ 0, /* maxRendererReadPositionUs= */ FIRST_AD_START_TIME_US);
playbackInfo.timeline,
/* rendererPositionUs= */ 0,
/* maxRendererReadPositionUs= */ FIRST_AD_START_TIME_US);
assertThat(changeHandled).isFalse();
assertThat(getQueueLength()).isEqualTo(1);
......@@ -256,6 +258,7 @@ public final class MediaPeriodQueueTest {
long readingPositionAtStartOfContentBetweenAds = FIRST_AD_START_TIME_US + AD_DURATION_US;
boolean changeHandled =
mediaPeriodQueue.updateQueuedPeriods(
playbackInfo.timeline,
/* rendererPositionUs= */ 0,
/* maxRendererReadPositionUs= */ readingPositionAtStartOfContentBetweenAds);
......@@ -285,6 +288,7 @@ public final class MediaPeriodQueueTest {
long readingPositionAtEndOfContentBetweenAds = SECOND_AD_START_TIME_US + AD_DURATION_US;
boolean changeHandled =
mediaPeriodQueue.updateQueuedPeriods(
playbackInfo.timeline,
/* rendererPositionUs= */ 0,
/* maxRendererReadPositionUs= */ readingPositionAtEndOfContentBetweenAds);
......@@ -313,7 +317,9 @@ public final class MediaPeriodQueueTest {
setAdGroupLoaded(/* adGroupIndex= */ 1);
boolean changeHandled =
mediaPeriodQueue.updateQueuedPeriods(
/* rendererPositionUs= */ 0, /* maxRendererReadPositionUs= */ C.TIME_END_OF_SOURCE);
playbackInfo.timeline,
/* rendererPositionUs= */ 0,
/* maxRendererReadPositionUs= */ C.TIME_END_OF_SOURCE);
assertThat(changeHandled).isFalse();
assertThat(getQueueLength()).isEqualTo(3);
......@@ -332,12 +338,11 @@ public final class MediaPeriodQueueTest {
Timeline timeline = createPlaylistTimeline();
periodUid = timeline.getUidOfPeriod(/* periodIndex= */ 0);
mediaPeriodQueue.setTimeline(timeline);
playbackInfo =
new PlaybackInfo(
timeline,
mediaPeriodQueue.resolveMediaPeriodIdForAds(periodUid, /* positionUs= */ 0),
mediaPeriodQueue.resolveMediaPeriodIdForAds(timeline, periodUid, /* positionUs= */ 0),
/* startPositionUs= */ 0,
/* contentPositionUs= */ 0,
Player.STATE_READY,
......@@ -361,7 +366,7 @@ public final class MediaPeriodQueueTest {
SinglePeriodAdTimeline adTimeline =
new SinglePeriodAdTimeline(CONTENT_TIMELINE, adPlaybackState);
fakeMediaSource.setNewSourceInfo(adTimeline, /* manifest */ null);
mediaPeriodQueue.setTimeline(createPlaylistTimeline());
playbackInfo = playbackInfo.copyWithTimeline(createPlaylistTimeline());
}
private Playlist.PlaylistTimeline createPlaylistTimeline() {
......
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