blob: 68970eb4a94c3d841685d706c52409948f0daa8a [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 Mondi667d8ea2019-05-10 17:40:02 +0200172/*
173 * \struct Camera3RequestDescriptor
174 *
175 * A utility structure that groups information about a capture request to be
176 * later re-used at request complete time to notify the framework.
177 */
178
179CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
180 unsigned int frameNumber, unsigned int numBuffers)
181 : frameNumber(frameNumber), numBuffers(numBuffers)
182{
183 buffers = new camera3_stream_buffer_t[numBuffers];
Kieran Bingham0cfdf732020-07-01 13:36:24 +0100184 frameBuffers.reserve(numBuffers);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200185}
186
187CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
188{
189 delete[] buffers;
190}
191
192/*
193 * \class CameraDevice
194 *
195 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200196 * the camera3_device_t interface, bridging calls received from the Android
197 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200198 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200199 * The class translates parameters and operations from the Camera HALv3 API to
200 * the libcamera API to provide static information for a Camera, create request
201 * templates for it, process capture requests and then deliver capture results
202 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200203 */
204
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300205CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000206 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200207 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200208{
209 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100210
211 /*
212 * \todo Determine a more accurate value for this during
213 * streamConfiguration.
214 */
215 maxJpegBufferSize_ = 13 << 20; /* 13631488 from USB HAL */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200216}
217
218CameraDevice::~CameraDevice()
219{
220 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300221 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200222
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200223 for (auto &it : requestTemplates_)
224 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200225}
226
Umang Jainf8e28132020-08-21 14:46:08 +0000227std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
228 const std::shared_ptr<Camera> &cam)
229{
230 CameraDevice *camera = new CameraDevice(id, cam);
231 return std::shared_ptr<CameraDevice>(camera);
232}
233
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200234/*
235 * Initialize the camera static information.
236 * This method is called before the camera device is opened.
237 */
238int CameraDevice::initialize()
239{
240 /* Initialize orientation and facing side of the camera. */
241 const ControlList &properties = camera_->properties();
242
243 if (properties.contains(properties::Location)) {
244 int32_t location = properties.get(properties::Location);
245 switch (location) {
246 case properties::CameraLocationFront:
247 facing_ = CAMERA_FACING_FRONT;
248 break;
249 case properties::CameraLocationBack:
250 facing_ = CAMERA_FACING_BACK;
251 break;
252 case properties::CameraLocationExternal:
253 facing_ = CAMERA_FACING_EXTERNAL;
254 break;
255 }
256 }
257
258 /*
Umang Jaine9176552020-09-09 16:17:54 +0530259 * The Android orientation metadata specifies its rotation correction
260 * value in clockwise direction whereas libcamera specifies the
261 * rotation property in anticlockwise direction. Read the libcamera's
262 * rotation property (anticlockwise) and compute the corresponding
263 * value for clockwise direction as required by the Android orientation
264 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200265 */
Umang Jaine9176552020-09-09 16:17:54 +0530266 if (properties.contains(properties::Rotation)) {
267 int rotation = properties.get(properties::Rotation);
268 orientation_ = (360 - rotation) % 360;
269 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200270
Jacopo Mondi117588b2020-05-23 18:53:54 +0200271 int ret = camera_->acquire();
272 if (ret) {
273 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
274 return ret;
275 }
276
277 ret = initializeStreamConfigurations();
278 camera_->release();
279 return ret;
280}
281
Jacopo Mondibfee6312020-09-01 17:42:13 +0200282std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
283 const PixelFormat &pixelFormat,
284 const std::vector<Size> &resolutions)
285{
286 std::vector<Size> supportedResolutions;
287
288 StreamConfiguration &cfg = cameraConfig->at(0);
289 for (const Size &res : resolutions) {
290 cfg.pixelFormat = pixelFormat;
291 cfg.size = res;
292
293 CameraConfiguration::Status status = cameraConfig->validate();
294 if (status != CameraConfiguration::Valid) {
295 LOG(HAL, Debug) << cfg.toString() << " not supported";
296 continue;
297 }
298
299 LOG(HAL, Debug) << cfg.toString() << " supported";
300
301 supportedResolutions.push_back(res);
302 }
303
304 return supportedResolutions;
305}
306
Jacopo Mondi49610332020-09-01 18:11:34 +0200307std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
308{
309 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200310 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200311 StreamConfiguration &cfg = cameraConfig->at(0);
312 const StreamFormats &formats = cfg.formats();
313 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
314
315 return supportedResolutions;
316}
317
Jacopo Mondi117588b2020-05-23 18:53:54 +0200318/*
319 * Initialize the format conversion map to translate from Android format
320 * identifier to libcamera pixel formats and fill in the list of supported
321 * stream configurations to be reported to the Android camera framework through
322 * the static stream configuration metadata.
323 */
324int CameraDevice::initializeStreamConfigurations()
325{
326 /*
327 * Get the maximum output resolutions
328 * \todo Get this from the camera properties once defined
329 */
330 std::unique_ptr<CameraConfiguration> cameraConfig =
331 camera_->generateConfiguration({ StillCapture });
332 if (!cameraConfig) {
333 LOG(HAL, Error) << "Failed to get maximum resolution";
334 return -EINVAL;
335 }
336 StreamConfiguration &cfg = cameraConfig->at(0);
337
338 /*
339 * \todo JPEG - Adjust the maximum available resolution by taking the
340 * JPEG encoder requirements into account (alignment and aspect ratio).
341 */
342 const Size maxRes = cfg.size;
343 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
344
345 /*
346 * Build the list of supported image resolutions.
347 *
348 * The resolutions listed in camera3Resolution are mandatory to be
349 * supported, up to the camera maximum resolution.
350 *
351 * Augment the list by adding resolutions calculated from the camera
352 * maximum one.
353 */
354 std::vector<Size> cameraResolutions;
355 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
356 std::back_inserter(cameraResolutions),
357 [&](const Size &res) { return res < maxRes; });
358
359 /*
360 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
361 * resolution.
362 */
363 for (unsigned int divider = 2;; divider <<= 1) {
364 Size derivedSize{
365 maxRes.width / divider,
366 maxRes.height / divider,
367 };
368
369 if (derivedSize.width < 320 ||
370 derivedSize.height < 240)
371 break;
372
373 cameraResolutions.push_back(derivedSize);
374 }
375 cameraResolutions.push_back(maxRes);
376
377 /* Remove duplicated entries from the list of supported resolutions. */
378 std::sort(cameraResolutions.begin(), cameraResolutions.end());
379 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
380 cameraResolutions.erase(last, cameraResolutions.end());
381
382 /*
383 * Build the list of supported camera formats.
384 *
385 * To each Android format a list of compatible libcamera formats is
386 * associated. The first libcamera format that tests successful is added
387 * to the format translation map used when configuring the streams.
388 * It is then tested against the list of supported camera resolutions to
389 * build the stream configuration map reported through the camera static
390 * metadata.
391 */
392 for (const auto &format : camera3FormatsMap) {
393 int androidFormat = format.first;
394 const Camera3Format &camera3Format = format.second;
395 const std::vector<PixelFormat> &libcameraFormats =
396 camera3Format.libcameraFormats;
397
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200398 LOG(HAL, Debug) << "Trying to map Android format "
399 << camera3Format.name;
400
Jacopo Mondi117588b2020-05-23 18:53:54 +0200401 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200402 * JPEG is always supported, either produced directly by the
403 * camera, or encoded in the HAL.
404 */
405 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
406 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200407 LOG(HAL, Debug) << "Mapped Android format "
408 << camera3Format.name << " to "
409 << formats::MJPEG.toString()
410 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200411 continue;
412 }
413
414 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200415 * Test the libcamera formats that can produce images
416 * compatible with the format defined by Android.
417 */
418 PixelFormat mappedFormat;
419 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200420
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200421 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
422
Jacopo Mondi117588b2020-05-23 18:53:54 +0200423 /*
424 * The stream configuration size can be adjusted,
425 * not the pixel format.
426 *
427 * \todo This could be simplified once all pipeline
428 * handlers will report the StreamFormats list of
429 * supported formats.
430 */
431 cfg.pixelFormat = pixelFormat;
432
433 CameraConfiguration::Status status = cameraConfig->validate();
434 if (status != CameraConfiguration::Invalid &&
435 cfg.pixelFormat == pixelFormat) {
436 mappedFormat = pixelFormat;
437 break;
438 }
439 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200440
441 if (!mappedFormat.isValid()) {
442 /* If the format is not mandatory, skip it. */
443 if (!camera3Format.mandatory)
444 continue;
445
446 LOG(HAL, Error)
447 << "Failed to map mandatory Android format "
448 << camera3Format.name << " ("
449 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200450 return -EINVAL;
451 }
452
453 /*
454 * Record the mapping and then proceed to generate the
455 * stream configurations map, by testing the image resolutions.
456 */
457 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200458 LOG(HAL, Debug) << "Mapped Android format "
459 << camera3Format.name << " to "
460 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200461
Jacopo Mondi49610332020-09-01 18:11:34 +0200462 std::vector<Size> resolutions;
463 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
464 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
465 resolutions = getRawResolutions(mappedFormat);
466 else
467 resolutions = getYUVResolutions(cameraConfig.get(),
468 mappedFormat,
469 cameraResolutions);
470
Jacopo Mondibfee6312020-09-01 17:42:13 +0200471 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200472 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200473
474 /*
475 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
476 * from which JPEG is produced, add an entry for
477 * the JPEG stream.
478 *
479 * \todo Wire the JPEG encoder to query the supported
480 * sizes provided a list of formats it can encode.
481 *
482 * \todo Support JPEG streams produced by the Camera
483 * natively.
484 */
485 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888)
486 streamConfigurations_.push_back(
487 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200488 }
489 }
490
491 LOG(HAL, Debug) << "Collected stream configuration map: ";
492 for (const auto &entry : streamConfigurations_)
493 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200494 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200495
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200496 return 0;
497}
498
499/*
500 * Open a camera device. The static information on the camera shall have been
501 * initialized with a call to CameraDevice::initialize().
502 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200503int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200504{
505 int ret = camera_->acquire();
506 if (ret) {
507 LOG(HAL, Error) << "Failed to acquire the camera";
508 return ret;
509 }
510
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200511 /* Initialize the hw_device_t in the instance camera3_module_t. */
512 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
513 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
514 camera3Device_.common.module = (hw_module_t *)hardwareModule;
515 camera3Device_.common.close = hal_dev_close;
516
517 /*
518 * The camera device operations. These actually implement
519 * the Android Camera HALv3 interface.
520 */
521 camera3Device_.ops = &hal_dev_ops;
522 camera3Device_.priv = this;
523
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200524 return 0;
525}
526
527void CameraDevice::close()
528{
529 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200530 camera_->release();
531
532 running_ = false;
533}
534
535void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
536{
537 callbacks_ = callbacks;
538}
539
Jacopo Mondia80d3812020-05-26 12:31:35 +0200540std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
541{
542 /*
543 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100544 * Currently: 51 entries, 687 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200545 */
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100546 uint32_t numEntries = 51;
547 uint32_t byteSize = 687;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200548
549 /*
550 * Calculate space occupation in bytes for dynamically built metadata
551 * entries.
552 *
553 * Each stream configuration entry requires 52 bytes:
554 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200555 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
556 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200557 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200558
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300559 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200560}
561
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200562/*
563 * Return static information for the camera.
564 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200565const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200566{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200567 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300568 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200569
570 /*
571 * The here reported metadata are enough to implement a basic capture
572 * example application, but a real camera implementation will require
573 * more.
574 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200575 uint32_t numEntries;
576 uint32_t byteSize;
577 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
578 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300579 if (!staticMetadata_->isValid()) {
580 LOG(HAL, Error) << "Failed to allocate static metadata";
581 delete staticMetadata_;
582 staticMetadata_ = nullptr;
583 return nullptr;
584 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200585
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200586 /* Color correction static metadata. */
587 std::vector<uint8_t> aberrationModes = {
588 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
589 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300590 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
591 aberrationModes.data(),
592 aberrationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200593
594 /* Control static metadata. */
595 std::vector<uint8_t> aeAvailableAntiBandingModes = {
596 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
597 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
598 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
599 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
600 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300601 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
602 aeAvailableAntiBandingModes.data(),
603 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200604
605 std::vector<uint8_t> aeAvailableModes = {
606 ANDROID_CONTROL_AE_MODE_ON,
607 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300608 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
609 aeAvailableModes.data(),
610 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200611
612 std::vector<int32_t> availableAeFpsTarget = {
613 15, 30,
614 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300615 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
616 availableAeFpsTarget.data(),
617 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200618
619 std::vector<int32_t> aeCompensationRange = {
620 0, 0,
621 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300622 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
623 aeCompensationRange.data(),
624 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200625
626 const camera_metadata_rational_t aeCompensationStep[] = {
627 { 0, 1 }
628 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300629 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
630 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200631
632 std::vector<uint8_t> availableAfModes = {
633 ANDROID_CONTROL_AF_MODE_OFF,
634 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300635 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
636 availableAfModes.data(),
637 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200638
639 std::vector<uint8_t> availableEffects = {
640 ANDROID_CONTROL_EFFECT_MODE_OFF,
641 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300642 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
643 availableEffects.data(),
644 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200645
646 std::vector<uint8_t> availableSceneModes = {
647 ANDROID_CONTROL_SCENE_MODE_DISABLED,
648 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300649 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
650 availableSceneModes.data(),
651 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200652
653 std::vector<uint8_t> availableStabilizationModes = {
654 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
655 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300656 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
657 availableStabilizationModes.data(),
658 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200659
660 std::vector<uint8_t> availableAwbModes = {
661 ANDROID_CONTROL_AWB_MODE_OFF,
662 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300663 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
664 availableAwbModes.data(),
665 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200666
667 std::vector<int32_t> availableMaxRegions = {
668 0, 0, 0,
669 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300670 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
671 availableMaxRegions.data(),
672 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200673
674 std::vector<uint8_t> sceneModesOverride = {
675 ANDROID_CONTROL_AE_MODE_ON,
676 ANDROID_CONTROL_AWB_MODE_AUTO,
677 ANDROID_CONTROL_AF_MODE_AUTO,
678 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300679 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
680 sceneModesOverride.data(),
681 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200682
683 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300684 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
685 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200686
687 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300688 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
689 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200690
691 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300692 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
693 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200694
695 /* JPEG static metadata. */
696 std::vector<int32_t> availableThumbnailSizes = {
697 0, 0,
698 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300699 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
700 availableThumbnailSizes.data(),
701 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200702
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100703 /*
704 * \todo Calculate the maximum JPEG buffer size by asking the encoder
705 * giving the maximum frame size required.
706 */
707 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
708
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200709 /* Sensor static metadata. */
710 int32_t pixelArraySize[] = {
711 2592, 1944,
712 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300713 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
714 &pixelArraySize, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200715
716 int32_t sensorSizes[] = {
717 0, 0, 2560, 1920,
718 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300719 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
720 &sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200721
722 int32_t sensitivityRange[] = {
723 32, 2400,
724 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300725 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
726 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200727
728 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300729 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
730 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200731
732 int64_t exposureTimeRange[] = {
733 100000, 200000000,
734 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300735 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
736 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200737
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200738 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200739
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200740 std::vector<int32_t> testPatterModes = {
741 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
742 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300743 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
744 testPatterModes.data(),
745 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200746
747 std::vector<float> physicalSize = {
748 2592, 1944,
749 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300750 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
751 physicalSize.data(),
752 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200753
754 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300755 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
756 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200757
758 /* Statistics static metadata. */
759 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300760 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
761 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200762
763 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300764 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
765 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200766
767 /* Sync static metadata. */
768 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300769 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200770
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200771 /* Flash static metadata. */
772 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300773 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
774 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200775
776 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200777 std::vector<float> lensApertures = {
778 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200779 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300780 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
781 lensApertures.data(),
782 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200783
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200784 uint8_t lensFacing;
785 switch (facing_) {
786 default:
787 case CAMERA_FACING_FRONT:
788 lensFacing = ANDROID_LENS_FACING_FRONT;
789 break;
790 case CAMERA_FACING_BACK:
791 lensFacing = ANDROID_LENS_FACING_BACK;
792 break;
793 case CAMERA_FACING_EXTERNAL:
794 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
795 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100796 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300797 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200798
799 std::vector<float> lensFocalLenghts = {
800 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200801 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300802 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
803 lensFocalLenghts.data(),
804 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200805
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200806 std::vector<uint8_t> opticalStabilizations = {
807 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
808 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300809 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
810 opticalStabilizations.data(),
811 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200812
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200813 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300814 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
815 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200816
817 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300818 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
819 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200820
821 /* Noise reduction modes. */
822 uint8_t noiseReductionModes = ANDROID_NOISE_REDUCTION_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300823 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
824 &noiseReductionModes, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200825
826 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200827 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300828 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
829 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200830
Jacopo Mondibde7b982020-05-25 17:18:28 +0200831 std::vector<uint32_t> availableStreamConfigurations;
832 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
833 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200834 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200835 availableStreamConfigurations.push_back(entry.resolution.width);
836 availableStreamConfigurations.push_back(entry.resolution.height);
837 availableStreamConfigurations.push_back(
838 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
839 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300840 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
841 availableStreamConfigurations.data(),
842 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200843
844 std::vector<int64_t> availableStallDurations = {
845 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
846 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300847 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
848 availableStallDurations.data(),
849 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200850
Jacopo Mondibde7b982020-05-25 17:18:28 +0200851 /* \todo Collect the minimum frame duration from the camera. */
852 std::vector<int64_t> minFrameDurations;
853 minFrameDurations.reserve(streamConfigurations_.size() * 4);
854 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200855 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200856 minFrameDurations.push_back(entry.resolution.width);
857 minFrameDurations.push_back(entry.resolution.height);
858 minFrameDurations.push_back(33333333);
859 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300860 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
861 minFrameDurations.data(),
862 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200863
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200864 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300865 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200866
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200867 /* Info static metadata. */
868 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300869 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
870 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200871
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200872 /* Request static metadata. */
873 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300874 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
875 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200876
877 uint8_t maxPipelineDepth = 2;
Laurent Pinchart39860092019-09-05 03:12:34 +0300878 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
879 &maxPipelineDepth, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200880
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200881 /* LIMITED does not support reprocessing. */
882 uint32_t maxNumInputStreams = 0;
883 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
884 &maxNumInputStreams, 1);
885
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200886 std::vector<uint8_t> availableCapabilities = {
887 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
888 };
Niklas Söderlund7876d632020-07-21 00:16:24 +0200889
890 /* Report if camera supports RAW. */
891 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200892 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +0200893 if (cameraConfig && !cameraConfig->empty()) {
894 const PixelFormatInfo &info =
895 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
896 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
897 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
898 }
899
Laurent Pinchart39860092019-09-05 03:12:34 +0300900 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
901 availableCapabilities.data(),
902 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200903
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200904 std::vector<int32_t> availableCharacteristicsKeys = {
905 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
906 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
907 ANDROID_CONTROL_AE_AVAILABLE_MODES,
908 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
909 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
910 ANDROID_CONTROL_AE_COMPENSATION_STEP,
911 ANDROID_CONTROL_AF_AVAILABLE_MODES,
912 ANDROID_CONTROL_AVAILABLE_EFFECTS,
913 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
914 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
915 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
916 ANDROID_CONTROL_MAX_REGIONS,
917 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
918 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
919 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
920 ANDROID_CONTROL_AVAILABLE_MODES,
921 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100922 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200923 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
924 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
925 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
926 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
927 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
928 ANDROID_SENSOR_ORIENTATION,
929 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
930 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
931 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
932 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
933 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
934 ANDROID_SYNC_MAX_LATENCY,
935 ANDROID_FLASH_INFO_AVAILABLE,
936 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
937 ANDROID_LENS_FACING,
938 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
939 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
940 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
941 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
942 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
943 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200944 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
945 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
946 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
947 ANDROID_SCALER_CROPPING_TYPE,
948 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
949 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
950 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200951 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200952 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
953 };
954 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
955 availableCharacteristicsKeys.data(),
956 availableCharacteristicsKeys.size());
957
958 std::vector<int32_t> availableRequestKeys = {
959 ANDROID_CONTROL_AE_MODE,
960 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
961 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200962 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
963 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200964 ANDROID_CONTROL_AE_LOCK,
965 ANDROID_CONTROL_AF_TRIGGER,
966 ANDROID_CONTROL_AWB_MODE,
967 ANDROID_CONTROL_AWB_LOCK,
968 ANDROID_FLASH_MODE,
969 ANDROID_STATISTICS_FACE_DETECT_MODE,
970 ANDROID_NOISE_REDUCTION_MODE,
971 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200972 ANDROID_LENS_APERTURE,
973 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
974 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200975 ANDROID_CONTROL_CAPTURE_INTENT,
976 };
977 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
978 availableRequestKeys.data(),
979 availableRequestKeys.size());
980
981 std::vector<int32_t> availableResultKeys = {
982 ANDROID_CONTROL_AE_STATE,
983 ANDROID_CONTROL_AE_LOCK,
984 ANDROID_CONTROL_AF_STATE,
985 ANDROID_CONTROL_AWB_STATE,
986 ANDROID_CONTROL_AWB_LOCK,
987 ANDROID_LENS_STATE,
988 ANDROID_SCALER_CROP_REGION,
989 ANDROID_SENSOR_TIMESTAMP,
990 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
991 ANDROID_SENSOR_EXPOSURE_TIME,
992 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
993 ANDROID_STATISTICS_SCENE_FLICKER,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100994 ANDROID_JPEG_SIZE,
995 ANDROID_JPEG_QUALITY,
996 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200997 };
998 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
999 availableResultKeys.data(),
1000 availableResultKeys.size());
1001
Laurent Pinchart39860092019-09-05 03:12:34 +03001002 if (!staticMetadata_->isValid()) {
1003 LOG(HAL, Error) << "Failed to construct static metadata";
1004 delete staticMetadata_;
1005 staticMetadata_ = nullptr;
1006 return nullptr;
1007 }
1008
1009 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001010}
1011
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001012CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001013{
Jacopo Mondi63703472019-09-04 16:18:22 +02001014 /*
1015 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001016 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001017 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001018 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001019 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001020 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001021 return nullptr;
1022 }
1023
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001024 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001025 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1026 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001027
1028 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001029 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1030 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001031
1032 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001033 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1034 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001035
1036 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001037 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1038 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001039
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001040 std::vector<int32_t> aeFpsTarget = {
1041 15, 30,
1042 };
1043 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1044 aeFpsTarget.data(),
1045 aeFpsTarget.size());
1046
1047 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1048 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1049 &aeAntibandingMode, 1);
1050
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001051 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001052 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1053 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001054
1055 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001056 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1057 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001058
1059 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001060 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1061 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001062
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001063 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001064 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1065 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001066
1067 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001068 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1069 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001070
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001071 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001072 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1073 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001074
1075 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001076 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1077 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001078
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001079 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1080 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1081
1082 float lensAperture = 2.53 / 100;
1083 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1084
1085 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1086 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1087 &opticalStabilization, 1);
1088
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001089 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001090 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1091 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001092
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001093 return requestTemplate;
1094}
1095
1096/*
1097 * Produce a metadata pack to be used as template for a capture request.
1098 */
1099const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1100{
1101 auto it = requestTemplates_.find(type);
1102 if (it != requestTemplates_.end())
1103 return it->second->get();
1104
1105 /* Use the capture intent matching the requested template type. */
1106 CameraMetadata *requestTemplate;
1107 uint8_t captureIntent;
1108 switch (type) {
1109 case CAMERA3_TEMPLATE_PREVIEW:
1110 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1111 break;
1112 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1113 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1114 break;
1115 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1116 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1117 break;
1118 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1119 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1120 break;
1121 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1122 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1123 break;
1124 case CAMERA3_TEMPLATE_MANUAL:
1125 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1126 break;
1127 default:
1128 LOG(HAL, Error) << "Invalid template request type: " << type;
1129 return nullptr;
1130 }
1131
1132 requestTemplate = requestTemplatePreview();
1133 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001134 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001135 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001136 return nullptr;
1137 }
1138
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001139 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1140 &captureIntent, 1);
1141
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001142 requestTemplates_[type] = requestTemplate;
1143 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001144}
1145
Kieran Bingham43e3b802020-06-26 09:58:49 +01001146PixelFormat CameraDevice::toPixelFormat(int format)
1147{
1148 /* Translate Android format code to libcamera pixel format. */
1149 auto it = formatsMap_.find(format);
1150 if (it == formatsMap_.end()) {
1151 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1152 << " not supported";
1153 return PixelFormat();
1154 }
1155
1156 return it->second;
1157}
1158
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001159/*
1160 * Inspect the stream_list to produce a list of StreamConfiguration to
1161 * be use to configure the Camera.
1162 */
1163int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1164{
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001165 /*
1166 * Generate an empty configuration, and construct a StreamConfiguration
1167 * for each camera3_stream to add to it.
1168 */
1169 config_ = camera_->generateConfiguration();
1170 if (!config_) {
1171 LOG(HAL, Error) << "Failed to generate camera configuration";
1172 return -EINVAL;
1173 }
1174
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001175 /*
1176 * Clear and remove any existing configuration from previous calls, and
1177 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001178 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001179 */
1180 streams_.clear();
1181 streams_.reserve(stream_list->num_streams);
1182
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001183 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001184 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001185 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1186 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001187 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001188
Kieran Bingham43e3b802020-06-26 09:58:49 +01001189 PixelFormat format = toPixelFormat(stream->format);
1190
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001191 LOG(HAL, Info) << "Stream #" << i
1192 << ", direction: " << stream->stream_type
1193 << ", width: " << stream->width
1194 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001195 << ", format: " << utils::hex(stream->format)
1196 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001197
1198 if (!format.isValid())
1199 return -EINVAL;
1200
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001201 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001202 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1203 if (jpegStream) {
1204 LOG(HAL, Error)
1205 << "Multiple JPEG streams are not supported";
1206 return -EINVAL;
1207 }
1208
1209 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001210 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001211 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001212
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001213 StreamConfiguration streamConfiguration;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001214 streamConfiguration.size = size;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001215 streamConfiguration.pixelFormat = format;
1216
1217 config_->addConfiguration(streamConfiguration);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001218 unsigned int index = config_->size() - 1;
Jacopo Mondi160bb092020-10-02 20:48:35 +02001219 streams_.emplace_back(this, stream, streamConfiguration,
1220 CameraStream::Type::Direct, index);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001221 stream->priv = static_cast<void *>(&streams_.back());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001222 }
1223
Jacopo Mondic82f9442020-09-02 11:58:00 +02001224 /* Now handle the MJPEG streams, adding a new stream if required. */
1225 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001226 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001227 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001228
Jacopo Mondic82f9442020-09-02 11:58:00 +02001229 /* Search for a compatible stream in the non-JPEG ones. */
1230 for (unsigned int i = 0; i < config_->size(); i++) {
1231 StreamConfiguration &cfg = config_->at(i);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001232
1233 /*
1234 * \todo The PixelFormat must also be compatible with
1235 * the encoder.
1236 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001237 if (cfg.size.width != jpegStream->width ||
1238 cfg.size.height != jpegStream->height)
1239 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001240
Jacopo Mondic82f9442020-09-02 11:58:00 +02001241 LOG(HAL, Info)
1242 << "Android JPEG stream mapped to libcamera stream " << i;
1243
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001244 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001245 index = i;
1246 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001247 }
1248
1249 /*
1250 * Without a compatible match for JPEG encoding we must
1251 * introduce a new stream to satisfy the request requirements.
1252 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001253 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001254 StreamConfiguration streamConfiguration;
1255
1256 /*
1257 * \todo The pixelFormat should be a 'best-fit' choice
1258 * and may require a validation cycle. This is not yet
1259 * handled, and should be considered as part of any
1260 * stream configuration reworks.
1261 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001262 streamConfiguration.size.width = jpegStream->width;
1263 streamConfiguration.size.height = jpegStream->height;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001264 streamConfiguration.pixelFormat = formats::NV12;
1265
1266 LOG(HAL, Info) << "Adding " << streamConfiguration.toString()
1267 << " for MJPEG support";
1268
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001269 type = CameraStream::Type::Internal;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001270 config_->addConfiguration(streamConfiguration);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001271 index = config_->size() - 1;
1272 }
1273
1274 StreamConfiguration &cfg = config_->at(index);
Jacopo Mondi160bb092020-10-02 20:48:35 +02001275 streams_.emplace_back(this, jpegStream, cfg, type, index);
Jacopo Mondifacadb12020-09-02 12:11:46 +02001276 jpegStream->priv = static_cast<void *>(&streams_.back());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001277 }
1278
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001279 switch (config_->validate()) {
1280 case CameraConfiguration::Valid:
1281 break;
1282 case CameraConfiguration::Adjusted:
1283 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001284
1285 for (const StreamConfiguration &cfg : *config_)
1286 LOG(HAL, Info) << " - " << cfg.toString();
1287
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001288 config_.reset();
1289 return -EINVAL;
1290 case CameraConfiguration::Invalid:
1291 LOG(HAL, Info) << "Camera configuration invalid";
1292 config_.reset();
1293 return -EINVAL;
1294 }
1295
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001296 /*
1297 * Configure the HAL CameraStream instances using the associated
1298 * StreamConfiguration and set the number of required buffers in
1299 * the Android camera3_stream_t.
1300 */
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001301 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1302 camera3_stream_t *stream = stream_list->streams[i];
Jacopo Mondic82f9442020-09-02 11:58:00 +02001303 CameraStream *cameraStream = static_cast<CameraStream *>(stream->priv);
1304 StreamConfiguration &cfg = config_->at(cameraStream->index());
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001305
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001306 int ret = cameraStream->configure(cfg);
1307 if (ret)
1308 return ret;
1309
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001310 /* Use the bufferCount confirmed by the validation process. */
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001311 stream->max_buffers = cfg.bufferCount;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001312 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001313
1314 /*
1315 * Once the CameraConfiguration has been adjusted/validated
1316 * it can be applied to the camera.
1317 */
1318 int ret = camera_->configure(config_.get());
1319 if (ret) {
1320 LOG(HAL, Error) << "Failed to configure camera '"
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001321 << camera_->id() << "'";
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001322 return ret;
1323 }
1324
1325 return 0;
1326}
1327
Kieran Bingham74ab4422020-07-01 13:25:38 +01001328FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1329{
1330 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001331 for (int i = 0; i < camera3buffer->numFds; i++) {
1332 /* Skip unused planes. */
1333 if (camera3buffer->data[i] == -1)
1334 break;
1335
Kieran Bingham74ab4422020-07-01 13:25:38 +01001336 FrameBuffer::Plane plane;
1337 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001338 if (!plane.fd.isValid()) {
1339 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1340 << camera3buffer->data[i] << ") "
1341 << " on plane " << i;
1342 return nullptr;
1343 }
1344
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001345 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1346 if (length == -1) {
1347 LOG(HAL, Error) << "Failed to query plane length";
1348 return nullptr;
1349 }
1350
1351 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001352 planes.push_back(std::move(plane));
1353 }
1354
1355 return new FrameBuffer(std::move(planes));
1356}
1357
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001358int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001359{
Kieran Bingham61f42962020-07-01 13:40:17 +01001360 if (!camera3Request->num_output_buffers) {
1361 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001362 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001363 }
1364
1365 /* Start the camera if that's the first request we handle. */
1366 if (!running_) {
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001367 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001368 if (ret) {
1369 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001370 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001371 }
1372
1373 running_ = true;
1374 }
1375
1376 /*
1377 * Queue a request for the Camera with the provided dmabuf file
1378 * descriptors.
1379 */
1380 const camera3_stream_buffer_t *camera3Buffers =
1381 camera3Request->output_buffers;
1382
1383 /*
1384 * Save the request descriptors for use at completion time.
1385 * The descriptor and the associated memory reserved here are freed
1386 * at request complete time.
1387 */
1388 Camera3RequestDescriptor *descriptor =
1389 new Camera3RequestDescriptor(camera3Request->frame_number,
1390 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001391
1392 Request *request =
1393 camera_->createRequest(reinterpret_cast<uint64_t>(descriptor));
1394
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001395 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001396 CameraStream *cameraStream =
1397 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1398
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001399 /*
1400 * Keep track of which stream the request belongs to and store
1401 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001402 */
1403 descriptor->buffers[i].stream = camera3Buffers[i].stream;
1404 descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001405
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001406 /* Software streams are handled after hardware streams complete. */
Jacopo Mondi160bb092020-10-02 20:48:35 +02001407 if (cameraStream->camera3Stream().format == HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001408 continue;
1409
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001410 /*
1411 * Create a libcamera buffer using the dmabuf descriptors of
1412 * the camera3Buffer for each stream. The FrameBuffer is
1413 * directly associated with the Camera3RequestDescriptor for
1414 * lifetime management only.
1415 */
1416 FrameBuffer *buffer = createFrameBuffer(*camera3Buffers[i].buffer);
1417 if (!buffer) {
1418 LOG(HAL, Error) << "Failed to create buffer";
1419 delete request;
1420 delete descriptor;
1421 return -ENOMEM;
1422 }
1423 descriptor->frameBuffers.emplace_back(buffer);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001424
Jacopo Mondic82f9442020-09-02 11:58:00 +02001425 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index());
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001426 Stream *stream = streamConfiguration->stream();
1427
1428 request->addBuffer(stream, buffer);
1429 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001430
1431 int ret = camera_->queueRequest(request);
1432 if (ret) {
1433 LOG(HAL, Error) << "Failed to queue request";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001434 delete request;
1435 delete descriptor;
1436 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001437 }
1438
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001439 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001440}
1441
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001442void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001443{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001444 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001445 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001446 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001447 Camera3RequestDescriptor *descriptor =
1448 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001449
1450 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001451 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001452 << request->status();
1453 status = CAMERA3_BUFFER_STATUS_ERROR;
1454 }
1455
Kieran Binghamc09aee42020-07-28 14:01:19 +01001456 /*
1457 * \todo The timestamp used for the metadata is currently always taken
1458 * from the first buffer (which may be the first stream) in the Request.
1459 * It might be appropriate to return a 'correct' (as determined by
1460 * pipeline handlers) timestamp in the Request itself.
1461 */
1462 FrameBuffer *buffer = buffers.begin()->second;
1463 resultMetadata = getResultMetadata(descriptor->frameNumber,
1464 buffer->metadata().timestamp);
1465
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001466 /* Handle any JPEG compression. */
1467 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
1468 CameraStream *cameraStream =
1469 static_cast<CameraStream *>(descriptor->buffers[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001470
Jacopo Mondi160bb092020-10-02 20:48:35 +02001471 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001472 continue;
1473
Jacopo Mondifacadb12020-09-02 12:11:46 +02001474 Encoder *encoder = cameraStream->encoder();
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001475 if (!encoder) {
1476 LOG(HAL, Error) << "Failed to identify encoder";
1477 continue;
1478 }
1479
Jacopo Mondic82f9442020-09-02 11:58:00 +02001480 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001481 Stream *stream = streamConfiguration->stream();
1482 FrameBuffer *buffer = request->findBuffer(stream);
1483 if (!buffer) {
1484 LOG(HAL, Error) << "Failed to find a source stream buffer";
1485 continue;
1486 }
1487
1488 /*
1489 * \todo Buffer mapping and compression should be moved to a
1490 * separate thread.
1491 */
1492
1493 MappedCamera3Buffer mapped(*descriptor->buffers[i].buffer,
1494 PROT_READ | PROT_WRITE);
1495 if (!mapped.isValid()) {
1496 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1497 continue;
1498 }
1499
Umang Jain6f09a612020-09-09 16:44:45 +05301500 /* Set EXIF metadata for various tags. */
1501 Exif exif;
1502 /* \todo Set Make and Model from external vendor tags. */
1503 exif.setMake("libcamera");
1504 exif.setModel("cameraModel");
1505 exif.setOrientation(orientation_);
Jacopo Mondi45fe8e92020-09-02 12:17:09 +02001506 exif.setSize(cameraStream->size());
Umang Jain6f09a612020-09-09 16:44:45 +05301507 /*
1508 * We set the frame's EXIF timestamp as the time of encode.
1509 * Since the precision we need for EXIF timestamp is only one
1510 * second, it is good enough.
1511 */
1512 exif.setTimestamp(std::time(nullptr));
1513 if (exif.generate() != 0)
1514 LOG(HAL, Error) << "Failed to generate valid EXIF data";
1515
1516 int jpeg_size = encoder->encode(buffer, mapped.maps()[0], exif.data());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001517 if (jpeg_size < 0) {
1518 LOG(HAL, Error) << "Failed to encode stream image";
1519 status = CAMERA3_BUFFER_STATUS_ERROR;
1520 continue;
1521 }
1522
1523 /*
1524 * Fill in the JPEG blob header.
1525 *
1526 * The mapped size of the buffer is being returned as
1527 * substantially larger than the requested JPEG_MAX_SIZE
1528 * (which is referenced from maxJpegBufferSize_). Utilise
1529 * this static size to ensure the correct offset of the blob is
1530 * determined.
1531 *
1532 * \todo Investigate if the buffer size mismatch is an issue or
1533 * expected behaviour.
1534 */
1535 uint8_t *resultPtr = mapped.maps()[0].data() +
1536 maxJpegBufferSize_ -
1537 sizeof(struct camera3_jpeg_blob);
1538 auto *blob = reinterpret_cast<struct camera3_jpeg_blob *>(resultPtr);
1539 blob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
1540 blob->jpeg_size = jpeg_size;
1541
1542 /* Update the JPEG result Metadata. */
1543 resultMetadata->addEntry(ANDROID_JPEG_SIZE,
1544 &jpeg_size, 1);
1545
1546 const uint32_t jpeg_quality = 95;
1547 resultMetadata->addEntry(ANDROID_JPEG_QUALITY,
1548 &jpeg_quality, 1);
1549
1550 const uint32_t jpeg_orientation = 0;
1551 resultMetadata->addEntry(ANDROID_JPEG_ORIENTATION,
1552 &jpeg_orientation, 1);
1553 }
1554
1555 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001556 camera3_capture_result_t captureResult = {};
1557 captureResult.frame_number = descriptor->frameNumber;
1558 captureResult.num_output_buffers = descriptor->numBuffers;
1559 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001560 descriptor->buffers[i].acquire_fence = -1;
1561 descriptor->buffers[i].release_fence = -1;
1562 descriptor->buffers[i].status = status;
1563 }
1564 captureResult.output_buffers =
1565 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers);
1566
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001567
Laurent Pinchart39860092019-09-05 03:12:34 +03001568 if (status == CAMERA3_BUFFER_STATUS_OK) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001569 notifyShutter(descriptor->frameNumber,
Niklas Söderlund9217f272019-11-22 16:22:56 +01001570 buffer->metadata().timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001571
1572 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001573 captureResult.result = resultMetadata->get();
1574 }
1575
1576 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1577 /* \todo Improve error handling. In case we notify an error
1578 * because the metadata generation fails, a shutter event has
1579 * already been notified for this frame number before the error
1580 * is here signalled. Make sure the error path plays well with
1581 * the camera stack state machine.
1582 */
1583 notifyError(descriptor->frameNumber,
1584 descriptor->buffers[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001585 }
1586
1587 callbacks_->process_capture_result(callbacks_, &captureResult);
1588
1589 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001590}
1591
Jacopo Mondia7b92772020-05-26 15:41:41 +02001592std::string CameraDevice::logPrefix() const
1593{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001594 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001595}
1596
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001597void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1598{
1599 camera3_notify_msg_t notify = {};
1600
1601 notify.type = CAMERA3_MSG_SHUTTER;
1602 notify.message.shutter.frame_number = frameNumber;
1603 notify.message.shutter.timestamp = timestamp;
1604
1605 callbacks_->notify(callbacks_, &notify);
1606}
1607
1608void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1609{
1610 camera3_notify_msg_t notify = {};
1611
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001612 /*
1613 * \todo Report and identify the stream number or configuration to
1614 * clarify the stream that failed.
1615 */
1616 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1617 << toPixelFormat(stream->format).toString() << ")";
1618
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001619 notify.type = CAMERA3_MSG_ERROR;
1620 notify.message.error.error_stream = stream;
1621 notify.message.error.frame_number = frameNumber;
1622 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1623
1624 callbacks_->notify(callbacks_, &notify);
1625}
1626
1627/*
1628 * Produce a set of fixed result metadata.
1629 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001630std::unique_ptr<CameraMetadata>
1631CameraDevice::getResultMetadata([[maybe_unused]] int frame_number,
1632 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001633{
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001634 /*
1635 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001636 * Currently: 18 entries, 62 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001637 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001638 std::unique_ptr<CameraMetadata> resultMetadata =
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001639 std::make_unique<CameraMetadata>(18, 62);
Laurent Pinchart39860092019-09-05 03:12:34 +03001640 if (!resultMetadata->isValid()) {
1641 LOG(HAL, Error) << "Failed to allocate static metadata";
1642 return nullptr;
1643 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001644
1645 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001646 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001647
1648 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001649 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001650
1651 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001652 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001653
1654 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001655 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001656
1657 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001658 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001659
1660 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001661 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001662
1663 int32_t sensorSizes[] = {
1664 0, 0, 2560, 1920,
1665 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001666 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001667
Laurent Pinchart39860092019-09-05 03:12:34 +03001668 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001669
1670 /* 33.3 msec */
1671 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001672 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1673 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001674
1675 /* 16.6 msec */
1676 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001677 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1678 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001679
1680 const uint8_t lens_shading_map_mode =
1681 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001682 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1683 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001684
1685 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001686 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1687 &scene_flicker, 1);
1688
1689 /*
1690 * Return the result metadata pack even is not valid: get() will return
1691 * nullptr.
1692 */
1693 if (!resultMetadata->isValid()) {
1694 LOG(HAL, Error) << "Failed to construct result metadata";
1695 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001696
1697 return resultMetadata;
1698}