Make CameraCapturer.switchCamera try again if session is still opening.

R=magjed@webrtc.org

Review-Url: https://codereview.webrtc.org/2238263002
Cr-Commit-Position: refs/heads/master@{#13747}
This commit is contained in:
sakal 2016-08-15 06:19:34 -07:00 committed by Commit bot
parent d7d05f8056
commit 92c09509bd
2 changed files with 65 additions and 36 deletions

View File

@ -318,21 +318,35 @@ public class Camera2Session implements CameraSession {
@Override
public void stop() {
Logging.d(TAG, "Stop camera2 session on camera " + cameraId);
final CountDownLatch stopLatch = new CountDownLatch(1);
cameraThreadHandler.post(new Runnable() {
@Override
public void run() {
if (state != SessionState.STOPPED) {
state = SessionState.STOPPED;
capturerObserver.onCapturerStopped();
stopLatch.countDown();
stopInternal();
}
if (Thread.currentThread() == cameraThreadHandler.getLooper().getThread()) {
if (state != SessionState.STOPPED) {
state = SessionState.STOPPED;
capturerObserver.onCapturerStopped();
// Post the stopInternal to return earlier.
cameraThreadHandler.post(new Runnable() {
@Override
public void run() {
stopInternal();
}
});
}
});
} else {
final CountDownLatch stopLatch = new CountDownLatch(1);
ThreadUtils.awaitUninterruptibly(stopLatch);
cameraThreadHandler.post(new Runnable() {
@Override
public void run() {
if (state != SessionState.STOPPED) {
state = SessionState.STOPPED;
capturerObserver.onCapturerStopped();
stopLatch.countDown();
stopInternal();
}
}
});
ThreadUtils.awaitUninterruptibly(stopLatch);
}
}
private void stopInternal() {

View File

@ -10,17 +10,19 @@
package org.webrtc;
import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
import android.content.Context;
import android.os.Handler;
import android.os.SystemClock;
import java.util.Arrays;
import java.util.List;
@SuppressWarnings("deprecation")
public abstract class CameraCapturer implements CameraVideoCapturer {
enum SwitchState {
IDLE, // No switch requested.
PENDING, // Waiting for previous capture session to open.
IN_PROGRESS, // Waiting for new switched capture session to start.
}
private static final String TAG = "CameraCapturer";
private final static int MAX_OPEN_CAMERA_ATTEMPTS = 3;
private final static int OPEN_CAMERA_DELAY_MS = 500;
@ -39,12 +41,17 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
currentSession = session;
stateLock.notifyAll();
if (switchEventsHandler != null) {
switchEventsHandler.onCameraSwitchDone(
cameraEnumerator.isFrontFacing(cameraName));
switchEventsHandler = null;
if (switchState == SwitchState.IN_PROGRESS) {
if (switchEventsHandler != null) {
switchEventsHandler.onCameraSwitchDone(
cameraEnumerator.isFrontFacing(cameraName));
switchEventsHandler = null;
}
switchState = SwitchState.IDLE;
} else if (switchState == SwitchState.PENDING) {
switchState = SwitchState.IDLE;
switchCameraInternal(switchEventsHandler);
}
switchInProgress = false;
}
}
@ -58,11 +65,13 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
sessionOpening = false;
stateLock.notifyAll();
if (switchEventsHandler != null) {
switchEventsHandler.onCameraSwitchError(error);
switchEventsHandler = null;
if (switchState != SwitchState.IDLE) {
if (switchEventsHandler != null) {
switchEventsHandler.onCameraSwitchError(error);
switchEventsHandler = null;
}
switchState = SwitchState.IDLE;
}
switchInProgress = false;
eventsHandler.onCameraError(error);
} else {
@ -76,8 +85,6 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
// Initialized on initialize
// -------------------------
// Use postOnCameraThread() instead of posting directly to the handler - this way all
// callbacks with a specifed token can be removed at once.
private Handler cameraThreadHandler;
private Context applicationContext;
private CapturerObserver capturerObserver;
@ -91,7 +98,7 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
private int height; /* guarded by stateLock */
private int framerate; /* guarded by stateLock */
private int openAttemptsRemaining; /* guarded by stateLock */
private boolean switchInProgress; /* guarded by stateLock */
private SwitchState switchState = SwitchState.IDLE; /* guarded by stateLock */
private CameraSwitchHandler switchEventsHandler; /* guarded by stateLock */
public CameraCapturer(
@ -219,6 +226,16 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
@Override
public void switchCamera(final CameraSwitchHandler switchEventsHandler) {
Logging.d(TAG, "switchCamera");
cameraThreadHandler.post(new Runnable() {
@Override
public void run() {
switchCameraInternal(switchEventsHandler);
}
});
}
private void switchCameraInternal(final CameraSwitchHandler switchEventsHandler) {
Logging.d(TAG, "switchCamera internal");
final String[] deviceNames = cameraEnumerator.getDeviceNames();
@ -230,7 +247,7 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
}
synchronized (stateLock) {
if (switchInProgress) {
if (switchState != SwitchState.IDLE) {
Logging.d(TAG, "switchCamera switchInProgress");
if (switchEventsHandler != null) {
switchEventsHandler.onCameraSwitchError("Camera switch already in progress.");
@ -238,12 +255,12 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
return;
}
this.switchEventsHandler = switchEventsHandler;
if (sessionOpening) {
Logging.d(TAG, "switchCamera sessionOpening");
if (switchEventsHandler != null) {
switchEventsHandler.onCameraSwitchError("Session is still opening.");
}
switchState = SwitchState.PENDING;
return;
} else {
switchState = SwitchState.IN_PROGRESS;
}
if (currentSession == null) {
@ -261,8 +278,6 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
int cameraNameIndex = Arrays.asList(deviceNames).indexOf(cameraName);
cameraName = deviceNames[(cameraNameIndex + 1) % deviceNames.length];
switchInProgress = true;
this.switchEventsHandler = switchEventsHandler;
sessionOpening = true;
openAttemptsRemaining = 1;
createSessionInternal(0);