blob: c29fcb43fe2dee438006a383f5a3a2cb731db177 [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
26using namespace libcamera;
27
Jacopo Mondi117588b2020-05-23 18:53:54 +020028namespace {
29
30/*
31 * \var camera3Resolutions
32 * \brief The list of image resolutions defined as mandatory to be supported by
33 * the Android Camera3 specification
34 */
35const std::vector<Size> camera3Resolutions = {
36 { 320, 240 },
37 { 640, 480 },
38 { 1280, 720 },
39 { 1920, 1080 }
40};
41
42/*
43 * \struct Camera3Format
44 * \brief Data associated with an Android format identifier
45 * \var libcameraFormats List of libcamera pixel formats compatible with the
46 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020047 * \var name The human-readable representation of the Android format code
48 */
49struct Camera3Format {
50 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020051 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020052 const char *name;
53};
54
55/*
56 * \var camera3FormatsMap
57 * \brief Associate Android format code with ancillary data
58 */
59const std::map<int, const Camera3Format> camera3FormatsMap = {
60 {
61 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030062 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020063 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020064 "BLOB"
65 }
66 }, {
67 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030068 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020069 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020070 "YCbCr_420_888"
71 }
72 }, {
73 /*
74 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
75 * usage flag. For now, copy the YCbCr_420 configuration.
76 */
77 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030078 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020079 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020080 "IMPLEMENTATION_DEFINED"
81 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020082 }, {
83 HAL_PIXEL_FORMAT_RAW10, {
84 {
85 formats::SBGGR10_CSI2P,
86 formats::SGBRG10_CSI2P,
87 formats::SGRBG10_CSI2P,
88 formats::SRGGB10_CSI2P
89 },
90 false,
91 "RAW10"
92 }
93 }, {
94 HAL_PIXEL_FORMAT_RAW12, {
95 {
96 formats::SBGGR12_CSI2P,
97 formats::SGBRG12_CSI2P,
98 formats::SGRBG12_CSI2P,
99 formats::SRGGB12_CSI2P
100 },
101 false,
102 "RAW12"
103 }
104 }, {
105 HAL_PIXEL_FORMAT_RAW16, {
106 {
107 formats::SBGGR16,
108 formats::SGBRG16,
109 formats::SGRBG16,
110 formats::SRGGB16
111 },
112 false,
113 "RAW16"
114 }
115 }, {
116 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
117 {
118 formats::SBGGR10_IPU3,
119 formats::SGBRG10_IPU3,
120 formats::SGRBG10_IPU3,
121 formats::SRGGB10_IPU3
122 },
123 false,
124 "RAW_OPAQUE"
125 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200126 },
127};
128
129} /* namespace */
130
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200131LOG_DECLARE_CATEGORY(HAL);
132
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100133MappedCamera3Buffer::MappedCamera3Buffer(const buffer_handle_t camera3buffer,
134 int flags)
135{
136 maps_.reserve(camera3buffer->numFds);
137 error_ = 0;
138
139 for (int i = 0; i < camera3buffer->numFds; i++) {
140 if (camera3buffer->data[i] == -1)
141 continue;
142
143 off_t length = lseek(camera3buffer->data[i], 0, SEEK_END);
144 if (length < 0) {
145 error_ = -errno;
146 LOG(HAL, Error) << "Failed to query plane length";
147 break;
148 }
149
150 void *address = mmap(nullptr, length, flags, MAP_SHARED,
151 camera3buffer->data[i], 0);
152 if (address == MAP_FAILED) {
153 error_ = -errno;
154 LOG(HAL, Error) << "Failed to mmap plane";
155 break;
156 }
157
158 maps_.emplace_back(static_cast<uint8_t *>(address),
159 static_cast<size_t>(length));
160 }
161}
162
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200163/*
164 * \struct Camera3RequestDescriptor
165 *
166 * A utility structure that groups information about a capture request to be
167 * later re-used at request complete time to notify the framework.
168 */
169
170CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
171 unsigned int frameNumber, unsigned int numBuffers)
172 : frameNumber(frameNumber), numBuffers(numBuffers)
173{
174 buffers = new camera3_stream_buffer_t[numBuffers];
Kieran Bingham0cfdf732020-07-01 13:36:24 +0100175 frameBuffers.reserve(numBuffers);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200176}
177
178CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
179{
180 delete[] buffers;
181}
182
183/*
184 * \class CameraDevice
185 *
186 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200187 * the camera3_device_t interface, bridging calls received from the Android
188 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200189 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200190 * The class translates parameters and operations from the Camera HALv3 API to
191 * the libcamera API to provide static information for a Camera, create request
192 * templates for it, process capture requests and then deliver capture results
193 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200194 */
195
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300196CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000197 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200198 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200199{
200 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100201
202 /*
203 * \todo Determine a more accurate value for this during
204 * streamConfiguration.
205 */
206 maxJpegBufferSize_ = 13 << 20; /* 13631488 from USB HAL */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200207}
208
209CameraDevice::~CameraDevice()
210{
211 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300212 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200213
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200214 for (auto &it : requestTemplates_)
215 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200216}
217
Umang Jainf8e28132020-08-21 14:46:08 +0000218std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
219 const std::shared_ptr<Camera> &cam)
220{
221 CameraDevice *camera = new CameraDevice(id, cam);
222 return std::shared_ptr<CameraDevice>(camera);
223}
224
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200225/*
226 * Initialize the camera static information.
227 * This method is called before the camera device is opened.
228 */
229int CameraDevice::initialize()
230{
231 /* Initialize orientation and facing side of the camera. */
232 const ControlList &properties = camera_->properties();
233
234 if (properties.contains(properties::Location)) {
235 int32_t location = properties.get(properties::Location);
236 switch (location) {
237 case properties::CameraLocationFront:
238 facing_ = CAMERA_FACING_FRONT;
239 break;
240 case properties::CameraLocationBack:
241 facing_ = CAMERA_FACING_BACK;
242 break;
243 case properties::CameraLocationExternal:
244 facing_ = CAMERA_FACING_EXTERNAL;
245 break;
246 }
247 }
248
249 /*
Umang Jaine9176552020-09-09 16:17:54 +0530250 * The Android orientation metadata specifies its rotation correction
251 * value in clockwise direction whereas libcamera specifies the
252 * rotation property in anticlockwise direction. Read the libcamera's
253 * rotation property (anticlockwise) and compute the corresponding
254 * value for clockwise direction as required by the Android orientation
255 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200256 */
Umang Jaine9176552020-09-09 16:17:54 +0530257 if (properties.contains(properties::Rotation)) {
258 int rotation = properties.get(properties::Rotation);
259 orientation_ = (360 - rotation) % 360;
260 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200261
Jacopo Mondi117588b2020-05-23 18:53:54 +0200262 int ret = camera_->acquire();
263 if (ret) {
264 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
265 return ret;
266 }
267
268 ret = initializeStreamConfigurations();
269 camera_->release();
270 return ret;
271}
272
Jacopo Mondibfee6312020-09-01 17:42:13 +0200273std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
274 const PixelFormat &pixelFormat,
275 const std::vector<Size> &resolutions)
276{
277 std::vector<Size> supportedResolutions;
278
279 StreamConfiguration &cfg = cameraConfig->at(0);
280 for (const Size &res : resolutions) {
281 cfg.pixelFormat = pixelFormat;
282 cfg.size = res;
283
284 CameraConfiguration::Status status = cameraConfig->validate();
285 if (status != CameraConfiguration::Valid) {
286 LOG(HAL, Debug) << cfg.toString() << " not supported";
287 continue;
288 }
289
290 LOG(HAL, Debug) << cfg.toString() << " supported";
291
292 supportedResolutions.push_back(res);
293 }
294
295 return supportedResolutions;
296}
297
Jacopo Mondi49610332020-09-01 18:11:34 +0200298std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
299{
300 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200301 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200302 StreamConfiguration &cfg = cameraConfig->at(0);
303 const StreamFormats &formats = cfg.formats();
304 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
305
306 return supportedResolutions;
307}
308
Jacopo Mondi117588b2020-05-23 18:53:54 +0200309/*
310 * Initialize the format conversion map to translate from Android format
311 * identifier to libcamera pixel formats and fill in the list of supported
312 * stream configurations to be reported to the Android camera framework through
313 * the static stream configuration metadata.
314 */
315int CameraDevice::initializeStreamConfigurations()
316{
317 /*
318 * Get the maximum output resolutions
319 * \todo Get this from the camera properties once defined
320 */
321 std::unique_ptr<CameraConfiguration> cameraConfig =
322 camera_->generateConfiguration({ StillCapture });
323 if (!cameraConfig) {
324 LOG(HAL, Error) << "Failed to get maximum resolution";
325 return -EINVAL;
326 }
327 StreamConfiguration &cfg = cameraConfig->at(0);
328
329 /*
330 * \todo JPEG - Adjust the maximum available resolution by taking the
331 * JPEG encoder requirements into account (alignment and aspect ratio).
332 */
333 const Size maxRes = cfg.size;
334 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
335
336 /*
337 * Build the list of supported image resolutions.
338 *
339 * The resolutions listed in camera3Resolution are mandatory to be
340 * supported, up to the camera maximum resolution.
341 *
342 * Augment the list by adding resolutions calculated from the camera
343 * maximum one.
344 */
345 std::vector<Size> cameraResolutions;
346 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
347 std::back_inserter(cameraResolutions),
348 [&](const Size &res) { return res < maxRes; });
349
350 /*
351 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
352 * resolution.
353 */
354 for (unsigned int divider = 2;; divider <<= 1) {
355 Size derivedSize{
356 maxRes.width / divider,
357 maxRes.height / divider,
358 };
359
360 if (derivedSize.width < 320 ||
361 derivedSize.height < 240)
362 break;
363
364 cameraResolutions.push_back(derivedSize);
365 }
366 cameraResolutions.push_back(maxRes);
367
368 /* Remove duplicated entries from the list of supported resolutions. */
369 std::sort(cameraResolutions.begin(), cameraResolutions.end());
370 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
371 cameraResolutions.erase(last, cameraResolutions.end());
372
373 /*
374 * Build the list of supported camera formats.
375 *
376 * To each Android format a list of compatible libcamera formats is
377 * associated. The first libcamera format that tests successful is added
378 * to the format translation map used when configuring the streams.
379 * It is then tested against the list of supported camera resolutions to
380 * build the stream configuration map reported through the camera static
381 * metadata.
382 */
383 for (const auto &format : camera3FormatsMap) {
384 int androidFormat = format.first;
385 const Camera3Format &camera3Format = format.second;
386 const std::vector<PixelFormat> &libcameraFormats =
387 camera3Format.libcameraFormats;
388
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200389 LOG(HAL, Debug) << "Trying to map Android format "
390 << camera3Format.name;
391
Jacopo Mondi117588b2020-05-23 18:53:54 +0200392 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200393 * JPEG is always supported, either produced directly by the
394 * camera, or encoded in the HAL.
395 */
396 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
397 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200398 LOG(HAL, Debug) << "Mapped Android format "
399 << camera3Format.name << " to "
400 << formats::MJPEG.toString()
401 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200402 continue;
403 }
404
405 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200406 * Test the libcamera formats that can produce images
407 * compatible with the format defined by Android.
408 */
409 PixelFormat mappedFormat;
410 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200411
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200412 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
413
Jacopo Mondi117588b2020-05-23 18:53:54 +0200414 /*
415 * The stream configuration size can be adjusted,
416 * not the pixel format.
417 *
418 * \todo This could be simplified once all pipeline
419 * handlers will report the StreamFormats list of
420 * supported formats.
421 */
422 cfg.pixelFormat = pixelFormat;
423
424 CameraConfiguration::Status status = cameraConfig->validate();
425 if (status != CameraConfiguration::Invalid &&
426 cfg.pixelFormat == pixelFormat) {
427 mappedFormat = pixelFormat;
428 break;
429 }
430 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200431
432 if (!mappedFormat.isValid()) {
433 /* If the format is not mandatory, skip it. */
434 if (!camera3Format.mandatory)
435 continue;
436
437 LOG(HAL, Error)
438 << "Failed to map mandatory Android format "
439 << camera3Format.name << " ("
440 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200441 return -EINVAL;
442 }
443
444 /*
445 * Record the mapping and then proceed to generate the
446 * stream configurations map, by testing the image resolutions.
447 */
448 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200449 LOG(HAL, Debug) << "Mapped Android format "
450 << camera3Format.name << " to "
451 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200452
Jacopo Mondi49610332020-09-01 18:11:34 +0200453 std::vector<Size> resolutions;
454 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
455 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
456 resolutions = getRawResolutions(mappedFormat);
457 else
458 resolutions = getYUVResolutions(cameraConfig.get(),
459 mappedFormat,
460 cameraResolutions);
461
Jacopo Mondibfee6312020-09-01 17:42:13 +0200462 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200463 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200464
465 /*
466 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
467 * from which JPEG is produced, add an entry for
468 * the JPEG stream.
469 *
470 * \todo Wire the JPEG encoder to query the supported
471 * sizes provided a list of formats it can encode.
472 *
473 * \todo Support JPEG streams produced by the Camera
474 * natively.
475 */
476 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888)
477 streamConfigurations_.push_back(
478 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200479 }
480 }
481
482 LOG(HAL, Debug) << "Collected stream configuration map: ";
483 for (const auto &entry : streamConfigurations_)
484 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200485 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200486
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200487 return 0;
488}
489
490/*
491 * Open a camera device. The static information on the camera shall have been
492 * initialized with a call to CameraDevice::initialize().
493 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200494int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200495{
496 int ret = camera_->acquire();
497 if (ret) {
498 LOG(HAL, Error) << "Failed to acquire the camera";
499 return ret;
500 }
501
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200502 /* Initialize the hw_device_t in the instance camera3_module_t. */
503 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
504 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
505 camera3Device_.common.module = (hw_module_t *)hardwareModule;
506 camera3Device_.common.close = hal_dev_close;
507
508 /*
509 * The camera device operations. These actually implement
510 * the Android Camera HALv3 interface.
511 */
512 camera3Device_.ops = &hal_dev_ops;
513 camera3Device_.priv = this;
514
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200515 return 0;
516}
517
518void CameraDevice::close()
519{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200520 streams_.clear();
521
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200522 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200523 camera_->release();
524
525 running_ = false;
526}
527
528void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
529{
530 callbacks_ = callbacks;
531}
532
Jacopo Mondia80d3812020-05-26 12:31:35 +0200533std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
534{
535 /*
536 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100537 * Currently: 51 entries, 687 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200538 */
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100539 uint32_t numEntries = 51;
540 uint32_t byteSize = 687;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200541
542 /*
543 * Calculate space occupation in bytes for dynamically built metadata
544 * entries.
545 *
546 * Each stream configuration entry requires 52 bytes:
547 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200548 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
549 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200550 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200551
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300552 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200553}
554
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200555/*
556 * Return static information for the camera.
557 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200558const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200559{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200560 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300561 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200562
563 /*
564 * The here reported metadata are enough to implement a basic capture
565 * example application, but a real camera implementation will require
566 * more.
567 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200568 uint32_t numEntries;
569 uint32_t byteSize;
570 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
571 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300572 if (!staticMetadata_->isValid()) {
573 LOG(HAL, Error) << "Failed to allocate static metadata";
574 delete staticMetadata_;
575 staticMetadata_ = nullptr;
576 return nullptr;
577 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200578
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200579 /* Color correction static metadata. */
580 std::vector<uint8_t> aberrationModes = {
581 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
582 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300583 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
584 aberrationModes.data(),
585 aberrationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200586
587 /* Control static metadata. */
588 std::vector<uint8_t> aeAvailableAntiBandingModes = {
589 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
590 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
591 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
592 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
593 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300594 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
595 aeAvailableAntiBandingModes.data(),
596 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200597
598 std::vector<uint8_t> aeAvailableModes = {
599 ANDROID_CONTROL_AE_MODE_ON,
600 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300601 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
602 aeAvailableModes.data(),
603 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200604
605 std::vector<int32_t> availableAeFpsTarget = {
606 15, 30,
607 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300608 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
609 availableAeFpsTarget.data(),
610 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200611
612 std::vector<int32_t> aeCompensationRange = {
613 0, 0,
614 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300615 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
616 aeCompensationRange.data(),
617 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200618
619 const camera_metadata_rational_t aeCompensationStep[] = {
620 { 0, 1 }
621 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300622 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
623 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200624
625 std::vector<uint8_t> availableAfModes = {
626 ANDROID_CONTROL_AF_MODE_OFF,
627 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300628 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
629 availableAfModes.data(),
630 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200631
632 std::vector<uint8_t> availableEffects = {
633 ANDROID_CONTROL_EFFECT_MODE_OFF,
634 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300635 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
636 availableEffects.data(),
637 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200638
639 std::vector<uint8_t> availableSceneModes = {
640 ANDROID_CONTROL_SCENE_MODE_DISABLED,
641 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300642 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
643 availableSceneModes.data(),
644 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200645
646 std::vector<uint8_t> availableStabilizationModes = {
647 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
648 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300649 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
650 availableStabilizationModes.data(),
651 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200652
653 std::vector<uint8_t> availableAwbModes = {
654 ANDROID_CONTROL_AWB_MODE_OFF,
655 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300656 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
657 availableAwbModes.data(),
658 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200659
660 std::vector<int32_t> availableMaxRegions = {
661 0, 0, 0,
662 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300663 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
664 availableMaxRegions.data(),
665 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200666
667 std::vector<uint8_t> sceneModesOverride = {
668 ANDROID_CONTROL_AE_MODE_ON,
669 ANDROID_CONTROL_AWB_MODE_AUTO,
670 ANDROID_CONTROL_AF_MODE_AUTO,
671 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300672 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
673 sceneModesOverride.data(),
674 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200675
676 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300677 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
678 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200679
680 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300681 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
682 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200683
684 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300685 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
686 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200687
688 /* JPEG static metadata. */
689 std::vector<int32_t> availableThumbnailSizes = {
690 0, 0,
691 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300692 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
693 availableThumbnailSizes.data(),
694 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200695
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100696 /*
697 * \todo Calculate the maximum JPEG buffer size by asking the encoder
698 * giving the maximum frame size required.
699 */
700 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
701
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200702 /* Sensor static metadata. */
703 int32_t pixelArraySize[] = {
704 2592, 1944,
705 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300706 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
707 &pixelArraySize, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200708
709 int32_t sensorSizes[] = {
710 0, 0, 2560, 1920,
711 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300712 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
713 &sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200714
715 int32_t sensitivityRange[] = {
716 32, 2400,
717 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300718 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
719 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200720
721 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300722 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
723 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200724
725 int64_t exposureTimeRange[] = {
726 100000, 200000000,
727 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300728 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
729 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200730
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200731 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200732
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200733 std::vector<int32_t> testPatterModes = {
734 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
735 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300736 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
737 testPatterModes.data(),
738 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200739
740 std::vector<float> physicalSize = {
741 2592, 1944,
742 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300743 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
744 physicalSize.data(),
745 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200746
747 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300748 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
749 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200750
751 /* Statistics static metadata. */
752 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300753 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
754 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200755
756 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300757 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
758 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200759
760 /* Sync static metadata. */
761 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300762 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200763
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200764 /* Flash static metadata. */
765 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300766 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
767 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200768
769 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200770 std::vector<float> lensApertures = {
771 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200772 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300773 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
774 lensApertures.data(),
775 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200776
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200777 uint8_t lensFacing;
778 switch (facing_) {
779 default:
780 case CAMERA_FACING_FRONT:
781 lensFacing = ANDROID_LENS_FACING_FRONT;
782 break;
783 case CAMERA_FACING_BACK:
784 lensFacing = ANDROID_LENS_FACING_BACK;
785 break;
786 case CAMERA_FACING_EXTERNAL:
787 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
788 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100789 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300790 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200791
792 std::vector<float> lensFocalLenghts = {
793 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200794 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300795 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
796 lensFocalLenghts.data(),
797 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200798
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200799 std::vector<uint8_t> opticalStabilizations = {
800 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
801 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300802 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
803 opticalStabilizations.data(),
804 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200805
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200806 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300807 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
808 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200809
810 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300811 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
812 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200813
814 /* Noise reduction modes. */
815 uint8_t noiseReductionModes = ANDROID_NOISE_REDUCTION_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300816 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
817 &noiseReductionModes, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200818
819 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200820 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300821 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
822 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200823
Jacopo Mondibde7b982020-05-25 17:18:28 +0200824 std::vector<uint32_t> availableStreamConfigurations;
825 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
826 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200827 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200828 availableStreamConfigurations.push_back(entry.resolution.width);
829 availableStreamConfigurations.push_back(entry.resolution.height);
830 availableStreamConfigurations.push_back(
831 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
832 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300833 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
834 availableStreamConfigurations.data(),
835 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200836
837 std::vector<int64_t> availableStallDurations = {
838 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
839 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300840 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
841 availableStallDurations.data(),
842 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200843
Jacopo Mondibde7b982020-05-25 17:18:28 +0200844 /* \todo Collect the minimum frame duration from the camera. */
845 std::vector<int64_t> minFrameDurations;
846 minFrameDurations.reserve(streamConfigurations_.size() * 4);
847 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200848 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200849 minFrameDurations.push_back(entry.resolution.width);
850 minFrameDurations.push_back(entry.resolution.height);
851 minFrameDurations.push_back(33333333);
852 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300853 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
854 minFrameDurations.data(),
855 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200856
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200857 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300858 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200859
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200860 /* Info static metadata. */
861 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300862 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
863 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200864
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200865 /* Request static metadata. */
866 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300867 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
868 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200869
870 uint8_t maxPipelineDepth = 2;
Laurent Pinchart39860092019-09-05 03:12:34 +0300871 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
872 &maxPipelineDepth, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200873
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200874 /* LIMITED does not support reprocessing. */
875 uint32_t maxNumInputStreams = 0;
876 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
877 &maxNumInputStreams, 1);
878
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200879 std::vector<uint8_t> availableCapabilities = {
880 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
881 };
Niklas Söderlund7876d632020-07-21 00:16:24 +0200882
883 /* Report if camera supports RAW. */
884 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200885 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +0200886 if (cameraConfig && !cameraConfig->empty()) {
887 const PixelFormatInfo &info =
888 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
889 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
890 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
891 }
892
Laurent Pinchart39860092019-09-05 03:12:34 +0300893 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
894 availableCapabilities.data(),
895 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200896
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200897 std::vector<int32_t> availableCharacteristicsKeys = {
898 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
899 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
900 ANDROID_CONTROL_AE_AVAILABLE_MODES,
901 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
902 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
903 ANDROID_CONTROL_AE_COMPENSATION_STEP,
904 ANDROID_CONTROL_AF_AVAILABLE_MODES,
905 ANDROID_CONTROL_AVAILABLE_EFFECTS,
906 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
907 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
908 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
909 ANDROID_CONTROL_MAX_REGIONS,
910 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
911 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
912 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
913 ANDROID_CONTROL_AVAILABLE_MODES,
914 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100915 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200916 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
917 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
918 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
919 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
920 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
921 ANDROID_SENSOR_ORIENTATION,
922 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
923 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
924 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
925 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
926 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
927 ANDROID_SYNC_MAX_LATENCY,
928 ANDROID_FLASH_INFO_AVAILABLE,
929 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
930 ANDROID_LENS_FACING,
931 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
932 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
933 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
934 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
935 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
936 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200937 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
938 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
939 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
940 ANDROID_SCALER_CROPPING_TYPE,
941 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
942 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
943 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200944 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200945 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
946 };
947 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
948 availableCharacteristicsKeys.data(),
949 availableCharacteristicsKeys.size());
950
951 std::vector<int32_t> availableRequestKeys = {
952 ANDROID_CONTROL_AE_MODE,
953 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
954 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200955 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
956 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200957 ANDROID_CONTROL_AE_LOCK,
958 ANDROID_CONTROL_AF_TRIGGER,
959 ANDROID_CONTROL_AWB_MODE,
960 ANDROID_CONTROL_AWB_LOCK,
961 ANDROID_FLASH_MODE,
962 ANDROID_STATISTICS_FACE_DETECT_MODE,
963 ANDROID_NOISE_REDUCTION_MODE,
964 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200965 ANDROID_LENS_APERTURE,
966 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
967 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200968 ANDROID_CONTROL_CAPTURE_INTENT,
969 };
970 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
971 availableRequestKeys.data(),
972 availableRequestKeys.size());
973
974 std::vector<int32_t> availableResultKeys = {
975 ANDROID_CONTROL_AE_STATE,
976 ANDROID_CONTROL_AE_LOCK,
977 ANDROID_CONTROL_AF_STATE,
978 ANDROID_CONTROL_AWB_STATE,
979 ANDROID_CONTROL_AWB_LOCK,
980 ANDROID_LENS_STATE,
981 ANDROID_SCALER_CROP_REGION,
982 ANDROID_SENSOR_TIMESTAMP,
983 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
984 ANDROID_SENSOR_EXPOSURE_TIME,
985 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
986 ANDROID_STATISTICS_SCENE_FLICKER,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100987 ANDROID_JPEG_SIZE,
988 ANDROID_JPEG_QUALITY,
989 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200990 };
991 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
992 availableResultKeys.data(),
993 availableResultKeys.size());
994
Laurent Pinchart39860092019-09-05 03:12:34 +0300995 if (!staticMetadata_->isValid()) {
996 LOG(HAL, Error) << "Failed to construct static metadata";
997 delete staticMetadata_;
998 staticMetadata_ = nullptr;
999 return nullptr;
1000 }
1001
1002 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001003}
1004
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001005CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001006{
Jacopo Mondi63703472019-09-04 16:18:22 +02001007 /*
1008 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001009 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001010 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001011 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001012 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001013 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001014 return nullptr;
1015 }
1016
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001017 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001018 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1019 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001020
1021 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001022 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1023 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001024
1025 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001026 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1027 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001028
1029 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001030 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1031 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001032
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001033 std::vector<int32_t> aeFpsTarget = {
1034 15, 30,
1035 };
1036 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1037 aeFpsTarget.data(),
1038 aeFpsTarget.size());
1039
1040 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1041 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1042 &aeAntibandingMode, 1);
1043
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001044 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001045 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1046 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001047
1048 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001049 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1050 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001051
1052 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001053 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1054 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001055
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001056 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001057 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1058 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001059
1060 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001061 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1062 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001063
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001064 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001065 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1066 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001067
1068 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001069 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1070 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001071
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001072 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1073 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1074
1075 float lensAperture = 2.53 / 100;
1076 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1077
1078 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1079 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1080 &opticalStabilization, 1);
1081
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001082 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001083 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1084 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001085
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001086 return requestTemplate;
1087}
1088
1089/*
1090 * Produce a metadata pack to be used as template for a capture request.
1091 */
1092const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1093{
1094 auto it = requestTemplates_.find(type);
1095 if (it != requestTemplates_.end())
1096 return it->second->get();
1097
1098 /* Use the capture intent matching the requested template type. */
1099 CameraMetadata *requestTemplate;
1100 uint8_t captureIntent;
1101 switch (type) {
1102 case CAMERA3_TEMPLATE_PREVIEW:
1103 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1104 break;
1105 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1106 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1107 break;
1108 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1109 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1110 break;
1111 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1112 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1113 break;
1114 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1115 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1116 break;
1117 case CAMERA3_TEMPLATE_MANUAL:
1118 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1119 break;
1120 default:
1121 LOG(HAL, Error) << "Invalid template request type: " << type;
1122 return nullptr;
1123 }
1124
1125 requestTemplate = requestTemplatePreview();
1126 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001127 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001128 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001129 return nullptr;
1130 }
1131
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001132 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1133 &captureIntent, 1);
1134
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001135 requestTemplates_[type] = requestTemplate;
1136 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001137}
1138
Kieran Bingham43e3b802020-06-26 09:58:49 +01001139PixelFormat CameraDevice::toPixelFormat(int format)
1140{
1141 /* Translate Android format code to libcamera pixel format. */
1142 auto it = formatsMap_.find(format);
1143 if (it == formatsMap_.end()) {
1144 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1145 << " not supported";
1146 return PixelFormat();
1147 }
1148
1149 return it->second;
1150}
1151
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001152/*
1153 * Inspect the stream_list to produce a list of StreamConfiguration to
1154 * be use to configure the Camera.
1155 */
1156int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1157{
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001158 /*
1159 * Generate an empty configuration, and construct a StreamConfiguration
1160 * for each camera3_stream to add to it.
1161 */
1162 config_ = camera_->generateConfiguration();
1163 if (!config_) {
1164 LOG(HAL, Error) << "Failed to generate camera configuration";
1165 return -EINVAL;
1166 }
1167
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001168 /*
1169 * Clear and remove any existing configuration from previous calls, and
1170 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001171 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001172 */
1173 streams_.clear();
1174 streams_.reserve(stream_list->num_streams);
1175
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001176 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001177 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001178 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1179 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001180 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001181
Kieran Bingham43e3b802020-06-26 09:58:49 +01001182 PixelFormat format = toPixelFormat(stream->format);
1183
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001184 LOG(HAL, Info) << "Stream #" << i
1185 << ", direction: " << stream->stream_type
1186 << ", width: " << stream->width
1187 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001188 << ", format: " << utils::hex(stream->format)
1189 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001190
1191 if (!format.isValid())
1192 return -EINVAL;
1193
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001194 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001195 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1196 if (jpegStream) {
1197 LOG(HAL, Error)
1198 << "Multiple JPEG streams are not supported";
1199 return -EINVAL;
1200 }
1201
1202 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001203 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001204 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001205
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001206 StreamConfiguration streamConfiguration;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001207 streamConfiguration.size = size;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001208 streamConfiguration.pixelFormat = format;
1209
1210 config_->addConfiguration(streamConfiguration);
Jacopo Mondie3393f12020-10-03 12:00:54 +02001211 streams_.emplace_back(this, CameraStream::Type::Direct,
1212 stream, config_->size() - 1);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001213 stream->priv = static_cast<void *>(&streams_.back());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001214 }
1215
Jacopo Mondic82f9442020-09-02 11:58:00 +02001216 /* Now handle the MJPEG streams, adding a new stream if required. */
1217 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001218 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001219 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001220
Jacopo Mondic82f9442020-09-02 11:58:00 +02001221 /* Search for a compatible stream in the non-JPEG ones. */
1222 for (unsigned int i = 0; i < config_->size(); i++) {
1223 StreamConfiguration &cfg = config_->at(i);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001224
1225 /*
1226 * \todo The PixelFormat must also be compatible with
1227 * the encoder.
1228 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001229 if (cfg.size.width != jpegStream->width ||
1230 cfg.size.height != jpegStream->height)
1231 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001232
Jacopo Mondic82f9442020-09-02 11:58:00 +02001233 LOG(HAL, Info)
1234 << "Android JPEG stream mapped to libcamera stream " << i;
1235
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001236 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001237 index = i;
1238 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001239 }
1240
1241 /*
1242 * Without a compatible match for JPEG encoding we must
1243 * introduce a new stream to satisfy the request requirements.
1244 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001245 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001246 StreamConfiguration streamConfiguration;
1247
1248 /*
1249 * \todo The pixelFormat should be a 'best-fit' choice
1250 * and may require a validation cycle. This is not yet
1251 * handled, and should be considered as part of any
1252 * stream configuration reworks.
1253 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001254 streamConfiguration.size.width = jpegStream->width;
1255 streamConfiguration.size.height = jpegStream->height;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001256 streamConfiguration.pixelFormat = formats::NV12;
1257
1258 LOG(HAL, Info) << "Adding " << streamConfiguration.toString()
1259 << " for MJPEG support";
1260
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001261 type = CameraStream::Type::Internal;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001262 config_->addConfiguration(streamConfiguration);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001263 index = config_->size() - 1;
1264 }
1265
Jacopo Mondie3393f12020-10-03 12:00:54 +02001266 streams_.emplace_back(this, type, jpegStream, index);
Jacopo Mondifacadb12020-09-02 12:11:46 +02001267 jpegStream->priv = static_cast<void *>(&streams_.back());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001268 }
1269
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001270 switch (config_->validate()) {
1271 case CameraConfiguration::Valid:
1272 break;
1273 case CameraConfiguration::Adjusted:
1274 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001275
1276 for (const StreamConfiguration &cfg : *config_)
1277 LOG(HAL, Info) << " - " << cfg.toString();
1278
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001279 config_.reset();
1280 return -EINVAL;
1281 case CameraConfiguration::Invalid:
1282 LOG(HAL, Info) << "Camera configuration invalid";
1283 config_.reset();
1284 return -EINVAL;
1285 }
1286
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001287 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001288 * Once the CameraConfiguration has been adjusted/validated
1289 * it can be applied to the camera.
1290 */
1291 int ret = camera_->configure(config_.get());
1292 if (ret) {
1293 LOG(HAL, Error) << "Failed to configure camera '"
1294 << camera_->id() << "'";
1295 return ret;
1296 }
1297
1298 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001299 * Configure the HAL CameraStream instances using the associated
1300 * StreamConfiguration and set the number of required buffers in
1301 * the Android camera3_stream_t.
1302 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001303 for (CameraStream &cameraStream : streams_) {
1304 int ret = cameraStream.configure();
1305 if (ret) {
1306 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001307 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001308 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001309 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001310
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001311 return 0;
1312}
1313
Kieran Bingham74ab4422020-07-01 13:25:38 +01001314FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1315{
1316 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001317 for (int i = 0; i < camera3buffer->numFds; i++) {
1318 /* Skip unused planes. */
1319 if (camera3buffer->data[i] == -1)
1320 break;
1321
Kieran Bingham74ab4422020-07-01 13:25:38 +01001322 FrameBuffer::Plane plane;
1323 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001324 if (!plane.fd.isValid()) {
1325 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1326 << camera3buffer->data[i] << ") "
1327 << " on plane " << i;
1328 return nullptr;
1329 }
1330
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001331 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1332 if (length == -1) {
1333 LOG(HAL, Error) << "Failed to query plane length";
1334 return nullptr;
1335 }
1336
1337 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001338 planes.push_back(std::move(plane));
1339 }
1340
1341 return new FrameBuffer(std::move(planes));
1342}
1343
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001344int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001345{
Kieran Bingham61f42962020-07-01 13:40:17 +01001346 if (!camera3Request->num_output_buffers) {
1347 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001348 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001349 }
1350
1351 /* Start the camera if that's the first request we handle. */
1352 if (!running_) {
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001353 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001354 if (ret) {
1355 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001356 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001357 }
1358
1359 running_ = true;
1360 }
1361
1362 /*
1363 * Queue a request for the Camera with the provided dmabuf file
1364 * descriptors.
1365 */
1366 const camera3_stream_buffer_t *camera3Buffers =
1367 camera3Request->output_buffers;
1368
1369 /*
1370 * Save the request descriptors for use at completion time.
1371 * The descriptor and the associated memory reserved here are freed
1372 * at request complete time.
1373 */
1374 Camera3RequestDescriptor *descriptor =
1375 new Camera3RequestDescriptor(camera3Request->frame_number,
1376 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001377
Paul Elderc7532232020-09-23 19:05:41 +09001378 std::unique_ptr<Request> request =
Kieran Binghameac05422020-07-01 13:28:16 +01001379 camera_->createRequest(reinterpret_cast<uint64_t>(descriptor));
Paul Elderc7532232020-09-23 19:05:41 +09001380 if (!request) {
1381 LOG(HAL, Error) << "Failed to create request";
1382 return -ENOMEM;
1383 }
Kieran Binghameac05422020-07-01 13:28:16 +01001384
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001385 LOG(HAL, Debug) << "Queueing Request to libcamera with "
1386 << descriptor->numBuffers << " HAL streams";
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001387 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001388 camera3_stream *camera3Stream = camera3Buffers[i].stream;
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001389 CameraStream *cameraStream =
1390 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1391
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001392 /*
1393 * Keep track of which stream the request belongs to and store
1394 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001395 */
1396 descriptor->buffers[i].stream = camera3Buffers[i].stream;
1397 descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001398
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001399 std::stringstream ss;
1400 ss << i << " - (" << camera3Stream->width << "x"
1401 << camera3Stream->height << ")"
1402 << "[" << utils::hex(camera3Stream->format) << "] -> "
1403 << "(" << cameraStream->configuration().size.toString() << ")["
1404 << cameraStream->configuration().pixelFormat.toString() << "]";
1405
Jacopo Mondide8304b2020-09-04 17:45:39 +02001406 /*
1407 * Inspect the camera stream type, create buffers opportunely
1408 * and add them to the Request if required.
1409 */
1410 FrameBuffer *buffer = nullptr;
1411 switch (cameraStream->type()) {
1412 case CameraStream::Type::Mapped:
1413 /*
1414 * Mapped streams don't need buffers added to the
1415 * Request.
1416 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001417 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001418 continue;
1419
Jacopo Mondide8304b2020-09-04 17:45:39 +02001420 case CameraStream::Type::Direct:
1421 /*
1422 * Create a libcamera buffer using the dmabuf
1423 * descriptors of the camera3Buffer for each stream and
1424 * associate it with the Camera3RequestDescriptor for
1425 * lifetime management only.
1426 */
1427 buffer = createFrameBuffer(*camera3Buffers[i].buffer);
1428 descriptor->frameBuffers.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001429 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001430 break;
1431
1432 case CameraStream::Type::Internal:
1433 /*
1434 * Get the frame buffer from the CameraStream internal
1435 * buffer pool.
1436 *
1437 * The buffer has to be returned to the CameraStream
1438 * once it has been processed.
1439 */
1440 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001441 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001442 break;
1443 }
1444
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001445 if (!buffer) {
1446 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001447 delete descriptor;
1448 return -ENOMEM;
1449 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001450
Jacopo Mondi216030a2020-10-03 11:36:41 +02001451 request->addBuffer(cameraStream->stream(), buffer);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001452 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001453
Paul Elderc7532232020-09-23 19:05:41 +09001454 int ret = camera_->queueRequest(request.get());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001455 if (ret) {
1456 LOG(HAL, Error) << "Failed to queue request";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001457 delete descriptor;
1458 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001459 }
1460
Paul Elderc7532232020-09-23 19:05:41 +09001461 /* The request will be deleted in the completion handler. */
1462 request.release();
1463
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001464 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001465}
1466
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001467void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001468{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001469 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001470 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001471 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001472 Camera3RequestDescriptor *descriptor =
1473 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001474
1475 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001476 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001477 << request->status();
1478 status = CAMERA3_BUFFER_STATUS_ERROR;
1479 }
1480
Kieran Binghamc09aee42020-07-28 14:01:19 +01001481 /*
1482 * \todo The timestamp used for the metadata is currently always taken
1483 * from the first buffer (which may be the first stream) in the Request.
1484 * It might be appropriate to return a 'correct' (as determined by
1485 * pipeline handlers) timestamp in the Request itself.
1486 */
1487 FrameBuffer *buffer = buffers.begin()->second;
1488 resultMetadata = getResultMetadata(descriptor->frameNumber,
1489 buffer->metadata().timestamp);
1490
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001491 /* Handle any JPEG compression. */
1492 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
1493 CameraStream *cameraStream =
1494 static_cast<CameraStream *>(descriptor->buffers[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001495
Jacopo Mondi160bb092020-10-02 20:48:35 +02001496 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001497 continue;
1498
Jacopo Mondi216030a2020-10-03 11:36:41 +02001499 FrameBuffer *buffer = request->findBuffer(cameraStream->stream());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001500 if (!buffer) {
1501 LOG(HAL, Error) << "Failed to find a source stream buffer";
1502 continue;
1503 }
1504
1505 /*
1506 * \todo Buffer mapping and compression should be moved to a
1507 * separate thread.
1508 */
1509
1510 MappedCamera3Buffer mapped(*descriptor->buffers[i].buffer,
1511 PROT_READ | PROT_WRITE);
1512 if (!mapped.isValid()) {
1513 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1514 continue;
1515 }
1516
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02001517 int ret = cameraStream->process(*buffer, &mapped,
1518 resultMetadata.get());
1519 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001520 status = CAMERA3_BUFFER_STATUS_ERROR;
1521 continue;
1522 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02001523
1524 /*
1525 * Return the FrameBuffer to the CameraStream now that we're
1526 * done processing it.
1527 */
1528 if (cameraStream->type() == CameraStream::Type::Internal)
1529 cameraStream->putBuffer(buffer);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001530 }
1531
1532 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001533 camera3_capture_result_t captureResult = {};
1534 captureResult.frame_number = descriptor->frameNumber;
1535 captureResult.num_output_buffers = descriptor->numBuffers;
1536 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001537 descriptor->buffers[i].acquire_fence = -1;
1538 descriptor->buffers[i].release_fence = -1;
1539 descriptor->buffers[i].status = status;
1540 }
1541 captureResult.output_buffers =
1542 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers);
1543
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001544
Laurent Pinchart39860092019-09-05 03:12:34 +03001545 if (status == CAMERA3_BUFFER_STATUS_OK) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001546 notifyShutter(descriptor->frameNumber,
Niklas Söderlund9217f272019-11-22 16:22:56 +01001547 buffer->metadata().timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001548
1549 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001550 captureResult.result = resultMetadata->get();
1551 }
1552
1553 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1554 /* \todo Improve error handling. In case we notify an error
1555 * because the metadata generation fails, a shutter event has
1556 * already been notified for this frame number before the error
1557 * is here signalled. Make sure the error path plays well with
1558 * the camera stack state machine.
1559 */
1560 notifyError(descriptor->frameNumber,
1561 descriptor->buffers[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001562 }
1563
1564 callbacks_->process_capture_result(callbacks_, &captureResult);
1565
1566 delete descriptor;
Paul Elderc7532232020-09-23 19:05:41 +09001567 delete request;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001568}
1569
Jacopo Mondia7b92772020-05-26 15:41:41 +02001570std::string CameraDevice::logPrefix() const
1571{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001572 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001573}
1574
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001575void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1576{
1577 camera3_notify_msg_t notify = {};
1578
1579 notify.type = CAMERA3_MSG_SHUTTER;
1580 notify.message.shutter.frame_number = frameNumber;
1581 notify.message.shutter.timestamp = timestamp;
1582
1583 callbacks_->notify(callbacks_, &notify);
1584}
1585
1586void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1587{
1588 camera3_notify_msg_t notify = {};
1589
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001590 /*
1591 * \todo Report and identify the stream number or configuration to
1592 * clarify the stream that failed.
1593 */
1594 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1595 << toPixelFormat(stream->format).toString() << ")";
1596
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001597 notify.type = CAMERA3_MSG_ERROR;
1598 notify.message.error.error_stream = stream;
1599 notify.message.error.frame_number = frameNumber;
1600 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1601
1602 callbacks_->notify(callbacks_, &notify);
1603}
1604
1605/*
1606 * Produce a set of fixed result metadata.
1607 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001608std::unique_ptr<CameraMetadata>
1609CameraDevice::getResultMetadata([[maybe_unused]] int frame_number,
1610 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001611{
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001612 /*
1613 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001614 * Currently: 18 entries, 62 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001615 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001616 std::unique_ptr<CameraMetadata> resultMetadata =
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001617 std::make_unique<CameraMetadata>(18, 62);
Laurent Pinchart39860092019-09-05 03:12:34 +03001618 if (!resultMetadata->isValid()) {
1619 LOG(HAL, Error) << "Failed to allocate static metadata";
1620 return nullptr;
1621 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001622
1623 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001624 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001625
1626 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001627 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001628
1629 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001630 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001631
1632 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001633 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001634
1635 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001636 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001637
1638 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001639 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001640
1641 int32_t sensorSizes[] = {
1642 0, 0, 2560, 1920,
1643 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001644 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001645
Laurent Pinchart39860092019-09-05 03:12:34 +03001646 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001647
1648 /* 33.3 msec */
1649 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001650 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1651 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001652
1653 /* 16.6 msec */
1654 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001655 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1656 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001657
1658 const uint8_t lens_shading_map_mode =
1659 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001660 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1661 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001662
1663 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001664 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1665 &scene_flicker, 1);
1666
1667 /*
1668 * Return the result metadata pack even is not valid: get() will return
1669 * nullptr.
1670 */
1671 if (!resultMetadata->isValid()) {
1672 LOG(HAL, Error) << "Failed to construct result metadata";
1673 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001674
1675 return resultMetadata;
1676}