Add TrackSelection.Factory createTrackSelections

createTrackSelections decides whether to create an adaptive or a fixed track seletion to create.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=222231011
This commit is contained in:
eguven 2018-11-20 05:32:51 -08:00 committed by Oliver Woodman
parent 55cc0df558
commit 527f2cf730
5 changed files with 196 additions and 136 deletions

View File

@ -1006,8 +1006,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param groups The {@link TrackGroupArray}.
* @return The override, or null if no override exists.
*/
public final @Nullable SelectionOverride getSelectionOverride(
int rendererIndex, TrackGroupArray groups) {
@Nullable
public final SelectionOverride getSelectionOverride(int rendererIndex, TrackGroupArray groups) {
Map<TrackGroupArray, SelectionOverride> overrides = selectionOverrides.get(rendererIndex);
return overrides != null ? overrides.get(groups) : null;
}
@ -1327,10 +1327,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static final int[] NO_TRACKS = new int[0];
private static final int WITHIN_RENDERER_CAPABILITIES_BONUS = 1000;
private final TrackSelection.Factory adaptiveTrackSelectionFactory;
private final TrackSelection.Factory trackSelectionFactory;
private final AtomicReference<Parameters> parametersReference;
/** Constructs an instance that uses a default factory to create adaptive track selections. */
public DefaultTrackSelector() {
this(new AdaptiveTrackSelection.Factory());
}
@ -1345,13 +1344,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
this(new AdaptiveTrackSelection.Factory(bandwidthMeter));
}
/**
* Constructs an instance that uses a factory to create adaptive track selections.
*
* @param adaptiveTrackSelectionFactory A factory for adaptive {@link TrackSelection}s.
*/
public DefaultTrackSelector(TrackSelection.Factory adaptiveTrackSelectionFactory) {
this.adaptiveTrackSelectionFactory = adaptiveTrackSelectionFactory;
/** @param trackSelectionFactory A factory for {@link TrackSelection}s. */
public DefaultTrackSelector(TrackSelection.Factory trackSelectionFactory) {
this.trackSelectionFactory = trackSelectionFactory;
parametersReference = new AtomicReference<>(Parameters.DEFAULT);
}
@ -1420,8 +1415,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/** @deprecated Use {@link Parameters#getSelectionOverride(int, TrackGroupArray)}. */
@Deprecated
public final @Nullable SelectionOverride getSelectionOverride(
int rendererIndex, TrackGroupArray groups) {
@Nullable
public final SelectionOverride getSelectionOverride(int rendererIndex, TrackGroupArray groups) {
return getParameters().getSelectionOverride(rendererIndex, groups);
}
@ -1460,7 +1455,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
throws ExoPlaybackException {
Parameters params = parametersReference.get();
int rendererCount = mappedTrackInfo.getRendererCount();
@NullableType TrackSelection[] rendererTrackSelections =
TrackSelection.@NullableType Definition[] definitions =
selectAllTracks(
mappedTrackInfo,
rendererFormatSupports,
@ -1470,28 +1465,24 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// Apply track disabling and overriding.
for (int i = 0; i < rendererCount; i++) {
if (params.getRendererDisabled(i)) {
rendererTrackSelections[i] = null;
} else {
definitions[i] = null;
continue;
}
TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(i);
if (params.hasSelectionOverride(i, rendererTrackGroups)) {
SelectionOverride override = params.getSelectionOverride(i, rendererTrackGroups);
if (override == null) {
rendererTrackSelections[i] = null;
} else if (override.length == 1) {
rendererTrackSelections[i] =
new FixedTrackSelection(
rendererTrackGroups.get(override.groupIndex), override.tracks[0]);
} else {
rendererTrackSelections[i] =
adaptiveTrackSelectionFactory.createTrackSelection(
rendererTrackGroups.get(override.groupIndex),
getBandwidthMeter(),
override.tracks);
}
}
definitions[i] =
override == null
? null
: new TrackSelection.Definition(
rendererTrackGroups.get(override.groupIndex), override.tracks);
}
}
@NullableType
TrackSelection[] rendererTrackSelections =
trackSelectionFactory.createTrackSelections(definitions, getBandwidthMeter());
// Initialize the renderer configurations to the default configuration for all renderers with
// selections, and null otherwise.
@NullableType RendererConfiguration[] rendererConfigurations =
@ -1530,32 +1521,33 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* each mapped track, indexed by renderer, track group and track (in that order).
* @param rendererMixedMimeTypeAdaptationSupports The result of {@link
* RendererCapabilities#supportsMixedMimeTypeAdaptation()} for each renderer.
* @return Track selections for each renderer. A null selection indicates the renderer should be
* disabled, unless RendererCapabilities#getTrackType()} is {@link C#TRACK_TYPE_NONE}.
* @return The {@link TrackSelection.Definition}s for the renderers. A null entry indicates no
* selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/
protected @NullableType TrackSelection[] selectAllTracks(
protected TrackSelection.@NullableType Definition[] selectAllTracks(
MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupports,
Parameters params)
throws ExoPlaybackException {
int rendererCount = mappedTrackInfo.getRendererCount();
@NullableType TrackSelection[] rendererTrackSelections = new TrackSelection[rendererCount];
TrackSelection.@NullableType Definition[] definitions =
new TrackSelection.Definition[rendererCount];
boolean seenVideoRendererWithMappedTracks = false;
boolean selectedVideoTracks = false;
for (int i = 0; i < rendererCount; i++) {
if (C.TRACK_TYPE_VIDEO == mappedTrackInfo.getRendererType(i)) {
if (!selectedVideoTracks) {
rendererTrackSelections[i] =
definitions[i] =
selectVideoTrack(
mappedTrackInfo.getTrackGroups(i),
rendererFormatSupports[i],
rendererMixedMimeTypeAdaptationSupports[i],
params,
adaptiveTrackSelectionFactory);
selectedVideoTracks = rendererTrackSelections[i] != null;
/* enableAdaptiveTrackSelection= */ true);
selectedVideoTracks = definitions[i] != null;
}
seenVideoRendererWithMappedTracks |= mappedTrackInfo.getTrackGroups(i).length > 0;
}
@ -1572,49 +1564,49 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// Already done. Do nothing.
break;
case C.TRACK_TYPE_AUDIO:
Pair<TrackSelection, AudioTrackScore> audioSelection =
Pair<TrackSelection.Definition, AudioTrackScore> audioSelection =
selectAudioTrack(
mappedTrackInfo.getTrackGroups(i),
rendererFormatSupports[i],
rendererMixedMimeTypeAdaptationSupports[i],
params,
seenVideoRendererWithMappedTracks ? null : adaptiveTrackSelectionFactory);
!seenVideoRendererWithMappedTracks);
if (audioSelection != null
&& (selectedAudioTrackScore == null
|| audioSelection.second.compareTo(selectedAudioTrackScore) > 0)) {
if (selectedAudioRendererIndex != C.INDEX_UNSET) {
// We've already made a selection for another audio renderer, but it had a lower
// score. Clear the selection for that renderer.
rendererTrackSelections[selectedAudioRendererIndex] = null;
definitions[selectedAudioRendererIndex] = null;
}
rendererTrackSelections[i] = audioSelection.first;
definitions[i] = audioSelection.first;
selectedAudioTrackScore = audioSelection.second;
selectedAudioRendererIndex = i;
}
break;
case C.TRACK_TYPE_TEXT:
Pair<TrackSelection, Integer> textSelection =
Pair<TrackSelection.Definition, Integer> textSelection =
selectTextTrack(mappedTrackInfo.getTrackGroups(i), rendererFormatSupports[i], params);
if (textSelection != null && textSelection.second > selectedTextTrackScore) {
if (selectedTextRendererIndex != C.INDEX_UNSET) {
// We've already made a selection for another text renderer, but it had a lower score.
// Clear the selection for that renderer.
rendererTrackSelections[selectedTextRendererIndex] = null;
definitions[selectedTextRendererIndex] = null;
}
rendererTrackSelections[i] = textSelection.first;
definitions[i] = textSelection.first;
selectedTextTrackScore = textSelection.second;
selectedTextRendererIndex = i;
}
break;
default:
rendererTrackSelections[i] =
definitions[i] =
selectOtherTrack(
trackType, mappedTrackInfo.getTrackGroups(i), rendererFormatSupports[i], params);
break;
}
}
return rendererTrackSelections;
return definitions;
}
// Video track selection implementation.
@ -1629,45 +1621,38 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param mixedMimeTypeAdaptationSupports The result of {@link
* RendererCapabilities#supportsMixedMimeTypeAdaptation()} for the renderer.
* @param params The selector's current constraint parameters.
* @param adaptiveTrackSelectionFactory A factory for generating adaptive track selections, or
* null if a fixed track selection is required.
* @return The {@link TrackSelection} for the renderer, or null if no selection was made.
* @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed.
* @return The {@link TrackSelection.Definition} for the renderer, or null if no selection was
* made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/
protected @Nullable TrackSelection selectVideoTrack(
@Nullable
protected TrackSelection.Definition selectVideoTrack(
TrackGroupArray groups,
int[][] formatSupports,
int mixedMimeTypeAdaptationSupports,
Parameters params,
@Nullable TrackSelection.Factory adaptiveTrackSelectionFactory)
boolean enableAdaptiveTrackSelection)
throws ExoPlaybackException {
TrackSelection selection = null;
TrackSelection.Definition definition = null;
if (!params.forceHighestSupportedBitrate
&& !params.forceLowestBitrate
&& adaptiveTrackSelectionFactory != null) {
selection =
selectAdaptiveVideoTrack(
groups,
formatSupports,
mixedMimeTypeAdaptationSupports,
params,
adaptiveTrackSelectionFactory,
getBandwidthMeter());
&& enableAdaptiveTrackSelection) {
definition =
selectAdaptiveVideoTrack(groups, formatSupports, mixedMimeTypeAdaptationSupports, params);
}
if (selection == null) {
selection = selectFixedVideoTrack(groups, formatSupports, params);
if (definition == null) {
definition = selectFixedVideoTrack(groups, formatSupports, params);
}
return selection;
return definition;
}
private static @Nullable TrackSelection selectAdaptiveVideoTrack(
@Nullable
private static TrackSelection.Definition selectAdaptiveVideoTrack(
TrackGroupArray groups,
int[][] formatSupport,
int mixedMimeTypeAdaptationSupports,
Parameters params,
TrackSelection.Factory adaptiveTrackSelectionFactory,
BandwidthMeter bandwidthMeter)
throws ExoPlaybackException {
Parameters params) {
int requiredAdaptiveSupport =
params.allowVideoNonSeamlessAdaptiveness
? (RendererCapabilities.ADAPTIVE_NOT_SEAMLESS | RendererCapabilities.ADAPTIVE_SEAMLESS)
@ -1691,8 +1676,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
params.viewportHeight,
params.viewportOrientationMayChange);
if (adaptiveTracks.length > 0) {
return adaptiveTrackSelectionFactory.createTrackSelection(
group, bandwidthMeter, adaptiveTracks);
return new TrackSelection.Definition(group, adaptiveTracks);
}
}
return null;
@ -1835,7 +1819,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
&& (format.bitrate == Format.NO_VALUE || format.bitrate <= maxVideoBitrate);
}
private static @Nullable TrackSelection selectFixedVideoTrack(
@Nullable
private static TrackSelection.Definition selectFixedVideoTrack(
TrackGroupArray groups, int[][] formatSupports, Parameters params) {
TrackGroup selectedGroup = null;
int selectedTrackIndex = 0;
@ -1897,8 +1882,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
}
}
return selectedGroup == null ? null
: new FixedTrackSelection(selectedGroup, selectedTrackIndex);
return selectedGroup == null
? null
: new TrackSelection.Definition(selectedGroup, selectedTrackIndex);
}
// Audio track selection implementation.
@ -1913,19 +1899,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param mixedMimeTypeAdaptationSupports The result of {@link
* RendererCapabilities#supportsMixedMimeTypeAdaptation()} for the renderer.
* @param params The selector's current constraint parameters.
* @param adaptiveTrackSelectionFactory A factory for generating adaptive track selections, or
* null if a fixed track selection is required.
* @return The {@link TrackSelection} and corresponding {@link AudioTrackScore}, or null if no
* selection was made.
* @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed.
* @return The {@link TrackSelection.Definition} and corresponding {@link AudioTrackScore}, or
* null if no selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/
@SuppressWarnings("unused")
protected @Nullable Pair<TrackSelection, AudioTrackScore> selectAudioTrack(
@Nullable
protected Pair<TrackSelection.Definition, AudioTrackScore> selectAudioTrack(
TrackGroupArray groups,
int[][] formatSupports,
int mixedMimeTypeAdaptationSupports,
Parameters params,
@Nullable TrackSelection.Factory adaptiveTrackSelectionFactory)
boolean enableAdaptiveTrackSelection)
throws ExoPlaybackException {
int selectedTrackIndex = C.INDEX_UNSET;
int selectedGroupIndex = C.INDEX_UNSET;
@ -1958,10 +1944,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TrackGroup selectedGroup = groups.get(selectedGroupIndex);
TrackSelection selection = null;
TrackSelection.Definition definition = null;
if (!params.forceHighestSupportedBitrate
&& !params.forceLowestBitrate
&& adaptiveTrackSelectionFactory != null) {
&& enableAdaptiveTrackSelection) {
// If the group of the track with the highest score allows it, try to enable adaptation.
int[] adaptiveTracks =
getAdaptiveAudioTracks(
@ -1970,17 +1956,15 @@ public class DefaultTrackSelector extends MappingTrackSelector {
params.allowAudioMixedMimeTypeAdaptiveness,
params.allowAudioMixedSampleRateAdaptiveness);
if (adaptiveTracks.length > 0) {
selection =
adaptiveTrackSelectionFactory.createTrackSelection(
selectedGroup, getBandwidthMeter(), adaptiveTracks);
definition = new TrackSelection.Definition(selectedGroup, adaptiveTracks);
}
}
if (selection == null) {
if (definition == null) {
// We didn't make an adaptive selection, so make a fixed one instead.
selection = new FixedTrackSelection(selectedGroup, selectedTrackIndex);
definition = new TrackSelection.Definition(selectedGroup, selectedTrackIndex);
}
return Pair.create(selection, Assertions.checkNotNull(selectedTrackScore));
return Pair.create(definition, Assertions.checkNotNull(selectedTrackScore));
}
private static int[] getAdaptiveAudioTracks(
@ -2076,11 +2060,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param formatSupport The result of {@link RendererCapabilities#supportsFormat} for each mapped
* track, indexed by track group index and track index (in that order).
* @param params The selector's current constraint parameters.
* @return The {@link TrackSelection} and corresponding track score, or null if no selection was
* made.
* @return The {@link TrackSelection.Definition} and corresponding track score, or null if no
* selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/
protected @Nullable Pair<TrackSelection, Integer> selectTextTrack(
@Nullable
protected Pair<TrackSelection.Definition, Integer> selectTextTrack(
TrackGroupArray groups, int[][] formatSupport, Parameters params)
throws ExoPlaybackException {
TrackGroup selectedGroup = null;
@ -2138,7 +2123,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return selectedGroup == null
? null
: Pair.create(
new FixedTrackSelection(selectedGroup, selectedTrackIndex), selectedTrackScore);
new TrackSelection.Definition(selectedGroup, selectedTrackIndex), selectedTrackScore);
}
// General track selection methods.
@ -2155,7 +2140,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @return The {@link TrackSelection} for the renderer, or null if no selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/
protected @Nullable TrackSelection selectOtherTrack(
@Nullable
protected TrackSelection.Definition selectOtherTrack(
int trackType, TrackGroupArray groups, int[][] formatSupport, Parameters params)
throws ExoPlaybackException {
TrackGroup selectedGroup = null;
@ -2181,8 +2167,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
}
}
return selectedGroup == null ? null
: new FixedTrackSelection(selectedGroup, selectedTrackIndex);
return selectedGroup == null
? null
: new TrackSelection.Definition(selectedGroup, selectedTrackIndex);
}
// Utility methods.

View File

@ -22,7 +22,9 @@ import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.chunk.MediaChunk;
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.util.Assertions;
import java.util.List;
import org.checkerframework.checker.nullness.compatqual.NullableType;
/**
* A track selection consisting of a static subset of selected tracks belonging to a {@link
@ -35,6 +37,24 @@ import java.util.List;
*/
public interface TrackSelection {
/** Contains of a subset of selected tracks belonging to a {@link TrackGroup}. */
final class Definition {
/** The {@link TrackGroup} which tracks belong to. */
public final TrackGroup group;
/** The indices of the selected tracks in {@link #group}. */
public final int[] tracks;
/**
* @param group The {@link TrackGroup}. Must not be null.
* @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
* null or empty. May be in any order.
*/
public Definition(TrackGroup group, int... tracks) {
this.group = group;
this.tracks = tracks;
}
}
/**
* Factory for {@link TrackSelection} instances.
*/
@ -51,6 +71,33 @@ public interface TrackSelection {
*/
TrackSelection createTrackSelection(
TrackGroup group, BandwidthMeter bandwidthMeter, int... tracks);
/**
* Creates a new selection for each {@link Definition}.
*
* @param definitions A {@link Definition} array. May include null values.
* @param bandwidthMeter A {@link BandwidthMeter} which can be used to select tracks.
* @return The created selections. For null entries in {@code definitions} returns null values.
*/
default @NullableType TrackSelection[] createTrackSelections(
@NullableType Definition[] definitions, BandwidthMeter bandwidthMeter) {
TrackSelection[] selections = new TrackSelection[definitions.length];
boolean createdAdaptiveTrackSelection = false;
for (int i = 0; i < definitions.length; i++) {
Definition definition = definitions[i];
if (definition == null) {
continue;
}
if (definition.tracks.length > 1) {
Assertions.checkState(!createdAdaptiveTrackSelection);
createdAdaptiveTrackSelection = true;
selections[i] = createTrackSelection(definition.group, bandwidthMeter, definition.tracks);
} else {
selections[i] = new FixedTrackSelection(definition.group, definition.tracks[0]);
}
}
return selections;
}
}
/**

View File

@ -773,7 +773,7 @@ public final class ExoPlayerTest {
}
// There are 2 renderers, and track selections are made twice. The second time one renderer is
// disabled, so only one out of the two track selections is enabled.
assertThat(createdTrackSelections).hasSize(4);
assertThat(createdTrackSelections).hasSize(3);
assertThat(numSelectionsEnabled).isEqualTo(3);
}

View File

@ -50,7 +50,6 @@ import com.google.android.exoplayer2.testutil.HostActivity;
import com.google.android.exoplayer2.testutil.HostActivity.HostedTest;
import com.google.android.exoplayer2.testutil.MetricsLogger;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.RandomTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelection;
@ -382,6 +381,7 @@ public final class DashTestRunner {
private DashTestTrackSelector(String tag, String audioFormatId, String[] videoFormatIds,
boolean canIncludeAdditionalVideoFormats) {
super(new RandomTrackSelection.Factory(/* seed= */ 0));
this.tag = tag;
this.audioFormatId = audioFormatId;
this.videoFormatIds = videoFormatIds;
@ -389,7 +389,7 @@ public final class DashTestRunner {
}
@Override
protected TrackSelection[] selectAllTracks(
protected TrackSelection.Definition[] selectAllTracks(
MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupports,
@ -403,22 +403,22 @@ public final class DashTestRunner {
TrackGroupArray audioTrackGroups = mappedTrackInfo.getTrackGroups(AUDIO_RENDERER_INDEX);
Assertions.checkState(videoTrackGroups.length == 1);
Assertions.checkState(audioTrackGroups.length == 1);
TrackSelection[] selections = new TrackSelection[mappedTrackInfo.getRendererCount()];
selections[VIDEO_RENDERER_INDEX] =
new RandomTrackSelection(
TrackSelection.Definition[] definitions =
new TrackSelection.Definition[mappedTrackInfo.getRendererCount()];
definitions[VIDEO_RENDERER_INDEX] =
new TrackSelection.Definition(
videoTrackGroups.get(0),
getVideoTrackIndices(
videoTrackGroups.get(0),
rendererFormatSupports[VIDEO_RENDERER_INDEX][0],
videoFormatIds,
canIncludeAdditionalVideoFormats),
0 /* seed */);
selections[AUDIO_RENDERER_INDEX] =
new FixedTrackSelection(
canIncludeAdditionalVideoFormats));
definitions[AUDIO_RENDERER_INDEX] =
new TrackSelection.Definition(
audioTrackGroups.get(0), getTrackIndex(audioTrackGroups.get(0), audioFormatId));
includedAdditionalVideoFormats =
selections[VIDEO_RENDERER_INDEX].length() > videoFormatIds.length;
return selections;
definitions[VIDEO_RENDERER_INDEX].tracks.length > videoFormatIds.length;
return definitions;
}
private int[] getVideoTrackIndices(

View File

@ -15,21 +15,19 @@
*/
package com.google.android.exoplayer2.testutil;
import android.support.annotation.NonNull;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import java.util.ArrayList;
import java.util.List;
/** A fake {@link MappingTrackSelector} that returns {@link FakeTrackSelection}s. */
public class FakeTrackSelector extends DefaultTrackSelector {
private final List<FakeTrackSelection> trackSelections = new ArrayList<>();
private final boolean mayReuseTrackSelection;
private final FakeTrackSelectionFactory fakeTrackSelectionFactory;
public FakeTrackSelector() {
this(false);
@ -41,28 +39,48 @@ public class FakeTrackSelector extends DefaultTrackSelector {
* using the same {@link TrackGroup}.
*/
public FakeTrackSelector(boolean mayReuseTrackSelection) {
this.mayReuseTrackSelection = mayReuseTrackSelection;
this(new FakeTrackSelectionFactory(mayReuseTrackSelection));
}
private FakeTrackSelector(FakeTrackSelectionFactory fakeTrackSelectionFactory) {
super(fakeTrackSelectionFactory);
this.fakeTrackSelectionFactory = fakeTrackSelectionFactory;
}
@Override
protected TrackSelection[] selectAllTracks(
protected TrackSelection.Definition[] selectAllTracks(
MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupports,
Parameters params)
throws ExoPlaybackException {
Parameters params) {
int rendererCount = mappedTrackInfo.getRendererCount();
TrackSelection[] selections = new TrackSelection[rendererCount];
TrackSelection.Definition[] definitions = new TrackSelection.Definition[rendererCount];
for (int i = 0; i < rendererCount; i++) {
TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(i);
boolean hasTracks = trackGroupArray.length > 0;
selections[i] = hasTracks ? reuseOrCreateTrackSelection(trackGroupArray.get(0)) : null;
definitions[i] = hasTracks ? new TrackSelection.Definition(trackGroupArray.get(0)) : null;
}
return selections;
return definitions;
}
@NonNull
private FakeTrackSelection reuseOrCreateTrackSelection(TrackGroup trackGroup) {
/** Returns list of all {@link FakeTrackSelection}s that this track selector has made so far. */
public List<FakeTrackSelection> getAllTrackSelections() {
return fakeTrackSelectionFactory.trackSelections;
}
private static class FakeTrackSelectionFactory implements TrackSelection.Factory {
private final List<FakeTrackSelection> trackSelections;
private final boolean mayReuseTrackSelection;
public FakeTrackSelectionFactory(boolean mayReuseTrackSelection) {
this.mayReuseTrackSelection = mayReuseTrackSelection;
trackSelections = new ArrayList<>();
}
@Override
public TrackSelection createTrackSelection(
TrackGroup trackGroup, BandwidthMeter bandwidthMeter, int... tracks) {
if (mayReuseTrackSelection) {
for (FakeTrackSelection trackSelection : trackSelections) {
if (trackSelection.getTrackGroup().equals(trackGroup)) {
@ -75,9 +93,17 @@ public class FakeTrackSelector extends DefaultTrackSelector {
return trackSelection;
}
/** Returns list of all {@link FakeTrackSelection}s that this track selector has made so far. */
public List<FakeTrackSelection> getAllTrackSelections() {
return trackSelections;
@Override
public TrackSelection[] createTrackSelections(
TrackSelection.Definition[] definitions, BandwidthMeter bandwidthMeter) {
TrackSelection[] selections = new TrackSelection[definitions.length];
for (int i = 0; i < definitions.length; i++) {
TrackSelection.Definition definition = definitions[i];
if (definition != null) {
selections[i] = createTrackSelection(definition.group, bandwidthMeter, definition.tracks);
}
}
return selections;
}
}
}