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