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