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