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 @Override
public void setParameters(Bundle params) { public void setParameters(Bundle params) {
codec.setParameters(params); bufferEnqueuer.setParameters(params);
} }
@Override @Override

View file

@ -21,6 +21,7 @@ import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Util.castNonNull; import static androidx.media3.common.util.Util.castNonNull;
import android.media.MediaCodec; import android.media.MediaCodec;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.Message; 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_INPUT_BUFFER = 0;
private static final int MSG_QUEUE_SECURE_INPUT_BUFFER = 1; private static final int MSG_QUEUE_SECURE_INPUT_BUFFER = 1;
private static final int MSG_OPEN_CV = 2; private static final int MSG_OPEN_CV = 2;
private static final int MSG_SET_PARAMETERS = 3;
@GuardedBy("MESSAGE_PARAMS_INSTANCE_POOL") @GuardedBy("MESSAGE_PARAMS_INSTANCE_POOL")
private static final ArrayDeque<MessageParams> MESSAGE_PARAMS_INSTANCE_POOL = new ArrayDeque<>(); private static final ArrayDeque<MessageParams> MESSAGE_PARAMS_INSTANCE_POOL = new ArrayDeque<>();
@ -134,6 +136,11 @@ class AsynchronousMediaCodecBufferEnqueuer {
message.sendToTarget(); message.sendToTarget();
} }
public void setParameters(Bundle params) {
maybeThrowException();
castNonNull(handler).obtainMessage(MSG_SET_PARAMETERS, params).sendToTarget();
}
/** Flushes the instance. */ /** Flushes the instance. */
public void flush() { public void flush() {
if (started) { if (started) {
@ -212,6 +219,10 @@ class AsynchronousMediaCodecBufferEnqueuer {
case MSG_OPEN_CV: case MSG_OPEN_CV:
conditionVariable.open(); conditionVariable.open();
break; break;
case MSG_SET_PARAMETERS:
Bundle parameters = (Bundle) msg.obj;
doSetParameters(parameters);
break;
default: default:
pendingRuntimeException.compareAndSet( pendingRuntimeException.compareAndSet(
null, new IllegalStateException(String.valueOf(msg.what))); 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() { private static MessageParams getMessageParams() {
synchronized (MESSAGE_PARAMS_INSTANCE_POOL) { synchronized (MESSAGE_PARAMS_INSTANCE_POOL) {
if (MESSAGE_PARAMS_INSTANCE_POOL.isEmpty()) { 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.MediaCodec;
import android.media.MediaFormat; import android.media.MediaFormat;
import android.os.Bundle;
import android.os.HandlerThread; import android.os.HandlerThread;
import androidx.media3.common.C; import androidx.media3.common.C;
import androidx.media3.common.util.ConditionVariable; import androidx.media3.common.util.ConditionVariable;
@ -161,6 +162,23 @@ public class AsynchronousMediaCodecBufferEnqueuerTest {
/* flags= */ 0)); /* 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 @Test
public void flush_withoutStart_works() { public void flush_withoutStart_works() {
enqueuer.flush(); enqueuer.flush();