Move preparation from MediaPeriod constructors to prepare().

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=134504088
This commit is contained in:
andrewlewis 2016-09-28 00:37:42 -07:00 committed by Oliver Woodman
parent c7b5c967ff
commit 825ec70d31
17 changed files with 86 additions and 97 deletions

View file

@ -952,8 +952,9 @@ import java.io.IOException;
periodStartPositionUs = defaultPosition.second;
}
Object newPeriodUid = timeline.getPeriod(newLoadingPeriodIndex, period, true).uid;
MediaPeriod newMediaPeriod = mediaSource.createPeriod(newLoadingPeriodIndex, this,
MediaPeriod newMediaPeriod = mediaSource.createPeriod(newLoadingPeriodIndex,
loadControl.getAllocator(), periodStartPositionUs);
newMediaPeriod.prepare(this);
MediaPeriodHolder<T> newPeriodHolder = new MediaPeriodHolder<>(renderers,
rendererCapabilities, trackSelector, mediaSource, newMediaPeriod, newPeriodUid,
periodStartPositionUs);

View file

@ -18,7 +18,6 @@ package com.google.android.exoplayer2.source;
import android.util.Pair;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaPeriod.Callback;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
@ -79,12 +78,11 @@ public final class ConcatenatingMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int index, Callback callback, Allocator allocator,
long positionUs) {
public MediaPeriod createPeriod(int index, Allocator allocator, long positionUs) {
int sourceIndex = timeline.getSourceIndexForPeriod(index);
int periodIndexInSource = index - timeline.getFirstPeriodIndexInSource(sourceIndex);
MediaPeriod mediaPeriod = mediaSources[sourceIndex].createPeriod(periodIndexInSource, callback,
allocator, positionUs);
MediaPeriod mediaPeriod = mediaSources[sourceIndex].createPeriod(periodIndexInSource, allocator,
positionUs);
sourceIndexByMediaPeriod.put(mediaPeriod, sourceIndex);
return mediaPeriod;
}

View file

@ -61,7 +61,6 @@ import java.util.Arrays;
private final Handler eventHandler;
private final ExtractorMediaSource.EventListener eventListener;
private final MediaSource.Listener sourceListener;
private final Callback callback;
private final Allocator allocator;
private final Loader loader;
private final ExtractorHolder extractorHolder;
@ -70,6 +69,7 @@ import java.util.Arrays;
private final Runnable onContinueLoadingRequestedRunnable;
private final Handler handler;
private Callback callback;
private SeekMap seekMap;
private boolean tracksBuilt;
private boolean prepared;
@ -98,20 +98,18 @@ import java.util.Arrays;
* @param eventHandler A handler for events. May be null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
* @param sourceListener A listener to notify when the timeline has been loaded.
* @param callback A callback to receive updates from the period.
* @param allocator An {@link Allocator} from which to obtain media buffer allocations.
*/
public ExtractorMediaPeriod(Uri uri, DataSource dataSource, Extractor[] extractors,
int minLoadableRetryCount, Handler eventHandler,
ExtractorMediaSource.EventListener eventListener, MediaSource.Listener sourceListener,
final Callback callback, Allocator allocator) {
Allocator allocator) {
this.uri = uri;
this.dataSource = dataSource;
this.minLoadableRetryCount = minLoadableRetryCount;
this.eventHandler = eventHandler;
this.eventListener = eventListener;
this.sourceListener = sourceListener;
this.callback = callback;
this.allocator = allocator;
loader = new Loader("Loader:ExtractorMediaPeriod");
extractorHolder = new ExtractorHolder(extractors, this);
@ -135,8 +133,6 @@ import java.util.Arrays;
pendingResetPositionUs = C.TIME_UNSET;
sampleQueues = new DefaultTrackOutput[0];
length = C.LENGTH_UNSET;
loadCondition.open();
startLoading();
}
public void release() {
@ -154,6 +150,13 @@ import java.util.Arrays;
released = true;
}
@Override
public void prepare(Callback callback) {
this.callback = callback;
loadCondition.open();
startLoading();
}
@Override
public void maybeThrowPrepareError() throws IOException {
maybeThrowError();

View file

@ -23,7 +23,6 @@ import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.MediaPeriod.Callback;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.util.Assertions;
@ -148,12 +147,11 @@ public final class ExtractorMediaSource implements MediaSource, MediaSource.List
}
@Override
public MediaPeriod createPeriod(int index, Callback callback, Allocator allocator,
long positionUs) {
public MediaPeriod createPeriod(int index, Allocator allocator, long positionUs) {
Assertions.checkArgument(index == 0);
return new ExtractorMediaPeriod(uri, dataSourceFactory.createDataSource(),
extractorsFactory.createExtractors(), minLoadableRetryCount, eventHandler, eventListener,
this, callback, allocator);
this, allocator);
}
@Override

View file

@ -19,7 +19,6 @@ import android.util.Log;
import android.util.Pair;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaPeriod.Callback;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException;
@ -76,9 +75,8 @@ public final class LoopingMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int index, Callback callback, Allocator allocator,
long positionUs) {
return childSource.createPeriod(index % childPeriodCount, callback, allocator, positionUs);
public MediaPeriod createPeriod(int index, Allocator allocator, long positionUs) {
return childSource.createPeriod(index % childPeriodCount, allocator, positionUs);
}
@Override

View file

@ -42,6 +42,17 @@ public interface MediaPeriod extends SequenceableLoader {
}
/**
* Prepares this media period asynchronously.
* <p>
* {@code callback.onPrepared} is called when preparation completes. If preparation fails,
* {@link #maybeThrowPrepareError()} will throw an {@link IOException}.
*
* @param callback Callback to receive updates from this period, including being notified when
* preparation completes.
*/
void prepare(Callback callback);
/**
* Throws an error that's preventing the period from becoming prepared. Does nothing if no such
* error exists.

View file

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.source;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaPeriod.Callback;
import com.google.android.exoplayer2.upstream.Allocator;
import java.io.IOException;
@ -54,18 +53,13 @@ public interface MediaSource {
/**
* Returns a {@link MediaPeriod} corresponding to the period at the specified index.
* <p>
* {@link Callback#onPrepared(MediaPeriod)} is called after this method has returned, when the new
* period is prepared. If preparation fails, {@link MediaPeriod#maybeThrowPrepareError()} will
* throw an {@link IOException} if called on the returned instance.
*
* @param index The index of the period.
* @param callback A callback to receive updates from the period.
* @param allocator An {@link Allocator} from which to obtain media buffer allocations.
* @param positionUs The player's current playback position.
* @return A new {@link MediaPeriod}.
*/
MediaPeriod createPeriod(int index, Callback callback, Allocator allocator, long positionUs);
MediaPeriod createPeriod(int index, Allocator allocator, long positionUs);
/**
* Releases the period.

View file

@ -28,20 +28,27 @@ import java.util.IdentityHashMap;
public final MediaPeriod[] periods;
private final Callback callback;
private final IdentityHashMap<SampleStream, Integer> streamPeriodIndices;
private Callback callback;
private int pendingChildPrepareCount;
private TrackGroupArray trackGroups;
private MediaPeriod[] enabledPeriods;
private SequenceableLoader sequenceableLoader;
public MergingMediaPeriod(Callback callback, MediaPeriod... periods) {
public MergingMediaPeriod(MediaPeriod... periods) {
this.periods = periods;
this.callback = callback;
streamPeriodIndices = new IdentityHashMap<>();
}
@Override
public void prepare(Callback callback) {
this.callback = callback;
pendingChildPrepareCount = periods.length;
for (MediaPeriod period : periods) {
period.prepare(this);
}
}
@Override

View file

@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source;
import android.support.annotation.IntDef;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaPeriod.Callback;
import com.google.android.exoplayer2.upstream.Allocator;
import java.io.IOException;
import java.lang.annotation.Retention;
@ -117,15 +116,12 @@ public final class MergingMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int index, Callback callback, Allocator allocator,
long positionUs) {
public MediaPeriod createPeriod(int index, Allocator allocator, long positionUs) {
MediaPeriod[] periods = new MediaPeriod[mediaSources.length];
// The periods are only referenced after they have all been prepared.
MergingMediaPeriod mergingPeriod = new MergingMediaPeriod(callback, periods);
for (int i = 0; i < periods.length; i++) {
periods[i] = mediaSources[i].createPeriod(index, mergingPeriod, allocator, positionUs);
periods[i] = mediaSources[i].createPeriod(index, allocator, positionUs);
}
return mergingPeriod;
return new MergingMediaPeriod(periods);
}
@Override

View file

@ -51,7 +51,6 @@ import java.util.Arrays;
private final int eventSourceId;
private final TrackGroupArray tracks;
private final ArrayList<SampleStreamImpl> sampleStreams;
private final Handler handler;
/* package */ final Loader loader;
/* package */ final Format format;
@ -61,7 +60,7 @@ import java.util.Arrays;
public SingleSampleMediaPeriod(Uri uri, DataSource.Factory dataSourceFactory, Format format,
int minLoadableRetryCount, Handler eventHandler, EventListener eventListener,
int eventSourceId, final Callback callback) {
int eventSourceId) {
this.uri = uri;
this.dataSourceFactory = dataSourceFactory;
this.format = format;
@ -71,20 +70,17 @@ import java.util.Arrays;
this.eventSourceId = eventSourceId;
tracks = new TrackGroupArray(new TrackGroup(format));
sampleStreams = new ArrayList<>();
handler = new Handler();
loader = new Loader("Loader:SingleSampleMediaPeriod");
sampleData = new byte[INITIAL_SAMPLE_SIZE];
handler.post(new Runnable() {
@Override
public void run() {
callback.onPrepared(SingleSampleMediaPeriod.this);
}
});
}
public void release() {
loader.release();
handler.removeCallbacksAndMessages(null);
}
@Override
public void prepare(Callback callback) {
callback.onPrepared(this);
}
@Override

View file

@ -19,7 +19,6 @@ import android.net.Uri;
import android.os.Handler;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaPeriod.Callback;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.util.Assertions;
@ -95,11 +94,10 @@ public final class SingleSampleMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int index, Callback callback, Allocator allocator,
long positionUs) {
public MediaPeriod createPeriod(int index, Allocator allocator, long positionUs) {
Assertions.checkArgument(index == 0);
return new SingleSampleMediaPeriod(uri, dataSourceFactory, format, minLoadableRetryCount,
eventHandler, eventListener, eventSourceId, callback);
eventHandler, eventListener, eventSourceId);
}
@Override

