LegacyMetadataMapper.java revision 733341bf0db89c93ee1341ddfca9b0c49731c836
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 17package android.hardware.camera2.legacy; 18 19import android.graphics.ImageFormat; 20import android.graphics.Rect; 21import android.hardware.Camera; 22import android.hardware.Camera.CameraInfo; 23import android.hardware.Camera.Parameters; 24import android.hardware.camera2.CameraCharacteristics; 25import android.hardware.camera2.CameraDevice; 26import android.hardware.camera2.CameraMetadata; 27import android.hardware.camera2.CaptureRequest; 28import android.hardware.camera2.CaptureResult; 29import android.hardware.camera2.impl.CameraMetadataNative; 30import android.hardware.camera2.params.MeteringRectangle; 31import android.hardware.camera2.params.StreamConfiguration; 32import android.hardware.camera2.params.StreamConfigurationDuration; 33import android.hardware.camera2.utils.ArrayUtils; 34import android.hardware.camera2.utils.ListUtils; 35import android.hardware.camera2.utils.ParamsUtils; 36import android.util.Log; 37import android.util.Range; 38import android.util.Size; 39 40import java.util.ArrayList; 41import java.util.Arrays; 42import java.util.List; 43 44import static com.android.internal.util.Preconditions.*; 45import static android.hardware.camera2.CameraCharacteristics.*; 46import static android.hardware.camera2.legacy.ParameterUtils.*; 47 48/** 49 * Provide legacy-specific implementations of camera2 metadata for legacy devices, such as the 50 * camera characteristics. 51 */ 52@SuppressWarnings("deprecation") 53public class LegacyMetadataMapper { 54 private static final String TAG = "LegacyMetadataMapper"; 55 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); 56 57 private static final long NS_PER_MS = 1000000; 58 59 // from graphics.h 60 private static final int HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22; 61 private static final int HAL_PIXEL_FORMAT_BLOB = 0x21; 62 63 // for metadata 64 private static final float LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS = 0.0f; 65 66 private static final int REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_RAW = 0; // no raw support 67 private static final int REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_PROC = 3; // preview, video, cb 68 private static final int REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_PROC_STALL = 1; // 1 jpeg only 69 private static final int REQUEST_MAX_NUM_INPUT_STREAMS_COUNT = 0; // no reprocessing 70 71 /** Assume 3 HAL1 stages: Exposure, Read-out, Post-Processing */ 72 private static final int REQUEST_PIPELINE_MAX_DEPTH_HAL1 = 3; 73 /** Assume 3 shim stages: Preview input, Split output, Format conversion for output */ 74 private static final int REQUEST_PIPELINE_MAX_DEPTH_OURS = 3; 75 /* TODO: Update above maxDepth values once we do more performance measurements */ 76 77 // For approximating JPEG stall durations 78 private static final long APPROXIMATE_CAPTURE_DELAY_MS = 200; // 200 milliseconds 79 private static final long APPROXIMATE_SENSOR_AREA_PX = (1 << 23); // 8 megapixels 80 private static final long APPROXIMATE_JPEG_ENCODE_TIME_MS = 600; // 600 milliseconds 81 82 static final int UNKNOWN_MODE = -1; 83 84 /* 85 * Development hijinks: Lie about not supporting certain capabilities 86 * 87 * - Unblock some CTS tests from running whose main intent is not the metadata itself 88 * 89 * TODO: Remove these constants and strip out any code that previously relied on them 90 * being set to true. 91 */ 92 static final boolean LIE_ABOUT_AE_STATE = false; 93 static final boolean LIE_ABOUT_AE_MAX_REGIONS = false; 94 static final boolean LIE_ABOUT_AF = false; 95 static final boolean LIE_ABOUT_AF_MAX_REGIONS = false; 96 static final boolean LIE_ABOUT_AWB_STATE = false; 97 static final boolean LIE_ABOUT_AWB = false; 98 99 /** 100 * Create characteristics for a legacy device by mapping the {@code parameters} 101 * and {@code info} 102 * 103 * @param parameters A non-{@code null} parameters set 104 * @param info Camera info with camera facing direction and angle of orientation 105 * 106 * @return static camera characteristics for a camera device 107 * 108 * @throws NullPointerException if any of the args were {@code null} 109 */ 110 public static CameraCharacteristics createCharacteristics(Camera.Parameters parameters, 111 CameraInfo info) { 112 checkNotNull(parameters, "parameters must not be null"); 113 checkNotNull(info, "info must not be null"); 114 115 String paramStr = parameters.flatten(); 116 android.hardware.CameraInfo outerInfo = new android.hardware.CameraInfo(); 117 outerInfo.info = info; 118 119 return createCharacteristics(paramStr, outerInfo); 120 } 121 122 /** 123 * Create characteristics for a legacy device by mapping the {@code parameters} 124 * and {@code info} 125 * 126 * @param parameters A string parseable by {@link Camera.Parameters#unflatten} 127 * @param info Camera info with camera facing direction and angle of orientation 128 * @return static camera characteristics for a camera device 129 * 130 * @throws NullPointerException if any of the args were {@code null} 131 */ 132 public static CameraCharacteristics createCharacteristics(String parameters, 133 android.hardware.CameraInfo info) { 134 checkNotNull(parameters, "parameters must not be null"); 135 checkNotNull(info, "info must not be null"); 136 checkNotNull(info.info, "info.info must not be null"); 137 138 CameraMetadataNative m = new CameraMetadataNative(); 139 140 mapCharacteristicsFromInfo(m, info.info); 141 142 Camera.Parameters params = Camera.getEmptyParameters(); 143 params.unflatten(parameters); 144 mapCharacteristicsFromParameters(m, params); 145 146 if (VERBOSE) { 147 Log.v(TAG, "createCharacteristics metadata:"); 148 Log.v(TAG, "--------------------------------------------------- (start)"); 149 m.dumpToLog(); 150 Log.v(TAG, "--------------------------------------------------- (end)"); 151 } 152 153 return new CameraCharacteristics(m); 154 } 155 156 private static void mapCharacteristicsFromInfo(CameraMetadataNative m, CameraInfo i) { 157 m.set(LENS_FACING, i.facing == CameraInfo.CAMERA_FACING_BACK ? 158 LENS_FACING_BACK : LENS_FACING_FRONT); 159 m.set(SENSOR_ORIENTATION, i.orientation); 160 } 161 162 private static void mapCharacteristicsFromParameters(CameraMetadataNative m, 163 Camera.Parameters p) { 164 /* 165 * control.ae* 166 */ 167 mapControlAe(m, p); 168 /* 169 * control.af* 170 */ 171 mapControlAf(m, p); 172 /* 173 * control.awb* 174 */ 175 mapControlAwb(m, p); 176 /* 177 * control.* 178 * - Anything that doesn't have a set of related fields 179 */ 180 mapControlOther(m, p); 181 /* 182 * lens.* 183 */ 184 mapLens(m, p); 185 /* 186 * flash.* 187 */ 188 mapFlash(m, p); 189 190 /* 191 * request.* 192 */ 193 mapRequest(m, p); 194 // TODO: map other fields 195 196 /* 197 * scaler.* 198 */ 199 mapScaler(m, p); 200 201 /* 202 * sensor.* 203 */ 204 mapSensor(m, p); 205 206 /* 207 * sync.* 208 */ 209 mapSync(m, p); 210 211 /* 212 * info.supportedHardwareLevel 213 */ 214 m.set(INFO_SUPPORTED_HARDWARE_LEVEL, INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY); 215 216 /* 217 * scaler.availableStream*, scaler.available*Durations, sensor.info.maxFrameDuration 218 */ 219 mapScalerStreamConfigs(m, p); 220 221 } 222 223 private static void mapScalerStreamConfigs(CameraMetadataNative m, Camera.Parameters p) { 224 225 ArrayList<StreamConfiguration> availableStreamConfigs = new ArrayList<>(); 226 /* 227 * Implementation-defined (preview, recording, etc) -> use camera1 preview sizes 228 * YUV_420_888 cpu callbacks -> use camera1 preview sizes 229 * Other preview callbacks (CPU) -> use camera1 preview sizes 230 * JPEG still capture -> use camera1 still capture sizes 231 * 232 * Use platform-internal format constants here, since StreamConfigurationMap does the 233 * remapping to public format constants. 234 */ 235 List<Camera.Size> previewSizes = p.getSupportedPreviewSizes(); 236 appendStreamConfig(availableStreamConfigs, 237 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, previewSizes); 238 appendStreamConfig(availableStreamConfigs, 239 ImageFormat.YUV_420_888, previewSizes); 240 for (int format : p.getSupportedPreviewFormats()) { 241 if (ImageFormat.isPublicFormat(format)) { 242 appendStreamConfig(availableStreamConfigs, format, previewSizes); 243 } else { 244 /* 245 * Do not add any formats unknown to us 246 * (since it would fail runtime checks in StreamConfigurationMap) 247 */ 248 Log.w(TAG, 249 String.format("mapStreamConfigs - Skipping non-public format %x", format)); 250 } 251 } 252 253 List<Camera.Size> jpegSizes = p.getSupportedPictureSizes(); 254 appendStreamConfig(availableStreamConfigs, 255 HAL_PIXEL_FORMAT_BLOB, p.getSupportedPictureSizes()); 256 /* 257 * scaler.availableStreamConfigurations 258 */ 259 m.set(SCALER_AVAILABLE_STREAM_CONFIGURATIONS, 260 availableStreamConfigs.toArray(new StreamConfiguration[0])); 261 262 /* 263 * scaler.availableMinFrameDurations 264 */ 265 // No frame durations available 266 m.set(SCALER_AVAILABLE_MIN_FRAME_DURATIONS, new StreamConfigurationDuration[0]); 267 268 StreamConfigurationDuration[] jpegStalls = 269 new StreamConfigurationDuration[jpegSizes.size()]; 270 int i = 0; 271 long longestStallDuration = -1; 272 for (Camera.Size s : jpegSizes) { 273 long stallDuration = calculateJpegStallDuration(s); 274 jpegStalls[i++] = new StreamConfigurationDuration(HAL_PIXEL_FORMAT_BLOB, s.width, 275 s.height, stallDuration); 276 if (longestStallDuration < stallDuration) { 277 longestStallDuration = stallDuration; 278 } 279 } 280 /* 281 * scaler.availableStallDurations 282 */ 283 // Set stall durations for jpeg, other formats use default stall duration 284 m.set(SCALER_AVAILABLE_STALL_DURATIONS, jpegStalls); 285 286 /* 287 * sensor.info.maxFrameDuration 288 */ 289 m.set(SENSOR_INFO_MAX_FRAME_DURATION, longestStallDuration); 290 } 291 292 @SuppressWarnings({"unchecked"}) 293 private static void mapControlAe(CameraMetadataNative m, Camera.Parameters p) { 294 /* 295 * control.aeAvailableAntiBandingModes 296 */ 297 List<String> antiBandingModes = p.getSupportedAntibanding(); 298 if (antiBandingModes != null && antiBandingModes.size() > 0) { // antibanding is optional 299 int[] modes = new int[antiBandingModes.size()]; 300 int j = 0; 301 for (String mode : antiBandingModes) { 302 int convertedMode = convertAntiBandingMode(mode); 303 if (convertedMode == -1) { 304 Log.w(TAG, "Antibanding mode " + ((mode == null) ? "NULL" : mode) + 305 " not supported, skipping..."); 306 } else { 307 modes[j++] = convertedMode; 308 } 309 } 310 m.set(CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, Arrays.copyOf(modes, j)); 311 } else { 312 m.set(CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, new int[0]); 313 } 314 315 /* 316 * control.aeAvailableTargetFpsRanges 317 */ 318 { 319 List<int[]> fpsRanges = p.getSupportedPreviewFpsRange(); 320 if (fpsRanges == null) { 321 throw new AssertionError("Supported FPS ranges cannot be null."); 322 } 323 int rangesSize = fpsRanges.size(); 324 if (rangesSize <= 0) { 325 throw new AssertionError("At least one FPS range must be supported."); 326 } 327 Range<Integer>[] ranges = new Range[rangesSize]; 328 int i = 0; 329 for (int[] r : fpsRanges) { 330 ranges[i++] = Range.create(r[Camera.Parameters.PREVIEW_FPS_MIN_INDEX], 331 r[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]); 332 } 333 m.set(CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, ranges); 334 } 335 336 /* 337 * control.aeAvailableModes 338 */ 339 { 340 List<String> flashModes = p.getSupportedFlashModes(); 341 342 String[] flashModeStrings = new String[] { 343 Camera.Parameters.FLASH_MODE_OFF, 344 Camera.Parameters.FLASH_MODE_AUTO, 345 Camera.Parameters.FLASH_MODE_ON, 346 Camera.Parameters.FLASH_MODE_RED_EYE, 347 // Map these manually 348 Camera.Parameters.FLASH_MODE_TORCH, 349 }; 350 int[] flashModeInts = new int[] { 351 CONTROL_AE_MODE_ON, 352 CONTROL_AE_MODE_ON_AUTO_FLASH, 353 CONTROL_AE_MODE_ON_ALWAYS_FLASH, 354 CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE 355 }; 356 int[] aeAvail = ArrayUtils.convertStringListToIntArray( 357 flashModes, flashModeStrings, flashModeInts); 358 359 // No flash control -> AE is always on 360 if (aeAvail == null || aeAvail.length == 0) { 361 aeAvail = new int[] { 362 CONTROL_AE_MODE_ON 363 }; 364 } 365 366 // Note that AE_MODE_OFF is never available. 367 m.set(CONTROL_AE_AVAILABLE_MODES, aeAvail); 368 } 369 370 /* 371 * control.aeCompensationRanges 372 */ 373 { 374 int min = p.getMinExposureCompensation(); 375 int max = p.getMaxExposureCompensation(); 376 377 m.set(CONTROL_AE_COMPENSATION_RANGE, Range.create(min, max)); 378 } 379 380 /* 381 * control.aeCompensationStep 382 */ 383 { 384 float step = p.getExposureCompensationStep(); 385 386 m.set(CONTROL_AE_COMPENSATION_STEP, ParamsUtils.createRational(step)); 387 } 388 } 389 390 391 @SuppressWarnings({"unchecked"}) 392 private static void mapControlAf(CameraMetadataNative m, Camera.Parameters p) { 393 /* 394 * control.afAvailableModes 395 */ 396 { 397 List<String> focusModes = p.getSupportedFocusModes(); 398 399 String[] focusModeStrings = new String[] { 400 Camera.Parameters.FOCUS_MODE_AUTO, 401 Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE, 402 Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO, 403 Camera.Parameters.FOCUS_MODE_EDOF, 404 Camera.Parameters.FOCUS_MODE_INFINITY, 405 Camera.Parameters.FOCUS_MODE_MACRO, 406 Camera.Parameters.FOCUS_MODE_FIXED, 407 }; 408 409 int[] focusModeInts = new int[] { 410 CONTROL_AF_MODE_AUTO, 411 CONTROL_AF_MODE_CONTINUOUS_PICTURE, 412 CONTROL_AF_MODE_CONTINUOUS_VIDEO, 413 CONTROL_AF_MODE_EDOF, 414 CONTROL_AF_MODE_OFF, 415 CONTROL_AF_MODE_MACRO, 416 CONTROL_AF_MODE_OFF 417 }; 418 419 List<Integer> afAvail = ArrayUtils.convertStringListToIntList( 420 focusModes, focusModeStrings, focusModeInts); 421 422 // No AF modes supported? That's unpossible! 423 if (afAvail == null || afAvail.size() == 0) { 424 Log.w(TAG, "No AF modes supported (HAL bug); defaulting to AF_MODE_OFF only"); 425 afAvail = new ArrayList<Integer>(/*capacity*/1); 426 afAvail.add(CONTROL_AF_MODE_OFF); 427 } 428 429 m.set(CONTROL_AF_AVAILABLE_MODES, ArrayUtils.toIntArray(afAvail)); 430 431 if (VERBOSE) { 432 Log.v(TAG, "mapControlAf - control.afAvailableModes set to " + 433 ListUtils.listToString(afAvail)); 434 } 435 } 436 } 437 438 private static void mapControlAwb(CameraMetadataNative m, Camera.Parameters p) { 439 /* 440 * control.awbAvailableModes 441 */ 442 443 { 444 List<String> wbModes = p.getSupportedWhiteBalance(); 445 446 String[] wbModeStrings = new String[] { 447 Camera.Parameters.WHITE_BALANCE_AUTO , 448 Camera.Parameters.WHITE_BALANCE_INCANDESCENT , 449 Camera.Parameters.WHITE_BALANCE_FLUORESCENT , 450 Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT , 451 Camera.Parameters.WHITE_BALANCE_DAYLIGHT , 452 Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT , 453 Camera.Parameters.WHITE_BALANCE_TWILIGHT , 454 Camera.Parameters.WHITE_BALANCE_SHADE , 455 }; 456 457 int[] wbModeInts = new int[] { 458 CONTROL_AWB_MODE_AUTO, 459 CONTROL_AWB_MODE_INCANDESCENT , 460 CONTROL_AWB_MODE_FLUORESCENT , 461 CONTROL_AWB_MODE_WARM_FLUORESCENT , 462 CONTROL_AWB_MODE_DAYLIGHT , 463 CONTROL_AWB_MODE_CLOUDY_DAYLIGHT , 464 CONTROL_AWB_MODE_TWILIGHT , 465 CONTROL_AWB_MODE_SHADE , 466 // Note that CONTROL_AWB_MODE_OFF is unsupported 467 }; 468 469 List<Integer> awbAvail = ArrayUtils.convertStringListToIntList( 470 wbModes, wbModeStrings, wbModeInts); 471 472 // No AWB modes supported? That's unpossible! 473 if (awbAvail == null || awbAvail.size() == 0) { 474 Log.w(TAG, "No AWB modes supported (HAL bug); defaulting to AWB_MODE_AUTO only"); 475 awbAvail = new ArrayList<Integer>(/*capacity*/1); 476 awbAvail.add(CONTROL_AWB_MODE_AUTO); 477 } 478 479 m.set(CONTROL_AWB_AVAILABLE_MODES, ArrayUtils.toIntArray(awbAvail)); 480 481 if (VERBOSE) { 482 Log.v(TAG, "mapControlAwb - control.awbAvailableModes set to " + 483 ListUtils.listToString(awbAvail)); 484 } 485 } 486 } 487 488 private static void mapControlOther(CameraMetadataNative m, Camera.Parameters p) { 489 /* 490 * android.control.maxRegions 491 */ 492 final int AE = 0, AWB = 1, AF = 2; 493 494 int[] maxRegions = new int[3]; 495 maxRegions[AE] = p.getMaxNumMeteringAreas(); 496 maxRegions[AWB] = 0; // AWB regions not supported in API1 497 maxRegions[AF] = p.getMaxNumFocusAreas(); 498 499 if (LIE_ABOUT_AE_MAX_REGIONS) { 500 maxRegions[AE] = 0; 501 } 502 if (LIE_ABOUT_AF_MAX_REGIONS) { 503 maxRegions[AF] = 0; 504 } 505 506 m.set(CONTROL_MAX_REGIONS, maxRegions); 507 508 /* 509 * android.control.availableEffects 510 */ 511 List<String> effectModes = p.getSupportedColorEffects(); 512 int[] supportedEffectModes = (effectModes == null) ? new int[0] : 513 ArrayUtils.convertStringListToIntArray(effectModes, sLegacyEffectMode, 514 sEffectModes); 515 m.set(CONTROL_AVAILABLE_EFFECTS, supportedEffectModes); 516 517 /* 518 * android.control.availableSceneModes 519 */ 520 List<String> sceneModes = p.getSupportedSceneModes(); 521 int[] supportedSceneModes = (sceneModes == null) ? new int[0] : 522 ArrayUtils.convertStringListToIntArray(sceneModes, sLegacySceneModes, sSceneModes); 523 m.set(CONTROL_AVAILABLE_SCENE_MODES, supportedSceneModes); 524 } 525 526 private static void mapLens(CameraMetadataNative m, Camera.Parameters p) { 527 /* 528 * We can tell if the lens is fixed focus; 529 * but if it's not, we can't tell the minimum focus distance, so leave it null then. 530 */ 531 if (p.getFocusMode() == Camera.Parameters.FOCUS_MODE_FIXED) { 532 /* 533 * lens.info.minimumFocusDistance 534 */ 535 m.set(LENS_INFO_MINIMUM_FOCUS_DISTANCE, LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS); 536 } 537 538 float[] focalLengths = new float[] { p.getFocalLength() }; 539 m.set(LENS_INFO_AVAILABLE_FOCAL_LENGTHS, focalLengths); 540 } 541 542 private static void mapFlash(CameraMetadataNative m, Camera.Parameters p) { 543 boolean flashAvailable = false; 544 List<String> supportedFlashModes = p.getSupportedFlashModes(); 545 546 if (supportedFlashModes != null) { 547 // If only 'OFF' is available, we don't really have flash support 548 flashAvailable = !ListUtils.listElementsEqualTo( 549 supportedFlashModes, Camera.Parameters.FLASH_MODE_OFF); 550 } 551 552 /* 553 * flash.info.available 554 */ 555 m.set(FLASH_INFO_AVAILABLE, flashAvailable); 556 } 557 558 private static void mapRequest(CameraMetadataNative m, Parameters p) { 559 /* 560 * request.availableCapabilities 561 */ 562 int[] capabilities = { REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE }; 563 m.set(REQUEST_AVAILABLE_CAPABILITIES, capabilities); 564 565 /* 566 * request.availableCharacteristicsKeys 567 */ 568 { 569 // TODO: check if the underlying key is supported before listing a key as available 570 571 // Note: We only list public keys. Native HALs should list ALL keys regardless of visibility. 572 573 Key<?> availableKeys[] = new Key<?>[] { 574 CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES , 575 CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES , 576 CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES , 577 CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE , 578 CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP , 579 CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES , 580 CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS , 581 CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES , 582 CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES , 583 CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES , 584 CameraCharacteristics.CONTROL_MAX_REGIONS , 585 CameraCharacteristics.FLASH_INFO_AVAILABLE , 586 CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL , 587 CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES , 588 CameraCharacteristics.LENS_FACING , 589 CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS , 590 CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES , 591 CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_STREAMS , 592 CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT , 593 CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH , 594 CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM , 595// CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP , 596 CameraCharacteristics.SCALER_CROPPING_TYPE , 597 CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES , 598 CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE , 599 CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE , 600 CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE , 601 CameraCharacteristics.SENSOR_ORIENTATION , 602 CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES , 603 CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT , 604 CameraCharacteristics.SYNC_MAX_LATENCY , 605 }; 606 m.set(REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, getTagsForKeys(availableKeys)); 607 } 608 609 /* 610 * request.availableRequestKeys 611 */ 612 { 613 CaptureRequest.Key<?> availableKeys[] = new CaptureRequest.Key<?>[] { 614 CaptureRequest.CONTROL_AE_ANTIBANDING_MODE, 615 CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 616 CaptureRequest.CONTROL_AE_LOCK, 617 CaptureRequest.CONTROL_AE_MODE, 618 CaptureRequest.CONTROL_AE_REGIONS, 619 CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, 620 CaptureRequest.CONTROL_AF_MODE, 621 CaptureRequest.CONTROL_AF_REGIONS, 622 CaptureRequest.CONTROL_AF_TRIGGER, 623 CaptureRequest.CONTROL_AWB_LOCK, 624 CaptureRequest.CONTROL_AWB_MODE, 625 CaptureRequest.CONTROL_CAPTURE_INTENT, 626 CaptureRequest.CONTROL_EFFECT_MODE, 627 CaptureRequest.CONTROL_MODE, 628 CaptureRequest.CONTROL_SCENE_MODE, 629 CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, 630 CaptureRequest.FLASH_MODE, 631 CaptureRequest.JPEG_GPS_COORDINATES, 632 CaptureRequest.JPEG_GPS_PROCESSING_METHOD, 633 CaptureRequest.JPEG_GPS_TIMESTAMP, 634 CaptureRequest.JPEG_ORIENTATION, 635 CaptureRequest.JPEG_QUALITY, 636 CaptureRequest.JPEG_THUMBNAIL_QUALITY, 637 CaptureRequest.JPEG_THUMBNAIL_SIZE, 638 CaptureRequest.LENS_FOCAL_LENGTH, 639 CaptureRequest.SCALER_CROP_REGION, 640 CaptureRequest.STATISTICS_FACE_DETECT_MODE, 641 }; 642 m.set(REQUEST_AVAILABLE_REQUEST_KEYS, getTagsForKeys(availableKeys)); 643 } 644 645 /* 646 * request.availableResultKeys 647 */ 648 { 649 CaptureResult.Key<?> availableKeys[] = new CaptureResult.Key<?>[] { 650 CaptureResult.CONTROL_AE_ANTIBANDING_MODE , 651 CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION , 652 CaptureResult.CONTROL_AE_LOCK , 653 CaptureResult.CONTROL_AE_MODE , 654 CaptureResult.CONTROL_AE_REGIONS , 655 CaptureResult.CONTROL_AF_MODE , 656 CaptureResult.CONTROL_AF_REGIONS , 657 CaptureResult.CONTROL_AF_STATE , 658 CaptureResult.CONTROL_AWB_MODE , 659 CaptureResult.CONTROL_AWB_LOCK , 660 CaptureResult.CONTROL_MODE , 661 CaptureResult.FLASH_MODE , 662 CaptureResult.JPEG_GPS_COORDINATES , 663 CaptureResult.JPEG_GPS_PROCESSING_METHOD , 664 CaptureResult.JPEG_GPS_TIMESTAMP , 665 CaptureResult.JPEG_ORIENTATION , 666 CaptureResult.JPEG_QUALITY , 667 CaptureResult.JPEG_THUMBNAIL_QUALITY , 668 CaptureResult.LENS_FOCAL_LENGTH , 669 CaptureResult.REQUEST_PIPELINE_DEPTH , 670 CaptureResult.SCALER_CROP_REGION , 671 CaptureResult.SENSOR_TIMESTAMP , 672 CaptureResult.STATISTICS_FACE_DETECT_MODE , 673// CaptureResult.STATISTICS_FACES , 674 }; 675 m.set(REQUEST_AVAILABLE_RESULT_KEYS, getTagsForKeys(availableKeys)); 676 } 677 678 /* 679 * request.maxNumOutputStreams 680 */ 681 int[] outputStreams = { 682 /* RAW */ 683 REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_RAW, 684 /* Processed & Not-Stalling */ 685 REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_PROC, 686 /* Processed & Stalling */ 687 REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_PROC_STALL, 688 }; 689 m.set(REQUEST_MAX_NUM_OUTPUT_STREAMS, outputStreams); 690 691 /* 692 * request.maxNumInputStreams 693 */ 694 m.set(REQUEST_MAX_NUM_INPUT_STREAMS, REQUEST_MAX_NUM_INPUT_STREAMS_COUNT); 695 696 /* 697 * request.partialResultCount 698 */ 699 m.set(REQUEST_PARTIAL_RESULT_COUNT, 1); // No partial results supported 700 701 /* 702 * request.pipelineMaxDepth 703 */ 704 m.set(REQUEST_PIPELINE_MAX_DEPTH, 705 (byte)(REQUEST_PIPELINE_MAX_DEPTH_HAL1 + REQUEST_PIPELINE_MAX_DEPTH_OURS)); 706 } 707 708 private static void mapScaler(CameraMetadataNative m, Parameters p) { 709 /* 710 * scaler.availableMaxDigitalZoom 711 */ 712 m.set(SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, ParameterUtils.getMaxZoomRatio(p)); 713 714 /* 715 * scaler.croppingType = CENTER_ONLY 716 */ 717 m.set(SCALER_CROPPING_TYPE, SCALER_CROPPING_TYPE_CENTER_ONLY); 718 } 719 720 private static void mapSensor(CameraMetadataNative m, Parameters p) { 721 // Use the largest jpeg size (by area) for both active array and pixel array 722 Size largestJpegSize = getLargestSupportedJpegSizeByArea(p); 723 /* 724 * sensor.info.activeArraySize 725 */ 726 { 727 Rect activeArrayRect = ParamsUtils.createRect(largestJpegSize); 728 m.set(SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArrayRect); 729 } 730 731 /* 732 * sensor.availableTestPatternModes 733 */ 734 { 735 // Only "OFF" test pattern mode is available 736 m.set(SENSOR_AVAILABLE_TEST_PATTERN_MODES, new int[] { SENSOR_TEST_PATTERN_MODE_OFF }); 737 } 738 739 /* 740 * sensor.info.pixelArraySize 741 */ 742 m.set(SENSOR_INFO_PIXEL_ARRAY_SIZE, largestJpegSize); 743 } 744 745 private static void mapSync(CameraMetadataNative m, Parameters p) { 746 /* 747 * sync.maxLatency 748 */ 749 m.set(SYNC_MAX_LATENCY, SYNC_MAX_LATENCY_UNKNOWN); 750 } 751 752 private static void appendStreamConfig( 753 ArrayList<StreamConfiguration> configs, int format, List<Camera.Size> sizes) { 754 for (Camera.Size size : sizes) { 755 StreamConfiguration config = 756 new StreamConfiguration(format, size.width, size.height, /*input*/false); 757 configs.add(config); 758 } 759 } 760 761 private final static String[] sLegacySceneModes = { 762 Parameters.SCENE_MODE_AUTO, 763 Parameters.SCENE_MODE_ACTION, 764 Parameters.SCENE_MODE_PORTRAIT, 765 Parameters.SCENE_MODE_LANDSCAPE, 766 Parameters.SCENE_MODE_NIGHT, 767 Parameters.SCENE_MODE_NIGHT_PORTRAIT, 768 Parameters.SCENE_MODE_THEATRE, 769 Parameters.SCENE_MODE_BEACH, 770 Parameters.SCENE_MODE_SNOW, 771 Parameters.SCENE_MODE_SUNSET, 772 Parameters.SCENE_MODE_STEADYPHOTO, 773 Parameters.SCENE_MODE_FIREWORKS, 774 Parameters.SCENE_MODE_SPORTS, 775 Parameters.SCENE_MODE_PARTY, 776 Parameters.SCENE_MODE_CANDLELIGHT, 777 Parameters.SCENE_MODE_BARCODE, 778 }; 779 780 private final static int[] sSceneModes = { 781 CameraCharacteristics.CONTROL_SCENE_MODE_DISABLED, 782 CameraCharacteristics.CONTROL_SCENE_MODE_ACTION, 783 CameraCharacteristics.CONTROL_SCENE_MODE_PORTRAIT, 784 CameraCharacteristics.CONTROL_SCENE_MODE_LANDSCAPE, 785 CameraCharacteristics.CONTROL_SCENE_MODE_NIGHT, 786 CameraCharacteristics.CONTROL_SCENE_MODE_NIGHT_PORTRAIT, 787 CameraCharacteristics.CONTROL_SCENE_MODE_THEATRE, 788 CameraCharacteristics.CONTROL_SCENE_MODE_BEACH, 789 CameraCharacteristics.CONTROL_SCENE_MODE_SNOW, 790 CameraCharacteristics.CONTROL_SCENE_MODE_SUNSET, 791 CameraCharacteristics.CONTROL_SCENE_MODE_STEADYPHOTO, 792 CameraCharacteristics.CONTROL_SCENE_MODE_FIREWORKS, 793 CameraCharacteristics.CONTROL_SCENE_MODE_SPORTS, 794 CameraCharacteristics.CONTROL_SCENE_MODE_PARTY, 795 CameraCharacteristics.CONTROL_SCENE_MODE_CANDLELIGHT, 796 CameraCharacteristics.CONTROL_SCENE_MODE_BARCODE, 797 }; 798 799 static int convertSceneModeFromLegacy(String mode) { 800 if (mode == null) { 801 return CameraCharacteristics.CONTROL_SCENE_MODE_DISABLED; 802 } 803 int index = ArrayUtils.getArrayIndex(sLegacySceneModes, mode); 804 if (index < 0) { 805 return UNKNOWN_MODE; 806 } 807 return sSceneModes[index]; 808 } 809 810 static String convertSceneModeToLegacy(int mode) { 811 int index = ArrayUtils.getArrayIndex(sSceneModes, mode); 812 if (index < 0) { 813 return null; 814 } 815 return sLegacySceneModes[index]; 816 } 817 818 private final static String[] sLegacyEffectMode = { 819 Parameters.EFFECT_NONE, 820 Parameters.EFFECT_MONO, 821 Parameters.EFFECT_NEGATIVE, 822 Parameters.EFFECT_SOLARIZE, 823 Parameters.EFFECT_SEPIA, 824 Parameters.EFFECT_POSTERIZE, 825 Parameters.EFFECT_WHITEBOARD, 826 Parameters.EFFECT_BLACKBOARD, 827 Parameters.EFFECT_AQUA, 828 }; 829 830 private final static int[] sEffectModes = { 831 CameraCharacteristics.CONTROL_EFFECT_MODE_OFF, 832 CameraCharacteristics.CONTROL_EFFECT_MODE_MONO, 833 CameraCharacteristics.CONTROL_EFFECT_MODE_NEGATIVE, 834 CameraCharacteristics.CONTROL_EFFECT_MODE_SOLARIZE, 835 CameraCharacteristics.CONTROL_EFFECT_MODE_SEPIA, 836 CameraCharacteristics.CONTROL_EFFECT_MODE_POSTERIZE, 837 CameraCharacteristics.CONTROL_EFFECT_MODE_WHITEBOARD, 838 CameraCharacteristics.CONTROL_EFFECT_MODE_BLACKBOARD, 839 CameraCharacteristics.CONTROL_EFFECT_MODE_AQUA, 840 }; 841 842 static int convertEffectModeFromLegacy(String mode) { 843 if (mode == null) { 844 return CameraCharacteristics.CONTROL_EFFECT_MODE_OFF; 845 } 846 int index = ArrayUtils.getArrayIndex(sLegacyEffectMode, mode); 847 if (index < 0) { 848 return UNKNOWN_MODE; 849 } 850 return sEffectModes[index]; 851 } 852 853 static String convertEffectModeToLegacy(int mode) { 854 int index = ArrayUtils.getArrayIndex(sEffectModes, mode); 855 if (index < 0) { 856 return null; 857 } 858 return sLegacyEffectMode[index]; 859 } 860 861 /** 862 * Convert the ae antibanding mode from api1 into api2. 863 * 864 * @param mode the api1 mode, {@code null} is allowed and will return {@code -1}. 865 * 866 * @return The api2 value, or {@code -1} by default if conversion failed 867 */ 868 private static int convertAntiBandingMode(String mode) { 869 if (mode == null) { 870 return -1; 871 } 872 873 switch (mode) { 874 case Camera.Parameters.ANTIBANDING_OFF: { 875 return CONTROL_AE_ANTIBANDING_MODE_OFF; 876 } 877 case Camera.Parameters.ANTIBANDING_50HZ: { 878 return CONTROL_AE_ANTIBANDING_MODE_50HZ; 879 } 880 case Camera.Parameters.ANTIBANDING_60HZ: { 881 return CONTROL_AE_ANTIBANDING_MODE_60HZ; 882 } 883 case Camera.Parameters.ANTIBANDING_AUTO: { 884 return CONTROL_AE_ANTIBANDING_MODE_AUTO; 885 } 886 default: { 887 Log.w(TAG, "convertAntiBandingMode - Unknown antibanding mode " + mode); 888 return -1; 889 } 890 } 891 } 892 893 /** 894 * Convert the ae antibanding mode from api1 into api2. 895 * 896 * @param mode the api1 mode, {@code null} is allowed and will return {@code MODE_OFF}. 897 * 898 * @return The api2 value, or {@code MODE_OFF} by default if conversion failed 899 */ 900 static int convertAntiBandingModeOrDefault(String mode) { 901 int antiBandingMode = convertAntiBandingMode(mode); 902 if (antiBandingMode == -1) { 903 return CONTROL_AE_ANTIBANDING_MODE_OFF; 904 } 905 906 return antiBandingMode; 907 } 908 909 private static int[] convertAeFpsRangeToLegacy(Range<Integer> fpsRange) { 910 int[] legacyFps = new int[2]; 911 legacyFps[Camera.Parameters.PREVIEW_FPS_MIN_INDEX] = fpsRange.getLower(); 912 legacyFps[Camera.Parameters.PREVIEW_FPS_MAX_INDEX] = fpsRange.getUpper(); 913 return legacyFps; 914 } 915 916 /** 917 * Return the stall duration for a given output jpeg size in nanoseconds. 918 * 919 * <p>An 8mp image is chosen to have a stall duration of 0.8 seconds.</p> 920 */ 921 private static long calculateJpegStallDuration(Camera.Size size) { 922 long baseDuration = APPROXIMATE_CAPTURE_DELAY_MS * NS_PER_MS; // 200ms for capture 923 long area = size.width * (long) size.height; 924 long stallPerArea = APPROXIMATE_JPEG_ENCODE_TIME_MS * NS_PER_MS / 925 APPROXIMATE_SENSOR_AREA_PX; // 600ms stall for 8mp 926 return baseDuration + area * stallPerArea; 927 } 928 929 /** 930 * Set the legacy parameters using the {@link LegacyRequest legacy request}. 931 * 932 * <p>The legacy request's parameters are changed as a side effect of calling this 933 * method.</p> 934 * 935 * @param request a non-{@code null} legacy request 936 */ 937 public static void convertRequestMetadata(LegacyRequest request) { 938 LegacyRequestMapper.convertRequestMetadata(request); 939 } 940 941 private static final int[] sAllowedTemplates = { 942 CameraDevice.TEMPLATE_PREVIEW, 943 CameraDevice.TEMPLATE_STILL_CAPTURE, 944 CameraDevice.TEMPLATE_RECORD, 945 // Disallowed templates in legacy mode: 946 // CameraDevice.TEMPLATE_VIDEO_SNAPSHOT, 947 // CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG, 948 // CameraDevice.TEMPLATE_MANUAL 949 }; 950 951 /** 952 * Create a request template 953 * 954 * @param c a non-{@code null} camera characteristics for this camera 955 * @param templateId a non-negative template ID 956 * 957 * @return a non-{@code null} request template 958 * 959 * @throws IllegalArgumentException if {@code templateId} was invalid 960 * 961 * @see android.hardware.camera2.CameraDevice#TEMPLATE_MANUAL 962 */ 963 public static CameraMetadataNative createRequestTemplate( 964 CameraCharacteristics c, int templateId) { 965 if (!ArrayUtils.contains(sAllowedTemplates, templateId)) { 966 throw new IllegalArgumentException("templateId out of range"); 967 } 968 969 CameraMetadataNative m = new CameraMetadataNative(); 970 971 /* 972 * NOTE: If adding new code here and it needs to query the static info, 973 * query the camera characteristics, so we can reuse this for api2 code later 974 * to create our own templates in the framework 975 */ 976 977 /* 978 * control.* 979 */ 980 981 // control.awbMode 982 m.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_AUTO); 983 // AWB is always unconditionally available in API1 devices 984 985 // control.aeAntibandingMode 986 m.set(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE, CONTROL_AE_ANTIBANDING_MODE_AUTO); 987 988 // control.aeExposureCompensation 989 m.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0); 990 991 // control.aeLock 992 m.set(CaptureRequest.CONTROL_AE_LOCK, false); 993 994 // control.aePrecaptureTrigger 995 m.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CONTROL_AE_PRECAPTURE_TRIGGER_IDLE); 996 997 // control.afTrigger 998 m.set(CaptureRequest.CONTROL_AF_TRIGGER, CONTROL_AF_TRIGGER_IDLE); 999 1000 // control.awbMode 1001 m.set(CaptureRequest.CONTROL_AWB_MODE, CONTROL_AWB_MODE_AUTO); 1002 1003 // control.awbLock 1004 m.set(CaptureRequest.CONTROL_AWB_LOCK, false); 1005 1006 // control.aeRegions, control.awbRegions, control.afRegions 1007 { 1008 Rect activeArray = c.get(SENSOR_INFO_ACTIVE_ARRAY_SIZE); 1009 MeteringRectangle[] activeRegions = new MeteringRectangle[] { 1010 new MeteringRectangle(/*x*/0, /*y*/0, /*width*/activeArray.width() - 1, 1011 /*height*/activeArray.height() - 1,/*weight*/1)}; 1012 m.set(CaptureRequest.CONTROL_AE_REGIONS, activeRegions); 1013 m.set(CaptureRequest.CONTROL_AWB_REGIONS, activeRegions); 1014 m.set(CaptureRequest.CONTROL_AF_REGIONS, activeRegions); 1015 } 1016 1017 // control.captureIntent 1018 m.set(CaptureRequest.CONTROL_CAPTURE_INTENT, templateId); 1019 1020 // control.aeMode 1021 m.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON); 1022 // AE is always unconditionally available in API1 devices 1023 1024 // control.mode 1025 m.set(CaptureRequest.CONTROL_MODE, CONTROL_MODE_AUTO); 1026 1027 // control.afMode 1028 { 1029 Float minimumFocusDistance = c.get(LENS_INFO_MINIMUM_FOCUS_DISTANCE); 1030 1031 int afMode; 1032 if (minimumFocusDistance != null && 1033 minimumFocusDistance == LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS) { 1034 // Cannot control auto-focus with fixed-focus cameras 1035 afMode = CameraMetadata.CONTROL_AF_MODE_OFF; 1036 } else { 1037 // If a minimum focus distance is reported; the camera must have AF 1038 afMode = CameraMetadata.CONTROL_AF_MODE_AUTO; 1039 1040 if (templateId == CameraDevice.TEMPLATE_RECORD || 1041 templateId == CameraDevice.TEMPLATE_VIDEO_SNAPSHOT) { 1042 if (ArrayUtils.contains(c.get(CONTROL_AF_AVAILABLE_MODES), 1043 CONTROL_AF_MODE_CONTINUOUS_VIDEO)) { 1044 afMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO; 1045 } 1046 } else if (templateId == CameraDevice.TEMPLATE_PREVIEW || 1047 templateId == CameraDevice.TEMPLATE_STILL_CAPTURE) { 1048 if (ArrayUtils.contains(c.get(CONTROL_AF_AVAILABLE_MODES), 1049 CONTROL_AF_MODE_CONTINUOUS_PICTURE)) { 1050 afMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE; 1051 } 1052 } 1053 } 1054 1055 m.set(CaptureRequest.CONTROL_AF_MODE, afMode); 1056 } 1057 1058 { 1059 // control.aeTargetFpsRange 1060 Range<Integer>[] availableFpsRange = c. 1061 get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); 1062 1063 // Pick FPS range with highest max value, tiebreak on higher min value 1064 Range<Integer> bestRange = availableFpsRange[0]; 1065 for (Range<Integer> r : availableFpsRange) { 1066 if (bestRange.getUpper() < r.getUpper()) { 1067 bestRange = r; 1068 } else if (bestRange.getUpper() == r.getUpper() && 1069 bestRange.getLower() < r.getLower()) { 1070 bestRange = r; 1071 } 1072 } 1073 m.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, bestRange); 1074 } 1075 1076 /* 1077 * statistics.* 1078 */ 1079 1080 // statistics.faceDetectMode 1081 m.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, STATISTICS_FACE_DETECT_MODE_OFF); 1082 1083 /* 1084 * flash.* 1085 */ 1086 1087 // flash.mode 1088 m.set(CaptureRequest.FLASH_MODE, FLASH_MODE_OFF); 1089 1090 /* 1091 * lens.* 1092 */ 1093 1094 // lens.focalLength 1095 m.set(CaptureRequest.LENS_FOCAL_LENGTH, 1096 c.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)[0]); 1097 1098 // TODO: map other request template values 1099 return m; 1100 } 1101 1102 private static int[] getTagsForKeys(Key<?>[] keys) { 1103 int[] tags = new int[keys.length]; 1104 1105 for (int i = 0; i < keys.length; ++i) { 1106 tags[i] = keys[i].getNativeKey().getTag(); 1107 } 1108 1109 return tags; 1110 } 1111 1112 private static int[] getTagsForKeys(CaptureRequest.Key<?>[] keys) { 1113 int[] tags = new int[keys.length]; 1114 1115 for (int i = 0; i < keys.length; ++i) { 1116 tags[i] = keys[i].getNativeKey().getTag(); 1117 } 1118 1119 return tags; 1120 } 1121 1122 private static int[] getTagsForKeys(CaptureResult.Key<?>[] keys) { 1123 int[] tags = new int[keys.length]; 1124 1125 for (int i = 0; i < keys.length; ++i) { 1126 tags[i] = keys[i].getNativeKey().getTag(); 1127 } 1128 1129 return tags; 1130 } 1131 1132 /** 1133 * Convert the requested AF mode into its equivalent supported parameter. 1134 * 1135 * @param mode {@code CONTROL_AF_MODE} 1136 * @param supportedFocusModes list of camera1's supported focus modes 1137 * @return the stringified af mode, or {@code null} if its not supported 1138 */ 1139 static String convertAfModeToLegacy(int mode, List<String> supportedFocusModes) { 1140 if (supportedFocusModes == null || supportedFocusModes.isEmpty()) { 1141 Log.w(TAG, "No focus modes supported; API1 bug"); 1142 return null; 1143 } 1144 1145 String param = null; 1146 switch (mode) { 1147 case CONTROL_AF_MODE_AUTO: 1148 param = Parameters.FOCUS_MODE_AUTO; 1149 break; 1150 case CONTROL_AF_MODE_CONTINUOUS_PICTURE: 1151 param = Parameters.FOCUS_MODE_CONTINUOUS_PICTURE; 1152 break; 1153 case CONTROL_AF_MODE_CONTINUOUS_VIDEO: 1154 param = Parameters.FOCUS_MODE_CONTINUOUS_VIDEO; 1155 break; 1156 case CONTROL_AF_MODE_EDOF: 1157 param = Parameters.FOCUS_MODE_EDOF; 1158 break; 1159 case CONTROL_AF_MODE_MACRO: 1160 param = Parameters.FOCUS_MODE_MACRO; 1161 break; 1162 case CONTROL_AF_MODE_OFF: 1163 if (supportedFocusModes.contains(Parameters.FOCUS_MODE_FIXED)) { 1164 param = Parameters.FOCUS_MODE_FIXED; 1165 } else { 1166 param = Parameters.FOCUS_MODE_INFINITY; 1167 } 1168 } 1169 1170 if (!supportedFocusModes.contains(param)) { 1171 // Weed out bad user input by setting to the first arbitrary focus mode 1172 String defaultMode = supportedFocusModes.get(0); 1173 Log.w(TAG, 1174 String.format( 1175 "convertAfModeToLegacy - ignoring unsupported mode %d, " + 1176 "defaulting to %s", mode, defaultMode)); 1177 param = defaultMode; 1178 } 1179 1180 return param; 1181 } 1182} 1183