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

View File

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

View File

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