From b7c3d83e518d9c708f78fd0bfdd6cf9558ae663f Mon Sep 17 00:00:00 2001 From: tonihei Date: Mon, 18 Dec 2023 00:34:30 -0800 Subject: [PATCH] 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 --- .../AsynchronousMediaCodecAdapter.java | 2 +- .../AsynchronousMediaCodecBufferEnqueuer.java | 19 +++++++++++++++++++ ...nchronousMediaCodecBufferEnqueuerTest.java | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecAdapter.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecAdapter.java index cfca26309b..745a5b0d5a 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecAdapter.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecAdapter.java @@ -248,7 +248,7 @@ import java.nio.ByteBuffer; @Override public void setParameters(Bundle params) { - codec.setParameters(params); + bufferEnqueuer.setParameters(params); } @Override diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecBufferEnqueuer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecBufferEnqueuer.java index fdf22fb25b..f6d33f78bb 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecBufferEnqueuer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecBufferEnqueuer.java @@ -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 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()) { diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecBufferEnqueuerTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecBufferEnqueuerTest.java index d4ea15ce5f..615eb9ce99 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecBufferEnqueuerTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/mediacodec/AsynchronousMediaCodecBufferEnqueuerTest.java @@ -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();