Android: Drop old frame in SurfaceTextureHelper.startListening()

Drop any pending texture frame when SurfaceTextureHelper.startListening()
is called because the frame might be from the previous
startListening()/stopListening() capture session. This typically happens
when switching between the front/back camera, and an old frame will get
incorrect rotation and mirroring because of the front/back camera
mismatch.

Dropping the frame in SurfaceTextureHelper also removes the need for
the |dropNextFrame| logic in VideoCapturerAndroid.

R=perkj@webrtc.org

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

Cr-Original-Commit-Position: refs/heads/master@{#12849}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 181310fb6fe2aff416b112b7e9945d651566fab0
diff --git a/api/java/android/org/webrtc/SurfaceTextureHelper.java b/api/java/android/org/webrtc/SurfaceTextureHelper.java
index 09f78a5..ef43c5e 100644
--- a/api/java/android/org/webrtc/SurfaceTextureHelper.java
+++ b/api/java/android/org/webrtc/SurfaceTextureHelper.java
@@ -309,8 +309,12 @@
       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 @@
     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 @@
     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/api/java/android/org/webrtc/VideoCapturerAndroid.java b/api/java/android/org/webrtc/VideoCapturerAndroid.java
index 6352bf7..e4c33d5 100644
--- a/api/java/android/org/webrtc/VideoCapturerAndroid.java
+++ b/api/java/android/org/webrtc/VideoCapturerAndroid.java
@@ -78,9 +78,6 @@
   private final Set<byte[]> queuedBuffers = new HashSet<byte[]>();
   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 @@
     // 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 @@
     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 @@
       throw new RuntimeException("onTextureFrameAvailable() called after stopCapture().");
     }
     checkIsOnCameraThread();
-    if (dropNextFrame)  {
-      surfaceHelper.returnTextureFrame();
-      dropNextFrame = false;
-      return;
-    }
     if (eventsHandler != null && !firstFrameReported) {
       eventsHandler.onFirstFrameAvailable();
       firstFrameReported = true;