aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorTimothy Knight <tknight@google.com>2014-10-11 21:13:30 -0700
committerTimothy Knight <tknight@google.com>2014-10-11 21:59:30 -0700
commit172ab2b9724d397daad6fdb8a34773f7a4022aa2 (patch)
treead9c8d3124747e12b8d63bda236ef39f76c3a655 /apps
parent5093c19aad3a02c6714082e72fbda39e801870a1 (diff)
downloadpdk-172ab2b9724d397daad6fdb8a34773f7a4022aa2.tar.gz
CameraITS: Plumbed 3A locking through to do_3a
Change-Id: I75dd8a37c5a27dc165822c9df7065c538cb30946
Diffstat (limited to 'apps')
-rw-r--r--apps/CameraITS/pymodules/its/device.py12
-rw-r--r--apps/CameraITS/service/src/com/android/camera2/its/ItsService.java46
-rw-r--r--apps/CameraITS/tests/scene1/test_burst_sameness_auto_fullres.py19
3 files changed, 64 insertions, 13 deletions
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
index 3134b47..2cefad1 100644
--- a/apps/CameraITS/pymodules/its/device.py
+++ b/apps/CameraITS/pymodules/its/device.py
@@ -254,7 +254,8 @@ class ItsSession(object):
def do_3a(self, regions_ae=[[0,0,1,1,1]],
regions_awb=[[0,0,1,1,1]],
regions_af=[[0,0,1,1,1]],
- do_ae=True, do_awb=True, do_af=True):
+ do_ae=True, do_awb=True, do_af=True,
+ lock_ae=False, lock_awb=False):
"""Perform a 3A operation on the device.
Triggers some or all of AE, AWB, and AF, and returns once they have
@@ -266,6 +267,11 @@ class ItsSession(object):
regions_ae: List of weighted AE regions.
regions_awb: List of weighted AWB regions.
regions_af: List of weighted AF regions.
+ do_ae: Trigger AE and wait for it to converge.
+ do_awb: Wait for AWB to converge.
+ do_af: Trigger AF and wait for it to converge.
+ lock_ae: Request AE lock after convergence, and wait for it.
+ lock_awb: Request AWB lock after convergence, and wait for it.
Region format in args:
Arguments are lists of weighted regions; each weighted region is a
@@ -290,6 +296,10 @@ class ItsSession(object):
"awb": sum(regions_awb, []),
"af": sum(regions_af, [])}
cmd["triggers"] = {"ae": do_ae, "af": do_af}
+ if lock_ae:
+ cmd["aeLock"] = True
+ if lock_awb:
+ cmd["awbLock"] = True
self.sock.send(json.dumps(cmd) + "\n")
# Wait for each specified 3A to converge.
diff --git a/apps/CameraITS/service/src/com/android/camera2/its/ItsService.java b/apps/CameraITS/service/src/com/android/camera2/its/ItsService.java
index d7e2525..5d8ba28 100644
--- a/apps/CameraITS/service/src/com/android/camera2/its/ItsService.java
+++ b/apps/CameraITS/service/src/com/android/camera2/its/ItsService.java
@@ -106,6 +106,8 @@ public class ItsService extends Service implements SensorEventListener {
public static final String REGION_AE_KEY = "ae";
public static final String REGION_AWB_KEY = "awb";
public static final String REGION_AF_KEY = "af";
+ public static final String LOCK_AE_KEY = "aeLock";
+ public static final String LOCK_AWB_KEY = "awbLock";
public static final String TRIGGER_KEY = "triggers";
public static final String TRIGGER_AE_KEY = "ae";
public static final String TRIGGER_AF_KEY = "af";
@@ -154,6 +156,10 @@ public class ItsService extends Service implements SensorEventListener {
private volatile boolean mConvergedAE = false;
private volatile boolean mConvergedAF = false;
private volatile boolean mConvergedAWB = false;
+ private volatile boolean mLockedAE = false;
+ private volatile boolean mLockedAWB = false;
+ private volatile boolean mNeedsLockedAE = false;
+ private volatile boolean mNeedsLockedAWB = false;
class MySensorEvent {
public Sensor sensor;
@@ -788,6 +794,11 @@ public class ItsService extends Service implements SensorEventListener {
}
}
+ // If AE or AWB lock is specified, then the 3A will converge first and then lock these
+ // values, waiting until the HAL has reported that the lock was successful.
+ mNeedsLockedAE = params.optBoolean(LOCK_AE_KEY, false);
+ mNeedsLockedAWB = params.optBoolean(LOCK_AWB_KEY, false);
+
// By default, AE and AF both get triggered, but the user can optionally override this.
// Also, AF won't get triggered if the lens is fixed-focus.
boolean doAE = true;
@@ -815,10 +826,15 @@ public class ItsService extends Service implements SensorEventListener {
mConvergedAE = false;
mConvergedAWB = false;
mConvergedAF = false;
+ mLockedAE = false;
+ mLockedAWB = false;
long tstart = System.currentTimeMillis();
boolean triggeredAE = false;
boolean triggeredAF = false;
+ Logt.i(TAG, String.format("Initiating 3A: AE:%d, AF:%d, AWB:1, AELOCK:%d, AWBLOCK:%d",
+ doAE?1:0, doAF?1:0, mNeedsLockedAE?1:0, mNeedsLockedAWB?1:0));
+
// Keep issuing capture requests until 3A has converged.
while (true) {
@@ -831,8 +847,11 @@ public class ItsService extends Service implements SensorEventListener {
mInterlock3A.close();
// If not converged yet, issue another capture request.
- if ((doAE && (!triggeredAE || !mConvergedAE)) || !mConvergedAWB ||
- (doAF && (!triggeredAF || !mConvergedAF))) {
+ if ( (doAE && (!triggeredAE || !mConvergedAE))
+ || !mConvergedAWB
+ || (doAF && (!triggeredAF || !mConvergedAF))
+ || (doAE && mNeedsLockedAE && !mLockedAE)
+ || (mNeedsLockedAWB && !mLockedAWB)) {
// Baseline capture request for 3A.
CaptureRequest.Builder req = mCamera.createCaptureRequest(
@@ -854,6 +873,13 @@ public class ItsService extends Service implements SensorEventListener {
req.set(CaptureRequest.CONTROL_AWB_LOCK, false);
req.set(CaptureRequest.CONTROL_AWB_REGIONS, regionAWB);
+ if (mConvergedAE && mNeedsLockedAE) {
+ req.set(CaptureRequest.CONTROL_AE_LOCK, true);
+ }
+ if (mConvergedAWB && mNeedsLockedAWB) {
+ req.set(CaptureRequest.CONTROL_AWB_LOCK, true);
+ }
+
// Trigger AE first.
if (doAE && !triggeredAE) {
Logt.i(TAG, "Triggering AE");
@@ -1192,7 +1218,11 @@ public class ItsService extends Service implements SensorEventListener {
mConvergedAE = result.get(CaptureResult.CONTROL_AE_STATE) ==
CaptureResult.CONTROL_AE_STATE_CONVERGED ||
result.get(CaptureResult.CONTROL_AE_STATE) ==
- CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED;
+ CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED ||
+ result.get(CaptureResult.CONTROL_AE_STATE) ==
+ CaptureResult.CONTROL_AE_STATE_LOCKED;
+ mLockedAE = result.get(CaptureResult.CONTROL_AE_STATE) ==
+ CaptureResult.CONTROL_AE_STATE_LOCKED;
}
if (result.get(CaptureResult.CONTROL_AF_STATE) != null) {
mConvergedAF = result.get(CaptureResult.CONTROL_AF_STATE) ==
@@ -1200,10 +1230,14 @@ public class ItsService extends Service implements SensorEventListener {
}
if (result.get(CaptureResult.CONTROL_AWB_STATE) != null) {
mConvergedAWB = result.get(CaptureResult.CONTROL_AWB_STATE) ==
- CaptureResult.CONTROL_AWB_STATE_CONVERGED;
+ CaptureResult.CONTROL_AWB_STATE_CONVERGED ||
+ result.get(CaptureResult.CONTROL_AWB_STATE) ==
+ CaptureResult.CONTROL_AWB_STATE_LOCKED;
+ mLockedAWB = result.get(CaptureResult.CONTROL_AWB_STATE) ==
+ CaptureResult.CONTROL_AWB_STATE_LOCKED;
}
- if (mConvergedAE) {
+ if (mConvergedAE && (!mNeedsLockedAE || mLockedAE)) {
mSocketRunnableObj.sendResponse("aeResult", String.format("%d %d",
result.get(CaptureResult.SENSOR_SENSITIVITY).intValue(),
result.get(CaptureResult.SENSOR_EXPOSURE_TIME).intValue()
@@ -1216,7 +1250,7 @@ public class ItsService extends Service implements SensorEventListener {
));
}
- if (mConvergedAWB) {
+ if (mConvergedAWB && (!mNeedsLockedAWB || mLockedAWB)) {
if (result.get(CaptureResult.COLOR_CORRECTION_GAINS) != null
&& result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM) != null) {
mSocketRunnableObj.sendResponse("awbResult", String.format(
diff --git a/apps/CameraITS/tests/scene1/test_burst_sameness_auto_fullres.py b/apps/CameraITS/tests/scene1/test_burst_sameness_auto_fullres.py
index 6955ad8..a8d1d45 100644
--- a/apps/CameraITS/tests/scene1/test_burst_sameness_auto_fullres.py
+++ b/apps/CameraITS/tests/scene1/test_burst_sameness_auto_fullres.py
@@ -41,20 +41,27 @@ def main():
# Capture at full resolution.
props = cam.get_camera_properties()
- req = its.objects.auto_capture_request()
w,h = its.objects.get_available_output_sizes("yuv", props)[0]
# Converge 3A prior to capture.
- cam.do_3a()
+ cam.do_3a(lock_ae=True, lock_awb=True)
+
+ # After 3A has converged, lock AE+AWB for the duration of the test.
+ req = its.objects.auto_capture_request()
+ req["android.blackLevel.lock"] = True
+ req["android.control.awbLock"] = True
+ req["android.control.aeLock"] = True
# Capture bursts of YUV shots.
- # Build a 4D array, which is an array of all RGB images.
- imgs = numpy.empty([FRAMES,h,w,3])
+ # Build a 4D array, which is an array of all RGB images after down-
+ # scaling them by a factor of 4x4.
+ imgs = numpy.empty([FRAMES,h/4,w/4,3])
for j in range(BURSTS):
caps = cam.do_capture([req]*BURST_LEN)
for i,cap in enumerate(caps):
n = j*BURST_LEN + i
- imgs[n] = its.image.convert_capture_to_rgb_image(cap)
+ imgs[n] = its.image.downscale_image(
+ its.image.convert_capture_to_rgb_image(cap), 4)
# Dump all images.
print "Dumping images"
@@ -70,7 +77,7 @@ def main():
print "Computing frame differences"
delta_maxes = []
for i in range(FRAMES):
- deltas = (imgs[i] - img_mean).reshape(h*w*3)
+ deltas = (imgs[i] - img_mean).reshape(h*w*3/16)
delta_max_pos = numpy.max(deltas)
delta_max_neg = numpy.min(deltas)
delta_maxes.append(max(abs(delta_max_pos), abs(delta_max_neg)))