1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "ExtCamDev (at) 3.4" 18 //#define LOG_NDEBUG 0 19 #include <log/log.h> 20 21 #include <algorithm> 22 #include <array> 23 #include <linux/videodev2.h> 24 #include "android-base/macros.h" 25 #include "CameraMetadata.h" 26 #include "../../3.2/default/include/convert.h" 27 #include "ExternalCameraDevice_3_4.h" 28 29 namespace android { 30 namespace hardware { 31 namespace camera { 32 namespace device { 33 namespace V3_4 { 34 namespace implementation { 35 36 namespace { 37 // Only support MJPEG for now as it seems to be the one supports higher fps 38 // Other formats to consider in the future: 39 // * V4L2_PIX_FMT_YVU420 (== YV12) 40 // * V4L2_PIX_FMT_YVYU (YVYU: can be converted to YV12 or other YUV420_888 formats) 41 const std::array<uint32_t, /*size*/1> kSupportedFourCCs {{ 42 V4L2_PIX_FMT_MJPEG 43 }}; // double braces required in C++11 44 45 constexpr int MAX_RETRY = 5; // Allow retry v4l2 open failures a few times. 46 constexpr int OPEN_RETRY_SLEEP_US = 100000; // 100ms * MAX_RETRY = 0.5 seconds 47 48 } // anonymous namespace 49 50 ExternalCameraDevice::ExternalCameraDevice( 51 const std::string& cameraId, const ExternalCameraConfig& cfg) : 52 mCameraId(cameraId), 53 mCfg(cfg) { 54 55 status_t ret = initCameraCharacteristics(); 56 if (ret != OK) { 57 ALOGE("%s: init camera characteristics failed: errorno %d", __FUNCTION__, ret); 58 mInitFailed = true; 59 } 60 } 61 62 ExternalCameraDevice::~ExternalCameraDevice() {} 63 64 bool ExternalCameraDevice::isInitFailed() { 65 return mInitFailed; 66 } 67 68 Return<void> ExternalCameraDevice::getResourceCost(getResourceCost_cb _hidl_cb) { 69 CameraResourceCost resCost; 70 resCost.resourceCost = 100; 71 _hidl_cb(Status::OK, resCost); 72 return Void(); 73 } 74 75 Return<void> ExternalCameraDevice::getCameraCharacteristics( 76 getCameraCharacteristics_cb _hidl_cb) { 77 Mutex::Autolock _l(mLock); 78 V3_2::CameraMetadata hidlChars; 79 80 if (isInitFailed()) { 81 _hidl_cb(Status::INTERNAL_ERROR, hidlChars); 82 return Void(); 83 } 84 85 const camera_metadata_t* rawMetadata = mCameraCharacteristics.getAndLock(); 86 V3_2::implementation::convertToHidl(rawMetadata, &hidlChars); 87 _hidl_cb(Status::OK, hidlChars); 88 mCameraCharacteristics.unlock(rawMetadata); 89 return Void(); 90 } 91 92 Return<Status> ExternalCameraDevice::setTorchMode(TorchMode) { 93 return Status::METHOD_NOT_SUPPORTED; 94 } 95 96 Return<void> ExternalCameraDevice::open( 97 const sp<ICameraDeviceCallback>& callback, open_cb _hidl_cb) { 98 Status status = Status::OK; 99 sp<ExternalCameraDeviceSession> session = nullptr; 100 101 if (callback == nullptr) { 102 ALOGE("%s: cannot open camera %s. callback is null!", 103 __FUNCTION__, mCameraId.c_str()); 104 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); 105 return Void(); 106 } 107 108 if (isInitFailed()) { 109 ALOGE("%s: cannot open camera %s. camera init failed!", 110 __FUNCTION__, mCameraId.c_str()); 111 _hidl_cb(Status::INTERNAL_ERROR, nullptr); 112 return Void(); 113 } 114 115 mLock.lock(); 116 117 ALOGV("%s: Initializing device for camera %s", __FUNCTION__, mCameraId.c_str()); 118 session = mSession.promote(); 119 if (session != nullptr && !session->isClosed()) { 120 ALOGE("%s: cannot open an already opened camera!", __FUNCTION__); 121 mLock.unlock(); 122 _hidl_cb(Status::CAMERA_IN_USE, nullptr); 123 return Void(); 124 } 125 126 unique_fd fd(::open(mCameraId.c_str(), O_RDWR)); 127 if (fd.get() < 0) { 128 int numAttempt = 0; 129 do { 130 ALOGW("%s: v4l2 device %s open failed, wait 33ms and try again", 131 __FUNCTION__, mCameraId.c_str()); 132 usleep(OPEN_RETRY_SLEEP_US); // sleep and try again 133 fd.reset(::open(mCameraId.c_str(), O_RDWR)); 134 numAttempt++; 135 } while (fd.get() < 0 && numAttempt <= MAX_RETRY); 136 137 if (fd.get() < 0) { 138 ALOGE("%s: v4l2 device open %s failed: %s", 139 __FUNCTION__, mCameraId.c_str(), strerror(errno)); 140 mLock.unlock(); 141 _hidl_cb(Status::INTERNAL_ERROR, nullptr); 142 return Void(); 143 } 144 } 145 146 session = new ExternalCameraDeviceSession( 147 callback, mCfg, mSupportedFormats, mCroppingType, 148 mCameraCharacteristics, mCameraId, std::move(fd)); 149 if (session == nullptr) { 150 ALOGE("%s: camera device session allocation failed", __FUNCTION__); 151 mLock.unlock(); 152 _hidl_cb(Status::INTERNAL_ERROR, nullptr); 153 return Void(); 154 } 155 if (session->isInitFailed()) { 156 ALOGE("%s: camera device session init failed", __FUNCTION__); 157 session = nullptr; 158 mLock.unlock(); 159 _hidl_cb(Status::INTERNAL_ERROR, nullptr); 160 return Void(); 161 } 162 mSession = session; 163 164 mLock.unlock(); 165 166 _hidl_cb(status, session->getInterface()); 167 return Void(); 168 } 169 170 Return<void> ExternalCameraDevice::dumpState(const ::android::hardware::hidl_handle& handle) { 171 Mutex::Autolock _l(mLock); 172 if (handle.getNativeHandle() == nullptr) { 173 ALOGE("%s: handle must not be null", __FUNCTION__); 174 return Void(); 175 } 176 if (handle->numFds != 1 || handle->numInts != 0) { 177 ALOGE("%s: handle must contain 1 FD and 0 integers! Got %d FDs and %d ints", 178 __FUNCTION__, handle->numFds, handle->numInts); 179 return Void(); 180 } 181 int fd = handle->data[0]; 182 if (mSession == nullptr) { 183 dprintf(fd, "No active camera device session instance\n"); 184 return Void(); 185 } 186 auto session = mSession.promote(); 187 if (session == nullptr) { 188 dprintf(fd, "No active camera device session instance\n"); 189 return Void(); 190 } 191 // Call into active session to dump states 192 session->dumpState(handle); 193 return Void(); 194 } 195 196 197 status_t ExternalCameraDevice::initCameraCharacteristics() { 198 if (mCameraCharacteristics.isEmpty()) { 199 // init camera characteristics 200 unique_fd fd(::open(mCameraId.c_str(), O_RDWR)); 201 if (fd.get() < 0) { 202 ALOGE("%s: v4l2 device open %s failed", __FUNCTION__, mCameraId.c_str()); 203 return DEAD_OBJECT; 204 } 205 206 status_t ret; 207 ret = initDefaultCharsKeys(&mCameraCharacteristics); 208 if (ret != OK) { 209 ALOGE("%s: init default characteristics key failed: errorno %d", __FUNCTION__, ret); 210 mCameraCharacteristics.clear(); 211 return ret; 212 } 213 214 ret = initCameraControlsCharsKeys(fd.get(), &mCameraCharacteristics); 215 if (ret != OK) { 216 ALOGE("%s: init camera control characteristics key failed: errorno %d", __FUNCTION__, ret); 217 mCameraCharacteristics.clear(); 218 return ret; 219 } 220 221 ret = initOutputCharsKeys(fd.get(), &mCameraCharacteristics); 222 if (ret != OK) { 223 ALOGE("%s: init output characteristics key failed: errorno %d", __FUNCTION__, ret); 224 mCameraCharacteristics.clear(); 225 return ret; 226 } 227 } 228 return OK; 229 } 230 231 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 232 #define UPDATE(tag, data, size) \ 233 do { \ 234 if (metadata->update((tag), (data), (size))) { \ 235 ALOGE("Update " #tag " failed!"); \ 236 return -EINVAL; \ 237 } \ 238 } while (0) 239 240 status_t ExternalCameraDevice::initDefaultCharsKeys( 241 ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) { 242 const uint8_t hardware_level = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL; 243 UPDATE(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &hardware_level, 1); 244 245 // android.colorCorrection 246 const uint8_t availableAberrationModes[] = { 247 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF}; 248 UPDATE(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES, 249 availableAberrationModes, ARRAY_SIZE(availableAberrationModes)); 250 251 // android.control 252 const uint8_t antibandingMode = 253 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO; 254 UPDATE(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, 255 &antibandingMode, 1); 256 257 const int32_t controlMaxRegions[] = {/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0}; 258 UPDATE(ANDROID_CONTROL_MAX_REGIONS, controlMaxRegions, 259 ARRAY_SIZE(controlMaxRegions)); 260 261 const uint8_t videoStabilizationMode = 262 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; 263 UPDATE(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, 264 &videoStabilizationMode, 1); 265 266 const uint8_t awbAvailableMode = ANDROID_CONTROL_AWB_MODE_AUTO; 267 UPDATE(ANDROID_CONTROL_AWB_AVAILABLE_MODES, &awbAvailableMode, 1); 268 269 const uint8_t aeAvailableMode = ANDROID_CONTROL_AE_MODE_ON; 270 UPDATE(ANDROID_CONTROL_AE_AVAILABLE_MODES, &aeAvailableMode, 1); 271 272 const uint8_t availableFffect = ANDROID_CONTROL_EFFECT_MODE_OFF; 273 UPDATE(ANDROID_CONTROL_AVAILABLE_EFFECTS, &availableFffect, 1); 274 275 const uint8_t controlAvailableModes[] = {ANDROID_CONTROL_MODE_OFF, 276 ANDROID_CONTROL_MODE_AUTO}; 277 UPDATE(ANDROID_CONTROL_AVAILABLE_MODES, controlAvailableModes, 278 ARRAY_SIZE(controlAvailableModes)); 279 280 // android.edge 281 const uint8_t edgeMode = ANDROID_EDGE_MODE_OFF; 282 UPDATE(ANDROID_EDGE_AVAILABLE_EDGE_MODES, &edgeMode, 1); 283 284 // android.flash 285 const uint8_t flashInfo = ANDROID_FLASH_INFO_AVAILABLE_FALSE; 286 UPDATE(ANDROID_FLASH_INFO_AVAILABLE, &flashInfo, 1); 287 288 // android.hotPixel 289 const uint8_t hotPixelMode = ANDROID_HOT_PIXEL_MODE_OFF; 290 UPDATE(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES, &hotPixelMode, 1); 291 292 // android.jpeg 293 // TODO: b/72261675 See if we can provide thumbnail size for all jpeg aspect ratios 294 const int32_t jpegAvailableThumbnailSizes[] = {0, 0, 240, 180}; 295 UPDATE(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegAvailableThumbnailSizes, 296 ARRAY_SIZE(jpegAvailableThumbnailSizes)); 297 298 const int32_t jpegMaxSize = mCfg.maxJpegBufSize; 299 UPDATE(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1); 300 301 // android.lens 302 const uint8_t focusDistanceCalibration = 303 ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED; 304 UPDATE(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION, &focusDistanceCalibration, 1); 305 306 const uint8_t opticalStabilizationMode = 307 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; 308 UPDATE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, 309 &opticalStabilizationMode, 1); 310 311 const uint8_t facing = ANDROID_LENS_FACING_EXTERNAL; 312 UPDATE(ANDROID_LENS_FACING, &facing, 1); 313 314 // android.noiseReduction 315 const uint8_t noiseReductionMode = ANDROID_NOISE_REDUCTION_MODE_OFF; 316 UPDATE(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES, 317 &noiseReductionMode, 1); 318 UPDATE(ANDROID_NOISE_REDUCTION_MODE, &noiseReductionMode, 1); 319 320 // android.request 321 const uint8_t availableCapabilities[] = { 322 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE}; 323 UPDATE(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, availableCapabilities, 324 ARRAY_SIZE(availableCapabilities)); 325 326 const int32_t partialResultCount = 1; 327 UPDATE(ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &partialResultCount, 1); 328 329 // This means pipeline latency of X frame intervals. The maximum number is 4. 330 const uint8_t requestPipelineMaxDepth = 4; 331 UPDATE(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &requestPipelineMaxDepth, 1); 332 333 // Three numbers represent the maximum numbers of different types of output 334 // streams simultaneously. The types are raw sensor, processed (but not 335 // stalling), and processed (but stalling). For usb limited mode, raw sensor 336 // is not supported. Stalling stream is JPEG. Non-stalling streams are 337 // YUV_420_888 or YV12. 338 const int32_t requestMaxNumOutputStreams[] = { 339 /*RAW*/0, 340 /*Processed*/ExternalCameraDeviceSession::kMaxProcessedStream, 341 /*Stall*/ExternalCameraDeviceSession::kMaxStallStream}; 342 UPDATE(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, requestMaxNumOutputStreams, 343 ARRAY_SIZE(requestMaxNumOutputStreams)); 344 345 // Limited mode doesn't support reprocessing. 346 const int32_t requestMaxNumInputStreams = 0; 347 UPDATE(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, &requestMaxNumInputStreams, 348 1); 349 350 // android.scaler 351 // TODO: b/72263447 V4L2_CID_ZOOM_* 352 const float scalerAvailableMaxDigitalZoom[] = {1}; 353 UPDATE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, 354 scalerAvailableMaxDigitalZoom, 355 ARRAY_SIZE(scalerAvailableMaxDigitalZoom)); 356 357 const uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY; 358 UPDATE(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1); 359 360 const int32_t testPatternModes[] = { 361 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF}; 362 UPDATE(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, testPatternModes, 363 ARRAY_SIZE(testPatternModes)); 364 365 const uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN; 366 UPDATE(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, ×tampSource, 1); 367 368 // Orientation probably isn't useful for external facing camera? 369 const int32_t orientation = 0; 370 UPDATE(ANDROID_SENSOR_ORIENTATION, &orientation, 1); 371 372 // android.shading 373 const uint8_t availabeMode = ANDROID_SHADING_MODE_OFF; 374 UPDATE(ANDROID_SHADING_AVAILABLE_MODES, &availabeMode, 1); 375 376 // android.statistics 377 const uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; 378 UPDATE(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, &faceDetectMode, 379 1); 380 381 const int32_t maxFaceCount = 0; 382 UPDATE(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, &maxFaceCount, 1); 383 384 const uint8_t availableHotpixelMode = 385 ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF; 386 UPDATE(ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES, 387 &availableHotpixelMode, 1); 388 389 const uint8_t lensShadingMapMode = 390 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF; 391 UPDATE(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, 392 &lensShadingMapMode, 1); 393 394 // android.sync 395 const int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN; 396 UPDATE(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1); 397 398 /* Other sensor/RAW realted keys: 399 * android.sensor.info.colorFilterArrangement -> no need if we don't do RAW 400 * android.sensor.info.physicalSize -> not available 401 * android.sensor.info.whiteLevel -> not available/not needed 402 * android.sensor.info.lensShadingApplied -> not needed 403 * android.sensor.info.preCorrectionActiveArraySize -> not available/not needed 404 * android.sensor.blackLevelPattern -> not available/not needed 405 */ 406 407 const int32_t availableRequestKeys[] = { 408 ANDROID_COLOR_CORRECTION_ABERRATION_MODE, 409 ANDROID_CONTROL_AE_ANTIBANDING_MODE, 410 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, 411 ANDROID_CONTROL_AE_LOCK, 412 ANDROID_CONTROL_AE_MODE, 413 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, 414 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, 415 ANDROID_CONTROL_AF_MODE, 416 ANDROID_CONTROL_AF_TRIGGER, 417 ANDROID_CONTROL_AWB_LOCK, 418 ANDROID_CONTROL_AWB_MODE, 419 ANDROID_CONTROL_CAPTURE_INTENT, 420 ANDROID_CONTROL_EFFECT_MODE, 421 ANDROID_CONTROL_MODE, 422 ANDROID_CONTROL_SCENE_MODE, 423 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, 424 ANDROID_FLASH_MODE, 425 ANDROID_JPEG_ORIENTATION, 426 ANDROID_JPEG_QUALITY, 427 ANDROID_JPEG_THUMBNAIL_QUALITY, 428 ANDROID_JPEG_THUMBNAIL_SIZE, 429 ANDROID_LENS_OPTICAL_STABILIZATION_MODE, 430 ANDROID_NOISE_REDUCTION_MODE, 431 ANDROID_SCALER_CROP_REGION, 432 ANDROID_SENSOR_TEST_PATTERN_MODE, 433 ANDROID_STATISTICS_FACE_DETECT_MODE, 434 ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE}; 435 UPDATE(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, availableRequestKeys, 436 ARRAY_SIZE(availableRequestKeys)); 437 438 const int32_t availableResultKeys[] = { 439 ANDROID_COLOR_CORRECTION_ABERRATION_MODE, 440 ANDROID_CONTROL_AE_ANTIBANDING_MODE, 441 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, 442 ANDROID_CONTROL_AE_LOCK, 443 ANDROID_CONTROL_AE_MODE, 444 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, 445 ANDROID_CONTROL_AE_STATE, 446 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, 447 ANDROID_CONTROL_AF_MODE, 448 ANDROID_CONTROL_AF_STATE, 449 ANDROID_CONTROL_AF_TRIGGER, 450 ANDROID_CONTROL_AWB_LOCK, 451 ANDROID_CONTROL_AWB_MODE, 452 ANDROID_CONTROL_AWB_STATE, 453 ANDROID_CONTROL_CAPTURE_INTENT, 454 ANDROID_CONTROL_EFFECT_MODE, 455 ANDROID_CONTROL_MODE, 456 ANDROID_CONTROL_SCENE_MODE, 457 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, 458 ANDROID_FLASH_MODE, 459 ANDROID_FLASH_STATE, 460 ANDROID_JPEG_ORIENTATION, 461 ANDROID_JPEG_QUALITY, 462 ANDROID_JPEG_THUMBNAIL_QUALITY, 463 ANDROID_JPEG_THUMBNAIL_SIZE, 464 ANDROID_LENS_OPTICAL_STABILIZATION_MODE, 465 ANDROID_NOISE_REDUCTION_MODE, 466 ANDROID_REQUEST_PIPELINE_DEPTH, 467 ANDROID_SCALER_CROP_REGION, 468 ANDROID_SENSOR_TIMESTAMP, 469 ANDROID_STATISTICS_FACE_DETECT_MODE, 470 ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, 471 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, 472 ANDROID_STATISTICS_SCENE_FLICKER}; 473 UPDATE(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, availableResultKeys, 474 ARRAY_SIZE(availableResultKeys)); 475 476 const int32_t availableCharacteristicsKeys[] = { 477 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES, 478 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, 479 ANDROID_CONTROL_AE_AVAILABLE_MODES, 480 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 481 ANDROID_CONTROL_AE_COMPENSATION_RANGE, 482 ANDROID_CONTROL_AE_COMPENSATION_STEP, 483 ANDROID_CONTROL_AE_LOCK_AVAILABLE, 484 ANDROID_CONTROL_AF_AVAILABLE_MODES, 485 ANDROID_CONTROL_AVAILABLE_EFFECTS, 486 ANDROID_CONTROL_AVAILABLE_MODES, 487 ANDROID_CONTROL_AVAILABLE_SCENE_MODES, 488 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, 489 ANDROID_CONTROL_AWB_AVAILABLE_MODES, 490 ANDROID_CONTROL_AWB_LOCK_AVAILABLE, 491 ANDROID_CONTROL_MAX_REGIONS, 492 ANDROID_FLASH_INFO_AVAILABLE, 493 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, 494 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 495 ANDROID_LENS_FACING, 496 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, 497 ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION, 498 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES, 499 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, 500 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, 501 ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, 502 ANDROID_REQUEST_PARTIAL_RESULT_COUNT, 503 ANDROID_REQUEST_PIPELINE_MAX_DEPTH, 504 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, 505 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, 506 ANDROID_SCALER_CROPPING_TYPE, 507 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, 508 ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, 509 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, 510 ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, 511 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, 512 ANDROID_SENSOR_ORIENTATION, 513 ANDROID_SHADING_AVAILABLE_MODES, 514 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, 515 ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES, 516 ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, 517 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, 518 ANDROID_SYNC_MAX_LATENCY}; 519 UPDATE(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, 520 availableCharacteristicsKeys, 521 ARRAY_SIZE(availableCharacteristicsKeys)); 522 523 return OK; 524 } 525 526 status_t ExternalCameraDevice::initCameraControlsCharsKeys(int, 527 ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) { 528 /** 529 * android.sensor.info.sensitivityRange -> V4L2_CID_ISO_SENSITIVITY 530 * android.sensor.info.exposureTimeRange -> V4L2_CID_EXPOSURE_ABSOLUTE 531 * android.sensor.info.maxFrameDuration -> TBD 532 * android.lens.info.minimumFocusDistance -> V4L2_CID_FOCUS_ABSOLUTE 533 * android.lens.info.hyperfocalDistance 534 * android.lens.info.availableFocalLengths -> not available? 535 */ 536 537 // android.control 538 // No AE compensation support for now. 539 // TODO: V4L2_CID_EXPOSURE_BIAS 540 const int32_t controlAeCompensationRange[] = {0, 0}; 541 UPDATE(ANDROID_CONTROL_AE_COMPENSATION_RANGE, controlAeCompensationRange, 542 ARRAY_SIZE(controlAeCompensationRange)); 543 const camera_metadata_rational_t controlAeCompensationStep[] = {{0, 1}}; 544 UPDATE(ANDROID_CONTROL_AE_COMPENSATION_STEP, controlAeCompensationStep, 545 ARRAY_SIZE(controlAeCompensationStep)); 546 547 548 // TODO: Check V4L2_CID_AUTO_FOCUS_*. 549 const uint8_t afAvailableModes[] = {ANDROID_CONTROL_AF_MODE_AUTO, 550 ANDROID_CONTROL_AF_MODE_OFF}; 551 UPDATE(ANDROID_CONTROL_AF_AVAILABLE_MODES, afAvailableModes, 552 ARRAY_SIZE(afAvailableModes)); 553 554 // TODO: V4L2_CID_SCENE_MODE 555 const uint8_t availableSceneMode = ANDROID_CONTROL_SCENE_MODE_DISABLED; 556 UPDATE(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, &availableSceneMode, 1); 557 558 // TODO: V4L2_CID_3A_LOCK 559 const uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE; 560 UPDATE(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &aeLockAvailable, 1); 561 const uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE; 562 UPDATE(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &awbLockAvailable, 1); 563 564 // TODO: V4L2_CID_ZOOM_* 565 const float scalerAvailableMaxDigitalZoom[] = {1}; 566 UPDATE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, 567 scalerAvailableMaxDigitalZoom, 568 ARRAY_SIZE(scalerAvailableMaxDigitalZoom)); 569 570 return OK; 571 } 572 573 status_t ExternalCameraDevice::initOutputCharsKeys(int fd, 574 ::android::hardware::camera::common::V1_0::helper::CameraMetadata* metadata) { 575 initSupportedFormatsLocked(fd); 576 if (mSupportedFormats.empty()) { 577 ALOGE("%s: Init supported format list failed", __FUNCTION__); 578 return UNKNOWN_ERROR; 579 } 580 581 std::vector<int32_t> streamConfigurations; 582 std::vector<int64_t> minFrameDurations; 583 std::vector<int64_t> stallDurations; 584 int32_t maxFps = std::numeric_limits<int32_t>::min(); 585 int32_t minFps = std::numeric_limits<int32_t>::max(); 586 std::set<int32_t> framerates; 587 588 std::array<int, /*size*/3> halFormats{{ 589 HAL_PIXEL_FORMAT_BLOB, 590 HAL_PIXEL_FORMAT_YCbCr_420_888, 591 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED}}; 592 593 for (const auto& supportedFormat : mSupportedFormats) { 594 for (const auto& format : halFormats) { 595 streamConfigurations.push_back(format); 596 streamConfigurations.push_back(supportedFormat.width); 597 streamConfigurations.push_back(supportedFormat.height); 598 streamConfigurations.push_back( 599 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT); 600 } 601 602 int64_t minFrameDuration = std::numeric_limits<int64_t>::max(); 603 for (const auto& fr : supportedFormat.frameRates) { 604 // 1000000000LL < (2^32 - 1) and 605 // fr.durationNumerator is uint32_t, so no overflow here 606 int64_t frameDuration = 1000000000LL * fr.durationNumerator / 607 fr.durationDenominator; 608 if (frameDuration < minFrameDuration) { 609 minFrameDuration = frameDuration; 610 } 611 int32_t frameRateInt = static_cast<int32_t>(fr.getDouble()); 612 if (minFps > frameRateInt) { 613 minFps = frameRateInt; 614 } 615 if (maxFps < frameRateInt) { 616 maxFps = frameRateInt; 617 } 618 framerates.insert(frameRateInt); 619 } 620 621 for (const auto& format : halFormats) { 622 minFrameDurations.push_back(format); 623 minFrameDurations.push_back(supportedFormat.width); 624 minFrameDurations.push_back(supportedFormat.height); 625 minFrameDurations.push_back(minFrameDuration); 626 } 627 628 // The stall duration is 0 for non-jpeg formats. For JPEG format, stall 629 // duration can be 0 if JPEG is small. Here we choose 1 sec for JPEG. 630 // TODO: b/72261675. Maybe set this dynamically 631 for (const auto& format : halFormats) { 632 const int64_t NS_TO_SECOND = 1000000000; 633 int64_t stall_duration = 634 (format == HAL_PIXEL_FORMAT_BLOB) ? NS_TO_SECOND : 0; 635 stallDurations.push_back(format); 636 stallDurations.push_back(supportedFormat.width); 637 stallDurations.push_back(supportedFormat.height); 638 stallDurations.push_back(stall_duration); 639 } 640 } 641 642 std::vector<int32_t> fpsRanges; 643 // FPS ranges 644 for (const auto& framerate : framerates) { 645 // Empirical: webcams often have close to 2x fps error and cannot support fixed fps range 646 fpsRanges.push_back(framerate / 2); 647 fpsRanges.push_back(framerate); 648 } 649 minFps /= 2; 650 int64_t maxFrameDuration = 1000000000LL / minFps; 651 652 UPDATE(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fpsRanges.data(), 653 fpsRanges.size()); 654 655 UPDATE(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, 656 streamConfigurations.data(), streamConfigurations.size()); 657 658 UPDATE(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, 659 minFrameDurations.data(), minFrameDurations.size()); 660 661 UPDATE(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, stallDurations.data(), 662 stallDurations.size()); 663 664 UPDATE(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, &maxFrameDuration, 1); 665 666 SupportedV4L2Format maximumFormat {.width = 0, .height = 0}; 667 for (const auto& supportedFormat : mSupportedFormats) { 668 if (supportedFormat.width >= maximumFormat.width && 669 supportedFormat.height >= maximumFormat.height) { 670 maximumFormat = supportedFormat; 671 } 672 } 673 int32_t activeArraySize[] = {0, 0, 674 static_cast<int32_t>(maximumFormat.width), 675 static_cast<int32_t>(maximumFormat.height)}; 676 UPDATE(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, 677 activeArraySize, ARRAY_SIZE(activeArraySize)); 678 UPDATE(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArraySize, 679 ARRAY_SIZE(activeArraySize)); 680 681 int32_t pixelArraySize[] = {static_cast<int32_t>(maximumFormat.width), 682 static_cast<int32_t>(maximumFormat.height)}; 683 UPDATE(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArraySize, 684 ARRAY_SIZE(pixelArraySize)); 685 return OK; 686 } 687 688 #undef ARRAY_SIZE 689 #undef UPDATE 690 691 void ExternalCameraDevice::getFrameRateList( 692 int fd, double fpsUpperBound, SupportedV4L2Format* format) { 693 format->frameRates.clear(); 694 695 v4l2_frmivalenum frameInterval { 696 .pixel_format = format->fourcc, 697 .width = format->width, 698 .height = format->height, 699 .index = 0 700 }; 701 702 for (frameInterval.index = 0; 703 TEMP_FAILURE_RETRY(ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frameInterval)) == 0; 704 ++frameInterval.index) { 705 if (frameInterval.type == V4L2_FRMIVAL_TYPE_DISCRETE) { 706 if (frameInterval.discrete.numerator != 0) { 707 SupportedV4L2Format::FrameRate fr = { 708 frameInterval.discrete.numerator, 709 frameInterval.discrete.denominator}; 710 double framerate = fr.getDouble(); 711 if (framerate > fpsUpperBound) { 712 continue; 713 } 714 ALOGV("index:%d, format:%c%c%c%c, w %d, h %d, framerate %f", 715 frameInterval.index, 716 frameInterval.pixel_format & 0xFF, 717 (frameInterval.pixel_format >> 8) & 0xFF, 718 (frameInterval.pixel_format >> 16) & 0xFF, 719 (frameInterval.pixel_format >> 24) & 0xFF, 720 frameInterval.width, frameInterval.height, framerate); 721 format->frameRates.push_back(fr); 722 } 723 } 724 } 725 726 if (format->frameRates.empty()) { 727 ALOGE("%s: failed to get supported frame rates for format:%c%c%c%c w %d h %d", 728 __FUNCTION__, 729 frameInterval.pixel_format & 0xFF, 730 (frameInterval.pixel_format >> 8) & 0xFF, 731 (frameInterval.pixel_format >> 16) & 0xFF, 732 (frameInterval.pixel_format >> 24) & 0xFF, 733 frameInterval.width, frameInterval.height); 734 } 735 } 736 737 void ExternalCameraDevice::trimSupportedFormats( 738 CroppingType cropType, 739 /*inout*/std::vector<SupportedV4L2Format>* pFmts) { 740 std::vector<SupportedV4L2Format>& sortedFmts = *pFmts; 741 if (cropType == VERTICAL) { 742 std::sort(sortedFmts.begin(), sortedFmts.end(), 743 [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool { 744 if (a.width == b.width) { 745 return a.height < b.height; 746 } 747 return a.width < b.width; 748 }); 749 } else { 750 std::sort(sortedFmts.begin(), sortedFmts.end(), 751 [](const SupportedV4L2Format& a, const SupportedV4L2Format& b) -> bool { 752 if (a.height == b.height) { 753 return a.width < b.width; 754 } 755 return a.height < b.height; 756 }); 757 } 758 759 if (sortedFmts.size() == 0) { 760 ALOGE("%s: input format list is empty!", __FUNCTION__); 761 return; 762 } 763 764 const auto& maxSize = sortedFmts[sortedFmts.size() - 1]; 765 float maxSizeAr = ASPECT_RATIO(maxSize); 766 767 // Remove formats that has aspect ratio not croppable from largest size 768 std::vector<SupportedV4L2Format> out; 769 for (const auto& fmt : sortedFmts) { 770 float ar = ASPECT_RATIO(fmt); 771 if (isAspectRatioClose(ar, maxSizeAr)) { 772 out.push_back(fmt); 773 } else if (cropType == HORIZONTAL && ar < maxSizeAr) { 774 out.push_back(fmt); 775 } else if (cropType == VERTICAL && ar > maxSizeAr) { 776 out.push_back(fmt); 777 } else { 778 ALOGV("%s: size (%d,%d) is removed due to unable to crop %s from (%d,%d)", 779 __FUNCTION__, fmt.width, fmt.height, 780 cropType == VERTICAL ? "vertically" : "horizontally", 781 maxSize.width, maxSize.height); 782 } 783 } 784 sortedFmts = out; 785 } 786 787 std::vector<SupportedV4L2Format> 788 ExternalCameraDevice::getCandidateSupportedFormatsLocked( 789 int fd, CroppingType cropType, 790 const std::vector<ExternalCameraConfig::FpsLimitation>& fpsLimits) { 791 std::vector<SupportedV4L2Format> outFmts; 792 struct v4l2_fmtdesc fmtdesc { 793 .index = 0, 794 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE}; 795 int ret = 0; 796 while (ret == 0) { 797 ret = TEMP_FAILURE_RETRY(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc)); 798 ALOGV("index:%d,ret:%d, format:%c%c%c%c", fmtdesc.index, ret, 799 fmtdesc.pixelformat & 0xFF, 800 (fmtdesc.pixelformat >> 8) & 0xFF, 801 (fmtdesc.pixelformat >> 16) & 0xFF, 802 (fmtdesc.pixelformat >> 24) & 0xFF); 803 if (ret == 0 && !(fmtdesc.flags & V4L2_FMT_FLAG_EMULATED)) { 804 auto it = std::find ( 805 kSupportedFourCCs.begin(), kSupportedFourCCs.end(), fmtdesc.pixelformat); 806 if (it != kSupportedFourCCs.end()) { 807 // Found supported format 808 v4l2_frmsizeenum frameSize { 809 .index = 0, 810 .pixel_format = fmtdesc.pixelformat}; 811 for (; TEMP_FAILURE_RETRY(ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frameSize)) == 0; 812 ++frameSize.index) { 813 if (frameSize.type == V4L2_FRMSIZE_TYPE_DISCRETE) { 814 ALOGV("index:%d, format:%c%c%c%c, w %d, h %d", frameSize.index, 815 fmtdesc.pixelformat & 0xFF, 816 (fmtdesc.pixelformat >> 8) & 0xFF, 817 (fmtdesc.pixelformat >> 16) & 0xFF, 818 (fmtdesc.pixelformat >> 24) & 0xFF, 819 frameSize.discrete.width, frameSize.discrete.height); 820 // Disregard h > w formats so all aspect ratio (h/w) <= 1.0 821 // This will simplify the crop/scaling logic down the road 822 if (frameSize.discrete.height > frameSize.discrete.width) { 823 continue; 824 } 825 SupportedV4L2Format format { 826 .width = frameSize.discrete.width, 827 .height = frameSize.discrete.height, 828 .fourcc = fmtdesc.pixelformat 829 }; 830 831 double fpsUpperBound = -1.0; 832 for (const auto& limit : fpsLimits) { 833 if (cropType == VERTICAL) { 834 if (format.width <= limit.size.width) { 835 fpsUpperBound = limit.fpsUpperBound; 836 break; 837 } 838 } else { // HORIZONTAL 839 if (format.height <= limit.size.height) { 840 fpsUpperBound = limit.fpsUpperBound; 841 break; 842 } 843 } 844 845 } 846 if (fpsUpperBound < 0.f) { 847 continue; 848 } 849 850 getFrameRateList(fd, fpsUpperBound, &format); 851 if (!format.frameRates.empty()) { 852 outFmts.push_back(format); 853 } 854 } 855 } 856 } 857 } 858 fmtdesc.index++; 859 } 860 trimSupportedFormats(cropType, &outFmts); 861 return outFmts; 862 } 863 864 void ExternalCameraDevice::initSupportedFormatsLocked(int fd) { 865 866 std::vector<SupportedV4L2Format> horizontalFmts = 867 getCandidateSupportedFormatsLocked(fd, HORIZONTAL, mCfg.fpsLimits); 868 std::vector<SupportedV4L2Format> verticalFmts = 869 getCandidateSupportedFormatsLocked(fd, VERTICAL, mCfg.fpsLimits); 870 871 size_t horiSize = horizontalFmts.size(); 872 size_t vertSize = verticalFmts.size(); 873 874 if (horiSize == 0 && vertSize == 0) { 875 ALOGE("%s: cannot find suitable cropping type!", __FUNCTION__); 876 return; 877 } 878 879 if (horiSize == 0) { 880 mSupportedFormats = verticalFmts; 881 mCroppingType = VERTICAL; 882 return; 883 } else if (vertSize == 0) { 884 mSupportedFormats = horizontalFmts; 885 mCroppingType = HORIZONTAL; 886 return; 887 } 888 889 const auto& maxHoriSize = horizontalFmts[horizontalFmts.size() - 1]; 890 const auto& maxVertSize = verticalFmts[verticalFmts.size() - 1]; 891 892 // Try to keep largest possible output size 893 // When they are the same or ambiguous, pick the one support more sizes 894 if (maxHoriSize.width == maxVertSize.width && 895 maxHoriSize.height == maxVertSize.height) { 896 if (horiSize > vertSize) { 897 mSupportedFormats = horizontalFmts; 898 mCroppingType = HORIZONTAL; 899 } else { 900 mSupportedFormats = verticalFmts; 901 mCroppingType = VERTICAL; 902 } 903 } else if (maxHoriSize.width >= maxVertSize.width && 904 maxHoriSize.height >= maxVertSize.height) { 905 mSupportedFormats = horizontalFmts; 906 mCroppingType = HORIZONTAL; 907 } else if (maxHoriSize.width <= maxVertSize.width && 908 maxHoriSize.height <= maxVertSize.height) { 909 mSupportedFormats = verticalFmts; 910 mCroppingType = VERTICAL; 911 } else { 912 if (horiSize > vertSize) { 913 mSupportedFormats = horizontalFmts; 914 mCroppingType = HORIZONTAL; 915 } else { 916 mSupportedFormats = verticalFmts; 917 mCroppingType = VERTICAL; 918 } 919 } 920 } 921 922 } // namespace implementation 923 } // namespace V3_4 924 } // namespace device 925 } // namespace camera 926 } // namespace hardware 927 } // namespace android 928 929