Index: media/base/android/java/src/org/chromium/media/VideoCaptureCamera2.java |
diff --git a/media/base/android/java/src/org/chromium/media/VideoCaptureCamera2.java b/media/base/android/java/src/org/chromium/media/VideoCaptureCamera2.java |
index 91aeee8cc93ce21aafce1194080b974878b8ee6d..49b8cf34153771e8ceba7fd63d561ea2763f2967 100644 |
--- a/media/base/android/java/src/org/chromium/media/VideoCaptureCamera2.java |
+++ b/media/base/android/java/src/org/chromium/media/VideoCaptureCamera2.java |
@@ -46,9 +46,10 @@ |
@Override |
public void onOpened(CameraDevice cameraDevice) { |
mCameraDevice = cameraDevice; |
- changeCameraStateAndNotify(CameraState.CONFIGURING); |
+ mOpeningCamera = false; |
+ mConfiguringCamera = true; |
if (!createCaptureObjects()) { |
- changeCameraStateAndNotify(CameraState.STOPPED); |
+ mConfiguringCamera = false; |
nativeOnError(mNativeVideoCaptureDeviceAndroid, |
"Error configuring camera"); |
} |
@@ -58,14 +59,14 @@ |
public void onDisconnected(CameraDevice cameraDevice) { |
cameraDevice.close(); |
mCameraDevice = null; |
- changeCameraStateAndNotify(CameraState.STOPPED); |
+ mOpeningCamera = false; |
} |
@Override |
public void onError(CameraDevice cameraDevice, int error) { |
cameraDevice.close(); |
mCameraDevice = null; |
- changeCameraStateAndNotify(CameraState.STOPPED); |
+ mOpeningCamera = false; |
nativeOnError(mNativeVideoCaptureDeviceAndroid, |
"Camera device error " + Integer.toString(error)); |
} |
@@ -77,15 +78,14 @@ |
public void onConfigured(CameraCaptureSession cameraCaptureSession) { |
Log.d(TAG, "onConfigured"); |
mCaptureSession = cameraCaptureSession; |
+ mConfiguringCamera = false; |
createCaptureRequest(); |
- changeCameraStateAndNotify(CameraState.STARTED); |
} |
@Override |
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { |
// TODO(mcasas): When signalling error, C++ will tear us down. Is there need for |
// cleanup? |
- changeCameraStateAndNotify(CameraState.STOPPED); |
nativeOnError(mNativeVideoCaptureDeviceAndroid, |
"Camera session configuration error"); |
} |
@@ -125,6 +125,14 @@ |
private byte[] mCapturedData; |
+ // |mOpeningCamera| is used to signal the transient between openCamera() and |
+ // CrStateListener.onOpened(). |
+ private boolean mOpeningCamera = false; |
+ // |mConfiguringCamera| marks the transient between CrStateListener.onOpened() |
+ // and CrCaptureSessionListener.onConfigured(), including the time it takes |
+ // to createCaptureObjects(). |
+ private boolean mConfiguringCamera = false; |
+ |
private CameraDevice mCameraDevice = null; |
private CaptureRequest.Builder mPreviewBuilder = null; |
private CameraCaptureSession mCaptureSession = null; |
@@ -132,10 +140,6 @@ |
private static final double kNanoSecondsToFps = 1.0E-9; |
private static final String TAG = "cr.media"; |
- |
- private static enum CameraState {OPENING, CONFIGURING, STARTED, STOPPED} |
- private CameraState mCameraState = CameraState.STOPPED; |
- private final Object mCameraStateLock = new Object(); |
// Service function to grab CameraCharacteristics and handle exceptions. |
private static CameraCharacteristics getCameraCharacteristics(Context appContext, int id) { |
@@ -276,13 +280,6 @@ |
data[offset++] = rowData[col * pixelStride]; |
} |
} |
- } |
- } |
- |
- private void changeCameraStateAndNotify(CameraState state) { |
- synchronized (mCameraStateLock) { |
- mCameraState = state; |
- mCameraStateLock.notifyAll(); |
} |
} |
@@ -390,11 +387,9 @@ |
@Override |
public boolean allocate(int width, int height, int frameRate) { |
Log.d(TAG, "allocate: requested (%d x %d) @%dfps", width, height, frameRate); |
- synchronized (mCameraStateLock) { |
- if (mCameraState == CameraState.OPENING || mCameraState == CameraState.CONFIGURING) { |
- Log.e(TAG, "allocate() invoked while Camera is busy opening/configuring."); |
- return false; |
- } |
+ if (mOpeningCamera || mConfiguringCamera) { |
+ Log.e(TAG, "allocate() invoked while Camera is busy opening/configuring."); |
+ return false; |
} |
// |mCaptureFormat| is also used to configure the ImageReader. |
mCaptureFormat = new VideoCaptureFormat(width, height, frameRate, ImageFormat.YUV_420_888); |
@@ -416,7 +411,8 @@ |
@Override |
public boolean startCapture() { |
Log.d(TAG, "startCapture"); |
- changeCameraStateAndNotify(CameraState.OPENING); |
+ mOpeningCamera = true; |
+ mConfiguringCamera = false; |
final CameraManager manager = |
(CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE); |
final Handler mainHandler = new Handler(mContext.getMainLooper()); |
@@ -433,28 +429,13 @@ |
Log.e(TAG, "allocate: manager.openCamera: " + ex); |
return false; |
} |
- |
return true; |
} |
@Override |
public boolean stopCapture() { |
Log.d(TAG, "stopCapture"); |
- |
- // With Camera2 API, the capture is started asynchronously, which will cause problem if |
- // stopCapture comes too quickly. Without stopping the previous capture properly, the next |
- // startCapture will fail and make Chrome no-responding. So wait camera to be STARTED. |
- synchronized (mCameraStateLock) { |
- while (mCameraState != CameraState.STARTED && mCameraState != CameraState.STOPPED) { |
- try { |
- mCameraStateLock.wait(); |
- } catch (InterruptedException ex) { |
- Log.e(TAG, "CaptureStartedEvent: " + ex); |
- } |
- } |
- if (mCameraState == CameraState.STOPPED) return true; |
- } |
- |
+ if (mCaptureSession == null) return false; |
try { |
mCaptureSession.abortCaptures(); |
} catch (CameraAccessException ex) { |
@@ -469,7 +450,7 @@ |
} |
if (mCameraDevice == null) return false; |
mCameraDevice.close(); |
- changeCameraStateAndNotify(CameraState.STOPPED); |
+ |
return true; |
} |