Forward setParameters to AsynchronousMediaCodecBufferEnqueuer

The parameters may change the decoding behavior of the
following samples and it's suprising/wrong to apply them
from another thread where we can't guarantee from which
sample they apply.

PiperOrigin-RevId: 591808760
This commit is contained in:
tonihei 2023-12-18 00:34:30 -08:00 committed by Copybara-Service
parent 236bad5597
commit b7c3d83e51
3 changed files with 38 additions and 1 deletions

View file

@ -248,7 +248,7 @@ import java.nio.ByteBuffer;
@Override
public void setParameters(Bundle params) {
codec.setParameters(params);
bufferEnqueuer.setParameters(params);
}
@Override

View file

@ -21,6 +21,7 @@ import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Util.castNonNull;
import android.media.MediaCodec;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
@ -49,6 +50,7 @@ class AsynchronousMediaCodecBufferEnqueuer {
private static final int MSG_QUEUE_INPUT_BUFFER = 0;
private static final int MSG_QUEUE_SECURE_INPUT_BUFFER = 1;
private static final int MSG_OPEN_CV = 2;
private static final int MSG_SET_PARAMETERS = 3;
@GuardedBy("MESSAGE_PARAMS_INSTANCE_POOL")
private static final ArrayDeque<MessageParams> MESSAGE_PARAMS_INSTANCE_POOL = new ArrayDeque<>();
@ -134,6 +136,11 @@ class AsynchronousMediaCodecBufferEnqueuer {
message.sendToTarget();
}
public void setParameters(Bundle params) {
maybeThrowException();
castNonNull(handler).obtainMessage(MSG_SET_PARAMETERS, params).sendToTarget();
}
/** Flushes the instance. */
public void flush() {
if (started) {
@ -212,6 +219,10 @@ class AsynchronousMediaCodecBufferEnqueuer {
case MSG_OPEN_CV:
conditionVariable.open();
break;
case MSG_SET_PARAMETERS:
Bundle parameters = (Bundle) msg.obj;
doSetParameters(parameters);
break;
default:
pendingRuntimeException.compareAndSet(
null, new IllegalStateException(String.valueOf(msg.what)));
@ -244,6 +255,14 @@ class AsynchronousMediaCodecBufferEnqueuer {
}
}
private void doSetParameters(Bundle parameters) {
try {
codec.setParameters(parameters);
} catch (RuntimeException e) {
pendingRuntimeException.compareAndSet(null, e);
}
}
private static MessageParams getMessageParams() {
synchronized (MESSAGE_PARAMS_INSTANCE_POOL) {
if (MESSAGE_PARAMS_INSTANCE_POOL.isEmpty()) {

View file

@ -23,6 +23,7 @@ import static org.robolectric.Shadows.shadowOf;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.os.Bundle;
import android.os.HandlerThread;
import androidx.media3.common.C;
import androidx.media3.common.util.ConditionVariable;
@ -161,6 +162,23 @@ public class AsynchronousMediaCodecBufferEnqueuerTest {
/* flags= */ 0));
}
@Test
public void setParameters_withPendingCryptoExceptionSet_throwsCryptoException() {
enqueuer.setPendingRuntimeException(
new MediaCodec.CryptoException(/* errorCode= */ 0, /* detailMessage= */ null));
enqueuer.start();
assertThrows(MediaCodec.CryptoException.class, () -> enqueuer.setParameters(new Bundle()));
}
@Test
public void setParameters_withPendingIllegalStateExceptionSet_throwsIllegalStateException() {
enqueuer.start();
enqueuer.setPendingRuntimeException(new IllegalStateException());
assertThrows(IllegalStateException.class, () -> enqueuer.setParameters(new Bundle()));
}
@Test
public void flush_withoutStart_works() {
enqueuer.flush();