Switch to getInput/OutputBuffer

Use getInput/OutputBuffer(index) instead of getInput/OutputBuffers() in
Android MediaCodec video encoder and decoder wrappers.

getInput/OutputBuffers(index) are available from SDK 21 which is the minimum required version in WebRTC: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/sdk/android/AndroidManifest.xml

Bug: b/234879577
Change-Id: I79fd234b104420ae3544229e8c62d7db2344cd01
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/265804
Reviewed-by: Xavier Lepaul‎ <xalep@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37241}
diff --git a/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java b/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java
index 651774e..ad40898 100644
--- a/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java
+++ b/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java
@@ -264,9 +264,9 @@
 
     ByteBuffer buffer;
     try {
-      buffer = codec.getInputBuffers()[index];
+      buffer = codec.getInputBuffer(index);
     } catch (IllegalStateException e) {
-      Logging.e(TAG, "getInputBuffers failed", e);
+      Logging.e(TAG, "getInputBuffer with index=" + index + " failed", e);
       return VideoCodecStatus.ERROR;
     }
 
@@ -377,14 +377,14 @@
       // exceeded, deliverDecodedFrame() will be called again on the next iteration of the output
       // thread's loop.  Blocking here prevents the output thread from busy-waiting while the codec
       // is idle.
-      int result = codec.dequeueOutputBuffer(info, DEQUEUE_OUTPUT_BUFFER_TIMEOUT_US);
-      if (result == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+      int index = codec.dequeueOutputBuffer(info, DEQUEUE_OUTPUT_BUFFER_TIMEOUT_US);
+      if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
         reformat(codec.getOutputFormat());
         return;
       }
 
-      if (result < 0) {
-        Logging.v(TAG, "dequeueOutputBuffer returned " + result);
+      if (index < 0) {
+        Logging.v(TAG, "dequeueOutputBuffer returned " + index);
         return;
       }
 
@@ -399,9 +399,9 @@
       hasDecodedFirstFrame = true;
 
       if (surfaceTextureHelper != null) {
-        deliverTextureFrame(result, info, rotation, decodeTimeMs);
+        deliverTextureFrame(index, info, rotation, decodeTimeMs);
       } else {
-        deliverByteFrame(result, info, rotation, decodeTimeMs);
+        deliverByteFrame(index, info, rotation, decodeTimeMs);
       }
 
     } catch (IllegalStateException e) {
@@ -452,7 +452,7 @@
   }
 
   private void deliverByteFrame(
-      int result, MediaCodec.BufferInfo info, int rotation, Integer decodeTimeMs) {
+      int index, MediaCodec.BufferInfo info, int rotation, Integer decodeTimeMs) {
     // Load dimensions from shared memory under the dimension lock.
     int width;
     int height;
@@ -479,7 +479,7 @@
       stride = info.size * 2 / (height * 3);
     }
 
-    ByteBuffer buffer = codec.getOutputBuffers()[result];
+    ByteBuffer buffer = codec.getOutputBuffer(index);
     buffer.position(info.offset);
     buffer.limit(info.offset + info.size);
     buffer = buffer.slice();
@@ -491,7 +491,7 @@
       // All other supported color formats are NV12.
       frameBuffer = copyNV12ToI420Buffer(buffer, stride, sliceHeight, width, height);
     }
-    codec.releaseOutputBuffer(result, /* render= */ false);
+    codec.releaseOutputBuffer(index, /* render= */ false);
 
     long presentationTimeNs = info.presentationTimeUs * 1000;
     VideoFrame frame = new VideoFrame(frameBuffer, rotation, presentationTimeNs);
diff --git a/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java b/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java
index 743edb0b..42a3ccf 100644
--- a/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java
+++ b/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java
@@ -56,7 +56,7 @@
   /**
    * Keeps track of the number of output buffers that have been passed down the pipeline and not yet
    * released. We need to wait for this to go down to zero before operations invalidating the output
-   * buffers, i.e., stop() and getOutputBuffers().
+   * buffers, i.e., stop() and getOutputBuffer().
    */
   private static class BusyCount {
     private final Object countLock = new Object();
@@ -132,7 +132,6 @@
 
   // --- Valid and immutable while an encoding session is running.
   @Nullable private MediaCodecWrapper codec;
-  @Nullable private ByteBuffer[] outputBuffers;
   // Thread that delivers encoded frames to the user callback.
   @Nullable private Thread outputThread;
 
@@ -285,7 +284,6 @@
       sliceHeight = getSliceHeight(inputFormat, height);
 
       codec.start();
-      outputBuffers = codec.getOutputBuffers();
     } catch (IllegalStateException e) {
       Logging.e(TAG, "initEncodeInternal failed", e);
       release();
@@ -335,7 +333,6 @@
     outputBuilders.clear();
 
     codec = null;
-    outputBuffers = null;
     outputThread = null;
 
     // Allow changing thread after release.
@@ -454,9 +451,9 @@
 
     ByteBuffer buffer;
     try {
-      buffer = codec.getInputBuffers()[index];
+      buffer = codec.getInputBuffer(index);
     } catch (IllegalStateException e) {
-      Logging.e(TAG, "getInputBuffers failed", e);
+      Logging.e(TAG, "getInputBuffer with index=" + index + " failed", e);
       return VideoCodecStatus.ERROR;
     }
     fillInputBuffer(buffer, videoFrameBuffer);
@@ -582,12 +579,11 @@
       if (index < 0) {
         if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
           outputBuffersBusyCount.waitForZero();
-          outputBuffers = codec.getOutputBuffers();
         }
         return;
       }
 
