Commit bf3816bd by krocard Committed by Ian Baker

Remove non Player use of TrackSelectionArray, use TrackSelection[]

This is necessary for the child cl that `TrackSelection`
in two distinct class. It avoids to split the array
version of such class too.

TrackSelectionArray exist to have an immutable array of TrackSelection.
Internal users are trusted to not mutate the array.

One drawback of this approach is that a `TrackSelectionArray`
has to be allocated on the boundary of the `Player` interface.
This should not be a performance issue as this only happens
on trackSelection changes, when the user calls
`Player.getCurrentTrackSelections` and on
`updateLoadControlTrackSelection`.

#player-to-common

PiperOrigin-RevId: 353582654
parent c5a81549
...@@ -138,8 +138,15 @@ import java.util.List; ...@@ -138,8 +138,15 @@ import java.util.List;
Clock clock, Clock clock,
Looper applicationLooper, Looper applicationLooper,
@Nullable Player wrappingPlayer) { @Nullable Player wrappingPlayer) {
Log.i(TAG, "Init " + Integer.toHexString(System.identityHashCode(this)) + " [" Log.i(
+ ExoPlayerLibraryInfo.VERSION_SLASHY + "] [" + Util.DEVICE_DEBUG_INFO + "]"); TAG,
"Init "
+ Integer.toHexString(System.identityHashCode(this))
+ " ["
+ ExoPlayerLibraryInfo.VERSION_SLASHY
+ "] ["
+ Util.DEVICE_DEBUG_INFO
+ "]");
checkState(renderers.length > 0); checkState(renderers.length > 0);
this.renderers = checkNotNull(renderers); this.renderers = checkNotNull(renderers);
this.trackSelector = checkNotNull(trackSelector); this.trackSelector = checkNotNull(trackSelector);
...@@ -731,9 +738,17 @@ import java.util.List; ...@@ -731,9 +738,17 @@ import java.util.List;
@Override @Override
public void release() { public void release() {
Log.i(TAG, "Release " + Integer.toHexString(System.identityHashCode(this)) + " [" Log.i(
+ ExoPlayerLibraryInfo.VERSION_SLASHY + "] [" + Util.DEVICE_DEBUG_INFO + "] [" TAG,
+ ExoPlayerLibraryInfo.registeredModules() + "]"); "Release "
+ Integer.toHexString(System.identityHashCode(this))
+ " ["
+ ExoPlayerLibraryInfo.VERSION_SLASHY
+ "] ["
+ Util.DEVICE_DEBUG_INFO
+ "] ["
+ ExoPlayerLibraryInfo.registeredModules()
+ "]");
if (!internalPlayer.release()) { if (!internalPlayer.release()) {
// One of the renderers timed out releasing its resources. // One of the renderers timed out releasing its resources.
listeners.sendEvent( listeners.sendEvent(
...@@ -890,7 +905,7 @@ import java.util.List; ...@@ -890,7 +905,7 @@ import java.util.List;
@Override @Override
public TrackSelectionArray getCurrentTrackSelections() { public TrackSelectionArray getCurrentTrackSelections() {
return playbackInfo.trackSelectorResult.selections; return new TrackSelectionArray(playbackInfo.trackSelectorResult.selections);
} }
@Override @Override
...@@ -1013,11 +1028,11 @@ import java.util.List; ...@@ -1013,11 +1028,11 @@ import java.util.List;
} }
if (previousPlaybackInfo.trackSelectorResult != newPlaybackInfo.trackSelectorResult) { if (previousPlaybackInfo.trackSelectorResult != newPlaybackInfo.trackSelectorResult) {
trackSelector.onSelectionActivated(newPlaybackInfo.trackSelectorResult.info); trackSelector.onSelectionActivated(newPlaybackInfo.trackSelectorResult.info);
TrackSelectionArray newSelection =
new TrackSelectionArray(newPlaybackInfo.trackSelectorResult.selections);
listeners.queueEvent( listeners.queueEvent(
Player.EVENT_TRACKS_CHANGED, Player.EVENT_TRACKS_CHANGED,
listener -> listener -> listener.onTracksChanged(newPlaybackInfo.trackGroups, newSelection));
listener.onTracksChanged(
newPlaybackInfo.trackGroups, newPlaybackInfo.trackSelectorResult.selections));
} }
if (!previousPlaybackInfo.staticMetadata.equals(newPlaybackInfo.staticMetadata)) { if (!previousPlaybackInfo.staticMetadata.equals(newPlaybackInfo.staticMetadata)) {
listeners.queueEvent( listeners.queueEvent(
......
...@@ -726,8 +726,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -726,8 +726,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void notifyTrackSelectionPlayWhenReadyChanged(boolean playWhenReady) { private void notifyTrackSelectionPlayWhenReadyChanged(boolean playWhenReady) {
MediaPeriodHolder periodHolder = queue.getPlayingPeriod(); MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
while (periodHolder != null) { while (periodHolder != null) {
TrackSelection[] trackSelections = periodHolder.getTrackSelectorResult().selections.getAll(); for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
for (TrackSelection trackSelection : trackSelections) {
if (trackSelection != null) { if (trackSelection != null) {
trackSelection.onPlayWhenReadyChanged(playWhenReady); trackSelection.onPlayWhenReadyChanged(playWhenReady);
} }
...@@ -901,8 +900,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -901,8 +900,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void notifyTrackSelectionRebuffer() { private void notifyTrackSelectionRebuffer() {
MediaPeriodHolder periodHolder = queue.getPlayingPeriod(); MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
while (periodHolder != null) { while (periodHolder != null) {
TrackSelection[] trackSelections = periodHolder.getTrackSelectorResult().selections.getAll(); for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
for (TrackSelection trackSelection : trackSelections) {
if (trackSelection != null) { if (trackSelection != null) {
trackSelection.onRebuffer(); trackSelection.onRebuffer();
} }
...@@ -1692,8 +1690,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1692,8 +1690,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void updateTrackSelectionPlaybackSpeed(float playbackSpeed) { private void updateTrackSelectionPlaybackSpeed(float playbackSpeed) {
MediaPeriodHolder periodHolder = queue.getPlayingPeriod(); MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
while (periodHolder != null) { while (periodHolder != null) {
TrackSelection[] trackSelections = periodHolder.getTrackSelectorResult().selections.getAll(); for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
for (TrackSelection trackSelection : trackSelections) {
if (trackSelection != null) { if (trackSelection != null) {
trackSelection.onPlaybackSpeed(playbackSpeed); trackSelection.onPlaybackSpeed(playbackSpeed);
} }
...@@ -1705,8 +1702,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1705,8 +1702,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void notifyTrackSelectionDiscontinuity() { private void notifyTrackSelectionDiscontinuity() {
MediaPeriodHolder periodHolder = queue.getPlayingPeriod(); MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
while (periodHolder != null) { while (periodHolder != null) {
TrackSelection[] trackSelections = periodHolder.getTrackSelectorResult().selections.getAll(); for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
for (TrackSelection trackSelection : trackSelections) {
if (trackSelection != null) { if (trackSelection != null) {
trackSelection.onDiscontinuity(); trackSelection.onDiscontinuity();
} }
...@@ -2018,7 +2014,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -2018,7 +2014,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
if (!renderer.isCurrentStreamFinal()) { if (!renderer.isCurrentStreamFinal()) {
// The renderer stream is not final, so we can replace the sample streams immediately. // The renderer stream is not final, so we can replace the sample streams immediately.
Format[] formats = getFormats(newTrackSelectorResult.selections.get(i)); Format[] formats = getFormats(newTrackSelectorResult.selections[i]);
renderer.replaceStream( renderer.replaceStream(
formats, formats,
readingPeriodHolder.sampleStreams[i], readingPeriodHolder.sampleStreams[i],
...@@ -2268,11 +2264,10 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -2268,11 +2264,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
private ImmutableList<Metadata> extractMetadataFromTrackSelectionArray( private ImmutableList<Metadata> extractMetadataFromTrackSelectionArray(
TrackSelectionArray trackSelectionArray) { TrackSelection[] trackSelections) {
ImmutableList.Builder<Metadata> result = new ImmutableList.Builder<>(); ImmutableList.Builder<Metadata> result = new ImmutableList.Builder<>();
boolean seenNonEmptyMetadata = false; boolean seenNonEmptyMetadata = false;
for (int i = 0; i < trackSelectionArray.length; i++) { for (TrackSelection trackSelection : trackSelections) {
@Nullable TrackSelection trackSelection = trackSelectionArray.get(i);
if (trackSelection != null) { if (trackSelection != null) {
Format format = trackSelection.getFormat(/* index= */ 0); Format format = trackSelection.getFormat(/* index= */ 0);
if (format.metadata == null) { if (format.metadata == null) {
...@@ -2320,7 +2315,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -2320,7 +2315,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
TrackSelectorResult trackSelectorResult = periodHolder.getTrackSelectorResult(); TrackSelectorResult trackSelectorResult = periodHolder.getTrackSelectorResult();
RendererConfiguration rendererConfiguration = RendererConfiguration rendererConfiguration =
trackSelectorResult.rendererConfigurations[rendererIndex]; trackSelectorResult.rendererConfigurations[rendererIndex];
TrackSelection newSelection = trackSelectorResult.selections.get(rendererIndex); TrackSelection newSelection = trackSelectorResult.selections[rendererIndex];
Format[] formats = getFormats(newSelection); Format[] formats = getFormats(newSelection);
// The renderer needs enabling with its new track selection. // The renderer needs enabling with its new track selection.
boolean playing = shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY; boolean playing = shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY;
...@@ -2401,7 +2396,8 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -2401,7 +2396,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void updateLoadControlTrackSelection( private void updateLoadControlTrackSelection(
TrackGroupArray trackGroups, TrackSelectorResult trackSelectorResult) { TrackGroupArray trackGroups, TrackSelectorResult trackSelectorResult) {
loadControl.onTracksSelected(renderers, trackGroups, trackSelectorResult.selections); TrackSelectionArray newSelection = new TrackSelectionArray(trackSelectorResult.selections);
loadControl.onTracksSelected(renderers, trackGroups, newSelection);
} }
private boolean shouldPlayWhenReady() { private boolean shouldPlayWhenReady() {
......
...@@ -25,7 +25,6 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; ...@@ -25,7 +25,6 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.SampleStream; import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectorResult; import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
...@@ -233,7 +232,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -233,7 +232,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
throws ExoPlaybackException { throws ExoPlaybackException {
TrackSelectorResult selectorResult = TrackSelectorResult selectorResult =
trackSelector.selectTracks(rendererCapabilities, getTrackGroups(), info.id, timeline); trackSelector.selectTracks(rendererCapabilities, getTrackGroups(), info.id, timeline);
for (TrackSelection trackSelection : selectorResult.selections.getAll()) { for (TrackSelection trackSelection : selectorResult.selections) {
if (trackSelection != null) { if (trackSelection != null) {
trackSelection.onPlaybackSpeed(playbackSpeed); trackSelection.onPlaybackSpeed(playbackSpeed);
} }
...@@ -289,10 +288,9 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -289,10 +288,9 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
trackSelectorResult = newTrackSelectorResult; trackSelectorResult = newTrackSelectorResult;
enableTrackSelectionsInResult(); enableTrackSelectionsInResult();
// Disable streams on the period and get new streams for updated/newly-enabled tracks. // Disable streams on the period and get new streams for updated/newly-enabled tracks.
TrackSelectionArray trackSelections = newTrackSelectorResult.selections;
positionUs = positionUs =
mediaPeriod.selectTracks( mediaPeriod.selectTracks(
trackSelections.getAll(), newTrackSelectorResult.selections,
mayRetainStreamFlags, mayRetainStreamFlags,
sampleStreams, sampleStreams,
streamResetFlags, streamResetFlags,
...@@ -309,7 +307,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -309,7 +307,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
hasEnabledTracks = true; hasEnabledTracks = true;
} }
} else { } else {
Assertions.checkState(trackSelections.get(i) == null); Assertions.checkState(newTrackSelectorResult.selections[i] == null);
} }
} }
return positionUs; return positionUs;
...@@ -361,7 +359,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -361,7 +359,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} }
for (int i = 0; i < trackSelectorResult.length; i++) { for (int i = 0; i < trackSelectorResult.length; i++) {
boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i); boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i);
TrackSelection trackSelection = trackSelectorResult.selections.get(i); TrackSelection trackSelection = trackSelectorResult.selections[i];
if (rendererEnabled && trackSelection != null) { if (rendererEnabled && trackSelection != null) {
trackSelection.enable(); trackSelection.enable();
} }
...@@ -374,7 +372,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -374,7 +372,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} }
for (int i = 0; i < trackSelectorResult.length; i++) { for (int i = 0; i < trackSelectorResult.length; i++) {
boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i); boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i);
TrackSelection trackSelection = trackSelectorResult.selections.get(i); TrackSelection trackSelection = trackSelectorResult.selections[i];
if (rendererEnabled && trackSelection != null) { if (rendererEnabled && trackSelection != null) {
trackSelection.disable(); trackSelection.disable();
} }
......
...@@ -847,7 +847,7 @@ public final class DownloadHelper { ...@@ -847,7 +847,7 @@ public final class DownloadHelper {
new MediaPeriodId(mediaPreparer.timeline.getUidOfPeriod(periodIndex)), new MediaPeriodId(mediaPreparer.timeline.getUidOfPeriod(periodIndex)),
mediaPreparer.timeline); mediaPreparer.timeline);
for (int i = 0; i < trackSelectorResult.length; i++) { for (int i = 0; i < trackSelectorResult.length; i++) {
@Nullable TrackSelection newSelection = trackSelectorResult.selections.get(i); @Nullable TrackSelection newSelection = trackSelectorResult.selections[i];
if (newSelection == null) { if (newSelection == null) {
continue; continue;
} }
......
...@@ -20,9 +20,7 @@ import com.google.android.exoplayer2.RendererConfiguration; ...@@ -20,9 +20,7 @@ import com.google.android.exoplayer2.RendererConfiguration;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import org.checkerframework.checker.nullness.compatqual.NullableType; import org.checkerframework.checker.nullness.compatqual.NullableType;
/** /** The result of a {@link TrackSelector} operation. */
* The result of a {@link TrackSelector} operation.
*/
public final class TrackSelectorResult { public final class TrackSelectorResult {
/** The number of selections in the result. Greater than or equal to zero. */ /** The number of selections in the result. Greater than or equal to zero. */
...@@ -32,10 +30,8 @@ public final class TrackSelectorResult { ...@@ -32,10 +30,8 @@ public final class TrackSelectorResult {
* renderer should be disabled. * renderer should be disabled.
*/ */
public final @NullableType RendererConfiguration[] rendererConfigurations; public final @NullableType RendererConfiguration[] rendererConfigurations;
/** /** A {@link TrackSelection} array containing the track selection for each renderer. */
* A {@link TrackSelectionArray} containing the track selection for each renderer. public final @NullableType TrackSelection[] selections;
*/
public final TrackSelectionArray selections;
/** /**
* An opaque object that will be returned to {@link TrackSelector#onSelectionActivated(Object)} * An opaque object that will be returned to {@link TrackSelector#onSelectionActivated(Object)}
* should the selections be activated. * should the selections be activated.
...@@ -45,7 +41,7 @@ public final class TrackSelectorResult { ...@@ -45,7 +41,7 @@ public final class TrackSelectorResult {
/** /**
* @param rendererConfigurations A {@link RendererConfiguration} for each renderer. A null entry * @param rendererConfigurations A {@link RendererConfiguration} for each renderer. A null entry
* indicates the corresponding renderer should be disabled. * indicates the corresponding renderer should be disabled.
* @param selections A {@link TrackSelectionArray} containing the selection for each renderer. * @param selections A {@link TrackSelection} array containing the selection for each renderer.
* @param info An opaque object that will be returned to {@link * @param info An opaque object that will be returned to {@link
* TrackSelector#onSelectionActivated(Object)} should the selection be activated. May be * TrackSelector#onSelectionActivated(Object)} should the selection be activated. May be
* {@code null}. * {@code null}.
...@@ -55,7 +51,7 @@ public final class TrackSelectorResult { ...@@ -55,7 +51,7 @@ public final class TrackSelectorResult {
@NullableType TrackSelection[] selections, @NullableType TrackSelection[] selections,
@Nullable Object info) { @Nullable Object info) {
this.rendererConfigurations = rendererConfigurations; this.rendererConfigurations = rendererConfigurations;
this.selections = new TrackSelectionArray(selections); this.selections = selections.clone();
this.info = info; this.info = info;
length = rendererConfigurations.length; length = rendererConfigurations.length;
} }
...@@ -100,7 +96,6 @@ public final class TrackSelectorResult { ...@@ -100,7 +96,6 @@ public final class TrackSelectorResult {
return false; return false;
} }
return Util.areEqual(rendererConfigurations[index], other.rendererConfigurations[index]) return Util.areEqual(rendererConfigurations[index], other.rendererConfigurations[index])
&& Util.areEqual(selections.get(index), other.selections.get(index)); && Util.areEqual(selections[index], other.selections[index]);
} }
} }
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