blob: 2cb813879e2753674cdce3712b11f9ea9cf0879f [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 Mondic82f9442020-09-02 11:58:00 +0200172CameraStream::CameraStream(PixelFormat f, Size s, unsigned int i)
173 : format(f), size(s), jpeg(nullptr), index_(i)
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100174{
175}
176
177CameraStream::~CameraStream()
178{
179 delete jpeg;
180};
181
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200182/*
183 * \struct Camera3RequestDescriptor
184 *
185 * A utility structure that groups information about a capture request to be
186 * later re-used at request complete time to notify the framework.
187 */
188
189CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
190 unsigned int frameNumber, unsigned int numBuffers)
191 : frameNumber(frameNumber), numBuffers(numBuffers)
192{
193 buffers = new camera3_stream_buffer_t[numBuffers];
Kieran Bingham0cfdf732020-07-01 13:36:24 +0100194 frameBuffers.reserve(numBuffers);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200195}
196
197CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
198{
199 delete[] buffers;
200}
201
202/*
203 * \class CameraDevice
204 *
205 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200206 * the camera3_device_t interface, bridging calls received from the Android
207 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200208 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200209 * The class translates parameters and operations from the Camera HALv3 API to
210 * the libcamera API to provide static information for a Camera, create request
211 * templates for it, process capture requests and then deliver capture results
212 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200213 */
214
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300215CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000216 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200217 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200218{
219 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100220
221 /*
222 * \todo Determine a more accurate value for this during
223 * streamConfiguration.
224 */
225 maxJpegBufferSize_ = 13 << 20; /* 13631488 from USB HAL */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200226}
227
228CameraDevice::~CameraDevice()
229{
230 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300231 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200232
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200233 for (auto &it : requestTemplates_)
234 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200235}
236
Umang Jainf8e28132020-08-21 14:46:08 +0000237std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
238 const std::shared_ptr<Camera> &cam)
239{
240 CameraDevice *camera = new CameraDevice(id, cam);
241 return std::shared_ptr<CameraDevice>(camera);
242}
243
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200244/*
245 * Initialize the camera static information.
246 * This method is called before the camera device is opened.
247 */
248int CameraDevice::initialize()
249{
250 /* Initialize orientation and facing side of the camera. */
251 const ControlList &properties = camera_->properties();
252
253 if (properties.contains(properties::Location)) {
254 int32_t location = properties.get(properties::Location);
255 switch (location) {
256 case properties::CameraLocationFront:
257 facing_ = CAMERA_FACING_FRONT;
258 break;
259 case properties::CameraLocationBack:
260 facing_ = CAMERA_FACING_BACK;
261 break;
262 case properties::CameraLocationExternal:
263 facing_ = CAMERA_FACING_EXTERNAL;
264 break;
265 }
266 }
267
268 /*
Umang Jaine9176552020-09-09 16:17:54 +0530269 * The Android orientation metadata specifies its rotation correction
270 * value in clockwise direction whereas libcamera specifies the
271 * rotation property in anticlockwise direction. Read the libcamera's
272 * rotation property (anticlockwise) and compute the corresponding
273 * value for clockwise direction as required by the Android orientation
274 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200275 */
Umang Jaine9176552020-09-09 16:17:54 +0530276 if (properties.contains(properties::Rotation)) {
277 int rotation = properties.get(properties::Rotation);
278 orientation_ = (360 - rotation) % 360;
279 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200280
Jacopo Mondi117588b2020-05-23 18:53:54 +0200281 int ret = camera_->acquire();
282 if (ret) {
283 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
284 return ret;
285 }
286
287 ret = initializeStreamConfigurations();
288 camera_->release();
289 return ret;
290}
291
Jacopo Mondibfee6312020-09-01 17:42:13 +0200292std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
293 const PixelFormat &pixelFormat,
294 const std::vector<Size> &resolutions)
295{
296 std::vector<Size> supportedResolutions;
297
298 StreamConfiguration &cfg = cameraConfig->at(0);
299 for (const Size &res : resolutions) {
300 cfg.pixelFormat = pixelFormat;
301 cfg.size = res;
302
303 CameraConfiguration::Status status = cameraConfig->validate();
304 if (status != CameraConfiguration::Valid) {
305 LOG(HAL, Debug) << cfg.toString() << " not supported";
306 continue;
307 }
308
309 LOG(HAL, Debug) << cfg.toString() << " supported";
310
311 supportedResolutions.push_back(res);
312 }
313
314 return supportedResolutions;
315}
316
Jacopo Mondi49610332020-09-01 18:11:34 +0200317std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
318{
319 std::unique_ptr<CameraConfiguration> cameraConfig =
320 camera_->generateConfiguration({ StillCaptureRaw });
321 StreamConfiguration &cfg = cameraConfig->at(0);
322 const StreamFormats &formats = cfg.formats();
323 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
324
325 return supportedResolutions;
326}
327
Jacopo Mondi117588b2020-05-23 18:53:54 +0200328/*
329 * Initialize the format conversion map to translate from Android format
330 * identifier to libcamera pixel formats and fill in the list of supported
331 * stream configurations to be reported to the Android camera framework through
332 * the static stream configuration metadata.
333 */
334int CameraDevice::initializeStreamConfigurations()
335{
336 /*
337 * Get the maximum output resolutions
338 * \todo Get this from the camera properties once defined
339 */
340 std::unique_ptr<CameraConfiguration> cameraConfig =
341 camera_->generateConfiguration({ StillCapture });
342 if (!cameraConfig) {
343 LOG(HAL, Error) << "Failed to get maximum resolution";
344 return -EINVAL;
345 }
346 StreamConfiguration &cfg = cameraConfig->at(0);
347
348 /*
349 * \todo JPEG - Adjust the maximum available resolution by taking the
350 * JPEG encoder requirements into account (alignment and aspect ratio).
351 */
352 const Size maxRes = cfg.size;
353 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
354
355 /*
356 * Build the list of supported image resolutions.
357 *
358 * The resolutions listed in camera3Resolution are mandatory to be
359 * supported, up to the camera maximum resolution.
360 *
361 * Augment the list by adding resolutions calculated from the camera
362 * maximum one.
363 */
364 std::vector<Size> cameraResolutions;
365 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
366 std::back_inserter(cameraResolutions),
367 [&](const Size &res) { return res < maxRes; });
368
369 /*
370 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
371 * resolution.
372 */
373 for (unsigned int divider = 2;; divider <<= 1) {
374 Size derivedSize{
375 maxRes.width / divider,
376 maxRes.height / divider,
377 };
378
379 if (derivedSize.width < 320 ||
380 derivedSize.height < 240)
381 break;
382
383 cameraResolutions.push_back(derivedSize);
384 }
385 cameraResolutions.push_back(maxRes);
386
387 /* Remove duplicated entries from the list of supported resolutions. */
388 std::sort(cameraResolutions.begin(), cameraResolutions.end());
389 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
390 cameraResolutions.erase(last, cameraResolutions.end());
391
392 /*
393 * Build the list of supported camera formats.
394 *
395 * To each Android format a list of compatible libcamera formats is
396 * associated. The first libcamera format that tests successful is added
397 * to the format translation map used when configuring the streams.
398 * It is then tested against the list of supported camera resolutions to
399 * build the stream configuration map reported through the camera static
400 * metadata.
401 */
402 for (const auto &format : camera3FormatsMap) {
403 int androidFormat = format.first;
404 const Camera3Format &camera3Format = format.second;
405 const std::vector<PixelFormat> &libcameraFormats =
406 camera3Format.libcameraFormats;
407
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200408 LOG(HAL, Debug) << "Trying to map Android format "
409 << camera3Format.name;
410
Jacopo Mondi117588b2020-05-23 18:53:54 +0200411 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200412 * JPEG is always supported, either produced directly by the
413 * camera, or encoded in the HAL.
414 */
415 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
416 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200417 LOG(HAL, Debug) << "Mapped Android format "
418 << camera3Format.name << " to "
419 << formats::MJPEG.toString()
420 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200421 continue;
422 }
423
424 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200425 * Test the libcamera formats that can produce images
426 * compatible with the format defined by Android.
427 */
428 PixelFormat mappedFormat;
429 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200430
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200431 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
432
Jacopo Mondi117588b2020-05-23 18:53:54 +0200433 /*
434 * The stream configuration size can be adjusted,
435 * not the pixel format.
436 *
437 * \todo This could be simplified once all pipeline
438 * handlers will report the StreamFormats list of
439 * supported formats.
440 */
441 cfg.pixelFormat = pixelFormat;
442
443 CameraConfiguration::Status status = cameraConfig->validate();
444 if (status != CameraConfiguration::Invalid &&
445 cfg.pixelFormat == pixelFormat) {
446 mappedFormat = pixelFormat;
447 break;
448 }
449 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200450
451 if (!mappedFormat.isValid()) {
452 /* If the format is not mandatory, skip it. */
453 if (!camera3Format.mandatory)
454 continue;
455
456 LOG(HAL, Error)
457 << "Failed to map mandatory Android format "
458 << camera3Format.name << " ("
459 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200460 return -EINVAL;
461 }
462
463 /*
464 * Record the mapping and then proceed to generate the
465 * stream configurations map, by testing the image resolutions.
466 */
467 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200468 LOG(HAL, Debug) << "Mapped Android format "
469 << camera3Format.name << " to "
470 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200471
Jacopo Mondi49610332020-09-01 18:11:34 +0200472 std::vector<Size> resolutions;
473 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
474 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
475 resolutions = getRawResolutions(mappedFormat);
476 else
477 resolutions = getYUVResolutions(cameraConfig.get(),
478 mappedFormat,
479 cameraResolutions);
480
Jacopo Mondibfee6312020-09-01 17:42:13 +0200481 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200482 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200483
484 /*
485 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
486 * from which JPEG is produced, add an entry for
487 * the JPEG stream.
488 *
489 * \todo Wire the JPEG encoder to query the supported
490 * sizes provided a list of formats it can encode.
491 *
492 * \todo Support JPEG streams produced by the Camera
493 * natively.
494 */
495 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888)
496 streamConfigurations_.push_back(
497 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200498 }
499 }
500
501 LOG(HAL, Debug) << "Collected stream configuration map: ";
502 for (const auto &entry : streamConfigurations_)
503 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200504 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200505
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200506 return 0;
507}
508
509/*
510 * Open a camera device. The static information on the camera shall have been
511 * initialized with a call to CameraDevice::initialize().
512 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200513int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200514{
515 int ret = camera_->acquire();
516 if (ret) {
517 LOG(HAL, Error) << "Failed to acquire the camera";
518 return ret;
519 }
520
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200521 /* Initialize the hw_device_t in the instance camera3_module_t. */
522 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
523 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
524 camera3Device_.common.module = (hw_module_t *)hardwareModule;
525 camera3Device_.common.close = hal_dev_close;
526
527 /*
528 * The camera device operations. These actually implement
529 * the Android Camera HALv3 interface.
530 */
531 camera3Device_.ops = &hal_dev_ops;
532 camera3Device_.priv = this;
533
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200534 return 0;
535}
536
537void CameraDevice::close()
538{
539 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200540 camera_->release();
541
542 running_ = false;
543}
544
545void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
546{
547 callbacks_ = callbacks;
548}
549
Jacopo Mondia80d3812020-05-26 12:31:35 +0200550std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
551{
552 /*
553 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100554 * Currently: 51 entries, 687 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200555 */
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100556 uint32_t numEntries = 51;
557 uint32_t byteSize = 687;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200558
559 /*
560 * Calculate space occupation in bytes for dynamically built metadata
561 * entries.
562 *
563 * Each stream configuration entry requires 52 bytes:
564 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200565 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
566 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200567 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200568
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300569 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200570}
571
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200572/*
573 * Return static information for the camera.
574 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200575const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200576{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200577 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300578 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200579
580 /*
581 * The here reported metadata are enough to implement a basic capture
582 * example application, but a real camera implementation will require
583 * more.
584 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200585 uint32_t numEntries;
586 uint32_t byteSize;
587 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
588 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300589 if (!staticMetadata_->isValid()) {
590 LOG(HAL, Error) << "Failed to allocate static metadata";
591 delete staticMetadata_;
592 staticMetadata_ = nullptr;
593 return nullptr;
594 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200595
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200596 /* Color correction static metadata. */
597 std::vector<uint8_t> aberrationModes = {
598 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
599 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300600 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
601 aberrationModes.data(),
602 aberrationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200603
604 /* Control static metadata. */
605 std::vector<uint8_t> aeAvailableAntiBandingModes = {
606 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
607 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
608 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
609 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
610 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300611 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
612 aeAvailableAntiBandingModes.data(),
613 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200614
615 std::vector<uint8_t> aeAvailableModes = {
616 ANDROID_CONTROL_AE_MODE_ON,
617 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300618 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
619 aeAvailableModes.data(),
620 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200621
622 std::vector<int32_t> availableAeFpsTarget = {
623 15, 30,
624 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300625 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
626 availableAeFpsTarget.data(),
627 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200628
629 std::vector<int32_t> aeCompensationRange = {
630 0, 0,
631 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300632 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
633 aeCompensationRange.data(),
634 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200635
636 const camera_metadata_rational_t aeCompensationStep[] = {
637 { 0, 1 }
638 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300639 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
640 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200641
642 std::vector<uint8_t> availableAfModes = {
643 ANDROID_CONTROL_AF_MODE_OFF,
644 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300645 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
646 availableAfModes.data(),
647 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200648
649 std::vector<uint8_t> availableEffects = {
650 ANDROID_CONTROL_EFFECT_MODE_OFF,
651 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300652 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
653 availableEffects.data(),
654 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200655
656 std::vector<uint8_t> availableSceneModes = {
657 ANDROID_CONTROL_SCENE_MODE_DISABLED,
658 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300659 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
660 availableSceneModes.data(),
661 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200662
663 std::vector<uint8_t> availableStabilizationModes = {
664 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
665 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300666 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
667 availableStabilizationModes.data(),
668 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200669
670 std::vector<uint8_t> availableAwbModes = {
671 ANDROID_CONTROL_AWB_MODE_OFF,
672 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300673 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
674 availableAwbModes.data(),
675 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200676
677 std::vector<int32_t> availableMaxRegions = {
678 0, 0, 0,
679 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300680 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
681 availableMaxRegions.data(),
682 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200683
684 std::vector<uint8_t> sceneModesOverride = {
685 ANDROID_CONTROL_AE_MODE_ON,
686 ANDROID_CONTROL_AWB_MODE_AUTO,
687 ANDROID_CONTROL_AF_MODE_AUTO,
688 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300689 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
690 sceneModesOverride.data(),
691 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200692
693 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300694 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
695 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200696
697 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300698 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
699 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200700
701 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300702 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
703 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200704
705 /* JPEG static metadata. */
706 std::vector<int32_t> availableThumbnailSizes = {
707 0, 0,
708 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300709 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
710 availableThumbnailSizes.data(),
711 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200712
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100713 /*
714 * \todo Calculate the maximum JPEG buffer size by asking the encoder
715 * giving the maximum frame size required.
716 */
717 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
718
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200719 /* Sensor static metadata. */
720 int32_t pixelArraySize[] = {
721 2592, 1944,
722 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300723 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
724 &pixelArraySize, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200725
726 int32_t sensorSizes[] = {
727 0, 0, 2560, 1920,
728 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300729 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
730 &sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200731
732 int32_t sensitivityRange[] = {
733 32, 2400,
734 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300735 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
736 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200737
738 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300739 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
740 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200741
742 int64_t exposureTimeRange[] = {
743 100000, 200000000,
744 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300745 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
746 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200747
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200748 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200749
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200750 std::vector<int32_t> testPatterModes = {
751 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
752 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300753 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
754 testPatterModes.data(),
755 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200756
757 std::vector<float> physicalSize = {
758 2592, 1944,
759 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300760 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
761 physicalSize.data(),
762 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200763
764 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300765 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
766 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200767
768 /* Statistics static metadata. */
769 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300770 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
771 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200772
773 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300774 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
775 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200776
777 /* Sync static metadata. */
778 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300779 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200780
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200781 /* Flash static metadata. */
782 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300783 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
784 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200785
786 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200787 std::vector<float> lensApertures = {
788 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200789 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300790 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
791 lensApertures.data(),
792 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200793
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200794 uint8_t lensFacing;
795 switch (facing_) {
796 default:
797 case CAMERA_FACING_FRONT:
798 lensFacing = ANDROID_LENS_FACING_FRONT;
799 break;
800 case CAMERA_FACING_BACK:
801 lensFacing = ANDROID_LENS_FACING_BACK;
802 break;
803 case CAMERA_FACING_EXTERNAL:
804 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
805 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100806 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300807 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200808
809 std::vector<float> lensFocalLenghts = {
810 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200811 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300812 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
813 lensFocalLenghts.data(),
814 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200815
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200816 std::vector<uint8_t> opticalStabilizations = {
817 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
818 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300819 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
820 opticalStabilizations.data(),
821 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200822
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200823 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300824 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
825 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200826
827 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300828 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
829 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200830
831 /* Noise reduction modes. */
832 uint8_t noiseReductionModes = ANDROID_NOISE_REDUCTION_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300833 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
834 &noiseReductionModes, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200835
836 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200837 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300838 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
839 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200840
Jacopo Mondibde7b982020-05-25 17:18:28 +0200841 std::vector<uint32_t> availableStreamConfigurations;
842 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
843 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200844 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200845 availableStreamConfigurations.push_back(entry.resolution.width);
846 availableStreamConfigurations.push_back(entry.resolution.height);
847 availableStreamConfigurations.push_back(
848 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
849 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300850 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
851 availableStreamConfigurations.data(),
852 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200853
854 std::vector<int64_t> availableStallDurations = {
855 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
856 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300857 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
858 availableStallDurations.data(),
859 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200860
Jacopo Mondibde7b982020-05-25 17:18:28 +0200861 /* \todo Collect the minimum frame duration from the camera. */
862 std::vector<int64_t> minFrameDurations;
863 minFrameDurations.reserve(streamConfigurations_.size() * 4);
864 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200865 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200866 minFrameDurations.push_back(entry.resolution.width);
867 minFrameDurations.push_back(entry.resolution.height);
868 minFrameDurations.push_back(33333333);
869 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300870 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
871 minFrameDurations.data(),
872 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200873
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200874 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300875 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200876
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200877 /* Info static metadata. */
878 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300879 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
880 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200881
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200882 /* Request static metadata. */
883 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300884 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
885 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200886
887 uint8_t maxPipelineDepth = 2;
Laurent Pinchart39860092019-09-05 03:12:34 +0300888 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
889 &maxPipelineDepth, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200890
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200891 /* LIMITED does not support reprocessing. */
892 uint32_t maxNumInputStreams = 0;
893 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
894 &maxNumInputStreams, 1);
895
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200896 std::vector<uint8_t> availableCapabilities = {
897 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
898 };
Niklas Söderlund7876d632020-07-21 00:16:24 +0200899
900 /* Report if camera supports RAW. */
901 std::unique_ptr<CameraConfiguration> cameraConfig =
902 camera_->generateConfiguration({ StillCaptureRaw });
903 if (cameraConfig && !cameraConfig->empty()) {
904 const PixelFormatInfo &info =
905 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
906 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
907 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
908 }
909
Laurent Pinchart39860092019-09-05 03:12:34 +0300910 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
911 availableCapabilities.data(),
912 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200913
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200914 std::vector<int32_t> availableCharacteristicsKeys = {
915 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
916 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
917 ANDROID_CONTROL_AE_AVAILABLE_MODES,
918 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
919 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
920 ANDROID_CONTROL_AE_COMPENSATION_STEP,
921 ANDROID_CONTROL_AF_AVAILABLE_MODES,
922 ANDROID_CONTROL_AVAILABLE_EFFECTS,
923 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
924 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
925 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
926 ANDROID_CONTROL_MAX_REGIONS,
927 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
928 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
929 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
930 ANDROID_CONTROL_AVAILABLE_MODES,
931 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100932 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200933 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
934 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
935 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
936 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
937 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
938 ANDROID_SENSOR_ORIENTATION,
939 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
940 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
941 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
942 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
943 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
944 ANDROID_SYNC_MAX_LATENCY,
945 ANDROID_FLASH_INFO_AVAILABLE,
946 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
947 ANDROID_LENS_FACING,
948 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
949 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
950 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
951 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
952 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
953 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200954 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
955 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
956 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
957 ANDROID_SCALER_CROPPING_TYPE,
958 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
959 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
960 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200961 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200962 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
963 };
964 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
965 availableCharacteristicsKeys.data(),
966 availableCharacteristicsKeys.size());
967
968 std::vector<int32_t> availableRequestKeys = {
969 ANDROID_CONTROL_AE_MODE,
970 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
971 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200972 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
973 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200974 ANDROID_CONTROL_AE_LOCK,
975 ANDROID_CONTROL_AF_TRIGGER,
976 ANDROID_CONTROL_AWB_MODE,
977 ANDROID_CONTROL_AWB_LOCK,
978 ANDROID_FLASH_MODE,
979 ANDROID_STATISTICS_FACE_DETECT_MODE,
980 ANDROID_NOISE_REDUCTION_MODE,
981 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200982 ANDROID_LENS_APERTURE,
983 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
984 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200985 ANDROID_CONTROL_CAPTURE_INTENT,
986 };
987 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
988 availableRequestKeys.data(),
989 availableRequestKeys.size());
990
991 std::vector<int32_t> availableResultKeys = {
992 ANDROID_CONTROL_AE_STATE,
993 ANDROID_CONTROL_AE_LOCK,
994 ANDROID_CONTROL_AF_STATE,
995 ANDROID_CONTROL_AWB_STATE,
996 ANDROID_CONTROL_AWB_LOCK,
997 ANDROID_LENS_STATE,
998 ANDROID_SCALER_CROP_REGION,
999 ANDROID_SENSOR_TIMESTAMP,
1000 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1001 ANDROID_SENSOR_EXPOSURE_TIME,
1002 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1003 ANDROID_STATISTICS_SCENE_FLICKER,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001004 ANDROID_JPEG_SIZE,
1005 ANDROID_JPEG_QUALITY,
1006 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001007 };
1008 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1009 availableResultKeys.data(),
1010 availableResultKeys.size());
1011
Laurent Pinchart39860092019-09-05 03:12:34 +03001012 if (!staticMetadata_->isValid()) {
1013 LOG(HAL, Error) << "Failed to construct static metadata";
1014 delete staticMetadata_;
1015 staticMetadata_ = nullptr;
1016 return nullptr;
1017 }
1018
1019 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001020}
1021
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001022CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001023{
Jacopo Mondi63703472019-09-04 16:18:22 +02001024 /*
1025 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001026 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001027 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001028 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001029 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001030 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001031 return nullptr;
1032 }
1033
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001034 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001035 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1036 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001037
1038 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001039 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1040 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001041
1042 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001043 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1044 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001045
1046 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001047 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1048 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001049
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001050 std::vector<int32_t> aeFpsTarget = {
1051 15, 30,
1052 };
1053 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1054 aeFpsTarget.data(),
1055 aeFpsTarget.size());
1056
1057 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1058 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1059 &aeAntibandingMode, 1);
1060
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001061 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001062 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1063 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001064
1065 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001066 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1067 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001068
1069 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001070 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1071 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001072
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001073 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001074 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1075 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001076
1077 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001078 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1079 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001080
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001081 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001082 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1083 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001084
1085 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001086 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1087 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001088
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001089 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1090 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1091
1092 float lensAperture = 2.53 / 100;
1093 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1094
1095 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1096 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1097 &opticalStabilization, 1);
1098
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001099 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001100 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1101 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001102
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001103 return requestTemplate;
1104}
1105
1106/*
1107 * Produce a metadata pack to be used as template for a capture request.
1108 */
1109const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1110{
1111 auto it = requestTemplates_.find(type);
1112 if (it != requestTemplates_.end())
1113 return it->second->get();
1114
1115 /* Use the capture intent matching the requested template type. */
1116 CameraMetadata *requestTemplate;
1117 uint8_t captureIntent;
1118 switch (type) {
1119 case CAMERA3_TEMPLATE_PREVIEW:
1120 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1121 break;
1122 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1123 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1124 break;
1125 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1126 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1127 break;
1128 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1129 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1130 break;
1131 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1132 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1133 break;
1134 case CAMERA3_TEMPLATE_MANUAL:
1135 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1136 break;
1137 default:
1138 LOG(HAL, Error) << "Invalid template request type: " << type;
1139 return nullptr;
1140 }
1141
1142 requestTemplate = requestTemplatePreview();
1143 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001144 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001145 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001146 return nullptr;
1147 }
1148
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001149 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1150 &captureIntent, 1);
1151
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001152 requestTemplates_[type] = requestTemplate;
1153 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001154}
1155
Kieran Bingham43e3b802020-06-26 09:58:49 +01001156PixelFormat CameraDevice::toPixelFormat(int format)
1157{
1158 /* Translate Android format code to libcamera pixel format. */
1159 auto it = formatsMap_.find(format);
1160 if (it == formatsMap_.end()) {
1161 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1162 << " not supported";
1163 return PixelFormat();
1164 }
1165
1166 return it->second;
1167}
1168
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001169/*
1170 * Inspect the stream_list to produce a list of StreamConfiguration to
1171 * be use to configure the Camera.
1172 */
1173int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1174{
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001175 /*
1176 * Generate an empty configuration, and construct a StreamConfiguration
1177 * for each camera3_stream to add to it.
1178 */
1179 config_ = camera_->generateConfiguration();
1180 if (!config_) {
1181 LOG(HAL, Error) << "Failed to generate camera configuration";
1182 return -EINVAL;
1183 }
1184
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001185 /*
1186 * Clear and remove any existing configuration from previous calls, and
1187 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001188 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001189 */
1190 streams_.clear();
1191 streams_.reserve(stream_list->num_streams);
1192
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001193 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001194 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001195 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1196 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001197 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001198
Kieran Bingham43e3b802020-06-26 09:58:49 +01001199 PixelFormat format = toPixelFormat(stream->format);
1200
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001201 LOG(HAL, Info) << "Stream #" << i
1202 << ", direction: " << stream->stream_type
1203 << ", width: " << stream->width
1204 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001205 << ", format: " << utils::hex(stream->format)
1206 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001207
1208 if (!format.isValid())
1209 return -EINVAL;
1210
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001211 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001212 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1213 if (jpegStream) {
1214 LOG(HAL, Error)
1215 << "Multiple JPEG streams are not supported";
1216 return -EINVAL;
1217 }
1218
1219 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001220 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001221 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001222
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001223 StreamConfiguration streamConfiguration;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001224 streamConfiguration.size = size;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001225 streamConfiguration.pixelFormat = format;
1226
1227 config_->addConfiguration(streamConfiguration);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001228 unsigned int index = config_->size() - 1;
1229 streams_.emplace_back(format, size, index);
1230 stream->priv = static_cast<void *>(&streams_.back());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001231 }
1232
Jacopo Mondic82f9442020-09-02 11:58:00 +02001233 /* Now handle the MJPEG streams, adding a new stream if required. */
1234 if (jpegStream) {
1235 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001236
Jacopo Mondic82f9442020-09-02 11:58:00 +02001237 /* Search for a compatible stream in the non-JPEG ones. */
1238 for (unsigned int i = 0; i < config_->size(); i++) {
1239 StreamConfiguration &cfg = config_->at(i);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001240
1241 /*
1242 * \todo The PixelFormat must also be compatible with
1243 * the encoder.
1244 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001245 if (cfg.size.width != jpegStream->width ||
1246 cfg.size.height != jpegStream->height)
1247 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001248
Jacopo Mondic82f9442020-09-02 11:58:00 +02001249 LOG(HAL, Info)
1250 << "Android JPEG stream mapped to libcamera stream " << i;
1251
1252 index = i;
1253 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001254 }
1255
1256 /*
1257 * Without a compatible match for JPEG encoding we must
1258 * introduce a new stream to satisfy the request requirements.
1259 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001260 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001261 StreamConfiguration streamConfiguration;
1262
1263 /*
1264 * \todo The pixelFormat should be a 'best-fit' choice
1265 * and may require a validation cycle. This is not yet
1266 * handled, and should be considered as part of any
1267 * stream configuration reworks.
1268 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001269 streamConfiguration.size.width = jpegStream->width;
1270 streamConfiguration.size.height = jpegStream->height;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001271 streamConfiguration.pixelFormat = formats::NV12;
1272
1273 LOG(HAL, Info) << "Adding " << streamConfiguration.toString()
1274 << " for MJPEG support";
1275
1276 config_->addConfiguration(streamConfiguration);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001277 index = config_->size() - 1;
1278 }
1279
1280 StreamConfiguration &cfg = config_->at(index);
1281 CameraStream &cameraStream =
1282 streams_.emplace_back(formats::MJPEG, cfg.size, index);
1283 jpegStream->priv = static_cast<void *>(&cameraStream);
1284
1285 /*
1286 * Construct a software encoder for the MJPEG streams from the
1287 * chosen libcamera source stream.
1288 */
1289 cameraStream.jpeg = new EncoderLibJpeg();
1290 int ret = cameraStream.jpeg->configure(cfg);
1291 if (ret) {
1292 LOG(HAL, Error) << "Failed to configure encoder";
1293 return ret;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001294 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001295 }
1296
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001297 switch (config_->validate()) {
1298 case CameraConfiguration::Valid:
1299 break;
1300 case CameraConfiguration::Adjusted:
1301 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001302
1303 for (const StreamConfiguration &cfg : *config_)
1304 LOG(HAL, Info) << " - " << cfg.toString();
1305
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001306 config_.reset();
1307 return -EINVAL;
1308 case CameraConfiguration::Invalid:
1309 LOG(HAL, Info) << "Camera configuration invalid";
1310 config_.reset();
1311 return -EINVAL;
1312 }
1313
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001314 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1315 camera3_stream_t *stream = stream_list->streams[i];
Jacopo Mondic82f9442020-09-02 11:58:00 +02001316 CameraStream *cameraStream = static_cast<CameraStream *>(stream->priv);
1317 StreamConfiguration &cfg = config_->at(cameraStream->index());
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001318
1319 /* Use the bufferCount confirmed by the validation process. */
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001320 stream->max_buffers = cfg.bufferCount;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001321 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001322
1323 /*
1324 * Once the CameraConfiguration has been adjusted/validated
1325 * it can be applied to the camera.
1326 */
1327 int ret = camera_->configure(config_.get());
1328 if (ret) {
1329 LOG(HAL, Error) << "Failed to configure camera '"
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001330 << camera_->id() << "'";
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001331 return ret;
1332 }
1333
1334 return 0;
1335}
1336
Kieran Bingham74ab4422020-07-01 13:25:38 +01001337FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1338{
1339 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001340 for (int i = 0; i < camera3buffer->numFds; i++) {
1341 /* Skip unused planes. */
1342 if (camera3buffer->data[i] == -1)
1343 break;
1344
Kieran Bingham74ab4422020-07-01 13:25:38 +01001345 FrameBuffer::Plane plane;
1346 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001347 if (!plane.fd.isValid()) {
1348 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1349 << camera3buffer->data[i] << ") "
1350 << " on plane " << i;
1351 return nullptr;
1352 }
1353
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001354 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1355 if (length == -1) {
1356 LOG(HAL, Error) << "Failed to query plane length";
1357 return nullptr;
1358 }
1359
1360 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001361 planes.push_back(std::move(plane));
1362 }
1363
1364 return new FrameBuffer(std::move(planes));
1365}
1366
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001367int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001368{
Kieran Bingham61f42962020-07-01 13:40:17 +01001369 if (!camera3Request->num_output_buffers) {
1370 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001371 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001372 }
1373
1374 /* Start the camera if that's the first request we handle. */
1375 if (!running_) {
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001376 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001377 if (ret) {
1378 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001379 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001380 }
1381
1382 running_ = true;
1383 }
1384
1385 /*
1386 * Queue a request for the Camera with the provided dmabuf file
1387 * descriptors.
1388 */
1389 const camera3_stream_buffer_t *camera3Buffers =
1390 camera3Request->output_buffers;
1391
1392 /*
1393 * Save the request descriptors for use at completion time.
1394 * The descriptor and the associated memory reserved here are freed
1395 * at request complete time.
1396 */
1397 Camera3RequestDescriptor *descriptor =
1398 new Camera3RequestDescriptor(camera3Request->frame_number,
1399 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001400
1401 Request *request =
1402 camera_->createRequest(reinterpret_cast<uint64_t>(descriptor));
1403
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001404 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001405 CameraStream *cameraStream =
1406 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1407
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001408 /*
1409 * Keep track of which stream the request belongs to and store
1410 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001411 */
1412 descriptor->buffers[i].stream = camera3Buffers[i].stream;
1413 descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001414
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001415 /* Software streams are handled after hardware streams complete. */
1416 if (cameraStream->format == formats::MJPEG)
1417 continue;
1418
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001419 /*
1420 * Create a libcamera buffer using the dmabuf descriptors of
1421 * the camera3Buffer for each stream. The FrameBuffer is
1422 * directly associated with the Camera3RequestDescriptor for
1423 * lifetime management only.
1424 */
1425 FrameBuffer *buffer = createFrameBuffer(*camera3Buffers[i].buffer);
1426 if (!buffer) {
1427 LOG(HAL, Error) << "Failed to create buffer";
1428 delete request;
1429 delete descriptor;
1430 return -ENOMEM;
1431 }
1432 descriptor->frameBuffers.emplace_back(buffer);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001433
Jacopo Mondic82f9442020-09-02 11:58:00 +02001434 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index());
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001435 Stream *stream = streamConfiguration->stream();
1436
1437 request->addBuffer(stream, buffer);
1438 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001439
1440 int ret = camera_->queueRequest(request);
1441 if (ret) {
1442 LOG(HAL, Error) << "Failed to queue request";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001443 delete request;
1444 delete descriptor;
1445 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001446 }
1447
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001448 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001449}
1450
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001451void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001452{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001453 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001454 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001455 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001456 Camera3RequestDescriptor *descriptor =
1457 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001458
1459 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001460 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001461 << request->status();
1462 status = CAMERA3_BUFFER_STATUS_ERROR;
1463 }
1464
Kieran Binghamc09aee42020-07-28 14:01:19 +01001465 /*
1466 * \todo The timestamp used for the metadata is currently always taken
1467 * from the first buffer (which may be the first stream) in the Request.
1468 * It might be appropriate to return a 'correct' (as determined by
1469 * pipeline handlers) timestamp in the Request itself.
1470 */
1471 FrameBuffer *buffer = buffers.begin()->second;
1472 resultMetadata = getResultMetadata(descriptor->frameNumber,
1473 buffer->metadata().timestamp);
1474
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001475 /* Handle any JPEG compression. */
1476 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
1477 CameraStream *cameraStream =
1478 static_cast<CameraStream *>(descriptor->buffers[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001479
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001480 if (cameraStream->format != formats::MJPEG)
1481 continue;
1482
1483 Encoder *encoder = cameraStream->jpeg;
1484 if (!encoder) {
1485 LOG(HAL, Error) << "Failed to identify encoder";
1486 continue;
1487 }
1488
Jacopo Mondic82f9442020-09-02 11:58:00 +02001489 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001490 Stream *stream = streamConfiguration->stream();
1491 FrameBuffer *buffer = request->findBuffer(stream);
1492 if (!buffer) {
1493 LOG(HAL, Error) << "Failed to find a source stream buffer";
1494 continue;
1495 }
1496
1497 /*
1498 * \todo Buffer mapping and compression should be moved to a
1499 * separate thread.
1500 */
1501
1502 MappedCamera3Buffer mapped(*descriptor->buffers[i].buffer,
1503 PROT_READ | PROT_WRITE);
1504 if (!mapped.isValid()) {
1505 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1506 continue;
1507 }
1508
Umang Jain6f09a612020-09-09 16:44:45 +05301509 /* Set EXIF metadata for various tags. */
1510 Exif exif;
1511 /* \todo Set Make and Model from external vendor tags. */
1512 exif.setMake("libcamera");
1513 exif.setModel("cameraModel");
1514 exif.setOrientation(orientation_);
1515 exif.setSize(cameraStream->size);
1516 /*
1517 * We set the frame's EXIF timestamp as the time of encode.
1518 * Since the precision we need for EXIF timestamp is only one
1519 * second, it is good enough.
1520 */
1521 exif.setTimestamp(std::time(nullptr));
1522 if (exif.generate() != 0)
1523 LOG(HAL, Error) << "Failed to generate valid EXIF data";
1524
1525 int jpeg_size = encoder->encode(buffer, mapped.maps()[0], exif.data());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001526 if (jpeg_size < 0) {
1527 LOG(HAL, Error) << "Failed to encode stream image";
1528 status = CAMERA3_BUFFER_STATUS_ERROR;
1529 continue;
1530 }
1531
1532 /*
1533 * Fill in the JPEG blob header.
1534 *
1535 * The mapped size of the buffer is being returned as
1536 * substantially larger than the requested JPEG_MAX_SIZE
1537 * (which is referenced from maxJpegBufferSize_). Utilise
1538 * this static size to ensure the correct offset of the blob is
1539 * determined.
1540 *
1541 * \todo Investigate if the buffer size mismatch is an issue or
1542 * expected behaviour.
1543 */
1544 uint8_t *resultPtr = mapped.maps()[0].data() +
1545 maxJpegBufferSize_ -
1546 sizeof(struct camera3_jpeg_blob);
1547 auto *blob = reinterpret_cast<struct camera3_jpeg_blob *>(resultPtr);
1548 blob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
1549 blob->jpeg_size = jpeg_size;
1550
1551 /* Update the JPEG result Metadata. */
1552 resultMetadata->addEntry(ANDROID_JPEG_SIZE,
1553 &jpeg_size, 1);
1554
1555 const uint32_t jpeg_quality = 95;
1556 resultMetadata->addEntry(ANDROID_JPEG_QUALITY,
1557 &jpeg_quality, 1);
1558
1559 const uint32_t jpeg_orientation = 0;
1560 resultMetadata->addEntry(ANDROID_JPEG_ORIENTATION,
1561 &jpeg_orientation, 1);
1562 }
1563
1564 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001565 camera3_capture_result_t captureResult = {};
1566 captureResult.frame_number = descriptor->frameNumber;
1567 captureResult.num_output_buffers = descriptor->numBuffers;
1568 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001569 descriptor->buffers[i].acquire_fence = -1;
1570 descriptor->buffers[i].release_fence = -1;
1571 descriptor->buffers[i].status = status;
1572 }
1573 captureResult.output_buffers =
1574 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers);
1575
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001576
Laurent Pinchart39860092019-09-05 03:12:34 +03001577 if (status == CAMERA3_BUFFER_STATUS_OK) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001578 notifyShutter(descriptor->frameNumber,
Niklas Söderlund9217f272019-11-22 16:22:56 +01001579 buffer->metadata().timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001580
1581 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001582 captureResult.result = resultMetadata->get();
1583 }
1584
1585 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1586 /* \todo Improve error handling. In case we notify an error
1587 * because the metadata generation fails, a shutter event has
1588 * already been notified for this frame number before the error
1589 * is here signalled. Make sure the error path plays well with
1590 * the camera stack state machine.
1591 */
1592 notifyError(descriptor->frameNumber,
1593 descriptor->buffers[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001594 }
1595
1596 callbacks_->process_capture_result(callbacks_, &captureResult);
1597
1598 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001599}
1600
Jacopo Mondia7b92772020-05-26 15:41:41 +02001601std::string CameraDevice::logPrefix() const
1602{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001603 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001604}
1605
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001606void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1607{
1608 camera3_notify_msg_t notify = {};
1609
1610 notify.type = CAMERA3_MSG_SHUTTER;
1611 notify.message.shutter.frame_number = frameNumber;
1612 notify.message.shutter.timestamp = timestamp;
1613
1614 callbacks_->notify(callbacks_, &notify);
1615}
1616
1617void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1618{
1619 camera3_notify_msg_t notify = {};
1620
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001621 /*
1622 * \todo Report and identify the stream number or configuration to
1623 * clarify the stream that failed.
1624 */
1625 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1626 << toPixelFormat(stream->format).toString() << ")";
1627
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001628 notify.type = CAMERA3_MSG_ERROR;
1629 notify.message.error.error_stream = stream;
1630 notify.message.error.frame_number = frameNumber;
1631 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1632
1633 callbacks_->notify(callbacks_, &notify);
1634}
1635
1636/*
1637 * Produce a set of fixed result metadata.
1638 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001639std::unique_ptr<CameraMetadata>
1640CameraDevice::getResultMetadata([[maybe_unused]] int frame_number,
1641 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001642{
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001643 /*
1644 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001645 * Currently: 18 entries, 62 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001646 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001647 std::unique_ptr<CameraMetadata> resultMetadata =
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001648 std::make_unique<CameraMetadata>(18, 62);
Laurent Pinchart39860092019-09-05 03:12:34 +03001649 if (!resultMetadata->isValid()) {
1650 LOG(HAL, Error) << "Failed to allocate static metadata";
1651 return nullptr;
1652 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001653
1654 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001655 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001656
1657 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001658 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001659
1660 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001661 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001662
1663 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001664 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001665
1666 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001667 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001668
1669 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001670 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001671
1672 int32_t sensorSizes[] = {
1673 0, 0, 2560, 1920,
1674 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001675 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001676
Laurent Pinchart39860092019-09-05 03:12:34 +03001677 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001678
1679 /* 33.3 msec */
1680 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001681 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1682 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001683
1684 /* 16.6 msec */
1685 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001686 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1687 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001688
1689 const uint8_t lens_shading_map_mode =
1690 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001691 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1692 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001693
1694 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001695 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1696 &scene_flicker, 1);
1697
1698 /*
1699 * Return the result metadata pack even is not valid: get() will return
1700 * nullptr.
1701 */
1702 if (!resultMetadata->isValid()) {
1703 LOG(HAL, Error) << "Failed to construct result metadata";
1704 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001705
1706 return resultMetadata;
1707}