• 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.source;
17 
18 import com.google.android.exoplayer2.C;
19 import com.google.android.exoplayer2.ExoPlayer;
20 import com.google.android.exoplayer2.SeekParameters;
21 import com.google.android.exoplayer2.Timeline;
22 import com.google.android.exoplayer2.offline.StreamKey;
23 import com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller;
24 import com.google.android.exoplayer2.trackselection.TrackSelection;
25 import java.io.IOException;
26 import java.util.Collections;
27 import java.util.List;
28 import org.checkerframework.checker.nullness.compatqual.NullableType;
29 
30 /**
31  * Loads media corresponding to a {@link Timeline.Period}, and allows that media to be read. All
32  * methods are called on the player's internal playback thread, as described in the
33  * {@link ExoPlayer} Javadoc.
34  */
35 public interface MediaPeriod extends SequenceableLoader {
36 
37   /**
38    * A callback to be notified of {@link MediaPeriod} events.
39    */
40   interface Callback extends SequenceableLoader.Callback<MediaPeriod> {
41 
42     /**
43      * Called when preparation completes.
44      *
45      * <p>Called on the playback thread. After invoking this method, the {@link MediaPeriod} can
46      * expect for {@link #selectTracks(TrackSelection[], boolean[], SampleStream[], boolean[],
47      * long)} to be called with the initial track selection.
48      *
49      * @param mediaPeriod The prepared {@link MediaPeriod}.
50      */
onPrepared(MediaPeriod mediaPeriod)51     void onPrepared(MediaPeriod mediaPeriod);
52   }
53 
54   /**
55    * Prepares this media period asynchronously.
56    *
57    * <p>{@code callback.onPrepared} is called when preparation completes. If preparation fails,
58    * {@link #maybeThrowPrepareError()} will throw an {@link IOException}.
59    *
60    * <p>If preparation succeeds and results in a source timeline change (e.g. the period duration
61    * becoming known), {@link MediaSourceCaller#onSourceInfoRefreshed(MediaSource, Timeline)} will be
62    * called before {@code callback.onPrepared}.
63    *
64    * @param callback Callback to receive updates from this period, including being notified when
65    *     preparation completes.
66    * @param positionUs The expected starting position, in microseconds.
67    */
prepare(Callback callback, long positionUs)68   void prepare(Callback callback, long positionUs);
69 
70   /**
71    * Throws an error that's preventing the period from becoming prepared. Does nothing if no such
72    * error exists.
73    *
74    * <p>This method is only called before the period has completed preparation.
75    *
76    * @throws IOException The underlying error.
77    */
maybeThrowPrepareError()78   void maybeThrowPrepareError() throws IOException;
79 
80   /**
81    * Returns the {@link TrackGroup}s exposed by the period.
82    *
83    * <p>This method is only called after the period has been prepared.
84    *
85    * @return The {@link TrackGroup}s.
86    */
getTrackGroups()87   TrackGroupArray getTrackGroups();
88 
89   /**
90    * Returns a list of {@link StreamKey StreamKeys} which allow to filter the media in this period
91    * to load only the parts needed to play the provided {@link TrackSelection TrackSelections}.
92    *
93    * <p>This method is only called after the period has been prepared.
94    *
95    * @param trackSelections The {@link TrackSelection TrackSelections} describing the tracks for
96    *     which stream keys are requested.
97    * @return The corresponding {@link StreamKey StreamKeys} for the selected tracks, or an empty
98    *     list if filtering is not possible and the entire media needs to be loaded to play the
99    *     selected tracks.
100    */
getStreamKeys(List<TrackSelection> trackSelections)101   default List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) {
102     return Collections.emptyList();
103   }
104 
105   /**
106    * Performs a track selection.
107    *
108    * <p>The call receives track {@code selections} for each renderer, {@code mayRetainStreamFlags}
109    * indicating whether the existing {@link SampleStream} can be retained for each selection, and
110    * the existing {@code stream}s themselves. The call will update {@code streams} to reflect the
111    * provided selections, clearing, setting and replacing entries as required. If an existing sample
112    * stream is retained but with the requirement that the consuming renderer be reset, then the
113    * corresponding flag in {@code streamResetFlags} will be set to true. This flag will also be set
114    * if a new sample stream is created.
115    *
116    * <p>Note that previously passed {@link TrackSelection TrackSelections} are no longer valid, and
117    * any references to them must be updated to point to the new selections.
118    *
119    * <p>This method is only called after the period has been prepared.
120    *
121    * @param selections The renderer track selections.
122    * @param mayRetainStreamFlags Flags indicating whether the existing sample stream can be retained
123    *     for each track selection. A {@code true} value indicates that the selection is equivalent
124    *     to the one that was previously passed, and that the caller does not require that the sample
125    *     stream be recreated. If a retained sample stream holds any references to the track
126    *     selection then they must be updated to point to the new selection.
127    * @param streams The existing sample streams, which will be updated to reflect the provided
128    *     selections.
129    * @param streamResetFlags Will be updated to indicate new sample streams, and sample streams that
130    *     have been retained but with the requirement that the consuming renderer be reset.
131    * @param positionUs The current playback position in microseconds. If playback of this period has
132    *     not yet started, the value will be the starting position.
133    * @return The actual position at which the tracks were enabled, in microseconds.
134    */
selectTracks( @ullableType TrackSelection[] selections, boolean[] mayRetainStreamFlags, @NullableType SampleStream[] streams, boolean[] streamResetFlags, long positionUs)135   long selectTracks(
136       @NullableType TrackSelection[] selections,
137       boolean[] mayRetainStreamFlags,
138       @NullableType SampleStream[] streams,
139       boolean[] streamResetFlags,
140       long positionUs);
141 
142   /**
143    * Discards buffered media up to the specified position.
144    *
145    * <p>This method is only called after the period has been prepared.
146    *
147    * @param positionUs The position in microseconds.
148    * @param toKeyframe If true then for each track discards samples up to the keyframe before or at
149    *     the specified position, rather than any sample before or at that position.
150    */
discardBuffer(long positionUs, boolean toKeyframe)151   void discardBuffer(long positionUs, boolean toKeyframe);
152 
153   /**
154    * Attempts to read a discontinuity.
155    *
156    * <p>After this method has returned a value other than {@link C#TIME_UNSET}, all {@link
157    * SampleStream}s provided by the period are guaranteed to start from a key frame.
158    *
159    * <p>This method is only called after the period has been prepared and before reading from any
160    * {@link SampleStream}s provided by the period.
161    *
162    * @return If a discontinuity was read then the playback position in microseconds after the
163    *     discontinuity. Else {@link C#TIME_UNSET}.
164    */
readDiscontinuity()165   long readDiscontinuity();
166 
167   /**
168    * Attempts to seek to the specified position in microseconds.
169    *
170    * <p>After this method has been called, all {@link SampleStream}s provided by the period are
171    * guaranteed to start from a key frame.
172    *
173    * <p>This method is only called when at least one track is selected.
174    *
175    * @param positionUs The seek position in microseconds.
176    * @return The actual position to which the period was seeked, in microseconds.
177    */
seekToUs(long positionUs)178   long seekToUs(long positionUs);
179 
180   /**
181    * Returns the position to which a seek will be performed, given the specified seek position and
182    * {@link SeekParameters}.
183    *
184    * <p>This method is only called after the period has been prepared.
185    *
186    * @param positionUs The seek position in microseconds.
187    * @param seekParameters Parameters that control how the seek is performed. Implementations may
188    *     apply seek parameters on a best effort basis.
189    * @return The actual position to which a seek will be performed, in microseconds.
190    */
getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters)191   long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters);
192 
193   // SequenceableLoader interface. Overridden to provide more specific documentation.
194 
195   /**
196    * Returns an estimate of the position up to which data is buffered for the enabled tracks.
197    *
198    * <p>This method is only called when at least one track is selected.
199    *
200    * @return An estimate of the absolute position in microseconds up to which data is buffered, or
201    *     {@link C#TIME_END_OF_SOURCE} if the track is fully buffered.
202    */
203   @Override
getBufferedPositionUs()204   long getBufferedPositionUs();
205 
206   /**
207    * Returns the next load time, or {@link C#TIME_END_OF_SOURCE} if loading has finished.
208    *
209    * <p>This method is only called after the period has been prepared. It may be called when no
210    * tracks are selected.
211    */
212   @Override
getNextLoadPositionUs()213   long getNextLoadPositionUs();
214 
215   /**
216    * Attempts to continue loading.
217    *
218    * <p>This method may be called both during and after the period has been prepared.
219    *
220    * <p>A period may call {@link Callback#onContinueLoadingRequested(SequenceableLoader)} on the
221    * {@link Callback} passed to {@link #prepare(Callback, long)} to request that this method be
222    * called when the period is permitted to continue loading data. A period may do this both during
223    * and after preparation.
224    *
225    * @param positionUs The current playback position in microseconds. If playback of this period has
226    *     not yet started, the value will be the starting position in this period minus the duration
227    *     of any media in previous periods still to be played.
228    * @return True if progress was made, meaning that {@link #getNextLoadPositionUs()} will return a
229    *     different value than prior to the call. False otherwise.
230    */
231   @Override
continueLoading(long positionUs)232   boolean continueLoading(long positionUs);
233 
234   /** Returns whether the media period is currently loading. */
isLoading()235   boolean isLoading();
236 
237   /**
238    * Re-evaluates the buffer given the playback position.
239    *
240    * <p>This method is only called after the period has been prepared.
241    *
242    * <p>A period may choose to discard buffered media so that it can be re-buffered in a different
243    * quality.
244    *
245    * @param positionUs The current playback position in microseconds. If playback of this period has
246    *     not yet started, the value will be the starting position in this period minus the duration
247    *     of any media in previous periods still to be played.
248    */
249   @Override
reevaluateBuffer(long positionUs)250   void reevaluateBuffer(long positionUs);
251 }
252