mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-19 08:37:54 +01:00
Fetch encoded QP before releasing output buffer
Before this change we first released output frame buffer in the code path which prepends config buffer to a keyframe and then called getOutputFormat(index). getOutputFormat(index) throws an exception if index points to a released buffer. This change rearranges calls such that getOutputFormat(index) always executed before releaseOutputBuffer(index). Bug: webrtc:15015 Change-Id: Ia64f5d8e7483aeeb316d1a71c0cb79233f4bbee9 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/301364 Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Philip Eliasson <philipel@webrtc.org> Cr-Commit-Position: refs/heads/main@{#39874}
This commit is contained in:
parent
ea1502accb
commit
6cf12bbe32
2 changed files with 40 additions and 9 deletions
|
@ -606,6 +606,15 @@ class HardwareVideoEncoder implements VideoEncoder {
|
|||
Logging.d(TAG, "Sync frame generated");
|
||||
}
|
||||
|
||||
// Extract QP before releasing output buffer.
|
||||
Integer qp = null;
|
||||
if (isEncodingStatisticsEnabled) {
|
||||
MediaFormat format = codec.getOutputFormat(index);
|
||||
if (format != null && format.containsKey(MediaFormat.KEY_VIDEO_QP_AVERAGE)) {
|
||||
qp = format.getInteger(MediaFormat.KEY_VIDEO_QP_AVERAGE);
|
||||
}
|
||||
}
|
||||
|
||||
final ByteBuffer frameBuffer;
|
||||
final Runnable releaseCallback;
|
||||
if (isKeyFrame && configBuffer != null) {
|
||||
|
@ -639,15 +648,9 @@ class HardwareVideoEncoder implements VideoEncoder {
|
|||
: EncodedImage.FrameType.VideoFrameDelta;
|
||||
|
||||
EncodedImage.Builder builder = outputBuilders.poll();
|
||||
builder.setBuffer(frameBuffer, releaseCallback).setFrameType(frameType);
|
||||
|
||||
if (isEncodingStatisticsEnabled) {
|
||||
MediaFormat format = codec.getOutputFormat(index);
|
||||
if (format != null && format.containsKey(MediaFormat.KEY_VIDEO_QP_AVERAGE)) {
|
||||
int qp = format.getInteger(MediaFormat.KEY_VIDEO_QP_AVERAGE);
|
||||
builder.setQp(qp);
|
||||
}
|
||||
}
|
||||
builder.setBuffer(frameBuffer, releaseCallback);
|
||||
builder.setFrameType(frameType);
|
||||
builder.setQp(qp);
|
||||
|
||||
EncodedImage encodedImage = builder.createEncodedImage();
|
||||
// TODO(mellem): Set codec-specific info.
|
||||
|
|
|
@ -18,8 +18,10 @@ import static org.mockito.ArgumentMatchers.any;
|
|||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
@ -43,6 +45,7 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
@ -288,6 +291,31 @@ public class HardwareVideoEncoderTest {
|
|||
assertThat(videoFrame.qp).isEqualTo(123);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodingStatistics_fetchedBeforeFrameBufferIsReleased() throws InterruptedException {
|
||||
TestEncoder encoder =
|
||||
new TestEncoderBuilder().setCodecType(H264).SetIsEncodingStatisticsSupported(true).build();
|
||||
assertThat(encoder.initEncode(TEST_ENCODER_SETTINGS, mockEncoderCallback))
|
||||
.isEqualTo(VideoCodecStatus.OK);
|
||||
|
||||
encoder.encode(createTestVideoFrame(/* timestampNs= */ 42), ENCODE_INFO_KEY_FRAME);
|
||||
fakeMediaCodecWrapper.addOutputData(CodecTestHelper.generateRandomData(/* length= */ 100),
|
||||
/* presentationTimestampUs= */ 0,
|
||||
/* flags= */ MediaCodec.BUFFER_FLAG_CODEC_CONFIG);
|
||||
encoder.waitDeliverEncodedImage();
|
||||
|
||||
int frameBufferIndex =
|
||||
fakeMediaCodecWrapper.addOutputData(CodecTestHelper.generateRandomData(/* length= */ 100),
|
||||
/* presentationTimestampUs= */ 0,
|
||||
/* flags= */ MediaCodec.BUFFER_FLAG_SYNC_FRAME);
|
||||
encoder.waitDeliverEncodedImage();
|
||||
|
||||
InOrder inOrder = inOrder(fakeMediaCodecWrapper);
|
||||
inOrder.verify(fakeMediaCodecWrapper).getOutputFormat(eq(frameBufferIndex));
|
||||
inOrder.verify(fakeMediaCodecWrapper)
|
||||
.releaseOutputBuffer(eq(frameBufferIndex), /* render= */ eq(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeByteBuffer() {
|
||||
// Set-up.
|
||||
|
|
Loading…
Reference in a new issue