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