aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Katz <michaelkatz@google.com>2024-04-26 02:16:23 -0700
committerCopybara-Service <copybara-worker@google.com>2024-04-26 02:17:07 -0700
commit4f32042afe54beb3c8a02a330ba479e16febf49d (patch)
tree2b3e03e92a24bd05d65e8b5c74ad143b2f22d9ee
parent41a9904a946afa40cd4b623ec088e9d018c0cb03 (diff)
downloadrobolectric-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.java9
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaCodec.java22
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) {}