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