diff options
author | Michael Katz <michaelkatz@google.com> | 2024-04-26 02:16:23 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-04-26 02:17:07 -0700 |
commit | 4f32042afe54beb3c8a02a330ba479e16febf49d (patch) | |
tree | 2b3e03e92a24bd05d65e8b5c74ad143b2f22d9ee | |
parent | 41a9904a946afa40cd4b623ec088e9d018c0cb03 (diff) | |
download | robolectric-4f32042afe54beb3c8a02a330ba479e16febf49d.tar.gz |
Adjust codec output format update in start to alter pendingOutputFormat
`ShadowMediaCodec.native_start`, if async, simulates a codec updating the output format.
The update overwrote the current pendingOutputFormat to the application.
The fix is to make those updates to the pendingOutputFormat and send that in the `CB_OUTPUT_FORMAT_CHANGE` event.
PiperOrigin-RevId: 628338243
-rw-r--r-- | robolectric/src/test/java/org/robolectric/shadows/ShadowMediaCodecTest.java | 9 | ||||
-rw-r--r-- | shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaCodec.java | 22 |
2 files changed, 27 insertions, 4 deletions
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaCodecTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaCodecTest.java index 7dc00c82e..72a75bec1 100644 --- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaCodecTest.java +++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaCodecTest.java @@ -7,6 +7,7 @@ import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.ArgumentMatchers.refEq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.same; import static org.mockito.Mockito.times; @@ -209,7 +210,13 @@ public final class ShadowMediaCodecTest { @Test public void formatChangeReported() throws IOException { MediaCodec codec = createAsyncEncoder(); - verify(callback).onOutputFormatChanged(same(codec), any()); + MediaFormat mediaFormat = getBasicAacFormat(); + // ShadowMediaCodec if async, simulates adding codec specific info before making input + // buffers available. + mediaFormat.setByteBuffer("csd-0", ByteBuffer.wrap(new byte[] {0x13, 0x10})); + mediaFormat.setByteBuffer("csd-1", ByteBuffer.wrap(new byte[0])); + + verify(callback).onOutputFormatChanged(same(codec), refEq(mediaFormat)); } @Test diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaCodec.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaCodec.java index 2e3003ac9..4bcc972dd 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaCodec.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaCodec.java @@ -98,6 +98,8 @@ public class ShadowMediaCodec { @Nullable private MediaFormat pendingOutputFormat; @Nullable private MediaFormat outputFormat; + @Nullable private String[] initialPendingOutputFormatKeys; + @Nullable private Object[] initialPendingOutputFormatValues; private final BlockingQueue<Integer> inputBuffersPendingDequeue = new LinkedBlockingDeque<>(); private final BlockingQueue<Integer> outputBuffersPendingDequeue = new LinkedBlockingDeque<>(); @@ -175,13 +177,15 @@ public class ShadowMediaCodec { } private void innerConfigure( - String[] keys, - Object[] values, + @Nullable String[] keys, + @Nullable Object[] values, @Nullable Surface surface, @Nullable MediaCrypto mediaCrypto, int flags) { isAsync = callback != null; pendingOutputFormat = recreateMediaFormatFromKeysValues(keys, values); + initialPendingOutputFormatKeys = keys; + initialPendingOutputFormatValues = values; fakeCodec.onConfigured(pendingOutputFormat, surface, mediaCrypto, flags); } @@ -202,10 +206,21 @@ public class ShadowMediaCodec { // Report the format as changed, to simulate adding codec specific info before making input // buffers available. HashMap<String, Object> format = new HashMap<>(); + if (pendingOutputFormat != null) { + pendingOutputFormat.setByteBuffer("csd-0", ByteBuffer.wrap(new byte[] {0x13, 0x10})); + pendingOutputFormat.setByteBuffer("csd-1", ByteBuffer.wrap(new byte[0])); + if (initialPendingOutputFormatKeys != null + && initialPendingOutputFormatValues != null + && initialPendingOutputFormatKeys.length == initialPendingOutputFormatValues.length) { + for (int i = 0; i < initialPendingOutputFormatKeys.length; i++) { + format.put(initialPendingOutputFormatKeys[i], initialPendingOutputFormatValues[i]); + } + } + } format.put("csd-0", ByteBuffer.wrap(new byte[] {0x13, 0x10})); format.put("csd-1", ByteBuffer.wrap(new byte[0])); - postFakeNativeEvent(EVENT_CALLBACK, CB_OUTPUT_FORMAT_CHANGE, 0, format); + postFakeNativeEvent(EVENT_CALLBACK, CB_OUTPUT_FORMAT_CHANGE, 0, format); try { makeInputBufferAvailable(inputBuffersPendingDequeue.take()); } catch (InterruptedException e) { @@ -544,6 +559,7 @@ public class ShadowMediaCodec { /** Move the bytes on the in buffer to the out buffer */ void process(ByteBuffer in, ByteBuffer out); + /** Called when the codec is configured. @see MediaCodec#configure */ default void onConfigured( MediaFormat format, @Nullable Surface surface, @Nullable MediaCrypto crypto, int flags) {} |