Commit 846e0666 by tonihei Committed by Oliver Woodman

Restructure updatePeriods code for better readability.

Moved update of reading and playing periods in their own respective method.
This is a no-op change.

PiperOrigin-RevId: 260463668
parent 09835c45
...@@ -1490,80 +1490,86 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1490,80 +1490,86 @@ import java.util.concurrent.atomic.AtomicBoolean;
mediaSource.maybeThrowSourceInfoRefreshError(); mediaSource.maybeThrowSourceInfoRefreshError();
return; return;
} }
// Update the loading period if required.
maybeUpdateLoadingPeriod(); maybeUpdateLoadingPeriod();
maybeUpdatePlayingPeriod();
maybeUpdateReadingPeriod();
}
private void maybeUpdateLoadingPeriod() throws IOException {
queue.reevaluateBuffer(rendererPositionUs);
if (queue.shouldLoadNextMediaPeriod()) {
MediaPeriodInfo info = queue.getNextMediaPeriodInfo(rendererPositionUs, playbackInfo);
if (info == null) {
maybeThrowSourceInfoRefreshError();
} else {
MediaPeriod mediaPeriod =
queue.enqueueNextMediaPeriod(
rendererCapabilities, trackSelector, loadControl.getAllocator(), mediaSource, info);
mediaPeriod.prepare(this, info.startPositionUs);
setIsLoading(true);
handleLoadingMediaPeriodChanged(/* loadingTrackSelectionChanged= */ false);
}
}
MediaPeriodHolder loadingPeriodHolder = queue.getLoadingPeriod(); MediaPeriodHolder loadingPeriodHolder = queue.getLoadingPeriod();
if (loadingPeriodHolder == null || loadingPeriodHolder.isFullyBuffered()) { if (loadingPeriodHolder == null || loadingPeriodHolder.isFullyBuffered()) {
setIsLoading(false); setIsLoading(false);
} else if (!playbackInfo.isLoading) { } else if (!playbackInfo.isLoading) {
maybeContinueLoading(); maybeContinueLoading();
} }
}
if (!queue.hasPlayingPeriod()) { private void maybeUpdatePlayingPeriod() throws ExoPlaybackException {
// We're waiting for the first period to be prepared.
return;
}
// Advance the playing period if necessary.
MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod();
boolean advancedPlayingPeriod = false; boolean advancedPlayingPeriod = false;
while (playWhenReady while (shouldAdvancePlayingPeriod()) {
&& playingPeriodHolder != readingPeriodHolder
&& rendererPositionUs >= playingPeriodHolder.getNext().getStartPositionRendererTime()) {
// All enabled renderers' streams have been read to the end, and the playback position reached
// the end of the playing period, so advance playback to the next period.
if (advancedPlayingPeriod) { if (advancedPlayingPeriod) {
// If we advance more than one period at a time, notify listeners after each update. // If we advance more than one period at a time, notify listeners after each update.
maybeNotifyPlaybackInfoChanged(); maybeNotifyPlaybackInfoChanged();
} }
int discontinuityReason = MediaPeriodHolder oldPlayingPeriodHolder = queue.getPlayingPeriod();
playingPeriodHolder.info.isLastInTimelinePeriod MediaPeriodHolder newPlayingPeriodHolder = queue.advancePlayingPeriod();
? Player.DISCONTINUITY_REASON_PERIOD_TRANSITION
: Player.DISCONTINUITY_REASON_AD_INSERTION;
MediaPeriodHolder oldPlayingPeriodHolder = playingPeriodHolder;
playingPeriodHolder = queue.advancePlayingPeriod();
updatePlayingPeriodRenderers(oldPlayingPeriodHolder); updatePlayingPeriodRenderers(oldPlayingPeriodHolder);
playbackInfo = playbackInfo =
playbackInfo.copyWithNewPosition( playbackInfo.copyWithNewPosition(
playingPeriodHolder.info.id, newPlayingPeriodHolder.info.id,
playingPeriodHolder.info.startPositionUs, newPlayingPeriodHolder.info.startPositionUs,
playingPeriodHolder.info.contentPositionUs, newPlayingPeriodHolder.info.contentPositionUs,
getTotalBufferedDurationUs()); getTotalBufferedDurationUs());
int discontinuityReason =
oldPlayingPeriodHolder.info.isLastInTimelinePeriod
? Player.DISCONTINUITY_REASON_PERIOD_TRANSITION
: Player.DISCONTINUITY_REASON_AD_INSERTION;
playbackInfoUpdate.setPositionDiscontinuity(discontinuityReason); playbackInfoUpdate.setPositionDiscontinuity(discontinuityReason);
updatePlaybackPositions(); updatePlaybackPositions();
advancedPlayingPeriod = true; advancedPlayingPeriod = true;
} }
}
if (readingPeriodHolder.info.isFinal) { private void maybeUpdateReadingPeriod() throws ExoPlaybackException, IOException {
for (int i = 0; i < renderers.length; i++) { MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod();
Renderer renderer = renderers[i]; if (readingPeriodHolder == null) {
SampleStream sampleStream = readingPeriodHolder.sampleStreams[i];
// Defer setting the stream as final until the renderer has actually consumed the whole
// stream in case of playlist changes that cause the stream to be no longer final.
if (sampleStream != null && renderer.getStream() == sampleStream
&& renderer.hasReadStreamToEnd()) {
renderer.setCurrentStreamFinal();
}
}
return; return;
} }
// Advance the reading period if necessary.
if (readingPeriodHolder.getNext() == null) { if (readingPeriodHolder.getNext() == null) {
// We don't have a successor to advance the reading period to. // We don't have a successor to advance the reading period to.
if (readingPeriodHolder.info.isFinal) {
for (int i = 0; i < renderers.length; i++) {
Renderer renderer = renderers[i];
SampleStream sampleStream = readingPeriodHolder.sampleStreams[i];
// Defer setting the stream as final until the renderer has actually consumed the whole
// stream in case of playlist changes that cause the stream to be no longer final.
if (sampleStream != null
&& renderer.getStream() == sampleStream
&& renderer.hasReadStreamToEnd()) {
renderer.setCurrentStreamFinal();
}
}
}
return; return;
} }
for (int i = 0; i < renderers.length; i++) { if (!hasReadingPeriodFinishedReading()) {
Renderer renderer = renderers[i]; return;
SampleStream sampleStream = readingPeriodHolder.sampleStreams[i];
if (renderer.getStream() != sampleStream
|| (sampleStream != null && !renderer.hasReadStreamToEnd())) {
// The current reading period is still being read by at least one renderer.
return;
}
} }
if (!readingPeriodHolder.getNext().prepared) { if (!readingPeriodHolder.getNext().prepared) {
...@@ -1576,18 +1582,18 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1576,18 +1582,18 @@ import java.util.concurrent.atomic.AtomicBoolean;
readingPeriodHolder = queue.advanceReadingPeriod(); readingPeriodHolder = queue.advanceReadingPeriod();
TrackSelectorResult newTrackSelectorResult = readingPeriodHolder.getTrackSelectorResult(); TrackSelectorResult newTrackSelectorResult = readingPeriodHolder.getTrackSelectorResult();
boolean initialDiscontinuity = if (readingPeriodHolder.mediaPeriod.readDiscontinuity() != C.TIME_UNSET) {
readingPeriodHolder.mediaPeriod.readDiscontinuity() != C.TIME_UNSET; // The new period starts with a discontinuity, so the renderers will play out all data, then
// be disabled and re-enabled when they start playing the next period.
setAllRendererStreamsFinal();
return;
}
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
Renderer renderer = renderers[i]; Renderer renderer = renderers[i];
boolean rendererWasEnabled = oldTrackSelectorResult.isRendererEnabled(i); boolean rendererWasEnabled = oldTrackSelectorResult.isRendererEnabled(i);
if (!rendererWasEnabled) { if (rendererWasEnabled && !renderer.isCurrentStreamFinal()) {
// The renderer was disabled and will be enabled when we play the next period. // The renderer is enabled and its stream is not final, so we still have a chance to replace
} else if (initialDiscontinuity) { // the sample streams.
// The new period starts with a discontinuity, so the renderer will play out all data then
// be disabled and re-enabled when it starts playing the next period.
renderer.setCurrentStreamFinal();
} else if (!renderer.isCurrentStreamFinal()) {
TrackSelection newSelection = newTrackSelectorResult.selections.get(i); TrackSelection newSelection = newTrackSelectorResult.selections.get(i);
boolean newRendererEnabled = newTrackSelectorResult.isRendererEnabled(i); boolean newRendererEnabled = newTrackSelectorResult.isRendererEnabled(i);
boolean isNoSampleRenderer = rendererCapabilities[i].getTrackType() == C.TRACK_TYPE_NONE; boolean isNoSampleRenderer = rendererCapabilities[i].getTrackType() == C.TRACK_TYPE_NONE;
...@@ -1615,23 +1621,41 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1615,23 +1621,41 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
} }
private void maybeUpdateLoadingPeriod() throws IOException { private boolean shouldAdvancePlayingPeriod() {
queue.reevaluateBuffer(rendererPositionUs); if (!playWhenReady) {
if (queue.shouldLoadNextMediaPeriod()) { return false;
MediaPeriodInfo info = queue.getNextMediaPeriodInfo(rendererPositionUs, playbackInfo); }
if (info == null) { MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
maybeThrowSourceInfoRefreshError(); if (playingPeriodHolder == null) {
} else { return false;
MediaPeriod mediaPeriod = }
queue.enqueueNextMediaPeriod( MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod();
rendererCapabilities, if (playingPeriodHolder == readingPeriodHolder) {
trackSelector, return false;
loadControl.getAllocator(), }
mediaSource, MediaPeriodHolder nextPlayingPeriodHolder =
info); Assertions.checkNotNull(playingPeriodHolder.getNext());
mediaPeriod.prepare(this, info.startPositionUs); return rendererPositionUs >= nextPlayingPeriodHolder.getStartPositionRendererTime();
setIsLoading(true); }
handleLoadingMediaPeriodChanged(/* loadingTrackSelectionChanged= */ false);
private boolean hasReadingPeriodFinishedReading() {
MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod();
for (int i = 0; i < renderers.length; i++) {
Renderer renderer = renderers[i];
SampleStream sampleStream = readingPeriodHolder.sampleStreams[i];
if (renderer.getStream() != sampleStream
|| (sampleStream != null && !renderer.hasReadStreamToEnd())) {
// The current reading period is still being read by at least one renderer.
return false;
}
}
return true;
}
private void setAllRendererStreamsFinal() {
for (Renderer renderer : renderers) {
if (renderer.getStream() != null) {
renderer.setCurrentStreamFinal();
} }
} }
} }
......
...@@ -170,6 +170,7 @@ import com.google.android.exoplayer2.util.Assertions; ...@@ -170,6 +170,7 @@ import com.google.android.exoplayer2.util.Assertions;
* Returns the loading period holder which is at the end of the queue, or null if the queue is * Returns the loading period holder which is at the end of the queue, or null if the queue is
* empty. * empty.
*/ */
@Nullable
public MediaPeriodHolder getLoadingPeriod() { public MediaPeriodHolder getLoadingPeriod() {
return loading; return loading;
} }
...@@ -178,6 +179,7 @@ import com.google.android.exoplayer2.util.Assertions; ...@@ -178,6 +179,7 @@ import com.google.android.exoplayer2.util.Assertions;
* Returns the playing period holder which is at the front of the queue, or null if the queue is * Returns the playing period holder which is at the front of the queue, or null if the queue is
* empty or hasn't started playing. * empty or hasn't started playing.
*/ */
@Nullable
public MediaPeriodHolder getPlayingPeriod() { public MediaPeriodHolder getPlayingPeriod() {
return playing; return playing;
} }
...@@ -186,6 +188,7 @@ import com.google.android.exoplayer2.util.Assertions; ...@@ -186,6 +188,7 @@ import com.google.android.exoplayer2.util.Assertions;
* Returns the reading period holder, or null if the queue is empty or the player hasn't started * Returns the reading period holder, or null if the queue is empty or the player hasn't started
* reading. * reading.
*/ */
@Nullable
public MediaPeriodHolder getReadingPeriod() { public MediaPeriodHolder getReadingPeriod() {
return reading; return reading;
} }
...@@ -194,6 +197,7 @@ import com.google.android.exoplayer2.util.Assertions; ...@@ -194,6 +197,7 @@ import com.google.android.exoplayer2.util.Assertions;
* Returns the period holder in the front of the queue which is the playing period holder when * Returns the period holder in the front of the queue which is the playing period holder when
* playing, or null if the queue is empty. * playing, or null if the queue is empty.
*/ */
@Nullable
public MediaPeriodHolder getFrontPeriod() { public MediaPeriodHolder getFrontPeriod() {
return hasPlayingPeriod() ? playing : loading; return hasPlayingPeriod() ? playing : loading;
} }
...@@ -221,6 +225,7 @@ import com.google.android.exoplayer2.util.Assertions; ...@@ -221,6 +225,7 @@ import com.google.android.exoplayer2.util.Assertions;
* *
* @return The updated playing period holder, or null if the queue is or becomes empty. * @return The updated playing period holder, or null if the queue is or becomes empty.
*/ */
@Nullable
public MediaPeriodHolder advancePlayingPeriod() { public MediaPeriodHolder advancePlayingPeriod() {
if (playing != null) { if (playing != null) {
if (playing == reading) { if (playing == reading) {
......
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