diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index e33b7358a4..daabbd5a72 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -92,10 +92,9 @@ import java.util.concurrent.CopyOnWriteArraySet; this.listeners = new CopyOnWriteArraySet<>(); emptyTrackSelectorResult = new TrackSelectorResult( - new boolean[renderers.length], - new TrackSelectionArray(new TrackSelection[renderers.length]), - null, - new RendererConfiguration[renderers.length]); + new RendererConfiguration[renderers.length], + new TrackSelection[renderers.length], + null); window = new Timeline.Window(); period = new Timeline.Period(); playbackParameters = PlaybackParameters.DEFAULT; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java index a937aa1185..ceee25af82 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java @@ -1438,7 +1438,7 @@ import java.util.Collections; readingPeriodHolder.mediaPeriod.readDiscontinuity() != C.TIME_UNSET; for (int i = 0; i < renderers.length; i++) { Renderer renderer = renderers[i]; - boolean rendererWasEnabled = oldTrackSelectorResult.renderersEnabled[i]; + boolean rendererWasEnabled = oldTrackSelectorResult.isRendererEnabled(i); if (!rendererWasEnabled) { // The renderer was disabled and will be enabled when we play the next period. } else if (initialDiscontinuity) { @@ -1447,7 +1447,7 @@ import java.util.Collections; renderer.setCurrentStreamFinal(); } else if (!renderer.isCurrentStreamFinal()) { TrackSelection newSelection = newTrackSelectorResult.selections.get(i); - boolean newRendererEnabled = newTrackSelectorResult.renderersEnabled[i]; + boolean newRendererEnabled = newTrackSelectorResult.isRendererEnabled(i); boolean isNoSampleRenderer = rendererCapabilities[i].getTrackType() == C.TRACK_TYPE_NONE; RendererConfiguration oldConfig = oldTrackSelectorResult.rendererConfigurations[i]; RendererConfiguration newConfig = newTrackSelectorResult.rendererConfigurations[i]; @@ -1551,11 +1551,11 @@ import java.util.Collections; for (int i = 0; i < renderers.length; i++) { Renderer renderer = renderers[i]; rendererWasEnabledFlags[i] = renderer.getState() != Renderer.STATE_DISABLED; - if (newPlayingPeriodHolder.trackSelectorResult.renderersEnabled[i]) { + if (newPlayingPeriodHolder.trackSelectorResult.isRendererEnabled(i)) { enabledRendererCount++; } if (rendererWasEnabledFlags[i] - && (!newPlayingPeriodHolder.trackSelectorResult.renderersEnabled[i] + && (!newPlayingPeriodHolder.trackSelectorResult.isRendererEnabled(i) || (renderer.isCurrentStreamFinal() && renderer.getStream() == oldPlayingPeriodHolder.sampleStreams[i]))) { // The renderer should be disabled before playing the next period, either because it's not @@ -1576,7 +1576,7 @@ import java.util.Collections; int enabledRendererCount = 0; MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod(); for (int i = 0; i < renderers.length; i++) { - if (playingPeriodHolder.trackSelectorResult.renderersEnabled[i]) { + if (playingPeriodHolder.trackSelectorResult.isRendererEnabled(i)) { enableRenderer(i, rendererWasEnabledFlags[i], enabledRendererCount++); } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodHolder.java b/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodHolder.java index 94614a372a..2f71d0d547 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodHolder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/MediaPeriodHolder.java @@ -179,8 +179,7 @@ import com.google.android.exoplayer2.util.Assertions; public long applyTrackSelection( long positionUs, boolean forceRecreateStreams, boolean[] streamResetFlags) { - TrackSelectionArray trackSelections = trackSelectorResult.selections; - for (int i = 0; i < trackSelections.length; i++) { + for (int i = 0; i < trackSelectorResult.length; i++) { mayRetainStreamFlags[i] = !forceRecreateStreams && trackSelectorResult.isEquivalent(periodTrackSelectorResult, i); } @@ -190,6 +189,7 @@ import com.google.android.exoplayer2.util.Assertions; disassociateNoSampleRenderersWithEmptySampleStream(sampleStreams); updatePeriodTrackSelectorResult(trackSelectorResult); // Disable streams on the period and get new streams for updated/newly-enabled tracks. + TrackSelectionArray trackSelections = trackSelectorResult.selections; positionUs = mediaPeriod.selectTracks( trackSelections.getAll(), @@ -203,7 +203,7 @@ import com.google.android.exoplayer2.util.Assertions; hasEnabledTracks = false; for (int i = 0; i < sampleStreams.length; i++) { if (sampleStreams[i] != null) { - Assertions.checkState(trackSelectorResult.renderersEnabled[i]); + Assertions.checkState(trackSelectorResult.isRendererEnabled(i)); // hasEnabledTracks should be true only when non-empty streams exists. if (rendererCapabilities[i].getTrackType() != C.TRACK_TYPE_NONE) { hasEnabledTracks = true; @@ -240,8 +240,8 @@ import com.google.android.exoplayer2.util.Assertions; } private void enableTrackSelectionsInResult(TrackSelectorResult trackSelectorResult) { - for (int i = 0; i < trackSelectorResult.renderersEnabled.length; i++) { - boolean rendererEnabled = trackSelectorResult.renderersEnabled[i]; + for (int i = 0; i < trackSelectorResult.length; i++) { + boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i); TrackSelection trackSelection = trackSelectorResult.selections.get(i); if (rendererEnabled && trackSelection != null) { trackSelection.enable(); @@ -250,8 +250,8 @@ import com.google.android.exoplayer2.util.Assertions; } private void disableTrackSelectionsInResult(TrackSelectorResult trackSelectorResult) { - for (int i = 0; i < trackSelectorResult.renderersEnabled.length; i++) { - boolean rendererEnabled = trackSelectorResult.renderersEnabled[i]; + for (int i = 0; i < trackSelectorResult.length; i++) { + boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i); TrackSelection trackSelection = trackSelectorResult.selections.get(i); if (rendererEnabled && trackSelection != null) { trackSelection.disable(); @@ -278,7 +278,7 @@ import com.google.android.exoplayer2.util.Assertions; private void associateNoSampleRenderersWithEmptySampleStream(SampleStream[] sampleStreams) { for (int i = 0; i < rendererCapabilities.length; i++) { if (rendererCapabilities[i].getTrackType() == C.TRACK_TYPE_NONE - && trackSelectorResult.renderersEnabled[i]) { + && trackSelectorResult.isRendererEnabled(i)) { sampleStreams[i] = new EmptySampleStream(); } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java index 9fc8f50f97..abb72b5cb1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/MappingTrackSelector.java @@ -597,11 +597,7 @@ public abstract class MappingTrackSelector extends TrackSelector { maybeConfigureRenderersForTunneling(rendererCapabilities, rendererTrackGroupArrays, rendererFormatSupports, rendererConfigurations, trackSelections, tunnelingAudioSessionId); - return new TrackSelectorResult( - rendererEnabled, - new TrackSelectionArray(trackSelections), - mappedTrackInfo, - rendererConfigurations); + return new TrackSelectorResult(rendererConfigurations, trackSelections, mappedTrackInfo); } private boolean[] determineEnabledRenderers(RendererCapabilities[] rendererCapabilities, diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionArray.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionArray.java index 809e571f10..2d457750e4 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionArray.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionArray.java @@ -17,14 +17,10 @@ package com.google.android.exoplayer2.trackselection; import java.util.Arrays; -/** - * The result of a {@link TrackSelector} operation. - */ +/** An array of {@link TrackSelection}s. */ public final class TrackSelectionArray { - /** - * The number of selections in the result. Greater than or equal to zero. - */ + /** The length of this array. */ public final int length; private final TrackSelection[] trackSelections; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java index 82b5d9e7c9..882d98764e 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectorResult.java @@ -23,10 +23,13 @@ import com.google.android.exoplayer2.util.Util; */ public final class TrackSelectorResult { + /** The number of selections in the result. Greater than or equal to zero. */ + public final int length; /** - * An array containing whether each renderer is enabled after the track selection operation. + * A {@link RendererConfiguration} for each renderer. A null entry indicates the corresponding + * renderer should be disabled. */ - public final boolean[] renderersEnabled; + public final RendererConfiguration[] rendererConfigurations; /** * A {@link TrackSelectionArray} containing the track selection for each renderer. */ @@ -36,29 +39,25 @@ public final class TrackSelectorResult { * should the selections be activated. */ public final Object info; - /** - * A {@link RendererConfiguration} for each enabled renderer, to be used with the selections. - */ - public final RendererConfiguration[] rendererConfigurations; /** - * @param renderersEnabled An array containing whether each renderer is enabled after the track - * selection operation. + * @param rendererConfigurations A {@link RendererConfiguration} for each renderer. A null entry + * indicates the corresponding renderer should be disabled. * @param selections A {@link TrackSelectionArray} containing the selection for each renderer. * @param info An opaque object that will be returned to {@link * TrackSelector#onSelectionActivated(Object)} should the selection be activated. - * @param rendererConfigurations A {@link RendererConfiguration} for each enabled renderer, to be - * used with the selections. */ public TrackSelectorResult( - boolean[] renderersEnabled, - TrackSelectionArray selections, - Object info, - RendererConfiguration[] rendererConfigurations) { - this.renderersEnabled = renderersEnabled; - this.selections = selections; - this.info = info; + RendererConfiguration[] rendererConfigurations, TrackSelection[] selections, Object info) { this.rendererConfigurations = rendererConfigurations; + this.selections = new TrackSelectionArray(selections); + this.info = info; + length = rendererConfigurations.length; + } + + /** Returns whether the renderer at the specified index is enabled. */ + public boolean isRendererEnabled(int index) { + return rendererConfigurations[index] != null; } /** @@ -95,9 +94,8 @@ public final class TrackSelectorResult { if (other == null) { return false; } - return renderersEnabled[index] == other.renderersEnabled[index] - && Util.areEqual(selections.get(index), other.selections.get(index)) - && Util.areEqual(rendererConfigurations[index], other.rendererConfigurations[index]); + return Util.areEqual(rendererConfigurations[index], other.rendererConfigurations[index]) + && Util.areEqual(selections.get(index), other.selections.get(index)); } } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/MappingTrackSelectorTest.java b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/MappingTrackSelectorTest.java index b80110365c..d20b5669c4 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/MappingTrackSelectorTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/MappingTrackSelectorTest.java @@ -121,11 +121,9 @@ public final class MappingTrackSelectorTest { FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector( TRACK_SELECTIONS); TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS); - assertThat(result.selections.get(0)).isEqualTo(TRACK_SELECTIONS[0]); - assertThat(result.selections.get(1)).isEqualTo(TRACK_SELECTIONS[1]); - assertThat(new boolean[] {true, true}).isEqualTo(result.renderersEnabled); - assertThat(new RendererConfiguration[] {DEFAULT, DEFAULT}) - .isEqualTo(result.rendererConfigurations); + assertTrackSelections(result, TRACK_SELECTIONS); + assertThat(result.rendererConfigurations) + .isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT}); } /** @@ -137,11 +135,9 @@ public final class MappingTrackSelectorTest { TRACK_SELECTIONS); trackSelector.setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP), null); TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS); - assertThat(result.selections.get(0)).isNull(); - assertThat(result.selections.get(1)).isEqualTo(TRACK_SELECTIONS[1]); - assertThat(new boolean[] {false, true}).isEqualTo(result.renderersEnabled); - assertThat(new RendererConfiguration[] {null, DEFAULT}) - .isEqualTo(result.rendererConfigurations); + assertTrackSelections(result, new TrackSelection[] {null, TRACK_SELECTIONS[1]}); + assertThat(result.rendererConfigurations) + .isEqualTo(new RendererConfiguration[] {null, DEFAULT}); } /** @@ -154,11 +150,9 @@ public final class MappingTrackSelectorTest { trackSelector.setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP), null); trackSelector.clearSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP)); TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS); - assertThat(result.selections.get(0)).isEqualTo(TRACK_SELECTIONS[0]); - assertThat(result.selections.get(1)).isEqualTo(TRACK_SELECTIONS[1]); - assertThat(new boolean[] {true, true}).isEqualTo(result.renderersEnabled); - assertThat(new RendererConfiguration[] {DEFAULT, DEFAULT}) - .isEqualTo(result.rendererConfigurations); + assertTrackSelections(result, TRACK_SELECTIONS); + assertThat(result.rendererConfigurations) + .isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT}); } /** @@ -171,11 +165,9 @@ public final class MappingTrackSelectorTest { trackSelector.setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP), null); TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP, VIDEO_TRACK_GROUP)); - assertThat(result.selections.get(0)).isEqualTo(TRACK_SELECTIONS[0]); - assertThat(result.selections.get(1)).isEqualTo(TRACK_SELECTIONS[1]); - assertThat(new boolean[] {true, true}).isEqualTo(result.renderersEnabled); - assertThat(new RendererConfiguration[] {DEFAULT, DEFAULT}) - .isEqualTo(result.rendererConfigurations); + assertTrackSelections(result, TRACK_SELECTIONS); + assertThat(result.rendererConfigurations) + .isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT}); } /** @@ -186,16 +178,13 @@ public final class MappingTrackSelectorTest { */ @Test public void testSelectTracksWithNoSampleRenderer() throws ExoPlaybackException { - TrackSelection[] expectedTrackSelection = TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER; - FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(expectedTrackSelection); + FakeMappingTrackSelector trackSelector = + new FakeMappingTrackSelector(TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER); TrackSelectorResult result = trackSelector.selectTracks( RENDERER_CAPABILITIES_WITH_NO_SAMPLE_RENDERER, TRACK_GROUPS); - assertThat(result.selections.get(0)).isEqualTo(expectedTrackSelection[0]); - assertThat(result.selections.get(1)).isEqualTo(expectedTrackSelection[1]); - assertThat(result.selections.get(2)).isNull(); - assertThat(new boolean[] {true, true, true}).isEqualTo(result.renderersEnabled); - assertThat(new RendererConfiguration[] {DEFAULT, DEFAULT, DEFAULT}) - .isEqualTo(result.rendererConfigurations); + assertTrackSelections(result, TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER); + assertThat(result.rendererConfigurations) + .isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT, DEFAULT}); } /** @@ -211,9 +200,8 @@ public final class MappingTrackSelectorTest { assertThat(result.selections.get(0)).isNull(); assertThat(result.selections.get(1)).isEqualTo(expectedTrackSelection[1]); assertThat(result.selections.get(2)).isNull(); - assertThat(new boolean[] {false, true, true}).isEqualTo(result.renderersEnabled); - assertThat(new RendererConfiguration[] {null, DEFAULT, DEFAULT}) - .isEqualTo(result.rendererConfigurations); + assertThat(result.rendererConfigurations) + .isEqualTo(new RendererConfiguration[] {null, DEFAULT, DEFAULT}); } /** @@ -222,18 +210,15 @@ public final class MappingTrackSelectorTest { @Test public void testSelectTracksWithNoSampleRendererWithClearedNullOverride() throws ExoPlaybackException { - TrackSelection[] expectedTrackSelection = TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER; - FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(expectedTrackSelection); + FakeMappingTrackSelector trackSelector = + new FakeMappingTrackSelector(TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER); trackSelector.setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP), null); trackSelector.clearSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP)); TrackSelectorResult result = trackSelector.selectTracks( RENDERER_CAPABILITIES_WITH_NO_SAMPLE_RENDERER, TRACK_GROUPS); - assertThat(result.selections.get(0)).isEqualTo(expectedTrackSelection[0]); - assertThat(result.selections.get(1)).isEqualTo(expectedTrackSelection[1]); - assertThat(result.selections.get(2)).isNull(); - assertThat(new boolean[] {true, true, true}).isEqualTo(result.renderersEnabled); - assertThat(new RendererConfiguration[] {DEFAULT, DEFAULT, DEFAULT}) - .isEqualTo(result.rendererConfigurations); + assertTrackSelections(result, TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER); + assertThat(result.rendererConfigurations) + .isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT, DEFAULT}); } /** @@ -249,12 +234,9 @@ public final class MappingTrackSelectorTest { TrackSelectorResult result = trackSelector.selectTracks( RENDERER_CAPABILITIES_WITH_NO_SAMPLE_RENDERER, new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP, VIDEO_TRACK_GROUP)); - assertThat(result.selections.get(0)).isEqualTo(expectedTrackSelection[0]); - assertThat(result.selections.get(1)).isEqualTo(expectedTrackSelection[1]); - assertThat(result.selections.get(2)).isNull(); - assertThat(new boolean[] {true, true, true}).isEqualTo(result.renderersEnabled); - assertThat(new RendererConfiguration[] {DEFAULT, DEFAULT, DEFAULT}) - .isEqualTo(result.rendererConfigurations); + assertTrackSelections(result, TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER); + assertThat(result.rendererConfigurations) + .isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT, DEFAULT}); } /** @@ -263,15 +245,13 @@ public final class MappingTrackSelectorTest { @Test public void testSelectTracksDisablingNormalRendererWithNoSampleRenderer() throws ExoPlaybackException { - TrackSelection[] expectedTrackSelection = TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER; - FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(expectedTrackSelection); + FakeMappingTrackSelector trackSelector = + new FakeMappingTrackSelector(TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER); trackSelector.setRendererDisabled(0, true); TrackSelectorResult result = trackSelector.selectTracks( RENDERER_CAPABILITIES_WITH_NO_SAMPLE_RENDERER, TRACK_GROUPS); - assertThat(result.selections.get(0)).isNull(); - assertThat(result.selections.get(1)).isEqualTo(expectedTrackSelection[1]); - assertThat(result.selections.get(2)).isNull(); - assertThat(new boolean[] {false, true, true}).isEqualTo(result.renderersEnabled); + assertTrackSelections( + result, new TrackSelection[] {null, TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER[1], null}); assertThat(new RendererConfiguration[] {null, DEFAULT, DEFAULT}) .isEqualTo(result.rendererConfigurations); } @@ -290,11 +270,17 @@ public final class MappingTrackSelectorTest { assertThat(result.selections.get(0)).isEqualTo(expectedTrackSelection[0]); assertThat(result.selections.get(1)).isEqualTo(expectedTrackSelection[1]); assertThat(result.selections.get(2)).isNull(); - assertThat(new boolean[] {true, true, false}).isEqualTo(result.renderersEnabled); assertThat(new RendererConfiguration[] {DEFAULT, DEFAULT, null}) .isEqualTo(result.rendererConfigurations); } + private static void assertTrackSelections(TrackSelectorResult result, TrackSelection[] expected) { + assertThat(result.length).isEqualTo(expected.length); + for (int i = 0; i < expected.length; i++) { + assertThat(result.selections.get(i)).isEqualTo(expected[i]); + } + } + /** * A {@link MappingTrackSelector} that returns a fixed result from * {@link #selectTracks(RendererCapabilities[], TrackGroupArray[], int[][][])}.