diff --git a/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java b/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java index 57febd1aae..cdde3337b3 100644 --- a/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java +++ b/demo/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java @@ -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); } diff --git a/extensions/flac/src/androidTest/java/com/google/android/exoplayer2/ext/flac/FlacPlaybackTest.java b/extensions/flac/src/androidTest/java/com/google/android/exoplayer2/ext/flac/FlacPlaybackTest.java index f0c1488262..8c99d1b895 100644 --- a/extensions/flac/src/androidTest/java/com/google/android/exoplayer2/ext/flac/FlacPlaybackTest.java +++ b/extensions/flac/src/androidTest/java/com/google/android/exoplayer2/ext/flac/FlacPlaybackTest.java @@ -77,7 +77,6 @@ public class FlacPlaybackTest extends InstrumentationTestCase { ExtractorMediaSource mediaSource = new ExtractorMediaSource( uri, new DefaultDataSourceFactory(context, "ExoPlayerExtFlacTest"), - null, MatroskaExtractor.FACTORY, null, null); diff --git a/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/DefaultOkHttpDataSourceFactory.java b/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/DefaultOkHttpDataSourceFactory.java index 394dbf35df..6a1d1e5a12 100644 --- a/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/DefaultOkHttpDataSourceFactory.java +++ b/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/DefaultOkHttpDataSourceFactory.java @@ -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 contentTypePredicate; + private final TransferListener transferListener; private final CacheControl cacheControl; public DefaultOkHttpDataSourceFactory(Context context, OkHttpClient client, String userAgent, - Predicate contentTypePredicate) { - this(context, client, userAgent, contentTypePredicate, null); + TransferListener transferListener) { + this(context, client, userAgent, transferListener, null); } public DefaultOkHttpDataSourceFactory(Context context, OkHttpClient client, String userAgent, - Predicate 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); } } diff --git a/extensions/opus/src/androidTest/java/com/google/android/exoplayer2/ext/opus/OpusPlaybackTest.java b/extensions/opus/src/androidTest/java/com/google/android/exoplayer2/ext/opus/OpusPlaybackTest.java index e34d3d0a9e..2b7c49ab20 100644 --- a/extensions/opus/src/androidTest/java/com/google/android/exoplayer2/ext/opus/OpusPlaybackTest.java +++ b/extensions/opus/src/androidTest/java/com/google/android/exoplayer2/ext/opus/OpusPlaybackTest.java @@ -77,7 +77,6 @@ public class OpusPlaybackTest extends InstrumentationTestCase { ExtractorMediaSource mediaSource = new ExtractorMediaSource( uri, new DefaultDataSourceFactory(context, "ExoPlayerExtOpusTest"), - null, MatroskaExtractor.FACTORY, null, null); diff --git a/extensions/vp9/src/androidTest/java/com/google/android/exoplayer2/ext/vp9/VpxPlaybackTest.java b/extensions/vp9/src/androidTest/java/com/google/android/exoplayer2/ext/vp9/VpxPlaybackTest.java index 5a89733ec1..e0928b1253 100644 --- a/extensions/vp9/src/androidTest/java/com/google/android/exoplayer2/ext/vp9/VpxPlaybackTest.java +++ b/extensions/vp9/src/androidTest/java/com/google/android/exoplayer2/ext/vp9/VpxPlaybackTest.java @@ -93,7 +93,6 @@ public class VpxPlaybackTest extends InstrumentationTestCase { ExtractorMediaSource mediaSource = new ExtractorMediaSource( uri, new DefaultDataSourceFactory(context, "ExoPlayerExtVp9Test"), - null, MatroskaExtractor.FACTORY, null, null); diff --git a/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java b/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java index bf3ee0f055..738671efb0 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java @@ -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(); diff --git a/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java b/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java index 85f099c790..beca9dc831 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java @@ -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; diff --git a/library/src/main/java/com/google/android/exoplayer2/source/chunk/FormatEvaluator.java b/library/src/main/java/com/google/android/exoplayer2/source/chunk/FormatEvaluator.java index 9e4f2497c4..f737ff2cdb 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/chunk/FormatEvaluator.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/chunk/FormatEvaluator.java @@ -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; diff --git a/library/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java b/library/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java index 90f7e43046..4abda3bda9 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaPeriod.java @@ -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> { - 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); diff --git a/library/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java b/library/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java index 3b9654ae51..5ea33925f1 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java @@ -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(); diff --git a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java index f5a0c23a8b..d1a0d2f79a 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java @@ -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 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, diff --git a/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SmoothStreamingMediaSource.java b/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SmoothStreamingMediaSource.java index 4a5694c3ff..4c7a962409 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SmoothStreamingMediaSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/SmoothStreamingMediaSource.java @@ -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); diff --git a/library/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java b/library/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java index 47ebd75e5d..44cb574115 100644 --- a/library/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java +++ b/library/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java @@ -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. *

diff --git a/library/src/main/java/com/google/android/exoplayer2/upstream/DataSourceFactory.java b/library/src/main/java/com/google/android/exoplayer2/upstream/DataSourceFactory.java deleted file mode 100644 index e79c1e9cca..0000000000 --- a/library/src/main/java/com/google/android/exoplayer2/upstream/DataSourceFactory.java +++ /dev/null @@ -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); - -} diff --git a/library/src/main/java/com/google/android/exoplayer2/upstream/DefaultDataSourceFactory.java b/library/src/main/java/com/google/android/exoplayer2/upstream/DefaultDataSourceFactory.java index 98e5411002..3a0d95bbec 100644 --- a/library/src/main/java/com/google/android/exoplayer2/upstream/DefaultDataSourceFactory.java +++ b/library/src/main/java/com/google/android/exoplayer2/upstream/DefaultDataSourceFactory.java @@ -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); } } diff --git a/playbacktests/src/main/java/com/google/android/exoplayer2/playbacktests/gts/DashTest.java b/playbacktests/src/main/java/com/google/android/exoplayer2/playbacktests/gts/DashTest.java index 14d06aec73..9253a6249c 100644 --- a/playbacktests/src/main/java/com/google/android/exoplayer2/playbacktests/gts/DashTest.java +++ b/playbacktests/src/main/java/com/google/android/exoplayer2/playbacktests/gts/DashTest.java @@ -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