Bug 1452048 - Leave critical section before calling into java StartCapture(). r?dminor
If we stay in the critical section, and the StartCapture() is a reconfiguring
one, we risk deadlocking with IncomingFrame which runs on the camera thread.
MozReview-Commit-ID: 5rU4urrBWxr
--- a/media/webrtc/trunk/webrtc/modules/video_capture/android/video_capture_android.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/android/video_capture_android.cc
@@ -180,42 +180,51 @@ VideoCaptureAndroid::~VideoCaptureAndroi
env->GetMethodID(g_java_capturer_class, "unlinkCapturer", "()V");
env->CallVoidMethod(_jCapturer, j_unlink);
env->DeleteGlobalRef(_jCapturer);
}
int32_t VideoCaptureAndroid::StartCapture(
const VideoCaptureCapability& capability) {
- CriticalSectionScoped cs(&_apiCs);
+ _apiCs.Enter();
AttachThreadScoped ats(g_jvm_capture);
JNIEnv* env = ats.env();
if (_deviceInfo.GetBestMatchedCapability(
_deviceUniqueId, capability, _captureCapability) < 0) {
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
"%s: GetBestMatchedCapability failed: %dx%d",
__FUNCTION__, capability.width, capability.height);
+ // Manual exit of critical section
+ _apiCs.Leave();
return -1;
}
_captureDelay = _captureCapability.expectedCaptureDelay;
- jmethodID j_start =
- env->GetMethodID(g_java_capturer_class, "startCapture", "(IIII)Z");
- assert(j_start);
+ int width = _captureCapability.width;
+ int height = _captureCapability.height;
int min_mfps = 0;
int max_mfps = 0;
_deviceInfo.GetMFpsRange(_deviceUniqueId, _captureCapability.maxFPS,
&min_mfps, &max_mfps);
+
+ // Exit critical section to avoid blocking camera thread inside
+ // onIncomingFrame() call.
+ _apiCs.Leave();
+
+ jmethodID j_start =
+ env->GetMethodID(g_java_capturer_class, "startCapture", "(IIII)Z");
+ assert(j_start);
bool started = env->CallBooleanMethod(_jCapturer, j_start,
- _captureCapability.width,
- _captureCapability.height,
+ width, height,
min_mfps, max_mfps);
if (started) {
+ CriticalSectionScoped cs(&_apiCs);
_requestedCapability = capability;
_captureStarted = true;
}
return started ? 0 : -1;
}
int32_t VideoCaptureAndroid::StopCapture() {
_apiCs.Enter();