Commit c85e5137 by tonihei Committed by Oliver Woodman

No-op change removing bookkeeping for enabled renderers.

This list was meant to simplify some usages where we only want to
make operations on enabled renderers. However, keeping this list
up-to-date is slightly error-prone (because renderers aren't added
and removed from this list next to the corresponding enable and disable
calls) and it makes it hard to do more fine-grained changes that only
enable or disabled a single renderer at a time.

PiperOrigin-RevId: 300513788
parent 82599960
...@@ -119,7 +119,6 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -119,7 +119,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
private PlaybackInfo playbackInfo; private PlaybackInfo playbackInfo;
private PlaybackInfoUpdate playbackInfoUpdate; private PlaybackInfoUpdate playbackInfoUpdate;
private Renderer[] enabledRenderers;
private boolean released; private boolean released;
private boolean pauseAtEndOfWindow; private boolean pauseAtEndOfWindow;
private boolean pendingPauseAtEndOfPeriod; private boolean pendingPauseAtEndOfPeriod;
...@@ -129,6 +128,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -129,6 +128,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private boolean shuffleModeEnabled; private boolean shuffleModeEnabled;
private boolean foregroundMode; private boolean foregroundMode;
private int enabledRendererCount;
@Nullable private SeekPosition pendingInitialSeekPosition; @Nullable private SeekPosition pendingInitialSeekPosition;
private long rendererPositionUs; private long rendererPositionUs;
private int nextPendingMessageIndex; private int nextPendingMessageIndex;
...@@ -171,7 +171,6 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -171,7 +171,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
mediaClock = new DefaultMediaClock(this, clock); mediaClock = new DefaultMediaClock(this, clock);
pendingMessages = new ArrayList<>(); pendingMessages = new ArrayList<>();
enabledRenderers = new Renderer[0];
window = new Timeline.Window(); window = new Timeline.Window();
period = new Timeline.Period(); period = new Timeline.Period();
trackSelector.init(/* listener= */ this, bandwidthMeter); trackSelector.init(/* listener= */ this, bandwidthMeter);
...@@ -728,15 +727,19 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -728,15 +727,19 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void startRenderers() throws ExoPlaybackException { private void startRenderers() throws ExoPlaybackException {
rebuffering = false; rebuffering = false;
mediaClock.start(); mediaClock.start();
for (Renderer renderer : enabledRenderers) { for (Renderer renderer : renderers) {
renderer.start(); if (isRendererEnabled(renderer)) {
renderer.start();
}
} }
} }
private void stopRenderers() throws ExoPlaybackException { private void stopRenderers() throws ExoPlaybackException {
mediaClock.stop(); mediaClock.stop();
for (Renderer renderer : enabledRenderers) { for (Renderer renderer : renderers) {
ensureStopped(renderer); if (isRendererEnabled(renderer)) {
ensureStopped(renderer);
}
} }
} }
...@@ -808,7 +811,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -808,7 +811,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
playbackInfo.positionUs - backBufferDurationUs, retainBackBufferFromKeyframe); playbackInfo.positionUs - backBufferDurationUs, retainBackBufferFromKeyframe);
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
Renderer renderer = renderers[i]; Renderer renderer = renderers[i];
if (renderer.getState() == Renderer.STATE_DISABLED) { if (!isRendererEnabled(renderer)) {
continue; continue;
} }
// TODO: Each renderer should return the maximum delay before which it wishes to be called // TODO: Each renderer should return the maximum delay before which it wishes to be called
...@@ -861,22 +864,24 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -861,22 +864,24 @@ import java.util.concurrent.atomic.AtomicBoolean;
startRenderers(); startRenderers();
} }
} else if (playbackInfo.playbackState == Player.STATE_READY } else if (playbackInfo.playbackState == Player.STATE_READY
&& !(enabledRenderers.length == 0 ? isTimelineReady() : renderersAllowPlayback)) { && !(enabledRendererCount == 0 ? isTimelineReady() : renderersAllowPlayback)) {
rebuffering = shouldPlayWhenReady(); rebuffering = shouldPlayWhenReady();
setState(Player.STATE_BUFFERING); setState(Player.STATE_BUFFERING);
stopRenderers(); stopRenderers();
} }
if (playbackInfo.playbackState == Player.STATE_BUFFERING) { if (playbackInfo.playbackState == Player.STATE_BUFFERING) {
for (Renderer renderer : enabledRenderers) { for (Renderer renderer : renderers) {
renderer.maybeThrowStreamError(); if (isRendererEnabled(renderer)) {
renderer.maybeThrowStreamError();
}
} }
} }
if ((shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY) if ((shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY)
|| playbackInfo.playbackState == Player.STATE_BUFFERING) { || playbackInfo.playbackState == Player.STATE_BUFFERING) {
scheduleNextWork(operationStartTimeMs, ACTIVE_INTERVAL_MS); scheduleNextWork(operationStartTimeMs, ACTIVE_INTERVAL_MS);
} else if (enabledRenderers.length != 0 && playbackInfo.playbackState != Player.STATE_ENDED) { } else if (enabledRendererCount != 0 && playbackInfo.playbackState != Player.STATE_ENDED) {
scheduleNextWork(operationStartTimeMs, IDLE_INTERVAL_MS); scheduleNextWork(operationStartTimeMs, IDLE_INTERVAL_MS);
} else { } else {
handler.removeMessages(MSG_DO_SOME_WORK); handler.removeMessages(MSG_DO_SOME_WORK);
...@@ -1029,10 +1034,9 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1029,10 +1034,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|| oldPlayingPeriodHolder != newPlayingPeriodHolder || oldPlayingPeriodHolder != newPlayingPeriodHolder
|| (newPlayingPeriodHolder != null || (newPlayingPeriodHolder != null
&& newPlayingPeriodHolder.toRendererTime(periodPositionUs) < 0)) { && newPlayingPeriodHolder.toRendererTime(periodPositionUs) < 0)) {
for (Renderer renderer : enabledRenderers) { for (Renderer renderer : renderers) {
disableRenderer(renderer); disableRenderer(renderer);
} }
enabledRenderers = new Renderer[0];
if (newPlayingPeriodHolder != null) { if (newPlayingPeriodHolder != null) {
// Update the queue and reenable renderers if the requested media period already exists. // Update the queue and reenable renderers if the requested media period already exists.
while (queue.getPlayingPeriod() != newPlayingPeriodHolder) { while (queue.getPlayingPeriod() != newPlayingPeriodHolder) {
...@@ -1081,8 +1085,10 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1081,8 +1085,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
? periodPositionUs ? periodPositionUs
: playingMediaPeriod.toRendererTime(periodPositionUs); : playingMediaPeriod.toRendererTime(periodPositionUs);
mediaClock.resetPosition(rendererPositionUs); mediaClock.resetPosition(rendererPositionUs);
for (Renderer renderer : enabledRenderers) { for (Renderer renderer : renderers) {
renderer.resetPosition(rendererPositionUs); if (isRendererEnabled(renderer)) {
renderer.resetPosition(rendererPositionUs);
}
} }
notifyTrackSelectionDiscontinuity(); notifyTrackSelectionDiscontinuity();
} }
...@@ -1102,7 +1108,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1102,7 +1108,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
this.foregroundMode = foregroundMode; this.foregroundMode = foregroundMode;
if (!foregroundMode) { if (!foregroundMode) {
for (Renderer renderer : renderers) { for (Renderer renderer : renderers) {
if (renderer.getState() == Renderer.STATE_DISABLED) { if (!isRendererEnabled(renderer)) {
renderer.reset(); renderer.reset();
} }
} }
...@@ -1155,7 +1161,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1155,7 +1161,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
rebuffering = false; rebuffering = false;
mediaClock.stop(); mediaClock.stop();
rendererPositionUs = 0; rendererPositionUs = 0;
for (Renderer renderer : enabledRenderers) { for (Renderer renderer : renderers) {
try { try {
disableRenderer(renderer); disableRenderer(renderer);
} catch (ExoPlaybackException | RuntimeException e) { } catch (ExoPlaybackException | RuntimeException e) {
...@@ -1173,7 +1179,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1173,7 +1179,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
} }
} }
enabledRenderers = new Renderer[0]; enabledRendererCount = 0;
Timeline timeline = playbackInfo.timeline; Timeline timeline = playbackInfo.timeline;
if (clearPlaylist) { if (clearPlaylist) {
...@@ -1410,9 +1416,13 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1410,9 +1416,13 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
private void disableRenderer(Renderer renderer) throws ExoPlaybackException { private void disableRenderer(Renderer renderer) throws ExoPlaybackException {
if (!isRendererEnabled(renderer)) {
return;
}
mediaClock.onRendererDisabled(renderer); mediaClock.onRendererDisabled(renderer);
ensureStopped(renderer); ensureStopped(renderer);
renderer.disable(); renderer.disable();
enabledRendererCount--;
} }
private void reselectTracksInternal() throws ExoPlaybackException { private void reselectTracksInternal() throws ExoPlaybackException {
...@@ -1457,15 +1467,11 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1457,15 +1467,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
resetRendererPosition(periodPositionUs); resetRendererPosition(periodPositionUs);
} }
int enabledRendererCount = 0;
boolean[] rendererWasEnabledFlags = new boolean[renderers.length]; boolean[] rendererWasEnabledFlags = new boolean[renderers.length];
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
Renderer renderer = renderers[i]; Renderer renderer = renderers[i];
rendererWasEnabledFlags[i] = renderer.getState() != Renderer.STATE_DISABLED; rendererWasEnabledFlags[i] = isRendererEnabled(renderer);
SampleStream sampleStream = playingPeriodHolder.sampleStreams[i]; SampleStream sampleStream = playingPeriodHolder.sampleStreams[i];
if (sampleStream != null) {
enabledRendererCount++;
}
if (rendererWasEnabledFlags[i]) { if (rendererWasEnabledFlags[i]) {
if (sampleStream != renderer.getStream()) { if (sampleStream != renderer.getStream()) {
// We need to disable the renderer. // We need to disable the renderer.
...@@ -1476,7 +1482,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1476,7 +1482,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
} }
} }
enableRenderers(rendererWasEnabledFlags, enabledRendererCount); enableRenderers(rendererWasEnabledFlags);
} else { } else {
// Release and re-prepare/buffer periods after the one whose selection changed. // Release and re-prepare/buffer periods after the one whose selection changed.
queue.removeAfter(periodHolder); queue.removeAfter(periodHolder);
...@@ -1522,7 +1528,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1522,7 +1528,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
private boolean shouldTransitionToReadyState(boolean renderersReadyOrEnded) { private boolean shouldTransitionToReadyState(boolean renderersReadyOrEnded) {
if (enabledRenderers.length == 0) { if (enabledRendererCount == 0) {
// If there are no enabled renderers, determine whether we're ready based on the timeline. // If there are no enabled renderers, determine whether we're ready based on the timeline.
return isTimelineReady(); return isTimelineReady();
} }
...@@ -1555,8 +1561,8 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1555,8 +1561,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
MediaPeriodHolder loadingPeriodHolder = queue.getLoadingPeriod(); MediaPeriodHolder loadingPeriodHolder = queue.getLoadingPeriod();
if (loadingPeriodHolder != null) { if (loadingPeriodHolder != null) {
// Defer throwing until we read all available media periods. // Defer throwing until we read all available media periods.
for (Renderer renderer : enabledRenderers) { for (Renderer renderer : renderers) {
if (!renderer.hasReadStreamToEnd()) { if (isRendererEnabled(renderer) && !renderer.hasReadStreamToEnd()) {
return; return;
} }
} }
...@@ -1640,7 +1646,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1640,7 +1646,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
return maxReadPositionUs; return maxReadPositionUs;
} }
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
if (renderers[i].getState() == Renderer.STATE_DISABLED if (!isRendererEnabled(renderers[i])
|| renderers[i].getStream() != readingHolder.sampleStreams[i]) { || renderers[i].getStream() != readingHolder.sampleStreams[i]) {
// Ignore disabled renderers and renderers with sample streams from previous periods. // Ignore disabled renderers and renderers with sample streams from previous periods.
continue; continue;
...@@ -1804,7 +1810,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1804,7 +1810,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
: Player.DISCONTINUITY_REASON_AD_INSERTION; : Player.DISCONTINUITY_REASON_AD_INSERTION;
playbackInfoUpdate.setPositionDiscontinuity(discontinuityReason); playbackInfoUpdate.setPositionDiscontinuity(discontinuityReason);
resetPendingPauseAtEndOfPeriod(); resetPendingPauseAtEndOfPeriod();
enablePlayingPeriodRenderers(rendererWasEnabledFlags); enableRenderers(rendererWasEnabledFlags);
updatePlaybackPositions(); updatePlaybackPositions();
advancedPlayingPeriod = true; advancedPlayingPeriod = true;
} }
...@@ -1993,7 +1999,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1993,7 +1999,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
Assertions.checkNotNull(oldPlayingPeriodHolder.getNext()); Assertions.checkNotNull(oldPlayingPeriodHolder.getNext());
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
Renderer renderer = renderers[i]; Renderer renderer = renderers[i];
outRendererWasEnabledFlags[i] = renderer.getState() != Renderer.STATE_DISABLED; outRendererWasEnabledFlags[i] = isRendererEnabled(renderer);
if (outRendererWasEnabledFlags[i] if (outRendererWasEnabledFlags[i]
&& (!newPlayingPeriodHolder.getTrackSelectorResult().isRendererEnabled(i) && (!newPlayingPeriodHolder.getTrackSelectorResult().isRendererEnabled(i)
|| (renderer.isCurrentStreamFinal() || (renderer.isCurrentStreamFinal()
...@@ -2007,25 +2013,10 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -2007,25 +2013,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
private void enablePlayingPeriodRenderers() throws ExoPlaybackException { private void enablePlayingPeriodRenderers() throws ExoPlaybackException {
enablePlayingPeriodRenderers(/* rendererWasEnabledFlags= */ new boolean[renderers.length]); enableRenderers(/* rendererWasEnabledFlags= */ new boolean[renderers.length]);
} }
private void enablePlayingPeriodRenderers(boolean[] rendererWasEnabledFlags) private void enableRenderers(boolean[] rendererWasEnabledFlags) throws ExoPlaybackException {
throws ExoPlaybackException {
MediaPeriodHolder playingPeriodHolder = Assertions.checkNotNull(queue.getPlayingPeriod());
int enabledRendererCount = 0;
for (int i = 0; i < renderers.length; i++) {
if (playingPeriodHolder.getTrackSelectorResult().isRendererEnabled(i)) {
enabledRendererCount++;
}
}
enableRenderers(rendererWasEnabledFlags, enabledRendererCount);
}
private void enableRenderers(boolean[] rendererWasEnabledFlags, int totalEnabledRendererCount)
throws ExoPlaybackException {
enabledRenderers = new Renderer[totalEnabledRendererCount];
int enabledRendererCount = 0;
TrackSelectorResult trackSelectorResult = queue.getPlayingPeriod().getTrackSelectorResult(); TrackSelectorResult trackSelectorResult = queue.getPlayingPeriod().getTrackSelectorResult();
// Reset all disabled renderers before enabling any new ones. This makes sure resources released // Reset all disabled renderers before enabling any new ones. This makes sure resources released
// by the disabled renderers will be available to renderers that are being enabled. // by the disabled renderers will be available to renderers that are being enabled.
...@@ -2037,41 +2028,41 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -2037,41 +2028,41 @@ import java.util.concurrent.atomic.AtomicBoolean;
// Enable the renderers. // Enable the renderers.
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
if (trackSelectorResult.isRendererEnabled(i)) { if (trackSelectorResult.isRendererEnabled(i)) {
enableRenderer(i, rendererWasEnabledFlags[i], enabledRendererCount++); enableRenderer(i, rendererWasEnabledFlags[i]);
} }
} }
} }
private void enableRenderer( private void enableRenderer(int rendererIndex, boolean wasRendererEnabled)
int rendererIndex, boolean wasRendererEnabled, int enabledRendererIndex)
throws ExoPlaybackException { throws ExoPlaybackException {
MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
Renderer renderer = renderers[rendererIndex]; Renderer renderer = renderers[rendererIndex];
enabledRenderers[enabledRendererIndex] = renderer; if (isRendererEnabled(renderer)) {
if (renderer.getState() == Renderer.STATE_DISABLED) { return;
TrackSelectorResult trackSelectorResult = playingPeriodHolder.getTrackSelectorResult(); }
RendererConfiguration rendererConfiguration = MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
trackSelectorResult.rendererConfigurations[rendererIndex]; TrackSelectorResult trackSelectorResult = playingPeriodHolder.getTrackSelectorResult();
TrackSelection newSelection = trackSelectorResult.selections.get(rendererIndex); RendererConfiguration rendererConfiguration =
Format[] formats = getFormats(newSelection); trackSelectorResult.rendererConfigurations[rendererIndex];
// The renderer needs enabling with its new track selection. TrackSelection newSelection = trackSelectorResult.selections.get(rendererIndex);
boolean playing = shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY; Format[] formats = getFormats(newSelection);
// Consider as joining only if the renderer was previously disabled. // The renderer needs enabling with its new track selection.
boolean joining = !wasRendererEnabled && playing; boolean playing = shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY;
// Enable the renderer. // Consider as joining only if the renderer was previously disabled.
renderer.enable( boolean joining = !wasRendererEnabled && playing;
rendererConfiguration, // Enable the renderer.
formats, enabledRendererCount++;
playingPeriodHolder.sampleStreams[rendererIndex], renderer.enable(
rendererPositionUs, rendererConfiguration,
joining, formats,
/* mayRenderStartOfStream= */ true, playingPeriodHolder.sampleStreams[rendererIndex],
playingPeriodHolder.getRendererOffset()); rendererPositionUs,
mediaClock.onRendererEnabled(renderer); joining,
// Start the renderer if playing. /* mayRenderStartOfStream= */ true,
if (playing) { playingPeriodHolder.getRendererOffset());
renderer.start(); mediaClock.onRendererEnabled(renderer);
} // Start the renderer if playing.
if (playing) {
renderer.start();
} }
} }
...@@ -2508,6 +2499,10 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -2508,6 +2499,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
return formats; return formats;
} }
private static boolean isRendererEnabled(Renderer renderer) {
return renderer.getState() != Renderer.STATE_DISABLED;
}
private static final class SeekPosition { private static final class SeekPosition {
public final Timeline timeline; public final Timeline timeline;
......
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