mirror of
https://github.com/samsonjs/media.git
synced 2026-03-29 10:05:48 +00:00
TrackSelection.Factory clean-up.
We currently have two factory methods where it is completely unclear which one needs to be overridden. This change deprecates the old one, adds a Util method to easily map back from the new to the old behaviour, and updates all implementations of the now deprecated method in our code. PiperOrigin-RevId: 224303560
This commit is contained in:
parent
9a5096ee64
commit
5776bed190
9 changed files with 151 additions and 101 deletions
|
|
@ -5,10 +5,13 @@
|
|||
* Support for playing spherical videos on Daydream.
|
||||
* Improve decoder re-use between playbacks. TODO: Write and link a blog post
|
||||
here ([#2826](https://github.com/google/ExoPlayer/issues/2826)).
|
||||
* Add options for controlling audio track selections to `DefaultTrackSelector`
|
||||
([#3314](https://github.com/google/ExoPlayer/issues/3314)).
|
||||
* Track selection:
|
||||
* Add options for controlling audio track selections to `DefaultTrackSelector`
|
||||
([#3314](https://github.com/google/ExoPlayer/issues/3314)).
|
||||
* Update `TrackSelection.Factory` interface to support creating all track
|
||||
selections together.
|
||||
* Do not retry failed loads whose error is `FileNotFoundException`.
|
||||
* Prevent Cea608Decoder from generating Subtitles with null Cues list
|
||||
* Prevent Cea608Decoder from generating Subtitles with null Cues list.
|
||||
* Caching: Cache data with unknown length by default. The previous flag to opt
|
||||
in to this behavior (`DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH`) has been
|
||||
replaced with an opt out flag (`DataSpec.FLAG_DONT_CACHE_IF_LENGTH_UNKNOWN`).
|
||||
|
|
|
|||
|
|
@ -227,8 +227,36 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AdaptiveTrackSelection createTrackSelection(
|
||||
TrackGroup group, BandwidthMeter bandwidthMeter, int... tracks) {
|
||||
public @NullableType TrackSelection[] createTrackSelections(
|
||||
@NullableType Definition[] definitions, BandwidthMeter bandwidthMeter) {
|
||||
TrackSelection[] selections = new TrackSelection[definitions.length];
|
||||
AdaptiveTrackSelection adaptiveSelection = null;
|
||||
int totalFixedBandwidth = 0;
|
||||
for (int i = 0; i < definitions.length; i++) {
|
||||
Definition definition = definitions[i];
|
||||
if (definition == null) {
|
||||
continue;
|
||||
}
|
||||
if (definition.tracks.length > 1) {
|
||||
adaptiveSelection =
|
||||
createAdaptiveTrackSelection(definition.group, bandwidthMeter, definition.tracks);
|
||||
selections[i] = adaptiveSelection;
|
||||
} else {
|
||||
selections[i] = new FixedTrackSelection(definition.group, definition.tracks[0]);
|
||||
int trackBitrate = definition.group.getFormat(definition.tracks[0]).bitrate;
|
||||
if (trackBitrate != Format.NO_VALUE) {
|
||||
totalFixedBandwidth += trackBitrate;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (blockFixedTrackSelectionBandwidth && adaptiveSelection != null) {
|
||||
adaptiveSelection.experimental_setNonAllocatableBandwidth(totalFixedBandwidth);
|
||||
}
|
||||
return selections;
|
||||
}
|
||||
|
||||
private AdaptiveTrackSelection createAdaptiveTrackSelection(
|
||||
TrackGroup group, BandwidthMeter bandwidthMeter, int[] tracks) {
|
||||
if (this.bandwidthMeter != null) {
|
||||
bandwidthMeter = this.bandwidthMeter;
|
||||
}
|
||||
|
|
@ -246,34 +274,6 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
|
|||
adaptiveTrackSelection.experimental_setTrackBitrateEstimator(trackBitrateEstimator);
|
||||
return adaptiveTrackSelection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NullableType TrackSelection[] createTrackSelections(
|
||||
@NullableType Definition[] definitions, BandwidthMeter bandwidthMeter) {
|
||||
TrackSelection[] selections = new TrackSelection[definitions.length];
|
||||
AdaptiveTrackSelection adaptiveSelection = null;
|
||||
int totalFixedBandwidth = 0;
|
||||
for (int i = 0; i < definitions.length; i++) {
|
||||
Definition definition = definitions[i];
|
||||
if (definition == null) {
|
||||
continue;
|
||||
}
|
||||
if (definition.tracks.length > 1) {
|
||||
selections[i] = createTrackSelection(definition.group, bandwidthMeter, definition.tracks);
|
||||
adaptiveSelection = (AdaptiveTrackSelection) selections[i];
|
||||
} else {
|
||||
selections[i] = new FixedTrackSelection(definition.group, definition.tracks[0]);
|
||||
int trackBitrate = definition.group.getFormat(definition.tracks[0]).bitrate;
|
||||
if (trackBitrate != Format.NO_VALUE) {
|
||||
totalFixedBandwidth += trackBitrate;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (blockFixedTrackSelectionBandwidth && adaptiveSelection != null) {
|
||||
adaptiveSelection.experimental_setNonAllocatableBandwidth(totalFixedBandwidth);
|
||||
}
|
||||
return selections;
|
||||
}
|
||||
}
|
||||
|
||||
public static final int DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS = 10000;
|
||||
|
|
|
|||
|
|
@ -24,12 +24,14 @@ import com.google.android.exoplayer2.LoadControl;
|
|||
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.trackselection.TrackSelection.Definition;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
import com.google.android.exoplayer2.upstream.DefaultAllocator;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Clock;
|
||||
import com.google.android.exoplayer2.util.PriorityTaskManager;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/**
|
||||
* Builder for a {@link TrackSelection.Factory} and {@link LoadControl} that implement buffer size
|
||||
|
|
@ -273,19 +275,22 @@ public final class BufferSizeAdaptationBuilder {
|
|||
TrackSelection.Factory trackSelectionFactory =
|
||||
new TrackSelection.Factory() {
|
||||
@Override
|
||||
public TrackSelection createTrackSelection(
|
||||
TrackGroup group, BandwidthMeter bandwidthMeter, int... tracks) {
|
||||
return new BufferSizeAdaptiveTrackSelection(
|
||||
group,
|
||||
tracks,
|
||||
bandwidthMeter,
|
||||
minBufferMs,
|
||||
maxBufferMs,
|
||||
hysteresisBufferMs,
|
||||
startUpBandwidthFraction,
|
||||
startUpMinBufferForQualityIncreaseMs,
|
||||
dynamicFormatFilter,
|
||||
clock);
|
||||
public @NullableType TrackSelection[] createTrackSelections(
|
||||
@NullableType Definition[] definitions, BandwidthMeter bandwidthMeter) {
|
||||
return TrackSelectionUtil.createTrackSelectionsForDefinitions(
|
||||
definitions,
|
||||
definition ->
|
||||
new BufferSizeAdaptiveTrackSelection(
|
||||
definition.group,
|
||||
definition.tracks,
|
||||
bandwidthMeter,
|
||||
minBufferMs,
|
||||
maxBufferMs,
|
||||
hysteresisBufferMs,
|
||||
startUpBandwidthFraction,
|
||||
startUpMinBufferForQualityIncreaseMs,
|
||||
dynamicFormatFilter,
|
||||
clock));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ 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 {@link TrackSelection} consisting of a single track.
|
||||
|
|
@ -56,10 +56,12 @@ public final class FixedTrackSelection extends BaseTrackSelection {
|
|||
}
|
||||
|
||||
@Override
|
||||
public FixedTrackSelection createTrackSelection(
|
||||
TrackGroup group, BandwidthMeter bandwidthMeter, int... tracks) {
|
||||
Assertions.checkArgument(tracks.length == 1);
|
||||
return new FixedTrackSelection(group, tracks[0], reason, data);
|
||||
public @NullableType TrackSelection[] createTrackSelections(
|
||||
@NullableType Definition[] definitions, BandwidthMeter bandwidthMeter) {
|
||||
return TrackSelectionUtil.createTrackSelectionsForDefinitions(
|
||||
definitions,
|
||||
definition ->
|
||||
new FixedTrackSelection(definition.group, definition.tracks[0], reason, data));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
|
|||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/**
|
||||
* A {@link TrackSelection} whose selected track is updated randomly.
|
||||
|
|
@ -49,9 +50,11 @@ public final class RandomTrackSelection extends BaseTrackSelection {
|
|||
}
|
||||
|
||||
@Override
|
||||
public RandomTrackSelection createTrackSelection(
|
||||
TrackGroup group, BandwidthMeter bandwidthMeter, int... tracks) {
|
||||
return new RandomTrackSelection(group, tracks, random);
|
||||
public @NullableType TrackSelection[] createTrackSelections(
|
||||
@NullableType Definition[] definitions, BandwidthMeter bandwidthMeter) {
|
||||
return TrackSelectionUtil.createTrackSelectionsForDefinitions(
|
||||
definitions,
|
||||
definition -> new RandomTrackSelection(definition.group, definition.tracks, random));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import com.google.android.exoplayer2.Format;
|
|||
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.trackselection.TrackSelectionUtil.AdaptiveTrackSelectionFactory;
|
||||
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;
|
||||
|
||||
|
|
@ -61,42 +61,31 @@ public interface TrackSelection {
|
|||
interface Factory {
|
||||
|
||||
/**
|
||||
* Creates a new selection.
|
||||
*
|
||||
* @param group The {@link TrackGroup}. Must not be null.
|
||||
* @param bandwidthMeter A {@link BandwidthMeter} which can be used to select tracks.
|
||||
* @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
|
||||
* null or empty. May be in any order.
|
||||
* @return The created selection.
|
||||
* @deprecated Implement {@link #createTrackSelections(Definition[], BandwidthMeter)} instead.
|
||||
* Calling {@link TrackSelectionUtil#createTrackSelectionsForDefinitions(Definition[],
|
||||
* AdaptiveTrackSelectionFactory)} helps to create a single adaptive track selection in the
|
||||
* same way as using this deprecated method.
|
||||
*/
|
||||
TrackSelection createTrackSelection(
|
||||
TrackGroup group, BandwidthMeter bandwidthMeter, int... tracks);
|
||||
@Deprecated
|
||||
default TrackSelection createTrackSelection(
|
||||
TrackGroup group, BandwidthMeter bandwidthMeter, int... tracks) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return The created selections. Must have the same length as {@code definitions} and may
|
||||
* include null values.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
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;
|
||||
return TrackSelectionUtil.createTrackSelectionsForDefinitions(
|
||||
definitions,
|
||||
definition -> createTrackSelection(definition.group, bandwidthMeter, definition.tracks));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,15 +22,59 @@ import com.google.android.exoplayer2.Format;
|
|||
import com.google.android.exoplayer2.source.chunk.MediaChunk;
|
||||
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
|
||||
import com.google.android.exoplayer2.source.chunk.MediaChunkListIterator;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection.Definition;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/** Track selection related utility methods. */
|
||||
public final class TrackSelectionUtil {
|
||||
|
||||
private TrackSelectionUtil() {}
|
||||
|
||||
/** Functional interface to create a single adaptive track selection. */
|
||||
public interface AdaptiveTrackSelectionFactory {
|
||||
|
||||
/**
|
||||
* Creates an adaptive track selection for the provided track selection definition.
|
||||
*
|
||||
* @param trackSelectionDefinition A {@link Definition} for the track selection.
|
||||
* @return The created track selection.
|
||||
*/
|
||||
TrackSelection createAdaptiveTrackSelection(Definition trackSelectionDefinition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates track selections for an array of track selection definitions, with at most one
|
||||
* multi-track adaptive selection.
|
||||
*
|
||||
* @param definitions The list of track selection {@link Definition definitions}. May include null
|
||||
* values.
|
||||
* @param adaptiveTrackSelectionFactory A factory for the multi-track adaptive track selection.
|
||||
* @return The array of created track selection. For null entries in {@code definitions} returns
|
||||
* null values.
|
||||
*/
|
||||
public static @NullableType TrackSelection[] createTrackSelectionsForDefinitions(
|
||||
@NullableType Definition[] definitions,
|
||||
AdaptiveTrackSelectionFactory adaptiveTrackSelectionFactory) {
|
||||
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 && !createdAdaptiveTrackSelection) {
|
||||
createdAdaptiveTrackSelection = true;
|
||||
selections[i] = adaptiveTrackSelectionFactory.createAdaptiveTrackSelection(definition);
|
||||
} else {
|
||||
selections[i] = new FixedTrackSelection(definition.group, definition.tracks[0]);
|
||||
}
|
||||
}
|
||||
return selections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns average bitrate for chunks in bits per second. Chunks are included in average until
|
||||
* {@code maxDurationMs} or the first unknown length chunk.
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import com.google.android.exoplayer2.source.TrackGroup;
|
|||
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
|
||||
import com.google.android.exoplayer2.testutil.FakeClock;
|
||||
import com.google.android.exoplayer2.testutil.FakeMediaChunk;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection.Definition;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -66,15 +67,20 @@ public final class AdaptiveTrackSelectionTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testFactoryUsesInitiallyProvidedBandwidthMeter() {
|
||||
BandwidthMeter initialBandwidthMeter = mock(BandwidthMeter.class);
|
||||
BandwidthMeter injectedBandwidthMeter = mock(BandwidthMeter.class);
|
||||
Format format = videoFormat(/* bitrate= */ 500, /* width= */ 320, /* height= */ 240);
|
||||
@SuppressWarnings("deprecation")
|
||||
AdaptiveTrackSelection adaptiveTrackSelection =
|
||||
Format format1 = videoFormat(/* bitrate= */ 500, /* width= */ 320, /* height= */ 240);
|
||||
Format format2 = videoFormat(/* bitrate= */ 1000, /* width= */ 640, /* height= */ 480);
|
||||
TrackSelection[] trackSelections =
|
||||
new AdaptiveTrackSelection.Factory(initialBandwidthMeter)
|
||||
.createTrackSelection(new TrackGroup(format), injectedBandwidthMeter, /* tracks= */ 0);
|
||||
adaptiveTrackSelection.updateSelectedTrack(
|
||||
.createTrackSelections(
|
||||
new Definition[] {
|
||||
new Definition(new TrackGroup(format1, format2), /* tracks= */ 0, 1)
|
||||
},
|
||||
injectedBandwidthMeter);
|
||||
trackSelections[0].updateSelectedTrack(
|
||||
/* playbackPositionUs= */ 0,
|
||||
/* bufferedDurationUs= */ 0,
|
||||
/* availableDurationUs= */ C.TIME_UNSET,
|
||||
|
|
|
|||
|
|
@ -79,8 +79,19 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
|||
}
|
||||
|
||||
@Override
|
||||
public TrackSelection createTrackSelection(
|
||||
TrackGroup trackGroup, BandwidthMeter bandwidthMeter, int... tracks) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
return selections;
|
||||
}
|
||||
|
||||
private TrackSelection createTrackSelection(TrackGroup trackGroup) {
|
||||
if (mayReuseTrackSelection) {
|
||||
for (FakeTrackSelection trackSelection : trackSelections) {
|
||||
if (trackSelection.getTrackGroup().equals(trackGroup)) {
|
||||
|
|
@ -92,18 +103,5 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
|||
trackSelections.add(trackSelection);
|
||||
return trackSelection;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue