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
// thread.
// Metadata for the last frame rendered to the texture.
private Object renderedTextureMetadataLock = new Object();
private DecodedTextureMetadata renderedTextureMetadata;
// Decoding proceeds asynchronously. This callback returns decoded frames to the caller. Valid
@ -320,6 +320,9 @@ class HardwareVideoDecoder
surfaceTextureHelper.dispose();
surfaceTextureHelper = null;
}
synchronized (renderedTextureMetadataLock) {
renderedTextureMetadata = null;
}
callback = null;
frameInfos.clear();
return status;
@ -424,25 +427,35 @@ class HardwareVideoDecoder
height = this.height;
}
surfaceTextureHelper.getHandler().post(new Runnable() {
@Override
public void run() {
renderedTextureMetadata = new DecodedTextureMetadata(
width, height, rotation, info.presentationTimeUs, decodeTimeMs);
codec.releaseOutputBuffer(index, true);
synchronized (renderedTextureMetadataLock) {
if (renderedTextureMetadata != null) {
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);
}
}
@Override
public void onTextureFrameAvailable(int oesTextureId, float[] transformMatrix, long timestampNs) {
VideoFrame.TextureBuffer oesBuffer = surfaceTextureHelper.createTextureBuffer(
renderedTextureMetadata.width, renderedTextureMetadata.height,
RendererCommon.convertMatrixToAndroidGraphicsMatrix(transformMatrix));
final VideoFrame frame;
final int decodeTimeMs;
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,
renderedTextureMetadata.presentationTimestampUs * 1000);
callback.onDecodedFrame(frame, renderedTextureMetadata.decodeTimeMs, null /* qp */);
callback.onDecodedFrame(frame, decodeTimeMs, null /* qp */);
frame.release();
}