diff options
author | Sol Boucher <solb@google.com> | 2014-08-23 01:30:21 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-08-23 01:30:21 +0000 |
commit | f27e71f979e803a3ac00f4057eb909886d957a3e (patch) | |
tree | 78b246728df89f94e32622a740c0ae4084593cf0 /camera2/portability/src | |
parent | 336f88ed91a43eb4d1d67fb805171433676279e3 (diff) | |
parent | 9d8668449376fa47bc6528c7a61b04d6a0f691b3 (diff) | |
download | android_frameworks_ex-f27e71f979e803a3ac00f4057eb909886d957a3e.tar.gz android_frameworks_ex-f27e71f979e803a3ac00f4057eb909886d957a3e.tar.bz2 android_frameworks_ex-f27e71f979e803a3ac00f4057eb909886d957a3e.zip |
Merge "camera2-portability: Switch to ratio-based zoom interfaces" into lmp-dev
Diffstat (limited to 'camera2/portability/src')
8 files changed, 103 insertions, 61 deletions
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Capabilities.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Capabilities.java index 51c1422..bd610cc 100644 --- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Capabilities.java +++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Capabilities.java @@ -81,7 +81,7 @@ public class AndroidCamera2Capabilities extends CameraCapabilities { mMaxNumOfFacesSupported = p.get(STATISTICS_INFO_MAX_FACE_COUNT); mMaxNumOfMeteringArea = p.get(CONTROL_MAX_REGIONS_AE); - // TODO: Populate mMaxZoomRatio + mMaxZoomRatio = p.get(SCALER_AVAILABLE_MAX_DIGITAL_ZOOM); // TODO: Populate mHorizontalViewAngle // TODO: Populate mVerticalViewAngle // TODO: Populate mZoomRatioList @@ -97,6 +97,10 @@ public class AndroidCamera2Capabilities extends CameraCapabilities { mSupportedFeatures.add(Feature.METERING_AREA); } + if (mMaxZoomRatio > CameraCapabilities.ZOOM_RATIO_UNZOOMED) { + mSupportedFeatures.add(Feature.ZOOM); + } + // TODO: Detect other features } 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 adf930e..7f6cffe 100644 --- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Settings.java +++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2Settings.java @@ -42,8 +42,9 @@ public class AndroidCamera2Settings extends CameraSettings { private static final Log.Tag TAG = new Log.Tag("AndCam2Set"); private final Builder mTemplateSettings; - private final Rect mActiveArray; private final Camera2RequestSettingsSet mRequestSettings; + private final Rect mActiveArray; + private final Rect mCropRectangle; /** * Create a settings representation that answers queries of unspecified @@ -57,19 +58,31 @@ public class AndroidCamera2Settings extends CameraSettings { * their effective values when submitting a capture request will be those of * the template that is provided to the camera framework at that time.</p> * - * @param camera Device from which to draw default settings. + * @param camera Device from which to draw default settings + * (non-{@code null}). * @param template Specific template to use for the defaults. - * @param activeArray Boundary coordinates of the sensor's active array. + * @param activeArray Boundary coordinates of the sensor's active array + * (non-{@code null}). * @param preview Dimensions of preview streams. * @param photo Dimensions of captured images. * + * @throws IllegalArgumentException If {@code camera} or {@code activeArray} + * is {@code null}. * @throws CameraAccessException Upon internal framework/driver failure. */ public AndroidCamera2Settings(CameraDevice camera, int template, Rect activeArray, Size preview, Size photo) throws CameraAccessException { + if (camera == null) { + throw new NullPointerException("camera must not be null"); + } + if (activeArray == null) { + throw new NullPointerException("activeArray must not be null"); + } + mTemplateSettings = camera.createCaptureRequest(template); - mActiveArray = activeArray; mRequestSettings = new Camera2RequestSettingsSet(); + mActiveArray = activeArray; + mCropRectangle = new Rect(0, 0, activeArray.width(), activeArray.height()); Range<Integer> previewFpsRange = mTemplateSettings.get(CONTROL_AE_TARGET_FPS_RANGE); if (previewFpsRange != null) { @@ -80,8 +93,8 @@ public class AndroidCamera2Settings extends CameraSettings { setPhotoSize(photo); mJpegCompressQuality = queryTemplateDefaultOrMakeOneUp(JPEG_QUALITY, (byte) 0); // TODO: mCurrentPhotoFormat - // TODO: mCurrentZoomRatio - mCurrentZoomRatio = 1.0f; + // NB: We're assuming that templates won't be zoomed in by default. + mCurrentZoomRatio = CameraCapabilities.ZOOM_RATIO_UNZOOMED; // TODO: mCurrentZoomIndex mExposureCompensationIndex = queryTemplateDefaultOrMakeOneUp(CONTROL_AE_EXPOSURE_COMPENSATION, 0); @@ -117,8 +130,9 @@ public class AndroidCamera2Settings extends CameraSettings { public AndroidCamera2Settings(AndroidCamera2Settings other) { super(other); mTemplateSettings = other.mTemplateSettings; - mActiveArray = other.mActiveArray; mRequestSettings = new Camera2RequestSettingsSet(other.mRequestSettings); + mActiveArray = other.mActiveArray; + mCropRectangle = new Rect(other.mCropRectangle); } @Override @@ -160,6 +174,18 @@ public class AndroidCamera2Settings extends CameraSettings { return null; } + @Override + public void setZoomRatio(float ratio) { + super.setZoomRatio(ratio); + mCropRectangle.set(0, 0, + toIntConstrained( + mActiveArray.width() / mCurrentZoomRatio, 0, mActiveArray.width()), + toIntConstrained( + mActiveArray.height() / mCurrentZoomRatio, 0, mActiveArray.height())); + mCropRectangle.offsetTo((mActiveArray.width() - mCropRectangle.width()) / 2, + (mActiveArray.height() - mCropRectangle.height()) / 2); + } + private boolean matchesTemplateDefault(Key<?> setting) { if (setting == CONTROL_AE_REGIONS) { return mMeteringAreas.size() == 0; @@ -214,7 +240,7 @@ public class AndroidCamera2Settings extends CameraSettings { // TODO: mCurrentPreviewFormat updateRequestSettingOrForceToDefault(JPEG_QUALITY, mJpegCompressQuality); // TODO: mCurrentPhotoFormat - // TODO: mCurrentZoomRatio + mRequestSettings.set(SCALER_CROP_REGION, mCropRectangle); // TODO: mCurrentZoomIndex updateRequestSettingOrForceToDefault(CONTROL_AE_EXPOSURE_COMPENSATION, mExposureCompensationIndex); @@ -244,25 +270,25 @@ public class AndroidCamera2Settings extends CameraSettings { List<android.hardware.Camera.Area> reference) { MeteringRectangle[] transformed = null; if (reference.size() > 0) { - transformed = new MeteringRectangle[reference.size()]; for (int index = 0; index < reference.size(); ++index) { android.hardware.Camera.Area source = reference.get(index); Rect rectangle = source.rect; // Old API coordinates were [-1000,1000]; new ones are [0,ACTIVE_ARRAY_SIZE). + // We're also going from preview image--relative to sensor active array--relative. double oldLeft = (rectangle.left + 1000) / 2000.0; double oldTop = (rectangle.top + 1000) / 2000.0; double oldRight = (rectangle.right + 1000) / 2000.0; double oldBottom = (rectangle.bottom + 1000) / 2000.0; - int left = toIntConstrained( mActiveArray.width() * oldLeft + mActiveArray.left, - 0, mActiveArray.width() - 1); - int top = toIntConstrained( mActiveArray.height() * oldTop + mActiveArray.top, - 0, mActiveArray.height() - 1); - int right = toIntConstrained( mActiveArray.width() * oldRight + mActiveArray.left, - 0, mActiveArray.width() - 1); - int bottom = toIntConstrained( mActiveArray.height() * oldBottom + mActiveArray.top, - 0, mActiveArray.height() - 1); + int left = mCropRectangle.left + toIntConstrained( + mCropRectangle.width() * oldLeft, 0, mCropRectangle.width() - 1); + int top = mCropRectangle.top + toIntConstrained( + mCropRectangle.height() * oldTop, 0, mCropRectangle.height() - 1); + int right = mCropRectangle.left + toIntConstrained( + mCropRectangle.width() * oldRight, 0, mCropRectangle.width() - 1); + int bottom = mCropRectangle.top + toIntConstrained( + mCropRectangle.height() * oldBottom, 0, mCropRectangle.height() - 1); transformed[index] = new MeteringRectangle(left, top, right - left, bottom - top, source.weight); } 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 c26a1a3..f8a2e38 100644 --- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraAgentImpl.java +++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraAgentImpl.java @@ -38,6 +38,8 @@ import android.view.SurfaceHolder; import com.android.ex.camera2.portability.debug.Log; import java.io.IOException; +import java.util.Collections; +import java.util.List; import java.util.StringTokenizer; /** @@ -596,8 +598,8 @@ class AndroidCameraAgentImpl extends CameraAgent { parameters.setPreviewFormat(settings.getCurrentPreviewFormat()); parameters.setJpegQuality(settings.getPhotoJpegCompressionQuality()); if (mCapabilities.supports(CameraCapabilities.Feature.ZOOM)) { - // Should use settings.getCurrentZoomRatio() instead here. - parameters.setZoom(settings.getCurrentZoomIndex()); + parameters.setZoom(zoomRatioToIndex(settings.getCurrentZoomRatio(), + parameters.getZoomRatios())); } parameters.setExposureCompensation(settings.getExposureCompensationIndex()); if (mCapabilities.supports(CameraCapabilities.Feature.AUTO_EXPOSURE_LOCK)) { @@ -648,6 +650,29 @@ class AndroidCameraAgentImpl extends CameraAgent { } } + + /** + * @param ratio Desired zoom ratio, in [1.0f,+Inf). + * @param percentages Available zoom ratios, as percentages. + * @return Index of the closest corresponding ratio, rounded up toward + * that of the maximum available ratio. + */ + private int zoomRatioToIndex(float ratio, List<Integer> percentages) { + int percent = (int) (ratio * AndroidCameraCapabilities.ZOOM_MULTIPLIER); + int index = Collections.binarySearch(percentages, percent); + if (index >= 0) { + // Found the desired ratio in the supported list + return index; + } else { + // Didn't find an exact match. Where would it have been? + index = -(index + 1); + if (index == percentages.size()) { + // Put it back in bounds by setting to the maximum allowable zoom + --index; + } + return index; + } + } } /** diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java index acff9c6..84b44e6 100644 --- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java +++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java @@ -31,6 +31,9 @@ class AndroidCameraCapabilities extends CameraCapabilities { private static Log.Tag TAG = new Log.Tag("AndCamCapabs"); + /** Conversion from ratios to percentages. */ + public static final float ZOOM_MULTIPLIER = 100f; + private FpsComparator mFpsComparator = new FpsComparator(); private SizeComparator mSizeComparator = new SizeComparator(); @@ -44,9 +47,7 @@ class AndroidCameraCapabilities extends CameraCapabilities { mPreferredPreviewSizeForVideo = new Size(p.getPreferredPreviewSizeForVideo()); mSupportedPreviewFormats.addAll(p.getSupportedPreviewFormats()); mSupportedPhotoFormats.addAll(p.getSupportedPictureFormats()); - mMaxZoomIndex = p.getMaxZoom(); - mZoomRatioList.addAll(p.getZoomRatios()); - mMaxZoomRatio = mZoomRatioList.get(mMaxZoomIndex); + mMaxZoomRatio = p.getZoomRatios().get(p.getMaxZoom()) / ZOOM_MULTIPLIER; mHorizontalViewAngle = p.getHorizontalViewAngle(); mVerticalViewAngle = p.getVerticalViewAngle(); buildPreviewFpsRange(p); 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 ceab7fe..f5421d6 100644 --- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java +++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java @@ -41,10 +41,8 @@ public class AndroidCameraSettings extends CameraSettings { // Capture: Focus, flash, zoom, exposure, scene mode. if (capabilities.supports(CameraCapabilities.Feature.ZOOM)) { setZoomRatio(params.getZoomRatios().get(params.getZoom()) / 100f); - setZoomIndex(params.getZoom()); } else { - setZoomRatio(1.0f); - setZoomIndex(0); + setZoomRatio(CameraCapabilities.ZOOM_RATIO_UNZOOMED); } setExposureCompensationIndex(params.getExposureCompensation()); setFlashMode(stringifier.flashModeFromString(params.getFlashMode())); 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 dd4f77c..df94a41 100644 --- a/camera2/portability/src/com/android/ex/camera2/portability/CameraAgent.java +++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraAgent.java @@ -732,10 +732,11 @@ public abstract class CameraAgent { protected boolean applySettingsHelper(CameraSettings settings, final int statesToAwait) { if (settings == null) { - Log.v(TAG, "null parameters in applySettings()"); + Log.v(TAG, "null argument in applySettings()"); return false; } if (!getCapabilities().supports(settings)) { + Log.w(TAG, "Unsupported settings in applySettings()"); return false; } diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java index 3dc19f7..0d7c302 100644 --- a/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java +++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java @@ -36,6 +36,9 @@ public class CameraCapabilities { private static Log.Tag TAG = new Log.Tag("CamCapabs"); + /** Zoom ratio used for seeing sensor's full field of view. */ + protected static final float ZOOM_RATIO_UNZOOMED = 1.0f; + /* All internal states are declared final and should be thread-safe. */ protected final ArrayList<int[]> mSupportedPreviewFpsRange = new ArrayList<int[]>(); @@ -57,12 +60,10 @@ public class CameraCapabilities { protected int mMaxNumOfFacesSupported; protected int mMaxNumOfFocusAreas; protected int mMaxNumOfMeteringArea; - protected int mMaxZoomRatio; + protected float mMaxZoomRatio; protected float mHorizontalViewAngle; protected float mVerticalViewAngle; private final Stringifier mStringifier; - protected final ArrayList<Integer> mZoomRatioList = new ArrayList<Integer>(); - protected int mMaxZoomIndex; /** * Focus modes. @@ -488,8 +489,6 @@ public class CameraCapabilities { mMaxNumOfFacesSupported = src.mMaxNumOfFacesSupported; mMaxNumOfFocusAreas = src.mMaxNumOfFocusAreas; mMaxNumOfMeteringArea = src.mMaxNumOfMeteringArea; - mMaxZoomIndex = src.mMaxZoomIndex; - mZoomRatioList.addAll(src.mZoomRatioList); mMaxZoomRatio = src.mMaxZoomRatio; mHorizontalViewAngle = src.mHorizontalViewAngle; mVerticalViewAngle = src.mVerticalViewAngle; @@ -635,17 +634,6 @@ public class CameraCapabilities { return mMaxZoomRatio; } - // We'll replace these old style methods with new ones. - @Deprecated - public int getMaxZoomIndex() { - return mMaxZoomIndex; - } - - @Deprecated - public List<Integer> getZoomRatioList() { - return new ArrayList<Integer>(mZoomRatioList); - } - /** * @return The min exposure compensation index. The EV is the compensation * index multiplied by the step value. If unsupported, both this method and @@ -689,17 +677,15 @@ public class CameraCapabilities { private boolean zoomCheck(final CameraSettings settings) { final float ratio = settings.getCurrentZoomRatio(); - final int index = settings.getCurrentZoomIndex(); if (!supports(Feature.ZOOM)) { - if (ratio != 1.0f || index != 0) { + if (ratio != ZOOM_RATIO_UNZOOMED) { Log.v(TAG, "Zoom is not supported"); return false; } } else { - if (settings.getCurrentZoomRatio() > getMaxZoomRatio() || - index > getMaxZoomIndex()) { + if (settings.getCurrentZoomRatio() > getMaxZoomRatio()) { Log.v(TAG, "Zoom ratio is not supported: ratio = " + - settings.getCurrentZoomRatio() + ", index = " + index); + settings.getCurrentZoomRatio()); return false; } } 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 cae022d..d0600e8 100644 --- a/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java +++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java @@ -47,7 +47,6 @@ public abstract class CameraSettings { protected byte mJpegCompressQuality; protected int mCurrentPhotoFormat; protected float mCurrentZoomRatio; - protected int mCurrentZoomIndex; protected int mExposureCompensationIndex; protected CameraCapabilities.FlashMode mCurrentFlashMode; protected CameraCapabilities.FocusMode mCurrentFocusMode; @@ -128,7 +127,6 @@ public abstract class CameraSettings { mJpegCompressQuality = src.mJpegCompressQuality; mCurrentPhotoFormat = src.mCurrentPhotoFormat; mCurrentZoomRatio = src.mCurrentZoomRatio; - mCurrentZoomIndex = src.mCurrentZoomIndex; mExposureCompensationIndex = src.mExposureCompensationIndex; mCurrentFlashMode = src.mCurrentFlashMode; mCurrentFocusMode = src.mCurrentFocusMode; @@ -312,16 +310,6 @@ public abstract class CameraSettings { mCurrentZoomRatio = ratio; } - @Deprecated - public int getCurrentZoomIndex() { - return mCurrentZoomIndex; - } - - @Deprecated - public void setZoomIndex(int index) { - mCurrentZoomIndex = index; - } - /** Exposure **/ public void setExposureCompensationIndex(int index) { @@ -343,6 +331,14 @@ public abstract class CameraSettings { return mAutoExposureLocked; } + /** + * @param areas The areas for autoexposure. The coordinate system has domain + * and range [-1000,1000], measured relative to the visible + * preview image, with orientation matching that of the sensor. + * This means the coordinates must be transformed to account + * for the devices rotation---but not the zoom level---before + * being passed into this method. + */ public void setMeteringAreas(List<Camera.Area> areas) { mMeteringAreas.clear(); if (areas != null) { @@ -382,7 +378,12 @@ public abstract class CameraSettings { } /** - * @param areas The areas to focus. + * @param areas The areas to focus. The coordinate system has domain and + * range [-1000,1000], measured relative to the visible preview + * image, with orientation matching that of the sensor. This + * means the coordinates must be transformed to account for + * the devices rotation---but not the zoom level---before being + * passed into this method. */ public void setFocusAreas(List<Camera.Area> areas) { mFocusAreas.clear(); |