View file

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.source.dash;
import android.os.Handler;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher;
@ -49,11 +48,10 @@ import java.util.List;
private final EventDispatcher eventDispatcher;
private final long elapsedRealtimeOffset;
private final LoaderErrorThrower manifestLoaderErrorThrower;
private final Callback callback;
private final Allocator allocator;
private final TrackGroupArray trackGroups;
private final Handler handler;
private Callback callback;
private ChunkSampleStream<DashChunkSource>[] sampleStreams;
private CompositeSequenceableLoader sequenceableLoader;
private DashManifest manifest;
@ -63,7 +61,7 @@ import java.util.List;
public DashMediaPeriod(int id, DashManifest manifest, int index,
DashChunkSource.Factory chunkSourceFactory, int minLoadableRetryCount,
EventDispatcher eventDispatcher, long elapsedRealtimeOffset,
LoaderErrorThrower manifestLoaderErrorThrower, Callback callback, Allocator allocator) {
LoaderErrorThrower manifestLoaderErrorThrower, Allocator allocator) {
this.id = id;
this.manifest = manifest;
this.index = index;
@ -72,19 +70,11 @@ import java.util.List;
this.eventDispatcher = eventDispatcher;
this.elapsedRealtimeOffset = elapsedRealtimeOffset;
this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
this.callback = callback;
this.allocator = allocator;
sampleStreams = newSampleStreamArray(0);
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
period = manifest.getPeriod(index);
trackGroups = buildTrackGroups(period);
handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
DashMediaPeriod.this.callback.onPrepared(DashMediaPeriod.this);
}
});
}
public void updateManifest(DashManifest manifest, int index) {
@ -103,7 +93,12 @@ import java.util.List;
for (ChunkSampleStream<DashChunkSource> sampleStream : sampleStreams) {
sampleStream.release();
}
handler.removeCallbacksAndMessages(null);
}
@Override
public void prepare(Callback callback) {
this.callback = callback;
callback.onPrepared(this);
}
@Override

