diff options
| author | Shuzhen Wang <shuzhenwang@google.com> | 2019-12-19 03:32:59 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-12-19 03:32:59 +0000 |
| commit | f8aca7b463ca4d3efc005dd7d189cf01d4efed4c (patch) | |
| tree | 731bcd90fbd0e1eaec330148a9993b1769b4dbd8 /core/java/android | |
| parent | 3bade4860ad1a0de088ff0318bc428bac4e7d02c (diff) | |
| parent | 55c1c3f8743867619d51ce681b8e307b81270da0 (diff) | |
Merge "Camera: Add support for CONTROL_ZOOM_RATIO"
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/hardware/camera2/CameraCharacteristics.java | 103 | ||||
| -rw-r--r-- | core/java/android/hardware/camera2/CameraMetadata.java | 4 | ||||
| -rw-r--r-- | core/java/android/hardware/camera2/CaptureRequest.java | 92 | ||||
| -rw-r--r-- | core/java/android/hardware/camera2/CaptureResult.java | 122 | ||||
| -rw-r--r-- | core/java/android/hardware/camera2/impl/CameraMetadataNative.java | 66 | ||||
| -rw-r--r-- | core/java/android/hardware/camera2/marshal/impl/MarshalQueryableCapabilityAndMaxSize.java | 77 | ||||
| -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 >= 1.0 >= 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> * >=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); } } |
