Rabbit-R1/android (non root)/java/sources/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecBufferEnqueuer.java
2024-05-21 17:08:36 -04:00

227 lines
8.5 KiB
Java

package androidx.media3.exoplayer.mediacodec;
import android.media.MediaCodec;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.ConditionVariable;
import androidx.media3.common.util.Util;
import androidx.media3.decoder.CryptoInfo;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference;
/* loaded from: classes2.dex */
class AsynchronousMediaCodecBufferEnqueuer {
private static final int MSG_OPEN_CV = 2;
private static final int MSG_QUEUE_INPUT_BUFFER = 0;
private static final int MSG_QUEUE_SECURE_INPUT_BUFFER = 1;
private final MediaCodec codec;
private final ConditionVariable conditionVariable;
private Handler handler;
private final HandlerThread handlerThread;
private final AtomicReference<RuntimeException> pendingRuntimeException;
private boolean started;
private static final ArrayDeque<MessageParams> MESSAGE_PARAMS_INSTANCE_POOL = new ArrayDeque<>();
private static final Object QUEUE_SECURE_LOCK = new Object();
public AsynchronousMediaCodecBufferEnqueuer(MediaCodec mediaCodec, HandlerThread handlerThread) {
this(mediaCodec, handlerThread, new ConditionVariable());
}
AsynchronousMediaCodecBufferEnqueuer(MediaCodec mediaCodec, HandlerThread handlerThread, ConditionVariable conditionVariable) {
this.codec = mediaCodec;
this.handlerThread = handlerThread;
this.conditionVariable = conditionVariable;
this.pendingRuntimeException = new AtomicReference<>();
}
public void start() {
if (this.started) {
return;
}
this.handlerThread.start();
this.handler = new Handler(this.handlerThread.getLooper()) { // from class: androidx.media3.exoplayer.mediacodec.AsynchronousMediaCodecBufferEnqueuer.1
@Override // android.os.Handler
public void handleMessage(Message message) {
AsynchronousMediaCodecBufferEnqueuer.this.doHandleMessage(message);
}
};
this.started = true;
}
public void queueInputBuffer(int i, int i2, int i3, long j, int i4) {
maybeThrowException();
MessageParams messageParams = getMessageParams();
messageParams.setQueueParams(i, i2, i3, j, i4);
((Handler) Util.castNonNull(this.handler)).obtainMessage(0, messageParams).sendToTarget();
}
public void queueSecureInputBuffer(int i, int i2, CryptoInfo cryptoInfo, long j, int i3) {
maybeThrowException();
MessageParams messageParams = getMessageParams();
messageParams.setQueueParams(i, i2, 0, j, i3);
copy(cryptoInfo, messageParams.cryptoInfo);
((Handler) Util.castNonNull(this.handler)).obtainMessage(1, messageParams).sendToTarget();
}
public void flush() {
if (this.started) {
try {
flushHandlerThread();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException(e);
}
}
}
public void shutdown() {
if (this.started) {
flush();
this.handlerThread.quit();
}
this.started = false;
}
public void waitUntilQueueingComplete() throws InterruptedException {
blockUntilHandlerThreadIsIdle();
}
public void maybeThrowException() {
RuntimeException andSet = this.pendingRuntimeException.getAndSet(null);
if (andSet != null) {
throw andSet;
}
}
private void flushHandlerThread() throws InterruptedException {
((Handler) Assertions.checkNotNull(this.handler)).removeCallbacksAndMessages(null);
blockUntilHandlerThreadIsIdle();
}
private void blockUntilHandlerThreadIsIdle() throws InterruptedException {
this.conditionVariable.close();
((Handler) Assertions.checkNotNull(this.handler)).obtainMessage(2).sendToTarget();
this.conditionVariable.block();
}
void setPendingRuntimeException(RuntimeException runtimeException) {
this.pendingRuntimeException.set(runtimeException);
}
/* JADX INFO: Access modifiers changed from: private */
public void doHandleMessage(Message message) {
MessageParams messageParams;
int i = message.what;
if (i == 0) {
messageParams = (MessageParams) message.obj;
doQueueInputBuffer(messageParams.index, messageParams.offset, messageParams.size, messageParams.presentationTimeUs, messageParams.flags);
} else if (i != 1) {
messageParams = null;
if (i == 2) {
this.conditionVariable.open();
} else {
this.pendingRuntimeException.compareAndSet(null, new IllegalStateException(String.valueOf(message.what)));
}
} else {
messageParams = (MessageParams) message.obj;
doQueueSecureInputBuffer(messageParams.index, messageParams.offset, messageParams.cryptoInfo, messageParams.presentationTimeUs, messageParams.flags);
}
if (messageParams != null) {
recycleMessageParams(messageParams);
}
}
private void doQueueInputBuffer(int i, int i2, int i3, long j, int i4) {
try {
this.codec.queueInputBuffer(i, i2, i3, j, i4);
} catch (RuntimeException e) {
this.pendingRuntimeException.compareAndSet(null, e);
}
}
private void doQueueSecureInputBuffer(int i, int i2, MediaCodec.CryptoInfo cryptoInfo, long j, int i3) {
try {
synchronized (QUEUE_SECURE_LOCK) {
this.codec.queueSecureInputBuffer(i, i2, cryptoInfo, j, i3);
}
} catch (RuntimeException e) {
this.pendingRuntimeException.compareAndSet(null, e);
}
}
private static MessageParams getMessageParams() {
ArrayDeque<MessageParams> arrayDeque = MESSAGE_PARAMS_INSTANCE_POOL;
synchronized (arrayDeque) {
if (arrayDeque.isEmpty()) {
return new MessageParams();
}
return arrayDeque.removeFirst();
}
}
private static void recycleMessageParams(MessageParams messageParams) {
ArrayDeque<MessageParams> arrayDeque = MESSAGE_PARAMS_INSTANCE_POOL;
synchronized (arrayDeque) {
arrayDeque.add(messageParams);
}
}
/* JADX INFO: Access modifiers changed from: private */
/* loaded from: classes2.dex */
public static class MessageParams {
public final MediaCodec.CryptoInfo cryptoInfo = new MediaCodec.CryptoInfo();
public int flags;
public int index;
public int offset;
public long presentationTimeUs;
public int size;
public void setQueueParams(int i, int i2, int i3, long j, int i4) {
this.index = i;
this.offset = i2;
this.size = i3;
this.presentationTimeUs = j;
this.flags = i4;
}
MessageParams() {
}
}
private static void copy(CryptoInfo cryptoInfo, MediaCodec.CryptoInfo cryptoInfo2) {
cryptoInfo2.numSubSamples = cryptoInfo.numSubSamples;
cryptoInfo2.numBytesOfClearData = copy(cryptoInfo.numBytesOfClearData, cryptoInfo2.numBytesOfClearData);
cryptoInfo2.numBytesOfEncryptedData = copy(cryptoInfo.numBytesOfEncryptedData, cryptoInfo2.numBytesOfEncryptedData);
cryptoInfo2.key = (byte[]) Assertions.checkNotNull(copy(cryptoInfo.key, cryptoInfo2.key));
cryptoInfo2.iv = (byte[]) Assertions.checkNotNull(copy(cryptoInfo.iv, cryptoInfo2.iv));
cryptoInfo2.mode = cryptoInfo.mode;
if (Util.SDK_INT >= 24) {
cryptoInfo2.setPattern(new MediaCodec.CryptoInfo.Pattern(cryptoInfo.encryptedBlocks, cryptoInfo.clearBlocks));
}
}
private static int[] copy(int[] iArr, int[] iArr2) {
if (iArr == null) {
return iArr2;
}
if (iArr2 == null || iArr2.length < iArr.length) {
return Arrays.copyOf(iArr, iArr.length);
}
System.arraycopy(iArr, 0, iArr2, 0, iArr.length);
return iArr2;
}
private static byte[] copy(byte[] bArr, byte[] bArr2) {
if (bArr == null) {
return bArr2;
}
if (bArr2 == null || bArr2.length < bArr.length) {
return Arrays.copyOf(bArr, bArr.length);
}
System.arraycopy(bArr, 0, bArr2, 0, bArr.length);
return bArr2;
}
}