Waiting for general 3A convergence and startFocusAndMetering()

55 views
Skip to first unread message
Assigned to tonyt...@google.com by scot...@google.com

Christophe Beyls

unread,
Sep 6, 2026, 10:18:47 AMSep 6
to Android CameraX Discussion Group
Hello CameraX team and thank you for providing this discussion board.

I'm not very experienced in Camera development and need your advice regarding a topic I found little information about.

If I understand correctly, when the CameraX image capture use case is configured with CAPTURE_MODE_MAXIMIZE_QUALITY, the CameraX capture pipeline will perform the following actions for a regular capture (no flash):
1) Wait for AF, AE and AWB to converge and lock AF
2) Capture the image
3) Unlock AF.

I would like to keep that behavior but capture multiple images in a row: a reference image followed by images with manually set exposure time and ISO. This means I also need to initially lock AE and AWB in addition to AF.

I can't use CAPTURE_MODE_MAXIMIZE_QUALITY because I don't want to run steps1 and 3 between images, so to get more control I want to use CAPTURE_MODE_MINIMIZE_LATENCY and replicate the pre-capture and post-capture steps manually.

My question is: what is the best way to wait for 3A convergence and lock AF, AE and AWB before capturing the series of images?

I identified 2 ways but I don't know if they are correct.

The first way, correct me if I'm wrong, is to call startFocusAndMetering() and wait for the operation to complete which should result in all 3 states to be converged if the 3 flags are passed as arguments, even if this is not documented explicitly. I've noticed that there is also a new API in the latest CameraX 1.7 to allow locking all 3 values after the metering and not just AF.
Can you confirm all 3 values would effectively converge then lock by calling this API?
And if so, since this API requires passing metering points, I also wonder which metering point should be used to get the most "neutral" behavior, meaning a behavior that is as close as possible to the default automatic AE and AWD scan behavior when no regions are specified. Should I use a centered point that is as large as the sensor or something else? Would that work correctly on all devices?

The second way is to replicate the custom logic that CameraX uses internally, which looks more complicated and I'm not sure how to achieve this. I understand it would require setting some Camera2 interop CaptureListener and repeatedly check the state of AE and AWB in TotalCaptureResult until they are all converged or a timeout occurs. As for the autofocus I have no clue which flags I should manually set so I would probably still call startFocusAndMetering() before but just for the AF.

What are your recommendations? Thank you in advance!

Wenhung Teng

unread,
Sep 7, 2026, 9:56:58 PMSep 7
to Android CameraX Discussion Group, chris...@beyls.net

Hi there,

Using startFocusAndMetering() in CameraX 1.7+ is indeed the recommended and most reliable way to achieve exactly what you want.

Here are the details on how it works and how to set it up to replicate the default manual capture behavior:

1. Waiting for 3A Convergence and Locking: With the new setLockingMode API introduced in CameraX 1.7, you can explicitly instruct the camera to lock Auto Focus (AF), Auto Exposure (AE), and Auto White Balance (AWB) after the scan completes.

https://developer.android.com/reference/kotlin/androidx/camera/core/FocusMeteringAction.Builder#setLockingMode(int)

When you submit the action via startFocusAndMetering(action), the returned ListenableFuture handles the heavy lifting for you—it will wait for the regions to update and for all requested locks to be successfully acquired before it completes.

To lock all three, you can configure your FocusMeteringAction like this:

int flags = FocusMeteringAction.FLAG_AF | FocusMeteringAction.FLAG_AE | FocusMeteringAction.FLAG_AWB; FocusMeteringAction action = new FocusMeteringAction.Builder(meteringPoint) .setLockingMode(flags) .build(); ListenableFuture<FocusMeteringResult> future = cameraControl.startFocusAndMetering(action); // Wait for the future to complete before capturing your series of images

2. Because the FocusMeteringAction.Builder strictly requires at least one MeteringPoint, you cannot pass "no region". However, your instinct to use a centered point that spans the entire sensor is perfectly correct, as this mimics the default behavior of evaluating the whole scene.

You can achieve this easily using SurfaceOrientedMeteringPointFactory. By defining a 1x1 surface and placing a point in the center (0.5f, 0.5f) with a size of 1.0f, you cover the entire available area:

// Create a factory for a normalized 1x1 area SurfaceOrientedMeteringPointFactory factory = new SurfaceOrientedMeteringPointFactory(1.0f, 1.0f); // x = 0.5f, y = 0.5f, size = 1.0f (100% of the sensor/crop region) MeteringPoint neutralPoint = factory.createPoint(0.5f, 0.5f, 1.0f);

Passing this neutralPoint to the builder will ensure that the 3A routines evaluate the whole sensor natively without biasing toward a small localized patch. This approach translates reliably across different devices.


While your second proposed method (replicating the internal logic via Camera2Interop CaptureCallbacks and listening to TotalCaptureResult) is technically possible, it is significantly more complex and bypasses CameraX's internal state management. We recommend sticking to the startFocusAndMetering future, as it handles device-specific quirks and timeouts safely under the hood.

Hope this helps you get your multi-image capture pipeline working smoothly! Let us know if you have any other questions.

Christophe Beyls

unread,
Sep 8, 2026, 5:15:23 AMSep 8
to Android CameraX Discussion Group, wenhu...@google.com, Christophe Beyls
Thank you for the very detailed explanation! I was indeed going for the very same code you suggested.

I still have 2 related questions:

1. What happens if this code is used and the camera supports an AF region but doesn't support AE or AWB regions (it only supports automatic scan without regions) ? Will AE and AWB still be properly converged then locked at the end of the startFocusAndMetering() action, even if the region is ignored for those two ? The documentation is not clear about that specific case. Also it states that "If none of the specified AF/AE/AWB MeteringPoint is supported, startFocusAndMetering() fails with IllegalArgumentException", which seems to imply that metering point support is required to get a lock.

2. Are there other actions that the CameraX capture pipeline performs for simple capture with no flash in CAPTURE_MODE_MAXIMIZE_QUALITY that differ from CAPTURE_MODE_MINIMIZE_LATENCY and that I can replicate to attempt improving image quality? (Besides changing the JPEG quality to 100). For example, is it setting different Camera2 CaptureRequest flags in that mode to improve image quality at the expense of speed?

Thank you very much and have a nice week.
Reply all
Reply to author
Forward
0 new messages