View file

@ -26,7 +26,6 @@ import com.google.android.exoplayer2.Timeline;
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.MediaPeriod.Callback;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.manifest.DashManifestParser;
@ -171,11 +170,10 @@ public final class DashMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int index, Callback callback, Allocator allocator,
long positionUs) {
public MediaPeriod createPeriod(int index, Allocator allocator, long positionUs) {
DashMediaPeriod mediaPeriod = new DashMediaPeriod(firstPeriodId + index, manifest, index,
chunkSourceFactory, minLoadableRetryCount, eventDispatcher, elapsedRealtimeOffsetMs, loader,
callback, allocator);
allocator);
periodsById.put(mediaPeriod.id, mediaPeriod);
return mediaPeriod;
}

View file

@ -50,11 +50,11 @@ import java.util.List;
/* package */ final class HlsMediaPeriod implements MediaPeriod,
Loader.Callback<ParsingLoadable<HlsPlaylist>>, HlsSampleStreamWrapper.Callback {
private final Uri manifestUri;
private final DataSource.Factory dataSourceFactory;
private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher;
private final MediaSource.Listener sourceListener;
private final Callback callback;
private final Allocator allocator;
private final IdentityHashMap<SampleStream, Integer> streamWrapperIndices;
private final TimestampAdjusterProvider timestampAdjusterProvider;
@ -64,6 +64,7 @@ import java.util.List;
private final long preparePositionUs;
private final Runnable continueLoadingRunnable;
private Callback callback;
private int pendingPrepareCount;
private HlsPlaylist playlist;
private boolean seenFirstTrackSelection;
@ -76,13 +77,13 @@ import java.util.List;
public HlsMediaPeriod(Uri manifestUri, DataSource.Factory dataSourceFactory,
int minLoadableRetryCount, EventDispatcher eventDispatcher,
MediaSource.Listener sourceListener, final Callback callback, Allocator allocator,
MediaSource.Listener sourceListener, Allocator allocator,
long positionUs) {
this.manifestUri = manifestUri;
this.dataSourceFactory = dataSourceFactory;
this.minLoadableRetryCount = minLoadableRetryCount;
this.eventDispatcher = eventDispatcher;
this.sourceListener = sourceListener;
this.callback = callback;
this.allocator = allocator;
streamWrapperIndices = new IdentityHashMap<>();
timestampAdjusterProvider = new TimestampAdjusterProvider();
@ -96,11 +97,6 @@ import java.util.List;
callback.onContinueLoadingRequested(HlsMediaPeriod.this);
}
};
ParsingLoadable<HlsPlaylist> loadable = new ParsingLoadable<>(
dataSourceFactory.createDataSource(), manifestUri, C.DATA_TYPE_MANIFEST, manifestParser);
long elapsedRealtimeMs = manifestFetcher.startLoading(loadable, this, minLoadableRetryCount);
eventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs);
}
public void release() {
@ -111,6 +107,15 @@ import java.util.List;
}
}
@Override
public void prepare(Callback callback) {
this.callback = callback;
ParsingLoadable<HlsPlaylist> loadable = new ParsingLoadable<>(
dataSourceFactory.createDataSource(), manifestUri, C.DATA_TYPE_MANIFEST, manifestParser);
long elapsedRealtimeMs = manifestFetcher.startLoading(loadable, this, minLoadableRetryCount);
eventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs);
}
@Override
public void maybeThrowPrepareError() throws IOException {
if (sampleStreamWrappers == null) {

View file

@ -21,7 +21,6 @@ import com.google.android.exoplayer2.C;
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.MediaPeriod.Callback;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.SinglePeriodTimeline;
import com.google.android.exoplayer2.upstream.Allocator;
@ -73,11 +72,10 @@ public final class HlsMediaSource implements MediaSource {
}
@Override
public MediaPeriod createPeriod(int index, Callback callback, Allocator allocator,
long positionUs) {
public MediaPeriod createPeriod(int index, Allocator allocator, long positionUs) {
Assertions.checkArgument(index == 0);
return new HlsMediaPeriod(manifestUri, dataSourceFactory, minLoadableRetryCount,
eventDispatcher, sourceListener, callback, allocator, positionUs);
eventDispatcher, sourceListener, allocator, positionUs);
}
@Override

View file

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.source.smoothstreaming;
import android.os.Handler;
import android.util.Base64;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.extractor.mp4.TrackEncryptionBox;
@ -47,24 +46,22 @@ import java.util.ArrayList;
private final LoaderErrorThrower manifestLoaderErrorThrower;
private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher;
private final Callback callback;
private final Allocator allocator;
private final TrackGroupArray trackGroups;
private final TrackEncryptionBox[] trackEncryptionBoxes;
private final Handler handler;
private Callback callback;
private SsManifest manifest;
private ChunkSampleStream<SsChunkSource>[] sampleStreams;
private CompositeSequenceableLoader sequenceableLoader;
public SsMediaPeriod(SsManifest manifest, SsChunkSource.Factory chunkSourceFactory,
int minLoadableRetryCount, EventDispatcher eventDispatcher,
LoaderErrorThrower manifestLoaderErrorThrower, Callback callback, Allocator allocator) {
LoaderErrorThrower manifestLoaderErrorThrower, Allocator allocator) {
this.chunkSourceFactory = chunkSourceFactory;
this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
this.minLoadableRetryCount = minLoadableRetryCount;
this.eventDispatcher = eventDispatcher;
this.callback = callback;
this.allocator = allocator;
trackGroups = buildTrackGroups(manifest);
@ -76,16 +73,9 @@ import java.util.ArrayList;
} else {
trackEncryptionBoxes = null;
}
handler = new Handler();
this.manifest = manifest;
sampleStreams = newSampleStreamArray(0);
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
handler.post(new Runnable() {
@Override
public void run() {
SsMediaPeriod.this.callback.onPrepared(SsMediaPeriod.this);
}
});
}
public void updateManifest(SsManifest manifest) {
@ -100,7 +90,12 @@ import java.util.ArrayList;
for (ChunkSampleStream<SsChunkSource> sampleStream : sampleStreams) {
sampleStream.release();
}
handler.removeCallbacksAndMessages(null);
}
@Override
public void prepare(Callback callback) {
this.callback = callback;
callback.onPrepared(this);
}
@Override

View file

@ -24,7 +24,6 @@ import com.google.android.exoplayer2.Timeline;
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.MediaPeriod.Callback;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.SinglePeriodTimeline;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
@ -122,11 +121,10 @@ public final class SsMediaSource implements MediaSource,
}
@Override
public MediaPeriod createPeriod(int index, Callback callback, Allocator allocator,
long positionUs) {
public MediaPeriod createPeriod(int index, Allocator allocator, long positionUs) {
Assertions.checkArgument(index == 0);
SsMediaPeriod period = new SsMediaPeriod(manifest, chunkSourceFactory, minLoadableRetryCount,
eventDispatcher, manifestLoader, callback, allocator);
eventDispatcher, manifestLoader, allocator);
mediaPeriods.add(period);
return period;
}