summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorShuzhen Wang <shuzhenwang@google.com>2019-12-19 03:32:59 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-12-19 03:32:59 +0000
commitf8aca7b463ca4d3efc005dd7d189cf01d4efed4c (patch)
tree731bcd90fbd0e1eaec330148a9993b1769b4dbd8 /core/java/android
parent3bade4860ad1a0de088ff0318bc428bac4e7d02c (diff)
parent55c1c3f8743867619d51ce681b8e307b81270da0 (diff)
Merge "Camera: Add support for CONTROL_ZOOM_RATIO"
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java103
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java4
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java92
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java122
-rw-r--r--core/java/android/hardware/camera2/impl/CameraMetadataNative.java66
-rw-r--r--core/java/android/hardware/camera2/marshal/impl/MarshalQueryableCapabilityAndMaxSize.java77
-rw-r--r--core/java/android/hardware/camera2/params/Capability.java (renamed from core/java/android/hardware/camera2/params/CapabilityAndMaxSize.java)61
7 files changed, 406 insertions, 119 deletions
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index c84c4a762796..b60586655dc8 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1125,8 +1125,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
new Key<android.util.Range<Integer>>("android.control.postRawSensitivityBoostRange", new TypeReference<android.util.Range<Integer>>() {{ }});
/**
- * <p>The list of bokeh modes that are supported by this camera device, and each bokeh mode's
- * maximum streaming (non-stall) size with bokeh effect.</p>
+ * <p>The list of bokeh modes for {@link CaptureRequest#CONTROL_BOKEH_MODE android.control.bokehMode} that are supported by this camera
+ * device, and each bokeh mode's maximum streaming (non-stall) size with bokeh effect.</p>
* <p>For OFF mode, the camera behaves normally with no bokeh effect.</p>
* <p>For STILL_CAPTURE mode, the maximum streaming dimension specifies the limit under which
* bokeh is effective when capture intent is PREVIEW. Note that when capture intent is
@@ -1148,12 +1148,86 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
+ * @see CaptureRequest#CONTROL_BOKEH_MODE
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @hide
+ */
+ public static final Key<int[]> CONTROL_AVAILABLE_BOKEH_MAX_SIZES =
+ new Key<int[]>("android.control.availableBokehMaxSizes", int[].class);
+
+ /**
+ * <p>The ranges of supported zoom ratio for non-OFF {@link CaptureRequest#CONTROL_BOKEH_MODE android.control.bokehMode}.</p>
+ * <p>When bokeh mode is enabled, the camera device may have limited range of zoom ratios
+ * compared to when bokeh mode is disabled. This tag lists the zoom ratio ranges for all
+ * supported non-OFF bokeh modes, in the same order as in
+ * {@link CameraCharacteristics#CONTROL_AVAILABLE_BOKEH_CAPABILITIES android.control.availableBokehCapabilities}.</p>
+ * <p>Range [1.0, 1.0] means that no zoom (optical or digital) is supported.</p>
+ * <p><b>Units</b>: (minZoom, maxZoom)</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
+ *
+ * @see CameraCharacteristics#CONTROL_AVAILABLE_BOKEH_CAPABILITIES
+ * @see CaptureRequest#CONTROL_BOKEH_MODE
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @hide
+ */
+ public static final Key<float[]> CONTROL_AVAILABLE_BOKEH_ZOOM_RATIO_RANGES =
+ new Key<float[]>("android.control.availableBokehZoomRatioRanges", float[].class);
+
+ /**
+ * <p>The list of bokeh modes for {@link CaptureRequest#CONTROL_BOKEH_MODE android.control.bokehMode} that are supported by
+ * this camera device, and each bokeh mode's capabilities such as maximum streaming size
+ * with bokeh effect, and supported zoom ratio ranges.</p>
+ * <p>For OFF mode, the camera behaves normally with no bokeh effect.</p>
+ * <p>For STILL_CAPTURE mode, the maximum streaming dimension specifies the limit under which
+ * bokeh is effective when capture intent is PREVIEW. Note that when capture intent is
+ * PREVIEW, the bokeh effect may not be as high quality compared to STILL_CAPTURE intent
+ * in order to maintain reasonable frame rate. The maximum streaming dimension must be one
+ * of the YUV_420_888 or PRIVATE resolutions in availableStreamConfigurations, or (0, 0)
+ * if preview bokeh is not supported. If the application configures a stream larger than
+ * the maximum streaming dimension, bokeh effect may not be applied for this stream for
+ * PREVIEW intent.</p>
+ * <p>For CONTINUOUS mode, the maximum streaming dimension specifies the limit under which
+ * bokeh is effective. This dimension must be one of the YUV_420_888 or PRIVATE resolutions
+ * in availableStreamConfigurations, and if the sensor maximum resolution is larger than or
+ * equal to 1080p, the maximum streaming dimension must be at least 1080p. If the
+ * application configures a stream with larger dimension, the stream may not have bokeh
+ * effect applied.</p>
+ * <p>When bokeh mode is enabled, the camera device may have limited range of zoom ratios
+ * compared to when bokeh mode is disabled. availableBokehCapabilities lists the zoom
+ * ranges for all supported bokeh modes. A range of (1.0, 1.0) means that no zoom
+ * (optical or digital) is supported.</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#CONTROL_BOKEH_MODE
+ */
+ @PublicKey
+ @NonNull
+ @SyntheticKey
+ public static final Key<android.hardware.camera2.params.Capability[]> CONTROL_AVAILABLE_BOKEH_CAPABILITIES =
+ new Key<android.hardware.camera2.params.Capability[]>("android.control.availableBokehCapabilities", android.hardware.camera2.params.Capability[].class);
+
+ /**
+ * <p>Minimum and maximum zoom ratios supported by this camera device.</p>
+ * <p>If the camera device supports zoom-out from 1x zoom, minZoom will be less than 1.0, and
+ * setting android.control.zoomRation to values less than 1.0 increases the camera's field
+ * of view.</p>
+ * <p><b>Units</b>: A pair of zoom ratio in floating points: (minZoom, maxZoom)</p>
+ * <p><b>Range of valid values:</b><br></p>
+ * <p>maxZoom &gt;= 1.0 &gt;= minZoom</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
+ *
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
*/
@PublicKey
@NonNull
- public static final Key<android.hardware.camera2.params.CapabilityAndMaxSize[]> CONTROL_AVAILABLE_BOKEH_CAPABILITIES =
- new Key<android.hardware.camera2.params.CapabilityAndMaxSize[]>("android.control.availableBokehCapabilities", android.hardware.camera2.params.CapabilityAndMaxSize[].class);
+ public static final Key<android.util.Range<Float>> CONTROL_ZOOM_RATIO_RANGE =
+ new Key<android.util.Range<Float>>("android.control.zoomRatioRange", new TypeReference<android.util.Range<Float>>() {{ }});
/**
* <p>List of edge enhancement modes for {@link CaptureRequest#EDGE_MODE android.edge.mode} that are supported by this camera
@@ -2215,11 +2289,16 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <p>Crop regions that have a width or height that is smaller
* than this ratio allows will be rounded up to the minimum
* allowed size by the camera device.</p>
+ * <p>Starting from API level 30, when using {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} to zoom in or out,
+ * the application must use {@link CameraCharacteristics#CONTROL_ZOOM_RATIO_RANGE android.control.zoomRatioRange} to query both the minimum and
+ * maximum zoom ratio.</p>
* <p><b>Units</b>: Zoom scale factor</p>
* <p><b>Range of valid values:</b><br>
* &gt;=1</p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
+ * @see CameraCharacteristics#CONTROL_ZOOM_RATIO_RANGE
* @see CaptureRequest#SCALER_CROP_REGION
*/
@PublicKey
@@ -2667,6 +2746,21 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <p>Camera devices that support FREEFORM cropping will support any crop region that
* is inside of the active array. The camera device will apply the same crop region and
* return the final used crop region in capture result metadata {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}.</p>
+ * <p>Starting from API level 30,</p>
+ * <ul>
+ * <li>If the camera device supports FREEFORM cropping, in order to do FREEFORM cropping, the
+ * application must set {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} to 1.0, and use {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}
+ * for zoom.</li>
+ * <li>To do CENTER_ONLY zoom, the application has below 2 options:<ol>
+ * <li>Set {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} to 1.0; adjust zoom by {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}.</li>
+ * <li>Adjust zoom by {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}; use {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to crop
+ * the field of view vertically (letterboxing) or horizontally (pillarboxing), but not
+ * windowboxing.</li>
+ * </ol>
+ * </li>
+ * <li>Setting {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} to values different than 1.0 and
+ * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to be windowboxing at the same time is undefined behavior.</li>
+ * </ul>
* <p>LEGACY capability devices will only support CENTER_ONLY cropping.</p>
* <p><b>Possible values:</b>
* <ul>
@@ -2675,6 +2769,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* </ul></p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
* @see #SCALER_CROPPING_TYPE_CENTER_ONLY
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index f2a7abd60d85..8e0a46d52dd6 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -764,6 +764,7 @@ public abstract class CameraMetadata<TKey> {
* <li>{@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions}</li>
* <li>{@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}</li>
* <li>{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}</li>
+ * <li>{@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}</li>
* </ul>
* <p>Outside of android.control.*, the following controls will work:</p>
* <ul>
@@ -812,6 +813,7 @@ public abstract class CameraMetadata<TKey> {
* @see CaptureRequest#CONTROL_AWB_REGIONS
* @see CaptureRequest#CONTROL_EFFECT_MODE
* @see CaptureRequest#CONTROL_MODE
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#FLASH_MODE
* @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
@@ -2316,6 +2318,7 @@ public abstract class CameraMetadata<TKey> {
* <li>{@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions}</li>
* <li>{@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}</li>
* <li>{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}</li>
+ * <li>{@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}</li>
* </ul>
* <p>Outside of android.control.*, the following controls will work:</p>
* <ul>
@@ -2362,6 +2365,7 @@ public abstract class CameraMetadata<TKey> {
* @see CaptureRequest#CONTROL_AWB_REGIONS
* @see CaptureRequest#CONTROL_EFFECT_MODE
* @see CaptureRequest#CONTROL_MODE
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#FLASH_MODE
* @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 5c76dff85a84..6bf57834ae6c 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1376,6 +1376,16 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
+ * <p>Starting from API level 30, the coordinate system of activeArraySize or
+ * preCorrectionActiveArraySize is used to represent post-zoomRatio field of view, not
+ * pre-zoom field of view. This means that the same aeRegions values at different
+ * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} represent different parts of the scene. The aeRegions
+ * coordinates are relative to the activeArray/preCorrectionActiveArray representing the
+ * zoomed field of view. If {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} is set to 1.0 (default), the same
+ * aeRegions at different {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} still represent the same parts of the
+ * scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
+ * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
+ * mode.</p>
* <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
* {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
* distortion correction capability and mode</p>
@@ -1386,6 +1396,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AE
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -1575,6 +1586,16 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
+ * <p>Starting from API level 30, the coordinate system of activeArraySize or
+ * preCorrectionActiveArraySize is used to represent post-zoomRatio field of view, not
+ * pre-zoom field of view. This means that the same afRegions values at different
+ * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} represent different parts of the scene. The afRegions
+ * coordinates are relative to the activeArray/preCorrectionActiveArray representing the
+ * zoomed field of view. If {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} is set to 1.0 (default), the same
+ * afRegions at different {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} still represent the same parts of the
+ * scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
+ * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
+ * mode.</p>
* <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
* {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
* distortion correction capability and mode</p>
@@ -1585,6 +1606,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AF
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -1767,6 +1789,16 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
+ * <p>Starting from API level 30, the coordinate system of activeArraySize or
+ * preCorrectionActiveArraySize is used to represent post-zoomRatio field of view, not
+ * pre-zoom field of view. This means that the same awbRegions values at different
+ * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} represent different parts of the scene. The awbRegions
+ * coordinates are relative to the activeArray/preCorrectionActiveArray representing the
+ * zoomed field of view. If {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} is set to 1.0 (default), the same
+ * awbRegions at different {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} still represent the same parts of
+ * the scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
+ * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
+ * mode.</p>
* <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
* {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
* distortion correction capability and mode</p>
@@ -1777,6 +1809,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AWB
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -2140,6 +2173,56 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
new Key<Integer>("android.control.bokehMode", int.class);
/**
+ * <p>The desired zoom ratio</p>
+ * <p>Instead of using {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} with dual purposes of crop and zoom, the
+ * application can now choose to use this tag to specify the desired zoom level. The
+ * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} can still be used to specify the horizontal or vertical
+ * crop to achieve aspect ratios different than the native camera sensor.</p>
+ * <p>By using this control, the application gains a simpler way to control zoom, which can
+ * be a combination of optical and digital zoom. More specifically, for a logical
+ * multi-camera with more than one focal length, using a floating point zoom ratio offers
+ * more zoom precision when a telephoto lens is used, as well as allowing zoom ratio of
+ * less than 1.0 to zoom out to a wide field of view.</p>
+ * <p>Note that the coordinate system of cropRegion, AE/AWB/AF regions, and faces now changes
+ * to the effective after-zoom field-of-view represented by rectangle of (0, 0,
+ * activeArrayWidth, activeArrayHeight).</p>
+ * <p>For example, if {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} is 4032*3024, and the preview stream
+ * is configured to the same 4:3 aspect ratio, the application can achieve 2.0x zoom in
+ * one of two ways:</p>
+ * <ul>
+ * <li>zoomRatio = 2.0, scaler.cropRegion = (0, 0, 4032, 3024)</li>
+ * <li>zoomRatio = 1.0 (default), scaler.cropRegion = (1008, 756, 3024, 2268)</li>
+ * </ul>
+ * <p>If the application intends to set aeRegions to be top-left quarter of the preview
+ * field-of-view, the {@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions} should be set to (0, 0, 2016, 1512) with
+ * zoomRatio set to 2.0. Alternatively, the application can set aeRegions to the equivalent
+ * region of (1008, 756, 2016, 1512) for zoomRatio of 1.0. If the application doesn't
+ * explicitly set {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}, its value defaults to 1.0.</p>
+ * <p>This coordinate system change isn't applicable to RAW capture and its related metadata
+ * such as intrinsicCalibration and lensShadingMap.</p>
+ * <p>One limitation of controlling zoom using zoomRatio is that the {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}
+ * must only be used for letterboxing or pillarboxing of the sensor active array, and no
+ * FREEFORM cropping can be used with {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} other than 1.0.</p>
+ * <p><b>Range of valid values:</b><br>
+ * {@link CameraCharacteristics#CONTROL_ZOOM_RATIO_RANGE android.control.zoomRatioRange}</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
+ *
+ * @see CaptureRequest#CONTROL_AE_REGIONS
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
+ * @see CameraCharacteristics#CONTROL_ZOOM_RATIO_RANGE
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @see CaptureRequest#SCALER_CROP_REGION
+ * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ */
+ @PublicKey
+ @NonNull
+ public static final Key<Float> CONTROL_ZOOM_RATIO =
+ new Key<Float>("android.control.zoomRatio", float.class);
+
+ /**
* <p>Operation mode for edge
* enhancement.</p>
* <p>Edge enhancement improves sharpness and details in the captured image. OFF means
@@ -2697,12 +2780,21 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* for rounding and other hardware requirements; the final
* crop region used will be included in the output capture
* result.</p>
+ * <p>Starting from API level 30, it's strongly recommended to use {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}
+ * to take advantage of better support for zoom with logical multi-camera. The benefits
+ * include better precision with optical-digital zoom combination, and ability to do
+ * zoom-out from 1.0x. When using {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for zoom, the crop region in
+ * the capture request must be either letterboxing or pillarboxing (but not both). The
+ * coordinate system is post-zoom, meaning that the activeArraySize or
+ * preCorrectionActiveArraySize covers the camera device's field of view "after" zoom.
+ * See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details.</p>
* <p><b>Units</b>: Pixel coordinates relative to
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
* {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on distortion correction
* capability and mode</p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 2d0ec6d19286..c9956231f34c 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -780,6 +780,16 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
+ * <p>Starting from API level 30, the coordinate system of activeArraySize or
+ * preCorrectionActiveArraySize is used to represent post-zoomRatio field of view, not
+ * pre-zoom field of view. This means that the same aeRegions values at different
+ * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} represent different parts of the scene. The aeRegions
+ * coordinates are relative to the activeArray/preCorrectionActiveArray representing the
+ * zoomed field of view. If {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} is set to 1.0 (default), the same
+ * aeRegions at different {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} still represent the same parts of the
+ * scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
+ * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
+ * mode.</p>
* <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
* {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
* distortion correction capability and mode</p>
@@ -790,6 +800,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AE
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -1228,6 +1239,16 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
+ * <p>Starting from API level 30, the coordinate system of activeArraySize or
+ * preCorrectionActiveArraySize is used to represent post-zoomRatio field of view, not
+ * pre-zoom field of view. This means that the same afRegions values at different
+ * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} represent different parts of the scene. The afRegions
+ * coordinates are relative to the activeArray/preCorrectionActiveArray representing the
+ * zoomed field of view. If {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} is set to 1.0 (default), the same
+ * afRegions at different {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} still represent the same parts of the
+ * scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
+ * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
+ * mode.</p>
* <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
* {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
* distortion correction capability and mode</p>
@@ -1238,6 +1259,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AF
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -1830,6 +1852,16 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* region and output only the intersection rectangle as the metering region in the result
* metadata. If the region is entirely outside the crop region, it will be ignored and
* not reported in the result metadata.</p>
+ * <p>Starting from API level 30, the coordinate system of activeArraySize or
+ * preCorrectionActiveArraySize is used to represent post-zoomRatio field of view, not
+ * pre-zoom field of view. This means that the same awbRegions values at different
+ * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} represent different parts of the scene. The awbRegions
+ * coordinates are relative to the activeArray/preCorrectionActiveArray representing the
+ * zoomed field of view. If {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} is set to 1.0 (default), the same
+ * awbRegions at different {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} still represent the same parts of
+ * the scene as they do before. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use
+ * activeArraySize or preCorrectionActiveArraySize still depends on distortion correction
+ * mode.</p>
* <p><b>Units</b>: Pixel coordinates within {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
* {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on
* distortion correction capability and mode</p>
@@ -1840,6 +1872,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#CONTROL_MAX_REGIONS_AWB
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -2370,6 +2403,56 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
new Key<Integer>("android.control.bokehMode", int.class);
/**
+ * <p>The desired zoom ratio</p>
+ * <p>Instead of using {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} with dual purposes of crop and zoom, the
+ * application can now choose to use this tag to specify the desired zoom level. The
+ * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} can still be used to specify the horizontal or vertical
+ * crop to achieve aspect ratios different than the native camera sensor.</p>
+ * <p>By using this control, the application gains a simpler way to control zoom, which can
+ * be a combination of optical and digital zoom. More specifically, for a logical
+ * multi-camera with more than one focal length, using a floating point zoom ratio offers
+ * more zoom precision when a telephoto lens is used, as well as allowing zoom ratio of
+ * less than 1.0 to zoom out to a wide field of view.</p>
+ * <p>Note that the coordinate system of cropRegion, AE/AWB/AF regions, and faces now changes
+ * to the effective after-zoom field-of-view represented by rectangle of (0, 0,
+ * activeArrayWidth, activeArrayHeight).</p>
+ * <p>For example, if {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} is 4032*3024, and the preview stream
+ * is configured to the same 4:3 aspect ratio, the application can achieve 2.0x zoom in
+ * one of two ways:</p>
+ * <ul>
+ * <li>zoomRatio = 2.0, scaler.cropRegion = (0, 0, 4032, 3024)</li>
+ * <li>zoomRatio = 1.0 (default), scaler.cropRegion = (1008, 756, 3024, 2268)</li>
+ * </ul>
+ * <p>If the application intends to set aeRegions to be top-left quarter of the preview
+ * field-of-view, the {@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions} should be set to (0, 0, 2016, 1512) with
+ * zoomRatio set to 2.0. Alternatively, the application can set aeRegions to the equivalent
+ * region of (1008, 756, 2016, 1512) for zoomRatio of 1.0. If the application doesn't
+ * explicitly set {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}, its value defaults to 1.0.</p>
+ * <p>This coordinate system change isn't applicable to RAW capture and its related metadata
+ * such as intrinsicCalibration and lensShadingMap.</p>
+ * <p>One limitation of controlling zoom using zoomRatio is that the {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}
+ * must only be used for letterboxing or pillarboxing of the sensor active array, and no
+ * FREEFORM cropping can be used with {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} other than 1.0.</p>
+ * <p><b>Range of valid values:</b><br>
+ * {@link CameraCharacteristics#CONTROL_ZOOM_RATIO_RANGE android.control.zoomRatioRange}</p>
+ * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
+ * <p><b>Limited capability</b> -
+ * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
+ * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
+ *
+ * @see CaptureRequest#CONTROL_AE_REGIONS
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
+ * @see CameraCharacteristics#CONTROL_ZOOM_RATIO_RANGE
+ * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+ * @see CaptureRequest#SCALER_CROP_REGION
+ * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+ */
+ @PublicKey
+ @NonNull
+ public static final Key<Float> CONTROL_ZOOM_RATIO =
+ new Key<Float>("android.control.zoomRatio", float.class);
+
+ /**
* <p>Operation mode for edge
* enhancement.</p>
* <p>Edge enhancement improves sharpness and details in the captured image. OFF means
@@ -3336,12 +3419,21 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* for rounding and other hardware requirements; the final
* crop region used will be included in the output capture
* result.</p>
+ * <p>Starting from API level 30, it's strongly recommended to use {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}
+ * to take advantage of better support for zoom with logical multi-camera. The benefits
+ * include better precision with optical-digital zoom combination, and ability to do
+ * zoom-out from 1.0x. When using {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for zoom, the crop region in
+ * the capture request must be either letterboxing or pillarboxing (but not both). The
+ * coordinate system is post-zoom, meaning that the activeArraySize or
+ * preCorrectionActiveArraySize covers the camera device's field of view "after" zoom.
+ * See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details.</p>
* <p><b>Units</b>: Pixel coordinates relative to
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize} or
* {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize} depending on distortion correction
* capability and mode</p>
* <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#DISTORTION_CORRECTION_MODE
* @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
@@ -3877,10 +3969,21 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* When the distortion correction mode is not OFF, the coordinate system follows
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
* <code>(0, 0)</code> being the top-left pixel of the active array.</p>
- * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} == FULL
- * This key is available on all devices.</p>
+ * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} == FULL.</p>
+ * <p>Starting from API level 30, the coordinate system of activeArraySize or
+ * preCorrectionActiveArraySize is used to represent post-zoomRatio field of view, not
+ * pre-zoomRatio field of view. This means that if the relative position of faces and
+ * the camera device doesn't change, when zooming in by increasing
+ * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}, the face landmarks move farther away from the center of the
+ * activeArray or preCorrectionActiveArray. If {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} is set to 1.0
+ * (default), the face landmarks coordinates won't change as {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}
+ * changes. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use activeArraySize or
+ * preCorrectionActiveArraySize still depends on distortion correction mode.</p>
+ * <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#DISTORTION_CORRECTION_MODE
+ * @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
* @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
@@ -3903,10 +4006,21 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* When the distortion correction mode is not OFF, the coordinate system follows
* {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}, with
* <code>(0, 0)</code> being the top-left pixel of the active array.</p>
- * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} != OFF
- * This key is available on all devices.</p>
+ * <p>Only available if {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} != OFF.</p>
+ * <p>Starting from API level 30, the coordinate system of activeArraySize or
+ * preCorrectionActiveArraySize is used to represent post-zoomRatio field of view, not
+ * pre-zoomRatio field of view. This means that if the relative position of faces and
+ * the camera device doesn't change, when zooming in by increasing
+ * {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}, the face rectangles grow larger and move farther away from
+ * the center of the activeArray or preCorrectionActiveArray. If {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio}
+ * is set to 1.0 (default), the face rectangles won't change as {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}
+ * changes. See {@link CaptureRequest#CONTROL_ZOOM_RATIO android.control.zoomRatio} for details. Whether to use activeArraySize or
+ * preCorrectionActiveArraySize still depends on distortion correction mode.</p>
+ * <p>This key is available on all devices.</p>
*
+ * @see CaptureRequest#CONTROL_ZOOM_RATIO
* @see CaptureRequest#DISTORTION_CORRECTION_MODE
+ * @see CaptureRequest#SCALER_CROP_REGION
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
* @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 7c1ddad5fe12..c3ebe434ca05 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -30,7 +30,6 @@ import android.hardware.camera2.marshal.MarshalRegistry;
import android.hardware.camera2.marshal.Marshaler;
import android.hardware.camera2.marshal.impl.MarshalQueryableArray;
import android.hardware.camera2.marshal.impl.MarshalQueryableBlackLevelPattern;
-import android.hardware.camera2.marshal.impl.MarshalQueryableCapabilityAndMaxSize;
import android.hardware.camera2.marshal.impl.MarshalQueryableBoolean;
import android.hardware.camera2.marshal.impl.MarshalQueryableColorSpaceTransform;
import android.hardware.camera2.marshal.impl.MarshalQueryableEnum;
@@ -50,7 +49,7 @@ import android.hardware.camera2.marshal.impl.MarshalQueryableSizeF;
import android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration;
import android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration;
import android.hardware.camera2.marshal.impl.MarshalQueryableString;
-import android.hardware.camera2.params.CapabilityAndMaxSize;
+import android.hardware.camera2.params.Capability;
import android.hardware.camera2.params.Face;
import android.hardware.camera2.params.HighSpeedVideoConfiguration;
import android.hardware.camera2.params.LensShadingMap;
@@ -71,6 +70,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.ServiceSpecificException;
import android.util.Log;
+import android.util.Range;
import android.util.Size;
import com.android.internal.util.Preconditions;
@@ -1385,22 +1385,57 @@ public class CameraMetadataNative implements Parcelable {
return samples;
}
- private CapabilityAndMaxSize[] getBokehCapabilities() {
- CapabilityAndMaxSize[] bcs = getBase(
- CameraCharacteristics.CONTROL_AVAILABLE_BOKEH_CAPABILITIES);
+ private Capability[] getBokehCapabilities() {
+ int[] bokehMaxSizes = getBase(CameraCharacteristics.CONTROL_AVAILABLE_BOKEH_MAX_SIZES);
+ float[] bokehZoomRanges = getBase(
+ CameraCharacteristics.CONTROL_AVAILABLE_BOKEH_ZOOM_RATIO_RANGES);
+ Range<Float> zoomRange = getBase(CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE);
+ float maxDigitalZoom = getBase(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
- if (bcs != null) {
- for (CapabilityAndMaxSize bc : bcs) {
- if (bc.getMode() < CameraMetadata.CONTROL_BOKEH_MODE_OFF ||
- bc.getMode() > CameraMetadata.CONTROL_BOKEH_MODE_CONTINUOUS) {
- throw new AssertionError(String.format(
- "bokehMode %d is out of valid range [%d, %d]", bc.getMode(),
- CameraMetadata.CONTROL_BOKEH_MODE_OFF,
- CameraMetadata.CONTROL_BOKEH_MODE_CONTINUOUS));
- }
+ if (bokehMaxSizes == null) {
+ return null;
+ }
+ if (bokehMaxSizes.length % 3 != 0) {
+ throw new AssertionError("availableBokehMaxSizes must be tuples of " +
+ "[mode, width, height]");
+ }
+ int numBokehModes = bokehMaxSizes.length / 3;
+ int numBokehZoomRanges = 0;
+ if (bokehZoomRanges != null) {
+ if (bokehZoomRanges.length % 2 != 0) {
+ throw new AssertionError("availableBokehZoomRanges must be tuples of " +
+ "[minZoom, maxZoom]");
+ }
+ numBokehZoomRanges = bokehZoomRanges.length / 2;
+ if (numBokehModes - numBokehZoomRanges != 1) {
+ throw new AssertionError("Number of bokeh zoom ranges must be 1 less than " +
+ "number of supported bokeh modes");
+ }
+ }
+
+ float bokehOffMinZoomRatio = 1.0f;
+ float bokehOffMaxZoomRatio = maxDigitalZoom;
+ if (zoomRange != null) {
+ bokehOffMinZoomRatio = zoomRange.getLower();
+ bokehOffMaxZoomRatio = zoomRange.getUpper();
+ }
+
+ Capability[] capabilities = new Capability[numBokehModes];
+ for (int i = 0, j = 0; i < numBokehModes; i++) {
+ int mode = bokehMaxSizes[3 * i];
+ int width = bokehMaxSizes[3 * i + 1];
+ int height = bokehMaxSizes[3 * i + 2];
+ if (mode != CameraMetadata.CONTROL_BOKEH_MODE_OFF && j < numBokehZoomRanges) {
+ capabilities[i] = new Capability(mode, width, height, bokehZoomRanges[2 * j],
+ bokehZoomRanges[2 * j + 1]);
+ j++;
+ } else {
+ capabilities[i] = new Capability(mode, width, height, bokehOffMinZoomRatio,
+ bokehOffMaxZoomRatio);
}
}
- return bcs;
+
+ return capabilities;
}
private <T> void setBase(CameraCharacteristics.Key<T> key, T value) {
@@ -1780,7 +1815,6 @@ public class CameraMetadataNative implements Parcelable {
new MarshalQueryableBlackLevelPattern(),
new MarshalQueryableHighSpeedVideoConfiguration(),
new MarshalQueryableRecommendedStreamConfiguration(),
- new MarshalQueryableCapabilityAndMaxSize(),
// generic parcelable marshaler (MUST BE LAST since it has lowest priority)
new MarshalQueryableParcelable(),
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableCapabilityAndMaxSize.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableCapabilityAndMaxSize.java
deleted file mode 100644
index 5c1f301369e1..000000000000
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableCapabilityAndMaxSize.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.hardware.camera2.marshal.impl;
-
-import android.hardware.camera2.marshal.MarshalQueryable;
-import android.hardware.camera2.marshal.Marshaler;
-import android.hardware.camera2.params.CapabilityAndMaxSize;
-import android.hardware.camera2.utils.TypeReference;
-import android.util.Size;
-
-import java.nio.ByteBuffer;
-
-import static android.hardware.camera2.impl.CameraMetadataNative.TYPE_INT32;
-import static android.hardware.camera2.marshal.MarshalHelpers.SIZEOF_INT32;
-
-/**
- * Marshal {@link CapabilityAndMaxSize} to/from {@link #TYPE_INT32} {@code x CapabilityAndMaxSize.COUNT}
- */
-public class MarshalQueryableCapabilityAndMaxSize implements MarshalQueryable<CapabilityAndMaxSize> {
- private static final int SIZE = SIZEOF_INT32 * CapabilityAndMaxSize.COUNT;
-
- private class MarshalerCapabilityAndMaxSize extends Marshaler<CapabilityAndMaxSize> {
- protected MarshalerCapabilityAndMaxSize(TypeReference<CapabilityAndMaxSize> typeReference,
- int nativeType) {
- super(MarshalQueryableCapabilityAndMaxSize.this, typeReference, nativeType);
- }
-
- @Override
- public void marshal(CapabilityAndMaxSize value, ByteBuffer buffer) {
- Size maxStreamingSize = value.getMaxStreamingSize();
-
- buffer.putInt(value.getMode());
- buffer.putInt(maxStreamingSize.getWidth());
- buffer.putInt(maxStreamingSize.getHeight());
- }
-
- @Override
- public CapabilityAndMaxSize unmarshal(ByteBuffer buffer) {
- int mode = buffer.getInt();
- int maxWidth = buffer.getInt();
- int maxHeight = buffer.getInt();
-
- return new CapabilityAndMaxSize(mode, maxWidth, maxHeight);
- }
-
- @Override
- public int getNativeSize() {
- return SIZE;
- }
- }
-
- @Override
- public Marshaler<CapabilityAndMaxSize> createMarshaler(
- TypeReference<CapabilityAndMaxSize> managedType, int nativeType) {
- return new MarshalerCapabilityAndMaxSize(managedType, nativeType);
- }
-
- @Override
- public boolean isTypeMappingSupported(
- TypeReference<CapabilityAndMaxSize> managedType, int nativeType) {
- return nativeType == TYPE_INT32 &&
- (CapabilityAndMaxSize.class.equals(managedType.getType()));
- }
-}
diff --git a/core/java/android/hardware/camera2/params/CapabilityAndMaxSize.java b/core/java/android/hardware/camera2/params/Capability.java
index be0829934a4b..367690c37960 100644
--- a/core/java/android/hardware/camera2/params/CapabilityAndMaxSize.java
+++ b/core/java/android/hardware/camera2/params/Capability.java
@@ -23,16 +23,17 @@ import android.annotation.NonNull;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.utils.HashCodeHelpers;
+import android.util.Range;
import android.util.Size;
/**
- * Immutable class to store the available camera capability and its
- * corresponding maximum streaming dimensions.
+ * Immutable class to store the camera capability, its corresponding maximum
+ * streaming dimension and zoom range.
*
* @see CameraCharacteristics#CONTROL_AVAILABLE_BOKEH_CAPABILITIES
*/
-public final class CapabilityAndMaxSize {
+public final class Capability {
/**
* @hide
*/
@@ -41,22 +42,31 @@ public final class CapabilityAndMaxSize {
private final int mMode;
private final int mMaxStreamingWidth;
private final int mMaxStreamingHeight;
+ private final float mMinZoomRatio;
+ private final float mMaxZoomRatio;
/**
- * Create a new CapabilityAndMaxSize object.
+ * Create a new Capability object.
*
* @param mode supported mode for a camera capability.
- * @param maxStreamingWidth width >= 0
- * @param maxStreamingHeight height >= 0
+ * @param maxStreamingWidth The width of the maximum streaming size for this mode
+ * @param maxStreamingHeight The height of the maximum streaming size for this mode
+ * @param minZoomRatio the minimum zoom ratio this mode supports
+ * @param maxZoomRatio the maximum zoom ratio this mode supports
*
+ * @throws IllegalArgumentException if any of the argument is not valid
* @hide
*/
- public CapabilityAndMaxSize(int mode, int maxStreamingWidth, int maxStreamingHeight) {
+ public Capability(int mode, int maxStreamingWidth, int maxStreamingHeight,
+ float minZoomRatio, float maxZoomRatio) {
mMode = mode;
mMaxStreamingWidth = checkArgumentNonnegative(maxStreamingWidth,
"maxStreamingWidth must be nonnegative");
mMaxStreamingHeight = checkArgumentNonnegative(maxStreamingHeight,
"maxStreamingHeight must be nonnegative");
+ mMinZoomRatio = checkArgumentInRange(minZoomRatio, 0.0f, 1.0f,
+ "minZoomRatio must be between 0.0f and 1.0f");
+ mMaxZoomRatio = maxZoomRatio;
}
/**
@@ -81,11 +91,22 @@ public final class CapabilityAndMaxSize {
}
/**
- * Compare two CapabilityAndMaxSize objects to see if they are equal.
+ * Return the zoom ratio range of this capability.
*
- * @param obj Another CapabilityAndMaxSize object
+ * @return The supported zoom ratio range supported by this capability
+ */
+ public @NonNull Range<Float> getZoomRatioRange() {
+ return new Range<Float>(mMinZoomRatio, mMaxZoomRatio);
+ }
+
+
+ /**
+ * Compare two Capability objects to see if they are equal.
+ *
+ * @param obj Another Capability object
*
- * @return {@code true} if the mode and max size are equal, {@code false} otherwise
+ * @return {@code true} if the mode, max size and zoom ratio range are equal,
+ * {@code false} otherwise
*/
@Override
public boolean equals(final Object obj) {
@@ -95,11 +116,13 @@ public final class CapabilityAndMaxSize {
if (this == obj) {
return true;
}
- if (obj instanceof CapabilityAndMaxSize) {
- final CapabilityAndMaxSize other = (CapabilityAndMaxSize) obj;
+ if (obj instanceof Capability) {
+ final Capability other = (Capability) obj;
return (mMode == other.mMode
&& mMaxStreamingWidth == other.mMaxStreamingWidth
- && mMaxStreamingHeight == other.mMaxStreamingHeight);
+ && mMaxStreamingHeight == other.mMaxStreamingHeight
+ && mMinZoomRatio == other.mMinZoomRatio
+ && mMaxZoomRatio == other.mMaxZoomRatio);
}
return false;
}
@@ -109,18 +132,20 @@ public final class CapabilityAndMaxSize {
*/
@Override
public int hashCode() {
- return HashCodeHelpers.hashCode(mMode, mMaxStreamingWidth, mMaxStreamingHeight);
+ return HashCodeHelpers.hashCode(mMode, mMaxStreamingWidth, mMaxStreamingHeight,
+ mMinZoomRatio, mMaxZoomRatio);
}
/**
- * Return the CapabilityAndMaxSize as a string representation
- * {@code "(mode:%d, maxStreamingSize:%d x %d)"}.
+ * Return the Capability as a string representation
+ * {@code "(mode:%d, maxStreamingSize:%d x %d, zoomRatio: %f-%f)"}.
*
* @return string representation of the capability and max streaming size.
*/
@Override
public String toString() {
- return String.format("(mode:%d, maxStreamingSize:%d x %d)",
- mMode, mMaxStreamingWidth, mMaxStreamingHeight);
+ return String.format("(mode:%d, maxStreamingSize:%d x %d, zoomRatio: %f-%f)",
+ mMode, mMaxStreamingWidth, mMaxStreamingHeight, mMinZoomRatio,
+ mMaxZoomRatio);
}
}