Home | History | Annotate | Download | only in default
      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, &timestampSource, 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