use of com.google.android.exoplayer2.source.SequenceableLoader in project ExoPlayer by google.
the class SsMediaPeriod method selectTracks.
@Override
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags, SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
ArrayList<ChunkSampleStream<SsChunkSource>> sampleStreamsList = new ArrayList<>();
for (int i = 0; i < selections.length; i++) {
if (streams[i] != null) {
@SuppressWarnings("unchecked") ChunkSampleStream<SsChunkSource> stream = (ChunkSampleStream<SsChunkSource>) streams[i];
if (selections[i] == null || !mayRetainStreamFlags[i]) {
stream.release();
streams[i] = null;
} else {
sampleStreamsList.add(stream);
}
}
if (streams[i] == null && selections[i] != null) {
ChunkSampleStream<SsChunkSource> stream = buildSampleStream(selections[i], positionUs);
sampleStreamsList.add(stream);
streams[i] = stream;
streamResetFlags[i] = true;
}
}
sampleStreams = newSampleStreamArray(sampleStreamsList.size());
sampleStreamsList.toArray(sampleStreams);
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
return positionUs;
}
use of com.google.android.exoplayer2.source.SequenceableLoader in project ExoPlayer by google.
the class ChunkSampleStream method continueLoading.
// SequenceableLoader implementation
@Override
public boolean continueLoading(long positionUs) {
if (loadingFinished || loader.isLoading() || loader.hasFatalError()) {
return false;
}
boolean pendingReset = isPendingReset();
List<BaseMediaChunk> chunkQueue;
long loadPositionUs;
if (pendingReset) {
chunkQueue = Collections.emptyList();
loadPositionUs = pendingResetPositionUs;
} else {
chunkQueue = readOnlyMediaChunks;
loadPositionUs = getLastMediaChunk().endTimeUs;
}
chunkSource.getNextChunk(positionUs, loadPositionUs, chunkQueue, nextChunkHolder);
boolean endOfStream = nextChunkHolder.endOfStream;
@Nullable Chunk loadable = nextChunkHolder.chunk;
nextChunkHolder.clear();
if (endOfStream) {
pendingResetPositionUs = C.TIME_UNSET;
loadingFinished = true;
return true;
}
if (loadable == null) {
return false;
}
loadingChunk = loadable;
if (isMediaChunk(loadable)) {
BaseMediaChunk mediaChunk = (BaseMediaChunk) loadable;
if (pendingReset) {
// even if its timestamp is slightly earlier than the advertised chunk start time.
if (mediaChunk.startTimeUs != pendingResetPositionUs) {
primarySampleQueue.setStartTimeUs(pendingResetPositionUs);
for (SampleQueue embeddedSampleQueue : embeddedSampleQueues) {
embeddedSampleQueue.setStartTimeUs(pendingResetPositionUs);
}
}
pendingResetPositionUs = C.TIME_UNSET;
}
mediaChunk.init(chunkOutput);
mediaChunks.add(mediaChunk);
} else if (loadable instanceof InitializationChunk) {
((InitializationChunk) loadable).init(chunkOutput);
}
long elapsedRealtimeMs = loader.startLoading(loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(loadable.type));
mediaSourceEventDispatcher.loadStarted(new LoadEventInfo(loadable.loadTaskId, loadable.dataSpec, elapsedRealtimeMs), loadable.type, primaryTrackType, loadable.trackFormat, loadable.trackSelectionReason, loadable.trackSelectionData, loadable.startTimeUs, loadable.endTimeUs);
return true;
}
use of com.google.android.exoplayer2.source.SequenceableLoader in project ExoPlayer by google.
the class FakeAdaptiveMediaPeriod method release.
/**
* Releases the media period.
*/
public void release() {
prepared = false;
for (ChunkSampleStream<FakeChunkSource> sampleStream : sampleStreams) {
sampleStream.release();
}
sampleStreams.clear();
sequenceableLoader = new CompositeSequenceableLoader(new SequenceableLoader[0]);
}
use of com.google.android.exoplayer2.source.SequenceableLoader in project ExoPlayer by google.
the class FakeAdaptiveMediaPeriod method selectTracks.
// Casting sample streams created by this class.
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public long selectTracks(@NullableType ExoTrackSelection[] selections, boolean[] mayRetainStreamFlags, @NullableType SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
assertThat(prepared).isTrue();
int rendererCount = selections.length;
for (int i = 0; i < rendererCount; i++) {
if (streams[i] != null && (selections[i] == null || !mayRetainStreamFlags[i])) {
((ChunkSampleStream<FakeChunkSource>) streams[i]).release();
sampleStreams.remove(streams[i]);
streams[i] = null;
}
if (streams[i] == null && selections[i] != null) {
ExoTrackSelection selection = selections[i];
assertThat(selection.length()).isAtLeast(1);
TrackGroup trackGroup = selection.getTrackGroup();
assertThat(trackGroupArray.indexOf(trackGroup)).isNotEqualTo(C.INDEX_UNSET);
int indexInTrackGroup = selection.getIndexInTrackGroup(selection.getSelectedIndex());
assertThat(indexInTrackGroup).isAtLeast(0);
assertThat(indexInTrackGroup).isLessThan(trackGroup.length);
FakeChunkSource chunkSource = chunkSourceFactory.createChunkSource(selection, durationUs, transferListener);
ChunkSampleStream<FakeChunkSource> sampleStream = new ChunkSampleStream<>(MimeTypes.getTrackType(selection.getSelectedFormat().sampleMimeType), /* embeddedTrackTypes= */
null, /* embeddedTrackFormats= */
null, chunkSource, /* callback= */
this, allocator, positionUs, DrmSessionManager.DRM_UNSUPPORTED, new DrmSessionEventListener.EventDispatcher(), new DefaultLoadErrorHandlingPolicy(/* minimumLoadableRetryCount= */
3), mediaSourceEventDispatcher);
streams[i] = sampleStream;
sampleStreams.add(sampleStream);
streamResetFlags[i] = true;
}
}
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams.toArray(new ChunkSampleStream[0]));
return seekToUs(positionUs);
}
use of com.google.android.exoplayer2.source.SequenceableLoader in project ExoPlayer by google.
the class DashMediaPeriod method selectTracks.
@Override
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags, SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
int adaptationSetCount = adaptationSets.size();
HashMap<Integer, ChunkSampleStream<DashChunkSource>> primarySampleStreams = new HashMap<>();
// First pass for primary tracks.
for (int i = 0; i < selections.length; i++) {
if (streams[i] instanceof ChunkSampleStream) {
@SuppressWarnings("unchecked") ChunkSampleStream<DashChunkSource> stream = (ChunkSampleStream<DashChunkSource>) streams[i];
if (selections[i] == null || !mayRetainStreamFlags[i]) {
stream.release();
streams[i] = null;
} else {
int adaptationSetIndex = trackGroups.indexOf(selections[i].getTrackGroup());
primarySampleStreams.put(adaptationSetIndex, stream);
}
}
if (streams[i] == null && selections[i] != null) {
int trackGroupIndex = trackGroups.indexOf(selections[i].getTrackGroup());
if (trackGroupIndex < adaptationSetCount) {
ChunkSampleStream<DashChunkSource> stream = buildSampleStream(trackGroupIndex, selections[i], positionUs);
primarySampleStreams.put(trackGroupIndex, stream);
streams[i] = stream;
streamResetFlags[i] = true;
}
}
}
// Second pass for embedded tracks.
for (int i = 0; i < selections.length; i++) {
if ((streams[i] instanceof EmbeddedSampleStream || streams[i] instanceof EmptySampleStream) && (selections[i] == null || !mayRetainStreamFlags[i])) {
// The stream is for an embedded track and is either no longer selected or needs replacing.
releaseIfEmbeddedSampleStream(streams[i]);
streams[i] = null;
}
// may have been replaced, selected or deselected.
if (selections[i] != null) {
int trackGroupIndex = trackGroups.indexOf(selections[i].getTrackGroup());
if (trackGroupIndex >= adaptationSetCount) {
int embeddedTrackIndex = trackGroupIndex - adaptationSetCount;
EmbeddedTrackInfo embeddedTrackInfo = embeddedTrackInfos[embeddedTrackIndex];
int adaptationSetIndex = embeddedTrackInfo.adaptationSetIndex;
ChunkSampleStream<?> primaryStream = primarySampleStreams.get(adaptationSetIndex);
SampleStream stream = streams[i];
boolean mayRetainStream = primaryStream == null ? stream instanceof EmptySampleStream : (stream instanceof EmbeddedSampleStream && ((EmbeddedSampleStream) stream).parent == primaryStream);
if (!mayRetainStream) {
releaseIfEmbeddedSampleStream(stream);
streams[i] = primaryStream == null ? new EmptySampleStream() : primaryStream.selectEmbeddedTrack(positionUs, embeddedTrackInfo.trackType);
streamResetFlags[i] = true;
}
}
}
}
sampleStreams = newSampleStreamArray(primarySampleStreams.size());
primarySampleStreams.values().toArray(sampleStreams);
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
return positionUs;
}
Aggregations