Add FilterableMediaPeriod interface and SmoothStreaming implementation.

This interface allows to put the mapping from tracks to StreamKeys in the same place
where we map manifest to tracks.

PiperOrigin-RevId: 225377033
This commit is contained in:
tonihei 2018-12-13 16:40:42 +00:00 committed by Oliver Woodman
parent 9c4258fef9
commit 9ed2a393b0
3 changed files with 41 additions and 11 deletions

View File

@ -19,11 +19,11 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
* Identifies a stream in a {@link FilterableManifest} by the index of the containing period, the
* index of the containing group within the period, and the index of the track within the group.
* A key for a subset of media which can be separately loaded (a "stream").
*
* <p>Note that the interpretation of period, group and index depends on the type of manifest being
* filtered.
* <p>The stream key consists of a period index, a group index within the period and a track index
* within the group. The interpretation of these indices depends on the type of media for which the
* stream key is used.
*/
public final class StreamKey implements Comparable<StreamKey> {

View File

@ -19,8 +19,11 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import org.checkerframework.checker.nullness.compatqual.NullableType;
/**
@ -83,6 +86,22 @@ public interface MediaPeriod extends SequenceableLoader {
*/
TrackGroupArray getTrackGroups();
/**
* Returns a list of {@link StreamKey stream keys} which allow to filter the media in this period
* to load only the parts needed to play the provided {@link TrackSelection}.
*
* <p>This method is only called after the period has been prepared.
*
* @param trackSelection The {@link TrackSelection} describing the tracks for which stream keys
* are requested.
* @return The corresponding {@link StreamKey stream keys} 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(TrackSelection trackSelection) {
return Collections.emptyList();
}
/**
* Performs a track selection.
*

View File

@ -20,6 +20,7 @@ import android.util.Base64;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.extractor.mp4.TrackEncryptionBox;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
@ -37,12 +38,11 @@ import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
import com.google.android.exoplayer2.upstream.TransferListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* A SmoothStreaming {@link MediaPeriod}.
*/
/* package */ final class SsMediaPeriod implements MediaPeriod,
SequenceableLoader.Callback<ChunkSampleStream<SsChunkSource>> {
/** A SmoothStreaming {@link MediaPeriod}. */
/* package */ final class SsMediaPeriod
implements MediaPeriod, SequenceableLoader.Callback<ChunkSampleStream<SsChunkSource>> {
private static final int INITIALIZATION_VECTOR_SIZE = 8;
@ -112,6 +112,8 @@ import java.util.ArrayList;
eventDispatcher.mediaPeriodReleased();
}
// MediaPeriod implementation.
@Override
public void prepare(Callback callback, long positionUs) {
this.callback = callback;
@ -157,6 +159,16 @@ import java.util.ArrayList;
return positionUs;
}
@Override
public List<StreamKey> getStreamKeys(TrackSelection trackSelection) {
List<StreamKey> streamKeys = new ArrayList<>(trackSelection.length());
int streamElementIndex = trackGroups.indexOf(trackSelection.getTrackGroup());
for (int i = 0; i < trackSelection.length(); i++) {
streamKeys.add(new StreamKey(streamElementIndex, trackSelection.getIndexInTrackGroup(i)));
}
return streamKeys;
}
@Override
public void discardBuffer(long positionUs, boolean toKeyframe) {
for (ChunkSampleStream<SsChunkSource> sampleStream : sampleStreams) {
@ -211,7 +223,7 @@ import java.util.ArrayList;
return positionUs;
}
// SequenceableLoader.Callback implementation
// SequenceableLoader.Callback implementation.
@Override
public void onContinueLoadingRequested(ChunkSampleStream<SsChunkSource> sampleStream) {
@ -277,5 +289,4 @@ import java.util.ArrayList;
data[firstPosition] = data[secondPosition];
data[secondPosition] = temp;
}
}