diff --git a/webrtc/api/java/android/org/webrtc/SurfaceTextureHelper.java b/webrtc/api/java/android/org/webrtc/SurfaceTextureHelper.java index 09f78a58f4..ef43c5e4dc 100644 --- a/webrtc/api/java/android/org/webrtc/SurfaceTextureHelper.java +++ b/webrtc/api/java/android/org/webrtc/SurfaceTextureHelper.java @@ -309,8 +309,12 @@ class SurfaceTextureHelper { Logging.d(TAG, "Setting listener to " + pendingListener); listener = pendingListener; pendingListener = null; - // May alredy have a pending frame - try delivering it. - tryDeliverTextureFrame(); + // May have a pending frame from the previous capture session - drop it. + if (hasPendingTexture) { + // Calling updateTexImage() is neccessary in order to receive new frames. + updateTexImage(); + hasPendingTexture = false; + } } }; @@ -455,6 +459,15 @@ class SurfaceTextureHelper { getYuvConverter().convert(buf, width, height, stride, textureId, transformMatrix); } + private void updateTexImage() { + // SurfaceTexture.updateTexImage apparently can compete and deadlock with eglSwapBuffers, + // as observed on Nexus 5. Therefore, synchronize it with the EGL functions. + // See https://bugs.chromium.org/p/webrtc/issues/detail?id=5702 for more info. + synchronized (EglBase.lock) { + surfaceTexture.updateTexImage(); + } + } + private void tryDeliverTextureFrame() { if (handler.getLooper().getThread() != Thread.currentThread()) { throw new IllegalStateException("Wrong thread."); @@ -465,12 +478,7 @@ class SurfaceTextureHelper { isTextureInUse = true; hasPendingTexture = false; - // SurfaceTexture.updateTexImage apparently can compete and deadlock with eglSwapBuffers, - // as observed on Nexus 5. Therefore, synchronize it with the EGL functions. - // See https://bugs.chromium.org/p/webrtc/issues/detail?id=5702 for more info. - synchronized (EglBase.lock) { - surfaceTexture.updateTexImage(); - } + updateTexImage(); final float[] transformMatrix = new float[16]; surfaceTexture.getTransformMatrix(transformMatrix); diff --git a/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java b/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java index 6352bf799f..e4c33d50a0 100644 --- a/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java +++ b/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java @@ -78,9 +78,6 @@ public class VideoCapturerAndroid implements private final Set queuedBuffers = new HashSet(); private final boolean isCapturingToTexture; private SurfaceTextureHelper surfaceHelper; - // The camera API can output one old frame after the camera has been switched or the resolution - // has been changed. This flag is used for dropping the first frame after camera restart. - private boolean dropNextFrame = false; private final static int MAX_OPEN_CAMERA_ATTEMPTS = 3; private final static int OPEN_CAMERA_DELAY_MS = 500; private int openCameraAttempts; @@ -462,7 +459,6 @@ public class VideoCapturerAndroid implements // Temporarily stop preview if it's already running. if (this.captureFormat != null) { camera.stopPreview(); - dropNextFrame = true; // Calling |setPreviewCallbackWithBuffer| with null should clear the internal camera buffer // queue, but sometimes we receive a frame with the old resolution after this call anyway. camera.setPreviewCallbackWithBuffer(null); @@ -564,7 +560,6 @@ public class VideoCapturerAndroid implements synchronized (cameraIdLock) { id = (id + 1) % android.hardware.Camera.getNumberOfCameras(); } - dropNextFrame = true; startCaptureOnCameraThread(requestedWidth, requestedHeight, requestedFramerate, frameObserver, applicationContext); Logging.d(TAG, "switchCameraOnCameraThread done"); @@ -654,11 +649,6 @@ public class VideoCapturerAndroid implements throw new RuntimeException("onTextureFrameAvailable() called after stopCapture()."); } checkIsOnCameraThread(); - if (dropNextFrame) { - surfaceHelper.returnTextureFrame(); - dropNextFrame = false; - return; - } if (eventsHandler != null && !firstFrameReported) { eventsHandler.onFirstFrameAvailable(); firstFrameReported = true;