From 95a5f00484d5c69b842aa75e2e66cd97726ce20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20Kalliom=C3=A4ki?= Date: Wed, 7 Feb 2018 13:54:12 +0100 Subject: [PATCH] Update HWVideoEncoder to reuse codec buffer instead of copying the data. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In practice, this is safe since WebRTC doesn't access the buffer after the callback returns. This avoids unnecessary memory allocations causing out of memory errors. Bug: b/72675429 Change-Id: I2ed0224f40b7e1fa67c7aba625b99211f9c1e0a3 Reviewed-on: https://webrtc-review.googlesource.com/49162 Commit-Queue: Sami Kalliomäki Reviewed-by: Magnus Jedvert Cr-Commit-Position: refs/heads/master@{#21932} --- .../org/webrtc/HardwareVideoEncoderTest.java | 17 ++++++++++++++++- .../java/org/webrtc/HardwareVideoEncoder.java | 6 +++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/sdk/android/instrumentationtests/src/org/webrtc/HardwareVideoEncoderTest.java b/sdk/android/instrumentationtests/src/org/webrtc/HardwareVideoEncoderTest.java index 5fbf239c44..2c45a4f16b 100644 --- a/sdk/android/instrumentationtests/src/org/webrtc/HardwareVideoEncoderTest.java +++ b/sdk/android/instrumentationtests/src/org/webrtc/HardwareVideoEncoderTest.java @@ -87,7 +87,22 @@ public class HardwareVideoEncoderTest { public void onEncodedFrame(EncodedImage frame, VideoEncoder.CodecSpecificInfo info) { assertNotNull(frame); assertNotNull(info); - frameQueue.offer(frame); + + // Make a copy because keeping a reference to the buffer is not allowed. + final ByteBuffer bufferCopy = ByteBuffer.allocateDirect(frame.buffer.remaining()); + bufferCopy.put(frame.buffer); + bufferCopy.rewind(); + + frameQueue.offer(EncodedImage.builder() + .setBuffer(bufferCopy) + .setEncodedWidth(frame.encodedWidth) + .setEncodedHeight(frame.encodedHeight) + .setCaptureTimeNs(frame.captureTimeNs) + .setFrameType(frame.frameType) + .setRotation(frame.rotation) + .setCompleteFrame(frame.completeFrame) + .setQp(frame.qp) + .createEncodedImage()); } public EncodedImage poll() { diff --git a/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java b/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java index 776923a60e..0d18a66eff 100644 --- a/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java +++ b/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java @@ -506,11 +506,11 @@ class HardwareVideoEncoder implements VideoEncoder { frameBuffer = ByteBuffer.allocateDirect(info.size + configBuffer.capacity()); configBuffer.rewind(); frameBuffer.put(configBuffer); + frameBuffer.put(codecOutputBuffer); + frameBuffer.rewind(); } else { - frameBuffer = ByteBuffer.allocateDirect(info.size); + frameBuffer = codecOutputBuffer.slice(); } - frameBuffer.put(codecOutputBuffer); - frameBuffer.rewind(); final EncodedImage.FrameType frameType = isKeyFrame ? EncodedImage.FrameType.VideoFrameKey