I'm having issues with my touch-to-focus implementation using Camera2 APIs. Here's my code:
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
if (isMeteringAreaAESupported()) {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS,
new MeteringRectangle[]{focusArea});
}
if (isMeteringAreaAFSupported()) {
mPreviewRequestBuilder
.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusArea});
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_AUTO);
}
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_START);
try {
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), null,
mBackgroundHandler);
mManualFocusEngaged = true;
} catch (CameraAccessException e) {
// error handling
}
The problem I'm seeing is weird behaviour with the flash on some devices when the above code is called multiple times within a short period of time (i.e. user touches the screen way too fast before the focus has been set). For example, on S5 it looks like all the requests are queued up and if the user touch quite a few times, they execute one by one for a while. On my Nexus 5, the flash will not blink from request to request, but will be constantly ON until the last request finished executing.
What I'm after is to actually cancel the in-flight request like they do in Google Camera. If you try the same thing with flash ON using Google Camera, they cancel the request immediately when the new touch is registered.
I've tried adding mCaptureSession.abortCaptures();
before the above method but it didn't work the same way and started dropping frames as well. mCaptureSession.stopRepeating();
didn't make any difference at all.
Apparently I had to do a capture request to cancel the AF.
I've added this after the first line with my CANCEL trigger:
try {
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
} catch (CameraAccessException e){
// log
}