Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2014 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package android.hardware.camera2.legacy; |
| 18 | |
| 19 | import android.graphics.Rect; |
| 20 | import android.hardware.Camera; |
| 21 | import android.hardware.Camera.Parameters; |
| 22 | import android.hardware.camera2.CameraCharacteristics; |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 23 | import android.hardware.camera2.CaptureRequest; |
| 24 | import android.hardware.camera2.CaptureResult; |
| 25 | import android.hardware.camera2.impl.CameraMetadataNative; |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 26 | import android.hardware.camera2.legacy.ParameterUtils.WeightedRectangle; |
| 27 | import android.hardware.camera2.legacy.ParameterUtils.ZoomData; |
| 28 | import android.hardware.camera2.params.MeteringRectangle; |
| 29 | import android.hardware.camera2.utils.ListUtils; |
Ruben Brunk | 3fe9eba | 2014-07-24 13:33:47 -0700 | [diff] [blame] | 30 | import android.hardware.camera2.utils.ParamsUtils; |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 31 | import android.util.Log; |
| 32 | import android.util.Size; |
| 33 | |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 34 | import java.util.ArrayList; |
| 35 | import java.util.List; |
| 36 | |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 37 | import static android.hardware.camera2.CaptureResult.*; |
| 38 | |
| 39 | /** |
| 40 | * Provide legacy-specific implementations of camera2 CaptureResult for legacy devices. |
| 41 | */ |
Igor Murashkin | 83d8639 | 2014-07-18 14:37:19 -0700 | [diff] [blame] | 42 | @SuppressWarnings("deprecation") |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 43 | public class LegacyResultMapper { |
| 44 | private static final String TAG = "LegacyResultMapper"; |
Eino-Ville Talvala | a78791f | 2015-06-01 12:39:54 -0700 | [diff] [blame] | 45 | private static final boolean DEBUG = false; |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 46 | |
Ruben Brunk | d1f113d | 2014-07-11 11:46:20 -0700 | [diff] [blame] | 47 | private LegacyRequest mCachedRequest = null; |
| 48 | private CameraMetadataNative mCachedResult = null; |
| 49 | |
| 50 | /** |
| 51 | * Generate capture result metadata from the legacy camera request. |
| 52 | * |
| 53 | * <p>This method caches and reuses the result from the previous call to this method if |
| 54 | * the {@code parameters} of the subsequent {@link LegacyRequest} passed to this method |
| 55 | * have not changed.</p> |
| 56 | * |
| 57 | * @param legacyRequest a non-{@code null} legacy request containing the latest parameters |
| 58 | * @param timestamp the timestamp to use for this result in nanoseconds. |
| 59 | * |
| 60 | * @return {@link CameraMetadataNative} object containing result metadata. |
| 61 | */ |
| 62 | public CameraMetadataNative cachedConvertResultMetadata( |
Igor Murashkin | 56678d8 | 2014-07-28 10:50:08 -0700 | [diff] [blame] | 63 | LegacyRequest legacyRequest, long timestamp) { |
Igor Murashkin | 3a3eb15 | 2014-07-24 18:19:30 -0700 | [diff] [blame] | 64 | CameraMetadataNative result; |
| 65 | boolean cached; |
Ruben Brunk | d1f113d | 2014-07-11 11:46:20 -0700 | [diff] [blame] | 66 | |
Igor Murashkin | 3a3eb15 | 2014-07-24 18:19:30 -0700 | [diff] [blame] | 67 | /* |
| 68 | * Attempt to look up the result from the cache if the parameters haven't changed |
| 69 | */ |
Yin-Chia Yeh | c885b5b | 2016-01-29 16:09:49 -0800 | [diff] [blame] | 70 | if (mCachedRequest != null && |
| 71 | legacyRequest.parameters.same(mCachedRequest.parameters) && |
| 72 | legacyRequest.captureRequest.equals(mCachedRequest.captureRequest)) { |
Igor Murashkin | 3a3eb15 | 2014-07-24 18:19:30 -0700 | [diff] [blame] | 73 | result = new CameraMetadataNative(mCachedResult); |
| 74 | cached = true; |
| 75 | } else { |
Igor Murashkin | 4423957 | 2014-09-10 15:08:00 -0700 | [diff] [blame] | 76 | result = convertResultMetadata(legacyRequest); |
Igor Murashkin | 3a3eb15 | 2014-07-24 18:19:30 -0700 | [diff] [blame] | 77 | cached = false; |
| 78 | |
| 79 | // Always cache a *copy* of the metadata result, |
| 80 | // since api2's client side takes ownership of it after it receives a result |
| 81 | mCachedRequest = legacyRequest; |
| 82 | mCachedResult = new CameraMetadataNative(result); |
Ruben Brunk | d1f113d | 2014-07-11 11:46:20 -0700 | [diff] [blame] | 83 | } |
| 84 | |
Igor Murashkin | 3a3eb15 | 2014-07-24 18:19:30 -0700 | [diff] [blame] | 85 | /* |
| 86 | * Unconditionally set fields that change in every single frame |
| 87 | */ |
| 88 | { |
Igor Murashkin | 3a3eb15 | 2014-07-24 18:19:30 -0700 | [diff] [blame] | 89 | // sensor.timestamp |
| 90 | result.set(SENSOR_TIMESTAMP, timestamp); |
| 91 | } |
| 92 | |
Eino-Ville Talvala | a78791f | 2015-06-01 12:39:54 -0700 | [diff] [blame] | 93 | if (DEBUG) { |
Igor Murashkin | 3a3eb15 | 2014-07-24 18:19:30 -0700 | [diff] [blame] | 94 | Log.v(TAG, "cachedConvertResultMetadata - cached? " + cached + |
Igor Murashkin | 56678d8 | 2014-07-28 10:50:08 -0700 | [diff] [blame] | 95 | " timestamp = " + timestamp); |
Igor Murashkin | 3a3eb15 | 2014-07-24 18:19:30 -0700 | [diff] [blame] | 96 | |
| 97 | Log.v(TAG, "----- beginning of result dump ------"); |
| 98 | result.dumpToLog(); |
| 99 | Log.v(TAG, "----- end of result dump ------"); |
| 100 | } |
| 101 | |
| 102 | return result; |
Ruben Brunk | d1f113d | 2014-07-11 11:46:20 -0700 | [diff] [blame] | 103 | } |
| 104 | |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 105 | /** |
| 106 | * Generate capture result metadata from the legacy camera request. |
| 107 | * |
| 108 | * @param legacyRequest a non-{@code null} legacy request containing the latest parameters |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 109 | * @return a {@link CameraMetadataNative} object containing result metadata. |
| 110 | */ |
Igor Murashkin | 4423957 | 2014-09-10 15:08:00 -0700 | [diff] [blame] | 111 | private static CameraMetadataNative convertResultMetadata(LegacyRequest legacyRequest) { |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 112 | CameraCharacteristics characteristics = legacyRequest.characteristics; |
| 113 | CaptureRequest request = legacyRequest.captureRequest; |
| 114 | Size previewSize = legacyRequest.previewSize; |
| 115 | Camera.Parameters params = legacyRequest.parameters; |
| 116 | |
| 117 | CameraMetadataNative result = new CameraMetadataNative(); |
| 118 | |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 119 | Rect activeArraySize = characteristics.get( |
| 120 | CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); |
Shuzhen Wang | f807a41 | 2020-03-27 18:32:27 -0700 | [diff] [blame] | 121 | ZoomData zoomData = ParameterUtils.convertToLegacyZoom(activeArraySize, |
| 122 | request.get(CaptureRequest.SCALER_CROP_REGION), |
| 123 | request.get(CaptureRequest.CONTROL_ZOOM_RATIO), |
| 124 | previewSize, params); |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 125 | |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 126 | /* |
Igor Murashkin | 4423957 | 2014-09-10 15:08:00 -0700 | [diff] [blame] | 127 | * colorCorrection |
| 128 | */ |
| 129 | // colorCorrection.aberrationMode |
| 130 | { |
Yin-Chia Yeh | c885b5b | 2016-01-29 16:09:49 -0800 | [diff] [blame] | 131 | result.set(COLOR_CORRECTION_ABERRATION_MODE, |
| 132 | request.get(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE)); |
Igor Murashkin | 4423957 | 2014-09-10 15:08:00 -0700 | [diff] [blame] | 133 | } |
| 134 | |
| 135 | /* |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 136 | * control |
| 137 | */ |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 138 | |
| 139 | /* |
| 140 | * control.ae* |
| 141 | */ |
Igor Murashkin | 396532f | 2014-07-10 18:08:47 -0700 | [diff] [blame] | 142 | mapAe(result, characteristics, request, activeArraySize, zoomData, /*out*/params); |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 143 | |
Igor Murashkin | 733341b | 2014-07-29 18:38:04 -0700 | [diff] [blame] | 144 | /* |
| 145 | * control.af* |
| 146 | */ |
| 147 | mapAf(result, activeArraySize, zoomData, /*out*/params); |
Igor Murashkin | 83d8639 | 2014-07-18 14:37:19 -0700 | [diff] [blame] | 148 | |
Igor Murashkin | 733341b | 2014-07-29 18:38:04 -0700 | [diff] [blame] | 149 | /* |
| 150 | * control.awb* |
| 151 | */ |
| 152 | mapAwb(result, /*out*/params); |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 153 | |
Ruben Brunk | 3fe9eba | 2014-07-24 13:33:47 -0700 | [diff] [blame] | 154 | /* |
Igor Murashkin | 7336f47 | 2014-08-08 16:44:34 -0700 | [diff] [blame] | 155 | * control.captureIntent |
| 156 | */ |
| 157 | { |
| 158 | int captureIntent = ParamsUtils.getOrDefault(request, |
| 159 | CaptureRequest.CONTROL_CAPTURE_INTENT, |
| 160 | /*defaultValue*/CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW); |
| 161 | |
| 162 | captureIntent = LegacyRequestMapper.filterSupportedCaptureIntent(captureIntent); |
| 163 | |
| 164 | result.set(CONTROL_CAPTURE_INTENT, captureIntent); |
| 165 | } |
| 166 | |
| 167 | /* |
Ruben Brunk | 3fe9eba | 2014-07-24 13:33:47 -0700 | [diff] [blame] | 168 | * control.mode |
| 169 | */ |
| 170 | { |
| 171 | int controlMode = ParamsUtils.getOrDefault(request, CaptureRequest.CONTROL_MODE, |
| 172 | CONTROL_MODE_AUTO); |
| 173 | if (controlMode == CaptureResult.CONTROL_MODE_USE_SCENE_MODE) { |
| 174 | result.set(CONTROL_MODE, CONTROL_MODE_USE_SCENE_MODE); |
| 175 | } else { |
| 176 | result.set(CONTROL_MODE, CONTROL_MODE_AUTO); |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | /* |
| 181 | * control.sceneMode |
| 182 | */ |
| 183 | { |
| 184 | String legacySceneMode = params.getSceneMode(); |
| 185 | int mode = LegacyMetadataMapper.convertSceneModeFromLegacy(legacySceneMode); |
| 186 | if (mode != LegacyMetadataMapper.UNKNOWN_MODE) { |
| 187 | result.set(CaptureResult.CONTROL_SCENE_MODE, mode); |
Igor Murashkin | 8c4486c1 | 2014-08-08 14:02:36 -0700 | [diff] [blame] | 188 | // In case of SCENE_MODE == FACE_PRIORITY, LegacyFaceDetectMapper will override |
| 189 | // the result to say SCENE_MODE == FACE_PRIORITY. |
Ruben Brunk | 3fe9eba | 2014-07-24 13:33:47 -0700 | [diff] [blame] | 190 | } else { |
| 191 | Log.w(TAG, "Unknown scene mode " + legacySceneMode + |
| 192 | " returned by camera HAL, setting to disabled."); |
| 193 | result.set(CaptureResult.CONTROL_SCENE_MODE, CONTROL_SCENE_MODE_DISABLED); |
| 194 | } |
| 195 | } |
| 196 | |
Ruben Brunk | 3fe9eba | 2014-07-24 13:33:47 -0700 | [diff] [blame] | 197 | /* |
| 198 | * control.effectMode |
| 199 | */ |
| 200 | { |
| 201 | String legacyEffectMode = params.getColorEffect(); |
| 202 | int mode = LegacyMetadataMapper.convertEffectModeFromLegacy(legacyEffectMode); |
| 203 | if (mode != LegacyMetadataMapper.UNKNOWN_MODE) { |
| 204 | result.set(CaptureResult.CONTROL_EFFECT_MODE, mode); |
| 205 | } else { |
| 206 | Log.w(TAG, "Unknown effect mode " + legacyEffectMode + |
| 207 | " returned by camera HAL, setting to off."); |
| 208 | result.set(CaptureResult.CONTROL_EFFECT_MODE, CONTROL_EFFECT_MODE_OFF); |
| 209 | } |
| 210 | } |
| 211 | |
Igor Murashkin | 0a1ef4d | 2014-07-31 15:53:34 -0700 | [diff] [blame] | 212 | // control.videoStabilizationMode |
| 213 | { |
| 214 | int stabMode = |
| 215 | (params.isVideoStabilizationSupported() && params.getVideoStabilization()) ? |
| 216 | CONTROL_VIDEO_STABILIZATION_MODE_ON : |
| 217 | CONTROL_VIDEO_STABILIZATION_MODE_OFF; |
| 218 | result.set(CONTROL_VIDEO_STABILIZATION_MODE, stabMode); |
| 219 | } |
| 220 | |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 221 | /* |
Igor Murashkin | 396532f | 2014-07-10 18:08:47 -0700 | [diff] [blame] | 222 | * flash |
| 223 | */ |
| 224 | { |
Igor Murashkin | 733341b | 2014-07-29 18:38:04 -0700 | [diff] [blame] | 225 | // flash.mode, flash.state mapped in mapAeAndFlashMode |
Igor Murashkin | 396532f | 2014-07-10 18:08:47 -0700 | [diff] [blame] | 226 | } |
| 227 | |
| 228 | /* |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 229 | * lens |
| 230 | */ |
Igor Murashkin | 83d8639 | 2014-07-18 14:37:19 -0700 | [diff] [blame] | 231 | // lens.focusDistance |
| 232 | { |
| 233 | if (Parameters.FOCUS_MODE_INFINITY.equals(params.getFocusMode())) { |
| 234 | result.set(CaptureResult.LENS_FOCUS_DISTANCE, 0.0f); |
| 235 | } |
| 236 | } |
| 237 | |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 238 | // lens.focalLength |
| 239 | result.set(CaptureResult.LENS_FOCAL_LENGTH, params.getFocalLength()); |
| 240 | |
| 241 | /* |
Igor Murashkin | 3a3eb15 | 2014-07-24 18:19:30 -0700 | [diff] [blame] | 242 | * request |
| 243 | */ |
| 244 | // request.pipelineDepth |
| 245 | result.set(REQUEST_PIPELINE_DEPTH, |
| 246 | characteristics.get(CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH)); |
| 247 | |
| 248 | /* |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 249 | * scaler |
| 250 | */ |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 251 | mapScaler(result, zoomData, /*out*/params); |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 252 | |
| 253 | /* |
| 254 | * sensor |
| 255 | */ |
Igor Murashkin | 733341b | 2014-07-29 18:38:04 -0700 | [diff] [blame] | 256 | // sensor.timestamp varies every frame; mapping is done in #cachedConvertResultMetadata |
| 257 | { |
| 258 | // Unconditionally no test patterns |
| 259 | result.set(SENSOR_TEST_PATTERN_MODE, SENSOR_TEST_PATTERN_MODE_OFF); |
| 260 | } |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 261 | |
Ruben Brunk | 1dc1326 | 2014-07-31 11:43:27 -0700 | [diff] [blame] | 262 | /* |
| 263 | * jpeg |
| 264 | */ |
| 265 | // jpeg.gpsLocation |
| 266 | result.set(JPEG_GPS_LOCATION, request.get(CaptureRequest.JPEG_GPS_LOCATION)); |
| 267 | |
| 268 | // jpeg.orientation |
| 269 | result.set(JPEG_ORIENTATION, request.get(CaptureRequest.JPEG_ORIENTATION)); |
| 270 | |
| 271 | // jpeg.quality |
| 272 | result.set(JPEG_QUALITY, (byte) params.getJpegQuality()); |
| 273 | |
| 274 | // jpeg.thumbnailQuality |
| 275 | result.set(JPEG_THUMBNAIL_QUALITY, (byte) params.getJpegThumbnailQuality()); |
| 276 | |
| 277 | // jpeg.thumbnailSize |
| 278 | Camera.Size s = params.getJpegThumbnailSize(); |
| 279 | if (s != null) { |
| 280 | result.set(JPEG_THUMBNAIL_SIZE, ParameterUtils.convertSize(s)); |
| 281 | } else { |
| 282 | Log.w(TAG, "Null thumbnail size received from parameters."); |
| 283 | } |
| 284 | |
Igor Murashkin | 4423957 | 2014-09-10 15:08:00 -0700 | [diff] [blame] | 285 | /* |
| 286 | * noiseReduction.* |
| 287 | */ |
| 288 | // noiseReduction.mode |
Yin-Chia Yeh | c885b5b | 2016-01-29 16:09:49 -0800 | [diff] [blame] | 289 | result.set(NOISE_REDUCTION_MODE, request.get(CaptureRequest.NOISE_REDUCTION_MODE)); |
Igor Murashkin | 4423957 | 2014-09-10 15:08:00 -0700 | [diff] [blame] | 290 | |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 291 | return result; |
| 292 | } |
| 293 | |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 294 | private static void mapAe(CameraMetadataNative m, |
Igor Murashkin | 396532f | 2014-07-10 18:08:47 -0700 | [diff] [blame] | 295 | CameraCharacteristics characteristics, |
Igor Murashkin | 49a1d7b | 2014-07-10 16:46:07 -0700 | [diff] [blame] | 296 | CaptureRequest request, Rect activeArray, ZoomData zoomData, /*out*/Parameters p) { |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 297 | // control.aeAntiBandingMode |
| 298 | { |
| 299 | int antiBandingMode = LegacyMetadataMapper.convertAntiBandingModeOrDefault( |
| 300 | p.getAntibanding()); |
| 301 | m.set(CONTROL_AE_ANTIBANDING_MODE, antiBandingMode); |
| 302 | } |
| 303 | |
Igor Murashkin | 3e280b4 | 2014-07-09 17:20:23 -0700 | [diff] [blame] | 304 | // control.aeExposureCompensation |
| 305 | { |
| 306 | m.set(CONTROL_AE_EXPOSURE_COMPENSATION, p.getExposureCompensation()); |
| 307 | } |
| 308 | |
| 309 | // control.aeLock |
| 310 | { |
| 311 | boolean lock = p.isAutoExposureLockSupported() ? p.getAutoExposureLock() : false; |
| 312 | m.set(CONTROL_AE_LOCK, lock); |
Eino-Ville Talvala | a78791f | 2015-06-01 12:39:54 -0700 | [diff] [blame] | 313 | if (DEBUG) { |
Igor Murashkin | 49a1d7b | 2014-07-10 16:46:07 -0700 | [diff] [blame] | 314 | Log.v(TAG, |
| 315 | "mapAe - android.control.aeLock = " + lock + |
| 316 | ", supported = " + p.isAutoExposureLockSupported()); |
| 317 | } |
| 318 | |
| 319 | Boolean requestLock = request.get(CaptureRequest.CONTROL_AE_LOCK); |
| 320 | if (requestLock != null && requestLock != lock) { |
| 321 | Log.w(TAG, |
| 322 | "mapAe - android.control.aeLock was requested to " + requestLock + |
| 323 | " but resulted in " + lock); |
| 324 | } |
Igor Murashkin | 3e280b4 | 2014-07-09 17:20:23 -0700 | [diff] [blame] | 325 | } |
| 326 | |
Igor Murashkin | 396532f | 2014-07-10 18:08:47 -0700 | [diff] [blame] | 327 | // control.aeMode, flash.mode, flash.state |
| 328 | mapAeAndFlashMode(m, characteristics, p); |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 329 | |
| 330 | // control.aeState |
| 331 | if (LegacyMetadataMapper.LIE_ABOUT_AE_STATE) { |
| 332 | // Lie to pass CTS temporarily. |
| 333 | // TODO: Implement precapture trigger, after which we can report CONVERGED ourselves |
| 334 | m.set(CONTROL_AE_STATE, CONTROL_AE_STATE_CONVERGED); |
| 335 | } |
Igor Murashkin | d25388c | 2014-07-07 15:29:28 -0700 | [diff] [blame] | 336 | |
| 337 | // control.aeRegions |
Yin-Chia Yeh | 808150f | 2014-09-08 15:48:47 -0700 | [diff] [blame] | 338 | if (p.getMaxNumMeteringAreas() > 0) { |
Eino-Ville Talvala | a78791f | 2015-06-01 12:39:54 -0700 | [diff] [blame] | 339 | if (DEBUG) { |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 340 | String meteringAreas = p.get("metering-areas"); |
| 341 | Log.v(TAG, "mapAe - parameter dump; metering-areas: " + meteringAreas); |
| 342 | } |
Igor Murashkin | d25388c | 2014-07-07 15:29:28 -0700 | [diff] [blame] | 343 | |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 344 | MeteringRectangle[] meteringRectArray = getMeteringRectangles(activeArray, |
| 345 | zoomData, p.getMeteringAreas(), "AE"); |
| 346 | |
| 347 | m.set(CONTROL_AE_REGIONS, meteringRectArray); |
| 348 | } |
| 349 | |
Igor Murashkin | 733341b | 2014-07-29 18:38:04 -0700 | [diff] [blame] | 350 | } |
| 351 | |
| 352 | private static void mapAf(CameraMetadataNative m, |
| 353 | Rect activeArray, ZoomData zoomData, Camera.Parameters p) { |
| 354 | // control.afMode |
| 355 | m.set(CaptureResult.CONTROL_AF_MODE, convertLegacyAfMode(p.getFocusMode())); |
| 356 | |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 357 | // control.afRegions |
Yin-Chia Yeh | 808150f | 2014-09-08 15:48:47 -0700 | [diff] [blame] | 358 | if (p.getMaxNumFocusAreas() > 0) { |
Eino-Ville Talvala | a78791f | 2015-06-01 12:39:54 -0700 | [diff] [blame] | 359 | if (DEBUG) { |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 360 | String focusAreas = p.get("focus-areas"); |
| 361 | Log.v(TAG, "mapAe - parameter dump; focus-areas: " + focusAreas); |
| 362 | } |
| 363 | |
| 364 | MeteringRectangle[] meteringRectArray = getMeteringRectangles(activeArray, |
| 365 | zoomData, p.getFocusAreas(), "AF"); |
| 366 | |
| 367 | m.set(CONTROL_AF_REGIONS, meteringRectArray); |
| 368 | } |
Igor Murashkin | 733341b | 2014-07-29 18:38:04 -0700 | [diff] [blame] | 369 | } |
Igor Murashkin | 3e280b4 | 2014-07-09 17:20:23 -0700 | [diff] [blame] | 370 | |
Igor Murashkin | 733341b | 2014-07-29 18:38:04 -0700 | [diff] [blame] | 371 | private static void mapAwb(CameraMetadataNative m, Camera.Parameters p) { |
Igor Murashkin | 3e280b4 | 2014-07-09 17:20:23 -0700 | [diff] [blame] | 372 | // control.awbLock |
| 373 | { |
| 374 | boolean lock = p.isAutoWhiteBalanceLockSupported() ? |
| 375 | p.getAutoWhiteBalanceLock() : false; |
| 376 | m.set(CONTROL_AWB_LOCK, lock); |
| 377 | } |
Igor Murashkin | 733341b | 2014-07-29 18:38:04 -0700 | [diff] [blame] | 378 | |
| 379 | // control.awbMode |
| 380 | { |
| 381 | int awbMode = convertLegacyAwbMode(p.getWhiteBalance()); |
| 382 | m.set(CONTROL_AWB_MODE, awbMode); |
| 383 | } |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 384 | } |
| 385 | |
| 386 | private static MeteringRectangle[] getMeteringRectangles(Rect activeArray, ZoomData zoomData, |
| 387 | List<Camera.Area> meteringAreaList, String regionName) { |
| 388 | List<MeteringRectangle> meteringRectList = new ArrayList<>(); |
| 389 | if (meteringAreaList != null) { |
| 390 | for (Camera.Area area : meteringAreaList) { |
| 391 | WeightedRectangle rect = |
| 392 | ParameterUtils.convertCameraAreaToActiveArrayRectangle( |
| 393 | activeArray, zoomData, area); |
| 394 | |
| 395 | meteringRectList.add(rect.toMetering()); |
| 396 | } |
| 397 | } |
| 398 | |
Eino-Ville Talvala | a78791f | 2015-06-01 12:39:54 -0700 | [diff] [blame] | 399 | if (DEBUG) { |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 400 | Log.v(TAG, |
| 401 | "Metering rectangles for " + regionName + ": " |
| 402 | + ListUtils.listToString(meteringRectList)); |
| 403 | } |
| 404 | |
| 405 | return meteringRectList.toArray(new MeteringRectangle[0]); |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 406 | } |
| 407 | |
Igor Murashkin | 396532f | 2014-07-10 18:08:47 -0700 | [diff] [blame] | 408 | /** Map results for control.aeMode, flash.mode, flash.state */ |
| 409 | private static void mapAeAndFlashMode(CameraMetadataNative m, |
| 410 | CameraCharacteristics characteristics, Parameters p) { |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 411 | // Default: AE mode on but flash never fires |
| 412 | int flashMode = FLASH_MODE_OFF; |
Igor Murashkin | 396532f | 2014-07-10 18:08:47 -0700 | [diff] [blame] | 413 | // If there is no flash on this camera, the state is always unavailable |
| 414 | // , otherwise it's only known for TORCH/SINGLE modes |
| 415 | Integer flashState = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE) |
| 416 | ? null : FLASH_STATE_UNAVAILABLE; |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 417 | int aeMode = CONTROL_AE_MODE_ON; |
| 418 | |
Igor Murashkin | 396532f | 2014-07-10 18:08:47 -0700 | [diff] [blame] | 419 | String flashModeSetting = p.getFlashMode(); |
| 420 | |
| 421 | if (flashModeSetting != null) { |
| 422 | switch (flashModeSetting) { |
| 423 | case Parameters.FLASH_MODE_OFF: |
| 424 | break; // ok, using default |
| 425 | case Parameters.FLASH_MODE_AUTO: |
| 426 | aeMode = CONTROL_AE_MODE_ON_AUTO_FLASH; |
| 427 | break; |
| 428 | case Parameters.FLASH_MODE_ON: |
| 429 | // flashMode = SINGLE + aeMode = ON is indistinguishable from ON_ALWAYS_FLASH |
| 430 | flashMode = FLASH_MODE_SINGLE; |
| 431 | aeMode = CONTROL_AE_MODE_ON_ALWAYS_FLASH; |
| 432 | flashState = FLASH_STATE_FIRED; |
| 433 | break; |
| 434 | case Parameters.FLASH_MODE_RED_EYE: |
| 435 | aeMode = CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE; |
| 436 | break; |
| 437 | case Parameters.FLASH_MODE_TORCH: |
| 438 | flashMode = FLASH_MODE_TORCH; |
| 439 | flashState = FLASH_STATE_FIRED; |
| 440 | break; |
| 441 | default: |
| 442 | Log.w(TAG, |
| 443 | "mapAeAndFlashMode - Ignoring unknown flash mode " + p.getFlashMode()); |
| 444 | } |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 445 | } |
| 446 | |
Igor Murashkin | 396532f | 2014-07-10 18:08:47 -0700 | [diff] [blame] | 447 | // flash.state |
| 448 | m.set(FLASH_STATE, flashState); |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 449 | // flash.mode |
| 450 | m.set(FLASH_MODE, flashMode); |
| 451 | // control.aeMode |
| 452 | m.set(CONTROL_AE_MODE, aeMode); |
| 453 | } |
| 454 | |
Igor Murashkin | 83d8639 | 2014-07-18 14:37:19 -0700 | [diff] [blame] | 455 | private static int convertLegacyAfMode(String mode) { |
| 456 | if (mode == null) { |
| 457 | Log.w(TAG, "convertLegacyAfMode - no AF mode, default to OFF"); |
| 458 | return CONTROL_AF_MODE_OFF; |
| 459 | } |
| 460 | |
| 461 | switch (mode) { |
| 462 | case Parameters.FOCUS_MODE_AUTO: |
| 463 | return CONTROL_AF_MODE_AUTO; |
| 464 | case Parameters.FOCUS_MODE_CONTINUOUS_PICTURE: |
| 465 | return CONTROL_AF_MODE_CONTINUOUS_PICTURE; |
| 466 | case Parameters.FOCUS_MODE_CONTINUOUS_VIDEO: |
| 467 | return CONTROL_AF_MODE_CONTINUOUS_VIDEO; |
| 468 | case Parameters.FOCUS_MODE_EDOF: |
| 469 | return CONTROL_AF_MODE_EDOF; |
| 470 | case Parameters.FOCUS_MODE_MACRO: |
| 471 | return CONTROL_AF_MODE_MACRO; |
| 472 | case Parameters.FOCUS_MODE_FIXED: |
| 473 | return CONTROL_AF_MODE_OFF; |
| 474 | case Parameters.FOCUS_MODE_INFINITY: |
| 475 | return CONTROL_AF_MODE_OFF; |
| 476 | default: |
| 477 | Log.w(TAG, "convertLegacyAfMode - unknown mode " + mode + " , ignoring"); |
| 478 | return CONTROL_AF_MODE_OFF; |
| 479 | } |
| 480 | } |
| 481 | |
Igor Murashkin | 733341b | 2014-07-29 18:38:04 -0700 | [diff] [blame] | 482 | private static int convertLegacyAwbMode(String mode) { |
| 483 | if (mode == null) { |
| 484 | // OK: camera1 api may not support changing WB modes; assume AUTO |
| 485 | return CONTROL_AWB_MODE_AUTO; |
| 486 | } |
| 487 | |
| 488 | switch (mode) { |
| 489 | case Camera.Parameters.WHITE_BALANCE_AUTO: |
| 490 | return CONTROL_AWB_MODE_AUTO; |
| 491 | case Camera.Parameters.WHITE_BALANCE_INCANDESCENT: |
| 492 | return CONTROL_AWB_MODE_INCANDESCENT; |
| 493 | case Camera.Parameters.WHITE_BALANCE_FLUORESCENT: |
| 494 | return CONTROL_AWB_MODE_FLUORESCENT; |
| 495 | case Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT: |
| 496 | return CONTROL_AWB_MODE_WARM_FLUORESCENT; |
| 497 | case Camera.Parameters.WHITE_BALANCE_DAYLIGHT: |
| 498 | return CONTROL_AWB_MODE_DAYLIGHT; |
| 499 | case Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT: |
| 500 | return CONTROL_AWB_MODE_CLOUDY_DAYLIGHT; |
| 501 | case Camera.Parameters.WHITE_BALANCE_TWILIGHT: |
| 502 | return CONTROL_AWB_MODE_TWILIGHT; |
| 503 | case Camera.Parameters.WHITE_BALANCE_SHADE: |
| 504 | return CONTROL_AWB_MODE_SHADE; |
| 505 | default: |
| 506 | Log.w(TAG, "convertAwbMode - unrecognized WB mode " + mode); |
| 507 | return CONTROL_AWB_MODE_AUTO; |
| 508 | } |
| 509 | } |
| 510 | |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 511 | /** Map results for scaler.* */ |
| 512 | private static void mapScaler(CameraMetadataNative m, |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 513 | ZoomData zoomData, |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 514 | /*out*/Parameters p) { |
| 515 | /* |
| 516 | * scaler.cropRegion |
| 517 | */ |
| 518 | { |
Igor Murashkin | 7ee78d1e | 2014-07-09 14:21:29 -0700 | [diff] [blame] | 519 | m.set(SCALER_CROP_REGION, zoomData.reportedCrop); |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 520 | } |
Shuzhen Wang | f807a41 | 2020-03-27 18:32:27 -0700 | [diff] [blame] | 521 | |
| 522 | /* |
| 523 | * control.zoomRatio |
| 524 | */ |
| 525 | { |
| 526 | m.set(CONTROL_ZOOM_RATIO, zoomData.reportedZoomRatio); |
| 527 | } |
Igor Murashkin | df6242e | 2014-07-01 18:06:13 -0700 | [diff] [blame] | 528 | } |
| 529 | } |