Commit 9ed2a393 by tonihei Committed by Oliver Woodman

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
parent 9c4258fe
......@@ -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> {
......
......@@ -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;
/**
......@@ -84,6 +87,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.
*
* <p>The call receives track {@code selections} for each renderer, {@code mayRetainStreamFlags}
......
......@@ -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;
......@@ -158,6 +160,16 @@ import java.util.ArrayList;
}
@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) {
sampleStream.discardBuffer(positionUs, toKeyframe);
......@@ -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;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment