Unlock inside Camera2Engine

pull/580/head
Mattia Iavarone 6 years ago
parent edf4950056
commit 5e66e6d560
  1. 58
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java
  2. 37
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Locker.java
  3. 7
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/locking/AutoExposure.java
  4. 16
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/locking/AutoFocus.java
  5. 6
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/locking/AutoWhiteBalance.java
  6. 16
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/locking/Parameter.java

@ -1244,10 +1244,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
private final Runnable mMeteringResetRunnable = new Runnable() {
@Override
public void run() {
if (mLocker != null) {
mLocker.unlock();
mLocker = null;
}
unlockMetering();
if (mMeter != null) {
mMeter.resetMetering();
mMeter = null;
@ -1282,8 +1279,7 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
"gesture:", mMeteringGesture,
"needsFlash:", mMeteringNeedsFlash,
"success:", success);
mLocker = new Locker(mCameraCharacteristics, this);
mLocker.lock(mLastRepeatingResult, point);
lockMetering(point);
}
/**
@ -1300,9 +1296,42 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
}
}
@NonNull
@Override
public CaptureRequest.Builder getMeteringBuilder() {
return mRepeatingRequestBuilder;
}
@Override
public void onMeteringChange() {
LOG.i("onMeteringChange:", "applying the builder.");
applyRepeatingRequestBuilder();
}
//endregion
//region 3A Locking
private void unlockMetering() {
if (getEngineState() == STATE_STARTED) {
mRepeatingRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
mRepeatingRequestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, false);
applyDefaultFocus(mRepeatingRequestBuilder);
applyRepeatingRequestBuilder(); // only if preview started
}
}
private void lockMetering(@Nullable PointF point) {
if (getPreviewState() == STATE_STARTED) {
mLocker = new Locker(mCameraCharacteristics, this);
mLocker.lock(mLastRepeatingResult, point);
}
}
@Override
public void onLocked(@Nullable PointF point, boolean success) {
LOG.w("onLocked - point:", point, "gesture:", mMeteringGesture, "success:", success);
mLocker = null;
if (point != null) {
mCallback.dispatchOnFocusEnd(mMeteringGesture, success, point);
mHandler.remove(mMeteringResetRunnable);
@ -1321,23 +1350,6 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
}
}
@Override
public void onUnlocked(@Nullable PointF point) {
// Nothing to do.
}
@NonNull
@Override
public CaptureRequest.Builder getMeteringBuilder() {
return mRepeatingRequestBuilder;
}
@Override
public void onMeteringChange() {
LOG.i("onMeteringChange:", "applying the builder.");
applyRepeatingRequestBuilder();
}
@NonNull
@Override
public CaptureRequest.Builder getLockingBuilder() {

@ -23,8 +23,7 @@ import com.otaliastudios.cameraview.engine.locking.Parameter;
*
* - Call {@link #lock(CaptureResult, PointF)} to start
* - Call {@link #onCapture(CaptureResult)} when they have partial or total results, as long as the
* locker is still in a locking operation, which can be checked through {@link #isLocking()} ()}
* - Call {@link #unlock()} to reset the locked parameters if needed.
* locker is still in a locking operation, which can be checked through {@link #isLocking()}
*/
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public class Locker {
@ -42,14 +41,6 @@ public class Locker {
*/
void onLocked(@Nullable PointF point, boolean success);
/**
* Notifies that locking has been undone. From now on, this locker instance
* is done, although in theory it could be reused by calling
* {@link #lock(CaptureResult, PointF)} again.
* @param point point
*/
void onUnlocked(@Nullable PointF point);
/**
* Returns the currently used builder. This can change while a locking
* operation happens, so the locker will never cache this value.
@ -95,7 +86,6 @@ public class Locker {
* @param lastResult the last result
* @param point a point
*/
@SuppressWarnings("WeakerAccess")
public void lock(@NonNull CaptureResult lastResult, @Nullable PointF point) {
mIsLocking = true;
mPoint = point;
@ -133,29 +123,12 @@ public class Locker {
boolean success = mAutoFocus.isSuccessful()
&& mAutoExposure.isSuccessful()
&& mAutoWhiteBalance.isSuccessful();
dispatchEnd(success);
mCallback.onLocked(mPoint, 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.");
dispatchEnd(false);
mCallback.onLocked(mPoint, false);
mIsLocking = false;
}
}
private void dispatchEnd(boolean success) {
mCallback.onLocked(mPoint, success);
mIsLocking = false;
}
/**
* Should be called to unlock.
* Note that {@link Callback#onUnlocked(PointF)} will be called immediately,
* we're not waiting for the results.
*/
@SuppressWarnings("WeakerAccess")
public void unlock() {
LOG.i("Unlocking.");
mAutoFocus.unlock(mCharacteristics, mCallback.getLockingBuilder());
mAutoExposure.unlock(mCharacteristics, mCallback.getLockingBuilder());
mAutoWhiteBalance.unlock(mCharacteristics, mCallback.getLockingBuilder());
mCallback.onUnlocked(mPoint);
}
}

@ -81,11 +81,4 @@ public class AutoExposure extends Parameter {
protected void onLocked(@NonNull CaptureRequest.Builder builder) {
// Do nothing
}
@Override
protected void onUnlock(@NonNull CameraCharacteristics characteristics,
@NonNull CaptureRequest.Builder builder) {
builder.set(CaptureRequest.CONTROL_AE_LOCK, false);
notifyBuilderChanged();
}
}

@ -6,21 +6,16 @@ import android.hardware.camera2.CaptureResult;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.otaliastudios.cameraview.CameraLogger;
import java.util.List;
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public class AutoFocus extends Parameter {
private static final String TAG = AutoFocus.class.getSimpleName();
private static final CameraLogger LOG = CameraLogger.create(TAG);
private Integer oldAfMode;
public AutoFocus(@NonNull LockingChangeCallback callback) {
super(callback);
}
@ -46,8 +41,8 @@ public class AutoFocus extends Parameter {
boolean afStateOk = afState != null &&
(afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
oldAfMode = lastResult.get(CaptureResult.CONTROL_AF_MODE);
boolean afModeOk = oldAfMode != null && oldAfMode == CaptureResult.CONTROL_AF_MODE_AUTO;
Integer afMode = lastResult.get(CaptureResult.CONTROL_AF_MODE);
boolean afModeOk = afMode != null && afMode == CaptureResult.CONTROL_AF_MODE_AUTO;
boolean result = afStateOk && afModeOk;
LOG.i("checkShouldSkip:", result);
return result;
@ -91,11 +86,4 @@ public class AutoFocus extends Parameter {
// Do nothing.
}
@Override
protected void onUnlock(@NonNull CameraCharacteristics characteristics,
@NonNull CaptureRequest.Builder builder) {
builder.set(CaptureRequest.CONTROL_AF_MODE, oldAfMode);
notifyBuilderChanged();
}
}

@ -71,10 +71,4 @@ public class AutoWhiteBalance extends Parameter {
protected void onLocked(@NonNull CaptureRequest.Builder builder) {
// Do nothing
}
@Override
protected void onUnlock(@NonNull CameraCharacteristics characteristics, @NonNull CaptureRequest.Builder builder) {
builder.set(CaptureRequest.CONTROL_AWB_LOCK, false);
notifyBuilderChanged();
}
}

@ -3,11 +3,9 @@ package com.otaliastudios.cameraview.engine.locking;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.params.MeteringRectangle;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import java.util.List;
@ -19,7 +17,6 @@ public abstract class Parameter {
void onLockingChange();
}
@SuppressWarnings("WeakerAccess")
protected boolean isSuccessful;
@SuppressWarnings("WeakerAccess")
@ -29,7 +26,6 @@ public abstract class Parameter {
private boolean shouldSkip;
private boolean supportsLocking;
@SuppressWarnings("WeakerAccess")
protected Parameter(@NonNull LockingChangeCallback callback) {
this.callback = callback;
}
@ -77,15 +73,6 @@ public abstract class Parameter {
if (isLocked()) onLocked(builder);
}
public final void unlock(@NonNull CameraCharacteristics characteristics,
@NonNull CaptureRequest.Builder builder) {
if (supportsLocking) {
// Not checking shouldSkip. Though we skipped locking, we're
// now asked to unlock, so do it.
onUnlock(characteristics, builder);
}
}
protected abstract boolean checkSupportsLocking(@NonNull CameraCharacteristics characteristics,
@NonNull CaptureRequest.Builder builder);
@ -97,7 +84,4 @@ public abstract class Parameter {
protected abstract void processCapture(@NonNull CaptureResult result);
protected abstract void onLocked(@NonNull CaptureRequest.Builder builder);
protected abstract void onUnlock(@NonNull CameraCharacteristics characteristics,
@NonNull CaptureRequest.Builder builder);
}

Loading…
Cancel
Save