From e1e3e12564eebf887cbe0a9c6d693578b46da665 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Tue, 3 Sep 2019 21:32:53 +0200 Subject: [PATCH] Remove AF and AWB for testing --- .../cameraview/engine/Camera2Engine.java | 38 ++++++++++++++----- .../cameraview/engine/Locker.java | 19 +++++----- .../cameraview/engine/Meter.java | 23 ++++++----- .../engine/locking/AutoExposure.java | 4 ++ .../engine/metering/AutoExposure.java | 29 ++++++++++---- .../cameraview/engine/metering/AutoFocus.java | 17 ++++++--- .../engine/metering/AutoWhiteBalance.java | 4 +- .../cameraview/engine/metering/Parameter.java | 6 +-- .../picture/Snapshot2PictureRecorder.java | 23 +++++++---- 9 files changed, 107 insertions(+), 56 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 5dff35de..552860ad 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -204,6 +204,17 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv } } + private void applyRepeatingRequestBuilderAsSingle() { + if (getPreviewState() == STATE_STARTED) { + try { + mSession.capture(mRepeatingRequestBuilder.build(), + mRepeatingRequestCallback, null); + } catch (CameraAccessException e) { + throw createCameraException(e); + } + } + } + /** * Applies the repeating request builder to the preview, assuming we actually have a preview * running. Can be called after changing parameters to the builder. @@ -266,7 +277,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv Boolean aeLock = result.get(CaptureResult.CONTROL_AE_LOCK); Integer aeTriggerState = result.get(CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER); Integer afTriggerState = result.get(CaptureResult.CONTROL_AF_TRIGGER); - String log = "metering: aeMode: " + aeMode + " aeLock: " + aeLock + + String log = "aeMode: " + aeMode + " aeLock: " + aeLock + " aeState: " + aeState + " aeTriggerState: " + aeTriggerState + " afState: " + afState + " afTriggerState: " + afTriggerState; if (!log.equals(mLastLog)) { @@ -274,6 +285,9 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv LOG.w(log); } + // START + // aeMode: 3 aeLock: false aeState: 4 aeTriggerState: 0 afState: 2 afTriggerState: 0 + // // DURING metering (focus skips) // aeMode: 3 aeLock: false aeState: 4 aeTriggerState: 0 afState: 0 afTriggerState: 0 // aeMode: 3 aeLock: false aeState: 5 aeTriggerState: 1 afState: 0 afTriggerState: 0 @@ -290,8 +304,8 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv // aeMode: 1 aeLock: true aeState: 3 aeTriggerState: 1 afState: 0 afTriggerState: 0 // // Reverting flash changes + reset lock + reset metering - // aeMode: 3 aeLock: false aeState: 4 aeTriggerState: 2 afState: 2 afTriggerState: 0 - // aeMode: 3 aeLock: false aeState: 1 aeTriggerState: 2 afState: 2 afTriggerState: 0 + // aeMode: 3 aeLock: false aeState: 4 aeTriggerState: 2(1 now) afState: 2 afTriggerState: 0 + // aeMode: 3 aeLock: false aeState: 1 aeTriggerState: 2(1 now) afState: 2 afTriggerState: 0 } }; @@ -1260,8 +1274,8 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv // - AF should be on CONTROL_AF_MODE_AUTO or others // The last one is under our control because the library has no focus API. // So let's set a good af mode here. This operation is reverted during onMeteringReset(). - applyFocusForMetering(mRepeatingRequestBuilder); - applyRepeatingRequestBuilder(); + // TODO applyFocusForMetering(mRepeatingRequestBuilder); + // TODO applyRepeatingRequestBuilder(); // Create the meter and start. mMeteringGesture = gesture; @@ -1335,8 +1349,8 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv @Override public void onMeteringReset(@Nullable PointF point) { if (getEngineState() == STATE_STARTED) { - applyDefaultFocus(mRepeatingRequestBuilder); - applyRepeatingRequestBuilder(); // only if preview started already + // TODO applyDefaultFocus(mRepeatingRequestBuilder); + // TODO applyRepeatingRequestBuilder(); // only if preview started already } } @@ -1347,9 +1361,13 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv } @Override - public void onMeteringChange() { + public void onMeteringChange(boolean single) { LOG.i("onMeteringChange:", "applying the builder."); - applyRepeatingRequestBuilder(); + if (single) { + applyRepeatingRequestBuilderAsSingle(); + } else { + applyRepeatingRequestBuilder(); + } } //endregion @@ -1361,7 +1379,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv if (getEngineState() == STATE_STARTED) { mRepeatingRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false); mRepeatingRequestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, false); - applyDefaultFocus(mRepeatingRequestBuilder); + // TODO applyDefaultFocus(mRepeatingRequestBuilder); applyRepeatingRequestBuilder(); // only if preview started } } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Locker.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Locker.java index cbc17255..46450cde 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Locker.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Locker.java @@ -83,8 +83,8 @@ public class Locker { public void lock(@NonNull CaptureResult lastResult) { mIsLocking = true; mLockingStartTime = System.currentTimeMillis(); - mAutoFocus.lock(mCharacteristics, mCallback.getLockingBuilder(), lastResult); - mAutoWhiteBalance.lock(mCharacteristics, mCallback.getLockingBuilder(), lastResult); + // TODO mAutoFocus.lock(mCharacteristics, mCallback.getLockingBuilder(), lastResult); + // TODO mAutoWhiteBalance.lock(mCharacteristics, mCallback.getLockingBuilder(), lastResult); mAutoExposure.lock(mCharacteristics, mCallback.getLockingBuilder(), lastResult); } @@ -103,23 +103,22 @@ public class Locker { * but only while {@link #isLocking()} returns true. * @param result result */ - @SuppressWarnings("WeakerAccess") public void onCapture(@NonNull CaptureResult result) { if (!mIsLocking) return; // We're not interested in results anymore if (!(result instanceof TotalCaptureResult)) return; // Let's ignore these, contents are missing/wrong - if (!mAutoFocus.isLocked()) mAutoFocus.onCapture(mCallback.getLockingBuilder(), result); + // TODO if (!mAutoFocus.isLocked()) mAutoFocus.onCapture(mCallback.getLockingBuilder(), result); if (!mAutoExposure.isLocked()) mAutoExposure.onCapture(mCallback.getLockingBuilder(), result); - if (!mAutoWhiteBalance.isLocked()) mAutoWhiteBalance.onCapture(mCallback.getLockingBuilder(), result); - if (mAutoFocus.isLocked() && mAutoExposure.isLocked() && mAutoWhiteBalance.isLocked()) { + // TODO if (!mAutoWhiteBalance.isLocked()) mAutoWhiteBalance.onCapture(mCallback.getLockingBuilder(), result); + if (/* TODO mAutoFocus.isLocked() && */ mAutoExposure.isLocked() /* && mAutoWhiteBalance.isLocked() */) { LOG.i("onCapture:", "all Parameters have converged. Dispatching onMeteringEnd"); - boolean success = mAutoFocus.isSuccessful() - && mAutoExposure.isSuccessful() - && mAutoWhiteBalance.isSuccessful(); + boolean success = /* TODO mAutoFocus.isSuccessful() + && */ mAutoExposure.isSuccessful() + /* TODO && mAutoWhiteBalance.isSuccessful() */; mCallback.onLocked(success); mIsLocking = false; } else if (System.currentTimeMillis() - mLockingStartTime >= FORCED_END_DELAY) { - LOG.i("onCapture:", "FORCED_END_DELAY was reached. Some Parameter is stuck. Forcing end."); + LOG.e("onCapture:", "FORCED_END_DELAY was reached. Some Parameter is stuck. Forcing end."); mCallback.onLocked(false); mIsLocking = false; } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Meter.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Meter.java index 6cc71644..195a274d 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Meter.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Meter.java @@ -167,8 +167,8 @@ public class Meter { } // 7. And finally dispatch everything - mAutoFocus.startMetering(mCharacteristics, mCallback.getMeteringBuilder(), areas, lastResult, skipIfPossible); - mAutoWhiteBalance.startMetering(mCharacteristics, mCallback.getMeteringBuilder(), areas, lastResult, skipIfPossible); + // TODO mAutoFocus.startMetering(mCharacteristics, mCallback.getMeteringBuilder(), areas, lastResult, skipIfPossible); + // TODO mAutoWhiteBalance.startMetering(mCharacteristics, mCallback.getMeteringBuilder(), areas, lastResult, skipIfPossible); mAutoExposure.startMetering(mCharacteristics, mCallback.getMeteringBuilder(), areas, lastResult, skipIfPossible); // Dispatch to callback @@ -324,22 +324,21 @@ public class Meter { * but only while {@link #isMetering()} returns true. * @param result result */ - @SuppressWarnings("WeakerAccess") public void onCapture(@NonNull CaptureResult result) { if (!mIsMetering) return; // We're not interested in results anymore if (!(result instanceof TotalCaptureResult)) return; // Let's ignore these, contents are missing/wrong - if (!mAutoFocus.isMetered()) mAutoFocus.onCapture(mCallback.getMeteringBuilder(), result); + // TODO if (!mAutoFocus.isMetered()) mAutoFocus.onCapture(mCallback.getMeteringBuilder(), result); if (!mAutoExposure.isMetered()) mAutoExposure.onCapture(mCallback.getMeteringBuilder(), result); - if (!mAutoWhiteBalance.isMetered()) mAutoWhiteBalance.onCapture(mCallback.getMeteringBuilder(), result); - if (mAutoFocus.isMetered() && mAutoExposure.isMetered() && mAutoWhiteBalance.isMetered()) { + // TODO if (!mAutoWhiteBalance.isMetered()) mAutoWhiteBalance.onCapture(mCallback.getMeteringBuilder(), result); + if (/* TODO mAutoFocus.isMetered() && */ mAutoExposure.isMetered() /* && mAutoWhiteBalance.isMetered() */) { LOG.i("onCapture:", "all Parameters have converged. Dispatching onMeteringEnd"); - boolean success = mAutoFocus.isSuccessful() - && mAutoExposure.isSuccessful() - && mAutoWhiteBalance.isSuccessful(); + boolean success = /* TODO mAutoFocus.isSuccessful() + && */ mAutoExposure.isSuccessful() + /* TODO && mAutoWhiteBalance.isSuccessful() */; onMeteringEnd(success); } else if (System.currentTimeMillis() - mMeteringStartTime >= FORCED_END_DELAY) { - LOG.i("onCapture:", "FORCED_END_DELAY was reached. Some Parameter is stuck. Forcing end."); + LOG.e("onCapture:", "FORCED_END_DELAY was reached. Some Parameter is stuck. Forcing end."); onMeteringEnd(false); } } @@ -362,8 +361,8 @@ public class Meter { if (wholeRect == null) wholeRect = new Rect(); whole = new MeteringRectangle(wholeRect, MeteringRectangle.METERING_WEIGHT_DONT_CARE); } - mAutoFocus.resetMetering(mCharacteristics, mCallback.getMeteringBuilder(), whole); - mAutoWhiteBalance.resetMetering(mCharacteristics, mCallback.getMeteringBuilder(), whole); + // TODO mAutoFocus.resetMetering(mCharacteristics, mCallback.getMeteringBuilder(), whole); + // TODO mAutoWhiteBalance.resetMetering(mCharacteristics, mCallback.getMeteringBuilder(), whole); mAutoExposure.resetMetering(mCharacteristics, mCallback.getMeteringBuilder(), whole); mCallback.onMeteringReset(mPoint); } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/locking/AutoExposure.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/locking/AutoExposure.java index 4254ccf3..12b386fe 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/locking/AutoExposure.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/locking/AutoExposure.java @@ -51,6 +51,10 @@ public class AutoExposure extends Parameter { @Override protected void onLock(@NonNull CameraCharacteristics characteristics, @NonNull CaptureRequest.Builder builder) { + int cancelTrigger = Build.VERSION.SDK_INT >= 23 + ? CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL + : CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; + builder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, cancelTrigger); builder.set(CaptureRequest.CONTROL_AE_LOCK, true); notifyBuilderChanged(); } 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 a630bbb1..8130e416 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 @@ -79,7 +79,7 @@ public class AutoExposure extends Parameter { } if (changed) { - notifyBuilderChanged(); + notifyBuilderChanged(false); // 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, @@ -147,7 +147,13 @@ public class AutoExposure extends Parameter { @Override protected void onMetered(@NonNull CaptureRequest.Builder builder, boolean success) { - // Do nothing + // Undo the trigger. + /* TODO thinking about it. int newTrigger = Build.VERSION.SDK_INT >= 23 + ? CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL + : CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; */ + builder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, null); + // builder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE); + // notifyBuilderChanged(); } @Override @@ -163,15 +169,24 @@ public class AutoExposure extends Parameter { changed = true; } if (supportsProcessing) { - // Cleanup any precapture sequence. - if (Build.VERSION.SDK_INT >= 23) { - builder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, - CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL); + Integer trigger = builder.get(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER); + LOG.w("onResetMetering:", "current precapture trigger is", trigger); + if (trigger == null || trigger == CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START) { + // Undo the trigger. This might happen if we can't meter in time / reset called before. + LOG.w("onResetMetering:", "canceling precapture."); + int newTrigger = Build.VERSION.SDK_INT >= 23 + ? CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL + : CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; + builder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, newTrigger); + + builder.set(CaptureRequest.CONTROL_AE_LOCK, true); + notifyBuilderChanged(true); + builder.set(CaptureRequest.CONTROL_AE_LOCK, false); changed = true; } } if (changed) { - notifyBuilderChanged(); + notifyBuilderChanged(false); } } } 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 736950c7..cc378955 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 @@ -70,7 +70,7 @@ public class AutoFocus extends Parameter { } if (changed) { - notifyBuilderChanged(); + notifyBuilderChanged(false); // Remove any problematic control for future requests /* builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_IDLE); */ @@ -99,7 +99,10 @@ public class AutoFocus extends Parameter { @Override protected void onMetered(@NonNull CaptureRequest.Builder builder, boolean success) { - // Do nothing. + // TODO thinking about this + builder.set(CaptureRequest.CONTROL_AF_TRIGGER, null); + // builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL); + // notifyBuilderChanged(); } @Override @@ -116,11 +119,15 @@ public class AutoFocus extends Parameter { } if (supportsProcessing) { // Cleanup any trigger. - builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL); - changed = true; + Integer trigger = builder.get(CaptureRequest.CONTROL_AF_TRIGGER); + LOG.w("onResetMetering:", "current focus trigger is", trigger); + if (trigger == null || trigger == CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START) { + builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL); + changed = true; + } } if (changed) { - notifyBuilderChanged(); + notifyBuilderChanged(false); } } } 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 94d47c60..41abfd2a 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 @@ -55,7 +55,7 @@ public class AutoWhiteBalance extends Parameter { int max = Math.min(maxRegions, areas.size()); builder.set(CaptureRequest.CONTROL_AWB_REGIONS, areas.subList(0, max).toArray(new MeteringRectangle[]{})); - notifyBuilderChanged(); + notifyBuilderChanged(false); } } @@ -97,7 +97,7 @@ public class AutoWhiteBalance extends Parameter { CameraCharacteristics.CONTROL_MAX_REGIONS_AWB, 0); if (area != null && maxRegions > 0) { builder.set(CaptureRequest.CONTROL_AWB_REGIONS, new MeteringRectangle[]{area}); - notifyBuilderChanged(); + notifyBuilderChanged(false); } } } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/Parameter.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/Parameter.java index 6f407a7d..53592e7f 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/Parameter.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/Parameter.java @@ -16,7 +16,7 @@ import java.util.List; public abstract class Parameter { public interface MeteringChangeCallback { - void onMeteringChange(); + void onMeteringChange(boolean single); } private boolean isSuccessful; @@ -39,8 +39,8 @@ public abstract class Parameter { } @SuppressWarnings("WeakerAccess") - protected void notifyBuilderChanged() { - callback.onMeteringChange(); + protected void notifyBuilderChanged(boolean single) { + callback.onMeteringChange(single); } @SuppressWarnings("WeakerAccess") 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 31753397..41f94506 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.java @@ -83,7 +83,8 @@ public class Snapshot2PictureRecorder extends SnapshotGlPictureRecorder implemen @Override public void take() { - if (!mActionNeeded) { + // TODO + if (true || !mActionNeeded) { LOG.i("take:", "Engine does no metering or needs no flash, taking fast snapshot."); super.take(); } else { @@ -120,10 +121,17 @@ public class Snapshot2PictureRecorder extends SnapshotGlPictureRecorder implemen @Override public void onLocked(boolean success) { LOG.i("onLocked:", "Parameters locked, 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); - applyBuilder(); + if (false) { + mState = STATE_WAITING_TORCH; + mBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH); + mBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); + applyBuilder(); + } else { + // TODO + LOG.e("Early taking image."); + mState = STATE_WAITING_IMAGE; + super.take(); + } } public void onCaptureCompleted(@NonNull TotalCaptureResult result) { @@ -151,9 +159,10 @@ public class Snapshot2PictureRecorder extends SnapshotGlPictureRecorder implemen @Override protected void dispatchResult() { - if (mState == STATE_WAITING_IMAGE) { + // TODO + if (false && mState == STATE_WAITING_IMAGE) { // Revert our changes. - LOG.i("dispatchResult:", "Reverting the capture intent changes."); + LOG.i("dispatchResult:", "Reverting the flash changes."); try { // See Camera2Engine.setFlash() comments: turning TORCH off has bugs and we must do // as follows.