The AE lock for Camera X doesn't work like should

416 views Asked by At

I use Camera X and trying to lock AF and AE using FocusMeteringAction, AF locking fine but AE doesn't lock. What can be a reason?

camerax_version = "1.1.0-alpha02"

val factory: MeteringPointFactory = previewView.meteringPointFactory
val point: MeteringPoint = factory.createPoint(x, y)
val builder = FocusMeteringAction.Builder(point)
builder.disableAutoCancel()
camerax?.cameraControl?.startFocusAndMetering(builder.build())

The code snippet is simple, and the ListenableFuture from startFocusAndMetering() returns a successful result, but AE still dynamic and not locked.

The result I am expecting: Then point the app towards something bright (eg. the sun or bright light) then lock the exposure. Then move the camera away from the light and everything will be super dark. This shows that the camera is not automatically adjusting the exposure (because it is locked).

My actual result is: Exposure adjusting and the picture is light/normal.

Would be grateful for any ideas! Thanks in advance!

1

There are 1 answers

0
sozsoy On

It's been a long time but this might be helpful to someone may ended up here.

I don't know if it is possible by using only CameraX apis. But I've achieved the expected behaviour with Camera2 apis. With the below snippet, the AF and AE can be measured and updated with a tap and stays locked afterwards until another tap occures.

private void initTapToFocus() {
    previewView.setOnTouchListener((v, event) -> {
        MeteringPointFactory meteringPointFactory = previewView.getMeteringPointFactory();
        MeteringPoint point = meteringPointFactory.createPoint(event.getX(), event.getY());
        FocusMeteringAction action = new FocusMeteringAction
                .Builder(point, FocusMeteringAction.FLAG_AF)
                .addPoint(point, FocusMeteringAction.FLAG_AE)
                .disableAutoCancel()
                .build();

        //Unlock AE before the tap so it can be updated.
        lockAe(false, () -> doFocusAndMetering(action));
        return true;
    });
}

private void doFocusAndMetering(FocusMeteringAction builder) {
    ListenableFuture<FocusMeteringResult> future = cameraControl.startFocusAndMetering(builder);

    //Lock AE again when measuring completed
    future.addListener(() -> lockAe(true, () -> {}), executor);
}


private void lockAe(boolean lockAe, Runnable doWhenComplete) {
    Camera2CameraControl camera2CameraControl = Camera2CameraControl.from(cameraControl);
    CaptureRequestOptions options = new CaptureRequestOptions.Builder()
            .setCaptureRequestOption(CaptureRequest.CONTROL_AE_LOCK, lockAe)
            .build();
    camera2CameraControl.setCaptureRequestOptions(options).addListener(doWhenComplete, executor);
}