From e1139e4ecbcacfd953479c5ec4f0f846e3e5d97b Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Sun, 1 Sep 2019 17:16:04 +0200 Subject: [PATCH] Fix AutoExposure metering --- .../cameraview/engine/Camera2Engine.java | 4 ++++ .../engine/metering/AutoExposure.java | 20 +++++++++++++------ .../cameraview/engine/metering/AutoFocus.java | 5 +++-- .../picture/Snapshot2PictureRecorder.java | 12 +++++++---- 4 files changed, 29 insertions(+), 12 deletions(-) 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 6bce83a8..7e2cfe6b 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -251,6 +251,9 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv if (mMeter != null && mMeter.isMetering()) { mMeter.onCapture(result); } + Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); + Integer aeTriggerState = result.get(CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER); + LOG.i("metering:", "aeState:", aeState, "aeTriggerState:", aeTriggerState); } }; @@ -1291,6 +1294,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv @Override public void onMeteringChange() { + LOG.i("onMeteringChange:", "applying the builder."); applyRepeatingRequestBuilder(); } 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 cf80b521..2d40faff 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 @@ -78,10 +78,12 @@ public class AutoExposure extends Parameter { changed = true; } - // Notify change and remove any problematic control for future request if (changed) { notifyBuilderChanged(); - builder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, null); + // Remove any problematic control for future requests + // NOTE: activating this invalidates the logic for early exit in processCapture + /* builder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, + CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE); */ } } @@ -89,7 +91,8 @@ public class AutoExposure extends Parameter { @Override public void processCapture(@NonNull CaptureResult result) { Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE); - LOG.i("onCapture:", "aeState:", aeState); + Integer aeTriggerState = result.get(CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER); + LOG.i("onCapture:", "aeState:", aeState, "aeTriggerState:", aeTriggerState); if (aeState == null) return; if (!isStarted) { @@ -100,9 +103,14 @@ public class AutoExposure extends Parameter { } 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; + // PRECAPTURE is a transient state. Being here might mean that precapture run + // and was successful, OR that the trigger was not even received yet. To + // distinguish, check the trigger state. + if (aeTriggerState != null + && aeTriggerState == CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER_START) { + isMetered = true; + isSuccessful = true; + } break; } case CaptureResult.CONTROL_AE_STATE_LOCKED: { diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoFocus.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoFocus.java index 129321f6..739e7722 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoFocus.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoFocus.java @@ -69,10 +69,11 @@ public class AutoFocus extends Parameter { changed = true; } - // Notify change and remove any problematic control for future request if (changed) { notifyBuilderChanged(); - builder.set(CaptureRequest.CONTROL_AF_TRIGGER, null); + // Remove any problematic control for future requests + /* builder.set(CaptureRequest.CONTROL_AF_TRIGGER, + CaptureRequest.CONTROL_AF_TRIGGER_IDLE); */ } } 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 7f3e17c4..c7439f0f 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java @@ -112,11 +112,15 @@ public class Snapshot2PictureRecorder extends SnapshotGlPictureRecorder { mNeedsFlash = aeState != null && aeState == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED; LOG.i("onCaptureCompleted:", "aeState:", aeState, "needsFlash:", mNeedsFlash); mState = STATE_WAITING_LOCK; + // Removing any ongoing precapture or trigger. This should not be needed. - // if (Build.VERSION.SDK_INT >= 23) { - // mBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL); - // } - // mBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL); + if (Build.VERSION.SDK_INT >= 23) { + mBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, + CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL); + } + mBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, + CaptureRequest.CONTROL_AF_TRIGGER_CANCEL); + // Lock AE, AWB, AF to their current values mBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true); mBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);