Commit 527f2cf7 by eguven Committed by Oliver Woodman

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
parent 55cc0df5
...@@ -22,7 +22,9 @@ import com.google.android.exoplayer2.source.TrackGroup; ...@@ -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.MediaChunk;
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator; import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.util.Assertions;
import java.util.List; 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 * A track selection consisting of a static subset of selected tracks belonging to a {@link
...@@ -35,6 +37,24 @@ import java.util.List; ...@@ -35,6 +37,24 @@ import java.util.List;
*/ */
public interface TrackSelection { 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. * Factory for {@link TrackSelection} instances.
*/ */
...@@ -51,6 +71,33 @@ public interface TrackSelection { ...@@ -51,6 +71,33 @@ public interface TrackSelection {
*/ */
TrackSelection createTrackSelection( TrackSelection createTrackSelection(
TrackGroup group, BandwidthMeter bandwidthMeter, int... tracks); 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;
}
} }
/** /**
......
...@@ -773,7 +773,7 @@ public final class ExoPlayerTest { ...@@ -773,7 +773,7 @@ public final class ExoPlayerTest {
} }
// There are 2 renderers, and track selections are made twice. The second time one renderer is // 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. // disabled, so only one out of the two track selections is enabled.
assertThat(createdTrackSelections).hasSize(4); assertThat(createdTrackSelections).hasSize(3);
assertThat(numSelectionsEnabled).isEqualTo(3); assertThat(numSelectionsEnabled).isEqualTo(3);
} }
......
...@@ -50,7 +50,6 @@ import com.google.android.exoplayer2.testutil.HostActivity; ...@@ -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.HostActivity.HostedTest;
import com.google.android.exoplayer2.testutil.MetricsLogger; import com.google.android.exoplayer2.testutil.MetricsLogger;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; 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.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.RandomTrackSelection; import com.google.android.exoplayer2.trackselection.RandomTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
...@@ -382,6 +381,7 @@ public final class DashTestRunner { ...@@ -382,6 +381,7 @@ public final class DashTestRunner {
private DashTestTrackSelector(String tag, String audioFormatId, String[] videoFormatIds, private DashTestTrackSelector(String tag, String audioFormatId, String[] videoFormatIds,
boolean canIncludeAdditionalVideoFormats) { boolean canIncludeAdditionalVideoFormats) {
super(new RandomTrackSelection.Factory(/* seed= */ 0));
this.tag = tag; this.tag = tag;
this.audioFormatId = audioFormatId; this.audioFormatId = audioFormatId;
this.videoFormatIds = videoFormatIds; this.videoFormatIds = videoFormatIds;
...@@ -389,7 +389,7 @@ public final class DashTestRunner { ...@@ -389,7 +389,7 @@ public final class DashTestRunner {
} }
@Override @Override
protected TrackSelection[] selectAllTracks( protected TrackSelection.Definition[] selectAllTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports, int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupports, int[] rendererMixedMimeTypeAdaptationSupports,
...@@ -403,22 +403,22 @@ public final class DashTestRunner { ...@@ -403,22 +403,22 @@ public final class DashTestRunner {
TrackGroupArray audioTrackGroups = mappedTrackInfo.getTrackGroups(AUDIO_RENDERER_INDEX); TrackGroupArray audioTrackGroups = mappedTrackInfo.getTrackGroups(AUDIO_RENDERER_INDEX);
Assertions.checkState(videoTrackGroups.length == 1); Assertions.checkState(videoTrackGroups.length == 1);
Assertions.checkState(audioTrackGroups.length == 1); Assertions.checkState(audioTrackGroups.length == 1);
TrackSelection[] selections = new TrackSelection[mappedTrackInfo.getRendererCount()]; TrackSelection.Definition[] definitions =
selections[VIDEO_RENDERER_INDEX] = new TrackSelection.Definition[mappedTrackInfo.getRendererCount()];
new RandomTrackSelection( definitions[VIDEO_RENDERER_INDEX] =
new TrackSelection.Definition(
videoTrackGroups.get(0), videoTrackGroups.get(0),
getVideoTrackIndices( getVideoTrackIndices(
videoTrackGroups.get(0), videoTrackGroups.get(0),
rendererFormatSupports[VIDEO_RENDERER_INDEX][0], rendererFormatSupports[VIDEO_RENDERER_INDEX][0],
videoFormatIds, videoFormatIds,
canIncludeAdditionalVideoFormats), canIncludeAdditionalVideoFormats));
0 /* seed */); definitions[AUDIO_RENDERER_INDEX] =
selections[AUDIO_RENDERER_INDEX] = new TrackSelection.Definition(
new FixedTrackSelection(
audioTrackGroups.get(0), getTrackIndex(audioTrackGroups.get(0), audioFormatId)); audioTrackGroups.get(0), getTrackIndex(audioTrackGroups.get(0), audioFormatId));
includedAdditionalVideoFormats = includedAdditionalVideoFormats =
selections[VIDEO_RENDERER_INDEX].length() > videoFormatIds.length; definitions[VIDEO_RENDERER_INDEX].tracks.length > videoFormatIds.length;
return selections; return definitions;
} }
private int[] getVideoTrackIndices( private int[] getVideoTrackIndices(
......
...@@ -15,21 +15,19 @@ ...@@ -15,21 +15,19 @@
*/ */
package com.google.android.exoplayer2.testutil; 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.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector; import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** A fake {@link MappingTrackSelector} that returns {@link FakeTrackSelection}s. */ /** A fake {@link MappingTrackSelector} that returns {@link FakeTrackSelection}s. */
public class FakeTrackSelector extends DefaultTrackSelector { public class FakeTrackSelector extends DefaultTrackSelector {
private final List<FakeTrackSelection> trackSelections = new ArrayList<>(); private final FakeTrackSelectionFactory fakeTrackSelectionFactory;
private final boolean mayReuseTrackSelection;
public FakeTrackSelector() { public FakeTrackSelector() {
this(false); this(false);
...@@ -41,43 +39,71 @@ public class FakeTrackSelector extends DefaultTrackSelector { ...@@ -41,43 +39,71 @@ public class FakeTrackSelector extends DefaultTrackSelector {
* using the same {@link TrackGroup}. * using the same {@link TrackGroup}.
*/ */
public FakeTrackSelector(boolean mayReuseTrackSelection) { public FakeTrackSelector(boolean mayReuseTrackSelection) {
this.mayReuseTrackSelection = mayReuseTrackSelection; this(new FakeTrackSelectionFactory(mayReuseTrackSelection));
}
private FakeTrackSelector(FakeTrackSelectionFactory fakeTrackSelectionFactory) {
super(fakeTrackSelectionFactory);
this.fakeTrackSelectionFactory = fakeTrackSelectionFactory;
} }
@Override @Override
protected TrackSelection[] selectAllTracks( protected TrackSelection.Definition[] selectAllTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports, int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupports, int[] rendererMixedMimeTypeAdaptationSupports,
Parameters params) Parameters params) {
throws ExoPlaybackException {
int rendererCount = mappedTrackInfo.getRendererCount(); int rendererCount = mappedTrackInfo.getRendererCount();
TrackSelection[] selections = new TrackSelection[rendererCount]; TrackSelection.Definition[] definitions = new TrackSelection.Definition[rendererCount];
for (int i = 0; i < rendererCount; i++) { for (int i = 0; i < rendererCount; i++) {
TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(i); TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(i);
boolean hasTracks = trackGroupArray.length > 0; 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 /** Returns list of all {@link FakeTrackSelection}s that this track selector has made so far. */
private FakeTrackSelection reuseOrCreateTrackSelection(TrackGroup trackGroup) { public List<FakeTrackSelection> getAllTrackSelections() {
if (mayReuseTrackSelection) { return fakeTrackSelectionFactory.trackSelections;
for (FakeTrackSelection trackSelection : trackSelections) { }
if (trackSelection.getTrackGroup().equals(trackGroup)) {
return trackSelection; 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)) {
return trackSelection;
}
} }
} }
FakeTrackSelection trackSelection = new FakeTrackSelection(trackGroup);
trackSelections.add(trackSelection);
return trackSelection;
} }
FakeTrackSelection trackSelection = new FakeTrackSelection(trackGroup);
trackSelections.add(trackSelection);
return trackSelection;
}
/** Returns list of all {@link FakeTrackSelection}s that this track selector has made so far. */ @Override
public List<FakeTrackSelection> getAllTrackSelections() { public TrackSelection[] createTrackSelections(
return trackSelections; 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;
}
} }
} }
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