Android SurfaceViewRenderer: Never hold a pending frame indefinitely

The original purpose with keeping one pending frame in SurfaceViewRenderer was to reduce latency for the first rendered frame when we are waiting for the Surface to be created. However, it is very dangerous to hold a pending frame indefinitely when used with a SurfaceTexture, because the SurfaceTexture only has one frame and thus holding a frame in the renderer will freeze everything and typically cause timeout crashes.

Review URL: https://codereview.webrtc.org/1435413006

Cr-Commit-Position: refs/heads/master@{#10638}
This commit is contained in:
magjed
2015-11-13 08:48:03 -08:00
committed by Commit bot
parent c01c25434b
commit 4a41361f98

View File

@ -429,13 +429,24 @@ public class SurfaceViewRenderer extends SurfaceView
if (Thread.currentThread() != renderThread) {
throw new IllegalStateException(getResourceName() + "Wrong thread.");
}
// Fetch and render |pendingFrame|.
final VideoRenderer.I420Frame frame;
synchronized (frameLock) {
if (pendingFrame == null) {
return;
}
frame = pendingFrame;
pendingFrame = null;
}
if (eglBase == null || !eglBase.hasSurface()) {
Logging.d(TAG, getResourceName() + "No surface to draw on");
VideoRenderer.renderFrameDone(frame);
return;
}
if (!checkConsistentLayout()) {
// Output intermediate black frames while the layout is updated.
makeBlack();
VideoRenderer.renderFrameDone(frame);
return;
}
// After a surface size change, the EGLSurface might still have a buffer of the old size in the
@ -446,15 +457,6 @@ public class SurfaceViewRenderer extends SurfaceView
makeBlack();
}
}
// Fetch and render |pendingFrame|.
final VideoRenderer.I420Frame frame;
synchronized (frameLock) {
if (pendingFrame == null) {
return;
}
frame = pendingFrame;
pendingFrame = null;
}
final long startTimeNs = System.nanoTime();
final float[] samplingMatrix;