Bug 1452048 - Leave critical section before calling into java StartCapture(). r=dminor
authorAndreas Pehrson <pehrsons@mozilla.com>
Fri, 06 Apr 2018 15:49:24 +0200
changeset 412400 729193a3d03ae3d3ed5ef9fcbf005662f256f2eb
parent 412399 7108113d5a4d26245cb0a469a03d812e82427992
child 412401 a83f3f831cabb7bacd03baadb2244f6bf34d242f
push id62381
push userpehrsons@gmail.com
push dateMon, 09 Apr 2018 15:30:59 +0000
treeherderautoland@a83f3f831cab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdminor
bugs1452048
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
media/webrtc/trunk/webrtc/modules/video_capture/android/video_capture_android.cc
--- 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();