| 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;
|
| }
|
|
|
|
|