Fix a crash in HardwareVideoDecoder on reinitialization.

Do not post releasing the texture output buffer.

Bug: webrtc:7760
Change-Id: Ie4d7165a24c791a406be75688c814e2b9d9cde8f
Reviewed-on: https://webrtc-review.googlesource.com/5440
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20072}
This commit is contained in:
Sami Kalliomäki
2017-10-02 13:12:17 +02:00
committed by Commit Bot
parent 17a0474379
commit a58f231018

View File

@ -125,8 +125,8 @@ class HardwareVideoDecoder
} }
} }
// Metadata for the last frame rendered to the texture. Only accessed on the texture helper's // Metadata for the last frame rendered to the texture.
// thread. private Object renderedTextureMetadataLock = new Object();
private DecodedTextureMetadata renderedTextureMetadata; private DecodedTextureMetadata renderedTextureMetadata;
// Decoding proceeds asynchronously. This callback returns decoded frames to the caller. Valid // Decoding proceeds asynchronously. This callback returns decoded frames to the caller. Valid
@ -320,6 +320,9 @@ class HardwareVideoDecoder
surfaceTextureHelper.dispose(); surfaceTextureHelper.dispose();
surfaceTextureHelper = null; surfaceTextureHelper = null;
} }
synchronized (renderedTextureMetadataLock) {
renderedTextureMetadata = null;
}
callback = null; callback = null;
frameInfos.clear(); frameInfos.clear();
return status; return status;
@ -424,25 +427,35 @@ class HardwareVideoDecoder
height = this.height; height = this.height;
} }
surfaceTextureHelper.getHandler().post(new Runnable() { synchronized (renderedTextureMetadataLock) {
@Override if (renderedTextureMetadata != null) {
public void run() { return; // We are still waiting for texture for the previous frame, drop this one.
renderedTextureMetadata = new DecodedTextureMetadata(
width, height, rotation, info.presentationTimeUs, decodeTimeMs);
codec.releaseOutputBuffer(index, true);
} }
}); renderedTextureMetadata = new DecodedTextureMetadata(
width, height, rotation, info.presentationTimeUs, decodeTimeMs);
codec.releaseOutputBuffer(index, true);
}
} }
@Override @Override
public void onTextureFrameAvailable(int oesTextureId, float[] transformMatrix, long timestampNs) { public void onTextureFrameAvailable(int oesTextureId, float[] transformMatrix, long timestampNs) {
VideoFrame.TextureBuffer oesBuffer = surfaceTextureHelper.createTextureBuffer( final VideoFrame frame;
renderedTextureMetadata.width, renderedTextureMetadata.height, final int decodeTimeMs;
RendererCommon.convertMatrixToAndroidGraphicsMatrix(transformMatrix)); synchronized (renderedTextureMetadataLock) {
if (renderedTextureMetadata == null) {
throw new IllegalStateException(
"Rendered texture metadata was null in onTextureFrameAvailable.");
}
VideoFrame.TextureBuffer oesBuffer = surfaceTextureHelper.createTextureBuffer(
renderedTextureMetadata.width, renderedTextureMetadata.height,
RendererCommon.convertMatrixToAndroidGraphicsMatrix(transformMatrix));
frame = new VideoFrame(oesBuffer, renderedTextureMetadata.rotation,
renderedTextureMetadata.presentationTimestampUs * 1000);
decodeTimeMs = renderedTextureMetadata.decodeTimeMs;
renderedTextureMetadata = null;
}
VideoFrame frame = new VideoFrame(oesBuffer, renderedTextureMetadata.rotation, callback.onDecodedFrame(frame, decodeTimeMs, null /* qp */);
renderedTextureMetadata.presentationTimestampUs * 1000);
callback.onDecodedFrame(frame, renderedTextureMetadata.decodeTimeMs, null /* qp */);
frame.release(); frame.release();
} }