diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java index acc2011a..582ef5b8 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -816,8 +816,6 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv builder.set(CaptureRequest.CONTROL_AF_REGIONS, oldBuilder.get(CaptureRequest.CONTROL_AF_REGIONS)); builder.set(CaptureRequest.CONTROL_AE_REGIONS, oldBuilder.get(CaptureRequest.CONTROL_AE_REGIONS)); builder.set(CaptureRequest.CONTROL_AWB_REGIONS, oldBuilder.get(CaptureRequest.CONTROL_AWB_REGIONS)); - builder.set(CaptureRequest.CONTROL_AE_LOCK, oldBuilder.get(CaptureRequest.CONTROL_AE_LOCK)); - builder.set(CaptureRequest.CONTROL_AWB_LOCK, oldBuilder.get(CaptureRequest.CONTROL_AWB_LOCK)); builder.set(CaptureRequest.CONTROL_AF_MODE, oldBuilder.get(CaptureRequest.CONTROL_AF_MODE)); } } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoExposure.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoExposure.java index 1ff25756..c066cf20 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoExposure.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoExposure.java @@ -57,8 +57,6 @@ public class AutoExposure extends Parameter { isStarted = false; if (supportsProcessing) { - // Remove any lock. This would make processing be stuck into the process method. - builder.set(CaptureRequest.CONTROL_AE_LOCK, false); // Launch the precapture trigger. builder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); @@ -82,26 +80,57 @@ public class AutoExposure extends Parameter { if (aeState == null) return; if (!isStarted) { - if (aeState == CaptureRequest.CONTROL_AE_STATE_PRECAPTURE) { - isStarted = true; - } else if (aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED - || aeState == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED) { - // PRECAPTURE is a transient state, so also check for the final states. - isMetered = true; - isSuccessful = true; + switch (aeState) { + case CaptureResult.CONTROL_AE_STATE_PRECAPTURE: { + isStarted = true; + break; + } + case CaptureResult.CONTROL_AE_STATE_CONVERGED: + case CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED: { + // PRECAPTURE is a transient state, so also check for the final states. + isMetered = true; + isSuccessful = true; + break; + } + case CaptureResult.CONTROL_AE_STATE_LOCKED: { + // There's nothing we can do, AE was locked, triggers are ignored. + isMetered = true; + isSuccessful = false; + break; + } + case CaptureResult.CONTROL_AE_STATE_INACTIVE: + case CaptureResult.CONTROL_AE_STATE_SEARCHING: { + // Wait... + break; + } } } else { - if (aeState == CaptureRequest.CONTROL_AE_STATE_CONVERGED - || aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) { - isMetered = true; - isSuccessful = true; + switch (aeState) { + case CaptureResult.CONTROL_AE_STATE_CONVERGED: + case CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED: { + isMetered = true; + isSuccessful = true; + break; + } + case CaptureResult.CONTROL_AE_STATE_LOCKED: { + // There's nothing we can do, AE was locked, triggers are ignored. + isMetered = true; + isSuccessful = false; + break; + } + case CaptureResult.CONTROL_AE_STATE_PRECAPTURE: + case CaptureResult.CONTROL_AE_STATE_INACTIVE: + case CaptureResult.CONTROL_AE_STATE_SEARCHING: { + // Wait... + break; + } } } } @Override protected void onMetered(@NonNull CaptureRequest.Builder builder) { - builder.set(CaptureRequest.CONTROL_AE_LOCK, true); + // Do nothing } @Override @@ -115,7 +144,6 @@ public class AutoExposure extends Parameter { builder.set(CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[]{area}); } if (supportsProcessing) { - builder.set(CaptureRequest.CONTROL_AE_LOCK, false); // Cleanup any precapture sequence. if (Build.VERSION.SDK_INT >= 23) { builder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoWhiteBalance.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoWhiteBalance.java index 58b34b87..86d5a3c6 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoWhiteBalance.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoWhiteBalance.java @@ -45,12 +45,6 @@ public class AutoWhiteBalance extends Parameter { @NonNull CaptureRequest.Builder builder, @NonNull List areas, boolean supportsProcessing) { - if (supportsProcessing) { - // Remove any lock. This would make processing be stuck into the process method. - builder.set(CaptureRequest.CONTROL_AWB_LOCK, false); - } - - // Even if auto is not supported, change the regions anyway. int maxRegions = readCharacteristic(characteristics, CameraCharacteristics.CONTROL_MAX_REGIONS_AWB, 0); if (!areas.isEmpty() && maxRegions > 0) { @@ -72,16 +66,23 @@ public class AutoWhiteBalance extends Parameter { isSuccessful = true; break; } - case CaptureRequest.CONTROL_AWB_STATE_LOCKED: break; - case CaptureRequest.CONTROL_AWB_STATE_INACTIVE: break; - case CaptureRequest.CONTROL_AWB_STATE_SEARCHING: break; - default: break; + case CaptureRequest.CONTROL_AWB_STATE_LOCKED: { + // Nothing we can do if AWB was locked. + isMetered = true; + isSuccessful = false; + break; + } + case CaptureRequest.CONTROL_AWB_STATE_INACTIVE: + case CaptureRequest.CONTROL_AWB_STATE_SEARCHING: { + // Wait... + break; + } } } @Override protected void onMetered(@NonNull CaptureRequest.Builder builder) { - builder.set(CaptureRequest.CONTROL_AWB_LOCK, true); + // Do nothing } @Override @@ -89,9 +90,6 @@ public class AutoWhiteBalance extends Parameter { @NonNull CaptureRequest.Builder builder, @Nullable MeteringRectangle area, boolean supportsProcessing) { - if (supportsProcessing) { - builder.set(CaptureRequest.CONTROL_AWB_LOCK, false); - } int maxRegions = readCharacteristic(characteristics, CameraCharacteristics.CONTROL_MAX_REGIONS_AWB, 0); if (area != null && maxRegions > 0) { diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java index 364a8025..2036ced9 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java @@ -97,27 +97,30 @@ public class Snapshot2PictureRecorder extends SnapshotGlPictureRecorder { if (mState == STATE_WAITING_FIRST_FRAME) { Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); if (aeState == null) { - LOG.w("onCaptureCompleted:", "aeState is null! This should never happen. Taking snapshot."); + LOG.w("onCaptureCompleted:", "aeState is null! This should never happen.", + "Taking snapshot."); mState = STATE_WAITING_IMAGE; super.take(); - } else if (aeState == CaptureRequest.CONTROL_AE_STATE_CONVERGED) { + } else if (aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) { LOG.i("onCaptureCompleted:", "aeState is optimal. Taking snapshot."); mState = STATE_WAITING_IMAGE; super.take(); + } else if (aeState == CaptureResult.CONTROL_AE_STATE_LOCKED) { + LOG.i("onCaptureCompleted:", "aeState is locked. There's nothing we can do.", + "Taking snapshot with no flash."); + mState = STATE_WAITING_IMAGE; + super.take(); } else if (aeState != CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) { - LOG.w("onCaptureCompleted:", "aeState is not CONVERGED yet not FLASH_REQUIRED.", + LOG.w("onCaptureCompleted:", "aeState is not CONVERGED, FLASH_REQUIRED or LOCKED.", aeState, "This seems to say that metering did not complete before. Let's take the snapshot."); - // TODO the metering system might set AE to LOCKED. what to do in this case? mState = STATE_WAITING_IMAGE; super.take(); } else { // Open the torch. AE_MODE_ON is guaranteed to be supported. - // Remove any AE lock that was set by the engine. LOG.w("onCaptureCompleted:", "aeState is FLASH_REQUIRED. Opening torch."); mState = STATE_WAITING_TORCH; mBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH); mBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); - mBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false); try { mSession.setRepeatingRequest(mBuilder.build(), mCallback, null); } catch (CameraAccessException e) { @@ -143,13 +146,30 @@ public class Snapshot2PictureRecorder extends SnapshotGlPictureRecorder { } else if (mState == STATE_WAITING_TORCH_EXPOSURE) { Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); - if (aeState != null && (aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED - || aeState == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED)) { - LOG.i("onCaptureCompleted:", "We have torch and good torch exposure.", aeState); + if (aeState == null) { + LOG.w("onCaptureCompleted:", "aeState is null! Taking snasphot."); mState = STATE_WAITING_IMAGE; super.take(); } else { - LOG.i("onCaptureCompleted:", "Waiting for torch exposure...:", aeState); + switch (aeState) { + case CaptureResult.CONTROL_AE_STATE_CONVERGED: + case CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED: { + LOG.i("onCaptureCompleted:", "We have torch and good torch exposure.", aeState); + mState = STATE_WAITING_IMAGE; + super.take(); + break; + } + case CaptureResult.CONTROL_AE_STATE_LOCKED: { + LOG.w("onCaptureCompleted:", "Final aeState is LOCKED. Should not happen."); + mState = STATE_WAITING_IMAGE; + super.take(); + break; + } + default: { + LOG.i("onCaptureCompleted:", "Waiting for torch exposure...:", aeState); + break; + } + } } } }