Rabbit-R1/original r1/java/sources/androidx/media3/exoplayer/offline/SegmentDownloader.java
2024-05-21 17:08:36 -04:00

478 lines
22 KiB
Java

package androidx.media3.exoplayer.offline;
import android.net.Uri;
import androidx.media3.common.MediaItem;
import androidx.media3.common.PriorityTaskManager;
import androidx.media3.common.StreamKey;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.RunnableFutureTask;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DataSpec;
import androidx.media3.datasource.cache.Cache;
import androidx.media3.datasource.cache.CacheDataSource;
import androidx.media3.datasource.cache.CacheKeyFactory;
import androidx.media3.datasource.cache.CacheWriter;
import androidx.media3.datasource.cache.ContentMetadata;
import androidx.media3.exoplayer.offline.Downloader;
import androidx.media3.exoplayer.offline.FilterableManifest;
import androidx.media3.exoplayer.upstream.ParsingLoadable;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
/* loaded from: classes2.dex */
public abstract class SegmentDownloader<M extends FilterableManifest<M>> implements Downloader {
private static final int BUFFER_SIZE_BYTES = 131072;
public static final long DEFAULT_MAX_MERGED_SEGMENT_START_TIME_DIFF_MS = 20000;
private final ArrayList<RunnableFutureTask<?, ?>> activeRunnables;
private final Cache cache;
private final CacheDataSource.Factory cacheDataSourceFactory;
private final CacheKeyFactory cacheKeyFactory;
private final Executor executor;
private volatile boolean isCanceled;
private final DataSpec manifestDataSpec;
private final ParsingLoadable.Parser<M> manifestParser;
private final long maxMergedSegmentStartTimeDiffUs;
private final PriorityTaskManager priorityTaskManager;
private final ArrayList<StreamKey> streamKeys;
protected abstract List<Segment> getSegments(DataSource dataSource, M m, boolean z) throws IOException, InterruptedException;
/* JADX INFO: Access modifiers changed from: protected */
/* loaded from: classes2.dex */
public static class Segment implements Comparable<Segment> {
public final DataSpec dataSpec;
public final long startTimeUs;
public Segment(long j, DataSpec dataSpec) {
this.startTimeUs = j;
this.dataSpec = dataSpec;
}
@Override // java.lang.Comparable
public int compareTo(Segment segment) {
return Util.compareLong(this.startTimeUs, segment.startTimeUs);
}
}
@Deprecated
public SegmentDownloader(MediaItem mediaItem, ParsingLoadable.Parser<M> parser, CacheDataSource.Factory factory, Executor executor) {
this(mediaItem, parser, factory, executor, 20000L);
}
public SegmentDownloader(MediaItem mediaItem, ParsingLoadable.Parser<M> parser, CacheDataSource.Factory factory, Executor executor, long j) {
Assertions.checkNotNull(mediaItem.localConfiguration);
this.manifestDataSpec = getCompressibleDataSpec(mediaItem.localConfiguration.uri);
this.manifestParser = parser;
this.streamKeys = new ArrayList<>(mediaItem.localConfiguration.streamKeys);
this.cacheDataSourceFactory = factory;
this.executor = executor;
this.cache = (Cache) Assertions.checkNotNull(factory.getCache());
this.cacheKeyFactory = factory.getCacheKeyFactory();
this.priorityTaskManager = factory.getUpstreamPriorityTaskManager();
this.activeRunnables = new ArrayList<>();
this.maxMergedSegmentStartTimeDiffUs = Util.msToUs(j);
}
/* JADX WARN: Multi-variable type inference failed */
@Override // androidx.media3.exoplayer.offline.Downloader
public final void download(Downloader.ProgressListener progressListener) throws IOException, InterruptedException {
int i;
int size;
CacheDataSource createDataSourceForDownloading;
byte[] bArr;
int i2;
ArrayDeque arrayDeque = new ArrayDeque();
ArrayDeque arrayDeque2 = new ArrayDeque();
PriorityTaskManager priorityTaskManager = this.priorityTaskManager;
if (priorityTaskManager != null) {
priorityTaskManager.add(-1000);
}
try {
CacheDataSource createDataSourceForDownloading2 = this.cacheDataSourceFactory.createDataSourceForDownloading();
FilterableManifest manifest = getManifest(createDataSourceForDownloading2, this.manifestDataSpec, false);
if (!this.streamKeys.isEmpty()) {
manifest = (FilterableManifest) manifest.copy(this.streamKeys);
}
List<Segment> segments = getSegments(createDataSourceForDownloading2, manifest, false);
Collections.sort(segments);
mergeSegments(segments, this.cacheKeyFactory, this.maxMergedSegmentStartTimeDiffUs);
int size2 = segments.size();
int i3 = 0;
long j = 0;
long j2 = 0;
for (int size3 = segments.size() - 1; size3 >= 0; size3 = i2 - 1) {
DataSpec dataSpec = segments.get(size3).dataSpec;
String buildCacheKey = this.cacheKeyFactory.buildCacheKey(dataSpec);
long j3 = dataSpec.length;
if (j3 == -1) {
long contentLength = ContentMetadata.getContentLength(this.cache.getContentMetadata(buildCacheKey));
if (contentLength != -1) {
j3 = contentLength - dataSpec.position;
}
}
int i4 = size3;
long cachedBytes = this.cache.getCachedBytes(buildCacheKey, dataSpec.position, j3);
j2 += cachedBytes;
if (j3 != -1) {
if (j3 == cachedBytes) {
i3++;
i2 = i4;
segments.remove(i2);
} else {
i2 = i4;
}
if (j != -1) {
j += j3;
}
} else {
i2 = i4;
j = -1;
}
}
ProgressNotifier progressNotifier = progressListener != null ? new ProgressNotifier(progressListener, j, size2, j2, i3) : null;
arrayDeque.addAll(segments);
while (!this.isCanceled && !arrayDeque.isEmpty()) {
PriorityTaskManager priorityTaskManager2 = this.priorityTaskManager;
if (priorityTaskManager2 != null) {
priorityTaskManager2.proceed(-1000);
}
if (!arrayDeque2.isEmpty()) {
SegmentDownloadRunnable segmentDownloadRunnable = (SegmentDownloadRunnable) arrayDeque2.removeFirst();
createDataSourceForDownloading = segmentDownloadRunnable.dataSource;
bArr = segmentDownloadRunnable.temporaryBuffer;
} else {
createDataSourceForDownloading = this.cacheDataSourceFactory.createDataSourceForDownloading();
bArr = new byte[131072];
}
SegmentDownloadRunnable segmentDownloadRunnable2 = new SegmentDownloadRunnable((Segment) arrayDeque.removeFirst(), createDataSourceForDownloading, progressNotifier, bArr);
addActiveRunnable(segmentDownloadRunnable2);
this.executor.execute(segmentDownloadRunnable2);
for (int size4 = this.activeRunnables.size() - 1; size4 >= 0; size4--) {
SegmentDownloadRunnable segmentDownloadRunnable3 = (SegmentDownloadRunnable) this.activeRunnables.get(size4);
if (arrayDeque.isEmpty() || segmentDownloadRunnable3.isDone()) {
try {
segmentDownloadRunnable3.get();
removeActiveRunnable(size4);
arrayDeque2.addLast(segmentDownloadRunnable3);
} catch (ExecutionException e) {
Throwable th = (Throwable) Assertions.checkNotNull(e.getCause());
if (th instanceof PriorityTaskManager.PriorityTooLowException) {
arrayDeque.addFirst(segmentDownloadRunnable3.segment);
removeActiveRunnable(size4);
arrayDeque2.addLast(segmentDownloadRunnable3);
} else {
if (th instanceof IOException) {
throw ((IOException) th);
}
Util.sneakyThrow(th);
}
}
}
}
segmentDownloadRunnable2.blockUntilStarted();
}
while (true) {
if (i >= size) {
break;
}
}
} finally {
for (i = 0; i < this.activeRunnables.size(); i++) {
this.activeRunnables.get(i).cancel(true);
}
for (int size5 = this.activeRunnables.size() - 1; size5 >= 0; size5--) {
this.activeRunnables.get(size5).blockUntilFinished();
removeActiveRunnable(size5);
}
PriorityTaskManager priorityTaskManager3 = this.priorityTaskManager;
if (priorityTaskManager3 != null) {
priorityTaskManager3.remove(-1000);
}
}
}
@Override // androidx.media3.exoplayer.offline.Downloader
public void cancel() {
synchronized (this.activeRunnables) {
this.isCanceled = true;
for (int i = 0; i < this.activeRunnables.size(); i++) {
this.activeRunnables.get(i).cancel(true);
}
}
}
@Override // androidx.media3.exoplayer.offline.Downloader
public final void remove() {
CacheDataSource createDataSourceForRemovingDownload = this.cacheDataSourceFactory.createDataSourceForRemovingDownload();
try {
try {
List<Segment> segments = getSegments(createDataSourceForRemovingDownload, getManifest(createDataSourceForRemovingDownload, this.manifestDataSpec, true), true);
for (int i = 0; i < segments.size(); i++) {
this.cache.removeResource(this.cacheKeyFactory.buildCacheKey(segments.get(i).dataSpec));
}
} catch (InterruptedException unused) {
Thread.currentThread().interrupt();
} catch (Exception unused2) {
}
} finally {
this.cache.removeResource(this.cacheKeyFactory.buildCacheKey(this.manifestDataSpec));
}
}
protected final M getManifest(final DataSource dataSource, final DataSpec dataSpec, boolean z) throws InterruptedException, IOException {
return (M) execute(new RunnableFutureTask<M, IOException>() { // from class: androidx.media3.exoplayer.offline.SegmentDownloader.1
/* JADX INFO: Access modifiers changed from: protected */
@Override // androidx.media3.common.util.RunnableFutureTask
public M doWork() throws IOException {
return (M) ParsingLoadable.load(dataSource, SegmentDownloader.this.manifestParser, dataSpec, 4);
}
}, z);
}
/* JADX WARN: Can't wrap try/catch for region: R(5:27|28|29|(2:34|(2:36|37)(3:38|39|40))(2:31|32)|33) */
/* JADX WARN: Code restructure failed: missing block: B:27:0x0042, code lost:
r4 = move-exception;
*/
/* JADX WARN: Code restructure failed: missing block: B:29:0x0043, code lost:
r0 = (java.lang.Throwable) androidx.media3.common.util.Assertions.checkNotNull(r4.getCause());
*/
/* JADX WARN: Code restructure failed: missing block: B:30:0x004f, code lost:
if ((r0 instanceof androidx.media3.common.PriorityTaskManager.PriorityTooLowException) == false) goto L27;
*/
/* JADX WARN: Code restructure failed: missing block: B:35:0x0054, code lost:
if ((r0 instanceof java.io.IOException) == false) goto L29;
*/
/* JADX WARN: Code restructure failed: missing block: B:36:0x0056, code lost:
androidx.media3.common.util.Util.sneakyThrow(r4);
*/
/* JADX WARN: Code restructure failed: missing block: B:40:0x0062, code lost:
throw ((java.io.IOException) r0);
*/
/* JADX WARN: Code restructure failed: missing block: B:41:0x0040, code lost:
r4 = move-exception;
*/
/* JADX WARN: Code restructure failed: missing block: B:42:0x0063, code lost:
r3.blockUntilFinished();
r2.removeActiveRunnable((androidx.media3.common.util.RunnableFutureTask<?, ?>) r3);
*/
/* JADX WARN: Code restructure failed: missing block: B:43:0x0069, code lost:
throw r4;
*/
/*
Code decompiled incorrectly, please refer to instructions dump.
To view partially-correct add '--show-bad-code' argument
*/
protected final <T> T execute(androidx.media3.common.util.RunnableFutureTask<T, ?> r3, boolean r4) throws java.lang.InterruptedException, java.io.IOException {
/*
r2 = this;
if (r4 == 0) goto L20
r3.run()
java.lang.Object r2 = r3.get() // Catch: java.util.concurrent.ExecutionException -> La
return r2
La:
r4 = move-exception
java.lang.Throwable r0 = r4.getCause()
java.lang.Object r0 = androidx.media3.common.util.Assertions.checkNotNull(r0)
java.lang.Throwable r0 = (java.lang.Throwable) r0
boolean r1 = r0 instanceof java.io.IOException
if (r1 != 0) goto L1d
androidx.media3.common.util.Util.sneakyThrow(r4)
goto L20
L1d:
java.io.IOException r0 = (java.io.IOException) r0
throw r0
L20:
boolean r4 = r2.isCanceled
if (r4 != 0) goto L6a
androidx.media3.common.PriorityTaskManager r4 = r2.priorityTaskManager
if (r4 == 0) goto L2d
r0 = -1000(0xfffffffffffffc18, float:NaN)
r4.proceed(r0)
L2d:
r2.addActiveRunnable(r3)
java.util.concurrent.Executor r4 = r2.executor
r4.execute(r3)
java.lang.Object r4 = r3.get() // Catch: java.lang.Throwable -> L40 java.util.concurrent.ExecutionException -> L42
r3.blockUntilFinished()
r2.removeActiveRunnable(r3)
return r4
L40:
r4 = move-exception
goto L63
L42:
r4 = move-exception
java.lang.Throwable r0 = r4.getCause() // Catch: java.lang.Throwable -> L40
java.lang.Object r0 = androidx.media3.common.util.Assertions.checkNotNull(r0) // Catch: java.lang.Throwable -> L40
java.lang.Throwable r0 = (java.lang.Throwable) r0 // Catch: java.lang.Throwable -> L40
boolean r1 = r0 instanceof androidx.media3.common.PriorityTaskManager.PriorityTooLowException // Catch: java.lang.Throwable -> L40
if (r1 == 0) goto L52
goto L59
L52:
boolean r1 = r0 instanceof java.io.IOException // Catch: java.lang.Throwable -> L40
if (r1 != 0) goto L60
androidx.media3.common.util.Util.sneakyThrow(r4) // Catch: java.lang.Throwable -> L40
L59:
r3.blockUntilFinished()
r2.removeActiveRunnable(r3)
goto L20
L60:
java.io.IOException r0 = (java.io.IOException) r0 // Catch: java.lang.Throwable -> L40
throw r0 // Catch: java.lang.Throwable -> L40
L63:
r3.blockUntilFinished()
r2.removeActiveRunnable(r3)
throw r4
L6a:
java.lang.InterruptedException r2 = new java.lang.InterruptedException
r2.<init>()
throw r2
*/
throw new UnsupportedOperationException("Method not decompiled: androidx.media3.exoplayer.offline.SegmentDownloader.execute(androidx.media3.common.util.RunnableFutureTask, boolean):java.lang.Object");
}
protected static DataSpec getCompressibleDataSpec(Uri uri) {
return new DataSpec.Builder().setUri(uri).setFlags(1).build();
}
private <T> void addActiveRunnable(RunnableFutureTask<T, ?> runnableFutureTask) throws InterruptedException {
synchronized (this.activeRunnables) {
if (this.isCanceled) {
throw new InterruptedException();
}
this.activeRunnables.add(runnableFutureTask);
}
}
private void removeActiveRunnable(RunnableFutureTask<?, ?> runnableFutureTask) {
synchronized (this.activeRunnables) {
this.activeRunnables.remove(runnableFutureTask);
}
}
private void removeActiveRunnable(int i) {
synchronized (this.activeRunnables) {
this.activeRunnables.remove(i);
}
}
private static void mergeSegments(List<Segment> list, CacheKeyFactory cacheKeyFactory, long j) {
HashMap hashMap = new HashMap();
int i = 0;
for (int i2 = 0; i2 < list.size(); i2++) {
Segment segment = list.get(i2);
String buildCacheKey = cacheKeyFactory.buildCacheKey(segment.dataSpec);
Integer num = (Integer) hashMap.get(buildCacheKey);
Segment segment2 = num == null ? null : list.get(num.intValue());
if (segment2 == null || segment.startTimeUs > segment2.startTimeUs + j || !canMergeSegments(segment2.dataSpec, segment.dataSpec)) {
hashMap.put(buildCacheKey, Integer.valueOf(i));
list.set(i, segment);
i++;
} else {
list.set(((Integer) Assertions.checkNotNull(num)).intValue(), new Segment(segment2.startTimeUs, segment2.dataSpec.subrange(0L, segment.dataSpec.length != -1 ? segment2.dataSpec.length + segment.dataSpec.length : -1L)));
}
}
Util.removeRange(list, i, list.size());
}
private static boolean canMergeSegments(DataSpec dataSpec, DataSpec dataSpec2) {
return dataSpec.uri.equals(dataSpec2.uri) && dataSpec.length != -1 && dataSpec.position + dataSpec.length == dataSpec2.position && Util.areEqual(dataSpec.key, dataSpec2.key) && dataSpec.flags == dataSpec2.flags && dataSpec.httpMethod == dataSpec2.httpMethod && dataSpec.httpRequestHeaders.equals(dataSpec2.httpRequestHeaders);
}
/* loaded from: classes2.dex */
private static final class SegmentDownloadRunnable extends RunnableFutureTask<Void, IOException> {
private final CacheWriter cacheWriter;
public final CacheDataSource dataSource;
private final ProgressNotifier progressNotifier;
public final Segment segment;
public final byte[] temporaryBuffer;
public SegmentDownloadRunnable(Segment segment, CacheDataSource cacheDataSource, ProgressNotifier progressNotifier, byte[] bArr) {
this.segment = segment;
this.dataSource = cacheDataSource;
this.progressNotifier = progressNotifier;
this.temporaryBuffer = bArr;
this.cacheWriter = new CacheWriter(cacheDataSource, segment.dataSpec, bArr, progressNotifier);
}
/* JADX INFO: Access modifiers changed from: protected */
@Override // androidx.media3.common.util.RunnableFutureTask
public Void doWork() throws IOException {
this.cacheWriter.cache();
ProgressNotifier progressNotifier = this.progressNotifier;
if (progressNotifier == null) {
return null;
}
progressNotifier.onSegmentDownloaded();
return null;
}
@Override // androidx.media3.common.util.RunnableFutureTask
protected void cancelWork() {
this.cacheWriter.cancel();
}
}
/* JADX INFO: Access modifiers changed from: private */
/* loaded from: classes2.dex */
public static final class ProgressNotifier implements CacheWriter.ProgressListener {
private long bytesDownloaded;
private final long contentLength;
private final Downloader.ProgressListener progressListener;
private int segmentsDownloaded;
private final int totalSegments;
private float getPercentDownloaded() {
float f;
float f2;
long j = this.contentLength;
if (j == -1 || j == 0) {
int i = this.totalSegments;
if (i == 0) {
return -1.0f;
}
f = this.segmentsDownloaded * 100.0f;
f2 = i;
} else {
f = ((float) this.bytesDownloaded) * 100.0f;
f2 = (float) j;
}
return f / f2;
}
public ProgressNotifier(Downloader.ProgressListener progressListener, long j, int i, long j2, int i2) {
this.progressListener = progressListener;
this.contentLength = j;
this.totalSegments = i;
this.bytesDownloaded = j2;
this.segmentsDownloaded = i2;
}
@Override // androidx.media3.datasource.cache.CacheWriter.ProgressListener
public void onProgress(long j, long j2, long j3) {
long j4 = this.bytesDownloaded + j3;
this.bytesDownloaded = j4;
this.progressListener.onProgress(this.contentLength, j4, getPercentDownloaded());
}
public void onSegmentDownloaded() {
this.segmentsDownloaded++;
this.progressListener.onProgress(this.contentLength, this.bytesDownloaded, getPercentDownloaded());
}
}
}