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 "[email protected]"
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, ×tampSource, 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