Allow injection of custom FormatEvaluators

This was possible previously, but now we support things
like multi-period DASH we need to do the injection in
the form of factories rather than concrete instances.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=127735816
This commit is contained in:
olly 2016-07-18 11:07:07 -07:00 committed by Oliver Woodman
parent e7d95aff34
commit 5360ddc519
17 changed files with 171 additions and 162 deletions

View file

@ -37,6 +37,8 @@ import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.FormatEvaluator;
import com.google.android.exoplayer2.source.chunk.FormatEvaluator.AdaptiveEvaluator;
import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.source.smoothstreaming.SmoothStreamingMediaSource;
@ -47,12 +49,12 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.TrackInfo;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.ui.DebugTextViewHelper;
import com.google.android.exoplayer2.ui.PlayerControl;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSourceFactory;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.ui.DebugTextViewHelper;
import com.google.android.exoplayer2.util.Util;
import android.Manifest.permission;
@ -129,12 +131,12 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
private SubtitleLayout subtitleLayout;
private Button retryButton;
private DataSourceFactory dataSourceFactory;
private DataSource.Factory dataSourceFactory;
private FormatEvaluator.Factory formatEvaluatorFactory;
private SimpleExoPlayer player;
private MappingTrackSelector trackSelector;
private TrackSelectionHelper trackSelectionHelper;
private DebugTextViewHelper debugViewHelper;
private BandwidthMeter bandwidthMeter;
private boolean playerNeedsSource;
private int playerPeriodIndex;
@ -146,10 +148,11 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String userAgent = Util.getUserAgent(this, "ExoPlayerDemo");
dataSourceFactory = new DefaultDataSourceFactory(this, userAgent);
bandwidthMeter = new DefaultBandwidthMeter();
mainHandler = new Handler();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
dataSourceFactory = new DefaultDataSourceFactory(this, userAgent, bandwidthMeter);
formatEvaluatorFactory = new AdaptiveEvaluator.Factory(bandwidthMeter);
mainHandler = new Handler();
setContentView(R.layout.player_activity);
rootView = findViewById(R.id.root);
rootView.setOnTouchListener(new OnTouchListener() {
@ -340,16 +343,17 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
int type = Util.inferContentType(lastPathSegment);
switch (type) {
case Util.TYPE_SS:
return new SmoothStreamingMediaSource(uri, dataSourceFactory, bandwidthMeter, mainHandler,
eventLogger);
return new SmoothStreamingMediaSource(uri, dataSourceFactory, formatEvaluatorFactory,
mainHandler, eventLogger);
case Util.TYPE_DASH:
return new DashMediaSource(uri, dataSourceFactory, bandwidthMeter, mainHandler,
return new DashMediaSource(uri, dataSourceFactory, formatEvaluatorFactory, mainHandler,
eventLogger);
case Util.TYPE_HLS:
return new HlsMediaSource(uri, dataSourceFactory, bandwidthMeter, mainHandler, eventLogger);
return new HlsMediaSource(uri, dataSourceFactory, formatEvaluatorFactory, mainHandler,
eventLogger);
case Util.TYPE_OTHER:
return new ExtractorMediaSource(uri, dataSourceFactory, bandwidthMeter,
new DefaultExtractorsFactory(), mainHandler, eventLogger);
return new ExtractorMediaSource(uri, dataSourceFactory, new DefaultExtractorsFactory(),
mainHandler, eventLogger);
default:
throw new IllegalStateException("Unsupported type: " + type);
}

View file

@ -77,7 +77,6 @@ public class FlacPlaybackTest extends InstrumentationTestCase {
ExtractorMediaSource mediaSource = new ExtractorMediaSource(
uri,
new DefaultDataSourceFactory(context, "ExoPlayerExtFlacTest"),
null,
MatroskaExtractor.FACTORY,
null,
null);

View file

@ -15,51 +15,46 @@
*/
package com.google.android.exoplayer2.ext.okhttp;
import com.google.android.exoplayer2.upstream.DataSourceFactory;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSource.Factory;
import com.google.android.exoplayer2.upstream.DefaultDataSource;
import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Predicate;
import android.content.Context;
import okhttp3.CacheControl;
import okhttp3.OkHttpClient;
/**
* A {@link DataSourceFactory} that produces {@link DefaultDataSource} instances that delegate to
* A {@link Factory} that produces {@link DefaultDataSource} instances that delegate to
* {@link OkHttpDataSource}s for non-file/asset/content URIs.
*/
public final class DefaultOkHttpDataSourceFactory implements DataSourceFactory {
public final class DefaultOkHttpDataSourceFactory implements Factory {
private final Context context;
private final OkHttpClient client;
private final String userAgent;
private final Predicate<String> contentTypePredicate;
private final TransferListener transferListener;
private final CacheControl cacheControl;
public DefaultOkHttpDataSourceFactory(Context context, OkHttpClient client, String userAgent,
Predicate<String> contentTypePredicate) {
this(context, client, userAgent, contentTypePredicate, null);
TransferListener transferListener) {
this(context, client, userAgent, transferListener, null);
}
public DefaultOkHttpDataSourceFactory(Context context, OkHttpClient client, String userAgent,
Predicate<String> contentTypePredicate, CacheControl cacheControl) {
TransferListener transferListener, CacheControl cacheControl) {
this.context = context.getApplicationContext();
this.client = client;
this.userAgent = userAgent;
this.contentTypePredicate = contentTypePredicate;
this.transferListener = transferListener;
this.cacheControl = cacheControl;
}
@Override
public DefaultDataSource createDataSource() {
return createDataSource(null);
}
@Override
public DefaultDataSource createDataSource(TransferListener listener) {
return new DefaultDataSource(context, listener,
new OkHttpDataSource(client, userAgent, contentTypePredicate, listener, cacheControl));
DataSource httpDataSource = new OkHttpDataSource(client, userAgent, null, transferListener,
cacheControl);
return new DefaultDataSource(context, transferListener, httpDataSource);
}
}

View file

@ -77,7 +77,6 @@ public class OpusPlaybackTest extends InstrumentationTestCase {
ExtractorMediaSource mediaSource = new ExtractorMediaSource(
uri,
new DefaultDataSourceFactory(context, "ExoPlayerExtOpusTest"),
null,
MatroskaExtractor.FACTORY,
null,
null);

View file

@ -93,7 +93,6 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
ExtractorMediaSource mediaSource = new ExtractorMediaSource(
uri,
new DefaultDataSourceFactory(context, "ExoPlayerExtVp9Test"),
null,
MatroskaExtractor.FACTORY,
null,
null);

View file

@ -33,9 +33,7 @@ import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSourceFactory;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.Loadable;
@ -112,8 +110,7 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
private static final long DEFAULT_LAST_SAMPLE_DURATION_US = 10000;
private final Uri uri;
private final DataSourceFactory dataSourceFactory;
private final BandwidthMeter bandwidthMeter;
private final DataSource.Factory dataSourceFactory;
private final ExtractorsFactory extractorsFactory;
private final int minLoadableRetryCount;
private final Handler eventHandler;
@ -148,23 +145,20 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
/**
* @param uri The {@link Uri} of the media stream.
* @param dataSourceFactory A factory for {@link DataSource}s to read the media.
* @param bandwidthMeter A {@link BandwidthMeter} to notify of loads performed by the source.
* @param extractorsFactory Factory for {@link Extractor}s to process the media stream. If the
* possible formats are known, pass a factory that instantiates extractors for those formats.
* Otherwise, pass a {@link DefaultExtractorsFactory} to use default extractors.
* @param eventListener A listener of events. May be null if delivery of events is not required.
*/
public ExtractorMediaSource(Uri uri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, ExtractorsFactory extractorsFactory, Handler eventHandler,
EventListener eventListener) {
this(uri, dataSourceFactory, bandwidthMeter, extractorsFactory,
MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA, eventHandler, eventListener);
public ExtractorMediaSource(Uri uri, DataSource.Factory dataSourceFactory,
ExtractorsFactory extractorsFactory, Handler eventHandler, EventListener eventListener) {
this(uri, dataSourceFactory, extractorsFactory, MIN_RETRY_COUNT_DEFAULT_FOR_MEDIA, eventHandler,
eventListener);
}
/**
* @param uri The {@link Uri} of the media stream.
* @param dataSourceFactory A factory for {@link DataSource}s to read the media.
* @param bandwidthMeter A {@link BandwidthMeter} to notify of loads performed by the source.
* @param extractorsFactory Factory for {@link Extractor}s to process the media stream. If the
* possible formats are known, pass a factory that instantiates extractors for those formats.
* Otherwise, pass a {@link DefaultExtractorsFactory} to use default extractors.
@ -172,12 +166,11 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
* if a loading error occurs.
* @param eventListener A listener of events. May be null if delivery of events is not required.
*/
public ExtractorMediaSource(Uri uri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, ExtractorsFactory extractorsFactory, int minLoadableRetryCount,
Handler eventHandler, EventListener eventListener) {
public ExtractorMediaSource(Uri uri, DataSource.Factory dataSourceFactory,
ExtractorsFactory extractorsFactory, int minLoadableRetryCount, Handler eventHandler,
EventListener eventListener) {
this.uri = uri;
this.dataSourceFactory = dataSourceFactory;
this.bandwidthMeter = bandwidthMeter;
this.extractorsFactory = extractorsFactory;
this.minLoadableRetryCount = minLoadableRetryCount;
this.eventHandler = eventHandler;
@ -214,7 +207,7 @@ public final class ExtractorMediaSource implements MediaPeriod, MediaSource,
this.callback = callback;
this.allocator = allocator;
dataSource = dataSourceFactory.createDataSource(bandwidthMeter);
dataSource = dataSourceFactory.createDataSource();
loader = new Loader("Loader:ExtractorMediaSource");
extractorHolder = new ExtractorHolder(extractorsFactory.createExtractors(), this);
loadCondition = new ConditionVariable();

View file

@ -22,7 +22,6 @@ import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSourceFactory;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.Loadable;
@ -71,7 +70,7 @@ public final class SingleSampleMediaSource implements MediaPeriod, MediaSource,
private static final int STREAM_STATE_END_OF_STREAM = 2;
private final Uri uri;
private final DataSourceFactory dataSourceFactory;
private final DataSource.Factory dataSourceFactory;
private final Format format;
private final long durationUs;
private final int minLoadableRetryCount;
@ -87,17 +86,17 @@ public final class SingleSampleMediaSource implements MediaPeriod, MediaSource,
private byte[] sampleData;
private int sampleSize;
public SingleSampleMediaSource(Uri uri, DataSourceFactory dataSourceFactory, Format format,
public SingleSampleMediaSource(Uri uri, DataSource.Factory dataSourceFactory, Format format,
long durationUs) {
this(uri, dataSourceFactory, format, durationUs, DEFAULT_MIN_LOADABLE_RETRY_COUNT);
}
public SingleSampleMediaSource(Uri uri, DataSourceFactory dataSourceFactory, Format format,
public SingleSampleMediaSource(Uri uri, DataSource.Factory dataSourceFactory, Format format,
long durationUs, int minLoadableRetryCount) {
this(uri, dataSourceFactory, format, durationUs, minLoadableRetryCount, null, null, 0);
}
public SingleSampleMediaSource(Uri uri, DataSourceFactory dataSourceFactory, Format format,
public SingleSampleMediaSource(Uri uri, DataSource.Factory dataSourceFactory, Format format,
long durationUs, int minLoadableRetryCount, Handler eventHandler, EventListener eventListener,
int eventSourceId) {
this.uri = uri;

View file

@ -25,6 +25,18 @@ import java.util.Random;
* Selects from a number of available formats during playback.
*/
public interface FormatEvaluator {
/**
* A factory for {@link FormatEvaluator} instances.
*/
interface Factory {
/**
* Creates a {@link FormatEvaluator} instance.
*/
FormatEvaluator createFormatEvaluator();
}
/**
* A trigger for a load whose reason is unknown or unspecified.
@ -124,6 +136,28 @@ public interface FormatEvaluator {
*/
final class RandomEvaluator implements FormatEvaluator {
public static class Factory implements FormatEvaluator.Factory {
private final int seed;
private final boolean seedIsSet;
public Factory() {
seed = 0;
seedIsSet = false;
}
public Factory(int seed) {
this.seed = seed;
seedIsSet = true;
}
@Override
public FormatEvaluator createFormatEvaluator() {
return seedIsSet ? new RandomEvaluator(seed) : new RandomEvaluator();
}
}
private final Random random;
private Format[] formats;
@ -196,6 +230,21 @@ public interface FormatEvaluator {
*/
final class AdaptiveEvaluator implements FormatEvaluator {
public static class Factory implements FormatEvaluator.Factory {
private final BandwidthMeter bandwidthMeter;
public Factory(BandwidthMeter bandwidthMeter) {
this.bandwidthMeter = bandwidthMeter;
}
@Override
public FormatEvaluator createFormatEvaluator() {
return new AdaptiveEvaluator(bandwidthMeter);
}
}
private static final int DEFAULT_MAX_INITIAL_BITRATE = 800000;
private static final int DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS = 10000;

View file

@ -32,9 +32,7 @@ import com.google.android.exoplayer2.source.dash.mpd.Period;
import com.google.android.exoplayer2.source.dash.mpd.Representation;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSourceFactory;
import com.google.android.exoplayer2.upstream.Loader;
import android.util.Pair;
@ -49,8 +47,8 @@ import java.util.List;
/* package */ final class DashMediaPeriod implements MediaPeriod,
SequenceableLoader.Callback<ChunkSampleStream<DashChunkSource>> {
private final DataSourceFactory dataSourceFactory;
private final BandwidthMeter bandwidthMeter;
private final DataSource.Factory dataSourceFactory;
private final FormatEvaluator.Factory formatEvaluatorFactory;
private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher;
private final long elapsedRealtimeOffset;
@ -68,13 +66,13 @@ import java.util.List;
private Period period;
public DashMediaPeriod(MediaPresentationDescription manifest, int index,
DataSourceFactory dataSourceFactory, BandwidthMeter bandwidthMeter,
DataSource.Factory dataSourceFactory, FormatEvaluator.Factory formatEvaluatorFactory,
int minLoadableRetryCount, EventDispatcher eventDispatcher, long elapsedRealtimeOffset,
Loader loader) {
this.manifest = manifest;
this.index = index;
this.dataSourceFactory = dataSourceFactory;
this.bandwidthMeter = bandwidthMeter;
this.formatEvaluatorFactory = formatEvaluatorFactory;
this.minLoadableRetryCount = minLoadableRetryCount;
this.eventDispatcher = eventDispatcher;
this.elapsedRealtimeOffset = elapsedRealtimeOffset;
@ -245,11 +243,11 @@ import java.util.List;
long positionUs) {
int[] selectedTracks = selection.getTracks();
FormatEvaluator adaptiveEvaluator = selectedTracks.length > 1
? new FormatEvaluator.AdaptiveEvaluator(bandwidthMeter) : null;
? formatEvaluatorFactory.createFormatEvaluator() : null;
int adaptationSetIndex = trackGroupAdaptationSetIndices[selection.group];
AdaptationSet adaptationSet = period.adaptationSets.get(adaptationSetIndex);
int adaptationSetType = adaptationSet.type;
DataSource dataSource = dataSourceFactory.createDataSource(bandwidthMeter);
DataSource dataSource = dataSourceFactory.createDataSource();
DashChunkSource chunkSource = new DashChunkSource(loader, manifest, index, adaptationSetIndex,
trackGroups.get(selection.group), selectedTracks, dataSource, adaptiveEvaluator,
elapsedRealtimeOffset);

View file

@ -21,12 +21,11 @@ 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.chunk.FormatEvaluator;
import com.google.android.exoplayer2.source.dash.mpd.MediaPresentationDescription;
import com.google.android.exoplayer2.source.dash.mpd.MediaPresentationDescriptionParser;
import com.google.android.exoplayer2.source.dash.mpd.UtcTimingElement;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSourceFactory;
import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.util.Util;
@ -57,8 +56,8 @@ public final class DashMediaSource implements MediaSource {
private static final String TAG = "DashMediaSource";
private final DataSourceFactory dataSourceFactory;
private final BandwidthMeter bandwidthMeter;
private final DataSource.Factory dataSourceFactory;
private final FormatEvaluator.Factory formatEvaluatorFactory;
private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher;
private final MediaPresentationDescriptionParser manifestParser;
@ -75,19 +74,19 @@ public final class DashMediaSource implements MediaSource {
private DashMediaPeriod[] periods;
private long elapsedRealtimeOffset;
public DashMediaSource(Uri manifestUri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, Handler eventHandler,
public DashMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory,
FormatEvaluator.Factory formatEvaluatorFactory, Handler eventHandler,
AdaptiveMediaSourceEventListener eventListener) {
this(manifestUri, dataSourceFactory, bandwidthMeter, DEFAULT_MIN_LOADABLE_RETRY_COUNT,
this(manifestUri, dataSourceFactory, formatEvaluatorFactory, DEFAULT_MIN_LOADABLE_RETRY_COUNT,
eventHandler, eventListener);
}
public DashMediaSource(Uri manifestUri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, int minLoadableRetryCount, Handler eventHandler,
AdaptiveMediaSourceEventListener eventListener) {
public DashMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory,
FormatEvaluator.Factory formatEvaluatorFactory, int minLoadableRetryCount,
Handler eventHandler, AdaptiveMediaSourceEventListener eventListener) {
this.manifestUri = manifestUri;
this.dataSourceFactory = dataSourceFactory;
this.bandwidthMeter = bandwidthMeter;
this.formatEvaluatorFactory = formatEvaluatorFactory;
this.minLoadableRetryCount = minLoadableRetryCount;
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
manifestParser = new MediaPresentationDescriptionParser();
@ -245,7 +244,7 @@ public final class DashMediaSource implements MediaSource {
int periodCount = manifest.getPeriodCount();
periods = new DashMediaPeriod[periodCount];
for (int i = 0; i < periodCount; i++) {
periods[i] = new DashMediaPeriod(manifest, i, dataSourceFactory, bandwidthMeter,
periods[i] = new DashMediaPeriod(manifest, i, dataSourceFactory, formatEvaluatorFactory,
minLoadableRetryCount, eventDispatcher, elapsedRealtimeOffset, loader);
}
scheduleManifestRefresh();

View file

@ -34,9 +34,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
import com.google.android.exoplayer2.source.hls.playlist.Variant;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSourceFactory;
import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.util.Assertions;
@ -64,8 +62,8 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
private final Uri manifestUri;
private final DataSourceFactory dataSourceFactory;
private final BandwidthMeter bandwidthMeter;
private final DataSource.Factory dataSourceFactory;
private final FormatEvaluator.Factory formatEvaluatorFactory;
private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher;
private final IdentityHashMap<SampleStream, HlsSampleStreamWrapper> sampleStreamSources;
@ -89,19 +87,19 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
private HlsSampleStreamWrapper[] enabledSampleStreamWrappers;
private CompositeSequenceableLoader sequenceableLoader;
public HlsMediaSource(Uri manifestUri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, Handler eventHandler,
public HlsMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory,
FormatEvaluator.Factory formatEvaluatorFactory, Handler eventHandler,
AdaptiveMediaSourceEventListener eventListener) {
this(manifestUri, dataSourceFactory, bandwidthMeter, DEFAULT_MIN_LOADABLE_RETRY_COUNT,
this(manifestUri, dataSourceFactory, formatEvaluatorFactory, DEFAULT_MIN_LOADABLE_RETRY_COUNT,
eventHandler, eventListener);
}
public HlsMediaSource(Uri manifestUri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, int minLoadableRetryCount, Handler eventHandler,
AdaptiveMediaSourceEventListener eventListener) {
public HlsMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory,
FormatEvaluator.Factory formatEvaluatorFactory, int minLoadableRetryCount,
Handler eventHandler, AdaptiveMediaSourceEventListener eventListener) {
this.manifestUri = manifestUri;
this.dataSourceFactory = dataSourceFactory;
this.bandwidthMeter = bandwidthMeter;
this.formatEvaluatorFactory = formatEvaluatorFactory;
this.minLoadableRetryCount = minLoadableRetryCount;
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
@ -347,7 +345,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
Format.NO_VALUE);
Variant[] variants = new Variant[] {new Variant(playlist.baseUri, format, null)};
sampleStreamWrappers.add(buildSampleStreamWrapper(C.TRACK_TYPE_DEFAULT, baseUri, variants,
new FormatEvaluator.AdaptiveEvaluator(bandwidthMeter), null, null));
formatEvaluatorFactory.createFormatEvaluator(), null, null));
return sampleStreamWrappers;
}
@ -381,7 +379,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
Variant[] variants = new Variant[selectedVariants.size()];
selectedVariants.toArray(variants);
sampleStreamWrappers.add(buildSampleStreamWrapper(C.TRACK_TYPE_DEFAULT, baseUri, variants,
new FormatEvaluator.AdaptiveEvaluator(bandwidthMeter), masterPlaylist.muxedAudioFormat,
formatEvaluatorFactory.createFormatEvaluator(), masterPlaylist.muxedAudioFormat,
masterPlaylist.muxedCaptionFormat));
}
@ -409,7 +407,7 @@ public final class HlsMediaSource implements MediaPeriod, MediaSource,
private HlsSampleStreamWrapper buildSampleStreamWrapper(int trackType, String baseUri,
Variant[] variants, FormatEvaluator formatEvaluator, Format muxedAudioFormat,
Format muxedCaptionFormat) {
DataSource dataSource = dataSourceFactory.createDataSource(bandwidthMeter);
DataSource dataSource = dataSourceFactory.createDataSource();
HlsChunkSource defaultChunkSource = new HlsChunkSource(baseUri, variants, dataSource,
timestampAdjusterProvider, formatEvaluator);
return new HlsSampleStreamWrapper(trackType, this, defaultChunkSource, allocator,

View file

@ -30,14 +30,11 @@ import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.ChunkSampleStream;
import com.google.android.exoplayer2.source.chunk.FormatEvaluator;
import com.google.android.exoplayer2.source.chunk.FormatEvaluator.AdaptiveEvaluator;
import com.google.android.exoplayer2.source.smoothstreaming.SmoothStreamingManifest.ProtectionElement;
import com.google.android.exoplayer2.source.smoothstreaming.SmoothStreamingManifest.StreamElement;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSourceFactory;
import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.util.Assertions;
@ -68,8 +65,8 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
private static final int INITIALIZATION_VECTOR_SIZE = 8;
private final Uri manifestUri;
private final DataSourceFactory dataSourceFactory;
private final BandwidthMeter bandwidthMeter;
private final DataSource.Factory dataSourceFactory;
private final FormatEvaluator.Factory formatEvaluatorFactory;
private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher;
private final SmoothStreamingManifestParser manifestParser;
@ -91,20 +88,20 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
private TrackGroupArray trackGroups;
private int[] trackGroupElementIndices;
public SmoothStreamingMediaSource(Uri manifestUri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, Handler eventHandler,
public SmoothStreamingMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory,
FormatEvaluator.Factory formatEvaluatorFactory, Handler eventHandler,
AdaptiveMediaSourceEventListener eventListener) {
this(manifestUri, dataSourceFactory, bandwidthMeter, DEFAULT_MIN_LOADABLE_RETRY_COUNT,
this(manifestUri, dataSourceFactory, formatEvaluatorFactory, DEFAULT_MIN_LOADABLE_RETRY_COUNT,
eventHandler, eventListener);
}
public SmoothStreamingMediaSource(Uri manifestUri, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter, int minLoadableRetryCount, Handler eventHandler,
AdaptiveMediaSourceEventListener eventListener) {
public SmoothStreamingMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory,
FormatEvaluator.Factory formatEvaluatorFactory, int minLoadableRetryCount,
Handler eventHandler, AdaptiveMediaSourceEventListener eventListener) {
this.manifestUri = Util.toLowerInvariant(manifestUri.getLastPathSegment()).equals("manifest")
? manifestUri : Uri.withAppendedPath(manifestUri, "Manifest");
this.dataSourceFactory = dataSourceFactory;
this.bandwidthMeter = bandwidthMeter;
this.formatEvaluatorFactory = formatEvaluatorFactory;
this.minLoadableRetryCount = minLoadableRetryCount;
this.eventDispatcher = new EventDispatcher(eventHandler, eventListener);
manifestParser = new SmoothStreamingManifestParser();
@ -358,11 +355,11 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
long positionUs) {
int[] selectedTracks = selection.getTracks();
FormatEvaluator adaptiveEvaluator = selectedTracks.length > 1
? new AdaptiveEvaluator(bandwidthMeter) : null;
? formatEvaluatorFactory.createFormatEvaluator() : null;
int streamElementIndex = trackGroupElementIndices[selection.group];
StreamElement streamElement = manifest.streamElements[streamElementIndex];
int streamElementType = streamElement.type;
DataSource dataSource = dataSourceFactory.createDataSource(bandwidthMeter);
DataSource dataSource = dataSourceFactory.createDataSource();
SmoothStreamingChunkSource chunkSource = new SmoothStreamingChunkSource(manifestLoader,
manifest, streamElementIndex, trackGroups.get(selection.group), selectedTracks, dataSource,
adaptiveEvaluator, trackEncryptionBoxes);

View file

@ -26,6 +26,18 @@ import java.io.IOException;
*/
public interface DataSource {
/**
* A factory for {@link DataSource} instances.
*/
interface Factory {
/**
* Creates a {@link DataSource} instance.
*/
DataSource createDataSource();
}
/**
* Opens the {@link DataSource} to read the specified data.
* <p>

View file

@ -1,35 +0,0 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.upstream;
/**
* A factory for {@link DataSource} instances.
*/
public interface DataSourceFactory {
/**
* Creates a {@link DataSource} instance.
*/
DataSource createDataSource();
/**
* Creates a {@link DataSource} instance.
*
* @param listener A {@link TransferListener} to receive events from the instance.
*/
DataSource createDataSource(TransferListener listener);
}

View file

@ -15,37 +15,41 @@
*/
package com.google.android.exoplayer2.upstream;
import com.google.android.exoplayer2.upstream.DataSource.Factory;
import android.content.Context;
/**
* A {@link DataSourceFactory} that produces {@link DefaultDataSource} instances that delegate to
* A {@link Factory} that produces {@link DefaultDataSource} instances that delegate to
* {@link DefaultHttpDataSource}s for non-file/asset/content URIs.
*/
public final class DefaultDataSourceFactory implements DataSourceFactory {
public final class DefaultDataSourceFactory implements Factory {
private final Context context;
private final String userAgent;
private final TransferListener transferListener;
private final boolean allowCrossProtocolRedirects;
public DefaultDataSourceFactory(Context context, String userAgent) {
this(context, userAgent, false);
this(context, userAgent, null);
}
public DefaultDataSourceFactory(Context context, String userAgent,
boolean allowCrossProtocolRedirects) {
TransferListener transferListener) {
this(context, userAgent, transferListener, false);
}
public DefaultDataSourceFactory(Context context, String userAgent,
TransferListener transferListener, boolean allowCrossProtocolRedirects) {
this.context = context.getApplicationContext();
this.userAgent = userAgent;
this.transferListener = transferListener;
this.allowCrossProtocolRedirects = allowCrossProtocolRedirects;
}
@Override
public DefaultDataSource createDataSource() {
return createDataSource(null);
}
@Override
public DefaultDataSource createDataSource(TransferListener listener) {
return new DefaultDataSource(context, listener, userAgent, allowCrossProtocolRedirects);
return new DefaultDataSource(context, transferListener, userAgent, allowCrossProtocolRedirects);
}
}

View file

@ -31,11 +31,15 @@ import com.google.android.exoplayer2.playbacktests.util.MetricsLogger;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.FormatEvaluator;
import com.google.android.exoplayer2.source.chunk.FormatEvaluator.AdaptiveEvaluator;
import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSourceFactory;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
@ -418,9 +422,13 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
}
@Override
public MediaSource buildSource(HostActivity host, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter) {
return new DashMediaSource(manifestUri, dataSourceFactory, bandwidthMeter,
public MediaSource buildSource(HostActivity host, String userAgent) {
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(host, userAgent,
bandwidthMeter);
FormatEvaluator.Factory formatEvaluatorFactory = new AdaptiveEvaluator.Factory(
bandwidthMeter);
return new DashMediaSource(manifestUri, dataSourceFactory, formatEvaluatorFactory,
MIN_LOADABLE_RETRY_COUNT, null, null);
}

View file

@ -26,17 +26,12 @@ import com.google.android.exoplayer2.playbacktests.util.HostActivity.HostedTest;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.Surface;
import junit.framework.Assert;
/**
@ -126,10 +121,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
// Build the player.
trackSelector = buildTrackSelector(host);
player = buildExoPlayer(host, surface, trackSelector);
DataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(host, Util
.getUserAgent(host, "ExoPlayerPlaybackTests"));
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
player.setMediaSource(buildSource(host, dataSourceFactory, bandwidthMeter));
player.setMediaSource(buildSource(host, Util.getUserAgent(host, "ExoPlayerPlaybackTests")));
player.addListener(this);
player.setDebugListener(this);
player.setPlayWhenReady(true);
@ -293,8 +285,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
}
@SuppressWarnings("unused")
protected abstract MediaSource buildSource(HostActivity host, DataSourceFactory dataSourceFactory,
BandwidthMeter bandwidthMeter);
protected abstract MediaSource buildSource(HostActivity host, String userAgent);
@SuppressWarnings("unused")
protected void onPlayerErrorInternal(ExoPlaybackException error) {