blob: b245c9a1b88505ed5fb32a04abf513726f891672 [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
Kieran Bingham83ae84e2020-07-03 12:34:59 +010011#include <sys/mman.h>
Jacopo Mondia80d3812020-05-26 12:31:35 +020012#include <tuple>
Jacopo Mondi117588b2020-05-23 18:53:54 +020013#include <vector>
14
Jacopo Mondi857a2162019-11-20 17:00:49 +010015#include <libcamera/controls.h>
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030016#include <libcamera/formats.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010017#include <libcamera/property_ids.h>
18
Niklas Söderlund7876d632020-07-21 00:16:24 +020019#include "libcamera/internal/formats.h"
Laurent Pinchart93e72b62020-05-12 00:58:34 +030020#include "libcamera/internal/log.h"
21#include "libcamera/internal/utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020022
Laurent Pinchart39860092019-09-05 03:12:34 +030023#include "camera_metadata.h"
Jacopo Mondi117588b2020-05-23 18:53:54 +020024#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020025
Kieran Bingham83ae84e2020-07-03 12:34:59 +010026#include "jpeg/encoder_libjpeg.h"
Umang Jain6f09a612020-09-09 16:44:45 +053027#include "jpeg/exif.h"
Kieran Bingham83ae84e2020-07-03 12:34:59 +010028
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020029using namespace libcamera;
30
Jacopo Mondi117588b2020-05-23 18:53:54 +020031namespace {
32
33/*
34 * \var camera3Resolutions
35 * \brief The list of image resolutions defined as mandatory to be supported by
36 * the Android Camera3 specification
37 */
38const std::vector<Size> camera3Resolutions = {
39 { 320, 240 },
40 { 640, 480 },
41 { 1280, 720 },
42 { 1920, 1080 }
43};
44
45/*
46 * \struct Camera3Format
47 * \brief Data associated with an Android format identifier
48 * \var libcameraFormats List of libcamera pixel formats compatible with the
49 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020050 * \var name The human-readable representation of the Android format code
51 */
52struct Camera3Format {
53 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020054 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020055 const char *name;
56};
57
58/*
59 * \var camera3FormatsMap
60 * \brief Associate Android format code with ancillary data
61 */
62const std::map<int, const Camera3Format> camera3FormatsMap = {
63 {
64 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030065 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020066 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020067 "BLOB"
68 }
69 }, {
70 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030071 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020072 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020073 "YCbCr_420_888"
74 }
75 }, {
76 /*
77 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
78 * usage flag. For now, copy the YCbCr_420 configuration.
79 */
80 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030081 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020082 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020083 "IMPLEMENTATION_DEFINED"
84 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020085 }, {
86 HAL_PIXEL_FORMAT_RAW10, {
87 {
88 formats::SBGGR10_CSI2P,
89 formats::SGBRG10_CSI2P,
90 formats::SGRBG10_CSI2P,
91 formats::SRGGB10_CSI2P
92 },
93 false,
94 "RAW10"
95 }
96 }, {
97 HAL_PIXEL_FORMAT_RAW12, {
98 {
99 formats::SBGGR12_CSI2P,
100 formats::SGBRG12_CSI2P,
101 formats::SGRBG12_CSI2P,
102 formats::SRGGB12_CSI2P
103 },
104 false,
105 "RAW12"
106 }
107 }, {
108 HAL_PIXEL_FORMAT_RAW16, {
109 {
110 formats::SBGGR16,
111 formats::SGBRG16,
112 formats::SGRBG16,
113 formats::SRGGB16
114 },
115 false,
116 "RAW16"
117 }
118 }, {
119 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
120 {
121 formats::SBGGR10_IPU3,
122 formats::SGBRG10_IPU3,
123 formats::SGRBG10_IPU3,
124 formats::SRGGB10_IPU3
125 },
126 false,
127 "RAW_OPAQUE"
128 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200129 },
130};
131
132} /* namespace */
133
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200134LOG_DECLARE_CATEGORY(HAL);
135
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100136class MappedCamera3Buffer : public MappedBuffer
137{
138public:
139 MappedCamera3Buffer(const buffer_handle_t camera3buffer, int flags);
140};
141
142MappedCamera3Buffer::MappedCamera3Buffer(const buffer_handle_t camera3buffer,
143 int flags)
144{
145 maps_.reserve(camera3buffer->numFds);
146 error_ = 0;
147
148 for (int i = 0; i < camera3buffer->numFds; i++) {
149 if (camera3buffer->data[i] == -1)
150 continue;
151
152 off_t length = lseek(camera3buffer->data[i], 0, SEEK_END);
153 if (length < 0) {
154 error_ = -errno;
155 LOG(HAL, Error) << "Failed to query plane length";
156 break;
157 }
158
159 void *address = mmap(nullptr, length, flags, MAP_SHARED,
160 camera3buffer->data[i], 0);
161 if (address == MAP_FAILED) {
162 error_ = -errno;
163 LOG(HAL, Error) << "Failed to mmap plane";
164 break;
165 }
166
167 maps_.emplace_back(static_cast<uint8_t *>(address),
168 static_cast<size_t>(length));
169 }
170}
171
Jacopo Mondifacadb12020-09-02 12:11:46 +0200172CameraStream::CameraStream(PixelFormat f, Size s, unsigned int i, Encoder *e)
173 : format(f), size(s), index_(i), encoder_(e)
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100174{
175}
176
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200177/*
178 * \struct Camera3RequestDescriptor
179 *
180 * A utility structure that groups information about a capture request to be
181 * later re-used at request complete time to notify the framework.
182 */
183
184CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
185 unsigned int frameNumber, unsigned int numBuffers)
186 : frameNumber(frameNumber), numBuffers(numBuffers)
187{
188 buffers = new camera3_stream_buffer_t[numBuffers];
Kieran Bingham0cfdf732020-07-01 13:36:24 +0100189 frameBuffers.reserve(numBuffers);
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 =
315 camera_->generateConfiguration({ StillCaptureRaw });
316 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{
534 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200535 camera_->release();
536
537 running_ = false;
538}
539
540void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
541{
542 callbacks_ = callbacks;
543}
544
Jacopo Mondia80d3812020-05-26 12:31:35 +0200545std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
546{
547 /*
548 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100549 * Currently: 51 entries, 687 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200550 */
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100551 uint32_t numEntries = 51;
552 uint32_t byteSize = 687;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200553
554 /*
555 * Calculate space occupation in bytes for dynamically built metadata
556 * entries.
557 *
558 * Each stream configuration entry requires 52 bytes:
559 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200560 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
561 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200562 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200563
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300564 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200565}
566
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200567/*
568 * Return static information for the camera.
569 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200570const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200571{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200572 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300573 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200574
575 /*
576 * The here reported metadata are enough to implement a basic capture
577 * example application, but a real camera implementation will require
578 * more.
579 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200580 uint32_t numEntries;
581 uint32_t byteSize;
582 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
583 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300584 if (!staticMetadata_->isValid()) {
585 LOG(HAL, Error) << "Failed to allocate static metadata";
586 delete staticMetadata_;
587 staticMetadata_ = nullptr;
588 return nullptr;
589 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200590
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200591 /* Color correction static metadata. */
592 std::vector<uint8_t> aberrationModes = {
593 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
594 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300595 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
596 aberrationModes.data(),
597 aberrationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200598
599 /* Control static metadata. */
600 std::vector<uint8_t> aeAvailableAntiBandingModes = {
601 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
602 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
603 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
604 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
605 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300606 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
607 aeAvailableAntiBandingModes.data(),
608 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200609
610 std::vector<uint8_t> aeAvailableModes = {
611 ANDROID_CONTROL_AE_MODE_ON,
612 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300613 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
614 aeAvailableModes.data(),
615 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200616
617 std::vector<int32_t> availableAeFpsTarget = {
618 15, 30,
619 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300620 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
621 availableAeFpsTarget.data(),
622 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200623
624 std::vector<int32_t> aeCompensationRange = {
625 0, 0,
626 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300627 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
628 aeCompensationRange.data(),
629 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200630
631 const camera_metadata_rational_t aeCompensationStep[] = {
632 { 0, 1 }
633 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300634 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
635 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200636
637 std::vector<uint8_t> availableAfModes = {
638 ANDROID_CONTROL_AF_MODE_OFF,
639 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300640 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
641 availableAfModes.data(),
642 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200643
644 std::vector<uint8_t> availableEffects = {
645 ANDROID_CONTROL_EFFECT_MODE_OFF,
646 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300647 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
648 availableEffects.data(),
649 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200650
651 std::vector<uint8_t> availableSceneModes = {
652 ANDROID_CONTROL_SCENE_MODE_DISABLED,
653 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300654 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
655 availableSceneModes.data(),
656 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200657
658 std::vector<uint8_t> availableStabilizationModes = {
659 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
660 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300661 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
662 availableStabilizationModes.data(),
663 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200664
665 std::vector<uint8_t> availableAwbModes = {
666 ANDROID_CONTROL_AWB_MODE_OFF,
667 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300668 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
669 availableAwbModes.data(),
670 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200671
672 std::vector<int32_t> availableMaxRegions = {
673 0, 0, 0,
674 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300675 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
676 availableMaxRegions.data(),
677 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200678
679 std::vector<uint8_t> sceneModesOverride = {
680 ANDROID_CONTROL_AE_MODE_ON,
681 ANDROID_CONTROL_AWB_MODE_AUTO,
682 ANDROID_CONTROL_AF_MODE_AUTO,
683 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300684 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
685 sceneModesOverride.data(),
686 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200687
688 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300689 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
690 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200691
692 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300693 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
694 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200695
696 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300697 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
698 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200699
700 /* JPEG static metadata. */
701 std::vector<int32_t> availableThumbnailSizes = {
702 0, 0,
703 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300704 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
705 availableThumbnailSizes.data(),
706 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200707
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100708 /*
709 * \todo Calculate the maximum JPEG buffer size by asking the encoder
710 * giving the maximum frame size required.
711 */
712 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
713
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200714 /* Sensor static metadata. */
715 int32_t pixelArraySize[] = {
716 2592, 1944,
717 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300718 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
719 &pixelArraySize, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200720
721 int32_t sensorSizes[] = {
722 0, 0, 2560, 1920,
723 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300724 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
725 &sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200726
727 int32_t sensitivityRange[] = {
728 32, 2400,
729 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300730 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
731 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200732
733 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300734 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
735 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200736
737 int64_t exposureTimeRange[] = {
738 100000, 200000000,
739 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300740 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
741 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200742
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200743 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200744
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200745 std::vector<int32_t> testPatterModes = {
746 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
747 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300748 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
749 testPatterModes.data(),
750 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200751
752 std::vector<float> physicalSize = {
753 2592, 1944,
754 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300755 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
756 physicalSize.data(),
757 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200758
759 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300760 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
761 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200762
763 /* Statistics static metadata. */
764 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300765 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
766 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200767
768 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300769 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
770 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200771
772 /* Sync static metadata. */
773 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300774 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200775
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200776 /* Flash static metadata. */
777 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300778 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
779 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200780
781 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200782 std::vector<float> lensApertures = {
783 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200784 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300785 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
786 lensApertures.data(),
787 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200788
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200789 uint8_t lensFacing;
790 switch (facing_) {
791 default:
792 case CAMERA_FACING_FRONT:
793 lensFacing = ANDROID_LENS_FACING_FRONT;
794 break;
795 case CAMERA_FACING_BACK:
796 lensFacing = ANDROID_LENS_FACING_BACK;
797 break;
798 case CAMERA_FACING_EXTERNAL:
799 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
800 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100801 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300802 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200803
804 std::vector<float> lensFocalLenghts = {
805 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200806 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300807 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
808 lensFocalLenghts.data(),
809 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200810
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200811 std::vector<uint8_t> opticalStabilizations = {
812 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
813 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300814 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
815 opticalStabilizations.data(),
816 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200817
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200818 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300819 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
820 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200821
822 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300823 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
824 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200825
826 /* Noise reduction modes. */
827 uint8_t noiseReductionModes = ANDROID_NOISE_REDUCTION_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300828 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
829 &noiseReductionModes, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200830
831 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200832 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300833 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
834 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200835
Jacopo Mondibde7b982020-05-25 17:18:28 +0200836 std::vector<uint32_t> availableStreamConfigurations;
837 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
838 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200839 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200840 availableStreamConfigurations.push_back(entry.resolution.width);
841 availableStreamConfigurations.push_back(entry.resolution.height);
842 availableStreamConfigurations.push_back(
843 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
844 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300845 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
846 availableStreamConfigurations.data(),
847 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200848
849 std::vector<int64_t> availableStallDurations = {
850 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
851 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300852 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
853 availableStallDurations.data(),
854 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200855
Jacopo Mondibde7b982020-05-25 17:18:28 +0200856 /* \todo Collect the minimum frame duration from the camera. */
857 std::vector<int64_t> minFrameDurations;
858 minFrameDurations.reserve(streamConfigurations_.size() * 4);
859 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200860 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200861 minFrameDurations.push_back(entry.resolution.width);
862 minFrameDurations.push_back(entry.resolution.height);
863 minFrameDurations.push_back(33333333);
864 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300865 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
866 minFrameDurations.data(),
867 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200868
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200869 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300870 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200871
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200872 /* Info static metadata. */
873 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300874 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
875 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200876
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200877 /* Request static metadata. */
878 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300879 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
880 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200881
882 uint8_t maxPipelineDepth = 2;
Laurent Pinchart39860092019-09-05 03:12:34 +0300883 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
884 &maxPipelineDepth, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200885
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200886 /* LIMITED does not support reprocessing. */
887 uint32_t maxNumInputStreams = 0;
888 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
889 &maxNumInputStreams, 1);
890
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200891 std::vector<uint8_t> availableCapabilities = {
892 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
893 };
Niklas Söderlund7876d632020-07-21 00:16:24 +0200894
895 /* Report if camera supports RAW. */
896 std::unique_ptr<CameraConfiguration> cameraConfig =
897 camera_->generateConfiguration({ StillCaptureRaw });
898 if (cameraConfig && !cameraConfig->empty()) {
899 const PixelFormatInfo &info =
900 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
901 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
902 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
903 }
904
Laurent Pinchart39860092019-09-05 03:12:34 +0300905 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
906 availableCapabilities.data(),
907 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200908
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200909 std::vector<int32_t> availableCharacteristicsKeys = {
910 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
911 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
912 ANDROID_CONTROL_AE_AVAILABLE_MODES,
913 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
914 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
915 ANDROID_CONTROL_AE_COMPENSATION_STEP,
916 ANDROID_CONTROL_AF_AVAILABLE_MODES,
917 ANDROID_CONTROL_AVAILABLE_EFFECTS,
918 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
919 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
920 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
921 ANDROID_CONTROL_MAX_REGIONS,
922 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
923 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
924 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
925 ANDROID_CONTROL_AVAILABLE_MODES,
926 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100927 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200928 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
929 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
930 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
931 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
932 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
933 ANDROID_SENSOR_ORIENTATION,
934 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
935 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
936 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
937 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
938 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
939 ANDROID_SYNC_MAX_LATENCY,
940 ANDROID_FLASH_INFO_AVAILABLE,
941 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
942 ANDROID_LENS_FACING,
943 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
944 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
945 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
946 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
947 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
948 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200949 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
950 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
951 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
952 ANDROID_SCALER_CROPPING_TYPE,
953 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
954 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
955 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200956 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200957 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
958 };
959 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
960 availableCharacteristicsKeys.data(),
961 availableCharacteristicsKeys.size());
962
963 std::vector<int32_t> availableRequestKeys = {
964 ANDROID_CONTROL_AE_MODE,
965 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
966 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200967 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
968 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200969 ANDROID_CONTROL_AE_LOCK,
970 ANDROID_CONTROL_AF_TRIGGER,
971 ANDROID_CONTROL_AWB_MODE,
972 ANDROID_CONTROL_AWB_LOCK,
973 ANDROID_FLASH_MODE,
974 ANDROID_STATISTICS_FACE_DETECT_MODE,
975 ANDROID_NOISE_REDUCTION_MODE,
976 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200977 ANDROID_LENS_APERTURE,
978 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
979 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200980 ANDROID_CONTROL_CAPTURE_INTENT,
981 };
982 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
983 availableRequestKeys.data(),
984 availableRequestKeys.size());
985
986 std::vector<int32_t> availableResultKeys = {
987 ANDROID_CONTROL_AE_STATE,
988 ANDROID_CONTROL_AE_LOCK,
989 ANDROID_CONTROL_AF_STATE,
990 ANDROID_CONTROL_AWB_STATE,
991 ANDROID_CONTROL_AWB_LOCK,
992 ANDROID_LENS_STATE,
993 ANDROID_SCALER_CROP_REGION,
994 ANDROID_SENSOR_TIMESTAMP,
995 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
996 ANDROID_SENSOR_EXPOSURE_TIME,
997 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
998 ANDROID_STATISTICS_SCENE_FLICKER,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100999 ANDROID_JPEG_SIZE,
1000 ANDROID_JPEG_QUALITY,
1001 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001002 };
1003 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1004 availableResultKeys.data(),
1005 availableResultKeys.size());
1006
Laurent Pinchart39860092019-09-05 03:12:34 +03001007 if (!staticMetadata_->isValid()) {
1008 LOG(HAL, Error) << "Failed to construct static metadata";
1009 delete staticMetadata_;
1010 staticMetadata_ = nullptr;
1011 return nullptr;
1012 }
1013
1014 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001015}
1016
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001017CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001018{
Jacopo Mondi63703472019-09-04 16:18:22 +02001019 /*
1020 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001021 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001022 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001023 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001024 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001025 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001026 return nullptr;
1027 }
1028
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001029 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001030 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1031 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001032
1033 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001034 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1035 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001036
1037 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001038 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1039 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001040
1041 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001042 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1043 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001044
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001045 std::vector<int32_t> aeFpsTarget = {
1046 15, 30,
1047 };
1048 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1049 aeFpsTarget.data(),
1050 aeFpsTarget.size());
1051
1052 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1053 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1054 &aeAntibandingMode, 1);
1055
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001056 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001057 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1058 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001059
1060 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001061 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1062 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001063
1064 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001065 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1066 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001067
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001068 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001069 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1070 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001071
1072 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001073 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1074 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001075
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001076 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001077 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1078 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001079
1080 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001081 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1082 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001083
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001084 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1085 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1086
1087 float lensAperture = 2.53 / 100;
1088 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1089
1090 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1091 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1092 &opticalStabilization, 1);
1093
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001094 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001095 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1096 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001097
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001098 return requestTemplate;
1099}
1100
1101/*
1102 * Produce a metadata pack to be used as template for a capture request.
1103 */
1104const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1105{
1106 auto it = requestTemplates_.find(type);
1107 if (it != requestTemplates_.end())
1108 return it->second->get();
1109
1110 /* Use the capture intent matching the requested template type. */
1111 CameraMetadata *requestTemplate;
1112 uint8_t captureIntent;
1113 switch (type) {
1114 case CAMERA3_TEMPLATE_PREVIEW:
1115 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1116 break;
1117 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1118 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1119 break;
1120 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1121 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1122 break;
1123 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1124 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1125 break;
1126 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1127 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1128 break;
1129 case CAMERA3_TEMPLATE_MANUAL:
1130 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1131 break;
1132 default:
1133 LOG(HAL, Error) << "Invalid template request type: " << type;
1134 return nullptr;
1135 }
1136
1137 requestTemplate = requestTemplatePreview();
1138 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001139 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001140 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001141 return nullptr;
1142 }
1143
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001144 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1145 &captureIntent, 1);
1146
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001147 requestTemplates_[type] = requestTemplate;
1148 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001149}
1150
Kieran Bingham43e3b802020-06-26 09:58:49 +01001151PixelFormat CameraDevice::toPixelFormat(int format)
1152{
1153 /* Translate Android format code to libcamera pixel format. */
1154 auto it = formatsMap_.find(format);
1155 if (it == formatsMap_.end()) {
1156 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1157 << " not supported";
1158 return PixelFormat();
1159 }
1160
1161 return it->second;
1162}
1163
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001164/*
1165 * Inspect the stream_list to produce a list of StreamConfiguration to
1166 * be use to configure the Camera.
1167 */
1168int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1169{
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001170 /*
1171 * Generate an empty configuration, and construct a StreamConfiguration
1172 * for each camera3_stream to add to it.
1173 */
1174 config_ = camera_->generateConfiguration();
1175 if (!config_) {
1176 LOG(HAL, Error) << "Failed to generate camera configuration";
1177 return -EINVAL;
1178 }
1179
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001180 /*
1181 * Clear and remove any existing configuration from previous calls, and
1182 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001183 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001184 */
1185 streams_.clear();
1186 streams_.reserve(stream_list->num_streams);
1187
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001188 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001189 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001190 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1191 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001192 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001193
Kieran Bingham43e3b802020-06-26 09:58:49 +01001194 PixelFormat format = toPixelFormat(stream->format);
1195
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001196 LOG(HAL, Info) << "Stream #" << i
1197 << ", direction: " << stream->stream_type
1198 << ", width: " << stream->width
1199 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001200 << ", format: " << utils::hex(stream->format)
1201 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001202
1203 if (!format.isValid())
1204 return -EINVAL;
1205
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001206 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001207 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1208 if (jpegStream) {
1209 LOG(HAL, Error)
1210 << "Multiple JPEG streams are not supported";
1211 return -EINVAL;
1212 }
1213
1214 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001215 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001216 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001217
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001218 StreamConfiguration streamConfiguration;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001219 streamConfiguration.size = size;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001220 streamConfiguration.pixelFormat = format;
1221
1222 config_->addConfiguration(streamConfiguration);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001223 unsigned int index = config_->size() - 1;
1224 streams_.emplace_back(format, size, index);
1225 stream->priv = static_cast<void *>(&streams_.back());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001226 }
1227
Jacopo Mondic82f9442020-09-02 11:58:00 +02001228 /* Now handle the MJPEG streams, adding a new stream if required. */
1229 if (jpegStream) {
1230 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001231
Jacopo Mondic82f9442020-09-02 11:58:00 +02001232 /* Search for a compatible stream in the non-JPEG ones. */
1233 for (unsigned int i = 0; i < config_->size(); i++) {
1234 StreamConfiguration &cfg = config_->at(i);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001235
1236 /*
1237 * \todo The PixelFormat must also be compatible with
1238 * the encoder.
1239 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001240 if (cfg.size.width != jpegStream->width ||
1241 cfg.size.height != jpegStream->height)
1242 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001243
Jacopo Mondic82f9442020-09-02 11:58:00 +02001244 LOG(HAL, Info)
1245 << "Android JPEG stream mapped to libcamera stream " << i;
1246
1247 index = i;
1248 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001249 }
1250
1251 /*
1252 * Without a compatible match for JPEG encoding we must
1253 * introduce a new stream to satisfy the request requirements.
1254 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001255 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001256 StreamConfiguration streamConfiguration;
1257
1258 /*
1259 * \todo The pixelFormat should be a 'best-fit' choice
1260 * and may require a validation cycle. This is not yet
1261 * handled, and should be considered as part of any
1262 * stream configuration reworks.
1263 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001264 streamConfiguration.size.width = jpegStream->width;
1265 streamConfiguration.size.height = jpegStream->height;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001266 streamConfiguration.pixelFormat = formats::NV12;
1267
1268 LOG(HAL, Info) << "Adding " << streamConfiguration.toString()
1269 << " for MJPEG support";
1270
1271 config_->addConfiguration(streamConfiguration);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001272 index = config_->size() - 1;
1273 }
1274
1275 StreamConfiguration &cfg = config_->at(index);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001276
1277 /*
1278 * Construct a software encoder for the MJPEG streams from the
1279 * chosen libcamera source stream.
1280 */
Jacopo Mondifacadb12020-09-02 12:11:46 +02001281 Encoder *encoder = new EncoderLibJpeg();
1282 int ret = encoder->configure(cfg);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001283 if (ret) {
1284 LOG(HAL, Error) << "Failed to configure encoder";
Jacopo Mondifacadb12020-09-02 12:11:46 +02001285 delete encoder;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001286 return ret;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001287 }
Jacopo Mondifacadb12020-09-02 12:11:46 +02001288
1289 streams_.emplace_back(formats::MJPEG, cfg.size, index, encoder);
1290 jpegStream->priv = static_cast<void *>(&streams_.back());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001291 }
1292
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001293 switch (config_->validate()) {
1294 case CameraConfiguration::Valid:
1295 break;
1296 case CameraConfiguration::Adjusted:
1297 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001298
1299 for (const StreamConfiguration &cfg : *config_)
1300 LOG(HAL, Info) << " - " << cfg.toString();
1301
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001302 config_.reset();
1303 return -EINVAL;
1304 case CameraConfiguration::Invalid:
1305 LOG(HAL, Info) << "Camera configuration invalid";
1306 config_.reset();
1307 return -EINVAL;
1308 }
1309
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001310 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1311 camera3_stream_t *stream = stream_list->streams[i];
Jacopo Mondic82f9442020-09-02 11:58:00 +02001312 CameraStream *cameraStream = static_cast<CameraStream *>(stream->priv);
1313 StreamConfiguration &cfg = config_->at(cameraStream->index());
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001314
1315 /* Use the bufferCount confirmed by the validation process. */
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001316 stream->max_buffers = cfg.bufferCount;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001317 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001318
1319 /*
1320 * Once the CameraConfiguration has been adjusted/validated
1321 * it can be applied to the camera.
1322 */
1323 int ret = camera_->configure(config_.get());
1324 if (ret) {
1325 LOG(HAL, Error) << "Failed to configure camera '"
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001326 << camera_->id() << "'";
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001327 return ret;
1328 }
1329
1330 return 0;
1331}
1332
Kieran Bingham74ab4422020-07-01 13:25:38 +01001333FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1334{
1335 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001336 for (int i = 0; i < camera3buffer->numFds; i++) {
1337 /* Skip unused planes. */
1338 if (camera3buffer->data[i] == -1)
1339 break;
1340
Kieran Bingham74ab4422020-07-01 13:25:38 +01001341 FrameBuffer::Plane plane;
1342 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001343 if (!plane.fd.isValid()) {
1344 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1345 << camera3buffer->data[i] << ") "
1346 << " on plane " << i;
1347 return nullptr;
1348 }
1349
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001350 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1351 if (length == -1) {
1352 LOG(HAL, Error) << "Failed to query plane length";
1353 return nullptr;
1354 }
1355
1356 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001357 planes.push_back(std::move(plane));
1358 }
1359
1360 return new FrameBuffer(std::move(planes));
1361}
1362
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001363int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001364{
Kieran Bingham61f42962020-07-01 13:40:17 +01001365 if (!camera3Request->num_output_buffers) {
1366 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001367 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001368 }
1369
1370 /* Start the camera if that's the first request we handle. */
1371 if (!running_) {
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001372 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001373 if (ret) {
1374 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001375 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001376 }
1377
1378 running_ = true;
1379 }
1380
1381 /*
1382 * Queue a request for the Camera with the provided dmabuf file
1383 * descriptors.
1384 */
1385 const camera3_stream_buffer_t *camera3Buffers =
1386 camera3Request->output_buffers;
1387
1388 /*
1389 * Save the request descriptors for use at completion time.
1390 * The descriptor and the associated memory reserved here are freed
1391 * at request complete time.
1392 */
1393 Camera3RequestDescriptor *descriptor =
1394 new Camera3RequestDescriptor(camera3Request->frame_number,
1395 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001396
1397 Request *request =
1398 camera_->createRequest(reinterpret_cast<uint64_t>(descriptor));
1399
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001400 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001401 CameraStream *cameraStream =
1402 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1403
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001404 /*
1405 * Keep track of which stream the request belongs to and store
1406 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001407 */
1408 descriptor->buffers[i].stream = camera3Buffers[i].stream;
1409 descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001410
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001411 /* Software streams are handled after hardware streams complete. */
1412 if (cameraStream->format == formats::MJPEG)
1413 continue;
1414
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001415 /*
1416 * Create a libcamera buffer using the dmabuf descriptors of
1417 * the camera3Buffer for each stream. The FrameBuffer is
1418 * directly associated with the Camera3RequestDescriptor for
1419 * lifetime management only.
1420 */
1421 FrameBuffer *buffer = createFrameBuffer(*camera3Buffers[i].buffer);
1422 if (!buffer) {
1423 LOG(HAL, Error) << "Failed to create buffer";
1424 delete request;
1425 delete descriptor;
1426 return -ENOMEM;
1427 }
1428 descriptor->frameBuffers.emplace_back(buffer);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001429
Jacopo Mondic82f9442020-09-02 11:58:00 +02001430 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index());
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001431 Stream *stream = streamConfiguration->stream();
1432
1433 request->addBuffer(stream, buffer);
1434 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001435
1436 int ret = camera_->queueRequest(request);
1437 if (ret) {
1438 LOG(HAL, Error) << "Failed to queue request";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001439 delete request;
1440 delete descriptor;
1441 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001442 }
1443
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001444 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001445}
1446
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001447void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001448{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001449 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001450 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001451 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001452 Camera3RequestDescriptor *descriptor =
1453 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001454
1455 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001456 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001457 << request->status();
1458 status = CAMERA3_BUFFER_STATUS_ERROR;
1459 }
1460
Kieran Binghamc09aee42020-07-28 14:01:19 +01001461 /*
1462 * \todo The timestamp used for the metadata is currently always taken
1463 * from the first buffer (which may be the first stream) in the Request.
1464 * It might be appropriate to return a 'correct' (as determined by
1465 * pipeline handlers) timestamp in the Request itself.
1466 */
1467 FrameBuffer *buffer = buffers.begin()->second;
1468 resultMetadata = getResultMetadata(descriptor->frameNumber,
1469 buffer->metadata().timestamp);
1470
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001471 /* Handle any JPEG compression. */
1472 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
1473 CameraStream *cameraStream =
1474 static_cast<CameraStream *>(descriptor->buffers[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001475
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001476 if (cameraStream->format != formats::MJPEG)
1477 continue;
1478
Jacopo Mondifacadb12020-09-02 12:11:46 +02001479 Encoder *encoder = cameraStream->encoder();
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001480 if (!encoder) {
1481 LOG(HAL, Error) << "Failed to identify encoder";
1482 continue;
1483 }
1484
Jacopo Mondic82f9442020-09-02 11:58:00 +02001485 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001486 Stream *stream = streamConfiguration->stream();
1487 FrameBuffer *buffer = request->findBuffer(stream);
1488 if (!buffer) {
1489 LOG(HAL, Error) << "Failed to find a source stream buffer";
1490 continue;
1491 }
1492
1493 /*
1494 * \todo Buffer mapping and compression should be moved to a
1495 * separate thread.
1496 */
1497
1498 MappedCamera3Buffer mapped(*descriptor->buffers[i].buffer,
1499 PROT_READ | PROT_WRITE);
1500 if (!mapped.isValid()) {
1501 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1502 continue;
1503 }
1504
Umang Jain6f09a612020-09-09 16:44:45 +05301505 /* Set EXIF metadata for various tags. */
1506 Exif exif;
1507 /* \todo Set Make and Model from external vendor tags. */
1508 exif.setMake("libcamera");
1509 exif.setModel("cameraModel");
1510 exif.setOrientation(orientation_);
1511 exif.setSize(cameraStream->size);
1512 /*
1513 * We set the frame's EXIF timestamp as the time of encode.
1514 * Since the precision we need for EXIF timestamp is only one
1515 * second, it is good enough.
1516 */
1517 exif.setTimestamp(std::time(nullptr));
1518 if (exif.generate() != 0)
1519 LOG(HAL, Error) << "Failed to generate valid EXIF data";
1520
1521 int jpeg_size = encoder->encode(buffer, mapped.maps()[0], exif.data());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001522 if (jpeg_size < 0) {
1523 LOG(HAL, Error) << "Failed to encode stream image";
1524 status = CAMERA3_BUFFER_STATUS_ERROR;
1525 continue;
1526 }
1527
1528 /*
1529 * Fill in the JPEG blob header.
1530 *
1531 * The mapped size of the buffer is being returned as
1532 * substantially larger than the requested JPEG_MAX_SIZE
1533 * (which is referenced from maxJpegBufferSize_). Utilise
1534 * this static size to ensure the correct offset of the blob is
1535 * determined.
1536 *
1537 * \todo Investigate if the buffer size mismatch is an issue or
1538 * expected behaviour.
1539 */
1540 uint8_t *resultPtr = mapped.maps()[0].data() +
1541 maxJpegBufferSize_ -
1542 sizeof(struct camera3_jpeg_blob);
1543 auto *blob = reinterpret_cast<struct camera3_jpeg_blob *>(resultPtr);
1544 blob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
1545 blob->jpeg_size = jpeg_size;
1546
1547 /* Update the JPEG result Metadata. */
1548 resultMetadata->addEntry(ANDROID_JPEG_SIZE,
1549 &jpeg_size, 1);
1550
1551 const uint32_t jpeg_quality = 95;
1552 resultMetadata->addEntry(ANDROID_JPEG_QUALITY,
1553 &jpeg_quality, 1);
1554
1555 const uint32_t jpeg_orientation = 0;
1556 resultMetadata->addEntry(ANDROID_JPEG_ORIENTATION,
1557 &jpeg_orientation, 1);
1558 }
1559
1560 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001561 camera3_capture_result_t captureResult = {};
1562 captureResult.frame_number = descriptor->frameNumber;
1563 captureResult.num_output_buffers = descriptor->numBuffers;
1564 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001565 descriptor->buffers[i].acquire_fence = -1;
1566 descriptor->buffers[i].release_fence = -1;
1567 descriptor->buffers[i].status = status;
1568 }
1569 captureResult.output_buffers =
1570 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers);
1571
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001572
Laurent Pinchart39860092019-09-05 03:12:34 +03001573 if (status == CAMERA3_BUFFER_STATUS_OK) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001574 notifyShutter(descriptor->frameNumber,
Niklas Söderlund9217f272019-11-22 16:22:56 +01001575 buffer->metadata().timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001576
1577 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001578 captureResult.result = resultMetadata->get();
1579 }
1580
1581 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1582 /* \todo Improve error handling. In case we notify an error
1583 * because the metadata generation fails, a shutter event has
1584 * already been notified for this frame number before the error
1585 * is here signalled. Make sure the error path plays well with
1586 * the camera stack state machine.
1587 */
1588 notifyError(descriptor->frameNumber,
1589 descriptor->buffers[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001590 }
1591
1592 callbacks_->process_capture_result(callbacks_, &captureResult);
1593
1594 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001595}
1596
Jacopo Mondia7b92772020-05-26 15:41:41 +02001597std::string CameraDevice::logPrefix() const
1598{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001599 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001600}
1601
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001602void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1603{
1604 camera3_notify_msg_t notify = {};
1605
1606 notify.type = CAMERA3_MSG_SHUTTER;
1607 notify.message.shutter.frame_number = frameNumber;
1608 notify.message.shutter.timestamp = timestamp;
1609
1610 callbacks_->notify(callbacks_, &notify);
1611}
1612
1613void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1614{
1615 camera3_notify_msg_t notify = {};
1616
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001617 /*
1618 * \todo Report and identify the stream number or configuration to
1619 * clarify the stream that failed.
1620 */
1621 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1622 << toPixelFormat(stream->format).toString() << ")";
1623
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001624 notify.type = CAMERA3_MSG_ERROR;
1625 notify.message.error.error_stream = stream;
1626 notify.message.error.frame_number = frameNumber;
1627 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1628
1629 callbacks_->notify(callbacks_, &notify);
1630}
1631
1632/*
1633 * Produce a set of fixed result metadata.
1634 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001635std::unique_ptr<CameraMetadata>
1636CameraDevice::getResultMetadata([[maybe_unused]] int frame_number,
1637 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001638{
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001639 /*
1640 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001641 * Currently: 18 entries, 62 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001642 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001643 std::unique_ptr<CameraMetadata> resultMetadata =
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001644 std::make_unique<CameraMetadata>(18, 62);
Laurent Pinchart39860092019-09-05 03:12:34 +03001645 if (!resultMetadata->isValid()) {
1646 LOG(HAL, Error) << "Failed to allocate static metadata";
1647 return nullptr;
1648 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001649
1650 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001651 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001652
1653 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001654 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001655
1656 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001657 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001658
1659 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001660 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001661
1662 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001663 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001664
1665 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001666 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001667
1668 int32_t sensorSizes[] = {
1669 0, 0, 2560, 1920,
1670 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001671 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001672
Laurent Pinchart39860092019-09-05 03:12:34 +03001673 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001674
1675 /* 33.3 msec */
1676 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001677 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1678 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001679
1680 /* 16.6 msec */
1681 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001682 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1683 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001684
1685 const uint8_t lens_shading_map_mode =
1686 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001687 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1688 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001689
1690 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001691 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1692 &scene_flicker, 1);
1693
1694 /*
1695 * Return the result metadata pack even is not valid: get() will return
1696 * nullptr.
1697 */
1698 if (!resultMetadata->isValid()) {
1699 LOG(HAL, Error) << "Failed to construct result metadata";
1700 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001701
1702 return resultMetadata;
1703}