diff options
author | Timothy Knight <tknight@google.com> | 2014-10-11 21:13:30 -0700 |
---|---|---|
committer | Timothy Knight <tknight@google.com> | 2014-10-11 21:59:30 -0700 |
commit | 172ab2b9724d397daad6fdb8a34773f7a4022aa2 (patch) | |
tree | ad9c8d3124747e12b8d63bda236ef39f76c3a655 /apps | |
parent | 5093c19aad3a02c6714082e72fbda39e801870a1 (diff) | |
download | pdk-172ab2b9724d397daad6fdb8a34773f7a4022aa2.tar.gz |
CameraITS: Plumbed 3A locking through to do_3a
Change-Id: I75dd8a37c5a27dc165822c9df7065c538cb30946
Diffstat (limited to 'apps')
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))) |