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:
@ -429,13 +429,24 @@ public class SurfaceViewRenderer extends SurfaceView
|
|||||||
if (Thread.currentThread() != renderThread) {
|
if (Thread.currentThread() != renderThread) {
|
||||||
throw new IllegalStateException(getResourceName() + "Wrong thread.");
|
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()) {
|
if (eglBase == null || !eglBase.hasSurface()) {
|
||||||
Logging.d(TAG, getResourceName() + "No surface to draw on");
|
Logging.d(TAG, getResourceName() + "No surface to draw on");
|
||||||
|
VideoRenderer.renderFrameDone(frame);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!checkConsistentLayout()) {
|
if (!checkConsistentLayout()) {
|
||||||
// Output intermediate black frames while the layout is updated.
|
// Output intermediate black frames while the layout is updated.
|
||||||
makeBlack();
|
makeBlack();
|
||||||
|
VideoRenderer.renderFrameDone(frame);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// After a surface size change, the EGLSurface might still have a buffer of the old size in the
|
// 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();
|
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 long startTimeNs = System.nanoTime();
|
||||||
final float[] samplingMatrix;
|
final float[] samplingMatrix;
|
||||||
|
Reference in New Issue
Block a user