blob: 4eb05df0fdc2a135107c475311ac5a80ea4eca6c [file] [log] [blame]
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2019, Google Inc.
4 *
5 * camera_device.cpp - libcamera Android Camera Device
6 */
7
8#include "camera_device.h"
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02009#include "camera_ops.h"
Umang Jainb2b8c4d2020-10-16 11:07:54 +053010#include "post_processor.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020011
Kieran Bingham83ae84e2020-07-03 12:34:59 +010012#include <sys/mman.h>
Jacopo Mondia80d3812020-05-26 12:31:35 +020013#include <tuple>
Jacopo Mondi117588b2020-05-23 18:53:54 +020014#include <vector>
15
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +020016#include <libcamera/control_ids.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010017#include <libcamera/controls.h>
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030018#include <libcamera/formats.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010019#include <libcamera/property_ids.h>
20
Niklas Söderlund7876d632020-07-21 00:16:24 +020021#include "libcamera/internal/formats.h"
Laurent Pinchart93e72b62020-05-12 00:58:34 +030022#include "libcamera/internal/log.h"
23#include "libcamera/internal/utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020024
Laurent Pinchart39860092019-09-05 03:12:34 +030025#include "camera_metadata.h"
Jacopo Mondi117588b2020-05-23 18:53:54 +020026#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020027
28using namespace libcamera;
29
Jacopo Mondi117588b2020-05-23 18:53:54 +020030namespace {
31
32/*
33 * \var camera3Resolutions
34 * \brief The list of image resolutions defined as mandatory to be supported by
35 * the Android Camera3 specification
36 */
37const std::vector<Size> camera3Resolutions = {
38 { 320, 240 },
39 { 640, 480 },
40 { 1280, 720 },
41 { 1920, 1080 }
42};
43
44/*
45 * \struct Camera3Format
46 * \brief Data associated with an Android format identifier
47 * \var libcameraFormats List of libcamera pixel formats compatible with the
48 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020049 * \var name The human-readable representation of the Android format code
50 */
51struct Camera3Format {
52 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020053 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020054 const char *name;
55};
56
57/*
58 * \var camera3FormatsMap
59 * \brief Associate Android format code with ancillary data
60 */
61const std::map<int, const Camera3Format> camera3FormatsMap = {
62 {
63 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030064 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020065 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020066 "BLOB"
67 }
68 }, {
69 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030070 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020071 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020072 "YCbCr_420_888"
73 }
74 }, {
75 /*
76 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
77 * usage flag. For now, copy the YCbCr_420 configuration.
78 */
79 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030080 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020081 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020082 "IMPLEMENTATION_DEFINED"
83 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020084 }, {
85 HAL_PIXEL_FORMAT_RAW10, {
86 {
87 formats::SBGGR10_CSI2P,
88 formats::SGBRG10_CSI2P,
89 formats::SGRBG10_CSI2P,
90 formats::SRGGB10_CSI2P
91 },
92 false,
93 "RAW10"
94 }
95 }, {
96 HAL_PIXEL_FORMAT_RAW12, {
97 {
98 formats::SBGGR12_CSI2P,
99 formats::SGBRG12_CSI2P,
100 formats::SGRBG12_CSI2P,
101 formats::SRGGB12_CSI2P
102 },
103 false,
104 "RAW12"
105 }
106 }, {
107 HAL_PIXEL_FORMAT_RAW16, {
108 {
109 formats::SBGGR16,
110 formats::SGBRG16,
111 formats::SGRBG16,
112 formats::SRGGB16
113 },
114 false,
115 "RAW16"
116 }
117 }, {
118 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
119 {
120 formats::SBGGR10_IPU3,
121 formats::SGBRG10_IPU3,
122 formats::SGRBG10_IPU3,
123 formats::SRGGB10_IPU3
124 },
125 false,
126 "RAW_OPAQUE"
127 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200128 },
129};
130
131} /* namespace */
132
Hirokazu Honda6c5792f2020-10-20 18:15:01 +0900133LOG_DECLARE_CATEGORY(HAL)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200134
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100135MappedCamera3Buffer::MappedCamera3Buffer(const buffer_handle_t camera3buffer,
136 int flags)
137{
138 maps_.reserve(camera3buffer->numFds);
139 error_ = 0;
140
141 for (int i = 0; i < camera3buffer->numFds; i++) {
142 if (camera3buffer->data[i] == -1)
143 continue;
144
145 off_t length = lseek(camera3buffer->data[i], 0, SEEK_END);
146 if (length < 0) {
147 error_ = -errno;
148 LOG(HAL, Error) << "Failed to query plane length";
149 break;
150 }
151
152 void *address = mmap(nullptr, length, flags, MAP_SHARED,
153 camera3buffer->data[i], 0);
154 if (address == MAP_FAILED) {
155 error_ = -errno;
156 LOG(HAL, Error) << "Failed to mmap plane";
157 break;
158 }
159
160 maps_.emplace_back(static_cast<uint8_t *>(address),
161 static_cast<size_t>(length));
162 }
163}
164
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200165/*
166 * \struct Camera3RequestDescriptor
167 *
168 * A utility structure that groups information about a capture request to be
169 * later re-used at request complete time to notify the framework.
170 */
171
172CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200173 Camera *camera, unsigned int frameNumber, unsigned int numBuffers)
Kieran Bingham37c18c22020-10-21 14:54:11 +0100174 : frameNumber_(frameNumber), numBuffers_(numBuffers)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200175{
Kieran Bingham37c18c22020-10-21 14:54:11 +0100176 buffers_ = new camera3_stream_buffer_t[numBuffers];
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200177
178 /*
179 * FrameBuffer instances created by wrapping a camera3 provided dmabuf
180 * are emplaced in this vector of unique_ptr<> for lifetime management.
181 */
Kieran Bingham37c18c22020-10-21 14:54:11 +0100182 frameBuffers_.reserve(numBuffers);
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200183
184 /*
185 * Create the libcamera::Request unique_ptr<> to tie its lifetime
186 * to the descriptor's one. Set the descriptor's address as the
187 * request's cookie to retrieve it at completion time.
188 */
Kieran Bingham37c18c22020-10-21 14:54:11 +0100189 request_ = std::make_unique<CaptureRequest>(camera,
190 reinterpret_cast<uint64_t>(this));
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200191}
192
193CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
194{
Kieran Bingham37c18c22020-10-21 14:54:11 +0100195 delete[] buffers_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200196}
197
198/*
199 * \class CameraDevice
200 *
201 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200202 * the camera3_device_t interface, bridging calls received from the Android
203 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200204 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200205 * The class translates parameters and operations from the Camera HALv3 API to
206 * the libcamera API to provide static information for a Camera, create request
207 * templates for it, process capture requests and then deliver capture results
208 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200209 */
210
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300211CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000212 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200213 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200214{
215 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100216
217 /*
218 * \todo Determine a more accurate value for this during
219 * streamConfiguration.
220 */
221 maxJpegBufferSize_ = 13 << 20; /* 13631488 from USB HAL */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200222}
223
224CameraDevice::~CameraDevice()
225{
226 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300227 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200228
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200229 for (auto &it : requestTemplates_)
230 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200231}
232
Umang Jainf8e28132020-08-21 14:46:08 +0000233std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
234 const std::shared_ptr<Camera> &cam)
235{
236 CameraDevice *camera = new CameraDevice(id, cam);
237 return std::shared_ptr<CameraDevice>(camera);
238}
239
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200240/*
241 * Initialize the camera static information.
242 * This method is called before the camera device is opened.
243 */
244int CameraDevice::initialize()
245{
246 /* Initialize orientation and facing side of the camera. */
247 const ControlList &properties = camera_->properties();
248
249 if (properties.contains(properties::Location)) {
250 int32_t location = properties.get(properties::Location);
251 switch (location) {
252 case properties::CameraLocationFront:
253 facing_ = CAMERA_FACING_FRONT;
254 break;
255 case properties::CameraLocationBack:
256 facing_ = CAMERA_FACING_BACK;
257 break;
258 case properties::CameraLocationExternal:
259 facing_ = CAMERA_FACING_EXTERNAL;
260 break;
261 }
262 }
263
264 /*
Umang Jaine9176552020-09-09 16:17:54 +0530265 * The Android orientation metadata specifies its rotation correction
266 * value in clockwise direction whereas libcamera specifies the
267 * rotation property in anticlockwise direction. Read the libcamera's
268 * rotation property (anticlockwise) and compute the corresponding
269 * value for clockwise direction as required by the Android orientation
270 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200271 */
Umang Jaine9176552020-09-09 16:17:54 +0530272 if (properties.contains(properties::Rotation)) {
273 int rotation = properties.get(properties::Rotation);
274 orientation_ = (360 - rotation) % 360;
275 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200276
Jacopo Mondi117588b2020-05-23 18:53:54 +0200277 int ret = camera_->acquire();
278 if (ret) {
279 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
280 return ret;
281 }
282
283 ret = initializeStreamConfigurations();
284 camera_->release();
285 return ret;
286}
287
Jacopo Mondibfee6312020-09-01 17:42:13 +0200288std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
289 const PixelFormat &pixelFormat,
290 const std::vector<Size> &resolutions)
291{
292 std::vector<Size> supportedResolutions;
293
294 StreamConfiguration &cfg = cameraConfig->at(0);
295 for (const Size &res : resolutions) {
296 cfg.pixelFormat = pixelFormat;
297 cfg.size = res;
298
299 CameraConfiguration::Status status = cameraConfig->validate();
300 if (status != CameraConfiguration::Valid) {
301 LOG(HAL, Debug) << cfg.toString() << " not supported";
302 continue;
303 }
304
305 LOG(HAL, Debug) << cfg.toString() << " supported";
306
307 supportedResolutions.push_back(res);
308 }
309
310 return supportedResolutions;
311}
312
Jacopo Mondi49610332020-09-01 18:11:34 +0200313std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
314{
315 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200316 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200317 StreamConfiguration &cfg = cameraConfig->at(0);
318 const StreamFormats &formats = cfg.formats();
319 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
320
321 return supportedResolutions;
322}
323
Jacopo Mondi117588b2020-05-23 18:53:54 +0200324/*
325 * Initialize the format conversion map to translate from Android format
326 * identifier to libcamera pixel formats and fill in the list of supported
327 * stream configurations to be reported to the Android camera framework through
328 * the static stream configuration metadata.
329 */
330int CameraDevice::initializeStreamConfigurations()
331{
332 /*
333 * Get the maximum output resolutions
334 * \todo Get this from the camera properties once defined
335 */
336 std::unique_ptr<CameraConfiguration> cameraConfig =
337 camera_->generateConfiguration({ StillCapture });
338 if (!cameraConfig) {
339 LOG(HAL, Error) << "Failed to get maximum resolution";
340 return -EINVAL;
341 }
342 StreamConfiguration &cfg = cameraConfig->at(0);
343
344 /*
345 * \todo JPEG - Adjust the maximum available resolution by taking the
346 * JPEG encoder requirements into account (alignment and aspect ratio).
347 */
348 const Size maxRes = cfg.size;
349 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
350
351 /*
352 * Build the list of supported image resolutions.
353 *
354 * The resolutions listed in camera3Resolution are mandatory to be
355 * supported, up to the camera maximum resolution.
356 *
357 * Augment the list by adding resolutions calculated from the camera
358 * maximum one.
359 */
360 std::vector<Size> cameraResolutions;
361 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
362 std::back_inserter(cameraResolutions),
363 [&](const Size &res) { return res < maxRes; });
364
365 /*
366 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
367 * resolution.
368 */
369 for (unsigned int divider = 2;; divider <<= 1) {
370 Size derivedSize{
371 maxRes.width / divider,
372 maxRes.height / divider,
373 };
374
375 if (derivedSize.width < 320 ||
376 derivedSize.height < 240)
377 break;
378
379 cameraResolutions.push_back(derivedSize);
380 }
381 cameraResolutions.push_back(maxRes);
382
383 /* Remove duplicated entries from the list of supported resolutions. */
384 std::sort(cameraResolutions.begin(), cameraResolutions.end());
385 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
386 cameraResolutions.erase(last, cameraResolutions.end());
387
388 /*
389 * Build the list of supported camera formats.
390 *
391 * To each Android format a list of compatible libcamera formats is
392 * associated. The first libcamera format that tests successful is added
393 * to the format translation map used when configuring the streams.
394 * It is then tested against the list of supported camera resolutions to
395 * build the stream configuration map reported through the camera static
396 * metadata.
397 */
398 for (const auto &format : camera3FormatsMap) {
399 int androidFormat = format.first;
400 const Camera3Format &camera3Format = format.second;
401 const std::vector<PixelFormat> &libcameraFormats =
402 camera3Format.libcameraFormats;
403
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200404 LOG(HAL, Debug) << "Trying to map Android format "
405 << camera3Format.name;
406
Jacopo Mondi117588b2020-05-23 18:53:54 +0200407 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200408 * JPEG is always supported, either produced directly by the
409 * camera, or encoded in the HAL.
410 */
411 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
412 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200413 LOG(HAL, Debug) << "Mapped Android format "
414 << camera3Format.name << " to "
415 << formats::MJPEG.toString()
416 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200417 continue;
418 }
419
420 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200421 * Test the libcamera formats that can produce images
422 * compatible with the format defined by Android.
423 */
424 PixelFormat mappedFormat;
425 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200426
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200427 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
428
Jacopo Mondi117588b2020-05-23 18:53:54 +0200429 /*
430 * The stream configuration size can be adjusted,
431 * not the pixel format.
432 *
433 * \todo This could be simplified once all pipeline
434 * handlers will report the StreamFormats list of
435 * supported formats.
436 */
437 cfg.pixelFormat = pixelFormat;
438
439 CameraConfiguration::Status status = cameraConfig->validate();
440 if (status != CameraConfiguration::Invalid &&
441 cfg.pixelFormat == pixelFormat) {
442 mappedFormat = pixelFormat;
443 break;
444 }
445 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200446
447 if (!mappedFormat.isValid()) {
448 /* If the format is not mandatory, skip it. */
449 if (!camera3Format.mandatory)
450 continue;
451
452 LOG(HAL, Error)
453 << "Failed to map mandatory Android format "
454 << camera3Format.name << " ("
455 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200456 return -EINVAL;
457 }
458
459 /*
460 * Record the mapping and then proceed to generate the
461 * stream configurations map, by testing the image resolutions.
462 */
463 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200464 LOG(HAL, Debug) << "Mapped Android format "
465 << camera3Format.name << " to "
466 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200467
Jacopo Mondi49610332020-09-01 18:11:34 +0200468 std::vector<Size> resolutions;
469 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
470 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
471 resolutions = getRawResolutions(mappedFormat);
472 else
473 resolutions = getYUVResolutions(cameraConfig.get(),
474 mappedFormat,
475 cameraResolutions);
476
Jacopo Mondibfee6312020-09-01 17:42:13 +0200477 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200478 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200479
480 /*
481 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
482 * from which JPEG is produced, add an entry for
483 * the JPEG stream.
484 *
485 * \todo Wire the JPEG encoder to query the supported
486 * sizes provided a list of formats it can encode.
487 *
488 * \todo Support JPEG streams produced by the Camera
489 * natively.
490 */
491 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888)
492 streamConfigurations_.push_back(
493 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200494 }
495 }
496
497 LOG(HAL, Debug) << "Collected stream configuration map: ";
498 for (const auto &entry : streamConfigurations_)
499 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200500 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200501
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200502 return 0;
503}
504
505/*
506 * Open a camera device. The static information on the camera shall have been
507 * initialized with a call to CameraDevice::initialize().
508 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200509int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200510{
511 int ret = camera_->acquire();
512 if (ret) {
513 LOG(HAL, Error) << "Failed to acquire the camera";
514 return ret;
515 }
516
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200517 /* Initialize the hw_device_t in the instance camera3_module_t. */
518 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
519 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
520 camera3Device_.common.module = (hw_module_t *)hardwareModule;
521 camera3Device_.common.close = hal_dev_close;
522
523 /*
524 * The camera device operations. These actually implement
525 * the Android Camera HALv3 interface.
526 */
527 camera3Device_.ops = &hal_dev_ops;
528 camera3Device_.priv = this;
529
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200530 return 0;
531}
532
533void CameraDevice::close()
534{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200535 streams_.clear();
536
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200537 worker_.stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200538 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200539 camera_->release();
540
541 running_ = false;
542}
543
544void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
545{
546 callbacks_ = callbacks;
547}
548
Jacopo Mondia80d3812020-05-26 12:31:35 +0200549std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
550{
551 /*
552 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100553 * Currently: 51 entries, 687 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200554 */
Jacopo Mondi2c618502020-10-08 16:47:36 +0200555 uint32_t numEntries = 52;
556 uint32_t byteSize = 694;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200557
558 /*
559 * Calculate space occupation in bytes for dynamically built metadata
560 * entries.
561 *
562 * Each stream configuration entry requires 52 bytes:
563 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200564 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
565 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200566 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200567
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300568 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200569}
570
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200571/*
572 * Return static information for the camera.
573 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200574const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200575{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200576 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300577 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200578
579 /*
580 * The here reported metadata are enough to implement a basic capture
581 * example application, but a real camera implementation will require
582 * more.
583 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200584 uint32_t numEntries;
585 uint32_t byteSize;
586 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
587 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300588 if (!staticMetadata_->isValid()) {
589 LOG(HAL, Error) << "Failed to allocate static metadata";
590 delete staticMetadata_;
591 staticMetadata_ = nullptr;
592 return nullptr;
593 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200594
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200595 const ControlInfoMap &controlsInfo = camera_->controls();
596
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200597 /* Color correction static metadata. */
Jacopo Mondi63336862020-10-08 16:18:26 +0200598 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100599 std::vector<uint8_t> data;
600 data.reserve(3);
Jacopo Mondi63336862020-10-08 16:18:26 +0200601 const auto &infoMap = controlsInfo.find(&controls::draft::ColorCorrectionAberrationMode);
602 if (infoMap != controlsInfo.end()) {
603 for (const auto &value : infoMap->second.values())
604 data.push_back(value.get<int32_t>());
605 } else {
606 data.push_back(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
607 }
608 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
609 data.data(), data.size());
610 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200611
612 /* Control static metadata. */
613 std::vector<uint8_t> aeAvailableAntiBandingModes = {
614 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
615 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
616 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
617 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
618 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300619 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
620 aeAvailableAntiBandingModes.data(),
621 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200622
623 std::vector<uint8_t> aeAvailableModes = {
624 ANDROID_CONTROL_AE_MODE_ON,
625 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300626 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
627 aeAvailableModes.data(),
628 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200629
630 std::vector<int32_t> availableAeFpsTarget = {
631 15, 30,
632 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300633 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
634 availableAeFpsTarget.data(),
635 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200636
637 std::vector<int32_t> aeCompensationRange = {
638 0, 0,
639 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300640 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
641 aeCompensationRange.data(),
642 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200643
644 const camera_metadata_rational_t aeCompensationStep[] = {
645 { 0, 1 }
646 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300647 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
648 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200649
650 std::vector<uint8_t> availableAfModes = {
651 ANDROID_CONTROL_AF_MODE_OFF,
652 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300653 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
654 availableAfModes.data(),
655 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200656
657 std::vector<uint8_t> availableEffects = {
658 ANDROID_CONTROL_EFFECT_MODE_OFF,
659 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300660 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
661 availableEffects.data(),
662 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200663
664 std::vector<uint8_t> availableSceneModes = {
665 ANDROID_CONTROL_SCENE_MODE_DISABLED,
666 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300667 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
668 availableSceneModes.data(),
669 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200670
671 std::vector<uint8_t> availableStabilizationModes = {
672 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
673 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300674 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
675 availableStabilizationModes.data(),
676 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200677
678 std::vector<uint8_t> availableAwbModes = {
679 ANDROID_CONTROL_AWB_MODE_OFF,
680 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300681 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
682 availableAwbModes.data(),
683 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200684
685 std::vector<int32_t> availableMaxRegions = {
686 0, 0, 0,
687 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300688 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
689 availableMaxRegions.data(),
690 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200691
692 std::vector<uint8_t> sceneModesOverride = {
693 ANDROID_CONTROL_AE_MODE_ON,
694 ANDROID_CONTROL_AWB_MODE_AUTO,
695 ANDROID_CONTROL_AF_MODE_AUTO,
696 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300697 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
698 sceneModesOverride.data(),
699 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200700
701 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300702 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
703 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200704
705 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300706 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
707 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200708
709 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300710 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
711 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200712
713 /* JPEG static metadata. */
714 std::vector<int32_t> availableThumbnailSizes = {
715 0, 0,
716 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300717 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
718 availableThumbnailSizes.data(),
719 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200720
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100721 /*
722 * \todo Calculate the maximum JPEG buffer size by asking the encoder
723 * giving the maximum frame size required.
724 */
725 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
726
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200727 /* Sensor static metadata. */
728 int32_t pixelArraySize[] = {
729 2592, 1944,
730 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300731 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
732 &pixelArraySize, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200733
734 int32_t sensorSizes[] = {
735 0, 0, 2560, 1920,
736 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300737 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
738 &sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200739
740 int32_t sensitivityRange[] = {
741 32, 2400,
742 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300743 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
744 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200745
746 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300747 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
748 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200749
750 int64_t exposureTimeRange[] = {
751 100000, 200000000,
752 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300753 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
754 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200755
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200756 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200757
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200758 std::vector<int32_t> testPatterModes = {
759 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
760 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300761 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
762 testPatterModes.data(),
763 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200764
765 std::vector<float> physicalSize = {
766 2592, 1944,
767 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300768 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
769 physicalSize.data(),
770 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200771
772 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300773 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
774 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200775
776 /* Statistics static metadata. */
777 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300778 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
779 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200780
781 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300782 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
783 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200784
Jacopo Mondi2c618502020-10-08 16:47:36 +0200785 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100786 std::vector<uint8_t> data;
787 data.reserve(2);
Jacopo Mondi2c618502020-10-08 16:47:36 +0200788 const auto &infoMap = controlsInfo.find(&controls::draft::LensShadingMapMode);
789 if (infoMap != controlsInfo.end()) {
790 for (const auto &value : infoMap->second.values())
791 data.push_back(value.get<int32_t>());
792 } else {
793 data.push_back(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
794 }
795 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
796 data.data(), data.size());
797 }
798
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200799 /* Sync static metadata. */
800 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300801 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200802
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200803 /* Flash static metadata. */
804 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300805 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
806 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200807
808 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200809 std::vector<float> lensApertures = {
810 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200811 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300812 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
813 lensApertures.data(),
814 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200815
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200816 uint8_t lensFacing;
817 switch (facing_) {
818 default:
819 case CAMERA_FACING_FRONT:
820 lensFacing = ANDROID_LENS_FACING_FRONT;
821 break;
822 case CAMERA_FACING_BACK:
823 lensFacing = ANDROID_LENS_FACING_BACK;
824 break;
825 case CAMERA_FACING_EXTERNAL:
826 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
827 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100828 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300829 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200830
831 std::vector<float> lensFocalLenghts = {
832 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200833 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300834 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
835 lensFocalLenghts.data(),
836 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200837
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200838 std::vector<uint8_t> opticalStabilizations = {
839 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
840 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300841 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
842 opticalStabilizations.data(),
843 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200844
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200845 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300846 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
847 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200848
849 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300850 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
851 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200852
853 /* Noise reduction modes. */
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +0200854 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100855 std::vector<uint8_t> data;
856 data.reserve(5);
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +0200857 const auto &infoMap = controlsInfo.find(&controls::draft::NoiseReductionMode);
858 if (infoMap != controlsInfo.end()) {
859 for (const auto &value : infoMap->second.values())
860 data.push_back(value.get<int32_t>());
861 } else {
862 data.push_back(ANDROID_NOISE_REDUCTION_MODE_OFF);
863 }
864 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
865 data.data(), data.size());
866 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200867
868 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200869 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300870 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
871 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200872
Jacopo Mondibde7b982020-05-25 17:18:28 +0200873 std::vector<uint32_t> availableStreamConfigurations;
874 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
875 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200876 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200877 availableStreamConfigurations.push_back(entry.resolution.width);
878 availableStreamConfigurations.push_back(entry.resolution.height);
879 availableStreamConfigurations.push_back(
880 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
881 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300882 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
883 availableStreamConfigurations.data(),
884 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200885
886 std::vector<int64_t> availableStallDurations = {
887 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
888 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300889 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
890 availableStallDurations.data(),
891 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200892
Jacopo Mondibde7b982020-05-25 17:18:28 +0200893 /* \todo Collect the minimum frame duration from the camera. */
894 std::vector<int64_t> minFrameDurations;
895 minFrameDurations.reserve(streamConfigurations_.size() * 4);
896 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200897 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200898 minFrameDurations.push_back(entry.resolution.width);
899 minFrameDurations.push_back(entry.resolution.height);
900 minFrameDurations.push_back(33333333);
901 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300902 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
903 minFrameDurations.data(),
904 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200905
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200906 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300907 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200908
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200909 /* Info static metadata. */
910 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300911 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
912 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200913
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200914 /* Request static metadata. */
915 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300916 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
917 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200918
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200919 {
920 /* Default the value to 2 if not reported by the camera. */
921 uint8_t maxPipelineDepth = 2;
922 const auto &infoMap = controlsInfo.find(&controls::draft::PipelineDepth);
923 if (infoMap != controlsInfo.end())
924 maxPipelineDepth = infoMap->second.max().get<int32_t>();
925 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
926 &maxPipelineDepth, 1);
927 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200928
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200929 /* LIMITED does not support reprocessing. */
930 uint32_t maxNumInputStreams = 0;
931 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
932 &maxNumInputStreams, 1);
933
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200934 std::vector<uint8_t> availableCapabilities = {
935 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
936 };
Niklas Söderlund7876d632020-07-21 00:16:24 +0200937
938 /* Report if camera supports RAW. */
939 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200940 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +0200941 if (cameraConfig && !cameraConfig->empty()) {
942 const PixelFormatInfo &info =
943 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
944 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
945 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
946 }
947
Laurent Pinchart39860092019-09-05 03:12:34 +0300948 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
949 availableCapabilities.data(),
950 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200951
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200952 std::vector<int32_t> availableCharacteristicsKeys = {
953 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
954 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
955 ANDROID_CONTROL_AE_AVAILABLE_MODES,
956 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
957 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
958 ANDROID_CONTROL_AE_COMPENSATION_STEP,
959 ANDROID_CONTROL_AF_AVAILABLE_MODES,
960 ANDROID_CONTROL_AVAILABLE_EFFECTS,
961 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
962 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
963 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
964 ANDROID_CONTROL_MAX_REGIONS,
965 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
966 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
967 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
968 ANDROID_CONTROL_AVAILABLE_MODES,
969 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100970 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200971 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
972 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
973 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
974 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
975 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
976 ANDROID_SENSOR_ORIENTATION,
977 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
978 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
979 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
980 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
981 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
982 ANDROID_SYNC_MAX_LATENCY,
983 ANDROID_FLASH_INFO_AVAILABLE,
984 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
985 ANDROID_LENS_FACING,
986 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
987 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
988 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
989 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
990 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
991 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200992 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
993 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
994 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
995 ANDROID_SCALER_CROPPING_TYPE,
996 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
997 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
998 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200999 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001000 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1001 };
1002 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
1003 availableCharacteristicsKeys.data(),
1004 availableCharacteristicsKeys.size());
1005
1006 std::vector<int32_t> availableRequestKeys = {
1007 ANDROID_CONTROL_AE_MODE,
1008 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1009 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001010 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1011 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001012 ANDROID_CONTROL_AE_LOCK,
1013 ANDROID_CONTROL_AF_TRIGGER,
1014 ANDROID_CONTROL_AWB_MODE,
1015 ANDROID_CONTROL_AWB_LOCK,
1016 ANDROID_FLASH_MODE,
1017 ANDROID_STATISTICS_FACE_DETECT_MODE,
1018 ANDROID_NOISE_REDUCTION_MODE,
1019 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001020 ANDROID_LENS_APERTURE,
1021 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1022 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001023 ANDROID_CONTROL_CAPTURE_INTENT,
1024 };
1025 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
1026 availableRequestKeys.data(),
1027 availableRequestKeys.size());
1028
1029 std::vector<int32_t> availableResultKeys = {
1030 ANDROID_CONTROL_AE_STATE,
1031 ANDROID_CONTROL_AE_LOCK,
1032 ANDROID_CONTROL_AF_STATE,
1033 ANDROID_CONTROL_AWB_STATE,
1034 ANDROID_CONTROL_AWB_LOCK,
1035 ANDROID_LENS_STATE,
1036 ANDROID_SCALER_CROP_REGION,
1037 ANDROID_SENSOR_TIMESTAMP,
1038 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1039 ANDROID_SENSOR_EXPOSURE_TIME,
1040 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1041 ANDROID_STATISTICS_SCENE_FLICKER,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001042 ANDROID_JPEG_SIZE,
1043 ANDROID_JPEG_QUALITY,
1044 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001045 };
1046 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1047 availableResultKeys.data(),
1048 availableResultKeys.size());
1049
Laurent Pinchart39860092019-09-05 03:12:34 +03001050 if (!staticMetadata_->isValid()) {
1051 LOG(HAL, Error) << "Failed to construct static metadata";
1052 delete staticMetadata_;
1053 staticMetadata_ = nullptr;
1054 return nullptr;
1055 }
1056
1057 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001058}
1059
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001060CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001061{
Jacopo Mondi63703472019-09-04 16:18:22 +02001062 /*
1063 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001064 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001065 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001066 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001067 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001068 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001069 return nullptr;
1070 }
1071
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001072 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001073 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1074 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001075
1076 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001077 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1078 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001079
1080 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001081 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1082 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001083
1084 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001085 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1086 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001087
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001088 std::vector<int32_t> aeFpsTarget = {
1089 15, 30,
1090 };
1091 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1092 aeFpsTarget.data(),
1093 aeFpsTarget.size());
1094
1095 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1096 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1097 &aeAntibandingMode, 1);
1098
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001099 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001100 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1101 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001102
1103 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001104 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1105 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001106
1107 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001108 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1109 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001110
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001111 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001112 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1113 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001114
1115 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001116 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1117 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001118
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001119 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001120 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1121 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001122
1123 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001124 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1125 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001126
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001127 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1128 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1129
1130 float lensAperture = 2.53 / 100;
1131 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1132
1133 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1134 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1135 &opticalStabilization, 1);
1136
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001137 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001138 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1139 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001140
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001141 return requestTemplate;
1142}
1143
1144/*
1145 * Produce a metadata pack to be used as template for a capture request.
1146 */
1147const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1148{
1149 auto it = requestTemplates_.find(type);
1150 if (it != requestTemplates_.end())
1151 return it->second->get();
1152
1153 /* Use the capture intent matching the requested template type. */
1154 CameraMetadata *requestTemplate;
1155 uint8_t captureIntent;
1156 switch (type) {
1157 case CAMERA3_TEMPLATE_PREVIEW:
1158 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1159 break;
1160 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1161 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1162 break;
1163 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1164 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1165 break;
1166 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1167 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1168 break;
1169 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1170 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1171 break;
1172 case CAMERA3_TEMPLATE_MANUAL:
1173 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1174 break;
1175 default:
1176 LOG(HAL, Error) << "Invalid template request type: " << type;
1177 return nullptr;
1178 }
1179
1180 requestTemplate = requestTemplatePreview();
1181 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001182 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001183 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001184 return nullptr;
1185 }
1186
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001187 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1188 &captureIntent, 1);
1189
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001190 requestTemplates_[type] = requestTemplate;
1191 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001192}
1193
Hirokazu Hondac1ae9052020-10-28 18:50:23 +09001194PixelFormat CameraDevice::toPixelFormat(int format) const
Kieran Bingham43e3b802020-06-26 09:58:49 +01001195{
1196 /* Translate Android format code to libcamera pixel format. */
1197 auto it = formatsMap_.find(format);
1198 if (it == formatsMap_.end()) {
1199 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1200 << " not supported";
1201 return PixelFormat();
1202 }
1203
1204 return it->second;
1205}
1206
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001207/*
1208 * Inspect the stream_list to produce a list of StreamConfiguration to
1209 * be use to configure the Camera.
1210 */
1211int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1212{
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001213 /*
1214 * Generate an empty configuration, and construct a StreamConfiguration
1215 * for each camera3_stream to add to it.
1216 */
1217 config_ = camera_->generateConfiguration();
1218 if (!config_) {
1219 LOG(HAL, Error) << "Failed to generate camera configuration";
1220 return -EINVAL;
1221 }
1222
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001223 /*
1224 * Clear and remove any existing configuration from previous calls, and
1225 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001226 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001227 */
1228 streams_.clear();
1229 streams_.reserve(stream_list->num_streams);
1230
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001231 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001232 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001233 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1234 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001235 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001236
Kieran Bingham43e3b802020-06-26 09:58:49 +01001237 PixelFormat format = toPixelFormat(stream->format);
1238
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001239 LOG(HAL, Info) << "Stream #" << i
1240 << ", direction: " << stream->stream_type
1241 << ", width: " << stream->width
1242 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001243 << ", format: " << utils::hex(stream->format)
1244 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001245
1246 if (!format.isValid())
1247 return -EINVAL;
1248
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001249 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001250 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1251 if (jpegStream) {
1252 LOG(HAL, Error)
1253 << "Multiple JPEG streams are not supported";
1254 return -EINVAL;
1255 }
1256
1257 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001258 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001259 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001260
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001261 StreamConfiguration streamConfiguration;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001262 streamConfiguration.size = size;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001263 streamConfiguration.pixelFormat = format;
1264
1265 config_->addConfiguration(streamConfiguration);
Jacopo Mondie3393f12020-10-03 12:00:54 +02001266 streams_.emplace_back(this, CameraStream::Type::Direct,
1267 stream, config_->size() - 1);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001268 stream->priv = static_cast<void *>(&streams_.back());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001269 }
1270
Jacopo Mondic82f9442020-09-02 11:58:00 +02001271 /* Now handle the MJPEG streams, adding a new stream if required. */
1272 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001273 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001274 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001275
Jacopo Mondic82f9442020-09-02 11:58:00 +02001276 /* Search for a compatible stream in the non-JPEG ones. */
1277 for (unsigned int i = 0; i < config_->size(); i++) {
1278 StreamConfiguration &cfg = config_->at(i);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001279
1280 /*
1281 * \todo The PixelFormat must also be compatible with
1282 * the encoder.
1283 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001284 if (cfg.size.width != jpegStream->width ||
1285 cfg.size.height != jpegStream->height)
1286 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001287
Jacopo Mondic82f9442020-09-02 11:58:00 +02001288 LOG(HAL, Info)
1289 << "Android JPEG stream mapped to libcamera stream " << i;
1290
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001291 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001292 index = i;
1293 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001294 }
1295
1296 /*
1297 * Without a compatible match for JPEG encoding we must
1298 * introduce a new stream to satisfy the request requirements.
1299 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001300 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001301 StreamConfiguration streamConfiguration;
1302
1303 /*
1304 * \todo The pixelFormat should be a 'best-fit' choice
1305 * and may require a validation cycle. This is not yet
1306 * handled, and should be considered as part of any
1307 * stream configuration reworks.
1308 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001309 streamConfiguration.size.width = jpegStream->width;
1310 streamConfiguration.size.height = jpegStream->height;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001311 streamConfiguration.pixelFormat = formats::NV12;
1312
1313 LOG(HAL, Info) << "Adding " << streamConfiguration.toString()
1314 << " for MJPEG support";
1315
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001316 type = CameraStream::Type::Internal;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001317 config_->addConfiguration(streamConfiguration);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001318 index = config_->size() - 1;
1319 }
1320
Jacopo Mondie3393f12020-10-03 12:00:54 +02001321 streams_.emplace_back(this, type, jpegStream, index);
Jacopo Mondifacadb12020-09-02 12:11:46 +02001322 jpegStream->priv = static_cast<void *>(&streams_.back());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001323 }
1324
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001325 switch (config_->validate()) {
1326 case CameraConfiguration::Valid:
1327 break;
1328 case CameraConfiguration::Adjusted:
1329 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001330
1331 for (const StreamConfiguration &cfg : *config_)
1332 LOG(HAL, Info) << " - " << cfg.toString();
1333
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001334 config_.reset();
1335 return -EINVAL;
1336 case CameraConfiguration::Invalid:
1337 LOG(HAL, Info) << "Camera configuration invalid";
1338 config_.reset();
1339 return -EINVAL;
1340 }
1341
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001342 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001343 * Once the CameraConfiguration has been adjusted/validated
1344 * it can be applied to the camera.
1345 */
1346 int ret = camera_->configure(config_.get());
1347 if (ret) {
1348 LOG(HAL, Error) << "Failed to configure camera '"
1349 << camera_->id() << "'";
1350 return ret;
1351 }
1352
1353 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001354 * Configure the HAL CameraStream instances using the associated
1355 * StreamConfiguration and set the number of required buffers in
1356 * the Android camera3_stream_t.
1357 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001358 for (CameraStream &cameraStream : streams_) {
Kieran Binghamc7bcae02020-10-13 15:58:26 +01001359 ret = cameraStream.configure();
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001360 if (ret) {
1361 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001362 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001363 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001364 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001365
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001366 return 0;
1367}
1368
Kieran Bingham74ab4422020-07-01 13:25:38 +01001369FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1370{
1371 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001372 for (int i = 0; i < camera3buffer->numFds; i++) {
1373 /* Skip unused planes. */
1374 if (camera3buffer->data[i] == -1)
1375 break;
1376
Kieran Bingham74ab4422020-07-01 13:25:38 +01001377 FrameBuffer::Plane plane;
1378 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001379 if (!plane.fd.isValid()) {
1380 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1381 << camera3buffer->data[i] << ") "
1382 << " on plane " << i;
1383 return nullptr;
1384 }
1385
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001386 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1387 if (length == -1) {
1388 LOG(HAL, Error) << "Failed to query plane length";
1389 return nullptr;
1390 }
1391
1392 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001393 planes.push_back(std::move(plane));
1394 }
1395
1396 return new FrameBuffer(std::move(planes));
1397}
1398
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001399int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001400{
Kieran Bingham61f42962020-07-01 13:40:17 +01001401 if (!camera3Request->num_output_buffers) {
1402 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001403 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001404 }
1405
1406 /* Start the camera if that's the first request we handle. */
1407 if (!running_) {
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001408 worker_.start();
1409
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001410 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001411 if (ret) {
1412 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001413 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001414 }
1415
1416 running_ = true;
1417 }
1418
1419 /*
1420 * Queue a request for the Camera with the provided dmabuf file
1421 * descriptors.
1422 */
1423 const camera3_stream_buffer_t *camera3Buffers =
1424 camera3Request->output_buffers;
1425
1426 /*
1427 * Save the request descriptors for use at completion time.
1428 * The descriptor and the associated memory reserved here are freed
1429 * at request complete time.
1430 */
1431 Camera3RequestDescriptor *descriptor =
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001432 new Camera3RequestDescriptor(camera_.get(), camera3Request->frame_number,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001433 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001434
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001435 LOG(HAL, Debug) << "Queueing Request to libcamera with "
Kieran Bingham37c18c22020-10-21 14:54:11 +01001436 << descriptor->numBuffers_ << " HAL streams";
1437 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001438 camera3_stream *camera3Stream = camera3Buffers[i].stream;
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001439 CameraStream *cameraStream =
1440 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1441
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001442 /*
1443 * Keep track of which stream the request belongs to and store
1444 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001445 */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001446 descriptor->buffers_[i].stream = camera3Buffers[i].stream;
1447 descriptor->buffers_[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001448
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001449 std::stringstream ss;
1450 ss << i << " - (" << camera3Stream->width << "x"
1451 << camera3Stream->height << ")"
1452 << "[" << utils::hex(camera3Stream->format) << "] -> "
1453 << "(" << cameraStream->configuration().size.toString() << ")["
1454 << cameraStream->configuration().pixelFormat.toString() << "]";
1455
Jacopo Mondide8304b2020-09-04 17:45:39 +02001456 /*
1457 * Inspect the camera stream type, create buffers opportunely
1458 * and add them to the Request if required.
1459 */
1460 FrameBuffer *buffer = nullptr;
1461 switch (cameraStream->type()) {
1462 case CameraStream::Type::Mapped:
1463 /*
1464 * Mapped streams don't need buffers added to the
1465 * Request.
1466 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001467 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001468 continue;
1469
Jacopo Mondide8304b2020-09-04 17:45:39 +02001470 case CameraStream::Type::Direct:
1471 /*
1472 * Create a libcamera buffer using the dmabuf
1473 * descriptors of the camera3Buffer for each stream and
1474 * associate it with the Camera3RequestDescriptor for
1475 * lifetime management only.
1476 */
1477 buffer = createFrameBuffer(*camera3Buffers[i].buffer);
Kieran Bingham37c18c22020-10-21 14:54:11 +01001478 descriptor->frameBuffers_.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001479 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001480 break;
1481
1482 case CameraStream::Type::Internal:
1483 /*
1484 * Get the frame buffer from the CameraStream internal
1485 * buffer pool.
1486 *
1487 * The buffer has to be returned to the CameraStream
1488 * once it has been processed.
1489 */
1490 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001491 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001492 break;
1493 }
1494
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001495 if (!buffer) {
1496 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001497 delete descriptor;
1498 return -ENOMEM;
1499 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001500
Kieran Bingham37c18c22020-10-21 14:54:11 +01001501 descriptor->request_->addBuffer(cameraStream->stream(), buffer,
1502 camera3Buffers[i].acquire_fence);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001503 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001504
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001505 /* Queue the request to the CameraWorker. */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001506 worker_.queueRequest(descriptor->request_.get());
Paul Elderc7532232020-09-23 19:05:41 +09001507
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001508 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001509}
1510
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001511void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001512{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001513 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001514 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001515 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001516 Camera3RequestDescriptor *descriptor =
1517 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001518
1519 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001520 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001521 << request->status();
1522 status = CAMERA3_BUFFER_STATUS_ERROR;
1523 }
1524
Kieran Binghamc09aee42020-07-28 14:01:19 +01001525 /*
1526 * \todo The timestamp used for the metadata is currently always taken
1527 * from the first buffer (which may be the first stream) in the Request.
1528 * It might be appropriate to return a 'correct' (as determined by
1529 * pipeline handlers) timestamp in the Request itself.
1530 */
Hirokazu Honda3a777d82020-10-28 17:57:26 +09001531 uint64_t timestamp = buffers.begin()->second->metadata().timestamp;
Kieran Binghame1f9fdb2020-10-21 15:31:10 +01001532 resultMetadata = getResultMetadata(descriptor->frameNumber_, timestamp);
Kieran Binghamc09aee42020-07-28 14:01:19 +01001533
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001534 /* Handle any JPEG compression. */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001535 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001536 CameraStream *cameraStream =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001537 static_cast<CameraStream *>(descriptor->buffers_[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001538
Jacopo Mondi160bb092020-10-02 20:48:35 +02001539 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001540 continue;
1541
Jacopo Mondi216030a2020-10-03 11:36:41 +02001542 FrameBuffer *buffer = request->findBuffer(cameraStream->stream());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001543 if (!buffer) {
1544 LOG(HAL, Error) << "Failed to find a source stream buffer";
1545 continue;
1546 }
1547
1548 /*
1549 * \todo Buffer mapping and compression should be moved to a
1550 * separate thread.
1551 */
1552
Kieran Bingham37c18c22020-10-21 14:54:11 +01001553 MappedCamera3Buffer mapped(*descriptor->buffers_[i].buffer,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001554 PROT_READ | PROT_WRITE);
1555 if (!mapped.isValid()) {
1556 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1557 continue;
1558 }
1559
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02001560 int ret = cameraStream->process(*buffer, &mapped,
1561 resultMetadata.get());
1562 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001563 status = CAMERA3_BUFFER_STATUS_ERROR;
1564 continue;
1565 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02001566
1567 /*
1568 * Return the FrameBuffer to the CameraStream now that we're
1569 * done processing it.
1570 */
1571 if (cameraStream->type() == CameraStream::Type::Internal)
1572 cameraStream->putBuffer(buffer);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001573 }
1574
1575 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001576 camera3_capture_result_t captureResult = {};
Kieran Bingham37c18c22020-10-21 14:54:11 +01001577 captureResult.frame_number = descriptor->frameNumber_;
1578 captureResult.num_output_buffers = descriptor->numBuffers_;
1579 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
1580 descriptor->buffers_[i].acquire_fence = -1;
1581 descriptor->buffers_[i].release_fence = -1;
1582 descriptor->buffers_[i].status = status;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001583 }
1584 captureResult.output_buffers =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001585 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers_);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001586
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001587
Laurent Pinchart39860092019-09-05 03:12:34 +03001588 if (status == CAMERA3_BUFFER_STATUS_OK) {
Kieran Binghame1f9fdb2020-10-21 15:31:10 +01001589 notifyShutter(descriptor->frameNumber_, timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001590
1591 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001592 captureResult.result = resultMetadata->get();
1593 }
1594
1595 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1596 /* \todo Improve error handling. In case we notify an error
1597 * because the metadata generation fails, a shutter event has
1598 * already been notified for this frame number before the error
1599 * is here signalled. Make sure the error path plays well with
1600 * the camera stack state machine.
1601 */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001602 notifyError(descriptor->frameNumber_,
1603 descriptor->buffers_[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001604 }
1605
1606 callbacks_->process_capture_result(callbacks_, &captureResult);
1607
1608 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001609}
1610
Jacopo Mondia7b92772020-05-26 15:41:41 +02001611std::string CameraDevice::logPrefix() const
1612{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001613 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001614}
1615
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001616void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1617{
1618 camera3_notify_msg_t notify = {};
1619
1620 notify.type = CAMERA3_MSG_SHUTTER;
1621 notify.message.shutter.frame_number = frameNumber;
1622 notify.message.shutter.timestamp = timestamp;
1623
1624 callbacks_->notify(callbacks_, &notify);
1625}
1626
1627void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1628{
1629 camera3_notify_msg_t notify = {};
1630
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001631 /*
1632 * \todo Report and identify the stream number or configuration to
1633 * clarify the stream that failed.
1634 */
1635 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1636 << toPixelFormat(stream->format).toString() << ")";
1637
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001638 notify.type = CAMERA3_MSG_ERROR;
1639 notify.message.error.error_stream = stream;
1640 notify.message.error.frame_number = frameNumber;
1641 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1642
1643 callbacks_->notify(callbacks_, &notify);
1644}
1645
1646/*
1647 * Produce a set of fixed result metadata.
1648 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001649std::unique_ptr<CameraMetadata>
1650CameraDevice::getResultMetadata([[maybe_unused]] int frame_number,
1651 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001652{
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001653 /*
1654 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001655 * Currently: 18 entries, 62 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001656 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001657 std::unique_ptr<CameraMetadata> resultMetadata =
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001658 std::make_unique<CameraMetadata>(18, 62);
Laurent Pinchart39860092019-09-05 03:12:34 +03001659 if (!resultMetadata->isValid()) {
1660 LOG(HAL, Error) << "Failed to allocate static metadata";
1661 return nullptr;
1662 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001663
1664 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001665 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001666
1667 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001668 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001669
1670 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001671 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001672
1673 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001674 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001675
1676 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001677 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001678
1679 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001680 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001681
1682 int32_t sensorSizes[] = {
1683 0, 0, 2560, 1920,
1684 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001685 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001686
Laurent Pinchart39860092019-09-05 03:12:34 +03001687 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001688
1689 /* 33.3 msec */
1690 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001691 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1692 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001693
1694 /* 16.6 msec */
1695 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001696 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1697 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001698
1699 const uint8_t lens_shading_map_mode =
1700 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001701 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1702 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001703
1704 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001705 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1706 &scene_flicker, 1);
1707
1708 /*
1709 * Return the result metadata pack even is not valid: get() will return
1710 * nullptr.
1711 */
1712 if (!resultMetadata->isValid()) {
1713 LOG(HAL, Error) << "Failed to construct result metadata";
1714 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001715
1716 return resultMetadata;
1717}