Fix deadlock issue in CameraCapturer.stopCapture.

BUG=webrtc:6404
NOTRY=True

Review-Url: https://codereview.webrtc.org/2357213002
Cr-Commit-Position: refs/heads/master@{#14333}
This commit is contained in:
sakal
2016-09-21 07:44:50 -07:00
committed by Commit bot
parent 7640fcf6ed
commit 28d5bc68c3
3 changed files with 34 additions and 73 deletions

View File

@ -22,7 +22,6 @@ import android.view.WindowManager;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@SuppressWarnings("deprecation")
@ -181,40 +180,15 @@ public class Camera1Session implements CameraSession {
@Override
public void stop() {
final long stopStartTime = System.nanoTime();
Logging.d(TAG, "Stop camera1 session on camera " + cameraId);
if (Thread.currentThread() == cameraThreadHandler.getLooper().getThread()) {
if (state != SessionState.STOPPED) {
state = SessionState.STOPPED;
// Post the stopInternal to return earlier.
cameraThreadHandler.post(new Runnable() {
@Override
public void run() {
stopInternal();
final int stopTimeMs =
(int) TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - stopStartTime);
camera1StopTimeMsHistogram.addSample(stopTimeMs);
}
});
}
} else {
final CountDownLatch stopLatch = new CountDownLatch(1);
cameraThreadHandler.post(new Runnable() {
@Override
public void run() {
if (state != SessionState.STOPPED) {
state = SessionState.STOPPED;
stopLatch.countDown();
stopInternal();
final int stopTimeMs =
(int) TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - stopStartTime);
camera1StopTimeMsHistogram.addSample(stopTimeMs);
}
}
});
ThreadUtils.awaitUninterruptibly(stopLatch);
checkIsOnCameraThread();
if (state != SessionState.STOPPED) {
final long stopStartTime = System.nanoTime();
state = SessionState.STOPPED;
stopInternal();
final int stopTimeMs =
(int) TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - stopStartTime);
camera1StopTimeMsHistogram.addSample(stopTimeMs);
}
}

View File

@ -31,7 +31,6 @@ import android.view.WindowManager;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@TargetApi(21)
@ -366,40 +365,15 @@ public class Camera2Session implements CameraSession {
@Override
public void stop() {
final long stopStartTime = System.nanoTime();
Logging.d(TAG, "Stop camera2 session on camera " + cameraId);
if (Thread.currentThread() == cameraThreadHandler.getLooper().getThread()) {
if (state != SessionState.STOPPED) {
state = SessionState.STOPPED;
// Post the stopInternal to return earlier.
cameraThreadHandler.post(new Runnable() {
@Override
public void run() {
stopInternal();
final int stopTimeMs =
(int) TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - stopStartTime);
camera2StopTimeMsHistogram.addSample(stopTimeMs);
}
});
}
} else {
final CountDownLatch stopLatch = new CountDownLatch(1);
cameraThreadHandler.post(new Runnable() {
@Override
public void run() {
if (state != SessionState.STOPPED) {
state = SessionState.STOPPED;
stopLatch.countDown();
stopInternal();
final int stopTimeMs =
(int) TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - stopStartTime);
camera2StopTimeMsHistogram.addSample(stopTimeMs);
}
}
});
ThreadUtils.awaitUninterruptibly(stopLatch);
checkIsOnCameraThread();
if (state != SessionState.STOPPED) {
final long stopStartTime = System.nanoTime();
state = SessionState.STOPPED;
stopInternal();
final int stopTimeMs =
(int) TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - stopStartTime);
camera2StopTimeMsHistogram.addSample(stopTimeMs);
}
}

View File

@ -40,8 +40,8 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
checkIsOnCameraThread();
Logging.d(TAG, "Create session done");
uiThreadHandler.removeCallbacks(openCameraTimeoutRunnable);
capturerObserver.onCapturerStarted(true /* success */);
synchronized (stateLock) {
capturerObserver.onCapturerStarted(true /* success */);
sessionOpening = false;
currentSession = session;
cameraStatistics = new CameraStatistics(surfaceHelper, eventsHandler);
@ -66,8 +66,8 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
public void onFailure(String error) {
checkIsOnCameraThread();
uiThreadHandler.removeCallbacks(openCameraTimeoutRunnable);
capturerObserver.onCapturerStarted(false /* success */);
synchronized (stateLock) {
capturerObserver.onCapturerStarted(false /* success */);
openAttemptsRemaining--;
if (openAttemptsRemaining <= 0) {
@ -284,11 +284,18 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
ThreadUtils.waitUninterruptibly(stateLock);
}
if (currentSession != null) {
Logging.d(TAG, "Stop capture: Stopping session");
Logging.d(TAG, "Stop capture: Nulling session");
cameraStatistics.release();
cameraStatistics = null;
currentSession.stop();
final CameraSession oldSession = currentSession;
cameraThreadHandler.post(new Runnable() {
@Override
public void run() {
oldSession.stop();
}
});
currentSession = null;
capturerObserver.onCapturerStopped();
} else {
@ -397,7 +404,13 @@ public abstract class CameraCapturer implements CameraVideoCapturer {
Logging.d(TAG, "switchCamera: Stopping session");
cameraStatistics.release();
cameraStatistics = null;
currentSession.stop();
final CameraSession oldSession = currentSession;
cameraThreadHandler.post(new Runnable() {
@Override
public void run() {
oldSession.stop();
}
});
currentSession = null;
int cameraNameIndex = Arrays.asList(deviceNames).indexOf(cameraName);