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}
This commit is contained in:
parent
ef3137a928
commit
7517fb639b
@ -264,9 +264,9 @@ class AndroidVideoDecoder implements VideoDecoder, VideoSink {
|
||||
|
||||
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 @@ class AndroidVideoDecoder implements VideoDecoder, VideoSink {
|
||||
// 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 @@ class AndroidVideoDecoder implements VideoDecoder, VideoSink {
|
||||
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 @@ class AndroidVideoDecoder implements VideoDecoder, VideoSink {
|
||||
}
|
||||
|
||||
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 @@ class AndroidVideoDecoder implements VideoDecoder, VideoSink {
|
||||
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 @@ class AndroidVideoDecoder implements VideoDecoder, VideoSink {
|
||||
// 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);
|
||||
|
||||
@ -56,7 +56,7 @@ class HardwareVideoEncoder implements VideoEncoder {
|
||||
/**
|
||||
* 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 @@ class HardwareVideoEncoder implements VideoEncoder {
|
||||
|
||||
// --- 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 @@ class HardwareVideoEncoder implements VideoEncoder {
|
||||
sliceHeight = getSliceHeight(inputFormat, height);
|
||||
|
||||
codec.start();
|
||||
outputBuffers = codec.getOutputBuffers();
|
||||
} catch (IllegalStateException e) {
|
||||
Logging.e(TAG, "initEncodeInternal failed", e);
|
||||
release();
|
||||
@ -335,7 +333,6 @@ class HardwareVideoEncoder implements VideoEncoder {
|
||||
outputBuilders.clear();
|
||||
|
||||
codec = null;
|
||||
outputBuffers = null;
|
||||
outputThread = null;
|
||||
|
||||
// Allow changing thread after release.
|
||||
@ -454,9 +451,9 @@ class HardwareVideoEncoder implements VideoEncoder {
|
||||
|
||||
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 @@ class HardwareVideoEncoder implements VideoEncoder {
|
||||
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);
|
||||
|
||||
|
||||
@ -45,9 +45,9 @@ interface MediaCodecWrapper {
|
||||
|
||||
MediaFormat getOutputFormat();
|
||||
|
||||
ByteBuffer[] getInputBuffers();
|
||||
ByteBuffer getInputBuffer(int index);
|
||||
|
||||
ByteBuffer[] getOutputBuffers();
|
||||
ByteBuffer getOutputBuffer(int index);
|
||||
|
||||
Surface createInputSurface();
|
||||
|
||||
|
||||
@ -88,13 +88,13 @@ class MediaCodecWrapperFactoryImpl implements MediaCodecWrapperFactory {
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@ -283,7 +283,7 @@ public class AndroidVideoDecoderTest {
|
||||
/* 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());
|
||||
}
|
||||
|
||||
@ -292,13 +292,13 @@ public class FakeMediaCodecWrapper implements MediaCodecWrapper {
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@ -216,7 +216,7 @@ public class HardwareVideoEncoderTest {
|
||||
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());
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user