SegmentDownloader cleanup

This is just some trivial cleanup to get things into a better state to
implement parallel segment downloads.

Issue: #5978
PiperOrigin-RevId: 308041996
This commit is contained in:
olly 2020-04-23 14:58:54 +01:00 committed by Ian Baker
parent 17fff2d0f4
commit 84faa1ae3f

View File

@ -21,6 +21,7 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.cache.Cache;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory; import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory;
import com.google.android.exoplayer2.upstream.cache.CacheUtil; import com.google.android.exoplayer2.upstream.cache.CacheUtil;
@ -67,9 +68,9 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
private static final long MAX_MERGED_SEGMENT_START_TIME_DIFF_US = 20 * C.MICROS_PER_SECOND; private static final long MAX_MERGED_SEGMENT_START_TIME_DIFF_US = 20 * C.MICROS_PER_SECOND;
private final DataSpec manifestDataSpec; private final DataSpec manifestDataSpec;
private final CacheDataSource dataSource;
private final CacheDataSource removingDataSource;
private final ArrayList<StreamKey> streamKeys; private final ArrayList<StreamKey> streamKeys;
private final CacheDataSource.Factory cacheDataSourceFactory;
@Nullable private final ExecutorService executorService;
private final AtomicBoolean isCanceled; private final AtomicBoolean isCanceled;
/** /**
@ -91,8 +92,8 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
@Nullable ExecutorService executorService) { @Nullable ExecutorService executorService) {
this.manifestDataSpec = getCompressibleDataSpec(manifestUri); this.manifestDataSpec = getCompressibleDataSpec(manifestUri);
this.streamKeys = new ArrayList<>(streamKeys); this.streamKeys = new ArrayList<>(streamKeys);
this.dataSource = cacheDataSourceFactory.createDataSourceForDownloading(); this.cacheDataSourceFactory = cacheDataSourceFactory;
this.removingDataSource = cacheDataSourceFactory.createDataSourceForRemovingDownload(); this.executorService = executorService;
isCanceled = new AtomicBoolean(); isCanceled = new AtomicBoolean();
} }
@ -106,6 +107,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
@Override @Override
public final void download(@Nullable ProgressListener progressListener) public final void download(@Nullable ProgressListener progressListener)
throws IOException, InterruptedException { throws IOException, InterruptedException {
CacheDataSource dataSource = cacheDataSourceFactory.createDataSourceForDownloading();
@Nullable PriorityTaskManager priorityTaskManager = dataSource.getUpstreamPriorityTaskManager(); @Nullable PriorityTaskManager priorityTaskManager = dataSource.getUpstreamPriorityTaskManager();
if (priorityTaskManager != null) { if (priorityTaskManager != null) {
priorityTaskManager.add(C.PRIORITY_DOWNLOAD); priorityTaskManager.add(C.PRIORITY_DOWNLOAD);
@ -148,16 +150,16 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
} }
// Download the segments. // Download the segments.
@Nullable ProgressNotifier progressNotifier = null; @Nullable
if (progressListener != null) { ProgressNotifier progressNotifier =
progressNotifier = progressListener != null
new ProgressNotifier( ? new ProgressNotifier(
progressListener, progressListener,
contentLength, contentLength,
totalSegments, totalSegments,
bytesDownloaded, bytesDownloaded,
segmentsDownloaded); segmentsDownloaded)
} : null;
byte[] temporaryBuffer = new byte[BUFFER_SIZE_BYTES]; byte[] temporaryBuffer = new byte[BUFFER_SIZE_BYTES];
for (int i = 0; i < segments.size(); i++) { for (int i = 0; i < segments.size(); i++) {
CacheUtil.cache( CacheUtil.cache(
@ -185,17 +187,20 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
@Override @Override
public final void remove() throws InterruptedException { public final void remove() throws InterruptedException {
CacheDataSource dataSource = cacheDataSourceFactory.createDataSourceForRemovingDownload();
Cache cache = dataSource.getCache();
CacheKeyFactory cacheKeyFactory = dataSource.getCacheKeyFactory();
try { try {
M manifest = getManifest(removingDataSource, manifestDataSpec); M manifest = getManifest(dataSource, manifestDataSpec);
List<Segment> segments = getSegments(removingDataSource, manifest, true); List<Segment> segments = getSegments(dataSource, manifest, true);
for (int i = 0; i < segments.size(); i++) { for (int i = 0; i < segments.size(); i++) {
removeDataSpec(segments.get(i).dataSpec); CacheUtil.remove(segments.get(i).dataSpec, cache, cacheKeyFactory);
} }
} catch (IOException e) { } catch (IOException e) {
// Ignore exceptions when removing. // Ignore exceptions when removing.
} finally { } finally {
// Always attempt to remove the manifest. // Always attempt to remove the manifest.
removeDataSpec(manifestDataSpec); CacheUtil.remove(manifestDataSpec, cache, cacheKeyFactory);
} }
} }
@ -228,10 +233,6 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
DataSource dataSource, M manifest, boolean allowIncompleteList) DataSource dataSource, M manifest, boolean allowIncompleteList)
throws InterruptedException, IOException; throws InterruptedException, IOException;
private void removeDataSpec(DataSpec dataSpec) {
CacheUtil.remove(dataSpec, dataSource.getCache(), dataSource.getCacheKeyFactory());
}
protected static DataSpec getCompressibleDataSpec(Uri uri) { protected static DataSpec getCompressibleDataSpec(Uri uri) {
return new DataSpec.Builder().setUri(uri).setFlags(DataSpec.FLAG_ALLOW_GZIP).build(); return new DataSpec.Builder().setUri(uri).setFlags(DataSpec.FLAG_ALLOW_GZIP).build();
} }