From 1a726286b4be774a6b8c662e62f32e31768e6dd4 Mon Sep 17 00:00:00 2001 From: Byunghun Jeon Date: Fri, 10 Jun 2016 18:16:00 -0700 Subject: SnapdragonCamera: Add touchAE to camera2 Add touchAE to camera by setting AE_Region. It uses the same logic as touchAF to calculate the region. Also fixed the region calculation of AF. Change-Id: Id83f3bd3042d41e2a36c18eb30e476ff1a66dfae CRs-Fixed: 1025759 --- src/com/android/camera/CaptureModule.java | 84 +++++++++++++++++++++-------- src/com/android/camera/SettingsManager.java | 19 +++++-- 2 files changed, 79 insertions(+), 24 deletions(-) diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java index 8ac48afcb..ba576306c 100644 --- a/src/com/android/camera/CaptureModule.java +++ b/src/com/android/camera/CaptureModule.java @@ -28,8 +28,10 @@ import android.content.Intent; import android.content.res.Configuration; import android.graphics.Camera; import android.graphics.ImageFormat; +import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; +import android.graphics.RectF; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCharacteristics; @@ -150,6 +152,7 @@ public class CaptureModule implements CameraModule, PhotoController, private static final int MAX_IMAGE_NUM = 8; MeteringRectangle[][] mAFRegions = new MeteringRectangle[MAX_NUM_CAM][]; + MeteringRectangle[][] mAERegions = new MeteringRectangle[MAX_NUM_CAM][]; CaptureRequest.Key BayerMonoLinkEnableKey = new CaptureRequest.Key<>("org.codeaurora.qcamera3.dualcam_link_meta_data.enable", Byte.class); @@ -166,7 +169,8 @@ public class CaptureModule implements CameraModule, PhotoController, private int mControlAFMode = CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE; private int mLastResultAFState = -1; private Rect[] mCropRegion = new Rect[MAX_NUM_CAM]; - private boolean mAutoFocusSupported; + private boolean mAutoFocusRegionSupported; + private boolean mAutoExposureRegionSupported; // The degrees of the device rotated clockwise from its natural orientation. private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN; private int mJpegQuality; @@ -189,6 +193,8 @@ public class CaptureModule implements CameraModule, PhotoController, private long SECONDARY_SERVER_MEM; private boolean mLongshotActive = false; private CameraCharacteristics mMainCameraCharacteristics; + private int mDisplayRotation; + private int mDisplayOrientation; /** * A {@link CameraCaptureSession } for camera preview. @@ -697,6 +703,7 @@ public class CaptureModule implements CameraModule, PhotoController, Log.d(TAG, "setAFModeToPreview " + afMode); mPreviewRequestBuilder[id].set(CaptureRequest.CONTROL_AF_MODE, afMode); applyAFRegions(mPreviewRequestBuilder[id], id); + applyAERegions(mPreviewRequestBuilder[id], id); try { mCaptureSession[id].setRepeatingRequest(mPreviewRequestBuilder[id] .build(), mCaptureCallback, mCameraHandler); @@ -1128,7 +1135,8 @@ public class CaptureModule implements CameraModule, PhotoController, } } - mAutoFocusSupported = mSettingsManager.isAutoFocusSupported(mCameraIdList); + mAutoFocusRegionSupported = mSettingsManager.isAutoFocusRegionSupported(mCameraIdList); + mAutoExposureRegionSupported = mSettingsManager.isAutoExposureRegionSupported(mCameraIdList); } catch (CameraAccessException e) { e.printStackTrace(); } @@ -1228,6 +1236,7 @@ public class CaptureModule implements CameraModule, PhotoController, private void applySettingsForLockFocus(CaptureRequest.Builder builder, int id) { builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START); applyAFRegions(builder, id); + applyAERegions(builder, id); applyCommonSettings(builder, id); applyFaceDetect(builder, id); } @@ -1256,6 +1265,7 @@ public class CaptureModule implements CameraModule, PhotoController, builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest .CONTROL_AF_TRIGGER_START); applyAFRegions(builder, id); + applyAERegions(builder, id); applyCommonSettings(builder, id); applyFaceDetect(builder, id); } @@ -1418,6 +1428,7 @@ public class CaptureModule implements CameraModule, PhotoController, } else { setUpCameraOutputs(ImageFormat.JPEG); } + setDisplayOrientation(); startBackgroundThread(); Message msg = Message.obtain(); msg.what = OPEN_CAMERA; @@ -1456,7 +1467,7 @@ public class CaptureModule implements CameraModule, PhotoController, @Override public void onConfigurationChanged(Configuration config) { - + setDisplayOrientation(); } @Override @@ -1574,8 +1585,8 @@ public class CaptureModule implements CameraModule, PhotoController, @Override public void onSingleTapUp(View view, int x, int y) { - if (mPaused || mCameraDevice == null || !mFirstTimeInitialized || !mAutoFocusSupported || - !isTouchToFocusAllowed()) { + if (mPaused || mCameraDevice == null || !mFirstTimeInitialized || !mAutoFocusRegionSupported + || !mAutoExposureRegionSupported || !isTouchToFocusAllowed()) { return; } Log.d(TAG, "onSingleTapUp " + x + " " + y); @@ -1653,7 +1664,9 @@ public class CaptureModule implements CameraModule, PhotoController, @Override public void updateCameraOrientation() { - + if (mDisplayRotation != CameraUtil.getDisplayRotation(mActivity)) { + setDisplayOrientation(); + } } @Override @@ -1990,6 +2003,14 @@ public class CaptureModule implements CameraModule, PhotoController, } } + private void applyAERegions(CaptureRequest.Builder request, int id) { + if (mControlAFMode == CaptureRequest.CONTROL_AF_MODE_AUTO) { + request.set(CaptureRequest.CONTROL_AE_REGIONS, mAERegions[id]); + } else { + request.set(CaptureRequest.CONTROL_AE_REGIONS, ZERO_WEIGHT_3A_REGION); + } + } + private void applySceneMode(CaptureRequest.Builder request) { String value = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE); if (value == null) return; @@ -2106,28 +2127,44 @@ public class CaptureModule implements CameraModule, PhotoController, Point p = mUI.getSurfaceViewSize(); int width = p.x; int height = p.y; - x = x / width; - y = y / height; - mAFRegions[id] = afRectangle(x, y, mCropRegion[id]); + mAFRegions[id] = afaeRectangle(x, y, width, height, 1f, mCropRegion[id]); + mAERegions[id] = afaeRectangle(x, y, width, height, 1.5f, mCropRegion[id]); mCameraHandler.removeMessages(CANCEL_TOUCH_FOCUS, id); autoFocusTrigger(id); } - private MeteringRectangle[] afRectangle(float x, float y, Rect cropRegion) { - int side = Math.max(cropRegion.width(), cropRegion.height()) / 8; - int xCenter = (int) (cropRegion.left + x * cropRegion.width()); - int yCenter = (int) (cropRegion.top + y * cropRegion.height()); - Rect meteringRegion = new Rect(xCenter - side / 2, yCenter - side / 2, xCenter + - side / 2, yCenter + side / 2); + private MeteringRectangle[] afaeRectangle(float x, float y, int width, int height, + float multiple, Rect cropRegion) { + int side = (int) (Math.max(width, height) / 8 * multiple); + RectF meteringRegionF = new RectF(x - side / 2, y - side / 2, x + side / 2, y + side / 2); - meteringRegion.left = CameraUtil.clamp(meteringRegion.left, cropRegion.left, cropRegion - .right); - meteringRegion.top = CameraUtil.clamp(meteringRegion.top, cropRegion.top, cropRegion - .bottom); - meteringRegion.right = CameraUtil.clamp(meteringRegion.right, cropRegion.left, cropRegion - .right); + // inverse of matrix1 will translate from touch to (-1000 to 1000), which is camera1 + // coordinates, while accounting for orientation and mirror + Matrix matrix1 = new Matrix(); + CameraUtil.prepareMatrix(matrix1, !isBackCamera(), mDisplayOrientation, width, height); + matrix1.invert(matrix1); + + // inverse of matrix2 will translate from (-1000 to 1000) to camera 2 coordinates + Matrix matrix2 = new Matrix(); + matrix2.preTranslate(-cropRegion.width() / 2f, -cropRegion.height() / 2f); + matrix2.postScale(2000f / cropRegion.width(), 2000f / cropRegion.height()); + matrix2.invert(matrix2); + + matrix1.mapRect(meteringRegionF); + matrix2.mapRect(meteringRegionF); + + Rect meteringRegion = new Rect((int) meteringRegionF.left, (int) meteringRegionF.top, + (int) meteringRegionF.right, (int) meteringRegionF.bottom); + + meteringRegion.left = CameraUtil.clamp(meteringRegion.left, cropRegion.left, + cropRegion.right); + meteringRegion.top = CameraUtil.clamp(meteringRegion.top, cropRegion.top, + cropRegion.bottom); + meteringRegion.right = CameraUtil.clamp(meteringRegion.right, cropRegion.left, + cropRegion.right); meteringRegion.bottom = CameraUtil.clamp(meteringRegion.bottom, cropRegion.top, cropRegion.bottom); + MeteringRectangle[] meteringRectangle = new MeteringRectangle[1]; meteringRectangle[0] = new MeteringRectangle(meteringRegion, 1); return meteringRectangle; @@ -2149,6 +2186,11 @@ public class CaptureModule implements CameraModule, PhotoController, mLastResultAFState = resultAFState; } + private void setDisplayOrientation() { + mDisplayRotation = CameraUtil.getDisplayRotation(mActivity); + mDisplayOrientation = CameraUtil.getDisplayOrientation(mDisplayRotation, getMainCameraId()); + } + @Override public void onSettingsChanged(List settings) { if (mPaused) return; diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java index bd9322b4d..a5b72488c 100644 --- a/src/com/android/camera/SettingsManager.java +++ b/src/com/android/camera/SettingsManager.java @@ -649,14 +649,21 @@ public class SettingsManager implements ListMenu.SettingsListener { .SCALER_AVAILABLE_MAX_DIGITAL_ZOOM) > 1f; } - public boolean isAutoFocusSupported(List ids) { + public boolean isAutoFocusRegionSupported(List ids) { for (int id : ids) { - if (!isAutoFocusSupported(id)) + if (!isAutoFocusRegionSupported(id)) return false; } return true; } + public boolean isAutoExposureRegionSupported(List ids) { + for (int id : ids) { + if (!isAutoExposureRegionSupported(id)) + return false; + } + return true; + } public boolean isZoomSupported(List ids) { for (int id : ids) { @@ -666,7 +673,13 @@ public class SettingsManager implements ListMenu.SettingsListener { return true; } - public boolean isAutoFocusSupported(int id) { + public boolean isAutoExposureRegionSupported(int id) { + Integer maxAERegions = mCharacteristics.get(id).get( + CameraCharacteristics.CONTROL_MAX_REGIONS_AE); + return maxAERegions != null && maxAERegions > 0; + } + + public boolean isAutoFocusRegionSupported(int id) { Integer maxAfRegions = mCharacteristics.get(id).get( CameraCharacteristics.CONTROL_MAX_REGIONS_AF); return maxAfRegions != null && maxAfRegions > 0; -- cgit v1.2.3