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, &timestampSource, 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