summaryrefslogtreecommitdiffstats
path: root/camera2
diff options
context:
space:
mode:
authorIgor Murashkin <iam@google.com>2014-08-29 22:24:31 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-08-29 22:24:32 +0000
commit58774cf3543e06c4b51a54bccd603a2cbcd7a816 (patch)
tree86524bb5e97071234353e144b4eecf390a723d83 /camera2
parentf73c6cf2f04451ba4517abccd36a114667c69ae3 (diff)
parent2569329d6cff25bfe9941df539df14a0aeb4c4f4 (diff)
downloadandroid_frameworks_ex-58774cf3543e06c4b51a54bccd603a2cbcd7a816.tar.gz
android_frameworks_ex-58774cf3543e06c4b51a54bccd603a2cbcd7a816.tar.bz2
android_frameworks_ex-58774cf3543e06c4b51a54bccd603a2cbcd7a816.zip
Merge "camera2-portability: Touch-to-focus accounting for effective crop" into lmp-dev
Diffstat (limited to 'camera2')
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java24
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Settings.java59
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraAgentImpl.java2
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java2
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/CameraAgent.java26
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java37
6 files changed, 144 insertions, 6 deletions
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
index 847ca22..913a575 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
@@ -305,6 +305,10 @@ class AndroidCamera2AgentImpl extends CameraAgent {
break;
}
+ // FIXME: We need to tear down the CameraCaptureSession here
+ // (and unlock the CameraSettings object from our
+ // CameraProxy) so that the preview/photo sizes can be
+ // changed again while no preview is running.
case CameraActions.STOP_PREVIEW: {
if (mCameraState.getState() <
AndroidCamera2StateHolder.CAMERA_PREVIEW_ACTIVE) {
@@ -972,6 +976,26 @@ class AndroidCamera2AgentImpl extends CameraAgent {
return mCapabilities;
}
+ // FIXME: Unlock the sizes in stopPreview(), as per the corresponding
+ // explanation on the STOP_PREVIEW case in the handler.
+ @Override
+ public void setPreviewTexture(SurfaceTexture surfaceTexture) {
+ // Once the Surface has been selected, we configure the session and
+ // are no longer able to change the sizes.
+ getSettings().setSizesLocked(true);
+ super.setPreviewTexture(surfaceTexture);
+ }
+
+ // FIXME: Unlock the sizes in stopPreview(), as per the corresponding
+ // explanation on the STOP_PREVIEW case in the handler.
+ @Override
+ public void setPreviewTextureSync(SurfaceTexture surfaceTexture) {
+ // Once the Surface has been selected, we configure the session and
+ // are no longer able to change the sizes.
+ getSettings().setSizesLocked(true);
+ super.setPreviewTexture(surfaceTexture);
+ }
+
// TODO: Implement
@Override
public void setPreviewDataCallback(Handler handler, CameraPreviewDataCallback cb) {}
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Settings.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Settings.java
index 7f6cffe..0d3ef26 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Settings.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Settings.java
@@ -18,7 +18,9 @@ package com.android.ex.camera2.portability;
import static android.hardware.camera2.CaptureRequest.*;
+import android.graphics.Matrix;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.params.MeteringRectangle;
@@ -43,8 +45,12 @@ public class AndroidCamera2Settings extends CameraSettings {
private final Builder mTemplateSettings;
private final Camera2RequestSettingsSet mRequestSettings;
+ /** Sensor's active array bounds. */
private final Rect mActiveArray;
+ /** Crop rectangle for digital zoom (measured WRT the active array). */
private final Rect mCropRectangle;
+ /** Bounds of visible preview portion (measured WRT the active array). */
+ private Rect mVisiblePreviewRectangle;
/**
* Create a settings representation that answers queries of unspecified
@@ -84,6 +90,8 @@ public class AndroidCamera2Settings extends CameraSettings {
mActiveArray = activeArray;
mCropRectangle = new Rect(0, 0, activeArray.width(), activeArray.height());
+ mSizesLocked = false;
+
Range<Integer> previewFpsRange = mTemplateSettings.get(CONTROL_AE_TARGET_FPS_RANGE);
if (previewFpsRange != null) {
setPreviewFpsRange(previewFpsRange.getLower(), previewFpsRange.getUpper());
@@ -177,6 +185,8 @@ public class AndroidCamera2Settings extends CameraSettings {
@Override
public void setZoomRatio(float ratio) {
super.setZoomRatio(ratio);
+
+ // Compute the crop rectangle to be passed to the framework
mCropRectangle.set(0, 0,
toIntConstrained(
mActiveArray.width() / mCurrentZoomRatio, 0, mActiveArray.width()),
@@ -184,6 +194,10 @@ public class AndroidCamera2Settings extends CameraSettings {
mActiveArray.height() / mCurrentZoomRatio, 0, mActiveArray.height()));
mCropRectangle.offsetTo((mActiveArray.width() - mCropRectangle.width()) / 2,
(mActiveArray.height() - mCropRectangle.height()) / 2);
+
+ // Compute the effective crop rectangle to be used for computing focus/metering coordinates
+ mVisiblePreviewRectangle =
+ effectiveCropRectFromRequested(mCropRectangle, mCurrentPreviewSize);
}
private boolean matchesTemplateDefault(Key<?> setting) {
@@ -512,4 +526,49 @@ public class AndroidCamera2Settings extends CameraSettings {
mRequestSettings.set(JPEG_GPS_LOCATION, location);
}
}
+
+ /**
+ * Calculate the effective crop rectangle for this preview viewport;
+ * assumes the preview is centered to the sensor and scaled to fit across one of the dimensions
+ * without skewing.
+ *
+ * <p>Assumes the zoom level of the provided desired crop rectangle.</p>
+ *
+ * @param requestedCrop Desired crop rectangle, in active array space.
+ * @param previewSize Size of the preview buffer render target, in pixels (not in sensor space).
+ * @return A rectangle that serves as the preview stream's effective crop region (unzoomed), in
+ * sensor space.
+ *
+ * @throws NullPointerException
+ * If any of the args were {@code null}.
+ */
+ private static Rect effectiveCropRectFromRequested(Rect requestedCrop, Size previewSize) {
+ float aspectRatioArray = requestedCrop.width() * 1.0f / requestedCrop.height();
+ float aspectRatioPreview = previewSize.width() * 1.0f / previewSize.height();
+
+ float cropHeight, cropWidth;
+ if (aspectRatioPreview < aspectRatioArray) {
+ // The new width must be smaller than the height, so scale the width by AR
+ cropHeight = requestedCrop.height();
+ cropWidth = cropHeight * aspectRatioPreview;
+ } else {
+ // The new height must be smaller (or equal) than the width, so scale the height by AR
+ cropWidth = requestedCrop.width();
+ cropHeight = cropWidth / aspectRatioPreview;
+ }
+
+ Matrix translateMatrix = new Matrix();
+ RectF cropRect = new RectF(/*left*/0, /*top*/0, cropWidth, cropHeight);
+
+ // Now center the crop rectangle so its center is in the center of the active array
+ translateMatrix.setTranslate(requestedCrop.exactCenterX(), requestedCrop.exactCenterY());
+ translateMatrix.postTranslate(-cropRect.centerX(), -cropRect.centerY());
+
+ translateMatrix.mapRect(/*inout*/cropRect);
+
+ // Round the rect corners towards the nearest integer values
+ Rect result = new Rect();
+ cropRect.roundOut(result);
+ return result;
+ }
}
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraAgentImpl.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraAgentImpl.java
index 41ad971..358d5f6 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraAgentImpl.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraAgentImpl.java
@@ -400,6 +400,7 @@ class AndroidCameraAgentImpl extends CameraAgent {
break;
}
+ // TODO: Lock the CameraSettings object's sizes
case CameraActions.SET_PREVIEW_TEXTURE_ASYNC: {
setPreviewTexture(msg.obj);
break;
@@ -424,6 +425,7 @@ class AndroidCameraAgentImpl extends CameraAgent {
break;
}
+ // TODO: Unlock the CameraSettings object's sizes
case CameraActions.STOP_PREVIEW: {
mCamera.stopPreview();
break;
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java
index f5421d6..ee69b54 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java
@@ -28,6 +28,8 @@ public class AndroidCameraSettings extends CameraSettings {
public AndroidCameraSettings(CameraCapabilities capabilities, Camera.Parameters params) {
CameraCapabilities.Stringifier stringifier = capabilities.getStringifier();
+ setSizesLocked(false);
+
// Preview
Camera.Size paramPreviewSize = params.getPreviewSize();
setPreviewSize(new Size(paramPreviewSize.width, paramPreviewSize.height));
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraAgent.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraAgent.java
index df94a41..b624b47 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/CameraAgent.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraAgent.java
@@ -436,8 +436,24 @@ public abstract class CameraAgent {
/**
* Sets the {@link android.graphics.SurfaceTexture} for preview.
*
+ * <p>Note that, once this operation has been performed, it is no longer
+ * possible to change the preview or photo sizes in the
+ * {@link CameraSettings} instance for this camera, and the mutators for
+ * these fields are allowed to ignore all further invocations until the
+ * preview is stopped with {@link #stopPreview}.</p>
+ *
* @param surfaceTexture The {@link SurfaceTexture} for preview.
- */
+ *
+ * @see CameraSettings#setPhotoSize
+ * @see CameraSettings#setPreviewSize
+ */
+ // XXX: Despite the above documentation about locking the sizes, the API
+ // 1 implementation doesn't currently enforce this at all, although the
+ // Camera class warns that preview sizes shouldn't be changed while a
+ // preview is running. Furthermore, the API 2 implementation doesn't yet
+ // unlock the sizes when stopPreview() is invoked (see related FIXME on
+ // the STOP_PREVIEW case in its handler; in the meantime, changing API 2
+ // sizes would require closing and reopening the camera.
public void setPreviewTexture(final SurfaceTexture surfaceTexture) {
getDispatchThread().runJob(new Runnable() {
@Override
@@ -452,7 +468,15 @@ public abstract class CameraAgent {
* Blocks until a {@link android.graphics.SurfaceTexture} has been set
* for preview.
*
+ * <p>Note that, once this operation has been performed, it is no longer
+ * possible to change the preview or photo sizes in the
+ * {@link CameraSettings} instance for this camera, and the mutators for
+ * these fields are allowed to ignore all further invocations.</p>
+ *
* @param surfaceTexture The {@link SurfaceTexture} for preview.
+ *
+ * @see CameraSettings#setPhotoSize
+ * @see CameraSettings#setPreviewSize
*/
public void setPreviewTextureSync(final SurfaceTexture surfaceTexture) {
final WaitDoneBundle bundle = new WaitDoneBundle();
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java
index d0600e8..87e9adf 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java
@@ -38,6 +38,7 @@ public abstract class CameraSettings {
protected final Map<String, String> mGeneralSetting = new TreeMap<>();
protected final List<Camera.Area> mMeteringAreas = new ArrayList<>();
protected final List<Camera.Area> mFocusAreas = new ArrayList<>();
+ protected boolean mSizesLocked;
protected int mPreviewFpsRangeMin;
protected int mPreviewFpsRangeMax;
protected int mPreviewFrameRate;
@@ -116,6 +117,7 @@ public abstract class CameraSettings {
mGeneralSetting.putAll(src.mGeneralSetting);
mMeteringAreas.addAll(src.mMeteringAreas);
mFocusAreas.addAll(src.mFocusAreas);
+ mSizesLocked = src.mSizesLocked;
mPreviewFpsRangeMin = src.mPreviewFpsRangeMin;
mPreviewFpsRangeMax = src.mPreviewFpsRangeMax;
mPreviewFrameRate = src.mPreviewFrameRate;
@@ -151,6 +153,19 @@ public abstract class CameraSettings {
mGeneralSetting.put(key, value);
}
+ /**
+ * Changes whether classes outside this class are allowed to set the preview
+ * and photo capture sizes.
+ *
+ * @param locked Whether to prevent changes to these fields.
+ *
+ * @see #setPhotoSize
+ * @see #setPreviewSize
+ */
+ /*package*/ void setSizesLocked(boolean locked) {
+ mSizesLocked = locked;
+ }
+
/** Preview **/
/**
@@ -212,9 +227,16 @@ public abstract class CameraSettings {
/**
* @param previewSize The size to use for preview.
+ * @return Whether the operation was allowed (i.e. the sizes are unlocked).
*/
- public void setPreviewSize(Size previewSize) {
+ public boolean setPreviewSize(Size previewSize) {
+ if (mSizesLocked) {
+ Log.w(TAG, "Attempt to change preview size while locked");
+ return false;
+ }
+
mCurrentPreviewSize = new Size(previewSize);
+ return true;
}
/**
@@ -245,12 +267,17 @@ public abstract class CameraSettings {
}
/**
- * Sets the size for the photo.
- *
- * @param photoSize The photo size.
+ * @param photoSize The size to use for preview.
+ * @return Whether the operation was allowed (i.e. the sizes are unlocked).
*/
- public void setPhotoSize(Size photoSize) {
+ public boolean setPhotoSize(Size photoSize) {
+ if (mSizesLocked) {
+ Log.w(TAG, "Attempt to change photo size while locked");
+ return false;
+ }
+
mCurrentPhotoSize = new Size(photoSize);
+ return true;
}
/**