Remove AE and AWB locks

pull/580/head
Mattia Iavarone 6 years ago
parent 04697e917d
commit 43c492e2d6
  1. 2
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java
  2. 58
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoExposure.java
  3. 26
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/metering/AutoWhiteBalance.java
  4. 40
      cameraview/src/main/java/com/otaliastudios/cameraview/picture/Snapshot2PictureRecorder.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));
}
}

@ -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,

@ -45,12 +45,6 @@ public class AutoWhiteBalance extends Parameter {
@NonNull CaptureRequest.Builder builder,
@NonNull List<MeteringRectangle> 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) {

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

Loading…
Cancel
Save