blob: 3f18fdfa3851e735d51c14f9070e0e10b63639a3 [file] [log] [blame]
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2019, Google Inc.
4 *
5 * camera_device.cpp - libcamera Android Camera Device
6 */
7
8#include "camera_device.h"
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02009#include "camera_ops.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020010
Jacopo Mondia80d3812020-05-26 12:31:35 +020011#include <tuple>
Jacopo Mondi117588b2020-05-23 18:53:54 +020012#include <vector>
13
Jacopo Mondi857a2162019-11-20 17:00:49 +010014#include <libcamera/controls.h>
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030015#include <libcamera/formats.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010016#include <libcamera/property_ids.h>
17
Laurent Pinchart93e72b62020-05-12 00:58:34 +030018#include "libcamera/internal/log.h"
19#include "libcamera/internal/utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020020
Laurent Pinchart39860092019-09-05 03:12:34 +030021#include "camera_metadata.h"
Jacopo Mondi117588b2020-05-23 18:53:54 +020022#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020023
24using namespace libcamera;
25
Jacopo Mondi117588b2020-05-23 18:53:54 +020026namespace {
27
28/*
29 * \var camera3Resolutions
30 * \brief The list of image resolutions defined as mandatory to be supported by
31 * the Android Camera3 specification
32 */
33const std::vector<Size> camera3Resolutions = {
34 { 320, 240 },
35 { 640, 480 },
36 { 1280, 720 },
37 { 1920, 1080 }
38};
39
40/*
41 * \struct Camera3Format
42 * \brief Data associated with an Android format identifier
43 * \var libcameraFormats List of libcamera pixel formats compatible with the
44 * Android format
45 * \var scalerFormat The format identifier to be reported to the android
46 * framework through the static format configuration map
47 * \var name The human-readable representation of the Android format code
48 */
49struct Camera3Format {
50 std::vector<PixelFormat> libcameraFormats;
51 camera_metadata_enum_android_scaler_available_formats_t scalerFormat;
52 const char *name;
53};
54
55/*
56 * \var camera3FormatsMap
57 * \brief Associate Android format code with ancillary data
58 */
59const std::map<int, const Camera3Format> camera3FormatsMap = {
60 {
61 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030062 { formats::MJPEG },
Jacopo Mondi117588b2020-05-23 18:53:54 +020063 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
64 "BLOB"
65 }
66 }, {
67 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030068 { formats::NV12, formats::NV21 },
Jacopo Mondi117588b2020-05-23 18:53:54 +020069 ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
70 "YCbCr_420_888"
71 }
72 }, {
73 /*
74 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
75 * usage flag. For now, copy the YCbCr_420 configuration.
76 */
77 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030078 { formats::NV12, formats::NV21 },
Jacopo Mondi117588b2020-05-23 18:53:54 +020079 ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
80 "IMPLEMENTATION_DEFINED"
81 }
82 },
83};
84
85} /* namespace */
86
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020087LOG_DECLARE_CATEGORY(HAL);
88
89/*
90 * \struct Camera3RequestDescriptor
91 *
92 * A utility structure that groups information about a capture request to be
93 * later re-used at request complete time to notify the framework.
94 */
95
96CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
97 unsigned int frameNumber, unsigned int numBuffers)
98 : frameNumber(frameNumber), numBuffers(numBuffers)
99{
100 buffers = new camera3_stream_buffer_t[numBuffers];
Kieran Bingham0cfdf732020-07-01 13:36:24 +0100101 frameBuffers.reserve(numBuffers);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200102}
103
104CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
105{
106 delete[] buffers;
107}
108
109/*
110 * \class CameraDevice
111 *
112 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200113 * the camera3_device_t interface, bridging calls received from the Android
114 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200115 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200116 * The class translates parameters and operations from the Camera HALv3 API to
117 * the libcamera API to provide static information for a Camera, create request
118 * templates for it, process capture requests and then deliver capture results
119 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200120 */
121
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300122CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200123 : running_(false), camera_(camera), staticMetadata_(nullptr),
124 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200125{
126 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
127}
128
129CameraDevice::~CameraDevice()
130{
131 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300132 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200133
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200134 for (auto &it : requestTemplates_)
135 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200136}
137
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200138/*
139 * Initialize the camera static information.
140 * This method is called before the camera device is opened.
141 */
142int CameraDevice::initialize()
143{
144 /* Initialize orientation and facing side of the camera. */
145 const ControlList &properties = camera_->properties();
146
147 if (properties.contains(properties::Location)) {
148 int32_t location = properties.get(properties::Location);
149 switch (location) {
150 case properties::CameraLocationFront:
151 facing_ = CAMERA_FACING_FRONT;
152 break;
153 case properties::CameraLocationBack:
154 facing_ = CAMERA_FACING_BACK;
155 break;
156 case properties::CameraLocationExternal:
157 facing_ = CAMERA_FACING_EXTERNAL;
158 break;
159 }
160 }
161
162 /*
163 * The Android orientation metadata and libcamera rotation property are
164 * defined differently but have identical numerical values for Android
165 * devices such as phones and tablets.
166 */
167 if (properties.contains(properties::Rotation))
168 orientation_ = properties.get(properties::Rotation);
169
Jacopo Mondi117588b2020-05-23 18:53:54 +0200170 int ret = camera_->acquire();
171 if (ret) {
172 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
173 return ret;
174 }
175
176 ret = initializeStreamConfigurations();
177 camera_->release();
178 return ret;
179}
180
181/*
182 * Initialize the format conversion map to translate from Android format
183 * identifier to libcamera pixel formats and fill in the list of supported
184 * stream configurations to be reported to the Android camera framework through
185 * the static stream configuration metadata.
186 */
187int CameraDevice::initializeStreamConfigurations()
188{
189 /*
190 * Get the maximum output resolutions
191 * \todo Get this from the camera properties once defined
192 */
193 std::unique_ptr<CameraConfiguration> cameraConfig =
194 camera_->generateConfiguration({ StillCapture });
195 if (!cameraConfig) {
196 LOG(HAL, Error) << "Failed to get maximum resolution";
197 return -EINVAL;
198 }
199 StreamConfiguration &cfg = cameraConfig->at(0);
200
201 /*
202 * \todo JPEG - Adjust the maximum available resolution by taking the
203 * JPEG encoder requirements into account (alignment and aspect ratio).
204 */
205 const Size maxRes = cfg.size;
206 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
207
208 /*
209 * Build the list of supported image resolutions.
210 *
211 * The resolutions listed in camera3Resolution are mandatory to be
212 * supported, up to the camera maximum resolution.
213 *
214 * Augment the list by adding resolutions calculated from the camera
215 * maximum one.
216 */
217 std::vector<Size> cameraResolutions;
218 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
219 std::back_inserter(cameraResolutions),
220 [&](const Size &res) { return res < maxRes; });
221
222 /*
223 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
224 * resolution.
225 */
226 for (unsigned int divider = 2;; divider <<= 1) {
227 Size derivedSize{
228 maxRes.width / divider,
229 maxRes.height / divider,
230 };
231
232 if (derivedSize.width < 320 ||
233 derivedSize.height < 240)
234 break;
235
236 cameraResolutions.push_back(derivedSize);
237 }
238 cameraResolutions.push_back(maxRes);
239
240 /* Remove duplicated entries from the list of supported resolutions. */
241 std::sort(cameraResolutions.begin(), cameraResolutions.end());
242 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
243 cameraResolutions.erase(last, cameraResolutions.end());
244
245 /*
246 * Build the list of supported camera formats.
247 *
248 * To each Android format a list of compatible libcamera formats is
249 * associated. The first libcamera format that tests successful is added
250 * to the format translation map used when configuring the streams.
251 * It is then tested against the list of supported camera resolutions to
252 * build the stream configuration map reported through the camera static
253 * metadata.
254 */
255 for (const auto &format : camera3FormatsMap) {
256 int androidFormat = format.first;
257 const Camera3Format &camera3Format = format.second;
258 const std::vector<PixelFormat> &libcameraFormats =
259 camera3Format.libcameraFormats;
260
261 /*
262 * Test the libcamera formats that can produce images
263 * compatible with the format defined by Android.
264 */
265 PixelFormat mappedFormat;
266 for (const PixelFormat &pixelFormat : libcameraFormats) {
267 /* \todo Fixed mapping for JPEG. */
268 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +0300269 mappedFormat = formats::MJPEG;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200270 break;
271 }
272
273 /*
274 * The stream configuration size can be adjusted,
275 * not the pixel format.
276 *
277 * \todo This could be simplified once all pipeline
278 * handlers will report the StreamFormats list of
279 * supported formats.
280 */
281 cfg.pixelFormat = pixelFormat;
282
283 CameraConfiguration::Status status = cameraConfig->validate();
284 if (status != CameraConfiguration::Invalid &&
285 cfg.pixelFormat == pixelFormat) {
286 mappedFormat = pixelFormat;
287 break;
288 }
289 }
290 if (!mappedFormat.isValid()) {
291 LOG(HAL, Error) << "Failed to map Android format "
292 << camera3Format.name << " ("
293 << utils::hex(androidFormat) << ")";
294 return -EINVAL;
295 }
296
297 /*
298 * Record the mapping and then proceed to generate the
299 * stream configurations map, by testing the image resolutions.
300 */
301 formatsMap_[androidFormat] = mappedFormat;
302
303 for (const Size &res : cameraResolutions) {
304 cfg.pixelFormat = mappedFormat;
305 cfg.size = res;
306
307 CameraConfiguration::Status status = cameraConfig->validate();
308 /*
309 * Unconditionally report we can produce JPEG.
310 *
311 * \todo The JPEG stream will be implemented as an
312 * HAL-only stream, but some cameras can produce it
313 * directly. As of now, claim support for JPEG without
314 * inspecting where the JPEG stream is produced.
315 */
316 if (androidFormat != HAL_PIXEL_FORMAT_BLOB &&
317 status != CameraConfiguration::Valid)
318 continue;
319
320 streamConfigurations_.push_back({ res, camera3Format.scalerFormat });
321 }
322 }
323
324 LOG(HAL, Debug) << "Collected stream configuration map: ";
325 for (const auto &entry : streamConfigurations_)
326 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
327 << utils::hex(entry.androidScalerCode) << " }";
328
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200329 return 0;
330}
331
332/*
333 * Open a camera device. The static information on the camera shall have been
334 * initialized with a call to CameraDevice::initialize().
335 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200336int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200337{
338 int ret = camera_->acquire();
339 if (ret) {
340 LOG(HAL, Error) << "Failed to acquire the camera";
341 return ret;
342 }
343
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200344 /* Initialize the hw_device_t in the instance camera3_module_t. */
345 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
346 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
347 camera3Device_.common.module = (hw_module_t *)hardwareModule;
348 camera3Device_.common.close = hal_dev_close;
349
350 /*
351 * The camera device operations. These actually implement
352 * the Android Camera HALv3 interface.
353 */
354 camera3Device_.ops = &hal_dev_ops;
355 camera3Device_.priv = this;
356
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200357 return 0;
358}
359
360void CameraDevice::close()
361{
362 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200363 camera_->release();
364
365 running_ = false;
366}
367
368void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
369{
370 callbacks_ = callbacks;
371}
372
Jacopo Mondia80d3812020-05-26 12:31:35 +0200373std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
374{
375 /*
376 * \todo Keep this in sync with the actual number of entries.
377 * Currently: 50 entries, 647 bytes of static metadata
378 */
379 uint32_t numEntries = 50;
380 uint32_t byteSize = 647;
381
382 /*
383 * Calculate space occupation in bytes for dynamically built metadata
384 * entries.
385 *
386 * Each stream configuration entry requires 52 bytes:
387 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
388 * 1 32bits integer for ANDROID_SCALER_AVAILABLE_FORMATS
389 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
390 */
391 byteSize += streamConfigurations_.size() * 52;
392
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300393 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200394}
395
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200396/*
397 * Return static information for the camera.
398 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200399const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200400{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200401 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300402 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200403
404 /*
405 * The here reported metadata are enough to implement a basic capture
406 * example application, but a real camera implementation will require
407 * more.
408 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200409 uint32_t numEntries;
410 uint32_t byteSize;
411 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
412 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300413 if (!staticMetadata_->isValid()) {
414 LOG(HAL, Error) << "Failed to allocate static metadata";
415 delete staticMetadata_;
416 staticMetadata_ = nullptr;
417 return nullptr;
418 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200419
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200420 /* Color correction static metadata. */
421 std::vector<uint8_t> aberrationModes = {
422 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
423 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300424 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
425 aberrationModes.data(),
426 aberrationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200427
428 /* Control static metadata. */
429 std::vector<uint8_t> aeAvailableAntiBandingModes = {
430 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
431 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
432 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
433 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
434 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300435 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
436 aeAvailableAntiBandingModes.data(),
437 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200438
439 std::vector<uint8_t> aeAvailableModes = {
440 ANDROID_CONTROL_AE_MODE_ON,
441 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300442 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
443 aeAvailableModes.data(),
444 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200445
446 std::vector<int32_t> availableAeFpsTarget = {
447 15, 30,
448 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300449 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
450 availableAeFpsTarget.data(),
451 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200452
453 std::vector<int32_t> aeCompensationRange = {
454 0, 0,
455 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300456 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
457 aeCompensationRange.data(),
458 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200459
460 const camera_metadata_rational_t aeCompensationStep[] = {
461 { 0, 1 }
462 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300463 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
464 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200465
466 std::vector<uint8_t> availableAfModes = {
467 ANDROID_CONTROL_AF_MODE_OFF,
468 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300469 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
470 availableAfModes.data(),
471 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200472
473 std::vector<uint8_t> availableEffects = {
474 ANDROID_CONTROL_EFFECT_MODE_OFF,
475 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300476 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
477 availableEffects.data(),
478 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200479
480 std::vector<uint8_t> availableSceneModes = {
481 ANDROID_CONTROL_SCENE_MODE_DISABLED,
482 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300483 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
484 availableSceneModes.data(),
485 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200486
487 std::vector<uint8_t> availableStabilizationModes = {
488 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
489 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300490 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
491 availableStabilizationModes.data(),
492 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200493
494 std::vector<uint8_t> availableAwbModes = {
495 ANDROID_CONTROL_AWB_MODE_OFF,
496 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300497 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
498 availableAwbModes.data(),
499 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200500
501 std::vector<int32_t> availableMaxRegions = {
502 0, 0, 0,
503 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300504 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
505 availableMaxRegions.data(),
506 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200507
508 std::vector<uint8_t> sceneModesOverride = {
509 ANDROID_CONTROL_AE_MODE_ON,
510 ANDROID_CONTROL_AWB_MODE_AUTO,
511 ANDROID_CONTROL_AF_MODE_AUTO,
512 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300513 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
514 sceneModesOverride.data(),
515 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200516
517 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300518 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
519 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200520
521 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300522 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
523 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200524
525 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300526 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
527 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200528
529 /* JPEG static metadata. */
530 std::vector<int32_t> availableThumbnailSizes = {
531 0, 0,
532 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300533 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
534 availableThumbnailSizes.data(),
535 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200536
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200537 /* Sensor static metadata. */
538 int32_t pixelArraySize[] = {
539 2592, 1944,
540 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300541 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
542 &pixelArraySize, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200543
544 int32_t sensorSizes[] = {
545 0, 0, 2560, 1920,
546 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300547 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
548 &sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200549
550 int32_t sensitivityRange[] = {
551 32, 2400,
552 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300553 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
554 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200555
556 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300557 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
558 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200559
560 int64_t exposureTimeRange[] = {
561 100000, 200000000,
562 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300563 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
564 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200565
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200566 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200567
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200568 std::vector<int32_t> testPatterModes = {
569 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
570 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300571 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
572 testPatterModes.data(),
573 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200574
575 std::vector<float> physicalSize = {
576 2592, 1944,
577 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300578 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
579 physicalSize.data(),
580 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200581
582 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300583 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
584 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200585
586 /* Statistics static metadata. */
587 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300588 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
589 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200590
591 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300592 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
593 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200594
595 /* Sync static metadata. */
596 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300597 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200598
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200599 /* Flash static metadata. */
600 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300601 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
602 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200603
604 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200605 std::vector<float> lensApertures = {
606 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200607 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300608 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
609 lensApertures.data(),
610 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200611
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200612 uint8_t lensFacing;
613 switch (facing_) {
614 default:
615 case CAMERA_FACING_FRONT:
616 lensFacing = ANDROID_LENS_FACING_FRONT;
617 break;
618 case CAMERA_FACING_BACK:
619 lensFacing = ANDROID_LENS_FACING_BACK;
620 break;
621 case CAMERA_FACING_EXTERNAL:
622 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
623 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100624 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300625 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200626
627 std::vector<float> lensFocalLenghts = {
628 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200629 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300630 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
631 lensFocalLenghts.data(),
632 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200633
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200634 std::vector<uint8_t> opticalStabilizations = {
635 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
636 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300637 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
638 opticalStabilizations.data(),
639 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200640
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200641 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300642 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
643 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200644
645 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300646 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
647 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200648
649 /* Noise reduction modes. */
650 uint8_t noiseReductionModes = ANDROID_NOISE_REDUCTION_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300651 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
652 &noiseReductionModes, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200653
654 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200655 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300656 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
657 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200658
Jacopo Mondibde7b982020-05-25 17:18:28 +0200659 std::vector<uint32_t> availableStreamFormats;
660 availableStreamFormats.reserve(streamConfigurations_.size());
661 std::transform(streamConfigurations_.begin(), streamConfigurations_.end(),
662 std::back_inserter(availableStreamFormats),
663 [](const auto &entry) { return entry.androidScalerCode; });
Laurent Pinchart39860092019-09-05 03:12:34 +0300664 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_FORMATS,
665 availableStreamFormats.data(),
666 availableStreamFormats.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200667
Jacopo Mondibde7b982020-05-25 17:18:28 +0200668 std::vector<uint32_t> availableStreamConfigurations;
669 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
670 for (const auto &entry : streamConfigurations_) {
671 availableStreamConfigurations.push_back(entry.androidScalerCode);
672 availableStreamConfigurations.push_back(entry.resolution.width);
673 availableStreamConfigurations.push_back(entry.resolution.height);
674 availableStreamConfigurations.push_back(
675 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
676 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300677 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
678 availableStreamConfigurations.data(),
679 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200680
681 std::vector<int64_t> availableStallDurations = {
682 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
683 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300684 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
685 availableStallDurations.data(),
686 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200687
Jacopo Mondibde7b982020-05-25 17:18:28 +0200688 /* \todo Collect the minimum frame duration from the camera. */
689 std::vector<int64_t> minFrameDurations;
690 minFrameDurations.reserve(streamConfigurations_.size() * 4);
691 for (const auto &entry : streamConfigurations_) {
692 minFrameDurations.push_back(entry.androidScalerCode);
693 minFrameDurations.push_back(entry.resolution.width);
694 minFrameDurations.push_back(entry.resolution.height);
695 minFrameDurations.push_back(33333333);
696 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300697 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
698 minFrameDurations.data(),
699 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200700
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200701 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300702 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200703
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200704 /* Info static metadata. */
705 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300706 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
707 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200708
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200709 /* Request static metadata. */
710 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300711 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
712 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200713
714 uint8_t maxPipelineDepth = 2;
Laurent Pinchart39860092019-09-05 03:12:34 +0300715 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
716 &maxPipelineDepth, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200717
718 std::vector<uint8_t> availableCapabilities = {
719 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
720 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300721 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
722 availableCapabilities.data(),
723 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200724
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200725 std::vector<int32_t> availableCharacteristicsKeys = {
726 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
727 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
728 ANDROID_CONTROL_AE_AVAILABLE_MODES,
729 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
730 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
731 ANDROID_CONTROL_AE_COMPENSATION_STEP,
732 ANDROID_CONTROL_AF_AVAILABLE_MODES,
733 ANDROID_CONTROL_AVAILABLE_EFFECTS,
734 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
735 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
736 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
737 ANDROID_CONTROL_MAX_REGIONS,
738 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
739 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
740 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
741 ANDROID_CONTROL_AVAILABLE_MODES,
742 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
743 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
744 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
745 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
746 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
747 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
748 ANDROID_SENSOR_ORIENTATION,
749 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
750 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
751 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
752 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
753 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
754 ANDROID_SYNC_MAX_LATENCY,
755 ANDROID_FLASH_INFO_AVAILABLE,
756 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
757 ANDROID_LENS_FACING,
758 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
759 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
760 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
761 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
762 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
763 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
764 ANDROID_SCALER_AVAILABLE_FORMATS,
765 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
766 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
767 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
768 ANDROID_SCALER_CROPPING_TYPE,
769 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
770 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
771 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
772 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
773 };
774 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
775 availableCharacteristicsKeys.data(),
776 availableCharacteristicsKeys.size());
777
778 std::vector<int32_t> availableRequestKeys = {
779 ANDROID_CONTROL_AE_MODE,
780 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
781 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
782 ANDROID_CONTROL_AE_LOCK,
783 ANDROID_CONTROL_AF_TRIGGER,
784 ANDROID_CONTROL_AWB_MODE,
785 ANDROID_CONTROL_AWB_LOCK,
786 ANDROID_FLASH_MODE,
787 ANDROID_STATISTICS_FACE_DETECT_MODE,
788 ANDROID_NOISE_REDUCTION_MODE,
789 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
790 ANDROID_CONTROL_CAPTURE_INTENT,
791 };
792 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
793 availableRequestKeys.data(),
794 availableRequestKeys.size());
795
796 std::vector<int32_t> availableResultKeys = {
797 ANDROID_CONTROL_AE_STATE,
798 ANDROID_CONTROL_AE_LOCK,
799 ANDROID_CONTROL_AF_STATE,
800 ANDROID_CONTROL_AWB_STATE,
801 ANDROID_CONTROL_AWB_LOCK,
802 ANDROID_LENS_STATE,
803 ANDROID_SCALER_CROP_REGION,
804 ANDROID_SENSOR_TIMESTAMP,
805 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
806 ANDROID_SENSOR_EXPOSURE_TIME,
807 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
808 ANDROID_STATISTICS_SCENE_FLICKER,
809 };
810 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
811 availableResultKeys.data(),
812 availableResultKeys.size());
813
Laurent Pinchart39860092019-09-05 03:12:34 +0300814 if (!staticMetadata_->isValid()) {
815 LOG(HAL, Error) << "Failed to construct static metadata";
816 delete staticMetadata_;
817 staticMetadata_ = nullptr;
818 return nullptr;
819 }
820
821 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200822}
823
824/*
825 * Produce a metadata pack to be used as template for a capture request.
826 */
827const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
828{
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200829 auto it = requestTemplates_.find(type);
830 if (it != requestTemplates_.end())
831 return it->second->get();
832
833 /* Use the capture intent matching the requested template type. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200834 uint8_t captureIntent;
835 switch (type) {
836 case CAMERA3_TEMPLATE_PREVIEW:
837 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
838 break;
839 case CAMERA3_TEMPLATE_STILL_CAPTURE:
840 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
841 break;
842 case CAMERA3_TEMPLATE_VIDEO_RECORD:
843 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
844 break;
845 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
846 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
847 break;
848 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
849 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
850 break;
851 case CAMERA3_TEMPLATE_MANUAL:
852 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
853 break;
854 default:
855 LOG(HAL, Error) << "Invalid template request type: " << type;
856 return nullptr;
857 }
858
Jacopo Mondi63703472019-09-04 16:18:22 +0200859 /*
860 * \todo Keep this in sync with the actual number of entries.
861 * Currently: 12 entries, 15 bytes
862 */
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200863 CameraMetadata *requestTemplate = new CameraMetadata(15, 20);
864 if (!requestTemplate->isValid()) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200865 LOG(HAL, Error) << "Failed to allocate template metadata";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200866 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200867 return nullptr;
868 }
869
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200870 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200871 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
872 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200873
874 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200875 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
876 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200877
878 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200879 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
880 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200881
882 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200883 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
884 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200885
886 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200887 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
888 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200889
890 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200891 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
892 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200893
894 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200895 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
896 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200897
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200898 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200899 requestTemplate->addEntry(ANDROID_FLASH_MODE,
900 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200901
902 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200903 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
904 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200905
Jacopo Mondi9b361dc2019-09-04 16:18:21 +0200906 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200907 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
908 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +0200909
910 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200911 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
912 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +0200913
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200914 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
915 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200916
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200917 if (!requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +0300918 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200919 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +0300920 return nullptr;
921 }
922
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200923 requestTemplates_[type] = requestTemplate;
924 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200925}
926
Kieran Bingham43e3b802020-06-26 09:58:49 +0100927PixelFormat CameraDevice::toPixelFormat(int format)
928{
929 /* Translate Android format code to libcamera pixel format. */
930 auto it = formatsMap_.find(format);
931 if (it == formatsMap_.end()) {
932 LOG(HAL, Error) << "Requested format " << utils::hex(format)
933 << " not supported";
934 return PixelFormat();
935 }
936
937 return it->second;
938}
939
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200940/*
941 * Inspect the stream_list to produce a list of StreamConfiguration to
942 * be use to configure the Camera.
943 */
944int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
945{
Kieran Bingham0a9244e2020-06-26 20:19:10 +0100946 /*
947 * Generate an empty configuration, and construct a StreamConfiguration
948 * for each camera3_stream to add to it.
949 */
950 config_ = camera_->generateConfiguration();
951 if (!config_) {
952 LOG(HAL, Error) << "Failed to generate camera configuration";
953 return -EINVAL;
954 }
955
Kieran Bingham2f34f5e2020-07-01 16:42:13 +0100956 /*
957 * Clear and remove any existing configuration from previous calls, and
958 * ensure the required entries are available without further
959 * re-allcoation.
960 */
961 streams_.clear();
962 streams_.reserve(stream_list->num_streams);
963
964 /*
965 * Track actually created streams, as there may not be a 1:1 mapping of
966 * camera3 streams to libcamera streams.
967 */
968 unsigned int streamIndex = 0;
969
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200970 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
971 camera3_stream_t *stream = stream_list->streams[i];
972
Kieran Bingham43e3b802020-06-26 09:58:49 +0100973 PixelFormat format = toPixelFormat(stream->format);
974
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200975 LOG(HAL, Info) << "Stream #" << i
976 << ", direction: " << stream->stream_type
977 << ", width: " << stream->width
978 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +0100979 << ", format: " << utils::hex(stream->format)
980 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +0100981
982 if (!format.isValid())
983 return -EINVAL;
984
985 StreamConfiguration streamConfiguration;
986
987 streamConfiguration.size.width = stream->width;
988 streamConfiguration.size.height = stream->height;
989 streamConfiguration.pixelFormat = format;
990
991 config_->addConfiguration(streamConfiguration);
Kieran Bingham2f34f5e2020-07-01 16:42:13 +0100992
993 streams_[i].index = streamIndex++;
Kieran Bingham0cfdf732020-07-01 13:36:24 +0100994 stream->priv = static_cast<void *>(&streams_[i]);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200995 }
996
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200997 switch (config_->validate()) {
998 case CameraConfiguration::Valid:
999 break;
1000 case CameraConfiguration::Adjusted:
1001 LOG(HAL, Info) << "Camera configuration adjusted";
1002 config_.reset();
1003 return -EINVAL;
1004 case CameraConfiguration::Invalid:
1005 LOG(HAL, Info) << "Camera configuration invalid";
1006 config_.reset();
1007 return -EINVAL;
1008 }
1009
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001010 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1011 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001012 CameraStream *cameraStream = &streams_[i];
1013 StreamConfiguration &cfg = config_->at(cameraStream->index);
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001014
1015 /* Use the bufferCount confirmed by the validation process. */
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001016 stream->max_buffers = cfg.bufferCount;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001017 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001018
1019 /*
1020 * Once the CameraConfiguration has been adjusted/validated
1021 * it can be applied to the camera.
1022 */
1023 int ret = camera_->configure(config_.get());
1024 if (ret) {
1025 LOG(HAL, Error) << "Failed to configure camera '"
1026 << camera_->name() << "'";
1027 return ret;
1028 }
1029
1030 return 0;
1031}
1032
Kieran Bingham74ab4422020-07-01 13:25:38 +01001033FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1034{
1035 std::vector<FrameBuffer::Plane> planes;
1036 for (unsigned int i = 0; i < 3; i++) {
1037 FrameBuffer::Plane plane;
1038 plane.fd = FileDescriptor(camera3buffer->data[i]);
1039 /*
1040 * Setting length to zero here is OK as the length is only used
1041 * to map the memory of the plane. Libcamera do not need to poke
1042 * at the memory content queued by the HAL.
1043 */
1044 plane.length = 0;
1045 planes.push_back(std::move(plane));
1046 }
1047
1048 return new FrameBuffer(std::move(planes));
1049}
1050
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001051int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001052{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001053 if (camera3Request->num_output_buffers != 1) {
1054 LOG(HAL, Error) << "Invalid number of output buffers: "
1055 << camera3Request->num_output_buffers;
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001056 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001057 }
1058
1059 /* Start the camera if that's the first request we handle. */
1060 if (!running_) {
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001061 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001062 if (ret) {
1063 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001064 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001065 }
1066
1067 running_ = true;
1068 }
1069
1070 /*
1071 * Queue a request for the Camera with the provided dmabuf file
1072 * descriptors.
1073 */
1074 const camera3_stream_buffer_t *camera3Buffers =
1075 camera3Request->output_buffers;
1076
1077 /*
1078 * Save the request descriptors for use at completion time.
1079 * The descriptor and the associated memory reserved here are freed
1080 * at request complete time.
1081 */
1082 Camera3RequestDescriptor *descriptor =
1083 new Camera3RequestDescriptor(camera3Request->frame_number,
1084 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001085
1086 Request *request =
1087 camera_->createRequest(reinterpret_cast<uint64_t>(descriptor));
1088
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001089 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001090 CameraStream *cameraStream =
1091 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1092
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001093 /*
1094 * Keep track of which stream the request belongs to and store
1095 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001096 */
1097 descriptor->buffers[i].stream = camera3Buffers[i].stream;
1098 descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001099
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001100 /*
1101 * Create a libcamera buffer using the dmabuf descriptors of
1102 * the camera3Buffer for each stream. The FrameBuffer is
1103 * directly associated with the Camera3RequestDescriptor for
1104 * lifetime management only.
1105 */
1106 FrameBuffer *buffer = createFrameBuffer(*camera3Buffers[i].buffer);
1107 if (!buffer) {
1108 LOG(HAL, Error) << "Failed to create buffer";
1109 delete request;
1110 delete descriptor;
1111 return -ENOMEM;
1112 }
1113 descriptor->frameBuffers.emplace_back(buffer);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001114
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001115 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index);
1116 Stream *stream = streamConfiguration->stream();
1117
1118 request->addBuffer(stream, buffer);
1119 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001120
1121 int ret = camera_->queueRequest(request);
1122 if (ret) {
1123 LOG(HAL, Error) << "Failed to queue request";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001124 delete request;
1125 delete descriptor;
1126 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001127 }
1128
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001129 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001130}
1131
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001132void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001133{
Niklas Söderlund9217f272019-11-22 16:22:56 +01001134 const std::map<Stream *, FrameBuffer *> &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001135 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001136 std::unique_ptr<CameraMetadata> resultMetadata;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001137
1138 if (request->status() != Request::RequestComplete) {
1139 LOG(HAL, Error) << "Request not succesfully completed: "
1140 << request->status();
1141 status = CAMERA3_BUFFER_STATUS_ERROR;
1142 }
1143
1144 /* Prepare to call back the Android camera stack. */
1145 Camera3RequestDescriptor *descriptor =
1146 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
1147
1148 camera3_capture_result_t captureResult = {};
1149 captureResult.frame_number = descriptor->frameNumber;
1150 captureResult.num_output_buffers = descriptor->numBuffers;
1151 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001152 descriptor->buffers[i].acquire_fence = -1;
1153 descriptor->buffers[i].release_fence = -1;
1154 descriptor->buffers[i].status = status;
1155 }
1156 captureResult.output_buffers =
1157 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers);
1158
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001159 /*
1160 * \todo The timestamp used for the metadata is currently always taken
1161 * from the first buffer (which may be the first stream) in the Request.
1162 * It might be appropriate to return a 'correct' (as determined by
1163 * pipeline handlers) timestamp in the Request itself.
1164 */
1165 FrameBuffer *buffer = buffers.begin()->second;
1166
Laurent Pinchart39860092019-09-05 03:12:34 +03001167 if (status == CAMERA3_BUFFER_STATUS_OK) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001168 notifyShutter(descriptor->frameNumber,
Niklas Söderlund9217f272019-11-22 16:22:56 +01001169 buffer->metadata().timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001170
1171 captureResult.partial_result = 1;
1172 resultMetadata = getResultMetadata(descriptor->frameNumber,
Niklas Söderlund9217f272019-11-22 16:22:56 +01001173 buffer->metadata().timestamp);
Laurent Pinchart39860092019-09-05 03:12:34 +03001174 captureResult.result = resultMetadata->get();
1175 }
1176
1177 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1178 /* \todo Improve error handling. In case we notify an error
1179 * because the metadata generation fails, a shutter event has
1180 * already been notified for this frame number before the error
1181 * is here signalled. Make sure the error path plays well with
1182 * the camera stack state machine.
1183 */
1184 notifyError(descriptor->frameNumber,
1185 descriptor->buffers[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001186 }
1187
1188 callbacks_->process_capture_result(callbacks_, &captureResult);
1189
1190 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001191}
1192
Jacopo Mondia7b92772020-05-26 15:41:41 +02001193std::string CameraDevice::logPrefix() const
1194{
1195 return "'" + camera_->name() + "'";
1196}
1197
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001198void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1199{
1200 camera3_notify_msg_t notify = {};
1201
1202 notify.type = CAMERA3_MSG_SHUTTER;
1203 notify.message.shutter.frame_number = frameNumber;
1204 notify.message.shutter.timestamp = timestamp;
1205
1206 callbacks_->notify(callbacks_, &notify);
1207}
1208
1209void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1210{
1211 camera3_notify_msg_t notify = {};
1212
1213 notify.type = CAMERA3_MSG_ERROR;
1214 notify.message.error.error_stream = stream;
1215 notify.message.error.frame_number = frameNumber;
1216 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1217
1218 callbacks_->notify(callbacks_, &notify);
1219}
1220
1221/*
1222 * Produce a set of fixed result metadata.
1223 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001224std::unique_ptr<CameraMetadata> CameraDevice::getResultMetadata(int frame_number,
1225 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001226{
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001227 /*
1228 * \todo Keep this in sync with the actual number of entries.
Laurent Pinchart39860092019-09-05 03:12:34 +03001229 * Currently: 12 entries, 36 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001230 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001231 std::unique_ptr<CameraMetadata> resultMetadata =
Laurent Pinchartacf18e42020-01-14 01:35:22 +02001232 std::make_unique<CameraMetadata>(15, 50);
Laurent Pinchart39860092019-09-05 03:12:34 +03001233 if (!resultMetadata->isValid()) {
1234 LOG(HAL, Error) << "Failed to allocate static metadata";
1235 return nullptr;
1236 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001237
1238 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001239 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001240
1241 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001242 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001243
1244 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001245 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001246
1247 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001248 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001249
1250 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001251 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001252
1253 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001254 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001255
1256 int32_t sensorSizes[] = {
1257 0, 0, 2560, 1920,
1258 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001259 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001260
Laurent Pinchart39860092019-09-05 03:12:34 +03001261 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001262
1263 /* 33.3 msec */
1264 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001265 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1266 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001267
1268 /* 16.6 msec */
1269 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001270 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1271 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001272
1273 const uint8_t lens_shading_map_mode =
1274 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001275 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1276 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001277
1278 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001279 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1280 &scene_flicker, 1);
1281
1282 /*
1283 * Return the result metadata pack even is not valid: get() will return
1284 * nullptr.
1285 */
1286 if (!resultMetadata->isValid()) {
1287 LOG(HAL, Error) << "Failed to construct result metadata";
1288 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001289
1290 return resultMetadata;
1291}