My app uses Camera2 API to take frames as fast as possible. We have a start / stop button to start / stop capturing frames. Focus is either set to auto, or done before capturing. If the focus is done before capturing, then during the capture it must be disabled.
I'm using this to make the focus:
public void focusAt(Point point) {
if(mCanAe || mCanAf) {
int areaSize = 200;
int ll = ((point.x * mActiveArraySize.right) - areaSize) / mTextureView.getWidth();
int rr = ((point.y * mActiveArraySize.bottom) - areaSize) / mTextureView.getHeight();
int focusLeft = clamp(ll, 0, mActiveArraySize.right);
int focusBottom = clamp(rr, 0, mActiveArraySize.bottom);
Rect newRect = new Rect(focusLeft, focusBottom, focusLeft + areaSize, focusBottom + areaSize);
MeteringRectangle meteringRectangle = new MeteringRectangle(newRect, 1);
final MeteringRectangle[] meteringRectangleArr = { meteringRectangle };
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
try {
mCaptureSession.capture(mPreviewRequestBuilder.build(), new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
if (mCanAe) {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, meteringRectangleArr );
}
if (mCanAf) {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, meteringRectangleArr );
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);
}
catch (CameraAccessException e) {
e.printStackTrace();
}
}
}, mBackgroundHandler);
}
catch (CameraAccessException e) { e.printStackTrace(); }
}
}
This function can't be called during the capture. I thought it would be enough, but sometimes during the capture, Camera2 tries to focus.
Is there a way to disable the focus?
Other question, is it mandatory to lock the focus before capturing? Seems to work fine without doing it, but I'd like to be sure.
EDIT: to capture I'm doing this:
private void capture() {
try {
final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
captureBuilder.addTarget(mImageReader.getSurface());
// Orientation
int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
mCaptureSession.capture(captureBuilder.build(), null, mTakeImageBackgroundHandler);
}
catch (CameraAccessException e) {
e.printStackTrace();
}
I call the capture() method as soon as a frame is saved.