mirror of
https://github.com/samsonjs/media.git
synced 2026-04-08 11:45:51 +00:00
Split mutations method out of TrackSelection
`TrackSelection` had mutation methods which were to be called only internally by ExoPlayer components but were exposed in the public `Player` interface. The mutation methods have been moved out of `TrackSelection` to a new class `ExoTrackSelection`. Current track related read-only method have also been moved out, because they are actually something quite unclear. Even for a single item playlist, it's the track being buffered rather than the track being played, which is unclear. But when you have a playlist it starts to get really confusing, because if the next item is being buffered, then it's actually the last track to be buffered in the currently playing item. As a final aside, the implementations don't do proper thread synchronization to ensure visibility of updated state by the calling thread. Exposing those mutable methods in the public `Player` interface was problematic because they leaking internal concepts of `ExoPlayer`. This is also required to minimize the `Player` interface for long term stability. `ExoTrackSelection` is a subclass of `TrackSelection`. This is not ideal as an `TrackSelection` implementation could break the current immutability. This was done in order for this refactor to be simpler. A future patch will fully split the two classes. All `MediaPeriod` and `Sources` had to be updated to use the new `TrackSelection` dynamic aspect class name. An alternative would have been to break ExoPlayer's public API, keeping `TrackSelection` as the dynamic aspect name, and calling the public static aspect class `TrackSelectionState` or similar. Nevertheless, while it would have impacted less files, it would have many more small apps and casual users of ExoPlayer. #player-to-common PiperOrigin-RevId: 353637924
This commit is contained in:
parent
b069a567ea
commit
ec43735054
45 changed files with 632 additions and 633 deletions
|
|
@ -167,6 +167,10 @@
|
|||
([#8320](https://github.com/google/ExoPlayer/issues/8320)).
|
||||
* Add option to specify preferred audio role flags.
|
||||
* Forward `Timeline` and `MediaPeriodId` to `TrackSelection.Factory`.
|
||||
* In order to make it immutable, `TrackSelection` in the `Player` API now
|
||||
only contains methods related to static selection.
|
||||
The rest of the methods have been moved to the child
|
||||
class `ExoTrackSelection` which is used by all ExoPlayer components.
|
||||
* DASH:
|
||||
* Support low-latency DASH playback (`availabilityTimeOffset` and
|
||||
`ServiceDescription` tags)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import static java.lang.Math.min;
|
|||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DefaultAllocator;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
|
|
@ -317,7 +317,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||
|
||||
@Override
|
||||
public void onTracksSelected(
|
||||
Renderer[] renderers, TrackGroupArray trackGroups, TrackSelection[] trackSelections) {
|
||||
Renderer[] renderers, TrackGroupArray trackGroups, ExoTrackSelection[] trackSelections) {
|
||||
targetBufferBytes =
|
||||
targetBufferBytesOverwrite == C.LENGTH_UNSET
|
||||
? calculateTargetBufferBytes(renderers, trackSelections)
|
||||
|
|
@ -400,7 +400,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||
* @return The target buffer size in bytes.
|
||||
*/
|
||||
protected int calculateTargetBufferBytes(
|
||||
Renderer[] renderers, TrackSelection[] trackSelectionArray) {
|
||||
Renderer[] renderers, ExoTrackSelection[] trackSelectionArray) {
|
||||
int targetBufferSize = 0;
|
||||
for (int i = 0; i < renderers.length; i++) {
|
||||
if (trackSelectionArray[i] != null) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||
import com.google.android.exoplayer2.source.MediaSourceFactory;
|
||||
import com.google.android.exoplayer2.source.ShuffleOrder;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
|
|
@ -171,7 +171,7 @@ import java.util.List;
|
|||
emptyTrackSelectorResult =
|
||||
new TrackSelectorResult(
|
||||
new RendererConfiguration[renderers.length],
|
||||
new TrackSelection[renderers.length],
|
||||
new ExoTrackSelection[renderers.length],
|
||||
/* info= */ null);
|
||||
period = new Timeline.Period();
|
||||
maskingWindowIndex = C.INDEX_UNSET;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||
import com.google.android.exoplayer2.source.SampleStream;
|
||||
import com.google.android.exoplayer2.source.ShuffleOrder;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
|
|
@ -725,7 +725,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
private void notifyTrackSelectionPlayWhenReadyChanged(boolean playWhenReady) {
|
||||
MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
|
||||
while (periodHolder != null) {
|
||||
for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
|
||||
for (ExoTrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
|
||||
if (trackSelection != null) {
|
||||
trackSelection.onPlayWhenReadyChanged(playWhenReady);
|
||||
}
|
||||
|
|
@ -899,7 +899,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
private void notifyTrackSelectionRebuffer() {
|
||||
MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
|
||||
while (periodHolder != null) {
|
||||
for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
|
||||
for (ExoTrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
|
||||
if (trackSelection != null) {
|
||||
trackSelection.onRebuffer();
|
||||
}
|
||||
|
|
@ -1689,7 +1689,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
private void updateTrackSelectionPlaybackSpeed(float playbackSpeed) {
|
||||
MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
|
||||
while (periodHolder != null) {
|
||||
for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
|
||||
for (ExoTrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
|
||||
if (trackSelection != null) {
|
||||
trackSelection.onPlaybackSpeed(playbackSpeed);
|
||||
}
|
||||
|
|
@ -1701,7 +1701,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
private void notifyTrackSelectionDiscontinuity() {
|
||||
MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
|
||||
while (periodHolder != null) {
|
||||
for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
|
||||
for (ExoTrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
|
||||
if (trackSelection != null) {
|
||||
trackSelection.onDiscontinuity();
|
||||
}
|
||||
|
|
@ -2268,10 +2268,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
}
|
||||
|
||||
private ImmutableList<Metadata> extractMetadataFromTrackSelectionArray(
|
||||
TrackSelection[] trackSelections) {
|
||||
ExoTrackSelection[] trackSelections) {
|
||||
ImmutableList.Builder<Metadata> result = new ImmutableList.Builder<>();
|
||||
boolean seenNonEmptyMetadata = false;
|
||||
for (TrackSelection trackSelection : trackSelections) {
|
||||
for (ExoTrackSelection trackSelection : trackSelections) {
|
||||
if (trackSelection != null) {
|
||||
Format format = trackSelection.getFormat(/* index= */ 0);
|
||||
if (format.metadata == null) {
|
||||
|
|
@ -2319,7 +2319,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
TrackSelectorResult trackSelectorResult = periodHolder.getTrackSelectorResult();
|
||||
RendererConfiguration rendererConfiguration =
|
||||
trackSelectorResult.rendererConfigurations[rendererIndex];
|
||||
TrackSelection newSelection = trackSelectorResult.selections[rendererIndex];
|
||||
ExoTrackSelection newSelection = trackSelectorResult.selections[rendererIndex];
|
||||
Format[] formats = getFormats(newSelection);
|
||||
// The renderer needs enabling with its new track selection.
|
||||
boolean playing = shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY;
|
||||
|
|
@ -2793,7 +2793,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
return newPeriodIndex == C.INDEX_UNSET ? null : newTimeline.getUidOfPeriod(newPeriodIndex);
|
||||
}
|
||||
|
||||
private static Format[] getFormats(TrackSelection newSelection) {
|
||||
private static Format[] getFormats(ExoTrackSelection newSelection) {
|
||||
// Build an array of formats contained by the selection.
|
||||
int length = newSelection != null ? newSelection.length() : 0;
|
||||
Format[] formats = new Format[length];
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ package com.google.android.exoplayer2;
|
|||
|
||||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
|
||||
/** Controls buffering of media. */
|
||||
|
|
@ -34,7 +34,7 @@ public interface LoadControl {
|
|||
* @param trackSelections The track selections that were made.
|
||||
*/
|
||||
void onTracksSelected(
|
||||
Renderer[] renderers, TrackGroupArray trackGroups, TrackSelection[] trackSelections);
|
||||
Renderer[] renderers, TrackGroupArray trackGroups, ExoTrackSelection[] trackSelections);
|
||||
|
||||
/** Called by the player when stopped. */
|
||||
void onStopped();
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import com.google.android.exoplayer2.source.MediaPeriod;
|
|||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.SampleStream;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
|
|
@ -232,7 +232,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
throws ExoPlaybackException {
|
||||
TrackSelectorResult selectorResult =
|
||||
trackSelector.selectTracks(rendererCapabilities, getTrackGroups(), info.id, timeline);
|
||||
for (TrackSelection trackSelection : selectorResult.selections) {
|
||||
for (ExoTrackSelection trackSelection : selectorResult.selections) {
|
||||
if (trackSelection != null) {
|
||||
trackSelection.onPlaybackSpeed(playbackSpeed);
|
||||
}
|
||||
|
|
@ -359,7 +359,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
}
|
||||
for (int i = 0; i < trackSelectorResult.length; i++) {
|
||||
boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i);
|
||||
TrackSelection trackSelection = trackSelectorResult.selections[i];
|
||||
ExoTrackSelection trackSelection = trackSelectorResult.selections[i];
|
||||
if (rendererEnabled && trackSelection != null) {
|
||||
trackSelection.enable();
|
||||
}
|
||||
|
|
@ -372,7 +372,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
}
|
||||
for (int i = 0; i < trackSelectorResult.length; i++) {
|
||||
boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i);
|
||||
TrackSelection trackSelection = trackSelectorResult.selections[i];
|
||||
ExoTrackSelection trackSelection = trackSelectorResult.selections[i];
|
||||
if (rendererEnabled && trackSelection != null) {
|
||||
trackSelection.disable();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ import com.google.android.exoplayer2.trackselection.BaseTrackSelection;
|
|||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.Parameters;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
|
|
@ -465,8 +465,9 @@ public final class DownloadHelper {
|
|||
private @MonotonicNonNull MediaPreparer mediaPreparer;
|
||||
private TrackGroupArray @MonotonicNonNull [] trackGroupArrays;
|
||||
private MappedTrackInfo @MonotonicNonNull [] mappedTrackInfos;
|
||||
private List<TrackSelection> @MonotonicNonNull [][] trackSelectionsByPeriodAndRenderer;
|
||||
private List<TrackSelection> @MonotonicNonNull [][] immutableTrackSelectionsByPeriodAndRenderer;
|
||||
private List<ExoTrackSelection> @MonotonicNonNull [][] trackSelectionsByPeriodAndRenderer;
|
||||
private List<ExoTrackSelection> @MonotonicNonNull [][]
|
||||
immutableTrackSelectionsByPeriodAndRenderer;
|
||||
|
||||
/**
|
||||
* Creates download helper.
|
||||
|
|
@ -573,14 +574,14 @@ public final class DownloadHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns all {@link TrackSelection track selections} for a period and renderer. Must not be
|
||||
* Returns all {@link ExoTrackSelection track selections} for a period and renderer. Must not be
|
||||
* called until after preparation completes.
|
||||
*
|
||||
* @param periodIndex The period index.
|
||||
* @param rendererIndex The renderer index.
|
||||
* @return A list of selected {@link TrackSelection track selections}.
|
||||
* @return A list of selected {@link ExoTrackSelection track selections}.
|
||||
*/
|
||||
public List<TrackSelection> getTrackSelections(int periodIndex, int rendererIndex) {
|
||||
public List<ExoTrackSelection> getTrackSelections(int periodIndex, int rendererIndex) {
|
||||
assertPreparedWithMedia();
|
||||
return immutableTrackSelectionsByPeriodAndRenderer[periodIndex][rendererIndex];
|
||||
}
|
||||
|
|
@ -751,7 +752,7 @@ public final class DownloadHelper {
|
|||
}
|
||||
assertPreparedWithMedia();
|
||||
List<StreamKey> streamKeys = new ArrayList<>();
|
||||
List<TrackSelection> allSelections = new ArrayList<>();
|
||||
List<ExoTrackSelection> allSelections = new ArrayList<>();
|
||||
int periodCount = trackSelectionsByPeriodAndRenderer.length;
|
||||
for (int periodIndex = 0; periodIndex < periodCount; periodIndex++) {
|
||||
allSelections.clear();
|
||||
|
|
@ -773,9 +774,9 @@ public final class DownloadHelper {
|
|||
int periodCount = mediaPreparer.mediaPeriods.length;
|
||||
int rendererCount = rendererCapabilities.length;
|
||||
trackSelectionsByPeriodAndRenderer =
|
||||
(List<TrackSelection>[][]) new List<?>[periodCount][rendererCount];
|
||||
(List<ExoTrackSelection>[][]) new List<?>[periodCount][rendererCount];
|
||||
immutableTrackSelectionsByPeriodAndRenderer =
|
||||
(List<TrackSelection>[][]) new List<?>[periodCount][rendererCount];
|
||||
(List<ExoTrackSelection>[][]) new List<?>[periodCount][rendererCount];
|
||||
for (int i = 0; i < periodCount; i++) {
|
||||
for (int j = 0; j < rendererCount; j++) {
|
||||
trackSelectionsByPeriodAndRenderer[i][j] = new ArrayList<>();
|
||||
|
|
@ -847,15 +848,15 @@ public final class DownloadHelper {
|
|||
new MediaPeriodId(mediaPreparer.timeline.getUidOfPeriod(periodIndex)),
|
||||
mediaPreparer.timeline);
|
||||
for (int i = 0; i < trackSelectorResult.length; i++) {
|
||||
@Nullable TrackSelection newSelection = trackSelectorResult.selections[i];
|
||||
@Nullable ExoTrackSelection newSelection = trackSelectorResult.selections[i];
|
||||
if (newSelection == null) {
|
||||
continue;
|
||||
}
|
||||
List<TrackSelection> existingSelectionList =
|
||||
List<ExoTrackSelection> existingSelectionList =
|
||||
trackSelectionsByPeriodAndRenderer[periodIndex][i];
|
||||
boolean mergedWithExistingSelection = false;
|
||||
for (int j = 0; j < existingSelectionList.size(); j++) {
|
||||
TrackSelection existingSelection = existingSelectionList.get(j);
|
||||
ExoTrackSelection existingSelection = existingSelectionList.get(j);
|
||||
if (existingSelection.getTrackGroup() == newSelection.getTrackGroup()) {
|
||||
// Merge with existing selection.
|
||||
scratchSet.clear();
|
||||
|
|
@ -1066,15 +1067,15 @@ public final class DownloadHelper {
|
|||
|
||||
private static final class DownloadTrackSelection extends BaseTrackSelection {
|
||||
|
||||
private static final class Factory implements TrackSelection.Factory {
|
||||
private static final class Factory implements ExoTrackSelection.Factory {
|
||||
|
||||
@Override
|
||||
public @NullableType TrackSelection[] createTrackSelections(
|
||||
public @NullableType ExoTrackSelection[] createTrackSelections(
|
||||
@NullableType Definition[] definitions,
|
||||
BandwidthMeter bandwidthMeter,
|
||||
MediaPeriodId mediaPeriodId,
|
||||
Timeline timeline) {
|
||||
@NullableType TrackSelection[] selections = new TrackSelection[definitions.length];
|
||||
@NullableType ExoTrackSelection[] selections = new ExoTrackSelection[definitions.length];
|
||||
for (int i = 0; i < definitions.length; i++) {
|
||||
selections[i] =
|
||||
definitions[i] == null
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import com.google.android.exoplayer2.Format;
|
|||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.SeekParameters;
|
||||
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
|
@ -34,9 +34,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
*/
|
||||
public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callback {
|
||||
|
||||
/**
|
||||
* The {@link MediaPeriod} wrapped by this clipping media period.
|
||||
*/
|
||||
/** The {@link MediaPeriod} wrapped by this clipping media period. */
|
||||
public final MediaPeriod mediaPeriod;
|
||||
|
||||
@Nullable private MediaPeriod.Callback callback;
|
||||
|
|
@ -98,7 +96,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
|
|||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
@ -250,7 +248,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
|
|||
}
|
||||
|
||||
private static boolean shouldKeepInitialDiscontinuity(
|
||||
long startUs, @NullableType TrackSelection[] selections) {
|
||||
long startUs, @NullableType ExoTrackSelection[] selections) {
|
||||
// If the clipping start position is non-zero, the clipping sample streams will adjust
|
||||
// timestamps on buffers they read from the unclipped sample streams. These adjusted buffer
|
||||
// timestamps can be negative, because sample streams provide buffers starting at a key-frame,
|
||||
|
|
@ -261,7 +259,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
|
|||
// However, for tracks where all samples are sync samples, we assume they have random access
|
||||
// seek behaviour and do not need an initial discontinuity to reset the renderer.
|
||||
if (startUs != 0) {
|
||||
for (TrackSelection trackSelection : selections) {
|
||||
for (ExoTrackSelection trackSelection : selections) {
|
||||
if (trackSelection != null) {
|
||||
Format selectedFormat = trackSelection.getSelectedFormat();
|
||||
if (!MimeTypes.allSamplesAreSyncSamples(
|
||||
|
|
@ -274,9 +272,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a {@link SampleStream} and clips its samples.
|
||||
*/
|
||||
/** Wraps a {@link SampleStream} and clips its samples. */
|
||||
private final class ClippingSampleStream implements SampleStream {
|
||||
|
||||
public final SampleStream childStream;
|
||||
|
|
@ -302,8 +298,8 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
|
|||
}
|
||||
|
||||
@Override
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
|
||||
boolean requireFormat) {
|
||||
public int readData(
|
||||
FormatHolder formatHolder, DecoderInputBuffer buffer, boolean requireFormat) {
|
||||
if (isPendingInitialDiscontinuity()) {
|
||||
return C.RESULT_NOTHING_READ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import androidx.annotation.Nullable;
|
|||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.SeekParameters;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import java.io.IOException;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
|
@ -173,7 +173,7 @@ public final class MaskingMediaPeriod implements MediaPeriod, MediaPeriod.Callba
|
|||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import com.google.android.exoplayer2.SeekParameters;
|
|||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
|
@ -45,7 +45,7 @@ public interface MediaPeriod extends SequenceableLoader {
|
|||
* Called when preparation completes.
|
||||
*
|
||||
* <p>Called on the playback thread. After invoking this method, the {@link MediaPeriod} can
|
||||
* expect for {@link #selectTracks(TrackSelection[], boolean[], SampleStream[], boolean[],
|
||||
* expect for {@link #selectTracks(ExoTrackSelection[], boolean[], SampleStream[], boolean[],
|
||||
* long)} to be called with the initial track selection.
|
||||
*
|
||||
* @param mediaPeriod The prepared {@link MediaPeriod}.
|
||||
|
|
@ -90,17 +90,17 @@ public interface MediaPeriod extends SequenceableLoader {
|
|||
|
||||
/**
|
||||
* Returns a list of {@link StreamKey StreamKeys} which allow to filter the media in this period
|
||||
* to load only the parts needed to play the provided {@link TrackSelection TrackSelections}.
|
||||
* to load only the parts needed to play the provided {@link ExoTrackSelection TrackSelections}.
|
||||
*
|
||||
* <p>This method is only called after the period has been prepared.
|
||||
*
|
||||
* @param trackSelections The {@link TrackSelection TrackSelections} describing the tracks for
|
||||
* @param trackSelections The {@link ExoTrackSelection TrackSelections} describing the tracks for
|
||||
* which stream keys are requested.
|
||||
* @return The corresponding {@link StreamKey StreamKeys} for the selected tracks, or an empty
|
||||
* list if filtering is not possible and the entire media needs to be loaded to play the
|
||||
* selected tracks.
|
||||
*/
|
||||
default List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) {
|
||||
default List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
|
@ -115,8 +115,8 @@ public interface MediaPeriod extends SequenceableLoader {
|
|||
* corresponding flag in {@code streamResetFlags} will be set to true. This flag will also be set
|
||||
* if a new sample stream is created.
|
||||
*
|
||||
* <p>Note that previously passed {@link TrackSelection TrackSelections} are no longer valid, and
|
||||
* any references to them must be updated to point to the new selections.
|
||||
* <p>Note that previously passed {@link ExoTrackSelection TrackSelections} are no longer valid,
|
||||
* and any references to them must be updated to point to the new selections.
|
||||
*
|
||||
* <p>This method is only called after the period has been prepared.
|
||||
*
|
||||
|
|
@ -135,7 +135,7 @@ public interface MediaPeriod extends SequenceableLoader {
|
|||
* @return The actual position at which the tracks were enabled, in microseconds.
|
||||
*/
|
||||
long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import com.google.android.exoplayer2.FormatHolder;
|
|||
import com.google.android.exoplayer2.SeekParameters;
|
||||
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -33,9 +33,7 @@ import java.util.List;
|
|||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* Merges multiple {@link MediaPeriod}s.
|
||||
*/
|
||||
/** Merges multiple {@link MediaPeriod}s. */
|
||||
/* package */ final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callback {
|
||||
|
||||
private final MediaPeriod[] periods;
|
||||
|
|
@ -100,7 +98,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
@ -126,15 +124,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
// Select tracks for each child, copying the resulting streams back into a new streams array.
|
||||
@NullableType SampleStream[] newStreams = new SampleStream[selections.length];
|
||||
@NullableType SampleStream[] childStreams = new SampleStream[selections.length];
|
||||
@NullableType TrackSelection[] childSelections = new TrackSelection[selections.length];
|
||||
@NullableType ExoTrackSelection[] childSelections = new ExoTrackSelection[selections.length];
|
||||
ArrayList<MediaPeriod> enabledPeriodsList = new ArrayList<>(periods.length);
|
||||
for (int i = 0; i < periods.length; i++) {
|
||||
for (int j = 0; j < selections.length; j++) {
|
||||
childStreams[j] = streamChildIndices[j] == i ? streams[j] : null;
|
||||
childSelections[j] = selectionChildIndices[j] == i ? selections[j] : null;
|
||||
}
|
||||
long selectPositionUs = periods[i].selectTracks(childSelections, mayRetainStreamFlags,
|
||||
childStreams, streamResetFlags, positionUs);
|
||||
long selectPositionUs =
|
||||
periods[i].selectTracks(
|
||||
childSelections, mayRetainStreamFlags, childStreams, streamResetFlags, positionUs);
|
||||
if (i == 0) {
|
||||
positionUs = selectPositionUs;
|
||||
} else if (selectPositionUs != positionUs) {
|
||||
|
|
@ -314,13 +313,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) {
|
||||
public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
|
||||
return mediaPeriod.getStreamKeys(trackSelections);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import com.google.android.exoplayer2.extractor.TrackOutput;
|
|||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.icy.IcyHeaders;
|
||||
import com.google.android.exoplayer2.source.SampleQueue.UpstreamFormatChangedListener;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
|
|
@ -252,7 +252,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
@ -277,7 +277,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
// Select new tracks.
|
||||
for (int i = 0; i < selections.length; i++) {
|
||||
if (streams[i] == null && selections[i] != null) {
|
||||
TrackSelection selection = selections[i];
|
||||
ExoTrackSelection selection = selections[i];
|
||||
Assertions.checkState(selection.length() == 1);
|
||||
Assertions.checkState(selection.getIndexInTrackGroup(0) == 0);
|
||||
int track = tracks.indexOf(selection.getTrackGroup());
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import com.google.android.exoplayer2.FormatHolder;
|
|||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.SeekParameters;
|
||||
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
|
|
@ -194,7 +194,7 @@ public final class SilenceMediaSource extends BaseMediaSource {
|
|||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import com.google.android.exoplayer2.FormatHolder;
|
|||
import com.google.android.exoplayer2.SeekParameters;
|
||||
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||
|
|
@ -41,15 +41,11 @@ import java.util.Arrays;
|
|||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* A {@link MediaPeriod} with a single sample.
|
||||
*/
|
||||
/* package */ final class SingleSampleMediaPeriod implements MediaPeriod,
|
||||
Loader.Callback<SingleSampleMediaPeriod.SourceLoadable> {
|
||||
/** A {@link MediaPeriod} with a single sample. */
|
||||
/* package */ final class SingleSampleMediaPeriod
|
||||
implements MediaPeriod, Loader.Callback<SingleSampleMediaPeriod.SourceLoadable> {
|
||||
|
||||
/**
|
||||
* The initial size of the allocation used to hold the sample data.
|
||||
*/
|
||||
/** The initial size of the allocation used to hold the sample data. */
|
||||
private static final int INITIAL_SAMPLE_SIZE = 1024;
|
||||
|
||||
private final DataSpec dataSpec;
|
||||
|
|
@ -113,7 +109,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
@ -348,8 +344,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
}
|
||||
|
||||
@Override
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
|
||||
boolean requireFormat) {
|
||||
public int readData(
|
||||
FormatHolder formatHolder, DecoderInputBuffer buffer, boolean requireFormat) {
|
||||
maybeNotifyDownstreamFormat();
|
||||
if (streamState == STREAM_STATE_END_OF_STREAM) {
|
||||
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
|
|
|
|||
|
|
@ -38,13 +38,13 @@ import java.util.List;
|
|||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/**
|
||||
* A bandwidth based adaptive {@link TrackSelection}, whose selected track is updated to be the one
|
||||
* of highest quality given the current network conditions and the state of the buffer.
|
||||
* A bandwidth based adaptive {@link ExoTrackSelection}, whose selected track is updated to be the
|
||||
* one of highest quality given the current network conditions and the state of the buffer.
|
||||
*/
|
||||
public class AdaptiveTrackSelection extends BaseTrackSelection {
|
||||
|
||||
/** Factory for {@link AdaptiveTrackSelection} instances. */
|
||||
public static class Factory implements TrackSelection.Factory {
|
||||
public static class Factory implements ExoTrackSelection.Factory {
|
||||
|
||||
private final int minDurationForQualityIncreaseMs;
|
||||
private final int maxDurationForQualityDecreaseMs;
|
||||
|
|
@ -132,14 +132,14 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
|
|||
}
|
||||
|
||||
@Override
|
||||
public final @NullableType TrackSelection[] createTrackSelections(
|
||||
public final @NullableType ExoTrackSelection[] createTrackSelections(
|
||||
@NullableType Definition[] definitions,
|
||||
BandwidthMeter bandwidthMeter,
|
||||
MediaPeriodId mediaPeriodId,
|
||||
Timeline timeline) {
|
||||
ImmutableList<ImmutableList<AdaptationCheckpoint>> adaptationCheckpoints =
|
||||
getAdaptationCheckpoints(definitions);
|
||||
TrackSelection[] selections = new TrackSelection[definitions.length];
|
||||
ExoTrackSelection[] selections = new ExoTrackSelection[definitions.length];
|
||||
for (int i = 0; i < definitions.length; i++) {
|
||||
@Nullable Definition definition = definitions[i];
|
||||
if (definition == null || definition.tracks.length == 0) {
|
||||
|
|
|
|||
|
|
@ -28,27 +28,17 @@ import com.google.android.exoplayer2.util.Util;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An abstract base class suitable for most {@link TrackSelection} implementations.
|
||||
*/
|
||||
public abstract class BaseTrackSelection implements TrackSelection {
|
||||
/** An abstract base class suitable for most {@link ExoTrackSelection} implementations. */
|
||||
public abstract class BaseTrackSelection implements ExoTrackSelection {
|
||||
|
||||
/**
|
||||
* The selected {@link TrackGroup}.
|
||||
*/
|
||||
/** The selected {@link TrackGroup}. */
|
||||
protected final TrackGroup group;
|
||||
/**
|
||||
* The number of selected tracks within the {@link TrackGroup}. Always greater than zero.
|
||||
*/
|
||||
/** The number of selected tracks within the {@link TrackGroup}. Always greater than zero. */
|
||||
protected final int length;
|
||||
/**
|
||||
* The indices of the selected tracks in {@link #group}, in order of decreasing bandwidth.
|
||||
*/
|
||||
/** The indices of the selected tracks in {@link #group}, in order of decreasing bandwidth. */
|
||||
protected final int[] tracks;
|
||||
|
||||
/**
|
||||
* The {@link Format}s of the selected tracks, in order of decreasing bandwidth.
|
||||
*/
|
||||
/** The {@link Format}s of the selected tracks, in order of decreasing bandwidth. */
|
||||
private final Format[] formats;
|
||||
/** Selected track exclusion timestamps, in order of decreasing bandwidth. */
|
||||
private final long[] excludeUntilTimes;
|
||||
|
|
|
|||
|
|
@ -222,7 +222,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
*
|
||||
* @param context Any context.
|
||||
*/
|
||||
|
||||
public ParametersBuilder(Context context) {
|
||||
super(context);
|
||||
setInitialValuesWithoutContext();
|
||||
|
|
@ -826,9 +825,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@link Parameters} instance with the selected values.
|
||||
*/
|
||||
/** Builds a {@link Parameters} instance with the selected values. */
|
||||
public Parameters build() {
|
||||
return new Parameters(
|
||||
// Video
|
||||
|
|
@ -1614,6 +1611,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
* dimension).
|
||||
*/
|
||||
private static final float FRACTION_TO_CONSIDER_FULLSCREEN = 0.98f;
|
||||
|
||||
private static final int[] NO_TRACKS = new int[0];
|
||||
/** Ordering of two format values. A known value is considered greater than Format#NO_VALUE. */
|
||||
private static final Ordering<Integer> FORMAT_VALUE_ORDERING =
|
||||
|
|
@ -1625,7 +1623,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
/** Ordering where all elements are equal. */
|
||||
private static final Ordering<Integer> NO_ORDER = Ordering.from((first, second) -> 0);
|
||||
|
||||
private final TrackSelection.Factory trackSelectionFactory;
|
||||
private final ExoTrackSelection.Factory trackSelectionFactory;
|
||||
private final AtomicReference<Parameters> parametersReference;
|
||||
|
||||
/** @deprecated Use {@link #DefaultTrackSelector(Context)} instead. */
|
||||
|
|
@ -1634,9 +1632,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
this(Parameters.DEFAULT_WITHOUT_CONTEXT, new AdaptiveTrackSelection.Factory());
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link #DefaultTrackSelector(Context, TrackSelection.Factory)}. */
|
||||
/** @deprecated Use {@link #DefaultTrackSelector(Context, ExoTrackSelection.Factory)}. */
|
||||
@Deprecated
|
||||
public DefaultTrackSelector(TrackSelection.Factory trackSelectionFactory) {
|
||||
public DefaultTrackSelector(ExoTrackSelection.Factory trackSelectionFactory) {
|
||||
this(Parameters.DEFAULT_WITHOUT_CONTEXT, trackSelectionFactory);
|
||||
}
|
||||
|
||||
|
|
@ -1647,17 +1645,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
|
||||
/**
|
||||
* @param context Any {@link Context}.
|
||||
* @param trackSelectionFactory A factory for {@link TrackSelection}s.
|
||||
* @param trackSelectionFactory A factory for {@link ExoTrackSelection}s.
|
||||
*/
|
||||
public DefaultTrackSelector(Context context, TrackSelection.Factory trackSelectionFactory) {
|
||||
public DefaultTrackSelector(Context context, ExoTrackSelection.Factory trackSelectionFactory) {
|
||||
this(Parameters.getDefaults(context), trackSelectionFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parameters Initial {@link Parameters}.
|
||||
* @param trackSelectionFactory A factory for {@link TrackSelection}s.
|
||||
* @param trackSelectionFactory A factory for {@link ExoTrackSelection}s.
|
||||
*/
|
||||
public DefaultTrackSelector(Parameters parameters, TrackSelection.Factory trackSelectionFactory) {
|
||||
public DefaultTrackSelector(
|
||||
Parameters parameters, ExoTrackSelection.Factory trackSelectionFactory) {
|
||||
this.trackSelectionFactory = trackSelectionFactory;
|
||||
parametersReference = new AtomicReference<>(parameters);
|
||||
}
|
||||
|
|
@ -1700,7 +1699,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
// MappingTrackSelector implementation.
|
||||
|
||||
@Override
|
||||
protected final Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]>
|
||||
protected final Pair<@NullableType RendererConfiguration[], @NullableType ExoTrackSelection[]>
|
||||
selectTracks(
|
||||
MappedTrackInfo mappedTrackInfo,
|
||||
@Capabilities int[][][] rendererFormatSupports,
|
||||
|
|
@ -1710,7 +1709,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
throws ExoPlaybackException {
|
||||
Parameters params = parametersReference.get();
|
||||
int rendererCount = mappedTrackInfo.getRendererCount();
|
||||
TrackSelection.@NullableType Definition[] definitions =
|
||||
ExoTrackSelection.@NullableType Definition[] definitions =
|
||||
selectAllTracks(
|
||||
mappedTrackInfo,
|
||||
rendererFormatSupports,
|
||||
|
|
@ -1729,7 +1728,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
definitions[i] =
|
||||
override == null
|
||||
? null
|
||||
: new TrackSelection.Definition(
|
||||
: new ExoTrackSelection.Definition(
|
||||
rendererTrackGroups.get(override.groupIndex),
|
||||
override.tracks,
|
||||
override.reason,
|
||||
|
|
@ -1738,14 +1737,14 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
}
|
||||
|
||||
@NullableType
|
||||
TrackSelection[] rendererTrackSelections =
|
||||
ExoTrackSelection[] rendererTrackSelections =
|
||||
trackSelectionFactory.createTrackSelections(
|
||||
definitions, getBandwidthMeter(), mediaPeriodId, timeline);
|
||||
|
||||
// Initialize the renderer configurations to the default configuration for all renderers with
|
||||
// selections, and null otherwise.
|
||||
@NullableType RendererConfiguration[] rendererConfigurations =
|
||||
new RendererConfiguration[rendererCount];
|
||||
@NullableType
|
||||
RendererConfiguration[] rendererConfigurations = new RendererConfiguration[rendererCount];
|
||||
for (int i = 0; i < rendererCount; i++) {
|
||||
boolean forceRendererDisabled = params.getRendererDisabled(i);
|
||||
boolean rendererEnabled =
|
||||
|
|
@ -1779,19 +1778,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
* renderer, track group and track (in that order).
|
||||
* @param rendererMixedMimeTypeAdaptationSupports The {@link AdaptiveSupport} for mixed MIME type
|
||||
* adaptation for the renderer.
|
||||
* @return The {@link TrackSelection.Definition}s for the renderers. A null entry indicates no
|
||||
* @return The {@link ExoTrackSelection.Definition}s for the renderers. A null entry indicates no
|
||||
* selection was made.
|
||||
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
|
||||
*/
|
||||
protected TrackSelection.@NullableType Definition[] selectAllTracks(
|
||||
protected ExoTrackSelection.@NullableType Definition[] selectAllTracks(
|
||||
MappedTrackInfo mappedTrackInfo,
|
||||
@Capabilities int[][][] rendererFormatSupports,
|
||||
@AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports,
|
||||
Parameters params)
|
||||
throws ExoPlaybackException {
|
||||
int rendererCount = mappedTrackInfo.getRendererCount();
|
||||
TrackSelection.@NullableType Definition[] definitions =
|
||||
new TrackSelection.Definition[rendererCount];
|
||||
ExoTrackSelection.@NullableType Definition[] definitions =
|
||||
new ExoTrackSelection.Definition[rendererCount];
|
||||
|
||||
boolean seenVideoRendererWithMappedTracks = false;
|
||||
boolean selectedVideoTracks = false;
|
||||
|
|
@ -1819,7 +1818,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
boolean enableAdaptiveTrackSelection =
|
||||
params.allowMultipleAdaptiveSelections || !seenVideoRendererWithMappedTracks;
|
||||
@Nullable
|
||||
Pair<TrackSelection.Definition, AudioTrackScore> audioSelection =
|
||||
Pair<ExoTrackSelection.Definition, AudioTrackScore> audioSelection =
|
||||
selectAudioTrack(
|
||||
mappedTrackInfo.getTrackGroups(i),
|
||||
rendererFormatSupports[i],
|
||||
|
|
@ -1834,7 +1833,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
// score. Clear the selection for that renderer.
|
||||
definitions[selectedAudioRendererIndex] = null;
|
||||
}
|
||||
TrackSelection.Definition definition = audioSelection.first;
|
||||
ExoTrackSelection.Definition definition = audioSelection.first;
|
||||
definitions[i] = definition;
|
||||
// We assume that audio tracks in the same group have matching language.
|
||||
selectedAudioLanguage = definition.group.getFormat(definition.tracks[0]).language;
|
||||
|
|
@ -1855,7 +1854,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
break;
|
||||
case C.TRACK_TYPE_TEXT:
|
||||
@Nullable
|
||||
Pair<TrackSelection.Definition, TextTrackScore> textSelection =
|
||||
Pair<ExoTrackSelection.Definition, TextTrackScore> textSelection =
|
||||
selectTextTrack(
|
||||
mappedTrackInfo.getTrackGroups(i),
|
||||
rendererFormatSupports[i],
|
||||
|
|
@ -1889,7 +1888,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
|
||||
/**
|
||||
* Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a
|
||||
* {@link TrackSelection} for a video renderer.
|
||||
* {@link ExoTrackSelection} for a video renderer.
|
||||
*
|
||||
* @param groups The {@link TrackGroupArray} mapped to the renderer.
|
||||
* @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and
|
||||
|
|
@ -1898,19 +1897,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
* adaptation for the renderer.
|
||||
* @param params The selector's current constraint parameters.
|
||||
* @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed.
|
||||
* @return The {@link TrackSelection.Definition} for the renderer, or null if no selection was
|
||||
* @return The {@link ExoTrackSelection.Definition} for the renderer, or null if no selection was
|
||||
* made.
|
||||
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
|
||||
*/
|
||||
@Nullable
|
||||
protected TrackSelection.Definition selectVideoTrack(
|
||||
protected ExoTrackSelection.Definition selectVideoTrack(
|
||||
TrackGroupArray groups,
|
||||
@Capabilities int[][] formatSupport,
|
||||
@AdaptiveSupport int mixedMimeTypeAdaptationSupports,
|
||||
Parameters params,
|
||||
boolean enableAdaptiveTrackSelection)
|
||||
throws ExoPlaybackException {
|
||||
TrackSelection.Definition definition = null;
|
||||
ExoTrackSelection.Definition definition = null;
|
||||
if (!params.forceHighestSupportedBitrate
|
||||
&& !params.forceLowestBitrate
|
||||
&& enableAdaptiveTrackSelection) {
|
||||
|
|
@ -1924,7 +1923,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
private static TrackSelection.Definition selectAdaptiveVideoTrack(
|
||||
private static ExoTrackSelection.Definition selectAdaptiveVideoTrack(
|
||||
TrackGroupArray groups,
|
||||
@Capabilities int[][] formatSupport,
|
||||
@AdaptiveSupport int mixedMimeTypeAdaptationSupports,
|
||||
|
|
@ -1956,7 +1955,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
params.viewportHeight,
|
||||
params.viewportOrientationMayChange);
|
||||
if (adaptiveTracks.length > 0) {
|
||||
return new TrackSelection.Definition(group, adaptiveTracks);
|
||||
return new ExoTrackSelection.Definition(group, adaptiveTracks);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
@ -1982,8 +1981,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
return NO_TRACKS;
|
||||
}
|
||||
|
||||
List<Integer> selectedTrackIndices = getViewportFilteredTrackIndices(group, viewportWidth,
|
||||
viewportHeight, viewportOrientationMayChange);
|
||||
List<Integer> selectedTrackIndices =
|
||||
getViewportFilteredTrackIndices(
|
||||
group, viewportWidth, viewportHeight, viewportOrientationMayChange);
|
||||
if (selectedTrackIndices.size() < 2) {
|
||||
return NO_TRACKS;
|
||||
}
|
||||
|
|
@ -2140,7 +2140,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
private static TrackSelection.Definition selectFixedVideoTrack(
|
||||
private static ExoTrackSelection.Definition selectFixedVideoTrack(
|
||||
TrackGroupArray groups, @Capabilities int[][] formatSupport, Parameters params) {
|
||||
int selectedTrackIndex = C.INDEX_UNSET;
|
||||
@Nullable TrackGroup selectedGroup = null;
|
||||
|
|
@ -2160,8 +2160,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
// Ignore trick-play tracks for now.
|
||||
continue;
|
||||
}
|
||||
if (isSupported(trackFormatSupport[trackIndex],
|
||||
params.exceedRendererCapabilitiesIfNecessary)) {
|
||||
if (isSupported(
|
||||
trackFormatSupport[trackIndex], params.exceedRendererCapabilitiesIfNecessary)) {
|
||||
VideoTrackScore trackScore =
|
||||
new VideoTrackScore(
|
||||
format,
|
||||
|
|
@ -2183,14 +2183,14 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
|
||||
return selectedGroup == null
|
||||
? null
|
||||
: new TrackSelection.Definition(selectedGroup, selectedTrackIndex);
|
||||
: new ExoTrackSelection.Definition(selectedGroup, selectedTrackIndex);
|
||||
}
|
||||
|
||||
// Audio track selection implementation.
|
||||
|
||||
/**
|
||||
* Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a
|
||||
* {@link TrackSelection} for an audio renderer.
|
||||
* {@link ExoTrackSelection} for an audio renderer.
|
||||
*
|
||||
* @param groups The {@link TrackGroupArray} mapped to the renderer.
|
||||
* @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and
|
||||
|
|
@ -2199,13 +2199,13 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
* adaptation for the renderer.
|
||||
* @param params The selector's current constraint parameters.
|
||||
* @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed.
|
||||
* @return The {@link TrackSelection.Definition} and corresponding {@link AudioTrackScore}, or
|
||||
* @return The {@link ExoTrackSelection.Definition} and corresponding {@link AudioTrackScore}, or
|
||||
* null if no selection was made.
|
||||
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Nullable
|
||||
protected Pair<TrackSelection.Definition, AudioTrackScore> selectAudioTrack(
|
||||
protected Pair<ExoTrackSelection.Definition, AudioTrackScore> selectAudioTrack(
|
||||
TrackGroupArray groups,
|
||||
@Capabilities int[][] formatSupport,
|
||||
@AdaptiveSupport int mixedMimeTypeAdaptationSupports,
|
||||
|
|
@ -2219,8 +2219,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
TrackGroup trackGroup = groups.get(groupIndex);
|
||||
@Capabilities int[] trackFormatSupport = formatSupport[groupIndex];
|
||||
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
||||
if (isSupported(trackFormatSupport[trackIndex],
|
||||
params.exceedRendererCapabilitiesIfNecessary)) {
|
||||
if (isSupported(
|
||||
trackFormatSupport[trackIndex], params.exceedRendererCapabilitiesIfNecessary)) {
|
||||
Format format = trackGroup.getFormat(trackIndex);
|
||||
AudioTrackScore trackScore =
|
||||
new AudioTrackScore(format, params, trackFormatSupport[trackIndex]);
|
||||
|
|
@ -2243,7 +2243,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
|
||||
TrackGroup selectedGroup = groups.get(selectedGroupIndex);
|
||||
|
||||
TrackSelection.Definition definition = null;
|
||||
ExoTrackSelection.Definition definition = null;
|
||||
if (!params.forceHighestSupportedBitrate
|
||||
&& !params.forceLowestBitrate
|
||||
&& enableAdaptiveTrackSelection) {
|
||||
|
|
@ -2258,12 +2258,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
params.allowAudioMixedSampleRateAdaptiveness,
|
||||
params.allowAudioMixedChannelCountAdaptiveness);
|
||||
if (adaptiveTracks.length > 1) {
|
||||
definition = new TrackSelection.Definition(selectedGroup, adaptiveTracks);
|
||||
definition = new ExoTrackSelection.Definition(selectedGroup, adaptiveTracks);
|
||||
}
|
||||
}
|
||||
if (definition == null) {
|
||||
// We didn't make an adaptive selection, so make a fixed one instead.
|
||||
definition = new TrackSelection.Definition(selectedGroup, selectedTrackIndex);
|
||||
definition = new ExoTrackSelection.Definition(selectedGroup, selectedTrackIndex);
|
||||
}
|
||||
|
||||
return Pair.create(definition, Assertions.checkNotNull(selectedTrackScore));
|
||||
|
|
@ -2322,7 +2322,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
|
||||
/**
|
||||
* Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a
|
||||
* {@link TrackSelection} for a text renderer.
|
||||
* {@link ExoTrackSelection} for a text renderer.
|
||||
*
|
||||
* @param groups The {@link TrackGroupArray} mapped to the renderer.
|
||||
* @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and
|
||||
|
|
@ -2330,12 +2330,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
* @param params The selector's current constraint parameters.
|
||||
* @param selectedAudioLanguage The language of the selected audio track. May be null if the
|
||||
* selected text track declares no language or no text track was selected.
|
||||
* @return The {@link TrackSelection.Definition} and corresponding {@link TextTrackScore}, or null
|
||||
* if no selection was made.
|
||||
* @return The {@link ExoTrackSelection.Definition} and corresponding {@link TextTrackScore}, or
|
||||
* null if no selection was made.
|
||||
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
|
||||
*/
|
||||
@Nullable
|
||||
protected Pair<TrackSelection.Definition, TextTrackScore> selectTextTrack(
|
||||
protected Pair<ExoTrackSelection.Definition, TextTrackScore> selectTextTrack(
|
||||
TrackGroupArray groups,
|
||||
@Capabilities int[][] formatSupport,
|
||||
Parameters params,
|
||||
|
|
@ -2348,8 +2348,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
TrackGroup trackGroup = groups.get(groupIndex);
|
||||
@Capabilities int[] trackFormatSupport = formatSupport[groupIndex];
|
||||
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
||||
if (isSupported(trackFormatSupport[trackIndex],
|
||||
params.exceedRendererCapabilitiesIfNecessary)) {
|
||||
if (isSupported(
|
||||
trackFormatSupport[trackIndex], params.exceedRendererCapabilitiesIfNecessary)) {
|
||||
Format format = trackGroup.getFormat(trackIndex);
|
||||
TextTrackScore trackScore =
|
||||
new TextTrackScore(
|
||||
|
|
@ -2366,7 +2366,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
return selectedGroup == null
|
||||
? null
|
||||
: Pair.create(
|
||||
new TrackSelection.Definition(selectedGroup, selectedTrackIndex),
|
||||
new ExoTrackSelection.Definition(selectedGroup, selectedTrackIndex),
|
||||
Assertions.checkNotNull(selectedTrackScore));
|
||||
}
|
||||
|
||||
|
|
@ -2374,18 +2374,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
|
||||
/**
|
||||
* Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a
|
||||
* {@link TrackSelection} for a renderer whose type is neither video, audio or text.
|
||||
* {@link ExoTrackSelection} for a renderer whose type is neither video, audio or text.
|
||||
*
|
||||
* @param trackType The type of the renderer.
|
||||
* @param groups The {@link TrackGroupArray} mapped to the renderer.
|
||||
* @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and
|
||||
* track (in that order).
|
||||
* @param params The selector's current constraint parameters.
|
||||
* @return The {@link TrackSelection} for the renderer, or null if no selection was made.
|
||||
* @return The {@link ExoTrackSelection} for the renderer, or null if no selection was made.
|
||||
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
|
||||
*/
|
||||
@Nullable
|
||||
protected TrackSelection.Definition selectOtherTrack(
|
||||
protected ExoTrackSelection.Definition selectOtherTrack(
|
||||
int trackType, TrackGroupArray groups, @Capabilities int[][] formatSupport, Parameters params)
|
||||
throws ExoPlaybackException {
|
||||
@Nullable TrackGroup selectedGroup = null;
|
||||
|
|
@ -2395,8 +2395,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
TrackGroup trackGroup = groups.get(groupIndex);
|
||||
@Capabilities int[] trackFormatSupport = formatSupport[groupIndex];
|
||||
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
|
||||
if (isSupported(trackFormatSupport[trackIndex],
|
||||
params.exceedRendererCapabilitiesIfNecessary)) {
|
||||
if (isSupported(
|
||||
trackFormatSupport[trackIndex], params.exceedRendererCapabilitiesIfNecessary)) {
|
||||
Format format = trackGroup.getFormat(trackIndex);
|
||||
OtherTrackScore trackScore = new OtherTrackScore(format, trackFormatSupport[trackIndex]);
|
||||
if (selectedTrackScore == null || trackScore.compareTo(selectedTrackScore) > 0) {
|
||||
|
|
@ -2409,7 +2409,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
}
|
||||
return selectedGroup == null
|
||||
? null
|
||||
: new TrackSelection.Definition(selectedGroup, selectedTrackIndex);
|
||||
: new ExoTrackSelection.Definition(selectedGroup, selectedTrackIndex);
|
||||
}
|
||||
|
||||
// Utility methods.
|
||||
|
|
@ -2430,7 +2430,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
MappedTrackInfo mappedTrackInfo,
|
||||
@Capabilities int[][][] renderererFormatSupports,
|
||||
@NullableType RendererConfiguration[] rendererConfigurations,
|
||||
@NullableType TrackSelection[] trackSelections) {
|
||||
@NullableType ExoTrackSelection[] trackSelections) {
|
||||
// Check whether we can enable tunneling. To enable tunneling we require exactly one audio and
|
||||
// one video renderer to support tunneling and have a selection.
|
||||
int tunnelingAudioRendererIndex = -1;
|
||||
|
|
@ -2438,7 +2438,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
boolean enableTunneling = true;
|
||||
for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
|
||||
int rendererType = mappedTrackInfo.getRendererType(i);
|
||||
TrackSelection trackSelection = trackSelections[i];
|
||||
ExoTrackSelection trackSelection = trackSelections[i];
|
||||
if ((rendererType == C.TRACK_TYPE_AUDIO || rendererType == C.TRACK_TYPE_VIDEO)
|
||||
&& trackSelection != null) {
|
||||
if (rendererSupportsTunneling(
|
||||
|
|
@ -2471,16 +2471,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns whether a renderer supports tunneling for a {@link TrackSelection}.
|
||||
* Returns whether a renderer supports tunneling for a {@link ExoTrackSelection}.
|
||||
*
|
||||
* @param formatSupport The {@link Capabilities} for each track, indexed by group index and track
|
||||
* index (in that order).
|
||||
* @param trackGroups The {@link TrackGroupArray}s for the renderer.
|
||||
* @param selection The track selection.
|
||||
* @return Whether the renderer supports tunneling for the {@link TrackSelection}.
|
||||
* @return Whether the renderer supports tunneling for the {@link ExoTrackSelection}.
|
||||
*/
|
||||
private static boolean rendererSupportsTunneling(
|
||||
@Capabilities int[][] formatSupport, TrackGroupArray trackGroups, TrackSelection selection) {
|
||||
@Capabilities int[][] formatSupport,
|
||||
TrackGroupArray trackGroups,
|
||||
ExoTrackSelection selection) {
|
||||
if (selection == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2565,8 +2567,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static List<Integer> getViewportFilteredTrackIndices(TrackGroup group, int viewportWidth,
|
||||
int viewportHeight, boolean orientationMayChange) {
|
||||
private static List<Integer> getViewportFilteredTrackIndices(
|
||||
TrackGroup group, int viewportWidth, int viewportHeight, boolean orientationMayChange) {
|
||||
// Initially include all indices.
|
||||
ArrayList<Integer> selectedTrackIndices = new ArrayList<>(group.length);
|
||||
for (int i = 0; i < group.length; i++) {
|
||||
|
|
@ -2585,8 +2587,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
// smallest to exceed the maximum size at which it can be displayed within the viewport.
|
||||
// We'll discard formats of higher resolution.
|
||||
if (format.width > 0 && format.height > 0) {
|
||||
Point maxVideoSizeInViewport = getMaxVideoSizeInViewport(orientationMayChange,
|
||||
viewportWidth, viewportHeight, format.width, format.height);
|
||||
Point maxVideoSizeInViewport =
|
||||
getMaxVideoSizeInViewport(
|
||||
orientationMayChange, viewportWidth, viewportHeight, format.width, format.height);
|
||||
int videoPixels = format.width * format.height;
|
||||
if (format.width >= (int) (maxVideoSizeInViewport.x * FRACTION_TO_CONSIDER_FULLSCREEN)
|
||||
&& format.height >= (int) (maxVideoSizeInViewport.y * FRACTION_TO_CONSIDER_FULLSCREEN)
|
||||
|
|
@ -2616,8 +2619,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
* Given viewport dimensions and video dimensions, computes the maximum size of the video as it
|
||||
* will be rendered to fit inside of the viewport.
|
||||
*/
|
||||
private static Point getMaxVideoSizeInViewport(boolean orientationMayChange, int viewportWidth,
|
||||
int viewportHeight, int videoWidth, int videoHeight) {
|
||||
private static Point getMaxVideoSizeInViewport(
|
||||
boolean orientationMayChange,
|
||||
int viewportWidth,
|
||||
int viewportHeight,
|
||||
int videoWidth,
|
||||
int videoHeight) {
|
||||
if (orientationMayChange && (videoWidth > videoHeight) != (viewportWidth > viewportHeight)) {
|
||||
// Rotation is allowed, and the video will be larger in the rotated viewport.
|
||||
int tempViewportWidth = viewportWidth;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.trackselection;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
import com.google.android.exoplayer2.source.chunk.Chunk;
|
||||
import com.google.android.exoplayer2.source.chunk.MediaChunk;
|
||||
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/**
|
||||
* A {@link TrackSelection} that can change the individually selected track as a result of calling
|
||||
* {@link #updateSelectedTrack(long, long, long, List, MediaChunkIterator[])} or {@link
|
||||
* #evaluateQueueSize(long, List)}. This only happens between calls to {@link #enable()} and {@link
|
||||
* #disable()}.
|
||||
*/
|
||||
public interface ExoTrackSelection extends 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;
|
||||
/** The track selection reason. One of the {@link C} SELECTION_REASON_ constants. */
|
||||
public final int reason;
|
||||
/** Optional data associated with this selection of tracks. */
|
||||
@Nullable public final Object data;
|
||||
|
||||
/**
|
||||
* @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, tracks, C.SELECTION_REASON_UNKNOWN, /* data= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param group The {@link TrackGroup}. Must not be null.
|
||||
* @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
|
||||
* @param reason The track selection reason. One of the {@link C} SELECTION_REASON_ constants.
|
||||
* @param data Optional data associated with this selection of tracks.
|
||||
*/
|
||||
public Definition(TrackGroup group, int[] tracks, int reason, @Nullable Object data) {
|
||||
this.group = group;
|
||||
this.tracks = tracks;
|
||||
this.reason = reason;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
/** Factory for {@link ExoTrackSelection} instances. */
|
||||
interface Factory {
|
||||
|
||||
/**
|
||||
* Creates track selections for the provided {@link Definition Definitions}.
|
||||
*
|
||||
* <p>Implementations that create at most one adaptive track selection may use {@link
|
||||
* TrackSelectionUtil#createTrackSelectionsForDefinitions}.
|
||||
*
|
||||
* @param definitions A {@link Definition} array. May include null values.
|
||||
* @param bandwidthMeter A {@link BandwidthMeter} which can be used to select tracks.
|
||||
* @param mediaPeriodId The {@link MediaPeriodId} of the period for which tracks are to be
|
||||
* selected.
|
||||
* @param timeline The {@link Timeline} holding the period for which tracks are to be selected.
|
||||
* @return The created selections. Must have the same length as {@code definitions} and may
|
||||
* include null values.
|
||||
*/
|
||||
@NullableType
|
||||
ExoTrackSelection[] createTrackSelections(
|
||||
@NullableType Definition[] definitions,
|
||||
BandwidthMeter bandwidthMeter,
|
||||
MediaPeriodId mediaPeriodId,
|
||||
Timeline timeline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the track selection. Dynamic changes via {@link #updateSelectedTrack(long, long, long,
|
||||
* List, MediaChunkIterator[])}, {@link #evaluateQueueSize(long, List)} or {@link
|
||||
* #shouldCancelChunkLoad(long, Chunk, List)} will only happen after this call.
|
||||
*
|
||||
* <p>This method may not be called when the track selection is already enabled.
|
||||
*/
|
||||
void enable();
|
||||
|
||||
/**
|
||||
* Disables this track selection. No further dynamic changes via {@link #updateSelectedTrack(long,
|
||||
* long, long, List, MediaChunkIterator[])}, {@link #evaluateQueueSize(long, List)} or {@link
|
||||
* #shouldCancelChunkLoad(long, Chunk, List)} will happen after this call.
|
||||
*
|
||||
* <p>This method may only be called when the track selection is already enabled.
|
||||
*/
|
||||
void disable();
|
||||
|
||||
// Individual selected track.
|
||||
|
||||
/** Returns the {@link Format} of the individual selected track. */
|
||||
Format getSelectedFormat();
|
||||
|
||||
/** Returns the index in the track group of the individual selected track. */
|
||||
int getSelectedIndexInTrackGroup();
|
||||
|
||||
/** Returns the index of the selected track. */
|
||||
int getSelectedIndex();
|
||||
|
||||
/** Returns the reason for the current track selection. */
|
||||
int getSelectionReason();
|
||||
|
||||
/** Returns optional data associated with the current track selection. */
|
||||
@Nullable
|
||||
Object getSelectionData();
|
||||
|
||||
// Adaptation.
|
||||
|
||||
/**
|
||||
* Called to notify the selection of the current playback speed. The playback speed may affect
|
||||
* adaptive track selection.
|
||||
*
|
||||
* @param speed The factor by which playback is sped up.
|
||||
*/
|
||||
void onPlaybackSpeed(float speed);
|
||||
|
||||
/**
|
||||
* Called to notify the selection of a position discontinuity.
|
||||
*
|
||||
* <p>This happens when the playback position jumps, e.g., as a result of a seek being performed.
|
||||
*/
|
||||
default void onDiscontinuity() {}
|
||||
|
||||
/**
|
||||
* Called to notify when a rebuffer occurred.
|
||||
*
|
||||
* <p>A rebuffer is defined to be caused by buffer depletion rather than a user action. Hence this
|
||||
* method is not called during initial buffering or when buffering as a result of a seek
|
||||
* operation.
|
||||
*/
|
||||
default void onRebuffer() {}
|
||||
|
||||
/**
|
||||
* Called to notify when the playback is paused or resumed.
|
||||
*
|
||||
* @param playWhenReady Whether playback will proceed when ready.
|
||||
*/
|
||||
default void onPlayWhenReadyChanged(boolean playWhenReady) {}
|
||||
|
||||
/**
|
||||
* Updates the selected track for sources that load media in discrete {@link MediaChunk}s.
|
||||
*
|
||||
* <p>This method will only be called when the selection is enabled.
|
||||
*
|
||||
* @param playbackPositionUs The current playback position in microseconds. If playback of the
|
||||
* period to which this track selection belongs has not yet started, the value will be the
|
||||
* starting position in the period minus the duration of any media in previous periods still
|
||||
* to be played.
|
||||
* @param bufferedDurationUs The duration of media currently buffered from the current playback
|
||||
* position, in microseconds. Note that the next load position can be calculated as {@code
|
||||
* (playbackPositionUs + bufferedDurationUs)}.
|
||||
* @param availableDurationUs The duration of media available for buffering from the current
|
||||
* playback position, in microseconds, or {@link C#TIME_UNSET} if media can be buffered to the
|
||||
* end of the current period. Note that if not set to {@link C#TIME_UNSET}, the position up to
|
||||
* which media is available for buffering can be calculated as {@code (playbackPositionUs +
|
||||
* availableDurationUs)}.
|
||||
* @param queue The queue of already buffered {@link MediaChunk}s. Must not be modified.
|
||||
* @param mediaChunkIterators An array of {@link MediaChunkIterator}s providing information about
|
||||
* the sequence of upcoming media chunks for each track in the selection. All iterators start
|
||||
* from the media chunk which will be loaded next if the respective track is selected. Note
|
||||
* that this information may not be available for all tracks, and so some iterators may be
|
||||
* empty.
|
||||
*/
|
||||
void updateSelectedTrack(
|
||||
long playbackPositionUs,
|
||||
long bufferedDurationUs,
|
||||
long availableDurationUs,
|
||||
List<? extends MediaChunk> queue,
|
||||
MediaChunkIterator[] mediaChunkIterators);
|
||||
|
||||
/**
|
||||
* Returns the number of chunks that should be retained in the queue.
|
||||
*
|
||||
* <p>May be called by sources that load media in discrete {@link MediaChunk MediaChunks} and
|
||||
* support discarding of buffered chunks.
|
||||
*
|
||||
* <p>To avoid excessive re-buffering, implementations should normally return the size of the
|
||||
* queue. An example of a case where a smaller value may be returned is if network conditions have
|
||||
* improved dramatically, allowing chunks to be discarded and re-buffered in a track of
|
||||
* significantly higher quality. Discarding chunks may allow faster switching to a higher quality
|
||||
* track in this case.
|
||||
*
|
||||
* <p>Note that even if the source supports discarding of buffered chunks, the actual number of
|
||||
* discarded chunks is not guaranteed. The source will call {@link #updateSelectedTrack(long,
|
||||
* long, long, List, MediaChunkIterator[])} with the updated queue of chunks before loading a new
|
||||
* chunk to allow switching to another quality.
|
||||
*
|
||||
* <p>This method will only be called when the selection is enabled and none of the {@link
|
||||
* MediaChunk MediaChunks} in the queue are currently loading.
|
||||
*
|
||||
* @param playbackPositionUs The current playback position in microseconds. If playback of the
|
||||
* period to which this track selection belongs has not yet started, the value will be the
|
||||
* starting position in the period minus the duration of any media in previous periods still
|
||||
* to be played.
|
||||
* @param queue The queue of buffered {@link MediaChunk MediaChunks}. Must not be modified.
|
||||
* @return The number of chunks to retain in the queue.
|
||||
*/
|
||||
int evaluateQueueSize(long playbackPositionUs, List<? extends MediaChunk> queue);
|
||||
|
||||
/**
|
||||
* Returns whether an ongoing load of a chunk should be canceled.
|
||||
*
|
||||
* <p>May be called by sources that load media in discrete {@link MediaChunk MediaChunks} and
|
||||
* support canceling the ongoing chunk load. The ongoing chunk load is either the last {@link
|
||||
* MediaChunk} in the queue or another type of {@link Chunk}, for example, if the source loads
|
||||
* initialization or encryption data.
|
||||
*
|
||||
* <p>To avoid excessive re-buffering, implementations should normally return {@code false}. An
|
||||
* example where {@code true} might be returned is if a load of a high quality chunk gets stuck
|
||||
* and canceling this load in favor of a lower quality alternative may avoid a rebuffer.
|
||||
*
|
||||
* <p>The source will call {@link #evaluateQueueSize(long, List)} after the cancelation finishes
|
||||
* to allow discarding of chunks, and {@link #updateSelectedTrack(long, long, long, List,
|
||||
* MediaChunkIterator[])} before loading a new chunk to allow switching to another quality.
|
||||
*
|
||||
* <p>This method will only be called when the selection is enabled.
|
||||
*
|
||||
* @param playbackPositionUs The current playback position in microseconds. If playback of the
|
||||
* period to which this track selection belongs has not yet started, the value will be the
|
||||
* starting position in the period minus the duration of any media in previous periods still
|
||||
* to be played.
|
||||
* @param loadingChunk The currently loading {@link Chunk} that will be canceled if this method
|
||||
* returns {@code true}.
|
||||
* @param queue The queue of buffered {@link MediaChunk MediaChunks}, including the {@code
|
||||
* loadingChunk} if it's a {@link MediaChunk}. Must not be modified.
|
||||
* @return Whether the ongoing load of {@code loadingChunk} should be canceled.
|
||||
*/
|
||||
default boolean shouldCancelChunkLoad(
|
||||
long playbackPositionUs, Chunk loadingChunk, List<? extends MediaChunk> queue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to exclude the track at the specified index in the selection, making it ineligible for
|
||||
* selection by calls to {@link #updateSelectedTrack(long, long, long, List,
|
||||
* MediaChunkIterator[])} for the specified period of time.
|
||||
*
|
||||
* <p>Exclusion will fail if all other tracks are currently excluded. If excluding the currently
|
||||
* selected track, note that it will remain selected until the next call to {@link
|
||||
* #updateSelectedTrack(long, long, long, List, MediaChunkIterator[])}.
|
||||
*
|
||||
* <p>This method will only be called when the selection is enabled.
|
||||
*
|
||||
* @param index The index of the track in the selection.
|
||||
* @param exclusionDurationMs The duration of time for which the track should be excluded, in
|
||||
* milliseconds.
|
||||
* @return Whether exclusion was successful.
|
||||
*/
|
||||
boolean blacklist(int index, long exclusionDurationMs);
|
||||
}
|
||||
|
|
@ -43,14 +43,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
|
||||
/**
|
||||
* Base class for {@link TrackSelector}s that first establish a mapping between {@link TrackGroup}s
|
||||
* and {@link Renderer}s, and then from that mapping create a {@link TrackSelection} for each
|
||||
* and {@link Renderer}s, and then from that mapping create a {@link ExoTrackSelection} for each
|
||||
* renderer.
|
||||
*/
|
||||
public abstract class MappingTrackSelector extends TrackSelector {
|
||||
|
||||
/**
|
||||
* Provides mapped track information for each renderer.
|
||||
*/
|
||||
/** Provides mapped track information for each renderer. */
|
||||
public static final class MappedTrackInfo {
|
||||
|
||||
/**
|
||||
|
|
@ -401,7 +399,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||
rendererFormatSupports,
|
||||
unmappedTrackGroupArray);
|
||||
|
||||
Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]> result =
|
||||
Pair<@NullableType RendererConfiguration[], @NullableType ExoTrackSelection[]> result =
|
||||
selectTracks(
|
||||
mappedTrackInfo,
|
||||
rendererFormatSupports,
|
||||
|
|
@ -428,7 +426,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||
* RendererCapabilities#getTrackType()} is {@link C#TRACK_TYPE_NONE}.
|
||||
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
|
||||
*/
|
||||
protected abstract Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]>
|
||||
protected abstract Pair<@NullableType RendererConfiguration[], @NullableType ExoTrackSelection[]>
|
||||
selectTracks(
|
||||
MappedTrackInfo mappedTrackInfo,
|
||||
@Capabilities int[][][] rendererFormatSupports,
|
||||
|
|
@ -538,5 +536,4 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||
}
|
||||
return mixedMimeTypeAdaptationSupport;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,15 +28,11 @@ import java.util.List;
|
|||
import java.util.Random;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/**
|
||||
* A {@link TrackSelection} whose selected track is updated randomly.
|
||||
*/
|
||||
/** An {@link ExoTrackSelection} whose selected track is updated randomly. */
|
||||
public final class RandomTrackSelection extends BaseTrackSelection {
|
||||
|
||||
/**
|
||||
* Factory for {@link RandomTrackSelection} instances.
|
||||
*/
|
||||
public static final class Factory implements TrackSelection.Factory {
|
||||
/** Factory for {@link RandomTrackSelection} instances. */
|
||||
public static final class Factory implements ExoTrackSelection.Factory {
|
||||
|
||||
private final Random random;
|
||||
|
||||
|
|
@ -44,15 +40,13 @@ public final class RandomTrackSelection extends BaseTrackSelection {
|
|||
random = new Random();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param seed A seed for the {@link Random} instance used by the factory.
|
||||
*/
|
||||
/** @param seed A seed for the {@link Random} instance used by the factory. */
|
||||
public Factory(int seed) {
|
||||
random = new Random(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NullableType TrackSelection[] createTrackSelections(
|
||||
public @NullableType ExoTrackSelection[] createTrackSelections(
|
||||
@NullableType Definition[] definitions,
|
||||
BandwidthMeter bandwidthMeter,
|
||||
MediaPeriodId mediaPeriodId,
|
||||
|
|
@ -144,5 +138,4 @@ public final class RandomTrackSelection extends BaseTrackSelection {
|
|||
public Object getSelectionData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,107 +15,18 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2.trackselection;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
import com.google.android.exoplayer2.source.chunk.Chunk;
|
||||
import com.google.android.exoplayer2.source.chunk.MediaChunk;
|
||||
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
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
|
||||
* TrackGroup}, and a possibly varying individual selected track from the subset.
|
||||
* TrackGroup}.
|
||||
*
|
||||
* <p>Tracks belonging to the subset are exposed in decreasing bandwidth order. The individual
|
||||
* selected track may change dynamically as a result of calling {@link #updateSelectedTrack(long,
|
||||
* long, long, List, MediaChunkIterator[])} or {@link #evaluateQueueSize(long, List)}. This only
|
||||
* happens between calls to {@link #enable()} and {@link #disable()}.
|
||||
* <p>Tracks belonging to the subset are exposed in decreasing bandwidth order.
|
||||
*/
|
||||
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;
|
||||
/** The track selection reason. One of the {@link C} SELECTION_REASON_ constants. */
|
||||
public final int reason;
|
||||
/** Optional data associated with this selection of tracks. */
|
||||
@Nullable public final Object data;
|
||||
|
||||
/**
|
||||
* @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, tracks, C.SELECTION_REASON_UNKNOWN, /* data= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param group The {@link TrackGroup}. Must not be null.
|
||||
* @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
|
||||
* @param reason The track selection reason. One of the {@link C} SELECTION_REASON_ constants.
|
||||
* @param data Optional data associated with this selection of tracks.
|
||||
*/
|
||||
public Definition(TrackGroup group, int[] tracks, int reason, @Nullable Object data) {
|
||||
this.group = group;
|
||||
this.tracks = tracks;
|
||||
this.reason = reason;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
/** Factory for {@link TrackSelection} instances. */
|
||||
interface Factory {
|
||||
|
||||
/**
|
||||
* Creates track selections for the provided {@link Definition Definitions}.
|
||||
*
|
||||
* <p>Implementations that create at most one adaptive track selection may use {@link
|
||||
* TrackSelectionUtil#createTrackSelectionsForDefinitions}.
|
||||
*
|
||||
* @param definitions A {@link Definition} array. May include null values.
|
||||
* @param bandwidthMeter A {@link BandwidthMeter} which can be used to select tracks.
|
||||
* @param mediaPeriodId The {@link MediaPeriodId} of the period for which tracks are to be
|
||||
* selected.
|
||||
* @param timeline The {@link Timeline} holding the period for which tracks are to be selected.
|
||||
* @return The created selections. Must have the same length as {@code definitions} and may
|
||||
* include null values.
|
||||
*/
|
||||
@NullableType
|
||||
TrackSelection[] createTrackSelections(
|
||||
@NullableType Definition[] definitions,
|
||||
BandwidthMeter bandwidthMeter,
|
||||
MediaPeriodId mediaPeriodId,
|
||||
Timeline timeline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the track selection. Dynamic changes via {@link #updateSelectedTrack(long, long, long,
|
||||
* List, MediaChunkIterator[])}, {@link #evaluateQueueSize(long, List)} or {@link
|
||||
* #shouldCancelChunkLoad(long, Chunk, List)} will only happen after this call.
|
||||
*
|
||||
* <p>This method may not be called when the track selection is already enabled.
|
||||
*/
|
||||
void enable();
|
||||
|
||||
/**
|
||||
* Disables this track selection. No further dynamic changes via {@link #updateSelectedTrack(long,
|
||||
* long, long, List, MediaChunkIterator[])}, {@link #evaluateQueueSize(long, List)} or {@link
|
||||
* #shouldCancelChunkLoad(long, Chunk, List)} will happen after this call.
|
||||
*
|
||||
* <p>This method may only be called when the track selection is already enabled.
|
||||
*/
|
||||
void disable();
|
||||
|
||||
/** Returns the {@link TrackGroup} to which the selected tracks belong. */
|
||||
TrackGroup getTrackGroup();
|
||||
|
||||
|
|
@ -159,166 +70,4 @@ public interface TrackSelection {
|
|||
* index is not part of the selection.
|
||||
*/
|
||||
int indexOf(int indexInTrackGroup);
|
||||
|
||||
// Individual selected track.
|
||||
|
||||
/** Returns the {@link Format} of the individual selected track. */
|
||||
Format getSelectedFormat();
|
||||
|
||||
/** Returns the index in the track group of the individual selected track. */
|
||||
int getSelectedIndexInTrackGroup();
|
||||
|
||||
/** Returns the index of the selected track. */
|
||||
int getSelectedIndex();
|
||||
|
||||
/** Returns the reason for the current track selection. */
|
||||
int getSelectionReason();
|
||||
|
||||
/** Returns optional data associated with the current track selection. */
|
||||
@Nullable
|
||||
Object getSelectionData();
|
||||
|
||||
// Adaptation.
|
||||
|
||||
/**
|
||||
* Called to notify the selection of the current playback speed. The playback speed may affect
|
||||
* adaptive track selection.
|
||||
*
|
||||
* @param speed The factor by which playback is sped up.
|
||||
*/
|
||||
void onPlaybackSpeed(float speed);
|
||||
|
||||
/**
|
||||
* Called to notify the selection of a position discontinuity.
|
||||
*
|
||||
* <p>This happens when the playback position jumps, e.g., as a result of a seek being performed.
|
||||
*/
|
||||
default void onDiscontinuity() {}
|
||||
|
||||
/**
|
||||
* Called to notify when a rebuffer occurred.
|
||||
*
|
||||
* <p>A rebuffer is defined to be caused by buffer depletion rather than a user action. Hence this
|
||||
* method is not called during initial buffering or when buffering as a result of a seek
|
||||
* operation.
|
||||
*/
|
||||
default void onRebuffer() {}
|
||||
|
||||
/**
|
||||
* Called to notify when the playback is paused or resumed.
|
||||
*
|
||||
* @param playWhenReady Whether playback will proceed when ready.
|
||||
*/
|
||||
default void onPlayWhenReadyChanged(boolean playWhenReady) {}
|
||||
|
||||
/**
|
||||
* Updates the selected track for sources that load media in discrete {@link MediaChunk}s.
|
||||
*
|
||||
* <p>This method will only be called when the selection is enabled.
|
||||
*
|
||||
* @param playbackPositionUs The current playback position in microseconds. If playback of the
|
||||
* period to which this track selection belongs has not yet started, the value will be the
|
||||
* starting position in the period minus the duration of any media in previous periods still
|
||||
* to be played.
|
||||
* @param bufferedDurationUs The duration of media currently buffered from the current playback
|
||||
* position, in microseconds. Note that the next load position can be calculated as {@code
|
||||
* (playbackPositionUs + bufferedDurationUs)}.
|
||||
* @param availableDurationUs The duration of media available for buffering from the current
|
||||
* playback position, in microseconds, or {@link C#TIME_UNSET} if media can be buffered to the
|
||||
* end of the current period. Note that if not set to {@link C#TIME_UNSET}, the position up to
|
||||
* which media is available for buffering can be calculated as {@code (playbackPositionUs +
|
||||
* availableDurationUs)}.
|
||||
* @param queue The queue of already buffered {@link MediaChunk}s. Must not be modified.
|
||||
* @param mediaChunkIterators An array of {@link MediaChunkIterator}s providing information about
|
||||
* the sequence of upcoming media chunks for each track in the selection. All iterators start
|
||||
* from the media chunk which will be loaded next if the respective track is selected. Note
|
||||
* that this information may not be available for all tracks, and so some iterators may be
|
||||
* empty.
|
||||
*/
|
||||
void updateSelectedTrack(
|
||||
long playbackPositionUs,
|
||||
long bufferedDurationUs,
|
||||
long availableDurationUs,
|
||||
List<? extends MediaChunk> queue,
|
||||
MediaChunkIterator[] mediaChunkIterators);
|
||||
|
||||
/**
|
||||
* Returns the number of chunks that should be retained in the queue.
|
||||
*
|
||||
* <p>May be called by sources that load media in discrete {@link MediaChunk MediaChunks} and
|
||||
* support discarding of buffered chunks.
|
||||
*
|
||||
* <p>To avoid excessive re-buffering, implementations should normally return the size of the
|
||||
* queue. An example of a case where a smaller value may be returned is if network conditions have
|
||||
* improved dramatically, allowing chunks to be discarded and re-buffered in a track of
|
||||
* significantly higher quality. Discarding chunks may allow faster switching to a higher quality
|
||||
* track in this case.
|
||||
*
|
||||
* <p>Note that even if the source supports discarding of buffered chunks, the actual number of
|
||||
* discarded chunks is not guaranteed. The source will call {@link #updateSelectedTrack(long,
|
||||
* long, long, List, MediaChunkIterator[])} with the updated queue of chunks before loading a new
|
||||
* chunk to allow switching to another quality.
|
||||
*
|
||||
* <p>This method will only be called when the selection is enabled and none of the {@link
|
||||
* MediaChunk MediaChunks} in the queue are currently loading.
|
||||
*
|
||||
* @param playbackPositionUs The current playback position in microseconds. If playback of the
|
||||
* period to which this track selection belongs has not yet started, the value will be the
|
||||
* starting position in the period minus the duration of any media in previous periods still
|
||||
* to be played.
|
||||
* @param queue The queue of buffered {@link MediaChunk MediaChunks}. Must not be modified.
|
||||
* @return The number of chunks to retain in the queue.
|
||||
*/
|
||||
int evaluateQueueSize(long playbackPositionUs, List<? extends MediaChunk> queue);
|
||||
|
||||
/**
|
||||
* Returns whether an ongoing load of a chunk should be canceled.
|
||||
*
|
||||
* <p>May be called by sources that load media in discrete {@link MediaChunk MediaChunks} and
|
||||
* support canceling the ongoing chunk load. The ongoing chunk load is either the last {@link
|
||||
* MediaChunk} in the queue or another type of {@link Chunk}, for example, if the source loads
|
||||
* initialization or encryption data.
|
||||
*
|
||||
* <p>To avoid excessive re-buffering, implementations should normally return {@code false}. An
|
||||
* example where {@code true} might be returned is if a load of a high quality chunk gets stuck
|
||||
* and canceling this load in favor of a lower quality alternative may avoid a rebuffer.
|
||||
*
|
||||
* <p>The source will call {@link #evaluateQueueSize(long, List)} after the cancelation finishes
|
||||
* to allow discarding of chunks, and {@link #updateSelectedTrack(long, long, long, List,
|
||||
* MediaChunkIterator[])} before loading a new chunk to allow switching to another quality.
|
||||
*
|
||||
* <p>This method will only be called when the selection is enabled.
|
||||
*
|
||||
* @param playbackPositionUs The current playback position in microseconds. If playback of the
|
||||
* period to which this track selection belongs has not yet started, the value will be the
|
||||
* starting position in the period minus the duration of any media in previous periods still
|
||||
* to be played.
|
||||
* @param loadingChunk The currently loading {@link Chunk} that will be canceled if this method
|
||||
* returns {@code true}.
|
||||
* @param queue The queue of buffered {@link MediaChunk MediaChunks}, including the {@code
|
||||
* loadingChunk} if it's a {@link MediaChunk}. Must not be modified.
|
||||
* @return Whether the ongoing load of {@code loadingChunk} should be canceled.
|
||||
*/
|
||||
default boolean shouldCancelChunkLoad(
|
||||
long playbackPositionUs, Chunk loadingChunk, List<? extends MediaChunk> queue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to exclude the track at the specified index in the selection, making it ineligible for
|
||||
* selection by calls to {@link #updateSelectedTrack(long, long, long, List,
|
||||
* MediaChunkIterator[])} for the specified period of time.
|
||||
*
|
||||
* <p>Exclusion will fail if all other tracks are currently excluded. If excluding the currently
|
||||
* selected track, note that it will remain selected until the next call to {@link
|
||||
* #updateSelectedTrack(long, long, long, List, MediaChunkIterator[])}.
|
||||
*
|
||||
* <p>This method will only be called when the selection is enabled.
|
||||
*
|
||||
* @param index The index of the track in the selection.
|
||||
* @param exclusionDurationMs The duration of time for which the track should be excluded, in
|
||||
* milliseconds.
|
||||
* @return Whether exclusion was successful.
|
||||
*/
|
||||
boolean blacklist(int index, long exclusionDurationMs);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package com.google.android.exoplayer2.trackselection;
|
|||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection.Definition;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection.Definition;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
/** Track selection related utility methods. */
|
||||
|
|
@ -35,7 +35,7 @@ public final class TrackSelectionUtil {
|
|||
* @param trackSelectionDefinition A {@link Definition} for the track selection.
|
||||
* @return The created track selection.
|
||||
*/
|
||||
TrackSelection createAdaptiveTrackSelection(Definition trackSelectionDefinition);
|
||||
ExoTrackSelection createAdaptiveTrackSelection(Definition trackSelectionDefinition);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -48,10 +48,10 @@ public final class TrackSelectionUtil {
|
|||
* @return The array of created track selection. For null entries in {@code definitions} returns
|
||||
* null values.
|
||||
*/
|
||||
public static @NullableType TrackSelection[] createTrackSelectionsForDefinitions(
|
||||
public static @NullableType ExoTrackSelection[] createTrackSelectionsForDefinitions(
|
||||
@NullableType Definition[] definitions,
|
||||
AdaptiveTrackSelectionFactory adaptiveTrackSelectionFactory) {
|
||||
TrackSelection[] selections = new TrackSelection[definitions.length];
|
||||
ExoTrackSelection[] selections = new ExoTrackSelection[definitions.length];
|
||||
boolean createdAdaptiveTrackSelection = false;
|
||||
for (int i = 0; i < definitions.length; i++) {
|
||||
Definition definition = definitions[i];
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ public final class TrackSelectorResult {
|
|||
* renderer should be disabled.
|
||||
*/
|
||||
public final @NullableType RendererConfiguration[] rendererConfigurations;
|
||||
/** A {@link TrackSelection} array containing the track selection for each renderer. */
|
||||
public final @NullableType TrackSelection[] selections;
|
||||
/** A {@link ExoTrackSelection} array containing the track selection for each renderer. */
|
||||
public final @NullableType ExoTrackSelection[] selections;
|
||||
/**
|
||||
* An opaque object that will be returned to {@link TrackSelector#onSelectionActivated(Object)}
|
||||
* should the selections be activated.
|
||||
|
|
@ -41,14 +41,14 @@ public final class TrackSelectorResult {
|
|||
/**
|
||||
* @param rendererConfigurations A {@link RendererConfiguration} for each renderer. A null entry
|
||||
* indicates the corresponding renderer should be disabled.
|
||||
* @param selections A {@link TrackSelection} array containing the selection for each renderer.
|
||||
* @param selections A {@link ExoTrackSelection} array 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. May be
|
||||
* {@code null}.
|
||||
*/
|
||||
public TrackSelectorResult(
|
||||
@NullableType RendererConfiguration[] rendererConfigurations,
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
@Nullable Object info) {
|
||||
this.rendererConfigurations = rendererConfigurations;
|
||||
this.selections = selections.clone();
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.DefaultLoadControl.Builder;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DefaultAllocator;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
|
@ -177,7 +177,7 @@ public class DefaultLoadControlTest {
|
|||
@Test
|
||||
public void shouldContinueLoading_withNoSelectedTracks_returnsTrue() {
|
||||
loadControl = builder.build();
|
||||
loadControl.onTracksSelected(new Renderer[0], TrackGroupArray.EMPTY, new TrackSelection[0]);
|
||||
loadControl.onTracksSelected(new Renderer[0], TrackGroupArray.EMPTY, new ExoTrackSelection[0]);
|
||||
|
||||
assertThat(
|
||||
loadControl.shouldContinueLoading(
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import com.google.android.exoplayer2.testutil.FakeMediaSource;
|
|||
import com.google.android.exoplayer2.testutil.FakeShuffleOrder;
|
||||
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
||||
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
|
|
@ -470,7 +470,7 @@ public final class MediaPeriodQueueTest {
|
|||
mediaSourceList,
|
||||
getNextMediaPeriodInfo(),
|
||||
new TrackSelectorResult(
|
||||
new RendererConfiguration[0], new TrackSelection[0], /* info= */ null));
|
||||
new RendererConfiguration[0], new ExoTrackSelection[0], /* info= */ null));
|
||||
}
|
||||
|
||||
private MediaPeriodInfo getNextMediaPeriodInfo() {
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ import com.google.android.exoplayer2.testutil.FakeRenderer;
|
|||
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
||||
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import java.io.IOException;
|
||||
|
|
@ -99,8 +99,7 @@ public class DownloadHelperTest {
|
|||
trackGroupTextZh);
|
||||
TrackGroupArray trackGroupArraySingle =
|
||||
new TrackGroupArray(TRACK_GROUP_VIDEO_SINGLE, trackGroupAudioUs);
|
||||
trackGroupArrays =
|
||||
new TrackGroupArray[] {trackGroupArrayAll, trackGroupArraySingle};
|
||||
trackGroupArrays = new TrackGroupArray[] {trackGroupArrayAll, trackGroupArraySingle};
|
||||
|
||||
testMediaItem =
|
||||
new MediaItem.Builder().setUri("http://test.uri").setCustomCacheKey("cacheKey").build();
|
||||
|
|
@ -194,17 +193,17 @@ public class DownloadHelperTest {
|
|||
public void getTrackSelections_returnsInitialSelection() throws Exception {
|
||||
prepareDownloadHelper(downloadHelper);
|
||||
|
||||
List<TrackSelection> selectedText0 =
|
||||
List<ExoTrackSelection> selectedText0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio0 =
|
||||
List<ExoTrackSelection> selectedAudio0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo0 =
|
||||
List<ExoTrackSelection> selectedVideo0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
|
||||
List<TrackSelection> selectedText1 =
|
||||
List<ExoTrackSelection> selectedText1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio1 =
|
||||
List<ExoTrackSelection> selectedAudio1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo1 =
|
||||
List<ExoTrackSelection> selectedVideo1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
|
||||
|
||||
assertSingleTrackSelectionEquals(selectedText0, trackGroupTextUs, 0);
|
||||
|
|
@ -222,17 +221,17 @@ public class DownloadHelperTest {
|
|||
|
||||
// Clear only one period selection to verify second period selection is untouched.
|
||||
downloadHelper.clearTrackSelections(/* periodIndex= */ 0);
|
||||
List<TrackSelection> selectedText0 =
|
||||
List<ExoTrackSelection> selectedText0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio0 =
|
||||
List<ExoTrackSelection> selectedAudio0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo0 =
|
||||
List<ExoTrackSelection> selectedVideo0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
|
||||
List<TrackSelection> selectedText1 =
|
||||
List<ExoTrackSelection> selectedText1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio1 =
|
||||
List<ExoTrackSelection> selectedAudio1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo1 =
|
||||
List<ExoTrackSelection> selectedVideo1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
|
||||
|
||||
assertThat(selectedText0).isEmpty();
|
||||
|
|
@ -258,17 +257,17 @@ public class DownloadHelperTest {
|
|||
|
||||
// Replace only one period selection to verify second period selection is untouched.
|
||||
downloadHelper.replaceTrackSelections(/* periodIndex= */ 0, parameters);
|
||||
List<TrackSelection> selectedText0 =
|
||||
List<ExoTrackSelection> selectedText0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio0 =
|
||||
List<ExoTrackSelection> selectedAudio0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo0 =
|
||||
List<ExoTrackSelection> selectedVideo0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
|
||||
List<TrackSelection> selectedText1 =
|
||||
List<ExoTrackSelection> selectedText1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio1 =
|
||||
List<ExoTrackSelection> selectedAudio1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo1 =
|
||||
List<ExoTrackSelection> selectedVideo1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
|
||||
|
||||
assertSingleTrackSelectionEquals(selectedText0, trackGroupTextZh, 0);
|
||||
|
|
@ -294,17 +293,17 @@ public class DownloadHelperTest {
|
|||
|
||||
// Add only to one period selection to verify second period selection is untouched.
|
||||
downloadHelper.addTrackSelection(/* periodIndex= */ 0, parameters);
|
||||
List<TrackSelection> selectedText0 =
|
||||
List<ExoTrackSelection> selectedText0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio0 =
|
||||
List<ExoTrackSelection> selectedAudio0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo0 =
|
||||
List<ExoTrackSelection> selectedVideo0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
|
||||
List<TrackSelection> selectedText1 =
|
||||
List<ExoTrackSelection> selectedText1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio1 =
|
||||
List<ExoTrackSelection> selectedAudio1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo1 =
|
||||
List<ExoTrackSelection> selectedVideo1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
|
||||
|
||||
assertSingleTrackSelectionEquals(selectedText0, trackGroupTextUs, 0);
|
||||
|
|
@ -327,17 +326,17 @@ public class DownloadHelperTest {
|
|||
|
||||
// Add a non-default language, and a non-existing language (which will select the default).
|
||||
downloadHelper.addAudioLanguagesToSelection("ZH", "Klingonese");
|
||||
List<TrackSelection> selectedText0 =
|
||||
List<ExoTrackSelection> selectedText0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio0 =
|
||||
List<ExoTrackSelection> selectedAudio0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo0 =
|
||||
List<ExoTrackSelection> selectedVideo0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
|
||||
List<TrackSelection> selectedText1 =
|
||||
List<ExoTrackSelection> selectedText1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio1 =
|
||||
List<ExoTrackSelection> selectedAudio1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo1 =
|
||||
List<ExoTrackSelection> selectedVideo1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
|
||||
|
||||
assertThat(selectedVideo0).isEmpty();
|
||||
|
|
@ -361,17 +360,17 @@ public class DownloadHelperTest {
|
|||
// Add a non-default language, and a non-existing language (which will select the default).
|
||||
downloadHelper.addTextLanguagesToSelection(
|
||||
/* selectUndeterminedTextLanguage= */ true, "ZH", "Klingonese");
|
||||
List<TrackSelection> selectedText0 =
|
||||
List<ExoTrackSelection> selectedText0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio0 =
|
||||
List<ExoTrackSelection> selectedAudio0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo0 =
|
||||
List<ExoTrackSelection> selectedVideo0 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
|
||||
List<TrackSelection> selectedText1 =
|
||||
List<ExoTrackSelection> selectedText1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
|
||||
List<TrackSelection> selectedAudio1 =
|
||||
List<ExoTrackSelection> selectedAudio1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
|
||||
List<TrackSelection> selectedVideo1 =
|
||||
List<ExoTrackSelection> selectedVideo1 =
|
||||
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
|
||||
|
||||
assertThat(selectedVideo0).isEmpty();
|
||||
|
|
@ -464,13 +463,13 @@ public class DownloadHelperTest {
|
|||
}
|
||||
|
||||
private static void assertSingleTrackSelectionEquals(
|
||||
List<TrackSelection> trackSelectionList, TrackGroup trackGroup, int... tracks) {
|
||||
List<ExoTrackSelection> trackSelectionList, TrackGroup trackGroup, int... tracks) {
|
||||
assertThat(trackSelectionList).hasSize(1);
|
||||
assertTrackSelectionEquals(trackSelectionList.get(0), trackGroup, tracks);
|
||||
}
|
||||
|
||||
private static void assertTrackSelectionEquals(
|
||||
TrackSelection trackSelection, TrackGroup trackGroup, int... tracks) {
|
||||
ExoTrackSelection trackSelection, TrackGroup trackGroup, int... tracks) {
|
||||
assertThat(trackSelection.getTrackGroup()).isEqualTo(trackGroup);
|
||||
assertThat(trackSelection.length()).isEqualTo(tracks.length);
|
||||
int[] selectedTracksInGroup = new int[trackSelection.length()];
|
||||
|
|
@ -498,9 +497,9 @@ public class DownloadHelperTest {
|
|||
new EventDispatcher()
|
||||
.withParameters(/* windowIndex= */ 0, id, /* mediaTimeOffsetMs= */ 0)) {
|
||||
@Override
|
||||
public List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) {
|
||||
public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
|
||||
List<StreamKey> result = new ArrayList<>();
|
||||
for (TrackSelection trackSelection : trackSelections) {
|
||||
for (ExoTrackSelection trackSelection : trackSelections) {
|
||||
int groupIndex = trackGroupArrays[periodIndex].indexOf(trackSelection.getTrackGroup());
|
||||
for (int i = 0; i < trackSelection.length(); i++) {
|
||||
result.add(
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
|
|||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
|
||||
import com.google.android.exoplayer2.testutil.FakeMediaPeriod;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DefaultAllocator;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
|
@ -72,13 +72,15 @@ public final class MergingMediaPeriodTest {
|
|||
new MergingPeriodDefinition(
|
||||
/* timeOffsetUs= */ 0, /* singleSampleTimeUs= */ 0, childFormat21, childFormat22));
|
||||
|
||||
TrackSelection selectionForChild1 =
|
||||
ExoTrackSelection selectionForChild1 =
|
||||
new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(1), /* track= */ 0);
|
||||
TrackSelection selectionForChild2 =
|
||||
ExoTrackSelection selectionForChild2 =
|
||||
new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(2), /* track= */ 0);
|
||||
SampleStream[] streams = new SampleStream[4];
|
||||
mergingMediaPeriod.selectTracks(
|
||||
/* selections= */ new TrackSelection[] {null, selectionForChild1, selectionForChild2, null},
|
||||
/* selections= */ new ExoTrackSelection[] {
|
||||
null, selectionForChild1, selectionForChild2, null
|
||||
},
|
||||
/* mayRetainStreamFlags= */ new boolean[] {false, false, false, false},
|
||||
streams,
|
||||
/* streamResetFlags= */ new boolean[] {false, false, false, false},
|
||||
|
|
@ -117,13 +119,13 @@ public final class MergingMediaPeriodTest {
|
|||
childFormat21,
|
||||
childFormat22));
|
||||
|
||||
TrackSelection selectionForChild1 =
|
||||
ExoTrackSelection selectionForChild1 =
|
||||
new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(0), /* track= */ 0);
|
||||
TrackSelection selectionForChild2 =
|
||||
ExoTrackSelection selectionForChild2 =
|
||||
new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(2), /* track= */ 0);
|
||||
SampleStream[] streams = new SampleStream[2];
|
||||
mergingMediaPeriod.selectTracks(
|
||||
/* selections= */ new TrackSelection[] {selectionForChild1, selectionForChild2},
|
||||
/* selections= */ new ExoTrackSelection[] {selectionForChild1, selectionForChild2},
|
||||
/* mayRetainStreamFlags= */ new boolean[] {false, false},
|
||||
streams,
|
||||
/* streamResetFlags= */ new boolean[] {false, false},
|
||||
|
|
@ -218,7 +220,7 @@ public final class MergingMediaPeriodTest {
|
|||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import com.google.android.exoplayer2.testutil.FakeClock;
|
|||
import com.google.android.exoplayer2.testutil.FakeMediaChunk;
|
||||
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
||||
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection.AdaptationCheckpoint;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection.Definition;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection.Definition;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ public final class MappingTrackSelectorTest {
|
|||
private MappedTrackInfo lastMappedTrackInfo;
|
||||
|
||||
@Override
|
||||
protected Pair<RendererConfiguration[], TrackSelection[]> selectTracks(
|
||||
protected Pair<RendererConfiguration[], ExoTrackSelection[]> selectTracks(
|
||||
MappedTrackInfo mappedTrackInfo,
|
||||
@Capabilities int[][][] rendererFormatSupports,
|
||||
@AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports,
|
||||
|
|
@ -147,7 +147,7 @@ public final class MappingTrackSelectorTest {
|
|||
int rendererCount = mappedTrackInfo.getRendererCount();
|
||||
lastMappedTrackInfo = mappedTrackInfo;
|
||||
return Pair.create(
|
||||
new RendererConfiguration[rendererCount], new TrackSelection[rendererCount]);
|
||||
new RendererConfiguration[rendererCount], new ExoTrackSelection[rendererCount]);
|
||||
}
|
||||
|
||||
public void assertMappedTrackGroups(int rendererIndex, TrackGroup... expected) {
|
||||
|
|
|
|||
|
|
@ -21,14 +21,12 @@ import com.google.android.exoplayer2.Format;
|
|||
import com.google.android.exoplayer2.source.chunk.ChunkSource;
|
||||
import com.google.android.exoplayer2.source.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An {@link ChunkSource} for DASH streams.
|
||||
*/
|
||||
/** A {@link ChunkSource} for DASH streams. */
|
||||
public interface DashChunkSource extends ChunkSource {
|
||||
|
||||
/** Factory for {@link DashChunkSource}s. */
|
||||
|
|
@ -55,7 +53,7 @@ public interface DashChunkSource extends ChunkSource {
|
|||
DashManifest manifest,
|
||||
int periodIndex,
|
||||
int[] adaptationSetIndices,
|
||||
TrackSelection trackSelection,
|
||||
ExoTrackSelection trackSelection,
|
||||
int type,
|
||||
long elapsedRealtimeOffsetMs,
|
||||
boolean enableEventMessageTrack,
|
||||
|
|
@ -76,5 +74,5 @@ public interface DashChunkSource extends ChunkSource {
|
|||
*
|
||||
* @param trackSelection The new track selection instance. Must be equivalent to the previous one.
|
||||
*/
|
||||
void updateTrackSelection(TrackSelection trackSelection);
|
||||
void updateTrackSelection(ExoTrackSelection trackSelection);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ import com.google.android.exoplayer2.source.dash.manifest.Descriptor;
|
|||
import com.google.android.exoplayer2.source.dash.manifest.EventStream;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.Period;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.Representation;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
|
|
@ -213,10 +213,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) {
|
||||
public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
|
||||
List<AdaptationSet> manifestAdaptationSets = manifest.getPeriod(periodIndex).adaptationSets;
|
||||
List<StreamKey> streamKeys = new ArrayList<>();
|
||||
for (TrackSelection trackSelection : trackSelections) {
|
||||
for (ExoTrackSelection trackSelection : trackSelections) {
|
||||
int trackGroupIndex = trackGroups.indexOf(trackSelection.getTrackGroup());
|
||||
TrackGroupInfo trackGroupInfo = trackGroupInfos[trackGroupIndex];
|
||||
if (trackGroupInfo.trackGroupCategory != TrackGroupInfo.CATEGORY_PRIMARY) {
|
||||
|
|
@ -256,7 +256,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
@ -356,7 +356,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
|
||||
// Internal methods.
|
||||
|
||||
private int[] getStreamIndexToTrackGroupIndex(TrackSelection[] selections) {
|
||||
private int[] getStreamIndexToTrackGroupIndex(ExoTrackSelection[] selections) {
|
||||
int[] streamIndexToTrackGroupIndex = new int[selections.length];
|
||||
for (int i = 0; i < selections.length; i++) {
|
||||
if (selections[i] != null) {
|
||||
|
|
@ -369,7 +369,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
}
|
||||
|
||||
private void releaseDisabledStreams(
|
||||
TrackSelection[] selections, boolean[] mayRetainStreamFlags, SampleStream[] streams) {
|
||||
ExoTrackSelection[] selections, boolean[] mayRetainStreamFlags, SampleStream[] streams) {
|
||||
for (int i = 0; i < selections.length; i++) {
|
||||
if (selections[i] == null || !mayRetainStreamFlags[i]) {
|
||||
if (streams[i] instanceof ChunkSampleStream) {
|
||||
|
|
@ -386,7 +386,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
}
|
||||
|
||||
private void releaseOrphanEmbeddedStreams(
|
||||
TrackSelection[] selections, SampleStream[] streams, int[] streamIndexToTrackGroupIndex) {
|
||||
ExoTrackSelection[] selections, SampleStream[] streams, int[] streamIndexToTrackGroupIndex) {
|
||||
for (int i = 0; i < selections.length; i++) {
|
||||
if (streams[i] instanceof EmptySampleStream || streams[i] instanceof EmbeddedSampleStream) {
|
||||
// We need to release an embedded stream if the corresponding primary stream is released.
|
||||
|
|
@ -414,14 +414,14 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
}
|
||||
|
||||
private void selectNewStreams(
|
||||
TrackSelection[] selections,
|
||||
ExoTrackSelection[] selections,
|
||||
SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
long positionUs,
|
||||
int[] streamIndexToTrackGroupIndex) {
|
||||
// Create newly selected primary and event streams.
|
||||
for (int i = 0; i < selections.length; i++) {
|
||||
TrackSelection selection = selections[i];
|
||||
ExoTrackSelection selection = selections[i];
|
||||
if (selection == null) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -703,8 +703,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
return trackGroupCount;
|
||||
}
|
||||
|
||||
private static void buildManifestEventTrackGroupInfos(List<EventStream> eventStreams,
|
||||
TrackGroup[] trackGroups, TrackGroupInfo[] trackGroupInfos, int existingTrackGroupCount) {
|
||||
private static void buildManifestEventTrackGroupInfos(
|
||||
List<EventStream> eventStreams,
|
||||
TrackGroup[] trackGroups,
|
||||
TrackGroupInfo[] trackGroupInfos,
|
||||
int existingTrackGroupCount) {
|
||||
for (int i = 0; i < eventStreams.size(); i++) {
|
||||
EventStream eventStream = eventStreams.get(i);
|
||||
Format format =
|
||||
|
|
@ -717,8 +720,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
}
|
||||
}
|
||||
|
||||
private ChunkSampleStream<DashChunkSource> buildSampleStream(TrackGroupInfo trackGroupInfo,
|
||||
TrackSelection selection, long positionUs) {
|
||||
private ChunkSampleStream<DashChunkSource> buildSampleStream(
|
||||
TrackGroupInfo trackGroupInfo, ExoTrackSelection selection, long positionUs) {
|
||||
int embeddedTrackCount = 0;
|
||||
boolean enableEventMessageTrack =
|
||||
trackGroupInfo.embeddedEventMessageTrackGroupIndex != C.INDEX_UNSET;
|
||||
|
|
@ -813,8 +816,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
return null;
|
||||
}
|
||||
|
||||
private static boolean hasEventMessageTrack(List<AdaptationSet> adaptationSets,
|
||||
int[] adaptationSetIndices) {
|
||||
private static boolean hasEventMessageTrack(
|
||||
List<AdaptationSet> adaptationSets, int[] adaptationSetIndices) {
|
||||
for (int i : adaptationSetIndices) {
|
||||
List<Representation> representations = adaptationSets.get(i).representations;
|
||||
for (int j = 0; j < representations.size(); j++) {
|
||||
|
|
@ -897,8 +900,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
public @interface TrackGroupCategory {}
|
||||
|
||||
/**
|
||||
* A normal track group that has its samples drawn from the stream.
|
||||
* For example: a video Track Group or an audio Track Group.
|
||||
* A normal track group that has its samples drawn from the stream. For example: a video Track
|
||||
* Group or an audio Track Group.
|
||||
*/
|
||||
private static final int CATEGORY_PRIMARY = 0;
|
||||
|
||||
|
|
@ -909,9 +912,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
private static final int CATEGORY_EMBEDDED = 1;
|
||||
|
||||
/**
|
||||
* A track group that has its samples listed explicitly in the DASH manifest file.
|
||||
* For example: an EventStream track has its sample (Events) included directly in the DASH
|
||||
* manifest file.
|
||||
* A track group that has its samples listed explicitly in the DASH manifest file. For example:
|
||||
* an EventStream track has its sample (Events) included directly in the DASH manifest file.
|
||||
*/
|
||||
private static final int CATEGORY_MANIFEST_EVENTS = 2;
|
||||
|
||||
|
|
@ -940,8 +942,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
/* eventStreamGroupIndex= */ -1);
|
||||
}
|
||||
|
||||
public static TrackGroupInfo embeddedEmsgTrack(int[] adaptationSetIndices,
|
||||
int primaryTrackGroupIndex) {
|
||||
public static TrackGroupInfo embeddedEmsgTrack(
|
||||
int[] adaptationSetIndices, int primaryTrackGroupIndex) {
|
||||
return new TrackGroupInfo(
|
||||
C.TRACK_TYPE_METADATA,
|
||||
CATEGORY_EMBEDDED,
|
||||
|
|
@ -992,5 +994,4 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
this.eventStreamGroupIndex = eventStreamGroupIndex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet;
|
|||
import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.RangedUri;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.Representation;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCodeException;
|
||||
|
|
@ -84,7 +84,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||
DashManifest manifest,
|
||||
int periodIndex,
|
||||
int[] adaptationSetIndices,
|
||||
TrackSelection trackSelection,
|
||||
ExoTrackSelection trackSelection,
|
||||
int trackType,
|
||||
long elapsedRealtimeOffsetMs,
|
||||
boolean enableEventMessageTrack,
|
||||
|
|
@ -122,7 +122,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||
|
||||
protected final RepresentationHolder[] representationHolders;
|
||||
|
||||
private TrackSelection trackSelection;
|
||||
private ExoTrackSelection trackSelection;
|
||||
private DashManifest manifest;
|
||||
private int periodIndex;
|
||||
@Nullable private IOException fatalError;
|
||||
|
|
@ -152,7 +152,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||
DashManifest manifest,
|
||||
int periodIndex,
|
||||
int[] adaptationSetIndices,
|
||||
TrackSelection trackSelection,
|
||||
ExoTrackSelection trackSelection,
|
||||
int trackType,
|
||||
DataSource dataSource,
|
||||
long elapsedRealtimeOffsetMs,
|
||||
|
|
@ -228,7 +228,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateTrackSelection(TrackSelection trackSelection) {
|
||||
public void updateTrackSelection(ExoTrackSelection trackSelection) {
|
||||
this.trackSelection = trackSelection;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
|
|||
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
|
||||
import com.google.android.exoplayer2.trackselection.BaseTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
|
|
@ -137,8 +137,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
|
||||
// Note: The track group in the selection is typically *not* equal to trackGroup. This is due to
|
||||
// the way in which HlsSampleStreamWrapper generates track groups. Use only index based methods
|
||||
// in TrackSelection to avoid unexpected behavior.
|
||||
private TrackSelection trackSelection;
|
||||
// in ExoTrackSelection to avoid unexpected behavior.
|
||||
private ExoTrackSelection trackSelection;
|
||||
private long liveEdgeInPeriodTimeUs;
|
||||
private boolean seenExpectedPlaylistError;
|
||||
|
||||
|
|
@ -219,14 +219,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
/**
|
||||
* Sets the current track selection.
|
||||
*
|
||||
* @param trackSelection The {@link TrackSelection}.
|
||||
* @param trackSelection The {@link ExoTrackSelection}.
|
||||
*/
|
||||
public void setTrackSelection(TrackSelection trackSelection) {
|
||||
public void setTrackSelection(ExoTrackSelection trackSelection) {
|
||||
this.trackSelection = trackSelection;
|
||||
}
|
||||
|
||||
/** Returns the current {@link TrackSelection}. */
|
||||
public TrackSelection getTrackSelection() {
|
||||
/** Returns the current {@link ExoTrackSelection}. */
|
||||
public ExoTrackSelection getTrackSelection() {
|
||||
return trackSelection;
|
||||
}
|
||||
|
||||
|
|
@ -810,9 +810,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
|
||||
// Private classes.
|
||||
|
||||
/**
|
||||
* A {@link TrackSelection} to use for initialization.
|
||||
*/
|
||||
/** A {@link ExoTrackSelection} to use for initialization. */
|
||||
private static final class InitializationTrackSelection extends BaseTrackSelection {
|
||||
|
||||
private int selectedIndex;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
|
|||
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Rendition;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Variant;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||
|
|
@ -177,7 +177,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
|||
// null URLs, this method must be updated to calculate stream keys that are compatible with those
|
||||
// that may already be persisted for offline.
|
||||
@Override
|
||||
public List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) {
|
||||
public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
|
||||
// See HlsMasterPlaylist.copy for interpretation of StreamKeys.
|
||||
HlsMasterPlaylist masterPlaylist = Assertions.checkNotNull(playlistTracker.getMasterPlaylist());
|
||||
boolean hasVariants = !masterPlaylist.variants.isEmpty();
|
||||
|
|
@ -202,7 +202,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
|||
List<StreamKey> streamKeys = new ArrayList<>();
|
||||
boolean needsPrimaryTrackGroupSelection = false;
|
||||
boolean hasPrimaryTrackGroupSelection = false;
|
||||
for (TrackSelection trackSelection : trackSelections) {
|
||||
for (ExoTrackSelection trackSelection : trackSelections) {
|
||||
TrackGroup trackSelectionGroup = trackSelection.getTrackGroup();
|
||||
int mainWrapperTrackGroupIndex = mainWrapperTrackGroups.indexOf(trackSelectionGroup);
|
||||
if (mainWrapperTrackGroupIndex != C.INDEX_UNSET) {
|
||||
|
|
@ -258,7 +258,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
|||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
@ -286,7 +286,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
|||
// Select tracks for each child, copying the resulting streams back into a new streams array.
|
||||
SampleStream[] newStreams = new SampleStream[selections.length];
|
||||
@NullableType SampleStream[] childStreams = new SampleStream[selections.length];
|
||||
@NullableType TrackSelection[] childSelections = new TrackSelection[selections.length];
|
||||
@NullableType ExoTrackSelection[] childSelections = new ExoTrackSelection[selections.length];
|
||||
int newEnabledSampleStreamWrapperCount = 0;
|
||||
HlsSampleStreamWrapper[] newEnabledSampleStreamWrappers =
|
||||
new HlsSampleStreamWrapper[sampleStreamWrappers.length];
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ import com.google.android.exoplayer2.source.TrackGroup;
|
|||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.source.chunk.Chunk;
|
||||
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataReader;
|
||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
||||
|
|
@ -331,7 +331,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||
* part of the track selection.
|
||||
*/
|
||||
public boolean selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
@ -358,11 +358,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||
: positionUs != lastSeekPositionUs);
|
||||
// Get the old (i.e. current before the loop below executes) primary track selection. The new
|
||||
// primary selection will equal the old one unless it's changed in the loop.
|
||||
TrackSelection oldPrimaryTrackSelection = chunkSource.getTrackSelection();
|
||||
TrackSelection primaryTrackSelection = oldPrimaryTrackSelection;
|
||||
ExoTrackSelection oldPrimaryTrackSelection = chunkSource.getTrackSelection();
|
||||
ExoTrackSelection primaryTrackSelection = oldPrimaryTrackSelection;
|
||||
// Select new tracks.
|
||||
for (int i = 0; i < selections.length; i++) {
|
||||
TrackSelection selection = selections[i];
|
||||
ExoTrackSelection selection = selections[i];
|
||||
if (selection == null) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import com.google.android.exoplayer2.source.chunk.MediaChunk;
|
|||
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
|
|
@ -61,7 +61,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
|||
LoaderErrorThrower manifestLoaderErrorThrower,
|
||||
SsManifest manifest,
|
||||
int elementIndex,
|
||||
TrackSelection trackSelection,
|
||||
ExoTrackSelection trackSelection,
|
||||
@Nullable TransferListener transferListener) {
|
||||
DataSource dataSource = dataSourceFactory.createDataSource();
|
||||
if (transferListener != null) {
|
||||
|
|
@ -78,7 +78,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
|||
private final ChunkExtractor[] chunkExtractors;
|
||||
private final DataSource dataSource;
|
||||
|
||||
private TrackSelection trackSelection;
|
||||
private ExoTrackSelection trackSelection;
|
||||
private SsManifest manifest;
|
||||
private int currentManifestChunkOffset;
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
|||
LoaderErrorThrower manifestLoaderErrorThrower,
|
||||
SsManifest manifest,
|
||||
int streamElementIndex,
|
||||
TrackSelection trackSelection,
|
||||
ExoTrackSelection trackSelection,
|
||||
DataSource dataSource) {
|
||||
this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
|
||||
this.manifest = manifest;
|
||||
|
|
@ -163,7 +163,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateTrackSelection(TrackSelection trackSelection) {
|
||||
public void updateTrackSelection(ExoTrackSelection trackSelection) {
|
||||
this.trackSelection = trackSelection;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,11 @@ package com.google.android.exoplayer2.source.smoothstreaming;
|
|||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.source.chunk.ChunkSource;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
|
||||
/**
|
||||
* A {@link ChunkSource} for SmoothStreaming.
|
||||
*/
|
||||
/** A {@link ChunkSource} for SmoothStreaming. */
|
||||
public interface SsChunkSource extends ChunkSource {
|
||||
|
||||
/** Factory for {@link SsChunkSource}s. */
|
||||
|
|
@ -45,7 +43,7 @@ public interface SsChunkSource extends ChunkSource {
|
|||
LoaderErrorThrower manifestLoaderErrorThrower,
|
||||
SsManifest manifest,
|
||||
int streamElementIndex,
|
||||
TrackSelection trackSelection,
|
||||
ExoTrackSelection trackSelection,
|
||||
@Nullable TransferListener transferListener);
|
||||
}
|
||||
|
||||
|
|
@ -61,5 +59,5 @@ public interface SsChunkSource extends ChunkSource {
|
|||
*
|
||||
* @param trackSelection The new track selection instance. Must be equivalent to the previous one.
|
||||
*/
|
||||
void updateTrackSelection(TrackSelection trackSelection);
|
||||
void updateTrackSelection(ExoTrackSelection trackSelection);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import com.google.android.exoplayer2.source.TrackGroup;
|
|||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.source.chunk.ChunkSampleStream;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
|
||||
|
|
@ -123,7 +123,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
@ -156,10 +156,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) {
|
||||
public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
|
||||
List<StreamKey> streamKeys = new ArrayList<>();
|
||||
for (int selectionIndex = 0; selectionIndex < trackSelections.size(); selectionIndex++) {
|
||||
TrackSelection trackSelection = trackSelections.get(selectionIndex);
|
||||
ExoTrackSelection trackSelection = trackSelections.get(selectionIndex);
|
||||
int streamElementIndex = trackGroups.indexOf(trackSelection.getTrackGroup());
|
||||
for (int i = 0; i < trackSelection.length(); i++) {
|
||||
streamKeys.add(new StreamKey(streamElementIndex, trackSelection.getIndexInTrackGroup(i)));
|
||||
|
|
@ -232,16 +232,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||
|
||||
// Private methods.
|
||||
|
||||
private ChunkSampleStream<SsChunkSource> buildSampleStream(TrackSelection selection,
|
||||
long positionUs) {
|
||||
private ChunkSampleStream<SsChunkSource> buildSampleStream(
|
||||
ExoTrackSelection selection, long positionUs) {
|
||||
int streamElementIndex = trackGroups.indexOf(selection.getTrackGroup());
|
||||
SsChunkSource chunkSource =
|
||||
chunkSourceFactory.createChunkSource(
|
||||
manifestLoaderErrorThrower,
|
||||
manifest,
|
||||
streamElementIndex,
|
||||
selection,
|
||||
transferListener);
|
||||
manifestLoaderErrorThrower, manifest, streamElementIndex, selection, transferListener);
|
||||
return new ChunkSampleStream<>(
|
||||
manifest.streamElements[streamElementIndex].type,
|
||||
null,
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ import com.google.android.exoplayer2.testutil.ExoHostedTest;
|
|||
import com.google.android.exoplayer2.testutil.HostActivity;
|
||||
import com.google.android.exoplayer2.testutil.HostActivity.HostedTest;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.RandomTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
||||
|
|
@ -386,7 +386,7 @@ import java.util.List;
|
|||
}
|
||||
|
||||
@Override
|
||||
protected TrackSelection.Definition[] selectAllTracks(
|
||||
protected ExoTrackSelection.Definition[] selectAllTracks(
|
||||
MappedTrackInfo mappedTrackInfo,
|
||||
int[][][] rendererFormatSupports,
|
||||
int[] rendererMixedMimeTypeAdaptationSupports,
|
||||
|
|
@ -399,10 +399,10 @@ import java.util.List;
|
|||
TrackGroupArray audioTrackGroups = mappedTrackInfo.getTrackGroups(AUDIO_RENDERER_INDEX);
|
||||
Assertions.checkState(videoTrackGroups.length == 1);
|
||||
Assertions.checkState(audioTrackGroups.length == 1);
|
||||
TrackSelection.Definition[] definitions =
|
||||
new TrackSelection.Definition[mappedTrackInfo.getRendererCount()];
|
||||
ExoTrackSelection.Definition[] definitions =
|
||||
new ExoTrackSelection.Definition[mappedTrackInfo.getRendererCount()];
|
||||
definitions[VIDEO_RENDERER_INDEX] =
|
||||
new TrackSelection.Definition(
|
||||
new ExoTrackSelection.Definition(
|
||||
videoTrackGroups.get(0),
|
||||
getVideoTrackIndices(
|
||||
videoTrackGroups.get(0),
|
||||
|
|
@ -410,7 +410,7 @@ import java.util.List;
|
|||
videoFormatIds,
|
||||
canIncludeAdditionalVideoFormats));
|
||||
definitions[AUDIO_RENDERER_INDEX] =
|
||||
new TrackSelection.Definition(
|
||||
new ExoTrackSelection.Definition(
|
||||
audioTrackGroups.get(0), getTrackIndex(audioTrackGroups.get(0), audioFormatId));
|
||||
includedAdditionalVideoFormats =
|
||||
definitions[VIDEO_RENDERER_INDEX].tracks.length > videoFormatIds.length;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import com.google.android.exoplayer2.source.SequenceableLoader;
|
|||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.source.chunk.ChunkSampleStream;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
|
||||
|
|
@ -143,7 +143,7 @@ public class FakeAdaptiveMediaPeriod
|
|||
@SuppressWarnings({"unchecked", "rawtypes"}) // Casting sample streams created by this class.
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
@ -157,7 +157,7 @@ public class FakeAdaptiveMediaPeriod
|
|||
streams[i] = null;
|
||||
}
|
||||
if (streams[i] == null && selections[i] != null) {
|
||||
TrackSelection selection = selections[i];
|
||||
ExoTrackSelection selection = selections[i];
|
||||
assertThat(selection.length()).isAtLeast(1);
|
||||
TrackGroup trackGroup = selection.getTrackGroup();
|
||||
assertThat(trackGroupArray.indexOf(trackGroup)).isNotEqualTo(C.INDEX_UNSET);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import com.google.android.exoplayer2.source.chunk.MediaChunk;
|
|||
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
|
||||
import com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSet.FakeData.Segment;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
|
|
@ -55,7 +55,7 @@ public final class FakeChunkSource implements ChunkSource {
|
|||
}
|
||||
|
||||
public FakeChunkSource createChunkSource(
|
||||
TrackSelection trackSelection,
|
||||
ExoTrackSelection trackSelection,
|
||||
long durationUs,
|
||||
@Nullable TransferListener transferListener) {
|
||||
FakeAdaptiveDataSet dataSet =
|
||||
|
|
@ -70,12 +70,12 @@ public final class FakeChunkSource implements ChunkSource {
|
|||
|
||||
}
|
||||
|
||||
private final TrackSelection trackSelection;
|
||||
private final ExoTrackSelection trackSelection;
|
||||
private final DataSource dataSource;
|
||||
private final FakeAdaptiveDataSet dataSet;
|
||||
|
||||
public FakeChunkSource(TrackSelection trackSelection, DataSource dataSource,
|
||||
FakeAdaptiveDataSet dataSet) {
|
||||
public FakeChunkSource(
|
||||
ExoTrackSelection trackSelection, DataSource dataSource, FakeAdaptiveDataSet dataSet) {
|
||||
this.trackSelection = trackSelection;
|
||||
this.dataSource = dataSource;
|
||||
this.dataSet = dataSet;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ import com.google.android.exoplayer2.source.SampleStream;
|
|||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
|
@ -187,8 +187,8 @@ public class FakeMediaPeriod implements MediaPeriod {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets a discontinuity position to be returned from the next call to
|
||||
* {@link #readDiscontinuity()}.
|
||||
* Sets a discontinuity position to be returned from the next call to {@link
|
||||
* #readDiscontinuity()}.
|
||||
*
|
||||
* @param discontinuityPositionUs The position to be returned, in microseconds.
|
||||
*/
|
||||
|
|
@ -196,9 +196,7 @@ public class FakeMediaPeriod implements MediaPeriod {
|
|||
this.discontinuityPositionUs = discontinuityPositionUs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the fake media period to complete preparation. May be called on any thread.
|
||||
*/
|
||||
/** Allows the fake media period to complete preparation. May be called on any thread. */
|
||||
public synchronized void setPreparationComplete() {
|
||||
deferOnPrepared = false;
|
||||
if (playerHandler != null && prepareCallback != null) {
|
||||
|
|
@ -256,7 +254,7 @@ public class FakeMediaPeriod implements MediaPeriod {
|
|||
|
||||
@Override
|
||||
public long selectTracks(
|
||||
@NullableType TrackSelection[] selections,
|
||||
@NullableType ExoTrackSelection[] selections,
|
||||
boolean[] mayRetainStreamFlags,
|
||||
@NullableType SampleStream[] streams,
|
||||
boolean[] streamResetFlags,
|
||||
|
|
@ -270,7 +268,7 @@ public class FakeMediaPeriod implements MediaPeriod {
|
|||
streams[i] = null;
|
||||
}
|
||||
if (streams[i] == null && selections[i] != null) {
|
||||
TrackSelection selection = selections[i];
|
||||
ExoTrackSelection selection = selections[i];
|
||||
assertThat(selection.length()).isAtLeast(1);
|
||||
TrackGroup trackGroup = selection.getTrackGroup();
|
||||
assertThat(trackGroupArray.indexOf(trackGroup) != C.INDEX_UNSET).isTrue();
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ 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.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A fake {@link TrackSelection} that only returns 1 fixed track, and allows querying the number of
|
||||
* calls to its methods.
|
||||
* A fake {@link ExoTrackSelection} that only returns 1 fixed track, and allows querying the number
|
||||
* of calls to its methods.
|
||||
*/
|
||||
public final class FakeTrackSelection implements TrackSelection {
|
||||
public final class FakeTrackSelection implements ExoTrackSelection {
|
||||
|
||||
private final TrackGroup rendererTrackGroup;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
|||
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.ExoTrackSelection;
|
||||
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;
|
||||
|
|
@ -41,8 +41,8 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
|||
|
||||
/**
|
||||
* @param mayReuseTrackSelection Whether this {@link FakeTrackSelector} will reuse {@link
|
||||
* TrackSelection}s during track selection, when it finds previously-selected track selection
|
||||
* using the same {@link TrackGroup}.
|
||||
* ExoTrackSelection}s during track selection, when it finds previously-selected track
|
||||
* selection using the same {@link TrackGroup}.
|
||||
*/
|
||||
public FakeTrackSelector(boolean mayReuseTrackSelection) {
|
||||
this(new FakeTrackSelectionFactory(mayReuseTrackSelection));
|
||||
|
|
@ -54,18 +54,18 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected TrackSelection.@NullableType Definition[] selectAllTracks(
|
||||
protected ExoTrackSelection.@NullableType Definition[] selectAllTracks(
|
||||
MappedTrackInfo mappedTrackInfo,
|
||||
@Capabilities int[][][] rendererFormatSupports,
|
||||
@AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports,
|
||||
Parameters params) {
|
||||
int rendererCount = mappedTrackInfo.getRendererCount();
|
||||
TrackSelection.@NullableType Definition[] definitions =
|
||||
new TrackSelection.Definition[rendererCount];
|
||||
ExoTrackSelection.@NullableType Definition[] definitions =
|
||||
new ExoTrackSelection.Definition[rendererCount];
|
||||
for (int i = 0; i < rendererCount; i++) {
|
||||
TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(i);
|
||||
boolean hasTracks = trackGroupArray.length > 0;
|
||||
definitions[i] = hasTracks ? new TrackSelection.Definition(trackGroupArray.get(0)) : null;
|
||||
definitions[i] = hasTracks ? new ExoTrackSelection.Definition(trackGroupArray.get(0)) : null;
|
||||
}
|
||||
return definitions;
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
|||
return fakeTrackSelectionFactory.trackSelections;
|
||||
}
|
||||
|
||||
private static class FakeTrackSelectionFactory implements TrackSelection.Factory {
|
||||
private static class FakeTrackSelectionFactory implements ExoTrackSelection.Factory {
|
||||
|
||||
private final List<FakeTrackSelection> trackSelections;
|
||||
private final boolean mayReuseTrackSelection;
|
||||
|
|
@ -86,14 +86,14 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
|||
}
|
||||
|
||||
@Override
|
||||
public TrackSelection[] createTrackSelections(
|
||||
TrackSelection.@NullableType Definition[] definitions,
|
||||
public ExoTrackSelection[] createTrackSelections(
|
||||
ExoTrackSelection.@NullableType Definition[] definitions,
|
||||
BandwidthMeter bandwidthMeter,
|
||||
MediaPeriodId mediaPeriodId,
|
||||
Timeline timeline) {
|
||||
TrackSelection[] selections = new TrackSelection[definitions.length];
|
||||
ExoTrackSelection[] selections = new ExoTrackSelection[definitions.length];
|
||||
for (int i = 0; i < definitions.length; i++) {
|
||||
TrackSelection.Definition definition = definitions[i];
|
||||
ExoTrackSelection.Definition definition = definitions[i];
|
||||
if (definition != null) {
|
||||
selections[i] = createTrackSelection(definition.group);
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ public class FakeTrackSelector extends DefaultTrackSelector {
|
|||
return selections;
|
||||
}
|
||||
|
||||
private TrackSelection createTrackSelection(TrackGroup trackGroup) {
|
||||
private ExoTrackSelection createTrackSelection(TrackGroup trackGroup) {
|
||||
if (mayReuseTrackSelection) {
|
||||
for (FakeTrackSelection trackSelection : trackSelections) {
|
||||
if (trackSelection.getTrackGroup().equals(trackGroup)) {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
|
|||
import com.google.android.exoplayer2.source.chunk.MediaChunk;
|
||||
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
|
||||
import com.google.android.exoplayer2.trackselection.BaseTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
|
||||
import com.google.android.exoplayer2.util.ConditionVariable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -102,7 +102,7 @@ public final class MediaPeriodAsserts {
|
|||
// - One selection with one track per group, two tracks or all tracks.
|
||||
// - Two selections with tracks from multiple groups, or tracks from a single group.
|
||||
// - Multiple selections with tracks from all groups.
|
||||
List<List<TrackSelection>> testSelections = new ArrayList<>();
|
||||
List<List<ExoTrackSelection>> testSelections = new ArrayList<>();
|
||||
for (int i = 0; i < trackGroupArray.length; i++) {
|
||||
TrackGroup trackGroup = trackGroupArray.get(i);
|
||||
for (int j = 0; j < trackGroup.length; j++) {
|
||||
|
|
@ -112,7 +112,7 @@ public final class MediaPeriodAsserts {
|
|||
testSelections.add(Collections.singletonList(new TestTrackSelection(trackGroup, 0, 1)));
|
||||
testSelections.add(
|
||||
Arrays.asList(
|
||||
new TrackSelection[] {
|
||||
new ExoTrackSelection[] {
|
||||
new TestTrackSelection(trackGroup, 0), new TestTrackSelection(trackGroup, 1)
|
||||
}));
|
||||
}
|
||||
|
|
@ -130,7 +130,7 @@ public final class MediaPeriodAsserts {
|
|||
for (int j = i + 1; j < trackGroupArray.length; j++) {
|
||||
testSelections.add(
|
||||
Arrays.asList(
|
||||
new TrackSelection[] {
|
||||
new ExoTrackSelection[] {
|
||||
new TestTrackSelection(trackGroupArray.get(i), 0),
|
||||
new TestTrackSelection(trackGroupArray.get(j), 0)
|
||||
}));
|
||||
|
|
@ -138,7 +138,7 @@ public final class MediaPeriodAsserts {
|
|||
}
|
||||
}
|
||||
if (trackGroupArray.length > 2) {
|
||||
List<TrackSelection> selectionsFromAllGroups = new ArrayList<>();
|
||||
List<ExoTrackSelection> selectionsFromAllGroups = new ArrayList<>();
|
||||
for (int i = 0; i < trackGroupArray.length; i++) {
|
||||
selectionsFromAllGroups.add(new TestTrackSelection(trackGroupArray.get(i), 0));
|
||||
}
|
||||
|
|
@ -147,7 +147,7 @@ public final class MediaPeriodAsserts {
|
|||
|
||||
// Verify for each case that stream keys can be used to create filtered tracks which still
|
||||
// contain at least all requested formats.
|
||||
for (List<TrackSelection> testSelection : testSelections) {
|
||||
for (List<ExoTrackSelection> testSelection : testSelections) {
|
||||
List<StreamKey> streamKeys = mediaPeriod.getStreamKeys(testSelection);
|
||||
if (streamKeys.isEmpty()) {
|
||||
// Manifests won't be filtered if stream key is empty.
|
||||
|
|
@ -158,7 +158,7 @@ public final class MediaPeriodAsserts {
|
|||
MediaPeriod filteredMediaPeriod =
|
||||
mediaPeriodFactory.createMediaPeriod(filteredManifest, /* periodIndex= */ 0);
|
||||
TrackGroupArray filteredTrackGroupArray = prepareAndGetTrackGroups(filteredMediaPeriod);
|
||||
for (TrackSelection trackSelection : testSelection) {
|
||||
for (ExoTrackSelection trackSelection : testSelection) {
|
||||
if (ignoredMimeType != null
|
||||
&& ignoredMimeType.equals(trackSelection.getFormat(0).sampleMimeType)) {
|
||||
continue;
|
||||
|
|
|
|||
Loading…
Reference in a new issue