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