• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.android.exoplayer2.trackselection;
17 
18 import androidx.annotation.Nullable;
19 import com.google.android.exoplayer2.C;
20 import com.google.android.exoplayer2.Format;
21 import com.google.android.exoplayer2.source.TrackGroup;
22 import com.google.android.exoplayer2.source.chunk.MediaChunk;
23 import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
24 import com.google.android.exoplayer2.upstream.BandwidthMeter;
25 import java.util.List;
26 import org.checkerframework.checker.nullness.compatqual.NullableType;
27 
28 /**
29  * A track selection consisting of a static subset of selected tracks belonging to a {@link
30  * TrackGroup}, and a possibly varying individual selected track from the subset.
31  *
32  * <p>Tracks belonging to the subset are exposed in decreasing bandwidth order. The individual
33  * selected track may change dynamically as a result of calling {@link #updateSelectedTrack(long,
34  * long, long, List, MediaChunkIterator[])} or {@link #evaluateQueueSize(long, List)}. This only
35  * happens between calls to {@link #enable()} and {@link #disable()}.
36  */
37 public interface TrackSelection {
38 
39   /** Contains of a subset of selected tracks belonging to a {@link TrackGroup}. */
40   final class Definition {
41     /** The {@link TrackGroup} which tracks belong to. */
42     public final TrackGroup group;
43     /** The indices of the selected tracks in {@link #group}. */
44     public final int[] tracks;
45     /** The track selection reason. One of the {@link C} SELECTION_REASON_ constants. */
46     public final int reason;
47     /** Optional data associated with this selection of tracks. */
48     @Nullable public final Object data;
49 
50     /**
51      * @param group The {@link TrackGroup}. Must not be null.
52      * @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
53      *     null or empty. May be in any order.
54      */
Definition(TrackGroup group, int... tracks)55     public Definition(TrackGroup group, int... tracks) {
56       this(group, tracks, C.SELECTION_REASON_UNKNOWN, /* data= */ null);
57     }
58 
59     /**
60      * @param group The {@link TrackGroup}. Must not be null.
61      * @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
62      * @param reason The track selection reason. One of the {@link C} SELECTION_REASON_ constants.
63      * @param data Optional data associated with this selection of tracks.
64      */
Definition(TrackGroup group, int[] tracks, int reason, @Nullable Object data)65     public Definition(TrackGroup group, int[] tracks, int reason, @Nullable Object data) {
66       this.group = group;
67       this.tracks = tracks;
68       this.reason = reason;
69       this.data = data;
70     }
71   }
72 
73   /**
74    * Factory for {@link TrackSelection} instances.
75    */
76   interface Factory {
77 
78     /**
79      * Creates track selections for the provided {@link Definition Definitions}.
80      *
81      * <p>Implementations that create at most one adaptive track selection may use {@link
82      * TrackSelectionUtil#createTrackSelectionsForDefinitions}.
83      *
84      * @param definitions A {@link Definition} array. May include null values.
85      * @param bandwidthMeter A {@link BandwidthMeter} which can be used to select tracks.
86      * @return The created selections. Must have the same length as {@code definitions} and may
87      *     include null values.
88      */
89     @NullableType
createTrackSelections( @ullableType Definition[] definitions, BandwidthMeter bandwidthMeter)90     TrackSelection[] createTrackSelections(
91         @NullableType Definition[] definitions, BandwidthMeter bandwidthMeter);
92   }
93 
94   /**
95    * Enables the track selection. Dynamic changes via {@link #updateSelectedTrack(long, long, long,
96    * List, MediaChunkIterator[])} or {@link #evaluateQueueSize(long, List)} will only happen after
97    * this call.
98    *
99    * <p>This method may not be called when the track selection is already enabled.
100    */
enable()101   void enable();
102 
103   /**
104    * Disables this track selection. No further dynamic changes via {@link #updateSelectedTrack(long,
105    * long, long, List, MediaChunkIterator[])} or {@link #evaluateQueueSize(long, List)} will happen
106    * after this call.
107    *
108    * <p>This method may only be called when the track selection is already enabled.
109    */
disable()110   void disable();
111 
112   /**
113    * Returns the {@link TrackGroup} to which the selected tracks belong.
114    */
getTrackGroup()115   TrackGroup getTrackGroup();
116 
117   // Static subset of selected tracks.
118 
119   /**
120    * Returns the number of tracks in the selection.
121    */
length()122   int length();
123 
124   /**
125    * Returns the format of the track at a given index in the selection.
126    *
127    * @param index The index in the selection.
128    * @return The format of the selected track.
129    */
getFormat(int index)130   Format getFormat(int index);
131 
132   /**
133    * Returns the index in the track group of the track at a given index in the selection.
134    *
135    * @param index The index in the selection.
136    * @return The index of the selected track.
137    */
getIndexInTrackGroup(int index)138   int getIndexInTrackGroup(int index);
139 
140   /**
141    * Returns the index in the selection of the track with the specified format. The format is
142    * located by identity so, for example, {@code selection.indexOf(selection.getFormat(index)) ==
143    * index} even if multiple selected tracks have formats that contain the same values.
144    *
145    * @param format The format.
146    * @return The index in the selection, or {@link C#INDEX_UNSET} if the track with the specified
147    *     format is not part of the selection.
148    */
indexOf(Format format)149   int indexOf(Format format);
150 
151   /**
152    * Returns the index in the selection of the track with the specified index in the track group.
153    *
154    * @param indexInTrackGroup The index in the track group.
155    * @return The index in the selection, or {@link C#INDEX_UNSET} if the track with the specified
156    *     index is not part of the selection.
157    */
indexOf(int indexInTrackGroup)158   int indexOf(int indexInTrackGroup);
159 
160   // Individual selected track.
161 
162   /**
163    * Returns the {@link Format} of the individual selected track.
164    */
getSelectedFormat()165   Format getSelectedFormat();
166 
167   /**
168    * Returns the index in the track group of the individual selected track.
169    */
getSelectedIndexInTrackGroup()170   int getSelectedIndexInTrackGroup();
171 
172   /**
173    * Returns the index of the selected track.
174    */
getSelectedIndex()175   int getSelectedIndex();
176 
177   /**
178    * Returns the reason for the current track selection.
179    */
getSelectionReason()180   int getSelectionReason();
181 
182   /** Returns optional data associated with the current track selection. */
getSelectionData()183   @Nullable Object getSelectionData();
184 
185   // Adaptation.
186 
187   /**
188    * Called to notify the selection of the current playback speed. The playback speed may affect
189    * adaptive track selection.
190    *
191    * @param speed The playback speed.
192    */
onPlaybackSpeed(float speed)193   void onPlaybackSpeed(float speed);
194 
195   /**
196    * Called to notify the selection of a position discontinuity.
197    *
198    * <p>This happens when the playback position jumps, e.g., as a result of a seek being performed.
199    */
onDiscontinuity()200   default void onDiscontinuity() {}
201 
202   /**
203    * Updates the selected track for sources that load media in discrete {@link MediaChunk}s.
204    *
205    * <p>This method may only be called when the selection is enabled.
206    *
207    * @param playbackPositionUs The current playback position in microseconds. If playback of the
208    *     period to which this track selection belongs has not yet started, the value will be the
209    *     starting position in the period minus the duration of any media in previous periods still
210    *     to be played.
211    * @param bufferedDurationUs The duration of media currently buffered from the current playback
212    *     position, in microseconds. Note that the next load position can be calculated as {@code
213    *     (playbackPositionUs + bufferedDurationUs)}.
214    * @param availableDurationUs The duration of media available for buffering from the current
215    *     playback position, in microseconds, or {@link C#TIME_UNSET} if media can be buffered to the
216    *     end of the current period. Note that if not set to {@link C#TIME_UNSET}, the position up to
217    *     which media is available for buffering can be calculated as {@code (playbackPositionUs +
218    *     availableDurationUs)}.
219    * @param queue The queue of already buffered {@link MediaChunk}s. Must not be modified.
220    * @param mediaChunkIterators An array of {@link MediaChunkIterator}s providing information about
221    *     the sequence of upcoming media chunks for each track in the selection. All iterators start
222    *     from the media chunk which will be loaded next if the respective track is selected. Note
223    *     that this information may not be available for all tracks, and so some iterators may be
224    *     empty.
225    */
updateSelectedTrack( long playbackPositionUs, long bufferedDurationUs, long availableDurationUs, List<? extends MediaChunk> queue, MediaChunkIterator[] mediaChunkIterators)226   void updateSelectedTrack(
227       long playbackPositionUs,
228       long bufferedDurationUs,
229       long availableDurationUs,
230       List<? extends MediaChunk> queue,
231       MediaChunkIterator[] mediaChunkIterators);
232 
233   /**
234    * May be called periodically by sources that load media in discrete {@link MediaChunk}s and
235    * support discarding of buffered chunks in order to re-buffer using a different selected track.
236    * Returns the number of chunks that should be retained in the queue.
237    * <p>
238    * To avoid excessive re-buffering, implementations should normally return the size of the queue.
239    * An example of a case where a smaller value may be returned is if network conditions have
240    * improved dramatically, allowing chunks to be discarded and re-buffered in a track of
241    * significantly higher quality. Discarding chunks may allow faster switching to a higher quality
242    * track in this case. This method may only be called when the selection is enabled.
243    *
244    * @param playbackPositionUs The current playback position in microseconds. If playback of the
245    *     period to which this track selection belongs has not yet started, the value will be the
246    *     starting position in the period minus the duration of any media in previous periods still
247    *     to be played.
248    * @param queue The queue of buffered {@link MediaChunk}s. Must not be modified.
249    * @return The number of chunks to retain in the queue.
250    */
evaluateQueueSize(long playbackPositionUs, List<? extends MediaChunk> queue)251   int evaluateQueueSize(long playbackPositionUs, List<? extends MediaChunk> queue);
252 
253   /**
254    * Attempts to blacklist the track at the specified index in the selection, making it ineligible
255    * for selection by calls to {@link #updateSelectedTrack(long, long, long, List,
256    * MediaChunkIterator[])} for the specified period of time. Blacklisting will fail if all other
257    * tracks are currently blacklisted. If blacklisting the currently selected track, note that it
258    * will remain selected until the next call to {@link #updateSelectedTrack(long, long, long, List,
259    * MediaChunkIterator[])}.
260    *
261    * <p>This method may only be called when the selection is enabled.
262    *
263    * @param index The index of the track in the selection.
264    * @param blacklistDurationMs The duration of time for which the track should be blacklisted, in
265    *     milliseconds.
266    * @return Whether blacklisting was successful.
267    */
blacklist(int index, long blacklistDurationMs)268   boolean blacklist(int index, long blacklistDurationMs);
269 }
270