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