-      ByteBuffer codecOutputBuffer = outputBuffers[index];
+      ByteBuffer codecOutputBuffer = codec.getOutputBuffer(index);
       codecOutputBuffer.position(info.offset);
       codecOutputBuffer.limit(info.offset + info.size);
 
diff --git a/sdk/android/src/java/org/webrtc/MediaCodecWrapper.java b/sdk/android/src/java/org/webrtc/MediaCodecWrapper.java
index 89f392d..60c853d 100644
--- a/sdk/android/src/java/org/webrtc/MediaCodecWrapper.java
+++ b/sdk/android/src/java/org/webrtc/MediaCodecWrapper.java
@@ -45,9 +45,9 @@
 
   MediaFormat getOutputFormat();
 
-  ByteBuffer[] getInputBuffers();
+  ByteBuffer getInputBuffer(int index);
 
-  ByteBuffer[] getOutputBuffers();
+  ByteBuffer getOutputBuffer(int index);
 
   Surface createInputSurface();
 
diff --git a/sdk/android/src/java/org/webrtc/MediaCodecWrapperFactoryImpl.java b/sdk/android/src/java/org/webrtc/MediaCodecWrapperFactoryImpl.java
index 3b4647b..2ba62ac 100644
--- a/sdk/android/src/java/org/webrtc/MediaCodecWrapperFactoryImpl.java
+++ b/sdk/android/src/java/org/webrtc/MediaCodecWrapperFactoryImpl.java
@@ -88,13 +88,13 @@
     }
 
     @Override
-    public ByteBuffer[] getInputBuffers() {
-      return mediaCodec.getInputBuffers();
+    public ByteBuffer getInputBuffer(int index) {
+      return mediaCodec.getInputBuffer(index);
     }
 
     @Override
-    public ByteBuffer[] getOutputBuffers() {
-      return mediaCodec.getOutputBuffers();
+    public ByteBuffer getOutputBuffer(int index) {
+      return mediaCodec.getOutputBuffer(index);
     }
 
     @Override
diff --git a/sdk/android/tests/src/org/webrtc/AndroidVideoDecoderTest.java b/sdk/android/tests/src/org/webrtc/AndroidVideoDecoderTest.java
index da75398..535187e 100644
--- a/sdk/android/tests/src/org/webrtc/AndroidVideoDecoderTest.java
+++ b/sdk/android/tests/src/org/webrtc/AndroidVideoDecoderTest.java
@@ -283,7 +283,7 @@
             /* presentationTimeUs= */ anyLong(),
             /* flags= */ eq(0));
 
-    ByteBuffer inputBuffer = fakeMediaCodecWrapper.getInputBuffers()[indexCaptor.getValue()];
+    ByteBuffer inputBuffer = fakeMediaCodecWrapper.getInputBuffer(indexCaptor.getValue());
     CodecTestHelper.assertEqualContents(
         ENCODED_TEST_DATA, inputBuffer, offsetCaptor.getValue(), sizeCaptor.getValue());
   }
diff --git a/sdk/android/tests/src/org/webrtc/FakeMediaCodecWrapper.java b/sdk/android/tests/src/org/webrtc/FakeMediaCodecWrapper.java
index c5e6949..fb7aba4 100644
--- a/sdk/android/tests/src/org/webrtc/FakeMediaCodecWrapper.java
+++ b/sdk/android/tests/src/org/webrtc/FakeMediaCodecWrapper.java
@@ -292,13 +292,13 @@
   }
 
   @Override
-  public ByteBuffer[] getInputBuffers() {
-    return inputBuffers;
+  public ByteBuffer getInputBuffer(int index) {
+    return inputBuffers[index];
   }
 
   @Override
-  public ByteBuffer[] getOutputBuffers() {
-    return outputBuffers;
+  public ByteBuffer getOutputBuffer(int index) {
+    return outputBuffers[index];
   }
 
   @Override
diff --git a/sdk/android/tests/src/org/webrtc/HardwareVideoEncoderTest.java b/sdk/android/tests/src/org/webrtc/HardwareVideoEncoderTest.java
index 635fffb..bd4a642 100644
--- a/sdk/android/tests/src/org/webrtc/HardwareVideoEncoderTest.java
+++ b/sdk/android/tests/src/org/webrtc/HardwareVideoEncoderTest.java
@@ -216,7 +216,7 @@
     verify(fakeMediaCodecWrapper)
         .queueInputBuffer(indexCaptor.capture(), offsetCaptor.capture(), sizeCaptor.capture(),
             anyLong(), anyInt());
-    ByteBuffer buffer = fakeMediaCodecWrapper.getInputBuffers()[indexCaptor.getValue()];
+    ByteBuffer buffer = fakeMediaCodecWrapper.getInputBuffer(indexCaptor.getValue());
     CodecTestHelper.assertEqualContents(
         i420, buffer, offsetCaptor.getValue(), sizeCaptor.getValue());
   }