Commit 3be4451e by aquilescanta Committed by Oliver Woodman

Allow injection of DataSource's per type of data

This allows the client to define what data source is used for
media chunks, encryption chunks and playlists.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=149537766
parent 78e7c3c5
/*
* Copyright (C) 2017 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.source.hls;
import com.google.android.exoplayer2.upstream.DataSource;
/**
* Default implementation of {@link HlsDataSourceFactory}.
*/
public final class DefaultHlsDataSourceFactory implements HlsDataSourceFactory {
private final DataSource.Factory dataSourceFactory;
/**
* @param dataSourceFactory The {@link DataSource.Factory} to use for all data types.
*/
public DefaultHlsDataSourceFactory(DataSource.Factory dataSourceFactory) {
this.dataSourceFactory = dataSourceFactory;
}
@Override
public DataSource createDataSource(int dataType) {
return dataSourceFactory.createDataSource();
}
}
...@@ -81,7 +81,8 @@ import java.util.Locale; ...@@ -81,7 +81,8 @@ import java.util.Locale;
} }
private final DataSource dataSource; private final DataSource mediaDataSource;
private final DataSource encryptionDataSource;
private final TimestampAdjusterProvider timestampAdjusterProvider; private final TimestampAdjusterProvider timestampAdjusterProvider;
private final HlsUrl[] variants; private final HlsUrl[] variants;
private final HlsPlaylistTracker playlistTracker; private final HlsPlaylistTracker playlistTracker;
...@@ -105,18 +106,18 @@ import java.util.Locale; ...@@ -105,18 +106,18 @@ import java.util.Locale;
/** /**
* @param playlistTracker The {@link HlsPlaylistTracker} from which to obtain media playlists. * @param playlistTracker The {@link HlsPlaylistTracker} from which to obtain media playlists.
* @param variants The available variants. * @param variants The available variants.
* @param dataSource A {@link DataSource} suitable for loading the media data. * @param dataSourceFactory An {@link HlsDataSourceFactory} to create {@link DataSource}s for the
* chunks.
* @param timestampAdjusterProvider A provider of {@link TimestampAdjuster} instances. If * @param timestampAdjusterProvider A provider of {@link TimestampAdjuster} instances. If
* multiple {@link HlsChunkSource}s are used for a single playback, they should all share the * multiple {@link HlsChunkSource}s are used for a single playback, they should all share the
* same provider. * same provider.
* @param muxedCaptionFormats List of muxed caption {@link Format}s. * @param muxedCaptionFormats List of muxed caption {@link Format}s.
*/ */
public HlsChunkSource(HlsPlaylistTracker playlistTracker, HlsUrl[] variants, public HlsChunkSource(HlsPlaylistTracker playlistTracker, HlsUrl[] variants,
DataSource dataSource, TimestampAdjusterProvider timestampAdjusterProvider, HlsDataSourceFactory dataSourceFactory, TimestampAdjusterProvider timestampAdjusterProvider,
List<Format> muxedCaptionFormats) { List<Format> muxedCaptionFormats) {
this.playlistTracker = playlistTracker; this.playlistTracker = playlistTracker;
this.variants = variants; this.variants = variants;
this.dataSource = dataSource;
this.timestampAdjusterProvider = timestampAdjusterProvider; this.timestampAdjusterProvider = timestampAdjusterProvider;
this.muxedCaptionFormats = muxedCaptionFormats; this.muxedCaptionFormats = muxedCaptionFormats;
Format[] variantFormats = new Format[variants.length]; Format[] variantFormats = new Format[variants.length];
...@@ -125,6 +126,8 @@ import java.util.Locale; ...@@ -125,6 +126,8 @@ import java.util.Locale;
variantFormats[i] = variants[i].format; variantFormats[i] = variants[i].format;
initialTrackSelection[i] = i; initialTrackSelection[i] = i;
} }
mediaDataSource = dataSourceFactory.createDataSource(C.DATA_TYPE_MEDIA);
encryptionDataSource = dataSourceFactory.createDataSource(C.DATA_TYPE_DRM);
trackGroup = new TrackGroup(variantFormats); trackGroup = new TrackGroup(variantFormats);
trackSelection = new InitializationTrackSelection(trackGroup, initialTrackSelection); trackSelection = new InitializationTrackSelection(trackGroup, initialTrackSelection);
} }
...@@ -285,7 +288,7 @@ import java.util.Locale; ...@@ -285,7 +288,7 @@ import java.util.Locale;
Uri chunkUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.url); Uri chunkUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.url);
DataSpec dataSpec = new DataSpec(chunkUri, segment.byterangeOffset, segment.byterangeLength, DataSpec dataSpec = new DataSpec(chunkUri, segment.byterangeOffset, segment.byterangeLength,
null); null);
out.chunk = new HlsMediaChunk(dataSource, dataSpec, initDataSpec, selectedUrl, out.chunk = new HlsMediaChunk(mediaDataSource, dataSpec, initDataSpec, selectedUrl,
muxedCaptionFormats, trackSelection.getSelectionReason(), trackSelection.getSelectionData(), muxedCaptionFormats, trackSelection.getSelectionReason(), trackSelection.getSelectionData(),
startTimeUs, startTimeUs + segment.durationUs, chunkMediaSequence, discontinuitySequence, startTimeUs, startTimeUs + segment.durationUs, chunkMediaSequence, discontinuitySequence,
isTimestampMaster, timestampAdjuster, previous, encryptionKey, encryptionIv); isTimestampMaster, timestampAdjuster, previous, encryptionKey, encryptionIv);
...@@ -341,7 +344,7 @@ import java.util.Locale; ...@@ -341,7 +344,7 @@ import java.util.Locale;
private EncryptionKeyChunk newEncryptionKeyChunk(Uri keyUri, String iv, int variantIndex, private EncryptionKeyChunk newEncryptionKeyChunk(Uri keyUri, String iv, int variantIndex,
int trackSelectionReason, Object trackSelectionData) { int trackSelectionReason, Object trackSelectionData) {
DataSpec dataSpec = new DataSpec(keyUri, 0, C.LENGTH_UNSET, null, DataSpec.FLAG_ALLOW_GZIP); DataSpec dataSpec = new DataSpec(keyUri, 0, C.LENGTH_UNSET, null, DataSpec.FLAG_ALLOW_GZIP);
return new EncryptionKeyChunk(dataSource, dataSpec, variants[variantIndex].format, return new EncryptionKeyChunk(encryptionDataSource, dataSpec, variants[variantIndex].format,
trackSelectionReason, trackSelectionData, scratchSpace, iv); trackSelectionReason, trackSelectionData, scratchSpace, iv);
} }
......
/*
* Copyright (C) 2017 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.source.hls;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.upstream.DataSource;
/**
* Creates {@link DataSource}s for HLS playlists, encryption and media chunks.
*/
public interface HlsDataSourceFactory {
/**
* Creates a {@link DataSource} for the given data type.
*
* @param dataType The data type for which the {@link DataSource} will be used. One of {@link C}
* {@code .DATA_TYPE_*} constants.
* @return A {@link DataSource} for the given data type.
*/
DataSource createDataSource(int dataType);
}
...@@ -30,7 +30,6 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUr ...@@ -30,7 +30,6 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUr
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -44,7 +43,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -44,7 +43,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
HlsPlaylistTracker.PlaylistEventListener { HlsPlaylistTracker.PlaylistEventListener {
private final HlsPlaylistTracker playlistTracker; private final HlsPlaylistTracker playlistTracker;
private final DataSource.Factory dataSourceFactory; private final HlsDataSourceFactory dataSourceFactory;
private final int minLoadableRetryCount; private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final Allocator allocator; private final Allocator allocator;
...@@ -61,7 +60,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -61,7 +60,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
private HlsSampleStreamWrapper[] enabledSampleStreamWrappers; private HlsSampleStreamWrapper[] enabledSampleStreamWrappers;
private CompositeSequenceableLoader sequenceableLoader; private CompositeSequenceableLoader sequenceableLoader;
public HlsMediaPeriod(HlsPlaylistTracker playlistTracker, DataSource.Factory dataSourceFactory, public HlsMediaPeriod(HlsPlaylistTracker playlistTracker, HlsDataSourceFactory dataSourceFactory,
int minLoadableRetryCount, EventDispatcher eventDispatcher, Allocator allocator, int minLoadableRetryCount, EventDispatcher eventDispatcher, Allocator allocator,
long positionUs) { long positionUs) {
this.playlistTracker = playlistTracker; this.playlistTracker = playlistTracker;
...@@ -349,9 +348,8 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -349,9 +348,8 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
private HlsSampleStreamWrapper buildSampleStreamWrapper(int trackType, HlsUrl[] variants, private HlsSampleStreamWrapper buildSampleStreamWrapper(int trackType, HlsUrl[] variants,
Format muxedAudioFormat, List<Format> muxedCaptionFormats) { Format muxedAudioFormat, List<Format> muxedCaptionFormats) {
DataSource dataSource = dataSourceFactory.createDataSource(); HlsChunkSource defaultChunkSource = new HlsChunkSource(playlistTracker, variants,
HlsChunkSource defaultChunkSource = new HlsChunkSource(playlistTracker, variants, dataSource, dataSourceFactory, timestampAdjusterProvider, muxedCaptionFormats);
timestampAdjusterProvider, muxedCaptionFormats);
return new HlsSampleStreamWrapper(trackType, this, defaultChunkSource, allocator, return new HlsSampleStreamWrapper(trackType, this, defaultChunkSource, allocator,
preparePositionUs, muxedAudioFormat, minLoadableRetryCount, eventDispatcher); preparePositionUs, muxedAudioFormat, minLoadableRetryCount, eventDispatcher);
} }
......
...@@ -44,7 +44,7 @@ public final class HlsMediaSource implements MediaSource, ...@@ -44,7 +44,7 @@ public final class HlsMediaSource implements MediaSource,
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3; public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
private final Uri manifestUri; private final Uri manifestUri;
private final DataSource.Factory dataSourceFactory; private final HlsDataSourceFactory dataSourceFactory;
private final int minLoadableRetryCount; private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
...@@ -60,6 +60,13 @@ public final class HlsMediaSource implements MediaSource, ...@@ -60,6 +60,13 @@ public final class HlsMediaSource implements MediaSource,
public HlsMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory, public HlsMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory,
int minLoadableRetryCount, Handler eventHandler, int minLoadableRetryCount, Handler eventHandler,
AdaptiveMediaSourceEventListener eventListener) { AdaptiveMediaSourceEventListener eventListener) {
this(manifestUri, new DefaultHlsDataSourceFactory(dataSourceFactory), minLoadableRetryCount,
eventHandler, eventListener);
}
public HlsMediaSource(Uri manifestUri, HlsDataSourceFactory dataSourceFactory,
int minLoadableRetryCount, Handler eventHandler,
AdaptiveMediaSourceEventListener eventListener) {
this.manifestUri = manifestUri; this.manifestUri = manifestUri;
this.dataSourceFactory = dataSourceFactory; this.dataSourceFactory = dataSourceFactory;
this.minLoadableRetryCount = minLoadableRetryCount; this.minLoadableRetryCount = minLoadableRetryCount;
......
...@@ -22,6 +22,7 @@ import com.google.android.exoplayer2.C; ...@@ -22,6 +22,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher; import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.chunk.ChunkedTrackBlacklistUtil; import com.google.android.exoplayer2.source.chunk.ChunkedTrackBlacklistUtil;
import com.google.android.exoplayer2.source.hls.HlsDataSourceFactory;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl; import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment; import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
...@@ -81,7 +82,7 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable ...@@ -81,7 +82,7 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
private static final long PRIMARY_URL_KEEPALIVE_MS = 15000; private static final long PRIMARY_URL_KEEPALIVE_MS = 15000;
private final Uri initialPlaylistUri; private final Uri initialPlaylistUri;
private final DataSource.Factory dataSourceFactory; private final HlsDataSourceFactory dataSourceFactory;
private final HlsPlaylistParser playlistParser; private final HlsPlaylistParser playlistParser;
private final int minRetryCount; private final int minRetryCount;
private final IdentityHashMap<HlsUrl, MediaPlaylistBundle> playlistBundles; private final IdentityHashMap<HlsUrl, MediaPlaylistBundle> playlistBundles;
...@@ -105,7 +106,7 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable ...@@ -105,7 +106,7 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
* playlist. * playlist.
* @param primaryPlaylistListener A callback for the primary playlist change events. * @param primaryPlaylistListener A callback for the primary playlist change events.
*/ */
public HlsPlaylistTracker(Uri initialPlaylistUri, DataSource.Factory dataSourceFactory, public HlsPlaylistTracker(Uri initialPlaylistUri, HlsDataSourceFactory dataSourceFactory,
EventDispatcher eventDispatcher, int minRetryCount, EventDispatcher eventDispatcher, int minRetryCount,
PrimaryPlaylistListener primaryPlaylistListener) { PrimaryPlaylistListener primaryPlaylistListener) {
this.initialPlaylistUri = initialPlaylistUri; this.initialPlaylistUri = initialPlaylistUri;
...@@ -143,8 +144,8 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable ...@@ -143,8 +144,8 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
*/ */
public void start() { public void start() {
ParsingLoadable<HlsPlaylist> masterPlaylistLoadable = new ParsingLoadable<>( ParsingLoadable<HlsPlaylist> masterPlaylistLoadable = new ParsingLoadable<>(
dataSourceFactory.createDataSource(), initialPlaylistUri, C.DATA_TYPE_MANIFEST, dataSourceFactory.createDataSource(C.DATA_TYPE_MANIFEST), initialPlaylistUri,
playlistParser); C.DATA_TYPE_MANIFEST, playlistParser);
initialPlaylistLoader.startLoading(masterPlaylistLoadable, this, minRetryCount); initialPlaylistLoader.startLoading(masterPlaylistLoadable, this, minRetryCount);
} }
...@@ -436,7 +437,8 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable ...@@ -436,7 +437,8 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
this.playlistUrl = playlistUrl; this.playlistUrl = playlistUrl;
lastSnapshotAccessTimeMs = initialLastSnapshotAccessTimeMs; lastSnapshotAccessTimeMs = initialLastSnapshotAccessTimeMs;
mediaPlaylistLoader = new Loader("HlsPlaylistTracker:MediaPlaylist"); mediaPlaylistLoader = new Loader("HlsPlaylistTracker:MediaPlaylist");
mediaPlaylistLoadable = new ParsingLoadable<>(dataSourceFactory.createDataSource(), mediaPlaylistLoadable = new ParsingLoadable<>(
dataSourceFactory.createDataSource(C.DATA_TYPE_MANIFEST),
UriUtil.resolveToUri(masterPlaylist.baseUri, playlistUrl.url), C.DATA_TYPE_MANIFEST, UriUtil.resolveToUri(masterPlaylist.baseUri, playlistUrl.url), C.DATA_TYPE_MANIFEST,
playlistParser); playlistParser);
} }
......
...@@ -47,7 +47,9 @@ public final class DataSpec { ...@@ -47,7 +47,9 @@ public final class DataSpec {
*/ */
public static final int FLAG_ALLOW_GZIP = 1 << 0; public static final int FLAG_ALLOW_GZIP = 1 << 0;
/** Permits content to be cached even if its length can not be resolved. */ /**
* Permits content to be cached even if its length can not be resolved.
*/
public static final int FLAG_ALLOW_CACHING_UNKNOWN_LENGTH = 1 << 1; public static final int FLAG_ALLOW_CACHING_UNKNOWN_LENGTH = 1 << 1;
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment