blob: e9404c2f300463d1c7c8008e30d020ebdc84a21a [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"
Umang Jainb2b8c4d2020-10-16 11:07:54 +053010#include "post_processor.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020011
Kieran Bingham83ae84e2020-07-03 12:34:59 +010012#include <sys/mman.h>
Jacopo Mondia80d3812020-05-26 12:31:35 +020013#include <tuple>
Jacopo Mondi117588b2020-05-23 18:53:54 +020014#include <vector>
15
Jacopo Mondi857a2162019-11-20 17:00:49 +010016#include <libcamera/controls.h>
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030017#include <libcamera/formats.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010018#include <libcamera/property_ids.h>
19
Niklas Söderlund7876d632020-07-21 00:16:24 +020020#include "libcamera/internal/formats.h"
Laurent Pinchart93e72b62020-05-12 00:58:34 +030021#include "libcamera/internal/log.h"
22#include "libcamera/internal/utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020023
Laurent Pinchart39860092019-09-05 03:12:34 +030024#include "camera_metadata.h"
Jacopo Mondi117588b2020-05-23 18:53:54 +020025#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020026
27using namespace libcamera;
28
Jacopo Mondi117588b2020-05-23 18:53:54 +020029namespace {
30
31/*
32 * \var camera3Resolutions
33 * \brief The list of image resolutions defined as mandatory to be supported by
34 * the Android Camera3 specification
35 */
36const std::vector<Size> camera3Resolutions = {
37 { 320, 240 },
38 { 640, 480 },
39 { 1280, 720 },
40 { 1920, 1080 }
41};
42
43/*
44 * \struct Camera3Format
45 * \brief Data associated with an Android format identifier
46 * \var libcameraFormats List of libcamera pixel formats compatible with the
47 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020048 * \var name The human-readable representation of the Android format code
49 */
50struct Camera3Format {
51 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020052 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020053 const char *name;
54};
55
56/*
57 * \var camera3FormatsMap
58 * \brief Associate Android format code with ancillary data
59 */
60const std::map<int, const Camera3Format> camera3FormatsMap = {
61 {
62 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030063 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020064 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020065 "BLOB"
66 }
67 }, {
68 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030069 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020070 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020071 "YCbCr_420_888"
72 }
73 }, {
74 /*
75 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
76 * usage flag. For now, copy the YCbCr_420 configuration.
77 */
78 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030079 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020080 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020081 "IMPLEMENTATION_DEFINED"
82 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020083 }, {
84 HAL_PIXEL_FORMAT_RAW10, {
85 {
86 formats::SBGGR10_CSI2P,
87 formats::SGBRG10_CSI2P,
88 formats::SGRBG10_CSI2P,
89 formats::SRGGB10_CSI2P
90 },
91 false,
92 "RAW10"
93 }
94 }, {
95 HAL_PIXEL_FORMAT_RAW12, {
96 {
97 formats::SBGGR12_CSI2P,
98 formats::SGBRG12_CSI2P,
99 formats::SGRBG12_CSI2P,
100 formats::SRGGB12_CSI2P
101 },
102 false,
103 "RAW12"
104 }
105 }, {
106 HAL_PIXEL_FORMAT_RAW16, {
107 {
108 formats::SBGGR16,
109 formats::SGBRG16,
110 formats::SGRBG16,
111 formats::SRGGB16
112 },
113 false,
114 "RAW16"
115 }
116 }, {
117 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
118 {
119 formats::SBGGR10_IPU3,
120 formats::SGBRG10_IPU3,
121 formats::SGRBG10_IPU3,
122 formats::SRGGB10_IPU3
123 },
124 false,
125 "RAW_OPAQUE"
126 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200127 },
128};
129
130} /* namespace */
131
Hirokazu Honda6c5792f2020-10-20 18:15:01 +0900132LOG_DECLARE_CATEGORY(HAL)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200133
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100134MappedCamera3Buffer::MappedCamera3Buffer(const buffer_handle_t camera3buffer,
135 int flags)
136{
137 maps_.reserve(camera3buffer->numFds);
138 error_ = 0;
139
140 for (int i = 0; i < camera3buffer->numFds; i++) {
141 if (camera3buffer->data[i] == -1)
142 continue;
143
144 off_t length = lseek(camera3buffer->data[i], 0, SEEK_END);
145 if (length < 0) {
146 error_ = -errno;
147 LOG(HAL, Error) << "Failed to query plane length";
148 break;
149 }
150
151 void *address = mmap(nullptr, length, flags, MAP_SHARED,
152 camera3buffer->data[i], 0);
153 if (address == MAP_FAILED) {
154 error_ = -errno;
155 LOG(HAL, Error) << "Failed to mmap plane";
156 break;
157 }
158
159 maps_.emplace_back(static_cast<uint8_t *>(address),
160 static_cast<size_t>(length));
161 }
162}
163
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200164/*
165 * \struct Camera3RequestDescriptor
166 *
167 * A utility structure that groups information about a capture request to be
168 * later re-used at request complete time to notify the framework.
169 */
170
171CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200172 Camera *camera, unsigned int frameNumber, unsigned int numBuffers)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200173 : frameNumber(frameNumber), numBuffers(numBuffers)
174{
175 buffers = new camera3_stream_buffer_t[numBuffers];
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200176
177 /*
178 * FrameBuffer instances created by wrapping a camera3 provided dmabuf
179 * are emplaced in this vector of unique_ptr<> for lifetime management.
180 */
Kieran Bingham0cfdf732020-07-01 13:36:24 +0100181 frameBuffers.reserve(numBuffers);
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200182
183 /*
184 * Create the libcamera::Request unique_ptr<> to tie its lifetime
185 * to the descriptor's one. Set the descriptor's address as the
186 * request's cookie to retrieve it at completion time.
187 */
188 request = std::make_unique<CaptureRequest>(camera,
189 reinterpret_cast<uint64_t>(this));
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200190}
191
192CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
193{
194 delete[] buffers;
195}
196
197/*
198 * \class CameraDevice
199 *
200 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200201 * the camera3_device_t interface, bridging calls received from the Android
202 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200203 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200204 * The class translates parameters and operations from the Camera HALv3 API to
205 * the libcamera API to provide static information for a Camera, create request
206 * templates for it, process capture requests and then deliver capture results
207 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200208 */
209
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300210CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000211 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200212 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200213{
214 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100215
216 /*
217 * \todo Determine a more accurate value for this during
218 * streamConfiguration.
219 */
220 maxJpegBufferSize_ = 13 << 20; /* 13631488 from USB HAL */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200221}
222
223CameraDevice::~CameraDevice()
224{
225 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300226 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200227
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200228 for (auto &it : requestTemplates_)
229 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200230}
231
Umang Jainf8e28132020-08-21 14:46:08 +0000232std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
233 const std::shared_ptr<Camera> &cam)
234{
235 CameraDevice *camera = new CameraDevice(id, cam);
236 return std::shared_ptr<CameraDevice>(camera);
237}
238
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200239/*
240 * Initialize the camera static information.
241 * This method is called before the camera device is opened.
242 */
243int CameraDevice::initialize()
244{
245 /* Initialize orientation and facing side of the camera. */
246 const ControlList &properties = camera_->properties();
247
248 if (properties.contains(properties::Location)) {
249 int32_t location = properties.get(properties::Location);
250 switch (location) {
251 case properties::CameraLocationFront:
252 facing_ = CAMERA_FACING_FRONT;
253 break;
254 case properties::CameraLocationBack:
255 facing_ = CAMERA_FACING_BACK;
256 break;
257 case properties::CameraLocationExternal:
258 facing_ = CAMERA_FACING_EXTERNAL;
259 break;
260 }
261 }
262
263 /*
Umang Jaine9176552020-09-09 16:17:54 +0530264 * The Android orientation metadata specifies its rotation correction
265 * value in clockwise direction whereas libcamera specifies the
266 * rotation property in anticlockwise direction. Read the libcamera's
267 * rotation property (anticlockwise) and compute the corresponding
268 * value for clockwise direction as required by the Android orientation
269 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200270 */
Umang Jaine9176552020-09-09 16:17:54 +0530271 if (properties.contains(properties::Rotation)) {
272 int rotation = properties.get(properties::Rotation);
273 orientation_ = (360 - rotation) % 360;
274 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200275
Jacopo Mondi117588b2020-05-23 18:53:54 +0200276 int ret = camera_->acquire();
277 if (ret) {
278 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
279 return ret;
280 }
281
282 ret = initializeStreamConfigurations();
283 camera_->release();
284 return ret;
285}
286
Jacopo Mondibfee6312020-09-01 17:42:13 +0200287std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
288 const PixelFormat &pixelFormat,
289 const std::vector<Size> &resolutions)
290{
291 std::vector<Size> supportedResolutions;
292
293 StreamConfiguration &cfg = cameraConfig->at(0);
294 for (const Size &res : resolutions) {
295 cfg.pixelFormat = pixelFormat;
296 cfg.size = res;
297
298 CameraConfiguration::Status status = cameraConfig->validate();
299 if (status != CameraConfiguration::Valid) {
300 LOG(HAL, Debug) << cfg.toString() << " not supported";
301 continue;
302 }
303
304 LOG(HAL, Debug) << cfg.toString() << " supported";
305
306 supportedResolutions.push_back(res);
307 }
308
309 return supportedResolutions;
310}
311
Jacopo Mondi49610332020-09-01 18:11:34 +0200312std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
313{
314 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200315 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200316 StreamConfiguration &cfg = cameraConfig->at(0);
317 const StreamFormats &formats = cfg.formats();
318 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
319
320 return supportedResolutions;
321}
322
Jacopo Mondi117588b2020-05-23 18:53:54 +0200323/*
324 * Initialize the format conversion map to translate from Android format
325 * identifier to libcamera pixel formats and fill in the list of supported
326 * stream configurations to be reported to the Android camera framework through
327 * the static stream configuration metadata.
328 */
329int CameraDevice::initializeStreamConfigurations()
330{
331 /*
332 * Get the maximum output resolutions
333 * \todo Get this from the camera properties once defined
334 */
335 std::unique_ptr<CameraConfiguration> cameraConfig =
336 camera_->generateConfiguration({ StillCapture });
337 if (!cameraConfig) {
338 LOG(HAL, Error) << "Failed to get maximum resolution";
339 return -EINVAL;
340 }
341 StreamConfiguration &cfg = cameraConfig->at(0);
342
343 /*
344 * \todo JPEG - Adjust the maximum available resolution by taking the
345 * JPEG encoder requirements into account (alignment and aspect ratio).
346 */
347 const Size maxRes = cfg.size;
348 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
349
350 /*
351 * Build the list of supported image resolutions.
352 *
353 * The resolutions listed in camera3Resolution are mandatory to be
354 * supported, up to the camera maximum resolution.
355 *
356 * Augment the list by adding resolutions calculated from the camera
357 * maximum one.
358 */
359 std::vector<Size> cameraResolutions;
360 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
361 std::back_inserter(cameraResolutions),
362 [&](const Size &res) { return res < maxRes; });
363
364 /*
365 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
366 * resolution.
367 */
368 for (unsigned int divider = 2;; divider <<= 1) {
369 Size derivedSize{
370 maxRes.width / divider,
371 maxRes.height / divider,
372 };
373
374 if (derivedSize.width < 320 ||
375 derivedSize.height < 240)
376 break;
377
378 cameraResolutions.push_back(derivedSize);
379 }
380 cameraResolutions.push_back(maxRes);
381
382 /* Remove duplicated entries from the list of supported resolutions. */
383 std::sort(cameraResolutions.begin(), cameraResolutions.end());
384 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
385 cameraResolutions.erase(last, cameraResolutions.end());
386
387 /*
388 * Build the list of supported camera formats.
389 *
390 * To each Android format a list of compatible libcamera formats is
391 * associated. The first libcamera format that tests successful is added
392 * to the format translation map used when configuring the streams.
393 * It is then tested against the list of supported camera resolutions to
394 * build the stream configuration map reported through the camera static
395 * metadata.
396 */
397 for (const auto &format : camera3FormatsMap) {
398 int androidFormat = format.first;
399 const Camera3Format &camera3Format = format.second;
400 const std::vector<PixelFormat> &libcameraFormats =
401 camera3Format.libcameraFormats;
402
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200403 LOG(HAL, Debug) << "Trying to map Android format "
404 << camera3Format.name;
405
Jacopo Mondi117588b2020-05-23 18:53:54 +0200406 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200407 * JPEG is always supported, either produced directly by the
408 * camera, or encoded in the HAL.
409 */
410 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
411 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200412 LOG(HAL, Debug) << "Mapped Android format "
413 << camera3Format.name << " to "
414 << formats::MJPEG.toString()
415 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200416 continue;
417 }
418
419 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200420 * Test the libcamera formats that can produce images
421 * compatible with the format defined by Android.
422 */
423 PixelFormat mappedFormat;
424 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200425
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200426 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
427
Jacopo Mondi117588b2020-05-23 18:53:54 +0200428 /*
429 * The stream configuration size can be adjusted,
430 * not the pixel format.
431 *
432 * \todo This could be simplified once all pipeline
433 * handlers will report the StreamFormats list of
434 * supported formats.
435 */
436 cfg.pixelFormat = pixelFormat;
437
438 CameraConfiguration::Status status = cameraConfig->validate();
439 if (status != CameraConfiguration::Invalid &&
440 cfg.pixelFormat == pixelFormat) {
441 mappedFormat = pixelFormat;
442 break;
443 }
444 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200445
446 if (!mappedFormat.isValid()) {
447 /* If the format is not mandatory, skip it. */
448 if (!camera3Format.mandatory)
449 continue;
450
451 LOG(HAL, Error)
452 << "Failed to map mandatory Android format "
453 << camera3Format.name << " ("
454 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200455 return -EINVAL;
456 }
457
458 /*
459 * Record the mapping and then proceed to generate the
460 * stream configurations map, by testing the image resolutions.
461 */
462 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200463 LOG(HAL, Debug) << "Mapped Android format "
464 << camera3Format.name << " to "
465 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200466
Jacopo Mondi49610332020-09-01 18:11:34 +0200467 std::vector<Size> resolutions;
468 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
469 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
470 resolutions = getRawResolutions(mappedFormat);
471 else
472 resolutions = getYUVResolutions(cameraConfig.get(),
473 mappedFormat,
474 cameraResolutions);
475
Jacopo Mondibfee6312020-09-01 17:42:13 +0200476 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200477 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200478
479 /*
480 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
481 * from which JPEG is produced, add an entry for
482 * the JPEG stream.
483 *
484 * \todo Wire the JPEG encoder to query the supported
485 * sizes provided a list of formats it can encode.
486 *
487 * \todo Support JPEG streams produced by the Camera
488 * natively.
489 */
490 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888)
491 streamConfigurations_.push_back(
492 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200493 }
494 }
495
496 LOG(HAL, Debug) << "Collected stream configuration map: ";
497 for (const auto &entry : streamConfigurations_)
498 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200499 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200500
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200501 return 0;
502}
503
504/*
505 * Open a camera device. The static information on the camera shall have been
506 * initialized with a call to CameraDevice::initialize().
507 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200508int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200509{
510 int ret = camera_->acquire();
511 if (ret) {
512 LOG(HAL, Error) << "Failed to acquire the camera";
513 return ret;
514 }
515
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200516 /* Initialize the hw_device_t in the instance camera3_module_t. */
517 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
518 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
519 camera3Device_.common.module = (hw_module_t *)hardwareModule;
520 camera3Device_.common.close = hal_dev_close;
521
522 /*
523 * The camera device operations. These actually implement
524 * the Android Camera HALv3 interface.
525 */
526 camera3Device_.ops = &hal_dev_ops;
527 camera3Device_.priv = this;
528
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200529 return 0;
530}
531
532void CameraDevice::close()
533{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200534 streams_.clear();
535
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200536 worker_.stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200537 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200538 camera_->release();
539
540 running_ = false;
541}
542
543void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
544{
545 callbacks_ = callbacks;
546}
547
Jacopo Mondia80d3812020-05-26 12:31:35 +0200548std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
549{
550 /*
551 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100552 * Currently: 51 entries, 687 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200553 */
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100554 uint32_t numEntries = 51;
555 uint32_t byteSize = 687;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200556
557 /*
558 * Calculate space occupation in bytes for dynamically built metadata
559 * entries.
560 *
561 * Each stream configuration entry requires 52 bytes:
562 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200563 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
564 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200565 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200566
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300567 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200568}
569
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200570/*
571 * Return static information for the camera.
572 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200573const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200574{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200575 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300576 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200577
578 /*
579 * The here reported metadata are enough to implement a basic capture
580 * example application, but a real camera implementation will require
581 * more.
582 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200583 uint32_t numEntries;
584 uint32_t byteSize;
585 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
586 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300587 if (!staticMetadata_->isValid()) {
588 LOG(HAL, Error) << "Failed to allocate static metadata";
589 delete staticMetadata_;
590 staticMetadata_ = nullptr;
591 return nullptr;
592 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200593
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200594 /* Color correction static metadata. */
595 std::vector<uint8_t> aberrationModes = {
596 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
597 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300598 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
599 aberrationModes.data(),
600 aberrationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200601
602 /* Control static metadata. */
603 std::vector<uint8_t> aeAvailableAntiBandingModes = {
604 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
605 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
606 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
607 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
608 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300609 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
610 aeAvailableAntiBandingModes.data(),
611 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200612
613 std::vector<uint8_t> aeAvailableModes = {
614 ANDROID_CONTROL_AE_MODE_ON,
615 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300616 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
617 aeAvailableModes.data(),
618 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200619
620 std::vector<int32_t> availableAeFpsTarget = {
621 15, 30,
622 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300623 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
624 availableAeFpsTarget.data(),
625 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200626
627 std::vector<int32_t> aeCompensationRange = {
628 0, 0,
629 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300630 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
631 aeCompensationRange.data(),
632 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200633
634 const camera_metadata_rational_t aeCompensationStep[] = {
635 { 0, 1 }
636 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300637 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
638 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200639
640 std::vector<uint8_t> availableAfModes = {
641 ANDROID_CONTROL_AF_MODE_OFF,
642 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300643 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
644 availableAfModes.data(),
645 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200646
647 std::vector<uint8_t> availableEffects = {
648 ANDROID_CONTROL_EFFECT_MODE_OFF,
649 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300650 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
651 availableEffects.data(),
652 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200653
654 std::vector<uint8_t> availableSceneModes = {
655 ANDROID_CONTROL_SCENE_MODE_DISABLED,
656 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300657 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
658 availableSceneModes.data(),
659 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200660
661 std::vector<uint8_t> availableStabilizationModes = {
662 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
663 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300664 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
665 availableStabilizationModes.data(),
666 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200667
668 std::vector<uint8_t> availableAwbModes = {
669 ANDROID_CONTROL_AWB_MODE_OFF,
670 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300671 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
672 availableAwbModes.data(),
673 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200674
675 std::vector<int32_t> availableMaxRegions = {
676 0, 0, 0,
677 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300678 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
679 availableMaxRegions.data(),
680 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200681
682 std::vector<uint8_t> sceneModesOverride = {
683 ANDROID_CONTROL_AE_MODE_ON,
684 ANDROID_CONTROL_AWB_MODE_AUTO,
685 ANDROID_CONTROL_AF_MODE_AUTO,
686 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300687 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
688 sceneModesOverride.data(),
689 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200690
691 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300692 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
693 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200694
695 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300696 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
697 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200698
699 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300700 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
701 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200702
703 /* JPEG static metadata. */
704 std::vector<int32_t> availableThumbnailSizes = {
705 0, 0,
706 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300707 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
708 availableThumbnailSizes.data(),
709 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200710
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100711 /*
712 * \todo Calculate the maximum JPEG buffer size by asking the encoder
713 * giving the maximum frame size required.
714 */
715 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
716
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200717 /* Sensor static metadata. */
718 int32_t pixelArraySize[] = {
719 2592, 1944,
720 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300721 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
722 &pixelArraySize, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200723
724 int32_t sensorSizes[] = {
725 0, 0, 2560, 1920,
726 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300727 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
728 &sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200729
730 int32_t sensitivityRange[] = {
731 32, 2400,
732 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300733 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
734 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200735
736 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300737 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
738 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200739
740 int64_t exposureTimeRange[] = {
741 100000, 200000000,
742 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300743 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
744 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200745
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200746 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200747
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200748 std::vector<int32_t> testPatterModes = {
749 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
750 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300751 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
752 testPatterModes.data(),
753 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200754
755 std::vector<float> physicalSize = {
756 2592, 1944,
757 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300758 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
759 physicalSize.data(),
760 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200761
762 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300763 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
764 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200765
766 /* Statistics static metadata. */
767 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300768 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
769 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200770
771 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300772 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
773 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200774
775 /* Sync static metadata. */
776 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300777 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200778
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200779 /* Flash static metadata. */
780 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300781 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
782 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200783
784 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200785 std::vector<float> lensApertures = {
786 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200787 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300788 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
789 lensApertures.data(),
790 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200791
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200792 uint8_t lensFacing;
793 switch (facing_) {
794 default:
795 case CAMERA_FACING_FRONT:
796 lensFacing = ANDROID_LENS_FACING_FRONT;
797 break;
798 case CAMERA_FACING_BACK:
799 lensFacing = ANDROID_LENS_FACING_BACK;
800 break;
801 case CAMERA_FACING_EXTERNAL:
802 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
803 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100804 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300805 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200806
807 std::vector<float> lensFocalLenghts = {
808 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200809 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300810 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
811 lensFocalLenghts.data(),
812 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200813
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200814 std::vector<uint8_t> opticalStabilizations = {
815 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
816 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300817 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
818 opticalStabilizations.data(),
819 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200820
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200821 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300822 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
823 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200824
825 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300826 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
827 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200828
829 /* Noise reduction modes. */
830 uint8_t noiseReductionModes = ANDROID_NOISE_REDUCTION_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300831 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
832 &noiseReductionModes, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200833
834 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200835 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300836 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
837 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200838
Jacopo Mondibde7b982020-05-25 17:18:28 +0200839 std::vector<uint32_t> availableStreamConfigurations;
840 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
841 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200842 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200843 availableStreamConfigurations.push_back(entry.resolution.width);
844 availableStreamConfigurations.push_back(entry.resolution.height);
845 availableStreamConfigurations.push_back(
846 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
847 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300848 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
849 availableStreamConfigurations.data(),
850 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200851
852 std::vector<int64_t> availableStallDurations = {
853 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
854 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300855 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
856 availableStallDurations.data(),
857 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200858
Jacopo Mondibde7b982020-05-25 17:18:28 +0200859 /* \todo Collect the minimum frame duration from the camera. */
860 std::vector<int64_t> minFrameDurations;
861 minFrameDurations.reserve(streamConfigurations_.size() * 4);
862 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200863 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200864 minFrameDurations.push_back(entry.resolution.width);
865 minFrameDurations.push_back(entry.resolution.height);
866 minFrameDurations.push_back(33333333);
867 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300868 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
869 minFrameDurations.data(),
870 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200871
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200872 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300873 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200874
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200875 /* Info static metadata. */
876 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300877 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
878 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200879
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200880 /* Request static metadata. */
881 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300882 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
883 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200884
885 uint8_t maxPipelineDepth = 2;
Laurent Pinchart39860092019-09-05 03:12:34 +0300886 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
887 &maxPipelineDepth, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200888
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200889 /* LIMITED does not support reprocessing. */
890 uint32_t maxNumInputStreams = 0;
891 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
892 &maxNumInputStreams, 1);
893
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200894 std::vector<uint8_t> availableCapabilities = {
895 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
896 };
Niklas Söderlund7876d632020-07-21 00:16:24 +0200897
898 /* Report if camera supports RAW. */
899 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200900 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +0200901 if (cameraConfig && !cameraConfig->empty()) {
902 const PixelFormatInfo &info =
903 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
904 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
905 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
906 }
907
Laurent Pinchart39860092019-09-05 03:12:34 +0300908 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
909 availableCapabilities.data(),
910 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200911
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200912 std::vector<int32_t> availableCharacteristicsKeys = {
913 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
914 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
915 ANDROID_CONTROL_AE_AVAILABLE_MODES,
916 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
917 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
918 ANDROID_CONTROL_AE_COMPENSATION_STEP,
919 ANDROID_CONTROL_AF_AVAILABLE_MODES,
920 ANDROID_CONTROL_AVAILABLE_EFFECTS,
921 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
922 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
923 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
924 ANDROID_CONTROL_MAX_REGIONS,
925 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
926 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
927 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
928 ANDROID_CONTROL_AVAILABLE_MODES,
929 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100930 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200931 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
932 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
933 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
934 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
935 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
936 ANDROID_SENSOR_ORIENTATION,
937 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
938 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
939 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
940 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
941 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
942 ANDROID_SYNC_MAX_LATENCY,
943 ANDROID_FLASH_INFO_AVAILABLE,
944 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
945 ANDROID_LENS_FACING,
946 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
947 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
948 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
949 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
950 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
951 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200952 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
953 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
954 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
955 ANDROID_SCALER_CROPPING_TYPE,
956 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
957 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
958 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200959 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200960 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
961 };
962 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
963 availableCharacteristicsKeys.data(),
964 availableCharacteristicsKeys.size());
965
966 std::vector<int32_t> availableRequestKeys = {
967 ANDROID_CONTROL_AE_MODE,
968 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
969 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200970 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
971 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200972 ANDROID_CONTROL_AE_LOCK,
973 ANDROID_CONTROL_AF_TRIGGER,
974 ANDROID_CONTROL_AWB_MODE,
975 ANDROID_CONTROL_AWB_LOCK,
976 ANDROID_FLASH_MODE,
977 ANDROID_STATISTICS_FACE_DETECT_MODE,
978 ANDROID_NOISE_REDUCTION_MODE,
979 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200980 ANDROID_LENS_APERTURE,
981 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
982 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200983 ANDROID_CONTROL_CAPTURE_INTENT,
984 };
985 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
986 availableRequestKeys.data(),
987 availableRequestKeys.size());
988
989 std::vector<int32_t> availableResultKeys = {
990 ANDROID_CONTROL_AE_STATE,
991 ANDROID_CONTROL_AE_LOCK,
992 ANDROID_CONTROL_AF_STATE,
993 ANDROID_CONTROL_AWB_STATE,
994 ANDROID_CONTROL_AWB_LOCK,
995 ANDROID_LENS_STATE,
996 ANDROID_SCALER_CROP_REGION,
997 ANDROID_SENSOR_TIMESTAMP,
998 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
999 ANDROID_SENSOR_EXPOSURE_TIME,
1000 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1001 ANDROID_STATISTICS_SCENE_FLICKER,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001002 ANDROID_JPEG_SIZE,
1003 ANDROID_JPEG_QUALITY,
1004 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001005 };
1006 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1007 availableResultKeys.data(),
1008 availableResultKeys.size());
1009
Laurent Pinchart39860092019-09-05 03:12:34 +03001010 if (!staticMetadata_->isValid()) {
1011 LOG(HAL, Error) << "Failed to construct static metadata";
1012 delete staticMetadata_;
1013 staticMetadata_ = nullptr;
1014 return nullptr;
1015 }
1016
1017 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001018}
1019
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001020CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001021{
Jacopo Mondi63703472019-09-04 16:18:22 +02001022 /*
1023 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001024 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001025 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001026 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001027 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001028 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001029 return nullptr;
1030 }
1031
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001032 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001033 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1034 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001035
1036 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001037 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1038 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001039
1040 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001041 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1042 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001043
1044 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001045 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1046 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001047
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001048 std::vector<int32_t> aeFpsTarget = {
1049 15, 30,
1050 };
1051 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1052 aeFpsTarget.data(),
1053 aeFpsTarget.size());
1054
1055 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1056 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1057 &aeAntibandingMode, 1);
1058
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001059 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001060 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1061 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001062
1063 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001064 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1065 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001066
1067 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001068 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1069 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001070
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001071 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001072 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1073 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001074
1075 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001076 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1077 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001078
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001079 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001080 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1081 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001082
1083 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001084 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1085 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001086
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001087 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1088 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1089
1090 float lensAperture = 2.53 / 100;
1091 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1092
1093 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1094 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1095 &opticalStabilization, 1);
1096
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001097 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001098 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1099 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001100
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001101 return requestTemplate;
1102}
1103
1104/*
1105 * Produce a metadata pack to be used as template for a capture request.
1106 */
1107const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1108{
1109 auto it = requestTemplates_.find(type);
1110 if (it != requestTemplates_.end())
1111 return it->second->get();
1112
1113 /* Use the capture intent matching the requested template type. */
1114 CameraMetadata *requestTemplate;
1115 uint8_t captureIntent;
1116 switch (type) {
1117 case CAMERA3_TEMPLATE_PREVIEW:
1118 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1119 break;
1120 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1121 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1122 break;
1123 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1124 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1125 break;
1126 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1127 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1128 break;
1129 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1130 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1131 break;
1132 case CAMERA3_TEMPLATE_MANUAL:
1133 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1134 break;
1135 default:
1136 LOG(HAL, Error) << "Invalid template request type: " << type;
1137 return nullptr;
1138 }
1139
1140 requestTemplate = requestTemplatePreview();
1141 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001142 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001143 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001144 return nullptr;
1145 }
1146
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001147 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1148 &captureIntent, 1);
1149
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001150 requestTemplates_[type] = requestTemplate;
1151 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001152}
1153
Kieran Bingham43e3b802020-06-26 09:58:49 +01001154PixelFormat CameraDevice::toPixelFormat(int format)
1155{
1156 /* Translate Android format code to libcamera pixel format. */
1157 auto it = formatsMap_.find(format);
1158 if (it == formatsMap_.end()) {
1159 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1160 << " not supported";
1161 return PixelFormat();
1162 }
1163
1164 return it->second;
1165}
1166
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001167/*
1168 * Inspect the stream_list to produce a list of StreamConfiguration to
1169 * be use to configure the Camera.
1170 */
1171int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1172{
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001173 /*
1174 * Generate an empty configuration, and construct a StreamConfiguration
1175 * for each camera3_stream to add to it.
1176 */
1177 config_ = camera_->generateConfiguration();
1178 if (!config_) {
1179 LOG(HAL, Error) << "Failed to generate camera configuration";
1180 return -EINVAL;
1181 }
1182
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001183 /*
1184 * Clear and remove any existing configuration from previous calls, and
1185 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001186 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001187 */
1188 streams_.clear();
1189 streams_.reserve(stream_list->num_streams);
1190
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001191 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001192 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001193 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1194 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001195 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001196
Kieran Bingham43e3b802020-06-26 09:58:49 +01001197 PixelFormat format = toPixelFormat(stream->format);
1198
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001199 LOG(HAL, Info) << "Stream #" << i
1200 << ", direction: " << stream->stream_type
1201 << ", width: " << stream->width
1202 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001203 << ", format: " << utils::hex(stream->format)
1204 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001205
1206 if (!format.isValid())
1207 return -EINVAL;
1208
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001209 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001210 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1211 if (jpegStream) {
1212 LOG(HAL, Error)
1213 << "Multiple JPEG streams are not supported";
1214 return -EINVAL;
1215 }
1216
1217 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001218 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001219 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001220
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001221 StreamConfiguration streamConfiguration;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001222 streamConfiguration.size = size;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001223 streamConfiguration.pixelFormat = format;
1224
1225 config_->addConfiguration(streamConfiguration);
Jacopo Mondie3393f12020-10-03 12:00:54 +02001226 streams_.emplace_back(this, CameraStream::Type::Direct,
1227 stream, config_->size() - 1);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001228 stream->priv = static_cast<void *>(&streams_.back());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001229 }
1230
Jacopo Mondic82f9442020-09-02 11:58:00 +02001231 /* Now handle the MJPEG streams, adding a new stream if required. */
1232 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001233 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001234 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001235
Jacopo Mondic82f9442020-09-02 11:58:00 +02001236 /* Search for a compatible stream in the non-JPEG ones. */
1237 for (unsigned int i = 0; i < config_->size(); i++) {
1238 StreamConfiguration &cfg = config_->at(i);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001239
1240 /*
1241 * \todo The PixelFormat must also be compatible with
1242 * the encoder.
1243 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001244 if (cfg.size.width != jpegStream->width ||
1245 cfg.size.height != jpegStream->height)
1246 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001247
Jacopo Mondic82f9442020-09-02 11:58:00 +02001248 LOG(HAL, Info)
1249 << "Android JPEG stream mapped to libcamera stream " << i;
1250
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001251 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001252 index = i;
1253 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001254 }
1255
1256 /*
1257 * Without a compatible match for JPEG encoding we must
1258 * introduce a new stream to satisfy the request requirements.
1259 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001260 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001261 StreamConfiguration streamConfiguration;
1262
1263 /*
1264 * \todo The pixelFormat should be a 'best-fit' choice
1265 * and may require a validation cycle. This is not yet
1266 * handled, and should be considered as part of any
1267 * stream configuration reworks.
1268 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001269 streamConfiguration.size.width = jpegStream->width;
1270 streamConfiguration.size.height = jpegStream->height;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001271 streamConfiguration.pixelFormat = formats::NV12;
1272
1273 LOG(HAL, Info) << "Adding " << streamConfiguration.toString()
1274 << " for MJPEG support";
1275
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001276 type = CameraStream::Type::Internal;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001277 config_->addConfiguration(streamConfiguration);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001278 index = config_->size() - 1;
1279 }
1280
Jacopo Mondie3393f12020-10-03 12:00:54 +02001281 streams_.emplace_back(this, type, jpegStream, index);
Jacopo Mondifacadb12020-09-02 12:11:46 +02001282 jpegStream->priv = static_cast<void *>(&streams_.back());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001283 }
1284
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001285 switch (config_->validate()) {
1286 case CameraConfiguration::Valid:
1287 break;
1288 case CameraConfiguration::Adjusted:
1289 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001290
1291 for (const StreamConfiguration &cfg : *config_)
1292 LOG(HAL, Info) << " - " << cfg.toString();
1293
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001294 config_.reset();
1295 return -EINVAL;
1296 case CameraConfiguration::Invalid:
1297 LOG(HAL, Info) << "Camera configuration invalid";
1298 config_.reset();
1299 return -EINVAL;
1300 }
1301
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001302 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001303 * Once the CameraConfiguration has been adjusted/validated
1304 * it can be applied to the camera.
1305 */
1306 int ret = camera_->configure(config_.get());
1307 if (ret) {
1308 LOG(HAL, Error) << "Failed to configure camera '"
1309 << camera_->id() << "'";
1310 return ret;
1311 }
1312
1313 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001314 * Configure the HAL CameraStream instances using the associated
1315 * StreamConfiguration and set the number of required buffers in
1316 * the Android camera3_stream_t.
1317 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001318 for (CameraStream &cameraStream : streams_) {
1319 int ret = cameraStream.configure();
1320 if (ret) {
1321 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001322 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001323 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001324 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001325
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001326 return 0;
1327}
1328
Kieran Bingham74ab4422020-07-01 13:25:38 +01001329FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1330{
1331 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001332 for (int i = 0; i < camera3buffer->numFds; i++) {
1333 /* Skip unused planes. */
1334 if (camera3buffer->data[i] == -1)
1335 break;
1336
Kieran Bingham74ab4422020-07-01 13:25:38 +01001337 FrameBuffer::Plane plane;
1338 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001339 if (!plane.fd.isValid()) {
1340 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1341 << camera3buffer->data[i] << ") "
1342 << " on plane " << i;
1343 return nullptr;
1344 }
1345
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001346 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1347 if (length == -1) {
1348 LOG(HAL, Error) << "Failed to query plane length";
1349 return nullptr;
1350 }
1351
1352 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001353 planes.push_back(std::move(plane));
1354 }
1355
1356 return new FrameBuffer(std::move(planes));
1357}
1358
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001359int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001360{
Kieran Bingham61f42962020-07-01 13:40:17 +01001361 if (!camera3Request->num_output_buffers) {
1362 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001363 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001364 }
1365
1366 /* Start the camera if that's the first request we handle. */
1367 if (!running_) {
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001368 worker_.start();
1369
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001370 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001371 if (ret) {
1372 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001373 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001374 }
1375
1376 running_ = true;
1377 }
1378
1379 /*
1380 * Queue a request for the Camera with the provided dmabuf file
1381 * descriptors.
1382 */
1383 const camera3_stream_buffer_t *camera3Buffers =
1384 camera3Request->output_buffers;
1385
1386 /*
1387 * Save the request descriptors for use at completion time.
1388 * The descriptor and the associated memory reserved here are freed
1389 * at request complete time.
1390 */
1391 Camera3RequestDescriptor *descriptor =
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001392 new Camera3RequestDescriptor(camera_.get(), camera3Request->frame_number,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001393 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001394
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001395 LOG(HAL, Debug) << "Queueing Request to libcamera with "
1396 << descriptor->numBuffers << " HAL streams";
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001397 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001398 camera3_stream *camera3Stream = camera3Buffers[i].stream;
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001399 CameraStream *cameraStream =
1400 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1401
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001402 /*
1403 * Keep track of which stream the request belongs to and store
1404 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001405 */
1406 descriptor->buffers[i].stream = camera3Buffers[i].stream;
1407 descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001408
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001409 std::stringstream ss;
1410 ss << i << " - (" << camera3Stream->width << "x"
1411 << camera3Stream->height << ")"
1412 << "[" << utils::hex(camera3Stream->format) << "] -> "
1413 << "(" << cameraStream->configuration().size.toString() << ")["
1414 << cameraStream->configuration().pixelFormat.toString() << "]";
1415
Jacopo Mondide8304b2020-09-04 17:45:39 +02001416 /*
1417 * Inspect the camera stream type, create buffers opportunely
1418 * and add them to the Request if required.
1419 */
1420 FrameBuffer *buffer = nullptr;
1421 switch (cameraStream->type()) {
1422 case CameraStream::Type::Mapped:
1423 /*
1424 * Mapped streams don't need buffers added to the
1425 * Request.
1426 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001427 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001428 continue;
1429
Jacopo Mondide8304b2020-09-04 17:45:39 +02001430 case CameraStream::Type::Direct:
1431 /*
1432 * Create a libcamera buffer using the dmabuf
1433 * descriptors of the camera3Buffer for each stream and
1434 * associate it with the Camera3RequestDescriptor for
1435 * lifetime management only.
1436 */
1437 buffer = createFrameBuffer(*camera3Buffers[i].buffer);
1438 descriptor->frameBuffers.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001439 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001440 break;
1441
1442 case CameraStream::Type::Internal:
1443 /*
1444 * Get the frame buffer from the CameraStream internal
1445 * buffer pool.
1446 *
1447 * The buffer has to be returned to the CameraStream
1448 * once it has been processed.
1449 */
1450 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001451 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001452 break;
1453 }
1454
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001455 if (!buffer) {
1456 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001457 delete descriptor;
1458 return -ENOMEM;
1459 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001460
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001461 descriptor->request->addBuffer(cameraStream->stream(), buffer,
1462 camera3Buffers[i].acquire_fence);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001463 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001464
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001465 /* Queue the request to the CameraWorker. */
1466 worker_.queueRequest(descriptor->request.get());
Paul Elderc7532232020-09-23 19:05:41 +09001467
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001468 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001469}
1470
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001471void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001472{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001473 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001474 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001475 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001476 Camera3RequestDescriptor *descriptor =
1477 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001478
1479 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001480 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001481 << request->status();
1482 status = CAMERA3_BUFFER_STATUS_ERROR;
1483 }
1484
Kieran Binghamc09aee42020-07-28 14:01:19 +01001485 /*
1486 * \todo The timestamp used for the metadata is currently always taken
1487 * from the first buffer (which may be the first stream) in the Request.
1488 * It might be appropriate to return a 'correct' (as determined by
1489 * pipeline handlers) timestamp in the Request itself.
1490 */
1491 FrameBuffer *buffer = buffers.begin()->second;
1492 resultMetadata = getResultMetadata(descriptor->frameNumber,
1493 buffer->metadata().timestamp);
1494
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001495 /* Handle any JPEG compression. */
1496 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
1497 CameraStream *cameraStream =
1498 static_cast<CameraStream *>(descriptor->buffers[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001499
Jacopo Mondi160bb092020-10-02 20:48:35 +02001500 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001501 continue;
1502
Jacopo Mondi216030a2020-10-03 11:36:41 +02001503 FrameBuffer *buffer = request->findBuffer(cameraStream->stream());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001504 if (!buffer) {
1505 LOG(HAL, Error) << "Failed to find a source stream buffer";
1506 continue;
1507 }
1508
1509 /*
1510 * \todo Buffer mapping and compression should be moved to a
1511 * separate thread.
1512 */
1513
1514 MappedCamera3Buffer mapped(*descriptor->buffers[i].buffer,
1515 PROT_READ | PROT_WRITE);
1516 if (!mapped.isValid()) {
1517 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1518 continue;
1519 }
1520
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02001521 int ret = cameraStream->process(*buffer, &mapped,
1522 resultMetadata.get());
1523 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001524 status = CAMERA3_BUFFER_STATUS_ERROR;
1525 continue;
1526 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02001527
1528 /*
1529 * Return the FrameBuffer to the CameraStream now that we're
1530 * done processing it.
1531 */
1532 if (cameraStream->type() == CameraStream::Type::Internal)
1533 cameraStream->putBuffer(buffer);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001534 }
1535
1536 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001537 camera3_capture_result_t captureResult = {};
1538 captureResult.frame_number = descriptor->frameNumber;
1539 captureResult.num_output_buffers = descriptor->numBuffers;
1540 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001541 descriptor->buffers[i].acquire_fence = -1;
1542 descriptor->buffers[i].release_fence = -1;
1543 descriptor->buffers[i].status = status;
1544 }
1545 captureResult.output_buffers =
1546 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers);
1547
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001548
Laurent Pinchart39860092019-09-05 03:12:34 +03001549 if (status == CAMERA3_BUFFER_STATUS_OK) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001550 notifyShutter(descriptor->frameNumber,
Niklas Söderlund9217f272019-11-22 16:22:56 +01001551 buffer->metadata().timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001552
1553 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001554 captureResult.result = resultMetadata->get();
1555 }
1556
1557 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1558 /* \todo Improve error handling. In case we notify an error
1559 * because the metadata generation fails, a shutter event has
1560 * already been notified for this frame number before the error
1561 * is here signalled. Make sure the error path plays well with
1562 * the camera stack state machine.
1563 */
1564 notifyError(descriptor->frameNumber,
1565 descriptor->buffers[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001566 }
1567
1568 callbacks_->process_capture_result(callbacks_, &captureResult);
1569
1570 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001571}
1572
Jacopo Mondia7b92772020-05-26 15:41:41 +02001573std::string CameraDevice::logPrefix() const
1574{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001575 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001576}
1577
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001578void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1579{
1580 camera3_notify_msg_t notify = {};
1581
1582 notify.type = CAMERA3_MSG_SHUTTER;
1583 notify.message.shutter.frame_number = frameNumber;
1584 notify.message.shutter.timestamp = timestamp;
1585
1586 callbacks_->notify(callbacks_, &notify);
1587}
1588
1589void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1590{
1591 camera3_notify_msg_t notify = {};
1592
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001593 /*
1594 * \todo Report and identify the stream number or configuration to
1595 * clarify the stream that failed.
1596 */
1597 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1598 << toPixelFormat(stream->format).toString() << ")";
1599
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001600 notify.type = CAMERA3_MSG_ERROR;
1601 notify.message.error.error_stream = stream;
1602 notify.message.error.frame_number = frameNumber;
1603 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1604
1605 callbacks_->notify(callbacks_, &notify);
1606}
1607
1608/*
1609 * Produce a set of fixed result metadata.
1610 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001611std::unique_ptr<CameraMetadata>
1612CameraDevice::getResultMetadata([[maybe_unused]] int frame_number,
1613 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001614{
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001615 /*
1616 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001617 * Currently: 18 entries, 62 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001618 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001619 std::unique_ptr<CameraMetadata> resultMetadata =
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001620 std::make_unique<CameraMetadata>(18, 62);
Laurent Pinchart39860092019-09-05 03:12:34 +03001621 if (!resultMetadata->isValid()) {
1622 LOG(HAL, Error) << "Failed to allocate static metadata";
1623 return nullptr;
1624 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001625
1626 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001627 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001628
1629 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001630 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001631
1632 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001633 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001634
1635 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001636 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001637
1638 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001639 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001640
1641 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001642 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001643
1644 int32_t sensorSizes[] = {
1645 0, 0, 2560, 1920,
1646 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001647 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001648
Laurent Pinchart39860092019-09-05 03:12:34 +03001649 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001650
1651 /* 33.3 msec */
1652 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001653 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1654 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001655
1656 /* 16.6 msec */
1657 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001658 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1659 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001660
1661 const uint8_t lens_shading_map_mode =
1662 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001663 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1664 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001665
1666 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001667 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1668 &scene_flicker, 1);
1669
1670 /*
1671 * Return the result metadata pack even is not valid: get() will return
1672 * nullptr.
1673 */
1674 if (!resultMetadata->isValid()) {
1675 LOG(HAL, Error) << "Failed to construct result metadata";
1676 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001677
1678 return resultMetadata;
1679}