mirror of
https://github.com/samsonjs/media.git
synced 2026-03-27 09:45:47 +00:00
TrackStream -> source.SampleStream
Also addded result constants to C to remove the dependency on TrackStream from extractor.DefaultTrackOutput. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=127192488
This commit is contained in:
parent
be9d77c59c
commit
de27b2e043
24 changed files with 307 additions and 308 deletions
|
|
@ -23,7 +23,6 @@ import com.google.android.exoplayer2.ExoPlayer;
|
|||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.Renderer;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.VideoRendererEventListener;
|
||||
import com.google.android.exoplayer2.VideoRendererEventListener.EventDispatcher;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
|
|
@ -289,10 +288,10 @@ public final class LibvpxVideoRenderer extends Renderer {
|
|||
}
|
||||
|
||||
int result = readSource(formatHolder, inputBuffer);
|
||||
if (result == TrackStream.NOTHING_READ) {
|
||||
if (result == C.RESULT_NOTHING_READ) {
|
||||
return false;
|
||||
}
|
||||
if (result == TrackStream.FORMAT_READ) {
|
||||
if (result == C.RESULT_FORMAT_READ) {
|
||||
onInputFormatChanged(formatHolder.format);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -396,7 +395,7 @@ public final class LibvpxVideoRenderer extends Renderer {
|
|||
|
||||
private boolean readFormat() {
|
||||
int result = readSource(formatHolder, null);
|
||||
if (result == TrackStream.FORMAT_READ) {
|
||||
if (result == C.RESULT_FORMAT_READ) {
|
||||
onInputFormatChanged(formatHolder.format);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,6 +152,21 @@ public interface C {
|
|||
*/
|
||||
int RESULT_MAX_LENGTH_EXCEEDED = -2;
|
||||
|
||||
/**
|
||||
* A return value for methods where nothing was read.
|
||||
*/
|
||||
int RESULT_NOTHING_READ = -3;
|
||||
|
||||
/**
|
||||
* A return value for methods where a buffer was read.
|
||||
*/
|
||||
int RESULT_BUFFER_READ = -4;
|
||||
|
||||
/**
|
||||
* A return value for methods where a format was read.
|
||||
*/
|
||||
int RESULT_FORMAT_READ = -5;
|
||||
|
||||
/**
|
||||
* A data type constant for data of unknown or unspecified type.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import com.google.android.exoplayer2.ExoPlayer.ExoPlayerMessage;
|
|||
import com.google.android.exoplayer2.TrackSelector.InvalidationListener;
|
||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.SampleStream;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.util.PriorityHandlerThread;
|
||||
import com.google.android.exoplayer2.util.TraceUtil;
|
||||
|
|
@ -682,7 +683,7 @@ import java.util.ArrayList;
|
|||
}
|
||||
updateTimelineState();
|
||||
if (readingPeriod == null) {
|
||||
// The renderers have their final TrackStreams.
|
||||
// The renderers have their final SampleStreams.
|
||||
return;
|
||||
}
|
||||
for (Renderer renderer : enabledRenderers) {
|
||||
|
|
@ -701,18 +702,18 @@ import java.util.ArrayList;
|
|||
TrackSelection newSelection = newTrackSelections.get(i);
|
||||
if (oldSelection != null) {
|
||||
if (newSelection != null) {
|
||||
// Replace the renderer's TrackStream so the transition to playing the next period can
|
||||
// be seamless.
|
||||
// Replace the renderer's SampleStream so the transition to playing the next period
|
||||
// can be seamless.
|
||||
Format[] formats = new Format[newSelection.length];
|
||||
for (int j = 0; j < formats.length; j++) {
|
||||
formats[j] = groups.get(newSelection.group).getFormat(newSelection.getTrack(j));
|
||||
}
|
||||
renderer.replaceTrackStream(formats, readingPeriod.trackStreams[i],
|
||||
renderer.replaceSampleStream(formats, readingPeriod.sampleStreams[i],
|
||||
readingPeriod.offsetUs);
|
||||
} else {
|
||||
// The renderer will be disabled when transitioning to playing the next period. Mark
|
||||
// the TrackStream as final to play out any remaining data.
|
||||
renderer.setCurrentTrackStreamIsFinal();
|
||||
// the SampleStream as final to play out any remaining data.
|
||||
renderer.setCurrentSampleStreamIsFinal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -721,7 +722,7 @@ import java.util.ArrayList;
|
|||
readingPeriod = null;
|
||||
// This is the last period, so signal the renderers to read the end of the stream.
|
||||
for (Renderer renderer : enabledRenderers) {
|
||||
renderer.setCurrentTrackStreamIsFinal();
|
||||
renderer.setCurrentSampleStreamIsFinal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -964,7 +965,7 @@ import java.util.ArrayList;
|
|||
formats[j] = trackGroups.get(newSelection.group).getFormat(newSelection.getTrack(j));
|
||||
}
|
||||
// Enable the renderer.
|
||||
renderer.enable(formats, playingPeriod.trackStreams[i], internalPositionUs, joining,
|
||||
renderer.enable(formats, playingPeriod.sampleStreams[i], internalPositionUs, joining,
|
||||
playingPeriod.offsetUs);
|
||||
MediaClock mediaClock = renderer.getMediaClock();
|
||||
if (mediaClock != null) {
|
||||
|
|
@ -996,7 +997,7 @@ import java.util.ArrayList;
|
|||
|
||||
public final MediaPeriod mediaPeriod;
|
||||
public final int index;
|
||||
public final TrackStream[] trackStreams;
|
||||
public final SampleStream[] sampleStreams;
|
||||
|
||||
public boolean prepared;
|
||||
public boolean hasEnabledTracks;
|
||||
|
|
@ -1014,7 +1015,7 @@ import java.util.ArrayList;
|
|||
this.trackSelector = trackSelector;
|
||||
this.mediaPeriod = mediaPeriod;
|
||||
this.index = index;
|
||||
trackStreams = new TrackStream[renderers.length];
|
||||
sampleStreams = new SampleStream[renderers.length];
|
||||
}
|
||||
|
||||
public void setNextPeriod(Period nextPeriod) {
|
||||
|
|
@ -1049,7 +1050,7 @@ import java.util.ArrayList;
|
|||
public void updatePeriodTrackSelection(long positionUs, LoadControl loadControl,
|
||||
boolean forceRecreateStreams) throws ExoPlaybackException {
|
||||
// Populate lists of streams that are being disabled/newly enabled.
|
||||
ArrayList<TrackStream> oldStreams = new ArrayList<>();
|
||||
ArrayList<SampleStream> oldStreams = new ArrayList<>();
|
||||
ArrayList<TrackSelection> newSelections = new ArrayList<>();
|
||||
for (int i = 0; i < trackSelections.length; i++) {
|
||||
TrackSelection oldSelection =
|
||||
|
|
@ -1057,7 +1058,7 @@ import java.util.ArrayList;
|
|||
TrackSelection newSelection = trackSelections.get(i);
|
||||
if (forceRecreateStreams || !Util.areEqual(oldSelection, newSelection)) {
|
||||
if (oldSelection != null) {
|
||||
oldStreams.add(trackStreams[i]);
|
||||
oldStreams.add(sampleStreams[i]);
|
||||
}
|
||||
if (newSelection != null) {
|
||||
newSelections.add(newSelection);
|
||||
|
|
@ -1066,7 +1067,7 @@ import java.util.ArrayList;
|
|||
}
|
||||
|
||||
// Disable streams on the period and get new streams for updated/newly-enabled tracks.
|
||||
TrackStream[] newStreams = mediaPeriod.selectTracks(oldStreams, newSelections, positionUs);
|
||||
SampleStream[] newStreams = mediaPeriod.selectTracks(oldStreams, newSelections, positionUs);
|
||||
periodTrackSelections = trackSelections;
|
||||
hasEnabledTracks = false;
|
||||
for (int i = 0; i < trackSelections.length; i++) {
|
||||
|
|
@ -1075,12 +1076,12 @@ import java.util.ArrayList;
|
|||
hasEnabledTracks = true;
|
||||
int index = newSelections.indexOf(selection);
|
||||
if (index != -1) {
|
||||
trackStreams[i] = newStreams[index];
|
||||
sampleStreams[i] = newStreams[index];
|
||||
} else {
|
||||
// This selection/stream is unchanged.
|
||||
}
|
||||
} else {
|
||||
trackStreams[i] = null;
|
||||
sampleStreams[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -461,7 +461,7 @@ public abstract class MediaCodecRenderer extends Renderer {
|
|||
|
||||
private void readFormat() throws ExoPlaybackException {
|
||||
int result = readSource(formatHolder, null);
|
||||
if (result == TrackStream.FORMAT_READ) {
|
||||
if (result == C.RESULT_FORMAT_READ) {
|
||||
onInputFormatChanged(formatHolder.format);
|
||||
}
|
||||
}
|
||||
|
|
@ -544,7 +544,7 @@ public abstract class MediaCodecRenderer extends Renderer {
|
|||
int adaptiveReconfigurationBytes = 0;
|
||||
if (waitingForKeys) {
|
||||
// We've already read an encrypted sample into buffer, and are waiting for keys.
|
||||
result = TrackStream.BUFFER_READ;
|
||||
result = C.RESULT_BUFFER_READ;
|
||||
} else {
|
||||
// For adaptive reconfiguration OMX decoders expect all reconfiguration data to be supplied
|
||||
// at the start of the buffer that also contains the first frame in the new format.
|
||||
|
|
@ -559,10 +559,10 @@ public abstract class MediaCodecRenderer extends Renderer {
|
|||
result = readSource(formatHolder, buffer);
|
||||
}
|
||||
|
||||
if (result == TrackStream.NOTHING_READ) {
|
||||
if (result == C.RESULT_NOTHING_READ) {
|
||||
return false;
|
||||
}
|
||||
if (result == TrackStream.FORMAT_READ) {
|
||||
if (result == C.RESULT_FORMAT_READ) {
|
||||
if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) {
|
||||
// We received two formats in a row. Clear the current buffer of any reconfiguration data
|
||||
// associated with the first format.
|
||||
|
|
|
|||
|
|
@ -16,13 +16,14 @@
|
|||
package com.google.android.exoplayer2;
|
||||
|
||||
import com.google.android.exoplayer2.ExoPlayer.ExoPlayerComponent;
|
||||
import com.google.android.exoplayer2.source.SampleStream;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Renders a single component of media.
|
||||
* Renders media samples read from a {@link SampleStream}.
|
||||
* <p>
|
||||
* Internally, a renderer's lifecycle is managed by the owning {@link ExoPlayer}. The player will
|
||||
* transition its renderers through various states as the overall playback state changes. The valid
|
||||
|
|
@ -107,7 +108,7 @@ public abstract class Renderer implements ExoPlayerComponent {
|
|||
|
||||
private int index;
|
||||
private int state;
|
||||
private TrackStream stream;
|
||||
private SampleStream stream;
|
||||
private long streamOffsetUs;
|
||||
private boolean readEndOfStream;
|
||||
private boolean streamIsFinal;
|
||||
|
|
@ -169,22 +170,22 @@ public abstract class Renderer implements ExoPlayerComponent {
|
|||
}
|
||||
|
||||
/**
|
||||
* Enable the renderer to consume from the specified {@link TrackStream}.
|
||||
* Enable the renderer to consume from the specified {@link SampleStream}.
|
||||
*
|
||||
* @param formats The enabled formats.
|
||||
* @param stream The track stream from which the renderer should consume.
|
||||
* @param stream The {@link SampleStream} from which the renderer should consume.
|
||||
* @param positionUs The player's current position.
|
||||
* @param joining Whether this renderer is being enabled to join an ongoing playback.
|
||||
* @param offsetUs The offset to be added to timestamps of buffers read from {@code stream}
|
||||
* before they are renderered.
|
||||
* before they are rendered.
|
||||
* @throws ExoPlaybackException If an error occurs.
|
||||
*/
|
||||
/* package */ final void enable(Format[] formats, TrackStream stream, long positionUs,
|
||||
/* package */ final void enable(Format[] formats, SampleStream stream, long positionUs,
|
||||
boolean joining, long offsetUs) throws ExoPlaybackException {
|
||||
Assertions.checkState(state == STATE_DISABLED);
|
||||
state = STATE_ENABLED;
|
||||
onEnabled(joining);
|
||||
replaceTrackStream(formats, stream, offsetUs);
|
||||
replaceSampleStream(formats, stream, offsetUs);
|
||||
onReset(positionUs, joining);
|
||||
}
|
||||
|
||||
|
|
@ -201,15 +202,15 @@ public abstract class Renderer implements ExoPlayerComponent {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link TrackStream} from which samples will be consumed.
|
||||
* Sets the {@link SampleStream} from which samples will be consumed.
|
||||
*
|
||||
* @param formats The enabled formats.
|
||||
* @param stream The track stream from which the renderer should consume.
|
||||
* @param stream The {@link SampleStream} from which the renderer should consume.
|
||||
* @param offsetUs The offset to be added to timestamps of buffers read from {@code stream} before
|
||||
* they are renderered.
|
||||
* they are rendered.
|
||||
* @throws ExoPlaybackException If an error occurs.
|
||||
*/
|
||||
/* package */ final void replaceTrackStream(Format[] formats, TrackStream stream, long offsetUs)
|
||||
/* package */ final void replaceSampleStream(Format[] formats, SampleStream stream, long offsetUs)
|
||||
throws ExoPlaybackException {
|
||||
Assertions.checkState(!streamIsFinal);
|
||||
this.stream = stream;
|
||||
|
|
@ -256,17 +257,17 @@ public abstract class Renderer implements ExoPlayerComponent {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns whether the renderer has read the current {@link TrackStream} to the end.
|
||||
* Returns whether the renderer has read the current {@link SampleStream} to the end.
|
||||
*/
|
||||
/* package */ final boolean hasReadStreamToEnd() {
|
||||
return readEndOfStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals to the renderer that the current {@link TrackStream} will be the final one supplied
|
||||
* Signals to the renderer that the current {@link SampleStream} will be the final one supplied
|
||||
* before it is next disabled or reset.
|
||||
*/
|
||||
/* package */ final void setCurrentTrackStreamIsFinal() {
|
||||
/* package */ final void setCurrentSampleStreamIsFinal() {
|
||||
streamIsFinal = true;
|
||||
}
|
||||
|
||||
|
|
@ -338,7 +339,7 @@ public abstract class Renderer implements ExoPlayerComponent {
|
|||
// Methods to be called by subclasses.
|
||||
|
||||
/**
|
||||
* Throws an error that's preventing the renderer from reading from its {@link TrackStream}. Does
|
||||
* Throws an error that's preventing the renderer from reading from its {@link SampleStream}. Does
|
||||
* nothing if no such error exists.
|
||||
* <p>
|
||||
* This method may be called when the renderer is in the following states:
|
||||
|
|
@ -354,14 +355,14 @@ public abstract class Renderer implements ExoPlayerComponent {
|
|||
/**
|
||||
* Reads from the enabled upstream source.
|
||||
*
|
||||
* @see TrackStream#readData(FormatHolder, DecoderInputBuffer)
|
||||
* @see SampleStream#readData(FormatHolder, DecoderInputBuffer)
|
||||
*/
|
||||
protected final int readSource(FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
int result = stream.readData(formatHolder, buffer);
|
||||
if (result == TrackStream.BUFFER_READ) {
|
||||
if (result == C.RESULT_BUFFER_READ) {
|
||||
if (buffer.isEndOfStream()) {
|
||||
readEndOfStream = true;
|
||||
return streamIsFinal ? TrackStream.BUFFER_READ : TrackStream.NOTHING_READ;
|
||||
return streamIsFinal ? C.RESULT_BUFFER_READ : C.RESULT_NOTHING_READ;
|
||||
}
|
||||
buffer.timeUs += streamOffsetUs;
|
||||
}
|
||||
|
|
@ -410,7 +411,7 @@ public abstract class Renderer implements ExoPlayerComponent {
|
|||
protected abstract int supportsFormat(Format format) throws ExoPlaybackException;
|
||||
|
||||
/**
|
||||
* Incrementally renders the {@link TrackStream}.
|
||||
* Incrementally renders the {@link SampleStream}.
|
||||
* <p>
|
||||
* This method should return quickly, and should not block if the renderer is unable to make
|
||||
* useful progress.
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ import com.google.android.exoplayer2.DecoderInputBuffer;
|
|||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.SequenceableLoader;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.extractor.DefaultTrackOutput;
|
||||
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher;
|
||||
import com.google.android.exoplayer2.source.SampleStream;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.Loader;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
|
|
@ -33,14 +33,14 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link TrackStream} that loads media in {@link Chunk}s, obtained from a {@link ChunkSource}.
|
||||
* A {@link SampleStream} that loads media in {@link Chunk}s, obtained from a {@link ChunkSource}.
|
||||
*/
|
||||
public class ChunkTrackStream<T extends ChunkSource> implements TrackStream, SequenceableLoader,
|
||||
public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, SequenceableLoader,
|
||||
Loader.Callback<Chunk> {
|
||||
|
||||
private final int trackType;
|
||||
private final T chunkSource;
|
||||
private final SequenceableLoader.Callback<ChunkTrackStream<T>> callback;
|
||||
private final SequenceableLoader.Callback<ChunkSampleStream<T>> callback;
|
||||
private final EventDispatcher eventDispatcher;
|
||||
private final int minLoadableRetryCount;
|
||||
private final LinkedList<BaseMediaChunk> mediaChunks;
|
||||
|
|
@ -66,15 +66,15 @@ public class ChunkTrackStream<T extends ChunkSource> implements TrackStream, Seq
|
|||
* before propagating an error.
|
||||
* @param eventDispatcher A dispatcher to notify of events.
|
||||
*/
|
||||
public ChunkTrackStream(int trackType, T chunkSource,
|
||||
SequenceableLoader.Callback<ChunkTrackStream<T>> callback, Allocator allocator,
|
||||
public ChunkSampleStream(int trackType, T chunkSource,
|
||||
SequenceableLoader.Callback<ChunkSampleStream<T>> callback, Allocator allocator,
|
||||
long positionUs, int minLoadableRetryCount, EventDispatcher eventDispatcher) {
|
||||
this.trackType = trackType;
|
||||
this.chunkSource = chunkSource;
|
||||
this.callback = callback;
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
loader = new Loader("Loader:ChunkTrackStream");
|
||||
loader = new Loader("Loader:ChunkSampleStream");
|
||||
nextChunkHolder = new ChunkHolder();
|
||||
mediaChunks = new LinkedList<>();
|
||||
readOnlyMediaChunks = Collections.unmodifiableList(mediaChunks);
|
||||
|
|
@ -155,7 +155,7 @@ public class ChunkTrackStream<T extends ChunkSource> implements TrackStream, Seq
|
|||
loader.release();
|
||||
}
|
||||
|
||||
// TrackStream implementation.
|
||||
// SampleStream implementation.
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
|
|
@ -173,7 +173,7 @@ public class ChunkTrackStream<T extends ChunkSource> implements TrackStream, Seq
|
|||
@Override
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
if (isPendingReset()) {
|
||||
return NOTHING_READ;
|
||||
return C.RESULT_NOTHING_READ;
|
||||
}
|
||||
|
||||
while (mediaChunks.size() > 1
|
||||
|
|
@ -19,7 +19,7 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A provider of {@link Chunk}s for a {@link ChunkTrackStream} to load.
|
||||
* A provider of {@link Chunk}s for a {@link ChunkSampleStream} to load.
|
||||
*/
|
||||
public interface ChunkSource {
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ public interface ChunkSource {
|
|||
void getNextChunk(MediaChunk previous, long playbackPositionUs, ChunkHolder out);
|
||||
|
||||
/**
|
||||
* Invoked when the {@link ChunkTrackStream} has finished loading a chunk obtained from this
|
||||
* Invoked when the {@link ChunkSampleStream} has finished loading a chunk obtained from this
|
||||
* source.
|
||||
* <p>
|
||||
* This method should only be called when the source is enabled.
|
||||
|
|
@ -72,7 +72,7 @@ public interface ChunkSource {
|
|||
void onChunkLoadCompleted(Chunk chunk);
|
||||
|
||||
/**
|
||||
* Invoked when the {@link ChunkTrackStream} encounters an error loading a chunk obtained from
|
||||
* Invoked when the {@link ChunkSampleStream} encounters an error loading a chunk obtained from
|
||||
* this source.
|
||||
* <p>
|
||||
* This method should only be called when the source is enabled.
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import com.google.android.exoplayer2.Format;
|
|||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.MediaClock;
|
||||
import com.google.android.exoplayer2.Renderer;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.audio.AudioCapabilities;
|
||||
import com.google.android.exoplayer2.audio.AudioTrack;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
|
|
@ -241,10 +240,10 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc
|
|||
}
|
||||
|
||||
int result = readSource(formatHolder, inputBuffer);
|
||||
if (result == TrackStream.NOTHING_READ) {
|
||||
if (result == C.RESULT_NOTHING_READ) {
|
||||
return false;
|
||||
}
|
||||
if (result == TrackStream.FORMAT_READ) {
|
||||
if (result == C.RESULT_FORMAT_READ) {
|
||||
onInputFormatChanged(formatHolder.format);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -354,7 +353,7 @@ public abstract class AudioDecoderRenderer extends Renderer implements MediaCloc
|
|||
|
||||
private boolean readFormat() {
|
||||
int result = readSource(formatHolder, null);
|
||||
if (result == TrackStream.FORMAT_READ) {
|
||||
if (result == C.RESULT_FORMAT_READ) {
|
||||
onInputFormatChanged(formatHolder.format);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import com.google.android.exoplayer2.C;
|
|||
import com.google.android.exoplayer2.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.upstream.Allocation;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
|
|
@ -252,22 +251,22 @@ public final class DefaultTrackOutput implements TrackOutput {
|
|||
* @param loadingFinished True if an empty queue should be considered the end of the stream.
|
||||
* @param decodeOnlyUntilUs If a buffer is read, the {@link C#BUFFER_FLAG_DECODE_ONLY} flag will
|
||||
* be set if the buffer's timestamp is less than this value.
|
||||
* @return The result, which can be {@link TrackStream#NOTHING_READ},
|
||||
* {@link TrackStream#FORMAT_READ} or {@link TrackStream#BUFFER_READ}.
|
||||
* @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ} or
|
||||
* {@link C#RESULT_BUFFER_READ}.
|
||||
*/
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, boolean loadingFinished,
|
||||
long decodeOnlyUntilUs) {
|
||||
switch (infoQueue.readData(formatHolder, buffer, downstreamFormat, extrasHolder)) {
|
||||
case TrackStream.NOTHING_READ:
|
||||
case C.RESULT_NOTHING_READ:
|
||||
if (loadingFinished) {
|
||||
buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
return TrackStream.BUFFER_READ;
|
||||
return C.RESULT_BUFFER_READ;
|
||||
}
|
||||
return TrackStream.NOTHING_READ;
|
||||
case TrackStream.FORMAT_READ:
|
||||
return C.RESULT_NOTHING_READ;
|
||||
case C.RESULT_FORMAT_READ:
|
||||
downstreamFormat = formatHolder.format;
|
||||
return TrackStream.FORMAT_READ;
|
||||
case TrackStream.BUFFER_READ:
|
||||
return C.RESULT_FORMAT_READ;
|
||||
case C.RESULT_BUFFER_READ:
|
||||
if (buffer.timeUs < decodeOnlyUntilUs) {
|
||||
buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
|
||||
}
|
||||
|
|
@ -280,7 +279,7 @@ public final class DefaultTrackOutput implements TrackOutput {
|
|||
readData(extrasHolder.offset, buffer.data, extrasHolder.size);
|
||||
// Advance the read head.
|
||||
dropDownstreamTo(extrasHolder.nextOffset);
|
||||
return TrackStream.BUFFER_READ;
|
||||
return C.RESULT_BUFFER_READ;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
|
@ -747,22 +746,22 @@ public final class DefaultTrackOutput implements TrackOutput {
|
|||
* @param downstreamFormat The current downstream {@link Format}. If the format of the next
|
||||
* sample is different to the current downstream format then a format will be read.
|
||||
* @param extrasHolder The holder into which extra sample information should be written.
|
||||
* @return The result, which can be {@link TrackStream#NOTHING_READ},
|
||||
* {@link TrackStream#FORMAT_READ} or {@link TrackStream#BUFFER_READ}.
|
||||
* @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ}
|
||||
* or {@link C#RESULT_BUFFER_READ}.
|
||||
*/
|
||||
public synchronized int readData(FormatHolder formatHolder, DecoderInputBuffer buffer,
|
||||
Format downstreamFormat, BufferExtrasHolder extrasHolder) {
|
||||
if (queueSize == 0) {
|
||||
if (upstreamFormat != null && upstreamFormat != downstreamFormat) {
|
||||
formatHolder.format = upstreamFormat;
|
||||
return TrackStream.FORMAT_READ;
|
||||
return C.RESULT_FORMAT_READ;
|
||||
}
|
||||
return TrackStream.NOTHING_READ;
|
||||
return C.RESULT_NOTHING_READ;
|
||||
}
|
||||
|
||||
if (formats[relativeReadIndex] != downstreamFormat) {
|
||||
formatHolder.format = formats[relativeReadIndex];
|
||||
return TrackStream.FORMAT_READ;
|
||||
return C.RESULT_FORMAT_READ;
|
||||
}
|
||||
|
||||
buffer.timeUs = timesUs[relativeReadIndex];
|
||||
|
|
@ -782,7 +781,7 @@ public final class DefaultTrackOutput implements TrackOutput {
|
|||
|
||||
extrasHolder.nextOffset = queueSize > 0 ? offsets[relativeReadIndex]
|
||||
: extrasHolder.offset + extrasHolder.size;
|
||||
return TrackStream.BUFFER_READ;
|
||||
return C.RESULT_BUFFER_READ;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import com.google.android.exoplayer2.ExoPlaybackException;
|
|||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.Renderer;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
|
||||
import android.os.Handler;
|
||||
|
|
@ -106,7 +105,7 @@ public final class MetadataRenderer<T> extends Renderer implements Callback {
|
|||
if (!inputStreamEnded && pendingMetadata == null) {
|
||||
buffer.clear();
|
||||
int result = readSource(formatHolder, buffer);
|
||||
if (result == TrackStream.BUFFER_READ) {
|
||||
if (result == C.RESULT_BUFFER_READ) {
|
||||
if (buffer.isEndOfStream()) {
|
||||
inputStreamEnded = true;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source;
|
|||
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.chunk.FormatEvaluator;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
|
|
@ -159,7 +158,7 @@ public interface AdaptiveMediaSourceEventListener {
|
|||
|
||||
/**
|
||||
* Invoked when a downstream format change occurs (i.e. when the format of the media being read
|
||||
* from one or more {@link TrackStream}s provided by the source changes).
|
||||
* from one or more {@link SampleStream}s provided by the source changes).
|
||||
*
|
||||
* @param trackType The type of the media. One of the {@link C} {@code TRACK_TYPE_*} constants.
|
||||
* @param format The new format.
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import com.google.android.exoplayer2.FormatHolder;
|
|||
import com.google.android.exoplayer2.ParserException;
|
||||
import com.google.android.exoplayer2.SequenceableLoader;
|
||||
import com.google.android.exoplayer2.TrackSelection;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||
import com.google.android.exoplayer2.extractor.DefaultTrackOutput;
|
||||
|
|
@ -234,19 +233,19 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
|
|||
}
|
||||
|
||||
@Override
|
||||
public TrackStream[] selectTracks(List<TrackStream> oldStreams,
|
||||
public SampleStream[] selectTracks(List<SampleStream> oldStreams,
|
||||
List<TrackSelection> newSelections, long positionUs) {
|
||||
Assertions.checkState(prepared);
|
||||
// Unselect old tracks.
|
||||
for (int i = 0; i < oldStreams.size(); i++) {
|
||||
int track = ((TrackStreamImpl) oldStreams.get(i)).track;
|
||||
int track = ((SampleStreamImpl) oldStreams.get(i)).track;
|
||||
Assertions.checkState(trackEnabledStates[track]);
|
||||
enabledTrackCount--;
|
||||
trackEnabledStates[track] = false;
|
||||
sampleQueues[track].disable();
|
||||
}
|
||||
// Select new tracks.
|
||||
TrackStream[] newStreams = new TrackStream[newSelections.size()];
|
||||
SampleStream[] newStreams = new SampleStream[newSelections.size()];
|
||||
for (int i = 0; i < newStreams.length; i++) {
|
||||
TrackSelection selection = newSelections.get(i);
|
||||
Assertions.checkState(selection.length == 1);
|
||||
|
|
@ -255,7 +254,7 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
|
|||
Assertions.checkState(!trackEnabledStates[track]);
|
||||
enabledTrackCount++;
|
||||
trackEnabledStates[track] = true;
|
||||
newStreams[i] = new TrackStreamImpl(track);
|
||||
newStreams[i] = new SampleStreamImpl(track);
|
||||
}
|
||||
// At the time of the first track selection all queues will be enabled, so we need to disable
|
||||
// any that are no longer required.
|
||||
|
|
@ -379,7 +378,7 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
|
|||
loadingFinished = false;
|
||||
}
|
||||
|
||||
// TrackStream methods.
|
||||
// SampleStream methods.
|
||||
|
||||
/* package */ boolean isReady(int track) {
|
||||
return loadingFinished || (!isPendingReset() && !sampleQueues[track].isEmpty());
|
||||
|
|
@ -391,7 +390,7 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
|
|||
|
||||
/* package */ int readData(int track, FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
if (notifyReset || isPendingReset()) {
|
||||
return TrackStream.NOTHING_READ;
|
||||
return C.RESULT_NOTHING_READ;
|
||||
}
|
||||
|
||||
return sampleQueues[track].readData(formatHolder, buffer, loadingFinished, lastSeekPositionUs);
|
||||
|
|
@ -580,11 +579,11 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
|
|||
}
|
||||
}
|
||||
|
||||
private final class TrackStreamImpl implements TrackStream {
|
||||
private final class SampleStreamImpl implements SampleStream {
|
||||
|
||||
private final int track;
|
||||
|
||||
public TrackStreamImpl(int track) {
|
||||
public SampleStreamImpl(int track) {
|
||||
this.track = track;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package com.google.android.exoplayer2.source;
|
|||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.SequenceableLoader;
|
||||
import com.google.android.exoplayer2.TrackSelection;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -94,28 +93,28 @@ public interface MediaPeriod extends SequenceableLoader {
|
|||
/**
|
||||
* Modifies the selected tracks.
|
||||
* <p>
|
||||
* {@link TrackStream}s corresponding to tracks being unselected are passed in {@code oldStreams}.
|
||||
* Tracks being selected are specified in {@code newSelections}. Each new {@link TrackSelection}
|
||||
* must have a {@link TrackSelection#group} index distinct from those of currently enabled tracks,
|
||||
* except for those being unselected.
|
||||
* {@link SampleStream}s corresponding to tracks being unselected are passed in
|
||||
* {@code oldStreams}. Tracks being selected are specified in {@code newSelections}. Each new
|
||||
* {@link TrackSelection} must have a {@link TrackSelection#group} index distinct from those of
|
||||
* currently enabled tracks, except for those being unselected.
|
||||
* <p>
|
||||
* This method should only be called after the period has been prepared.
|
||||
*
|
||||
* @param oldStreams {@link TrackStream}s corresponding to tracks being unselected. May be empty
|
||||
* @param oldStreams {@link SampleStream}s corresponding to tracks being unselected. May be empty
|
||||
* but must not be null.
|
||||
* @param newSelections {@link TrackSelection}s that define tracks being selected. May be empty
|
||||
* but must not be null.
|
||||
* @param positionUs The current playback position in microseconds.
|
||||
* @return The {@link TrackStream}s corresponding to each of the newly selected tracks.
|
||||
* @return The {@link SampleStream}s corresponding to each of the newly selected tracks.
|
||||
*/
|
||||
TrackStream[] selectTracks(List<TrackStream> oldStreams, List<TrackSelection> newSelections,
|
||||
SampleStream[] selectTracks(List<SampleStream> oldStreams, List<TrackSelection> newSelections,
|
||||
long positionUs);
|
||||
|
||||
/**
|
||||
* Attempts to read a discontinuity.
|
||||
* <p>
|
||||
* After this method has returned a value other than {@link C#UNSET_TIME_US}, all
|
||||
* {@link TrackStream}s provided by the period are guaranteed to start from a key frame.
|
||||
* {@link SampleStream}s provided by the period are guaranteed to start from a key frame.
|
||||
*
|
||||
* @return If a discontinuity was read then the playback position in microseconds after the
|
||||
* discontinuity. Else {@link C#UNSET_TIME_US}.
|
||||
|
|
@ -135,7 +134,7 @@ public interface MediaPeriod extends SequenceableLoader {
|
|||
/**
|
||||
* Attempts to seek to the specified position in microseconds.
|
||||
* <p>
|
||||
* After this method has been called, all {@link TrackStream}s provided by the period are
|
||||
* After this method has been called, all {@link SampleStream}s provided by the period are
|
||||
* guaranteed to start from a key frame.
|
||||
* <p>
|
||||
* This method should only be called when at least one track is selected.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import com.google.android.exoplayer2.C;
|
|||
import com.google.android.exoplayer2.CompositeSequenceableLoader;
|
||||
import com.google.android.exoplayer2.SequenceableLoader;
|
||||
import com.google.android.exoplayer2.TrackSelection;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
|
||||
import android.util.Pair;
|
||||
|
|
@ -35,7 +34,7 @@ import java.util.List;
|
|||
public final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callback {
|
||||
|
||||
private final MediaPeriod[] periods;
|
||||
private final IdentityHashMap<TrackStream, MediaPeriod> trackStreamPeriods;
|
||||
private final IdentityHashMap<SampleStream, MediaPeriod> sampleStreamPeriods;
|
||||
private final int[] selectedTrackCounts;
|
||||
|
||||
private Callback callback;
|
||||
|
|
@ -50,7 +49,7 @@ public final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callba
|
|||
public MergingMediaPeriod(MediaPeriod... periods) {
|
||||
this.periods = periods;
|
||||
pendingChildPrepareCount = periods.length;
|
||||
trackStreamPeriods = new IdentityHashMap<>();
|
||||
sampleStreamPeriods = new IdentityHashMap<>();
|
||||
selectedTrackCounts = new int[periods.length];
|
||||
}
|
||||
|
||||
|
|
@ -80,9 +79,9 @@ public final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callba
|
|||
}
|
||||
|
||||
@Override
|
||||
public TrackStream[] selectTracks(List<TrackStream> oldStreams,
|
||||
public SampleStream[] selectTracks(List<SampleStream> oldStreams,
|
||||
List<TrackSelection> newSelections, long positionUs) {
|
||||
TrackStream[] newStreams = new TrackStream[newSelections.size()];
|
||||
SampleStream[] newStreams = new SampleStream[newSelections.size()];
|
||||
// Select tracks for each period.
|
||||
int enabledPeriodCount = 0;
|
||||
for (int i = 0; i < periods.length; i++) {
|
||||
|
|
@ -206,15 +205,15 @@ public final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callba
|
|||
|
||||
// Internal methods.
|
||||
|
||||
private int selectTracks(MediaPeriod period, List<TrackStream> allOldStreams,
|
||||
List<TrackSelection> allNewSelections, long positionUs, TrackStream[] allNewStreams,
|
||||
private int selectTracks(MediaPeriod period, List<SampleStream> allOldStreams,
|
||||
List<TrackSelection> allNewSelections, long positionUs, SampleStream[] allNewStreams,
|
||||
boolean seenFirstTrackSelection) {
|
||||
// Get the subset of the old streams for the period.
|
||||
ArrayList<TrackStream> oldStreams = new ArrayList<>();
|
||||
ArrayList<SampleStream> oldStreams = new ArrayList<>();
|
||||
for (int i = 0; i < allOldStreams.size(); i++) {
|
||||
TrackStream stream = allOldStreams.get(i);
|
||||
if (trackStreamPeriods.get(stream) == period) {
|
||||
trackStreamPeriods.remove(stream);
|
||||
SampleStream stream = allOldStreams.get(i);
|
||||
if (sampleStreamPeriods.get(stream) == period) {
|
||||
sampleStreamPeriods.remove(stream);
|
||||
oldStreams.add(stream);
|
||||
}
|
||||
}
|
||||
|
|
@ -234,10 +233,10 @@ public final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callba
|
|||
return 0;
|
||||
}
|
||||
// Perform the selection.
|
||||
TrackStream[] newStreams = period.selectTracks(oldStreams, newSelections, positionUs);
|
||||
SampleStream[] newStreams = period.selectTracks(oldStreams, newSelections, positionUs);
|
||||
for (int j = 0; j < newStreams.length; j++) {
|
||||
allNewStreams[newSelectionOriginalIndices[j]] = newStreams[j];
|
||||
trackStreamPeriods.put(newStreams[j], period);
|
||||
sampleStreamPeriods.put(newStreams[j], period);
|
||||
}
|
||||
return newSelections.size() - oldStreams.size();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,27 +13,18 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2;
|
||||
package com.google.android.exoplayer2.source;
|
||||
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer2.FormatHolder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A stream of media data.
|
||||
* A stream of media samples (and associated format information).
|
||||
*/
|
||||
public interface TrackStream {
|
||||
|
||||
/**
|
||||
* Nothing was read.
|
||||
*/
|
||||
int NOTHING_READ = -1;
|
||||
/**
|
||||
* The buffer was populated.
|
||||
*/
|
||||
int BUFFER_READ = -2;
|
||||
/**
|
||||
* A format was read.
|
||||
*/
|
||||
int FORMAT_READ = -3;
|
||||
public interface SampleStream {
|
||||
|
||||
/**
|
||||
* Returns whether data is available to be read.
|
||||
|
|
@ -59,8 +50,8 @@ public interface TrackStream {
|
|||
* @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
|
||||
* end of the stream. If the end of the stream has been reached, the
|
||||
* {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer.
|
||||
* @return The result, which can be {@link #NOTHING_READ}, {@link #FORMAT_READ} or
|
||||
* {@link #BUFFER_READ}.
|
||||
* @return The result, which can be {@link C#RESULT_NOTHING_READ}, {@link C#RESULT_FORMAT_READ} or
|
||||
* {@link C#RESULT_BUFFER_READ}.
|
||||
*/
|
||||
int readData(FormatHolder formatHolder, DecoderInputBuffer buffer);
|
||||
|
||||
|
|
@ -20,7 +20,6 @@ import com.google.android.exoplayer2.DecoderInputBuffer;
|
|||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.TrackSelection;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSourceFactory;
|
||||
|
|
@ -39,7 +38,7 @@ import java.util.List;
|
|||
/**
|
||||
* Loads data at a given {@link Uri} as a single sample belonging to a single {@link MediaPeriod}.
|
||||
*/
|
||||
public final class SingleSampleMediaSource implements MediaPeriod, MediaSource, TrackStream,
|
||||
public final class SingleSampleMediaSource implements MediaPeriod, MediaSource, SampleStream,
|
||||
Loader.Callback<SingleSampleMediaSource.SourceLoadable> {
|
||||
|
||||
/**
|
||||
|
|
@ -151,12 +150,12 @@ public final class SingleSampleMediaSource implements MediaPeriod, MediaSource,
|
|||
}
|
||||
|
||||
@Override
|
||||
public TrackStream[] selectTracks(List<TrackStream> oldStreams,
|
||||
public SampleStream[] selectTracks(List<SampleStream> oldStreams,
|
||||
List<TrackSelection> newSelections, long positionUs) {
|
||||
Assertions.checkState(oldStreams.size() <= 1);
|
||||
Assertions.checkState(newSelections.size() <= 1);
|
||||
// Select new tracks.
|
||||
TrackStream[] newStreams = new TrackStream[newSelections.size()];
|
||||
SampleStream[] newStreams = new SampleStream[newSelections.size()];
|
||||
if (!newSelections.isEmpty()) {
|
||||
newStreams[0] = this;
|
||||
streamState = STREAM_STATE_SEND_FORMAT;
|
||||
|
|
@ -204,7 +203,7 @@ public final class SingleSampleMediaSource implements MediaPeriod, MediaSource,
|
|||
sampleSize = 0;
|
||||
}
|
||||
|
||||
// TrackStream implementation.
|
||||
// SampleStream implementation.
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
|
|
@ -225,23 +224,23 @@ public final class SingleSampleMediaSource implements MediaPeriod, MediaSource,
|
|||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
if (streamState == STREAM_STATE_END_OF_STREAM) {
|
||||
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
return BUFFER_READ;
|
||||
return C.RESULT_BUFFER_READ;
|
||||
} else if (streamState == STREAM_STATE_SEND_FORMAT) {
|
||||
formatHolder.format = format;
|
||||
streamState = STREAM_STATE_SEND_SAMPLE;
|
||||
return FORMAT_READ;
|
||||
return C.RESULT_FORMAT_READ;
|
||||
}
|
||||
|
||||
Assertions.checkState(streamState == STREAM_STATE_SEND_SAMPLE);
|
||||
if (!loadingFinished) {
|
||||
return NOTHING_READ;
|
||||
return C.RESULT_NOTHING_READ;
|
||||
} else {
|
||||
buffer.timeUs = 0;
|
||||
buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
|
||||
buffer.ensureSpaceForWrite(sampleSize);
|
||||
buffer.data.put(sampleData, 0, sampleSize);
|
||||
streamState = STREAM_STATE_END_OF_STREAM;
|
||||
return BUFFER_READ;
|
||||
return C.RESULT_BUFFER_READ;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
package com.google.android.exoplayer2.source;
|
||||
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
|
@ -24,8 +23,8 @@ import java.util.Arrays;
|
|||
/**
|
||||
* Defines a group of tracks exposed by a {@link MediaPeriod}.
|
||||
* <p>
|
||||
* A {@link MediaPeriod} is only able to provide one {@link TrackStream} corresponding to a group
|
||||
* at any given time. If {@link #adaptive} is true this {@link TrackStream} can adapt between
|
||||
* A {@link MediaPeriod} is only able to provide one {@link SampleStream} corresponding to a group
|
||||
* at any given time. If {@link #adaptive} is true this {@link SampleStream} can adapt between
|
||||
* multiple tracks within the group. If {@link #adaptive} is false then it's only possible to
|
||||
* consume one track from the group at a given time.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -21,14 +21,14 @@ import com.google.android.exoplayer2.Format;
|
|||
import com.google.android.exoplayer2.ParserException;
|
||||
import com.google.android.exoplayer2.SequenceableLoader;
|
||||
import com.google.android.exoplayer2.TrackSelection;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.chunk.ChunkTrackStream;
|
||||
import com.google.android.exoplayer2.chunk.ChunkSampleStream;
|
||||
import com.google.android.exoplayer2.chunk.FormatEvaluator;
|
||||
import com.google.android.exoplayer2.chunk.FormatEvaluator.AdaptiveEvaluator;
|
||||
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener;
|
||||
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher;
|
||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
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.source.dash.mpd.AdaptationSet;
|
||||
|
|
@ -66,7 +66,7 @@ import java.util.TimeZone;
|
|||
* A DASH {@link MediaSource}.
|
||||
*/
|
||||
public final class DashMediaSource implements MediaPeriod, MediaSource,
|
||||
SequenceableLoader.Callback<ChunkTrackStream<DashChunkSource>> {
|
||||
SequenceableLoader.Callback<ChunkSampleStream<DashChunkSource>> {
|
||||
|
||||
/**
|
||||
* The default minimum number of times to retry loading data prior to failing.
|
||||
|
|
@ -84,7 +84,7 @@ public final class DashMediaSource implements MediaPeriod, MediaSource,
|
|||
|
||||
private DataSource dataSource;
|
||||
private Loader loader;
|
||||
private ChunkTrackStream<DashChunkSource>[] trackStreams;
|
||||
private ChunkSampleStream<DashChunkSource>[] sampleStreams;
|
||||
private CompositeSequenceableLoader sequenceableLoader;
|
||||
|
||||
private Uri manifestUri;
|
||||
|
|
@ -139,8 +139,8 @@ public final class DashMediaSource implements MediaPeriod, MediaSource,
|
|||
public void prepare(Callback callback, Allocator allocator, long positionUs) {
|
||||
this.callback = callback;
|
||||
this.allocator = allocator;
|
||||
trackStreams = newTrackStreamArray(0);
|
||||
sequenceableLoader = new CompositeSequenceableLoader(trackStreams);
|
||||
sampleStreams = newSampleStreamArray(0);
|
||||
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
||||
dataSource = dataSourceFactory.createDataSource();
|
||||
loader = new Loader("Loader:DashMediaSource");
|
||||
manifestRefreshHandler = new Handler();
|
||||
|
|
@ -163,32 +163,32 @@ public final class DashMediaSource implements MediaPeriod, MediaSource,
|
|||
}
|
||||
|
||||
@Override
|
||||
public TrackStream[] selectTracks(List<TrackStream> oldStreams,
|
||||
public SampleStream[] selectTracks(List<SampleStream> oldStreams,
|
||||
List<TrackSelection> newSelections, long positionUs) {
|
||||
int newEnabledSourceCount = trackStreams.length + newSelections.size() - oldStreams.size();
|
||||
ChunkTrackStream<DashChunkSource>[] newTrackStreams =
|
||||
newTrackStreamArray(newEnabledSourceCount);
|
||||
int newEnabledSourceCount = sampleStreams.length + newSelections.size() - oldStreams.size();
|
||||
ChunkSampleStream<DashChunkSource>[] newSampleStreams =
|
||||
newSampleStreamArray(newEnabledSourceCount);
|
||||
int newEnabledSourceIndex = 0;
|
||||
|
||||
// Iterate over currently enabled streams, either releasing them or adding them to the new list.
|
||||
for (ChunkTrackStream<DashChunkSource> trackStream : trackStreams) {
|
||||
if (oldStreams.contains(trackStream)) {
|
||||
trackStream.release();
|
||||
for (ChunkSampleStream<DashChunkSource> sampleStream : sampleStreams) {
|
||||
if (oldStreams.contains(sampleStream)) {
|
||||
sampleStream.release();
|
||||
} else {
|
||||
newTrackStreams[newEnabledSourceIndex++] = trackStream;
|
||||
newSampleStreams[newEnabledSourceIndex++] = sampleStream;
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate and return new streams.
|
||||
TrackStream[] streamsToReturn = new TrackStream[newSelections.size()];
|
||||
SampleStream[] streamsToReturn = new SampleStream[newSelections.size()];
|
||||
for (int i = 0; i < newSelections.size(); i++) {
|
||||
newTrackStreams[newEnabledSourceIndex] = buildTrackStream(newSelections.get(i), positionUs);
|
||||
streamsToReturn[i] = newTrackStreams[newEnabledSourceIndex];
|
||||
newSampleStreams[newEnabledSourceIndex] = buildSampleStream(newSelections.get(i), positionUs);
|
||||
streamsToReturn[i] = newSampleStreams[newEnabledSourceIndex];
|
||||
newEnabledSourceIndex++;
|
||||
}
|
||||
|
||||
trackStreams = newTrackStreams;
|
||||
sequenceableLoader = new CompositeSequenceableLoader(trackStreams);
|
||||
sampleStreams = newSampleStreams;
|
||||
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
||||
return streamsToReturn;
|
||||
}
|
||||
|
||||
|
|
@ -210,8 +210,8 @@ public final class DashMediaSource implements MediaPeriod, MediaSource,
|
|||
@Override
|
||||
public long getBufferedPositionUs() {
|
||||
long bufferedPositionUs = Long.MAX_VALUE;
|
||||
for (ChunkTrackStream<DashChunkSource> trackStream : trackStreams) {
|
||||
long rendererBufferedPositionUs = trackStream.getBufferedPositionUs();
|
||||
for (ChunkSampleStream<DashChunkSource> sampleStream : sampleStreams) {
|
||||
long rendererBufferedPositionUs = sampleStream.getBufferedPositionUs();
|
||||
if (rendererBufferedPositionUs != C.END_OF_SOURCE_US) {
|
||||
bufferedPositionUs = Math.min(bufferedPositionUs, rendererBufferedPositionUs);
|
||||
}
|
||||
|
|
@ -221,8 +221,8 @@ public final class DashMediaSource implements MediaPeriod, MediaSource,
|
|||
|
||||
@Override
|
||||
public long seekToUs(long positionUs) {
|
||||
for (ChunkTrackStream<DashChunkSource> trackStream : trackStreams) {
|
||||
trackStream.seekToUs(positionUs);
|
||||
for (ChunkSampleStream<DashChunkSource> sampleStream : sampleStreams) {
|
||||
sampleStream.seekToUs(positionUs);
|
||||
}
|
||||
return positionUs;
|
||||
}
|
||||
|
|
@ -234,11 +234,11 @@ public final class DashMediaSource implements MediaPeriod, MediaSource,
|
|||
loader.release();
|
||||
loader = null;
|
||||
}
|
||||
if (trackStreams != null) {
|
||||
for (ChunkTrackStream<DashChunkSource> trackStream : trackStreams) {
|
||||
trackStream.release();
|
||||
if (sampleStreams != null) {
|
||||
for (ChunkSampleStream<DashChunkSource> sampleStream : sampleStreams) {
|
||||
sampleStream.release();
|
||||
}
|
||||
trackStreams = null;
|
||||
sampleStreams = null;
|
||||
}
|
||||
sequenceableLoader = null;
|
||||
manifestLoadStartTimestamp = 0;
|
||||
|
|
@ -260,7 +260,7 @@ public final class DashMediaSource implements MediaPeriod, MediaSource,
|
|||
// SequenceableLoader.Callback implementation.
|
||||
|
||||
@Override
|
||||
public void onContinueLoadingRequested(ChunkTrackStream<DashChunkSource> trackStream) {
|
||||
public void onContinueLoadingRequested(ChunkSampleStream<DashChunkSource> sampleStream) {
|
||||
callback.onContinueLoadingRequested(this);
|
||||
}
|
||||
|
||||
|
|
@ -285,8 +285,8 @@ public final class DashMediaSource implements MediaPeriod, MediaSource,
|
|||
finishPrepare();
|
||||
}
|
||||
} else {
|
||||
for (ChunkTrackStream<DashChunkSource> trackStream : trackStreams) {
|
||||
trackStream.getChunkSource().updateManifest(manifest);
|
||||
for (ChunkSampleStream<DashChunkSource> sampleStream : sampleStreams) {
|
||||
sampleStream.getChunkSource().updateManifest(manifest);
|
||||
}
|
||||
callback.onContinueLoadingRequested(this);
|
||||
scheduleManifestRefresh();
|
||||
|
|
@ -432,7 +432,7 @@ public final class DashMediaSource implements MediaPeriod, MediaSource,
|
|||
trackGroups = new TrackGroupArray(trackGroupArray);
|
||||
}
|
||||
|
||||
private ChunkTrackStream<DashChunkSource> buildTrackStream(TrackSelection selection,
|
||||
private ChunkSampleStream<DashChunkSource> buildSampleStream(TrackSelection selection,
|
||||
long positionUs) {
|
||||
int[] selectedTracks = selection.getTracks();
|
||||
FormatEvaluator adaptiveEvaluator = selectedTracks.length > 1
|
||||
|
|
@ -445,13 +445,13 @@ public final class DashMediaSource implements MediaPeriod, MediaSource,
|
|||
DashChunkSource chunkSource = new DashChunkSource(loader, manifest, adaptationSetIndex,
|
||||
trackGroups.get(selection.group), selectedTracks, dataSource, adaptiveEvaluator,
|
||||
elapsedRealtimeOffset);
|
||||
return new ChunkTrackStream<>(adaptationSetType, chunkSource, this, allocator, positionUs,
|
||||
return new ChunkSampleStream<>(adaptationSetType, chunkSource, this, allocator, positionUs,
|
||||
minLoadableRetryCount, eventDispatcher);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static ChunkTrackStream<DashChunkSource>[] newTrackStreamArray(int length) {
|
||||
return new ChunkTrackStream[length];
|
||||
private static ChunkSampleStream<DashChunkSource>[] newSampleStreamArray(int length) {
|
||||
return new ChunkSampleStream[length];
|
||||
}
|
||||
|
||||
private final class ManifestCallback implements
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ public class HlsChunkSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Invoked when the {@link HlsTrackStreamWrapper} has finished loading a chunk obtained from this
|
||||
* Invoked when the {@link HlsSampleStreamWrapper} has finished loading a chunk obtained from this
|
||||
* source.
|
||||
*
|
||||
* @param chunk The chunk whose load has been completed.
|
||||
|
|
@ -376,7 +376,7 @@ public class HlsChunkSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Invoked when the {@link HlsTrackStreamWrapper} encounters an error loading a chunk obtained
|
||||
* Invoked when the {@link HlsSampleStreamWrapper} encounters an error loading a chunk obtained
|
||||
* from this source.
|
||||
*
|
||||
* @param chunk The chunk whose load encountered the error.
|
||||
|
|
|
|||
|
|
@ -69,9 +69,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
* @param discontinuitySequenceNumber The discontinuity sequence number of the chunk.
|
||||
* @param extractor The extractor to parse samples from the data.
|
||||
* @param extractorNeedsInit Whether the extractor needs initializing with the target
|
||||
* {@link HlsTrackStreamWrapper}.
|
||||
* {@link HlsSampleStreamWrapper}.
|
||||
* @param shouldSpliceIn Whether the samples parsed from this chunk should be spliced into any
|
||||
* samples already queued to the {@link HlsTrackStreamWrapper}.
|
||||
* samples already queued to the {@link HlsSampleStreamWrapper}.
|
||||
* @param encryptionKey For AES encryption chunks, the encryption key.
|
||||
* @param encryptionIv For AES encryption chunks, the encryption initialization vector.
|
||||
*/
|
||||
|
|
@ -92,12 +92,12 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
}
|
||||
|
||||
/**
|
||||
* Initializes the chunk for loading, setting the {@link HlsTrackStreamWrapper} that will receive
|
||||
* Initializes the chunk for loading, setting the {@link HlsSampleStreamWrapper} that will receive
|
||||
* samples as they are loaded.
|
||||
*
|
||||
* @param output The output that will receive the loaded samples.
|
||||
*/
|
||||
public void init(HlsTrackStreamWrapper output) {
|
||||
public void init(HlsSampleStreamWrapper output) {
|
||||
output.init(uid, shouldSpliceIn);
|
||||
if (extractorNeedsInit) {
|
||||
extractor.init(output);
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ import com.google.android.exoplayer2.CompositeSequenceableLoader;
|
|||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.ParserException;
|
||||
import com.google.android.exoplayer2.TrackSelection;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.chunk.FormatEvaluator;
|
||||
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener;
|
||||
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher;
|
||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
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.source.hls.playlist.HlsMasterPlaylist;
|
||||
|
|
@ -56,7 +56,7 @@ import java.util.List;
|
|||
* An HLS {@link MediaSource}.
|
||||
*/
|
||||
public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
||||
Loader.Callback<ParsingLoadable<HlsPlaylist>>, HlsTrackStreamWrapper.Callback {
|
||||
Loader.Callback<ParsingLoadable<HlsPlaylist>>, HlsSampleStreamWrapper.Callback {
|
||||
|
||||
/**
|
||||
* The default minimum number of times to retry loading data prior to failing.
|
||||
|
|
@ -68,7 +68,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
private final BandwidthMeter bandwidthMeter;
|
||||
private final int minLoadableRetryCount;
|
||||
private final EventDispatcher eventDispatcher;
|
||||
private final IdentityHashMap<TrackStream, HlsTrackStreamWrapper> trackStreamSources;
|
||||
private final IdentityHashMap<SampleStream, HlsSampleStreamWrapper> sampleStreamSources;
|
||||
private final PtsTimestampAdjusterProvider timestampAdjusterProvider;
|
||||
private final HlsPlaylistParser manifestParser;
|
||||
|
||||
|
|
@ -85,8 +85,8 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
private boolean isLive;
|
||||
private TrackGroupArray trackGroups;
|
||||
private int[] selectedTrackCounts;
|
||||
private HlsTrackStreamWrapper[] trackStreamWrappers;
|
||||
private HlsTrackStreamWrapper[] enabledTrackStreamWrappers;
|
||||
private HlsSampleStreamWrapper[] sampleStreamWrappers;
|
||||
private HlsSampleStreamWrapper[] enabledSampleStreamWrappers;
|
||||
private CompositeSequenceableLoader sequenceableLoader;
|
||||
|
||||
public HlsMediaSource(Uri manifestUri, DataSourceFactory dataSourceFactory,
|
||||
|
|
@ -105,7 +105,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
|
||||
|
||||
trackStreamSources = new IdentityHashMap<>();
|
||||
sampleStreamSources = new IdentityHashMap<>();
|
||||
timestampAdjusterProvider = new PtsTimestampAdjusterProvider();
|
||||
manifestParser = new HlsPlaylistParser();
|
||||
}
|
||||
|
|
@ -140,11 +140,11 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
|
||||
@Override
|
||||
public void maybeThrowPrepareError() throws IOException {
|
||||
if (trackStreamWrappers == null) {
|
||||
if (sampleStreamWrappers == null) {
|
||||
manifestFetcher.maybeThrowError();
|
||||
} else {
|
||||
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
||||
trackStreamWrapper.maybeThrowPrepareError();
|
||||
for (HlsSampleStreamWrapper sampleStreamWrapper : sampleStreamWrappers) {
|
||||
sampleStreamWrapper.maybeThrowPrepareError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -160,28 +160,29 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
}
|
||||
|
||||
@Override
|
||||
public TrackStream[] selectTracks(List<TrackStream> oldStreams,
|
||||
public SampleStream[] selectTracks(List<SampleStream> oldStreams,
|
||||
List<TrackSelection> newSelections, long positionUs) {
|
||||
TrackStream[] newStreams = new TrackStream[newSelections.size()];
|
||||
SampleStream[] newStreams = new SampleStream[newSelections.size()];
|
||||
// Select tracks for each wrapper.
|
||||
int enabledTrackStreamWrapperCount = 0;
|
||||
for (int i = 0; i < trackStreamWrappers.length; i++) {
|
||||
selectedTrackCounts[i] += selectTracks(trackStreamWrappers[i], oldStreams, newSelections,
|
||||
int enabledSampleStreamWrapperCount = 0;
|
||||
for (int i = 0; i < sampleStreamWrappers.length; i++) {
|
||||
selectedTrackCounts[i] += selectTracks(sampleStreamWrappers[i], oldStreams, newSelections,
|
||||
newStreams);
|
||||
if (selectedTrackCounts[i] > 0) {
|
||||
enabledTrackStreamWrapperCount++;
|
||||
enabledSampleStreamWrapperCount++;
|
||||
}
|
||||
}
|
||||
// Update the enabled wrappers.
|
||||
enabledTrackStreamWrappers = new HlsTrackStreamWrapper[enabledTrackStreamWrapperCount];
|
||||
sequenceableLoader = new CompositeSequenceableLoader(enabledTrackStreamWrappers);
|
||||
enabledTrackStreamWrapperCount = 0;
|
||||
for (int i = 0; i < trackStreamWrappers.length; i++) {
|
||||
enabledSampleStreamWrappers = new HlsSampleStreamWrapper[enabledSampleStreamWrapperCount];
|
||||
sequenceableLoader = new CompositeSequenceableLoader(enabledSampleStreamWrappers);
|
||||
enabledSampleStreamWrapperCount = 0;
|
||||
for (int i = 0; i < sampleStreamWrappers.length; i++) {
|
||||
if (selectedTrackCounts[i] > 0) {
|
||||
enabledTrackStreamWrappers[enabledTrackStreamWrapperCount++] = trackStreamWrappers[i];
|
||||
enabledSampleStreamWrappers[enabledSampleStreamWrapperCount++] = sampleStreamWrappers[i];
|
||||
}
|
||||
}
|
||||
if (enabledTrackStreamWrapperCount > 0 && seenFirstTrackSelection && !newSelections.isEmpty()) {
|
||||
if (enabledSampleStreamWrapperCount > 0 && seenFirstTrackSelection
|
||||
&& !newSelections.isEmpty()) {
|
||||
seekToUs(positionUs);
|
||||
}
|
||||
seenFirstTrackSelection = true;
|
||||
|
|
@ -206,8 +207,8 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
@Override
|
||||
public long getBufferedPositionUs() {
|
||||
long bufferedPositionUs = Long.MAX_VALUE;
|
||||
for (HlsTrackStreamWrapper trackStreamWrapper : enabledTrackStreamWrappers) {
|
||||
long rendererBufferedPositionUs = trackStreamWrapper.getBufferedPositionUs();
|
||||
for (HlsSampleStreamWrapper sampleStreamWrapper : enabledSampleStreamWrappers) {
|
||||
long rendererBufferedPositionUs = sampleStreamWrapper.getBufferedPositionUs();
|
||||
if (rendererBufferedPositionUs != C.END_OF_SOURCE_US) {
|
||||
bufferedPositionUs = Math.min(bufferedPositionUs, rendererBufferedPositionUs);
|
||||
}
|
||||
|
|
@ -220,15 +221,15 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
// Treat all seeks into non-seekable media as being to t=0.
|
||||
positionUs = isLive ? 0 : positionUs;
|
||||
timestampAdjusterProvider.reset();
|
||||
for (HlsTrackStreamWrapper trackStreamWrapper : enabledTrackStreamWrappers) {
|
||||
trackStreamWrapper.seekTo(positionUs);
|
||||
for (HlsSampleStreamWrapper sampleStreamWrapper : enabledSampleStreamWrappers) {
|
||||
sampleStreamWrapper.seekTo(positionUs);
|
||||
}
|
||||
return positionUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
trackStreamSources.clear();
|
||||
sampleStreamSources.clear();
|
||||
timestampAdjusterProvider.reset();
|
||||
manifestDataSource = null;
|
||||
if (manifestFetcher != null) {
|
||||
|
|
@ -244,13 +245,13 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
isLive = false;
|
||||
trackGroups = null;
|
||||
selectedTrackCounts = null;
|
||||
if (trackStreamWrappers != null) {
|
||||
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
||||
trackStreamWrapper.release();
|
||||
if (sampleStreamWrappers != null) {
|
||||
for (HlsSampleStreamWrapper sampleStreamWrapper : sampleStreamWrappers) {
|
||||
sampleStreamWrapper.release();
|
||||
}
|
||||
trackStreamWrappers = null;
|
||||
sampleStreamWrappers = null;
|
||||
}
|
||||
enabledTrackStreamWrappers = null;
|
||||
enabledSampleStreamWrappers = null;
|
||||
sequenceableLoader = null;
|
||||
}
|
||||
|
||||
|
|
@ -262,13 +263,13 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
eventDispatcher.loadCompleted(loadable.dataSpec, loadable.type, elapsedRealtimeMs,
|
||||
loadDurationMs, loadable.bytesLoaded());
|
||||
HlsPlaylist playlist = loadable.getResult();
|
||||
List<HlsTrackStreamWrapper> trackStreamWrapperList = buildTrackStreamWrappers(playlist);
|
||||
trackStreamWrappers = new HlsTrackStreamWrapper[trackStreamWrapperList.size()];
|
||||
trackStreamWrapperList.toArray(trackStreamWrappers);
|
||||
selectedTrackCounts = new int[trackStreamWrappers.length];
|
||||
pendingPrepareCount = trackStreamWrappers.length;
|
||||
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
||||
trackStreamWrapper.prepare();
|
||||
List<HlsSampleStreamWrapper> sampleStreamWrapperList = buildSampleStreamWrappers(playlist);
|
||||
sampleStreamWrappers = new HlsSampleStreamWrapper[sampleStreamWrapperList.size()];
|
||||
sampleStreamWrapperList.toArray(sampleStreamWrappers);
|
||||
selectedTrackCounts = new int[sampleStreamWrappers.length];
|
||||
pendingPrepareCount = sampleStreamWrappers.length;
|
||||
for (HlsSampleStreamWrapper sampleStreamWrapper : sampleStreamWrappers) {
|
||||
sampleStreamWrapper.prepare();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -288,7 +289,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
return isFatal ? Loader.DONT_RETRY_FATAL : Loader.RETRY;
|
||||
}
|
||||
|
||||
// HlsTrackStreamWrapper.Callback implementation.
|
||||
// HlsSampleStreamWrapper.Callback implementation.
|
||||
|
||||
@Override
|
||||
public void onPrepared() {
|
||||
|
|
@ -297,19 +298,19 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
}
|
||||
|
||||
// The wrapper at index 0 is the one of type TRACK_TYPE_DEFAULT.
|
||||
durationUs = trackStreamWrappers[0].getDurationUs();
|
||||
isLive = trackStreamWrappers[0].isLive();
|
||||
durationUs = sampleStreamWrappers[0].getDurationUs();
|
||||
isLive = sampleStreamWrappers[0].isLive();
|
||||
|
||||
int totalTrackGroupCount = 0;
|
||||
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
||||
totalTrackGroupCount += trackStreamWrapper.getTrackGroups().length;
|
||||
for (HlsSampleStreamWrapper sampleStreamWrapper : sampleStreamWrappers) {
|
||||
totalTrackGroupCount += sampleStreamWrapper.getTrackGroups().length;
|
||||
}
|
||||
TrackGroup[] trackGroupArray = new TrackGroup[totalTrackGroupCount];
|
||||
int trackGroupIndex = 0;
|
||||
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
||||
int wrapperTrackGroupCount = trackStreamWrapper.getTrackGroups().length;
|
||||
for (HlsSampleStreamWrapper sampleStreamWrapper : sampleStreamWrappers) {
|
||||
int wrapperTrackGroupCount = sampleStreamWrapper.getTrackGroups().length;
|
||||
for (int j = 0; j < wrapperTrackGroupCount; j++) {
|
||||
trackGroupArray[trackGroupIndex++] = trackStreamWrapper.getTrackGroups().get(j);
|
||||
trackGroupArray[trackGroupIndex++] = sampleStreamWrapper.getTrackGroups().get(j);
|
||||
}
|
||||
}
|
||||
trackGroups = new TrackGroupArray(trackGroupArray);
|
||||
|
|
@ -317,7 +318,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onContinueLoadingRequested(HlsTrackStreamWrapper trackStreamWrapper) {
|
||||
public void onContinueLoadingRequested(HlsSampleStreamWrapper sampleStreamWrapper) {
|
||||
if (trackGroups == null) {
|
||||
// Still preparing.
|
||||
return;
|
||||
|
|
@ -327,17 +328,17 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
|
||||
// Internal methods.
|
||||
|
||||
private List<HlsTrackStreamWrapper> buildTrackStreamWrappers(HlsPlaylist playlist) {
|
||||
ArrayList<HlsTrackStreamWrapper> trackStreamWrappers = new ArrayList<>();
|
||||
private List<HlsSampleStreamWrapper> buildSampleStreamWrappers(HlsPlaylist playlist) {
|
||||
ArrayList<HlsSampleStreamWrapper> sampleStreamWrappers = new ArrayList<>();
|
||||
String baseUri = playlist.baseUri;
|
||||
|
||||
if (playlist instanceof HlsMediaPlaylist) {
|
||||
Format format = Format.createContainerFormat("0", MimeTypes.APPLICATION_M3U8, null,
|
||||
Format.NO_VALUE);
|
||||
Variant[] variants = new Variant[] {new Variant(playlist.baseUri, format, null)};
|
||||
trackStreamWrappers.add(buildTrackStreamWrapper(C.TRACK_TYPE_DEFAULT, baseUri, variants,
|
||||
sampleStreamWrappers.add(buildSampleStreamWrapper(C.TRACK_TYPE_DEFAULT, baseUri, variants,
|
||||
new FormatEvaluator.AdaptiveEvaluator(bandwidthMeter), null, null));
|
||||
return trackStreamWrappers;
|
||||
return sampleStreamWrappers;
|
||||
}
|
||||
|
||||
HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) playlist;
|
||||
|
|
@ -369,7 +370,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
if (!selectedVariants.isEmpty()) {
|
||||
Variant[] variants = new Variant[selectedVariants.size()];
|
||||
selectedVariants.toArray(variants);
|
||||
trackStreamWrappers.add(buildTrackStreamWrapper(C.TRACK_TYPE_DEFAULT, baseUri, variants,
|
||||
sampleStreamWrappers.add(buildSampleStreamWrapper(C.TRACK_TYPE_DEFAULT, baseUri, variants,
|
||||
new FormatEvaluator.AdaptiveEvaluator(bandwidthMeter), masterPlaylist.muxedAudioFormat,
|
||||
masterPlaylist.muxedCaptionFormat));
|
||||
}
|
||||
|
|
@ -379,7 +380,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
if (!audioVariants.isEmpty()) {
|
||||
Variant[] variants = new Variant[audioVariants.size()];
|
||||
audioVariants.toArray(variants);
|
||||
trackStreamWrappers.add(buildTrackStreamWrapper(C.TRACK_TYPE_AUDIO, baseUri, variants, null,
|
||||
sampleStreamWrappers.add(buildSampleStreamWrapper(C.TRACK_TYPE_AUDIO, baseUri, variants, null,
|
||||
null, null));
|
||||
}
|
||||
|
||||
|
|
@ -388,33 +389,33 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
if (!subtitleVariants.isEmpty()) {
|
||||
Variant[] variants = new Variant[subtitleVariants.size()];
|
||||
subtitleVariants.toArray(variants);
|
||||
trackStreamWrappers.add(buildTrackStreamWrapper(C.TRACK_TYPE_TEXT, baseUri, variants, null,
|
||||
sampleStreamWrappers.add(buildSampleStreamWrapper(C.TRACK_TYPE_TEXT, baseUri, variants, null,
|
||||
null, null));
|
||||
}
|
||||
|
||||
return trackStreamWrappers;
|
||||
return sampleStreamWrappers;
|
||||
}
|
||||
|
||||
private HlsTrackStreamWrapper buildTrackStreamWrapper(int trackType, String baseUri,
|
||||
private HlsSampleStreamWrapper buildSampleStreamWrapper(int trackType, String baseUri,
|
||||
Variant[] variants, FormatEvaluator formatEvaluator, Format muxedAudioFormat,
|
||||
Format muxedCaptionFormat) {
|
||||
DataSource dataSource = dataSourceFactory.createDataSource(bandwidthMeter);
|
||||
HlsChunkSource defaultChunkSource = new HlsChunkSource(baseUri, variants, dataSource,
|
||||
timestampAdjusterProvider, formatEvaluator);
|
||||
return new HlsTrackStreamWrapper(trackType, this, defaultChunkSource, allocator,
|
||||
return new HlsSampleStreamWrapper(trackType, this, defaultChunkSource, allocator,
|
||||
preparePositionUs, muxedAudioFormat, muxedCaptionFormat, minLoadableRetryCount,
|
||||
eventDispatcher);
|
||||
}
|
||||
|
||||
private int selectTracks(HlsTrackStreamWrapper trackStreamWrapper,
|
||||
List<TrackStream> allOldStreams, List<TrackSelection> allNewSelections,
|
||||
TrackStream[] allNewStreams) {
|
||||
private int selectTracks(HlsSampleStreamWrapper sampleStreamWrapper,
|
||||
List<SampleStream> allOldStreams, List<TrackSelection> allNewSelections,
|
||||
SampleStream[] allNewStreams) {
|
||||
// Get the subset of the old streams for the source.
|
||||
ArrayList<TrackStream> oldStreams = new ArrayList<>();
|
||||
ArrayList<SampleStream> oldStreams = new ArrayList<>();
|
||||
for (int i = 0; i < allOldStreams.size(); i++) {
|
||||
TrackStream stream = allOldStreams.get(i);
|
||||
if (trackStreamSources.get(stream) == trackStreamWrapper) {
|
||||
trackStreamSources.remove(stream);
|
||||
SampleStream stream = allOldStreams.get(i);
|
||||
if (sampleStreamSources.get(stream) == sampleStreamWrapper) {
|
||||
sampleStreamSources.remove(stream);
|
||||
oldStreams.add(stream);
|
||||
}
|
||||
}
|
||||
|
|
@ -423,8 +424,8 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
int[] newSelectionOriginalIndices = new int[allNewSelections.size()];
|
||||
for (int i = 0; i < allNewSelections.size(); i++) {
|
||||
TrackSelection selection = allNewSelections.get(i);
|
||||
Pair<HlsTrackStreamWrapper, Integer> sourceAndGroup = getSourceAndGroup(selection.group);
|
||||
if (sourceAndGroup.first == trackStreamWrapper) {
|
||||
Pair<HlsSampleStreamWrapper, Integer> sourceAndGroup = getSourceAndGroup(selection.group);
|
||||
if (sourceAndGroup.first == sampleStreamWrapper) {
|
||||
newSelectionOriginalIndices[newSelections.size()] = i;
|
||||
newSelections.add(new TrackSelection(sourceAndGroup.second, selection.getTracks()));
|
||||
}
|
||||
|
|
@ -434,21 +435,21 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
|
|||
return 0;
|
||||
}
|
||||
// Perform the selection.
|
||||
TrackStream[] newStreams = trackStreamWrapper.selectTracks(oldStreams, newSelections,
|
||||
SampleStream[] newStreams = sampleStreamWrapper.selectTracks(oldStreams, newSelections,
|
||||
!seenFirstTrackSelection);
|
||||
for (int j = 0; j < newStreams.length; j++) {
|
||||
allNewStreams[newSelectionOriginalIndices[j]] = newStreams[j];
|
||||
trackStreamSources.put(newStreams[j], trackStreamWrapper);
|
||||
sampleStreamSources.put(newStreams[j], sampleStreamWrapper);
|
||||
}
|
||||
return newSelections.size() - oldStreams.size();
|
||||
}
|
||||
|
||||
private Pair<HlsTrackStreamWrapper, Integer> getSourceAndGroup(int group) {
|
||||
private Pair<HlsSampleStreamWrapper, Integer> getSourceAndGroup(int group) {
|
||||
int totalTrackGroupCount = 0;
|
||||
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
||||
int sourceTrackGroupCount = trackStreamWrapper.getTrackGroups().length;
|
||||
for (HlsSampleStreamWrapper sampleStreamWrapper : sampleStreamWrappers) {
|
||||
int sourceTrackGroupCount = sampleStreamWrapper.getTrackGroups().length;
|
||||
if (group < totalTrackGroupCount + sourceTrackGroupCount) {
|
||||
return Pair.create(trackStreamWrapper, group - totalTrackGroupCount);
|
||||
return Pair.create(sampleStreamWrapper, group - totalTrackGroupCount);
|
||||
}
|
||||
totalTrackGroupCount += sourceTrackGroupCount;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import com.google.android.exoplayer2.Format;
|
|||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.SequenceableLoader;
|
||||
import com.google.android.exoplayer2.TrackSelection;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.chunk.Chunk;
|
||||
import com.google.android.exoplayer2.chunk.ChunkHolder;
|
||||
import com.google.android.exoplayer2.extractor.DefaultTrackOutput;
|
||||
|
|
@ -29,6 +28,7 @@ import com.google.android.exoplayer2.extractor.DefaultTrackOutput.UpstreamFormat
|
|||
import com.google.android.exoplayer2.extractor.ExtractorOutput;
|
||||
import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher;
|
||||
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.upstream.Allocator;
|
||||
|
|
@ -44,15 +44,15 @@ import java.util.List;
|
|||
|
||||
/**
|
||||
* Loads {@link HlsMediaChunk}s obtained from a {@link HlsChunkSource}, and provides
|
||||
* {@link TrackStream}s from which the loaded media can be consumed.
|
||||
* {@link SampleStream}s from which the loaded media can be consumed.
|
||||
*/
|
||||
/* package */ final class HlsTrackStreamWrapper implements Loader.Callback<Chunk>,
|
||||
/* package */ final class HlsSampleStreamWrapper implements Loader.Callback<Chunk>,
|
||||
SequenceableLoader, ExtractorOutput, UpstreamFormatChangedListener {
|
||||
|
||||
/**
|
||||
* A callback to be notified of events.
|
||||
*/
|
||||
public interface Callback extends SequenceableLoader.Callback<HlsTrackStreamWrapper> {
|
||||
public interface Callback extends SequenceableLoader.Callback<HlsSampleStreamWrapper> {
|
||||
|
||||
/**
|
||||
* Invoked when the wrapper has been prepared.
|
||||
|
|
@ -112,7 +112,7 @@ import java.util.List;
|
|||
* before propagating an error.
|
||||
* @param eventDispatcher A dispatcher to notify of events.
|
||||
*/
|
||||
public HlsTrackStreamWrapper(int trackType, Callback callback, HlsChunkSource chunkSource,
|
||||
public HlsSampleStreamWrapper(int trackType, Callback callback, HlsChunkSource chunkSource,
|
||||
Allocator allocator, long positionUs, Format muxedAudioFormat, Format muxedCaptionFormat,
|
||||
int minLoadableRetryCount, EventDispatcher eventDispatcher) {
|
||||
this.trackType = trackType;
|
||||
|
|
@ -123,7 +123,7 @@ import java.util.List;
|
|||
this.muxedCaptionFormat = muxedCaptionFormat;
|
||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
loader = new Loader("Loader:HlsTrackStreamWrapper");
|
||||
loader = new Loader("Loader:HlsSampleStreamWrapper");
|
||||
nextChunkHolder = new ChunkHolder();
|
||||
sampleQueues = new SparseArray<>();
|
||||
mediaChunks = new LinkedList<>();
|
||||
|
|
@ -151,17 +151,17 @@ import java.util.List;
|
|||
return trackGroups;
|
||||
}
|
||||
|
||||
public TrackStream[] selectTracks(List<TrackStream> oldStreams,
|
||||
public SampleStream[] selectTracks(List<SampleStream> oldStreams,
|
||||
List<TrackSelection> newSelections, boolean isFirstTrackSelection) {
|
||||
Assertions.checkState(prepared);
|
||||
// Unselect old tracks.
|
||||
for (int i = 0; i < oldStreams.size(); i++) {
|
||||
int group = ((TrackStreamImpl) oldStreams.get(i)).group;
|
||||
int group = ((SampleStreamImpl) oldStreams.get(i)).group;
|
||||
setTrackGroupEnabledState(group, false);
|
||||
sampleQueues.valueAt(group).disable();
|
||||
}
|
||||
// Select new tracks.
|
||||
TrackStream[] newStreams = new TrackStream[newSelections.size()];
|
||||
SampleStream[] newStreams = new SampleStream[newSelections.size()];
|
||||
for (int i = 0; i < newStreams.length; i++) {
|
||||
TrackSelection selection = newSelections.get(i);
|
||||
int group = selection.group;
|
||||
|
|
@ -170,7 +170,7 @@ import java.util.List;
|
|||
if (group == primaryTrackGroupIndex) {
|
||||
chunkSource.selectTracks(tracks);
|
||||
}
|
||||
newStreams[i] = new TrackStreamImpl(group);
|
||||
newStreams[i] = new SampleStreamImpl(group);
|
||||
}
|
||||
// At the time of the first track selection all queues will be enabled, so we need to disable
|
||||
// any that are no longer required.
|
||||
|
|
@ -239,7 +239,7 @@ import java.util.List;
|
|||
loader.release();
|
||||
}
|
||||
|
||||
// TrackStream implementation.
|
||||
// SampleStream implementation.
|
||||
|
||||
/* package */ boolean isReady(int group) {
|
||||
return loadingFinished || (!isPendingReset() && !sampleQueues.valueAt(group).isEmpty());
|
||||
|
|
@ -252,7 +252,7 @@ import java.util.List;
|
|||
|
||||
/* package */ int readData(int group, FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
if (isPendingReset()) {
|
||||
return TrackStream.NOTHING_READ;
|
||||
return C.RESULT_NOTHING_READ;
|
||||
}
|
||||
|
||||
while (mediaChunks.size() > 1 && finishedReadingChunk(mediaChunks.getFirst())) {
|
||||
|
|
@ -461,7 +461,7 @@ import java.util.List;
|
|||
}
|
||||
|
||||
/**
|
||||
* Builds tracks that are exposed by this {@link HlsTrackStreamWrapper} instance, as well as
|
||||
* Builds tracks that are exposed by this {@link HlsSampleStreamWrapper} instance, as well as
|
||||
* internal data-structures required for operation.
|
||||
* <p>
|
||||
* Tracks in HLS are complicated. A HLS master playlist contains a number of "variants". Each
|
||||
|
|
@ -475,7 +475,7 @@ import java.util.List;
|
|||
* adaptive track defined to span all variants and a track for each individual variant. The
|
||||
* adaptive track is initially selected. The extractor is then prepared to discover the tracks
|
||||
* inside of each variant stream. The two sets of tracks are then combined by this method to
|
||||
* create a third set, which is the set exposed by this {@link HlsTrackStreamWrapper}:
|
||||
* create a third set, which is the set exposed by this {@link HlsSampleStreamWrapper}:
|
||||
* <ul>
|
||||
* <li>The extractor tracks are inspected to infer a "primary" track type. If a video track is
|
||||
* present then it is always the primary type. If not, audio is the primary type if present.
|
||||
|
|
@ -587,27 +587,27 @@ import java.util.List;
|
|||
return pendingResetPositionUs != C.UNSET_TIME_US;
|
||||
}
|
||||
|
||||
private final class TrackStreamImpl implements TrackStream {
|
||||
private final class SampleStreamImpl implements SampleStream {
|
||||
|
||||
private final int group;
|
||||
|
||||
public TrackStreamImpl(int group) {
|
||||
public SampleStreamImpl(int group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return HlsTrackStreamWrapper.this.isReady(group);
|
||||
return HlsSampleStreamWrapper.this.isReady(group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void maybeThrowError() throws IOException {
|
||||
HlsTrackStreamWrapper.this.maybeThrowError();
|
||||
HlsSampleStreamWrapper.this.maybeThrowError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
return HlsTrackStreamWrapper.this.readData(group, formatHolder, buffer);
|
||||
return HlsSampleStreamWrapper.this.readData(group, formatHolder, buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,8 +21,7 @@ import com.google.android.exoplayer2.Format;
|
|||
import com.google.android.exoplayer2.ParserException;
|
||||
import com.google.android.exoplayer2.SequenceableLoader;
|
||||
import com.google.android.exoplayer2.TrackSelection;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.chunk.ChunkTrackStream;
|
||||
import com.google.android.exoplayer2.chunk.ChunkSampleStream;
|
||||
import com.google.android.exoplayer2.chunk.FormatEvaluator;
|
||||
import com.google.android.exoplayer2.chunk.FormatEvaluator.AdaptiveEvaluator;
|
||||
import com.google.android.exoplayer2.extractor.mp4.TrackEncryptionBox;
|
||||
|
|
@ -30,6 +29,7 @@ import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener;
|
|||
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher;
|
||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
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.source.smoothstreaming.SmoothStreamingManifest.ProtectionElement;
|
||||
|
|
@ -56,7 +56,7 @@ import java.util.List;
|
|||
* A SmoothStreaming {@link MediaSource}.
|
||||
*/
|
||||
public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSource,
|
||||
SequenceableLoader.Callback<ChunkTrackStream<SmoothStreamingChunkSource>>,
|
||||
SequenceableLoader.Callback<ChunkSampleStream<SmoothStreamingChunkSource>>,
|
||||
Loader.Callback<ParsingLoadable<SmoothStreamingManifest>> {
|
||||
|
||||
/**
|
||||
|
|
@ -76,7 +76,7 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
|
|||
|
||||
private DataSource manifestDataSource;
|
||||
private Loader manifestLoader;
|
||||
private ChunkTrackStream<SmoothStreamingChunkSource>[] trackStreams;
|
||||
private ChunkSampleStream<SmoothStreamingChunkSource>[] sampleStreams;
|
||||
private CompositeSequenceableLoader sequenceableLoader;
|
||||
|
||||
private long manifestLoadStartTimestamp;
|
||||
|
|
@ -129,8 +129,8 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
|
|||
public void prepare(Callback callback, Allocator allocator, long positionUs) {
|
||||
this.callback = callback;
|
||||
this.allocator = allocator;
|
||||
trackStreams = newTrackStreamArray(0);
|
||||
sequenceableLoader = new CompositeSequenceableLoader(trackStreams);
|
||||
sampleStreams = newSampleStreamArray(0);
|
||||
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
||||
manifestDataSource = dataSourceFactory.createDataSource();
|
||||
manifestLoader = new Loader("Loader:Manifest");
|
||||
manifestRefreshHandler = new Handler();
|
||||
|
|
@ -153,32 +153,32 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
|
|||
}
|
||||
|
||||
@Override
|
||||
public TrackStream[] selectTracks(List<TrackStream> oldStreams,
|
||||
public SampleStream[] selectTracks(List<SampleStream> oldStreams,
|
||||
List<TrackSelection> newSelections, long positionUs) {
|
||||
int newEnabledSourceCount = trackStreams.length + newSelections.size() - oldStreams.size();
|
||||
ChunkTrackStream<SmoothStreamingChunkSource>[] newTrackStreams =
|
||||
newTrackStreamArray(newEnabledSourceCount);
|
||||
int newEnabledSourceCount = sampleStreams.length + newSelections.size() - oldStreams.size();
|
||||
ChunkSampleStream<SmoothStreamingChunkSource>[] newSampleStreams =
|
||||
newSampleStreamArray(newEnabledSourceCount);
|
||||
int newEnabledSourceIndex = 0;
|
||||
|
||||
// Iterate over currently enabled streams, either releasing them or adding them to the new list.
|
||||
for (ChunkTrackStream<SmoothStreamingChunkSource> trackStream : trackStreams) {
|
||||
if (oldStreams.contains(trackStream)) {
|
||||
trackStream.release();
|
||||
for (ChunkSampleStream<SmoothStreamingChunkSource> sampleStream : sampleStreams) {
|
||||
if (oldStreams.contains(sampleStream)) {
|
||||
sampleStream.release();
|
||||
} else {
|
||||
newTrackStreams[newEnabledSourceIndex++] = trackStream;
|
||||
newSampleStreams[newEnabledSourceIndex++] = sampleStream;
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate and return new streams.
|
||||
TrackStream[] streamsToReturn = new TrackStream[newSelections.size()];
|
||||
SampleStream[] streamsToReturn = new SampleStream[newSelections.size()];
|
||||
for (int i = 0; i < newSelections.size(); i++) {
|
||||
newTrackStreams[newEnabledSourceIndex] = buildTrackStream(newSelections.get(i), positionUs);
|
||||
streamsToReturn[i] = newTrackStreams[newEnabledSourceIndex];
|
||||
newSampleStreams[newEnabledSourceIndex] = buildSampleStream(newSelections.get(i), positionUs);
|
||||
streamsToReturn[i] = newSampleStreams[newEnabledSourceIndex];
|
||||
newEnabledSourceIndex++;
|
||||
}
|
||||
|
||||
trackStreams = newTrackStreams;
|
||||
sequenceableLoader = new CompositeSequenceableLoader(trackStreams);
|
||||
sampleStreams = newSampleStreams;
|
||||
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
||||
return streamsToReturn;
|
||||
}
|
||||
|
||||
|
|
@ -200,8 +200,8 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
|
|||
@Override
|
||||
public long getBufferedPositionUs() {
|
||||
long bufferedPositionUs = Long.MAX_VALUE;
|
||||
for (ChunkTrackStream<SmoothStreamingChunkSource> trackStream : trackStreams) {
|
||||
long rendererBufferedPositionUs = trackStream.getBufferedPositionUs();
|
||||
for (ChunkSampleStream<SmoothStreamingChunkSource> sampleStream : sampleStreams) {
|
||||
long rendererBufferedPositionUs = sampleStream.getBufferedPositionUs();
|
||||
if (rendererBufferedPositionUs != C.END_OF_SOURCE_US) {
|
||||
bufferedPositionUs = Math.min(bufferedPositionUs, rendererBufferedPositionUs);
|
||||
}
|
||||
|
|
@ -211,8 +211,8 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
|
|||
|
||||
@Override
|
||||
public long seekToUs(long positionUs) {
|
||||
for (ChunkTrackStream<SmoothStreamingChunkSource> trackStream : trackStreams) {
|
||||
trackStream.seekToUs(positionUs);
|
||||
for (ChunkSampleStream<SmoothStreamingChunkSource> sampleStream : sampleStreams) {
|
||||
sampleStream.seekToUs(positionUs);
|
||||
}
|
||||
return positionUs;
|
||||
}
|
||||
|
|
@ -224,11 +224,11 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
|
|||
manifestLoader.release();
|
||||
manifestLoader = null;
|
||||
}
|
||||
if (trackStreams != null) {
|
||||
for (ChunkTrackStream<SmoothStreamingChunkSource> trackStream : trackStreams) {
|
||||
trackStream.release();
|
||||
if (sampleStreams != null) {
|
||||
for (ChunkSampleStream<SmoothStreamingChunkSource> sampleStream : sampleStreams) {
|
||||
sampleStream.release();
|
||||
}
|
||||
trackStreams = null;
|
||||
sampleStreams = null;
|
||||
}
|
||||
sequenceableLoader = null;
|
||||
manifestLoadStartTimestamp = 0;
|
||||
|
|
@ -249,7 +249,8 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
|
|||
// SequenceableLoader.Callback implementation
|
||||
|
||||
@Override
|
||||
public void onContinueLoadingRequested(ChunkTrackStream<SmoothStreamingChunkSource> trackStream) {
|
||||
public void onContinueLoadingRequested(
|
||||
ChunkSampleStream<SmoothStreamingChunkSource> sampleStream) {
|
||||
callback.onContinueLoadingRequested(this);
|
||||
}
|
||||
|
||||
|
|
@ -274,8 +275,8 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
|
|||
prepared = true;
|
||||
callback.onPeriodPrepared(this);
|
||||
} else {
|
||||
for (ChunkTrackStream<SmoothStreamingChunkSource> trackStream : trackStreams) {
|
||||
trackStream.getChunkSource().updateManifest(manifest);
|
||||
for (ChunkSampleStream<SmoothStreamingChunkSource> sampleStream : sampleStreams) {
|
||||
sampleStream.getChunkSource().updateManifest(manifest);
|
||||
}
|
||||
callback.onContinueLoadingRequested(this);
|
||||
}
|
||||
|
|
@ -343,7 +344,7 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
|
|||
trackGroups = new TrackGroupArray(trackGroupArray);
|
||||
}
|
||||
|
||||
private ChunkTrackStream<SmoothStreamingChunkSource> buildTrackStream(TrackSelection selection,
|
||||
private ChunkSampleStream<SmoothStreamingChunkSource> buildSampleStream(TrackSelection selection,
|
||||
long positionUs) {
|
||||
int[] selectedTracks = selection.getTracks();
|
||||
FormatEvaluator adaptiveEvaluator = selectedTracks.length > 1
|
||||
|
|
@ -355,13 +356,13 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
|
|||
SmoothStreamingChunkSource chunkSource = new SmoothStreamingChunkSource(manifestLoader,
|
||||
manifest, streamElementIndex, trackGroups.get(selection.group), selectedTracks, dataSource,
|
||||
adaptiveEvaluator, trackEncryptionBoxes);
|
||||
return new ChunkTrackStream<>(streamElementType, chunkSource, this, allocator, positionUs,
|
||||
return new ChunkSampleStream<>(streamElementType, chunkSource, this, allocator, positionUs,
|
||||
minLoadableRetryCount, eventDispatcher);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static ChunkTrackStream<SmoothStreamingChunkSource>[] newTrackStreamArray(int length) {
|
||||
return new ChunkTrackStream[length];
|
||||
private static ChunkSampleStream<SmoothStreamingChunkSource>[] newSampleStreamArray(int length) {
|
||||
return new ChunkSampleStream[length];
|
||||
}
|
||||
|
||||
private static byte[] getProtectionElementKeyId(byte[] initData) {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import com.google.android.exoplayer2.Format;
|
|||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.ParserException;
|
||||
import com.google.android.exoplayer2.Renderer;
|
||||
import com.google.android.exoplayer2.TrackStream;
|
||||
import com.google.android.exoplayer2.extensions.Decoder;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
|
|
@ -203,7 +202,7 @@ public final class TextRenderer extends Renderer implements Callback {
|
|||
}
|
||||
// Try and read the next subtitle from the source.
|
||||
int result = readSource(formatHolder, nextInputBuffer);
|
||||
if (result == TrackStream.BUFFER_READ) {
|
||||
if (result == C.RESULT_BUFFER_READ) {
|
||||
// Clear BUFFER_FLAG_DECODE_ONLY (see [Internal: b/27893809]) and queue the buffer.
|
||||
nextInputBuffer.clearFlag(C.BUFFER_FLAG_DECODE_ONLY);
|
||||
if (nextInputBuffer.isEndOfStream()) {
|
||||
|
|
@ -214,7 +213,7 @@ public final class TextRenderer extends Renderer implements Callback {
|
|||
}
|
||||
parser.queueInputBuffer(nextInputBuffer);
|
||||
nextInputBuffer = null;
|
||||
} else if (result == TrackStream.NOTHING_READ) {
|
||||
} else if (result == C.RESULT_NOTHING_READ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue