blob: bc224ecc38af40c7a21d1c9fc781c22e2e5a7958 [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
Paul Elder229653a2021-01-21 17:44:14 +090012#include <fstream>
Kieran Bingham83ae84e2020-07-03 12:34:59 +010013#include <sys/mman.h>
Jacopo Mondia80d3812020-05-26 12:31:35 +020014#include <tuple>
Jacopo Mondi117588b2020-05-23 18:53:54 +020015#include <vector>
16
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +020017#include <libcamera/control_ids.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010018#include <libcamera/controls.h>
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030019#include <libcamera/formats.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010020#include <libcamera/property_ids.h>
21
Niklas Söderlund7876d632020-07-21 00:16:24 +020022#include "libcamera/internal/formats.h"
Laurent Pinchart93e72b62020-05-12 00:58:34 +030023#include "libcamera/internal/log.h"
24#include "libcamera/internal/utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020025
Jacopo Mondi117588b2020-05-23 18:53:54 +020026#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020027
28using namespace libcamera;
29
Hirokazu Honda26d90af2020-12-11 09:53:36 +000030LOG_DECLARE_CATEGORY(HAL)
31
Jacopo Mondi117588b2020-05-23 18:53:54 +020032namespace {
33
34/*
35 * \var camera3Resolutions
36 * \brief The list of image resolutions defined as mandatory to be supported by
37 * the Android Camera3 specification
38 */
39const std::vector<Size> camera3Resolutions = {
40 { 320, 240 },
41 { 640, 480 },
42 { 1280, 720 },
43 { 1920, 1080 }
44};
45
46/*
47 * \struct Camera3Format
48 * \brief Data associated with an Android format identifier
49 * \var libcameraFormats List of libcamera pixel formats compatible with the
50 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020051 * \var name The human-readable representation of the Android format code
52 */
53struct Camera3Format {
54 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020055 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020056 const char *name;
57};
58
59/*
60 * \var camera3FormatsMap
61 * \brief Associate Android format code with ancillary data
62 */
63const std::map<int, const Camera3Format> camera3FormatsMap = {
64 {
65 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030066 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020067 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020068 "BLOB"
69 }
70 }, {
71 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030072 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020073 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020074 "YCbCr_420_888"
75 }
76 }, {
77 /*
78 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
79 * usage flag. For now, copy the YCbCr_420 configuration.
80 */
81 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030082 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020083 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020084 "IMPLEMENTATION_DEFINED"
85 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020086 }, {
87 HAL_PIXEL_FORMAT_RAW10, {
88 {
89 formats::SBGGR10_CSI2P,
90 formats::SGBRG10_CSI2P,
91 formats::SGRBG10_CSI2P,
92 formats::SRGGB10_CSI2P
93 },
94 false,
95 "RAW10"
96 }
97 }, {
98 HAL_PIXEL_FORMAT_RAW12, {
99 {
100 formats::SBGGR12_CSI2P,
101 formats::SGBRG12_CSI2P,
102 formats::SGRBG12_CSI2P,
103 formats::SRGGB12_CSI2P
104 },
105 false,
106 "RAW12"
107 }
108 }, {
109 HAL_PIXEL_FORMAT_RAW16, {
110 {
111 formats::SBGGR16,
112 formats::SGBRG16,
113 formats::SGRBG16,
114 formats::SRGGB16
115 },
116 false,
117 "RAW16"
118 }
119 }, {
120 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
121 {
122 formats::SBGGR10_IPU3,
123 formats::SGBRG10_IPU3,
124 formats::SGRBG10_IPU3,
125 formats::SRGGB10_IPU3
126 },
127 false,
128 "RAW_OPAQUE"
129 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200130 },
131};
132
Hirokazu Hondac2df7432020-12-11 09:53:34 +0000133/*
134 * \struct Camera3StreamConfig
135 * \brief Data to store StreamConfiguration associated with camera3_stream(s)
136 * \var streams List of the pairs of a stream requested by Android HAL client
137 * and CameraStream::Type associated with the stream
138 * \var config StreamConfiguration for streams
139 */
140struct Camera3StreamConfig {
141 struct Camera3Stream {
142 camera3_stream_t *stream;
143 CameraStream::Type type;
144 };
145
146 std::vector<Camera3Stream> streams;
147 StreamConfiguration config;
148};
149
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000150/*
151 * Reorder the configurations so that libcamera::Camera can accept them as much
152 * as possible. The sort rule is as follows.
153 * 1.) The configuration for NV12 request whose resolution is the largest.
154 * 2.) The configuration for JPEG request.
155 * 3.) Others. Larger resolutions and different formats are put earlier.
156 */
157void sortCamera3StreamConfigs(std::vector<Camera3StreamConfig> &unsortedConfigs,
158 const camera3_stream_t *jpegStream)
159{
160 const Camera3StreamConfig *jpegConfig = nullptr;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200161
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000162 std::map<PixelFormat, std::vector<const Camera3StreamConfig *>> formatToConfigs;
163 for (const auto &streamConfig : unsortedConfigs) {
164 if (jpegStream && !jpegConfig) {
165 const auto &streams = streamConfig.streams;
166 if (std::find_if(streams.begin(), streams.end(),
167 [jpegStream](const auto &stream) {
168 return stream.stream == jpegStream;
169 }) != streams.end()) {
170 jpegConfig = &streamConfig;
171 continue;
172 }
173 }
174 formatToConfigs[streamConfig.config.pixelFormat].push_back(&streamConfig);
175 }
176
177 if (jpegStream && !jpegConfig)
178 LOG(HAL, Fatal) << "No Camera3StreamConfig is found for JPEG";
179
180 for (auto &fmt : formatToConfigs) {
181 auto &streamConfigs = fmt.second;
182
183 /* Sorted by resolution. Smaller is put first. */
184 std::sort(streamConfigs.begin(), streamConfigs.end(),
185 [](const auto *streamConfigA, const auto *streamConfigB) {
186 const Size &sizeA = streamConfigA->config.size;
187 const Size &sizeB = streamConfigB->config.size;
188 return sizeA < sizeB;
189 });
190 }
191
192 std::vector<Camera3StreamConfig> sortedConfigs;
193 sortedConfigs.reserve(unsortedConfigs.size());
194
195 /*
196 * NV12 is the most prioritized format. Put the configuration with NV12
197 * and the largest resolution first.
198 */
199 const auto nv12It = formatToConfigs.find(formats::NV12);
200 if (nv12It != formatToConfigs.end()) {
201 auto &nv12Configs = nv12It->second;
Laurent Pinchartbd4894d2020-12-12 05:22:31 +0200202 const Camera3StreamConfig *nv12Largest = nv12Configs.back();
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000203
204 /*
205 * If JPEG will be created from NV12 and the size is larger than
206 * the largest NV12 configurations, then put the NV12
207 * configuration for JPEG first.
208 */
209 if (jpegConfig && jpegConfig->config.pixelFormat == formats::NV12) {
210 const Size &nv12SizeForJpeg = jpegConfig->config.size;
211 const Size &nv12LargestSize = nv12Largest->config.size;
212
213 if (nv12LargestSize < nv12SizeForJpeg) {
214 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
215 sortedConfigs.push_back(std::move(*jpegConfig));
216 jpegConfig = nullptr;
217 }
218 }
219
220 LOG(HAL, Debug) << "Insert " << nv12Largest->config.toString();
221 sortedConfigs.push_back(*nv12Largest);
222 nv12Configs.pop_back();
223
224 if (nv12Configs.empty())
225 formatToConfigs.erase(nv12It);
226 }
227
228 /* If the configuration for JPEG is there, then put it. */
229 if (jpegConfig) {
230 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
231 sortedConfigs.push_back(std::move(*jpegConfig));
232 jpegConfig = nullptr;
233 }
234
235 /*
236 * Put configurations with different formats and larger resolutions
237 * earlier.
238 */
239 while (!formatToConfigs.empty()) {
240 for (auto it = formatToConfigs.begin(); it != formatToConfigs.end();) {
241 auto &configs = it->second;
242 LOG(HAL, Debug) << "Insert " << configs.back()->config.toString();
243 sortedConfigs.push_back(*configs.back());
244 configs.pop_back();
245
246 if (configs.empty())
247 it = formatToConfigs.erase(it);
248 else
249 it++;
250 }
251 }
252
253 ASSERT(sortedConfigs.size() == unsortedConfigs.size());
254
255 unsortedConfigs = sortedConfigs;
256}
257
258} /* namespace */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200259
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100260MappedCamera3Buffer::MappedCamera3Buffer(const buffer_handle_t camera3buffer,
261 int flags)
262{
263 maps_.reserve(camera3buffer->numFds);
264 error_ = 0;
265
266 for (int i = 0; i < camera3buffer->numFds; i++) {
267 if (camera3buffer->data[i] == -1)
268 continue;
269
270 off_t length = lseek(camera3buffer->data[i], 0, SEEK_END);
271 if (length < 0) {
272 error_ = -errno;
273 LOG(HAL, Error) << "Failed to query plane length";
274 break;
275 }
276
277 void *address = mmap(nullptr, length, flags, MAP_SHARED,
278 camera3buffer->data[i], 0);
279 if (address == MAP_FAILED) {
280 error_ = -errno;
281 LOG(HAL, Error) << "Failed to mmap plane";
282 break;
283 }
284
285 maps_.emplace_back(static_cast<uint8_t *>(address),
286 static_cast<size_t>(length));
287 }
288}
289
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200290/*
291 * \struct Camera3RequestDescriptor
292 *
293 * A utility structure that groups information about a capture request to be
294 * later re-used at request complete time to notify the framework.
295 */
296
297CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100298 Camera *camera, const camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200299{
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100300 frameNumber_ = camera3Request->frame_number;
301
Jacopo Mondi4b18b822021-01-21 11:10:08 +0100302 /* Copy the camera3 request stream information for later access. */
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100303 numBuffers_ = camera3Request->num_output_buffers;
304 buffers_ = new camera3_stream_buffer_t[numBuffers_];
Jacopo Mondi4b18b822021-01-21 11:10:08 +0100305 for (unsigned int i = 0; i < numBuffers_; ++i)
306 buffers_[i] = camera3Request->output_buffers[i];
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200307
308 /*
309 * FrameBuffer instances created by wrapping a camera3 provided dmabuf
310 * are emplaced in this vector of unique_ptr<> for lifetime management.
311 */
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100312 frameBuffers_.reserve(numBuffers_);
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200313
Jacopo Mondi9e6eece2021-01-21 12:52:10 +0100314 /* Clone the controls associated with the camera3 request. */
315 settings_ = CameraMetadata(camera3Request->settings);
316
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200317 /*
318 * Create the libcamera::Request unique_ptr<> to tie its lifetime
319 * to the descriptor's one. Set the descriptor's address as the
320 * request's cookie to retrieve it at completion time.
321 */
Kieran Bingham37c18c22020-10-21 14:54:11 +0100322 request_ = std::make_unique<CaptureRequest>(camera,
323 reinterpret_cast<uint64_t>(this));
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200324}
325
326CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
327{
Kieran Bingham37c18c22020-10-21 14:54:11 +0100328 delete[] buffers_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200329}
330
331/*
332 * \class CameraDevice
333 *
334 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200335 * the camera3_device_t interface, bridging calls received from the Android
336 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200337 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200338 * The class translates parameters and operations from the Camera HALv3 API to
339 * the libcamera API to provide static information for a Camera, create request
340 * templates for it, process capture requests and then deliver capture results
341 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200342 */
343
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300344CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000345 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200346 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200347{
348 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100349
350 /*
351 * \todo Determine a more accurate value for this during
352 * streamConfiguration.
353 */
354 maxJpegBufferSize_ = 13 << 20; /* 13631488 from USB HAL */
Paul Elder229653a2021-01-21 17:44:14 +0900355
356 maker_ = "libcamera";
357 model_ = "cameraModel";
358
359 /* \todo Support getting properties on Android */
360 std::ifstream fstream("/var/cache/camera/camera.prop");
361 if (!fstream.is_open())
362 return;
363
364 std::string line;
365 while (std::getline(fstream, line)) {
366 std::string::size_type delimPos = line.find("=");
367 if (delimPos == std::string::npos)
368 continue;
369 std::string key = line.substr(0, delimPos);
370 std::string val = line.substr(delimPos + 1);
371
372 if (!key.compare("ro.product.model"))
373 model_ = val;
374 else if (!key.compare("ro.product.manufacturer"))
375 maker_ = val;
376 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200377}
378
379CameraDevice::~CameraDevice()
380{
381 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300382 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200383
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200384 for (auto &it : requestTemplates_)
385 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200386}
387
Umang Jainf8e28132020-08-21 14:46:08 +0000388std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
389 const std::shared_ptr<Camera> &cam)
390{
391 CameraDevice *camera = new CameraDevice(id, cam);
392 return std::shared_ptr<CameraDevice>(camera);
393}
394
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200395/*
396 * Initialize the camera static information.
397 * This method is called before the camera device is opened.
398 */
399int CameraDevice::initialize()
400{
401 /* Initialize orientation and facing side of the camera. */
402 const ControlList &properties = camera_->properties();
403
404 if (properties.contains(properties::Location)) {
405 int32_t location = properties.get(properties::Location);
406 switch (location) {
407 case properties::CameraLocationFront:
408 facing_ = CAMERA_FACING_FRONT;
409 break;
410 case properties::CameraLocationBack:
411 facing_ = CAMERA_FACING_BACK;
412 break;
413 case properties::CameraLocationExternal:
414 facing_ = CAMERA_FACING_EXTERNAL;
415 break;
416 }
417 }
418
419 /*
Umang Jaine9176552020-09-09 16:17:54 +0530420 * The Android orientation metadata specifies its rotation correction
421 * value in clockwise direction whereas libcamera specifies the
422 * rotation property in anticlockwise direction. Read the libcamera's
423 * rotation property (anticlockwise) and compute the corresponding
424 * value for clockwise direction as required by the Android orientation
425 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200426 */
Umang Jaine9176552020-09-09 16:17:54 +0530427 if (properties.contains(properties::Rotation)) {
428 int rotation = properties.get(properties::Rotation);
429 orientation_ = (360 - rotation) % 360;
430 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200431
Jacopo Mondi117588b2020-05-23 18:53:54 +0200432 int ret = camera_->acquire();
433 if (ret) {
434 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
435 return ret;
436 }
437
438 ret = initializeStreamConfigurations();
439 camera_->release();
440 return ret;
441}
442
Jacopo Mondibfee6312020-09-01 17:42:13 +0200443std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
444 const PixelFormat &pixelFormat,
445 const std::vector<Size> &resolutions)
446{
447 std::vector<Size> supportedResolutions;
448
449 StreamConfiguration &cfg = cameraConfig->at(0);
450 for (const Size &res : resolutions) {
451 cfg.pixelFormat = pixelFormat;
452 cfg.size = res;
453
454 CameraConfiguration::Status status = cameraConfig->validate();
455 if (status != CameraConfiguration::Valid) {
456 LOG(HAL, Debug) << cfg.toString() << " not supported";
457 continue;
458 }
459
460 LOG(HAL, Debug) << cfg.toString() << " supported";
461
462 supportedResolutions.push_back(res);
463 }
464
465 return supportedResolutions;
466}
467
Jacopo Mondi49610332020-09-01 18:11:34 +0200468std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
469{
470 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200471 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200472 StreamConfiguration &cfg = cameraConfig->at(0);
473 const StreamFormats &formats = cfg.formats();
474 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
475
476 return supportedResolutions;
477}
478
Jacopo Mondi117588b2020-05-23 18:53:54 +0200479/*
480 * Initialize the format conversion map to translate from Android format
481 * identifier to libcamera pixel formats and fill in the list of supported
482 * stream configurations to be reported to the Android camera framework through
483 * the static stream configuration metadata.
484 */
485int CameraDevice::initializeStreamConfigurations()
486{
487 /*
488 * Get the maximum output resolutions
489 * \todo Get this from the camera properties once defined
490 */
491 std::unique_ptr<CameraConfiguration> cameraConfig =
492 camera_->generateConfiguration({ StillCapture });
493 if (!cameraConfig) {
494 LOG(HAL, Error) << "Failed to get maximum resolution";
495 return -EINVAL;
496 }
497 StreamConfiguration &cfg = cameraConfig->at(0);
498
499 /*
500 * \todo JPEG - Adjust the maximum available resolution by taking the
501 * JPEG encoder requirements into account (alignment and aspect ratio).
502 */
503 const Size maxRes = cfg.size;
504 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
505
506 /*
507 * Build the list of supported image resolutions.
508 *
509 * The resolutions listed in camera3Resolution are mandatory to be
510 * supported, up to the camera maximum resolution.
511 *
512 * Augment the list by adding resolutions calculated from the camera
513 * maximum one.
514 */
515 std::vector<Size> cameraResolutions;
516 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
517 std::back_inserter(cameraResolutions),
518 [&](const Size &res) { return res < maxRes; });
519
520 /*
521 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
522 * resolution.
523 */
524 for (unsigned int divider = 2;; divider <<= 1) {
525 Size derivedSize{
526 maxRes.width / divider,
527 maxRes.height / divider,
528 };
529
530 if (derivedSize.width < 320 ||
531 derivedSize.height < 240)
532 break;
533
534 cameraResolutions.push_back(derivedSize);
535 }
536 cameraResolutions.push_back(maxRes);
537
538 /* Remove duplicated entries from the list of supported resolutions. */
539 std::sort(cameraResolutions.begin(), cameraResolutions.end());
540 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
541 cameraResolutions.erase(last, cameraResolutions.end());
542
543 /*
544 * Build the list of supported camera formats.
545 *
546 * To each Android format a list of compatible libcamera formats is
547 * associated. The first libcamera format that tests successful is added
548 * to the format translation map used when configuring the streams.
549 * It is then tested against the list of supported camera resolutions to
550 * build the stream configuration map reported through the camera static
551 * metadata.
552 */
553 for (const auto &format : camera3FormatsMap) {
554 int androidFormat = format.first;
555 const Camera3Format &camera3Format = format.second;
556 const std::vector<PixelFormat> &libcameraFormats =
557 camera3Format.libcameraFormats;
558
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200559 LOG(HAL, Debug) << "Trying to map Android format "
560 << camera3Format.name;
561
Jacopo Mondi117588b2020-05-23 18:53:54 +0200562 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200563 * JPEG is always supported, either produced directly by the
564 * camera, or encoded in the HAL.
565 */
566 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
567 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200568 LOG(HAL, Debug) << "Mapped Android format "
569 << camera3Format.name << " to "
570 << formats::MJPEG.toString()
571 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200572 continue;
573 }
574
575 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200576 * Test the libcamera formats that can produce images
577 * compatible with the format defined by Android.
578 */
579 PixelFormat mappedFormat;
580 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200581
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200582 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
583
Jacopo Mondi117588b2020-05-23 18:53:54 +0200584 /*
585 * The stream configuration size can be adjusted,
586 * not the pixel format.
587 *
588 * \todo This could be simplified once all pipeline
589 * handlers will report the StreamFormats list of
590 * supported formats.
591 */
592 cfg.pixelFormat = pixelFormat;
593
594 CameraConfiguration::Status status = cameraConfig->validate();
595 if (status != CameraConfiguration::Invalid &&
596 cfg.pixelFormat == pixelFormat) {
597 mappedFormat = pixelFormat;
598 break;
599 }
600 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200601
602 if (!mappedFormat.isValid()) {
603 /* If the format is not mandatory, skip it. */
604 if (!camera3Format.mandatory)
605 continue;
606
607 LOG(HAL, Error)
608 << "Failed to map mandatory Android format "
609 << camera3Format.name << " ("
610 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200611 return -EINVAL;
612 }
613
614 /*
615 * Record the mapping and then proceed to generate the
616 * stream configurations map, by testing the image resolutions.
617 */
618 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200619 LOG(HAL, Debug) << "Mapped Android format "
620 << camera3Format.name << " to "
621 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200622
Jacopo Mondi49610332020-09-01 18:11:34 +0200623 std::vector<Size> resolutions;
624 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
625 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
626 resolutions = getRawResolutions(mappedFormat);
627 else
628 resolutions = getYUVResolutions(cameraConfig.get(),
629 mappedFormat,
630 cameraResolutions);
631
Jacopo Mondibfee6312020-09-01 17:42:13 +0200632 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200633 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200634
635 /*
636 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
637 * from which JPEG is produced, add an entry for
638 * the JPEG stream.
639 *
640 * \todo Wire the JPEG encoder to query the supported
641 * sizes provided a list of formats it can encode.
642 *
643 * \todo Support JPEG streams produced by the Camera
644 * natively.
645 */
646 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888)
647 streamConfigurations_.push_back(
648 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200649 }
650 }
651
652 LOG(HAL, Debug) << "Collected stream configuration map: ";
653 for (const auto &entry : streamConfigurations_)
654 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200655 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200656
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200657 return 0;
658}
659
660/*
661 * Open a camera device. The static information on the camera shall have been
662 * initialized with a call to CameraDevice::initialize().
663 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200664int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200665{
666 int ret = camera_->acquire();
667 if (ret) {
668 LOG(HAL, Error) << "Failed to acquire the camera";
669 return ret;
670 }
671
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200672 /* Initialize the hw_device_t in the instance camera3_module_t. */
673 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
674 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
675 camera3Device_.common.module = (hw_module_t *)hardwareModule;
676 camera3Device_.common.close = hal_dev_close;
677
678 /*
679 * The camera device operations. These actually implement
680 * the Android Camera HALv3 interface.
681 */
682 camera3Device_.ops = &hal_dev_ops;
683 camera3Device_.priv = this;
684
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200685 return 0;
686}
687
688void CameraDevice::close()
689{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200690 streams_.clear();
691
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200692 worker_.stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200693 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200694 camera_->release();
695
696 running_ = false;
697}
698
699void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
700{
701 callbacks_ = callbacks;
702}
703
Jacopo Mondia80d3812020-05-26 12:31:35 +0200704std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
705{
706 /*
707 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondie9c28752021-02-03 14:47:45 +0100708 * Currently: 53 entries, 846 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200709 */
Jacopo Mondieec6c542020-12-09 18:16:11 +0100710 uint32_t numEntries = 53;
Jacopo Mondie9c28752021-02-03 14:47:45 +0100711 uint32_t byteSize = 846;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200712
713 /*
714 * Calculate space occupation in bytes for dynamically built metadata
715 * entries.
716 *
Jacopo Mondi00982fb2021-02-04 16:57:55 +0100717 * Each stream configuration entry requires 48 bytes:
Jacopo Mondia80d3812020-05-26 12:31:35 +0200718 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200719 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
720 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200721 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200722
Jacopo Mondi9e807052021-02-04 15:32:00 +0100723 /*
724 * 2 32bits integers for each HAL_PIXEL_FORMAT_BLOB for thumbnail sizes
725 * 2 32bits integers for the (0, 0) thumbnail size
726 *
727 * This is a worst case estimates as different configurations with the
728 * same aspect ratio will generate the same size.
729 */
730 for (const auto &entry : streamConfigurations_) {
731 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
732 continue;
733
734 byteSize += 8;
735 }
736 byteSize += 8;
737
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300738 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200739}
740
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200741/*
742 * Return static information for the camera.
743 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200744const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200745{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200746 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300747 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200748
749 /*
750 * The here reported metadata are enough to implement a basic capture
751 * example application, but a real camera implementation will require
752 * more.
753 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200754 uint32_t numEntries;
755 uint32_t byteSize;
756 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
757 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300758 if (!staticMetadata_->isValid()) {
759 LOG(HAL, Error) << "Failed to allocate static metadata";
760 delete staticMetadata_;
761 staticMetadata_ = nullptr;
762 return nullptr;
763 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200764
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200765 const ControlInfoMap &controlsInfo = camera_->controls();
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100766 const ControlList &properties = camera_->properties();
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200767
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200768 /* Color correction static metadata. */
Jacopo Mondi63336862020-10-08 16:18:26 +0200769 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100770 std::vector<uint8_t> data;
771 data.reserve(3);
Jacopo Mondi63336862020-10-08 16:18:26 +0200772 const auto &infoMap = controlsInfo.find(&controls::draft::ColorCorrectionAberrationMode);
773 if (infoMap != controlsInfo.end()) {
774 for (const auto &value : infoMap->second.values())
775 data.push_back(value.get<int32_t>());
776 } else {
777 data.push_back(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
778 }
779 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
780 data.data(), data.size());
781 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200782
783 /* Control static metadata. */
784 std::vector<uint8_t> aeAvailableAntiBandingModes = {
785 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
786 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
787 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
788 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
789 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300790 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
791 aeAvailableAntiBandingModes.data(),
792 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200793
794 std::vector<uint8_t> aeAvailableModes = {
795 ANDROID_CONTROL_AE_MODE_ON,
796 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300797 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
798 aeAvailableModes.data(),
799 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200800
801 std::vector<int32_t> availableAeFpsTarget = {
802 15, 30,
803 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300804 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
805 availableAeFpsTarget.data(),
806 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200807
808 std::vector<int32_t> aeCompensationRange = {
809 0, 0,
810 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300811 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
812 aeCompensationRange.data(),
813 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200814
815 const camera_metadata_rational_t aeCompensationStep[] = {
816 { 0, 1 }
817 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300818 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
819 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200820
821 std::vector<uint8_t> availableAfModes = {
822 ANDROID_CONTROL_AF_MODE_OFF,
823 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300824 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
825 availableAfModes.data(),
826 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200827
828 std::vector<uint8_t> availableEffects = {
829 ANDROID_CONTROL_EFFECT_MODE_OFF,
830 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300831 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
832 availableEffects.data(),
833 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200834
835 std::vector<uint8_t> availableSceneModes = {
836 ANDROID_CONTROL_SCENE_MODE_DISABLED,
837 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300838 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
839 availableSceneModes.data(),
840 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200841
842 std::vector<uint8_t> availableStabilizationModes = {
843 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
844 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300845 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
846 availableStabilizationModes.data(),
847 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200848
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100849 /*
850 * \todo Inspect the Camera capabilities to report the available
851 * AWB modes. Default to AUTO as CTS tests require it.
852 */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200853 std::vector<uint8_t> availableAwbModes = {
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100854 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200855 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300856 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
857 availableAwbModes.data(),
858 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200859
860 std::vector<int32_t> availableMaxRegions = {
861 0, 0, 0,
862 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300863 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
864 availableMaxRegions.data(),
865 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200866
867 std::vector<uint8_t> sceneModesOverride = {
868 ANDROID_CONTROL_AE_MODE_ON,
869 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondif266c0e2021-02-03 16:34:40 +0100870 ANDROID_CONTROL_AF_MODE_OFF,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200871 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300872 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
873 sceneModesOverride.data(),
874 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200875
876 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300877 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
878 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200879
880 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300881 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
882 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200883
884 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300885 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
886 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200887
888 /* JPEG static metadata. */
Jacopo Mondi9e807052021-02-04 15:32:00 +0100889
890 /*
891 * Create the list of supported thumbnail sizes by inspecting the
892 * available JPEG resolutions collected in streamConfigurations_ and
893 * generate one entry for each aspect ratio.
894 *
895 * The JPEG thumbnailer can freely scale, so pick an arbitrary
896 * (160, 160) size as the bounding rectangle, which is then cropped to
897 * the different supported aspect ratios.
898 */
899 constexpr Size maxJpegThumbnail(160, 160);
900 std::vector<Size> thumbnailSizes;
901 thumbnailSizes.push_back({ 0, 0 });
902 for (const auto &entry : streamConfigurations_) {
903 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
904 continue;
905
906 Size thumbnailSize = maxJpegThumbnail
907 .boundedToAspectRatio({ entry.resolution.width,
908 entry.resolution.height });
909 thumbnailSizes.push_back(thumbnailSize);
910 }
911
912 std::sort(thumbnailSizes.begin(), thumbnailSizes.end());
913 auto last = std::unique(thumbnailSizes.begin(), thumbnailSizes.end());
914 thumbnailSizes.erase(last, thumbnailSizes.end());
915
916 /* Transform sizes in to a list of integers that can be consumed. */
917 std::vector<int32_t> thumbnailEntries;
918 thumbnailEntries.reserve(thumbnailSizes.size() * 2);
919 for (const auto &size : thumbnailSizes) {
920 thumbnailEntries.push_back(size.width);
921 thumbnailEntries.push_back(size.height);
922 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300923 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Jacopo Mondi9e807052021-02-04 15:32:00 +0100924 thumbnailEntries.data(), thumbnailEntries.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200925
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100926 /*
927 * \todo Calculate the maximum JPEG buffer size by asking the encoder
928 * giving the maximum frame size required.
929 */
930 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
931
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200932 /* Sensor static metadata. */
Jacopo Mondicda41ff2020-12-30 17:18:51 +0100933 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100934 const Size &size =
Jacopo Mondi0ed05322020-12-23 18:34:34 +0100935 properties.get(properties::PixelArraySize);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100936 std::vector<int32_t> data{
937 static_cast<int32_t>(size.width),
938 static_cast<int32_t>(size.height),
939 };
940 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
941 data.data(), data.size());
942 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200943
Jacopo Mondicda41ff2020-12-30 17:18:51 +0100944 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100945 const Span<const Rectangle> &rects =
Jacopo Mondi0ed05322020-12-23 18:34:34 +0100946 properties.get(properties::PixelArrayActiveAreas);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100947 std::vector<int32_t> data{
948 static_cast<int32_t>(rects[0].x),
949 static_cast<int32_t>(rects[0].y),
950 static_cast<int32_t>(rects[0].width),
951 static_cast<int32_t>(rects[0].height),
952 };
953 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
954 data.data(), data.size());
955 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200956
957 int32_t sensitivityRange[] = {
958 32, 2400,
959 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300960 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
961 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200962
Jacopo Mondicb35ed22020-12-18 16:28:43 +0100963 /* Report the color filter arrangement if the camera reports it. */
964 if (properties.contains(properties::draft::ColorFilterArrangement)) {
965 uint8_t filterArr = properties.get(properties::draft::ColorFilterArrangement);
966 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
967 &filterArr, 1);
968 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200969
Jacopo Mondi753d7532021-01-02 12:34:06 +0100970 const auto &exposureInfo = controlsInfo.find(&controls::ExposureTime);
971 if (exposureInfo != controlsInfo.end()) {
972 int64_t exposureTimeRange[2] = {
973 exposureInfo->second.min().get<int32_t>() * 1000LL,
974 exposureInfo->second.max().get<int32_t>() * 1000LL,
975 };
976 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
977 &exposureTimeRange, 2);
978 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200979
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200980 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200981
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200982 std::vector<int32_t> testPatterModes = {
983 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
984 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300985 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
986 testPatterModes.data(),
987 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200988
989 std::vector<float> physicalSize = {
990 2592, 1944,
991 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300992 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
993 physicalSize.data(),
994 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200995
996 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300997 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
998 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200999
1000 /* Statistics static metadata. */
1001 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001002 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1003 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001004
1005 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001006 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1007 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001008
Jacopo Mondi2c618502020-10-08 16:47:36 +02001009 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001010 std::vector<uint8_t> data;
1011 data.reserve(2);
Jacopo Mondi2c618502020-10-08 16:47:36 +02001012 const auto &infoMap = controlsInfo.find(&controls::draft::LensShadingMapMode);
1013 if (infoMap != controlsInfo.end()) {
1014 for (const auto &value : infoMap->second.values())
1015 data.push_back(value.get<int32_t>());
1016 } else {
1017 data.push_back(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
1018 }
1019 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
1020 data.data(), data.size());
1021 }
1022
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001023 /* Sync static metadata. */
1024 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +03001025 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001026
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001027 /* Flash static metadata. */
1028 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001029 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
1030 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001031
1032 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001033 std::vector<float> lensApertures = {
1034 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001035 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001036 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
1037 lensApertures.data(),
1038 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001039
Jacopo Mondi64f4f662020-05-25 16:08:22 +02001040 uint8_t lensFacing;
1041 switch (facing_) {
1042 default:
1043 case CAMERA_FACING_FRONT:
1044 lensFacing = ANDROID_LENS_FACING_FRONT;
1045 break;
1046 case CAMERA_FACING_BACK:
1047 lensFacing = ANDROID_LENS_FACING_BACK;
1048 break;
1049 case CAMERA_FACING_EXTERNAL:
1050 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
1051 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +01001052 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001053 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001054
1055 std::vector<float> lensFocalLenghts = {
1056 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001057 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001058 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1059 lensFocalLenghts.data(),
1060 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001061
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001062 std::vector<uint8_t> opticalStabilizations = {
1063 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
1064 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001065 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1066 opticalStabilizations.data(),
1067 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001068
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001069 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001070 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1071 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001072
1073 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001074 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1075 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001076
1077 /* Noise reduction modes. */
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001078 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001079 std::vector<uint8_t> data;
1080 data.reserve(5);
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001081 const auto &infoMap = controlsInfo.find(&controls::draft::NoiseReductionMode);
1082 if (infoMap != controlsInfo.end()) {
1083 for (const auto &value : infoMap->second.values())
1084 data.push_back(value.get<int32_t>());
1085 } else {
1086 data.push_back(ANDROID_NOISE_REDUCTION_MODE_OFF);
1087 }
1088 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
1089 data.data(), data.size());
1090 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001091
1092 /* Scaler static metadata. */
Jacopo Mondi31a1a622021-01-03 19:57:36 +01001093 {
1094 /*
1095 * \todo The digital zoom factor is a property that depends
1096 * on the desired output configuration and the sensor frame size
1097 * input to the ISP. This information is not available to the
1098 * Android HAL, not at initialization time at least.
1099 *
1100 * As a workaround rely on pipeline handlers initializing the
1101 * ScalerCrop control with the camera default configuration and
1102 * use the maximum and minimum crop rectangles to calculate the
1103 * digital zoom factor.
1104 */
1105 const auto info = controlsInfo.find(&controls::ScalerCrop);
1106 Rectangle min = info->second.min().get<Rectangle>();
1107 Rectangle max = info->second.max().get<Rectangle>();
1108 float maxZoom = std::min(1.0f * max.width / min.width,
1109 1.0f * max.height / min.height);
1110 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1111 &maxZoom, 1);
1112 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001113
Jacopo Mondibde7b982020-05-25 17:18:28 +02001114 std::vector<uint32_t> availableStreamConfigurations;
1115 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
1116 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +02001117 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +02001118 availableStreamConfigurations.push_back(entry.resolution.width);
1119 availableStreamConfigurations.push_back(entry.resolution.height);
1120 availableStreamConfigurations.push_back(
1121 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
1122 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001123 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1124 availableStreamConfigurations.data(),
1125 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001126
1127 std::vector<int64_t> availableStallDurations = {
1128 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
1129 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001130 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1131 availableStallDurations.data(),
1132 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001133
Jacopo Mondibde7b982020-05-25 17:18:28 +02001134 /* \todo Collect the minimum frame duration from the camera. */
1135 std::vector<int64_t> minFrameDurations;
1136 minFrameDurations.reserve(streamConfigurations_.size() * 4);
1137 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +02001138 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +02001139 minFrameDurations.push_back(entry.resolution.width);
1140 minFrameDurations.push_back(entry.resolution.height);
1141 minFrameDurations.push_back(33333333);
1142 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001143 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1144 minFrameDurations.data(),
1145 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001146
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001147 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001148 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001149
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001150 /* Info static metadata. */
1151 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001152 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
1153 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001154
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001155 /* Request static metadata. */
1156 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001157 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1158 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001159
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +02001160 {
1161 /* Default the value to 2 if not reported by the camera. */
1162 uint8_t maxPipelineDepth = 2;
1163 const auto &infoMap = controlsInfo.find(&controls::draft::PipelineDepth);
1164 if (infoMap != controlsInfo.end())
1165 maxPipelineDepth = infoMap->second.max().get<int32_t>();
1166 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
1167 &maxPipelineDepth, 1);
1168 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001169
Niklas Söderlunda2a6f952020-07-21 00:16:02 +02001170 /* LIMITED does not support reprocessing. */
1171 uint32_t maxNumInputStreams = 0;
1172 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1173 &maxNumInputStreams, 1);
1174
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001175 std::vector<uint8_t> availableCapabilities = {
1176 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
1177 };
Niklas Söderlund7876d632020-07-21 00:16:24 +02001178
1179 /* Report if camera supports RAW. */
Jacopo Mondieec6c542020-12-09 18:16:11 +01001180 bool rawStreamAvailable = false;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001181 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +02001182 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +02001183 if (cameraConfig && !cameraConfig->empty()) {
1184 const PixelFormatInfo &info =
1185 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
Niklas Söderlund35de31e2020-12-31 00:11:59 +01001186 /* Only advertise RAW support if RAW16 is possible. */
1187 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW &&
1188 info.bitsPerPixel == 16) {
Jacopo Mondieec6c542020-12-09 18:16:11 +01001189 rawStreamAvailable = true;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001190 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
Jacopo Mondieec6c542020-12-09 18:16:11 +01001191 }
Niklas Söderlund7876d632020-07-21 00:16:24 +02001192 }
1193
Jacopo Mondieec6c542020-12-09 18:16:11 +01001194 /* Number of { RAW, YUV, JPEG } supported output streams */
1195 int32_t numOutStreams[] = { rawStreamAvailable, 2, 1 };
1196 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
1197 &numOutStreams, 3);
1198
Laurent Pinchart39860092019-09-05 03:12:34 +03001199 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1200 availableCapabilities.data(),
1201 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001202
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001203 std::vector<int32_t> availableCharacteristicsKeys = {
1204 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
1205 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
1206 ANDROID_CONTROL_AE_AVAILABLE_MODES,
1207 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1208 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
1209 ANDROID_CONTROL_AE_COMPENSATION_STEP,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001210 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001211 ANDROID_CONTROL_AF_AVAILABLE_MODES,
1212 ANDROID_CONTROL_AVAILABLE_EFFECTS,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001213 ANDROID_CONTROL_AVAILABLE_MODES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001214 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
1215 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
1216 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001217 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001218 ANDROID_CONTROL_MAX_REGIONS,
1219 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001220 ANDROID_FLASH_INFO_AVAILABLE,
1221 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001222 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001223 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001224 ANDROID_LENS_FACING,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001225 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001226 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1227 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1228 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1229 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1230 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001231 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1232 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1233 ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001234 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1235 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001236 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1237 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1238 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1239 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1240 ANDROID_SCALER_CROPPING_TYPE,
1241 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
1242 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
1243 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
1244 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
1245 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1246 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
1247 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
1248 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1249 ANDROID_SENSOR_ORIENTATION,
1250 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1251 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1252 ANDROID_SYNC_MAX_LATENCY,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001253 };
1254 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
1255 availableCharacteristicsKeys.data(),
1256 availableCharacteristicsKeys.size());
1257
1258 std::vector<int32_t> availableRequestKeys = {
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001259 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1260 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001261 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001262 ANDROID_CONTROL_AE_LOCK,
1263 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001264 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001265 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001266 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001267 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001268 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001269 ANDROID_CONTROL_AWB_MODE,
1270 ANDROID_CONTROL_CAPTURE_INTENT,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001271 ANDROID_CONTROL_EFFECT_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001272 ANDROID_CONTROL_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001273 ANDROID_CONTROL_SCENE_MODE,
1274 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001275 ANDROID_FLASH_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001276 ANDROID_JPEG_ORIENTATION,
1277 ANDROID_JPEG_QUALITY,
1278 ANDROID_JPEG_THUMBNAIL_QUALITY,
1279 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001280 ANDROID_LENS_APERTURE,
1281 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001282 ANDROID_NOISE_REDUCTION_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001283 ANDROID_SCALER_CROP_REGION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001284 ANDROID_STATISTICS_FACE_DETECT_MODE
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001285 };
1286 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
1287 availableRequestKeys.data(),
1288 availableRequestKeys.size());
1289
1290 std::vector<int32_t> availableResultKeys = {
Jacopo Mondi520c3662021-02-03 14:44:34 +01001291 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001292 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondie9c28752021-02-03 14:47:45 +01001293 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001294 ANDROID_CONTROL_AE_LOCK,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001295 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001296 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1297 ANDROID_CONTROL_AE_STATE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001298 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001299 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001300 ANDROID_CONTROL_AF_STATE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001301 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001302 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001303 ANDROID_CONTROL_AWB_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001304 ANDROID_CONTROL_AWB_STATE,
1305 ANDROID_CONTROL_CAPTURE_INTENT,
1306 ANDROID_CONTROL_EFFECT_MODE,
1307 ANDROID_CONTROL_MODE,
1308 ANDROID_CONTROL_SCENE_MODE,
1309 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
1310 ANDROID_FLASH_MODE,
1311 ANDROID_FLASH_STATE,
Paul Elderabfabdd2021-01-23 13:54:28 +09001312 ANDROID_JPEG_GPS_COORDINATES,
1313 ANDROID_JPEG_GPS_PROCESSING_METHOD,
1314 ANDROID_JPEG_GPS_TIMESTAMP,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001315 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001316 ANDROID_JPEG_QUALITY,
1317 ANDROID_JPEG_SIZE,
Paul Elder12646282021-01-23 13:56:01 +09001318 ANDROID_JPEG_THUMBNAIL_QUALITY,
1319 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001320 ANDROID_LENS_APERTURE,
1321 ANDROID_LENS_FOCAL_LENGTH,
1322 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1323 ANDROID_LENS_STATE,
1324 ANDROID_NOISE_REDUCTION_MODE,
1325 ANDROID_REQUEST_PIPELINE_DEPTH,
1326 ANDROID_SCALER_CROP_REGION,
1327 ANDROID_SENSOR_EXPOSURE_TIME,
1328 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1329 ANDROID_SENSOR_TIMESTAMP,
1330 ANDROID_STATISTICS_FACE_DETECT_MODE,
1331 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1332 ANDROID_STATISTICS_SCENE_FLICKER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001333 };
1334 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1335 availableResultKeys.data(),
1336 availableResultKeys.size());
1337
Laurent Pinchart39860092019-09-05 03:12:34 +03001338 if (!staticMetadata_->isValid()) {
1339 LOG(HAL, Error) << "Failed to construct static metadata";
1340 delete staticMetadata_;
1341 staticMetadata_ = nullptr;
1342 return nullptr;
1343 }
1344
1345 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001346}
1347
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001348CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001349{
Jacopo Mondi63703472019-09-04 16:18:22 +02001350 /*
1351 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001352 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001353 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001354 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001355 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001356 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001357 return nullptr;
1358 }
1359
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001360 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001361 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1362 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001363
1364 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001365 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1366 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001367
1368 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001369 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1370 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001371
1372 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001373 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1374 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001375
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001376 std::vector<int32_t> aeFpsTarget = {
1377 15, 30,
1378 };
1379 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1380 aeFpsTarget.data(),
1381 aeFpsTarget.size());
1382
1383 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1384 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1385 &aeAntibandingMode, 1);
1386
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001387 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001388 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1389 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001390
1391 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001392 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1393 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001394
1395 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001396 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1397 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001398
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001399 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001400 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1401 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001402
1403 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001404 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1405 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001406
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001407 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001408 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1409 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001410
1411 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001412 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1413 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001414
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001415 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1416 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1417
1418 float lensAperture = 2.53 / 100;
1419 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1420
1421 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1422 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1423 &opticalStabilization, 1);
1424
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001425 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001426 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1427 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001428
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001429 return requestTemplate;
1430}
1431
1432/*
1433 * Produce a metadata pack to be used as template for a capture request.
1434 */
1435const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1436{
1437 auto it = requestTemplates_.find(type);
1438 if (it != requestTemplates_.end())
1439 return it->second->get();
1440
1441 /* Use the capture intent matching the requested template type. */
1442 CameraMetadata *requestTemplate;
1443 uint8_t captureIntent;
1444 switch (type) {
1445 case CAMERA3_TEMPLATE_PREVIEW:
1446 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1447 break;
1448 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1449 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1450 break;
1451 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1452 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1453 break;
1454 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1455 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1456 break;
1457 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1458 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1459 break;
1460 case CAMERA3_TEMPLATE_MANUAL:
1461 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1462 break;
1463 default:
1464 LOG(HAL, Error) << "Invalid template request type: " << type;
1465 return nullptr;
1466 }
1467
1468 requestTemplate = requestTemplatePreview();
1469 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001470 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001471 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001472 return nullptr;
1473 }
1474
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001475 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1476 &captureIntent, 1);
1477
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001478 requestTemplates_[type] = requestTemplate;
1479 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001480}
1481
Hirokazu Hondac1ae9052020-10-28 18:50:23 +09001482PixelFormat CameraDevice::toPixelFormat(int format) const
Kieran Bingham43e3b802020-06-26 09:58:49 +01001483{
1484 /* Translate Android format code to libcamera pixel format. */
1485 auto it = formatsMap_.find(format);
1486 if (it == formatsMap_.end()) {
1487 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1488 << " not supported";
1489 return PixelFormat();
1490 }
1491
1492 return it->second;
1493}
1494
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001495/*
1496 * Inspect the stream_list to produce a list of StreamConfiguration to
1497 * be use to configure the Camera.
1498 */
1499int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1500{
Jacopo Mondi8fed6132020-12-04 15:26:47 +01001501 /* Before any configuration attempt, stop the camera if it's running. */
1502 if (running_) {
1503 worker_.stop();
1504 camera_->stop();
1505 running_ = false;
1506 }
1507
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001508 /*
1509 * Generate an empty configuration, and construct a StreamConfiguration
1510 * for each camera3_stream to add to it.
1511 */
1512 config_ = camera_->generateConfiguration();
1513 if (!config_) {
1514 LOG(HAL, Error) << "Failed to generate camera configuration";
1515 return -EINVAL;
1516 }
1517
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001518 /*
1519 * Clear and remove any existing configuration from previous calls, and
1520 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001521 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001522 */
1523 streams_.clear();
1524 streams_.reserve(stream_list->num_streams);
1525
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001526 std::vector<Camera3StreamConfig> streamConfigs;
1527 streamConfigs.reserve(stream_list->num_streams);
1528
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001529 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001530 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001531 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1532 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001533 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001534
Kieran Bingham43e3b802020-06-26 09:58:49 +01001535 PixelFormat format = toPixelFormat(stream->format);
1536
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001537 LOG(HAL, Info) << "Stream #" << i
1538 << ", direction: " << stream->stream_type
1539 << ", width: " << stream->width
1540 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001541 << ", format: " << utils::hex(stream->format)
1542 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001543
1544 if (!format.isValid())
1545 return -EINVAL;
1546
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001547 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001548 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1549 if (jpegStream) {
1550 LOG(HAL, Error)
1551 << "Multiple JPEG streams are not supported";
1552 return -EINVAL;
1553 }
1554
1555 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001556 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001557 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001558
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001559 Camera3StreamConfig streamConfig;
1560 streamConfig.streams = { { stream, CameraStream::Type::Direct } };
1561 streamConfig.config.size = size;
1562 streamConfig.config.pixelFormat = format;
1563 streamConfigs.push_back(std::move(streamConfig));
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001564 }
1565
Jacopo Mondic82f9442020-09-02 11:58:00 +02001566 /* Now handle the MJPEG streams, adding a new stream if required. */
1567 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001568 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001569 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001570
Jacopo Mondic82f9442020-09-02 11:58:00 +02001571 /* Search for a compatible stream in the non-JPEG ones. */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001572 for (size_t i = 0; i < streamConfigs.size(); ++i) {
1573 const auto &cfg = streamConfigs[i].config;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001574
1575 /*
1576 * \todo The PixelFormat must also be compatible with
1577 * the encoder.
1578 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001579 if (cfg.size.width != jpegStream->width ||
1580 cfg.size.height != jpegStream->height)
1581 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001582
Jacopo Mondic82f9442020-09-02 11:58:00 +02001583 LOG(HAL, Info)
1584 << "Android JPEG stream mapped to libcamera stream " << i;
1585
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001586 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001587 index = i;
1588 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001589 }
1590
1591 /*
1592 * Without a compatible match for JPEG encoding we must
1593 * introduce a new stream to satisfy the request requirements.
1594 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001595 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001596 /*
1597 * \todo The pixelFormat should be a 'best-fit' choice
1598 * and may require a validation cycle. This is not yet
1599 * handled, and should be considered as part of any
1600 * stream configuration reworks.
1601 */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001602 Camera3StreamConfig streamConfig;
1603 streamConfig.config.size.width = jpegStream->width;
1604 streamConfig.config.size.height = jpegStream->height;
1605 streamConfig.config.pixelFormat = formats::NV12;
1606 streamConfigs.push_back(std::move(streamConfig));
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001607
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001608 LOG(HAL, Info) << "Adding " << streamConfig.config.toString()
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001609 << " for MJPEG support";
1610
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001611 type = CameraStream::Type::Internal;
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001612 index = streamConfigs.size() - 1;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001613 }
1614
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001615 streamConfigs[index].streams.push_back({ jpegStream, type });
1616 }
1617
Hirokazu Honda26d90af2020-12-11 09:53:36 +00001618 sortCamera3StreamConfigs(streamConfigs, jpegStream);
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001619 for (const auto &streamConfig : streamConfigs) {
1620 config_->addConfiguration(streamConfig.config);
1621
1622 for (auto &stream : streamConfig.streams) {
1623 streams_.emplace_back(this, stream.type, stream.stream,
1624 config_->size() - 1);
1625 stream.stream->priv = static_cast<void *>(&streams_.back());
1626 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001627 }
1628
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001629 switch (config_->validate()) {
1630 case CameraConfiguration::Valid:
1631 break;
1632 case CameraConfiguration::Adjusted:
1633 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001634
1635 for (const StreamConfiguration &cfg : *config_)
1636 LOG(HAL, Info) << " - " << cfg.toString();
1637
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001638 config_.reset();
1639 return -EINVAL;
1640 case CameraConfiguration::Invalid:
1641 LOG(HAL, Info) << "Camera configuration invalid";
1642 config_.reset();
1643 return -EINVAL;
1644 }
1645
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001646 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001647 * Once the CameraConfiguration has been adjusted/validated
1648 * it can be applied to the camera.
1649 */
1650 int ret = camera_->configure(config_.get());
1651 if (ret) {
1652 LOG(HAL, Error) << "Failed to configure camera '"
1653 << camera_->id() << "'";
1654 return ret;
1655 }
1656
1657 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001658 * Configure the HAL CameraStream instances using the associated
1659 * StreamConfiguration and set the number of required buffers in
1660 * the Android camera3_stream_t.
1661 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001662 for (CameraStream &cameraStream : streams_) {
Kieran Binghamc7bcae02020-10-13 15:58:26 +01001663 ret = cameraStream.configure();
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001664 if (ret) {
1665 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001666 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001667 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001668 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001669
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001670 return 0;
1671}
1672
Kieran Bingham74ab4422020-07-01 13:25:38 +01001673FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1674{
1675 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001676 for (int i = 0; i < camera3buffer->numFds; i++) {
1677 /* Skip unused planes. */
1678 if (camera3buffer->data[i] == -1)
1679 break;
1680
Kieran Bingham74ab4422020-07-01 13:25:38 +01001681 FrameBuffer::Plane plane;
1682 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001683 if (!plane.fd.isValid()) {
1684 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1685 << camera3buffer->data[i] << ") "
1686 << " on plane " << i;
1687 return nullptr;
1688 }
1689
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001690 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1691 if (length == -1) {
1692 LOG(HAL, Error) << "Failed to query plane length";
1693 return nullptr;
1694 }
1695
1696 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001697 planes.push_back(std::move(plane));
1698 }
1699
1700 return new FrameBuffer(std::move(planes));
1701}
1702
Jacopo Mondibb2b4002021-01-04 16:20:05 +01001703int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)
1704{
1705 const CameraMetadata &settings = descriptor->settings_;
1706 if (!settings.isValid())
1707 return 0;
1708
1709 /* Translate the Android request settings to libcamera controls. */
1710 camera_metadata_ro_entry_t entry;
1711 if (settings.getEntry(ANDROID_SCALER_CROP_REGION, &entry)) {
1712 const int32_t *data = entry.data.i32;
1713 Rectangle cropRegion{ data[0], data[1],
1714 static_cast<unsigned int>(data[2]),
1715 static_cast<unsigned int>(data[3]) };
1716 ControlList &controls = descriptor->request_->controls();
1717 controls.set(controls::ScalerCrop, cropRegion);
1718 }
1719
1720 return 0;
1721}
1722
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001723int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001724{
Jacopo Mondic5b732b2020-12-01 17:12:19 +01001725 if (!camera3Request) {
1726 LOG(HAL, Error) << "No capture request provided";
1727 return -EINVAL;
1728 }
1729
Kieran Bingham61f42962020-07-01 13:40:17 +01001730 if (!camera3Request->num_output_buffers) {
1731 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001732 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001733 }
1734
1735 /* Start the camera if that's the first request we handle. */
1736 if (!running_) {
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001737 worker_.start();
1738
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001739 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001740 if (ret) {
1741 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001742 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001743 }
1744
1745 running_ = true;
1746 }
1747
1748 /*
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001749 * Save the request descriptors for use at completion time.
1750 * The descriptor and the associated memory reserved here are freed
1751 * at request complete time.
1752 */
1753 Camera3RequestDescriptor *descriptor =
Jacopo Mondidd1cd532021-01-21 10:51:05 +01001754 new Camera3RequestDescriptor(camera_.get(), camera3Request);
Paul Eldera6de3f02021-01-21 18:59:24 +09001755 /*
1756 * \todo The Android request model is incremental, settings passed in
1757 * previous requests are to be effective until overridden explicitly in
1758 * a new request. Do we need to cache settings incrementally here, or is
1759 * it handled by the Android camera service ?
1760 */
1761 if (camera3Request->settings)
1762 lastSettings_ = camera3Request->settings;
1763 else
1764 descriptor->settings_ = lastSettings_;
Kieran Binghameac05422020-07-01 13:28:16 +01001765
Jacopo Mondibc644072021-01-28 09:58:06 +01001766 LOG(HAL, Debug) << "Queueing request " << descriptor->request_->cookie()
1767 << " with " << descriptor->numBuffers_ << " streams";
Kieran Bingham37c18c22020-10-21 14:54:11 +01001768 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001769 const camera3_stream_buffer_t *camera3Buffer = &descriptor->buffers_[i];
1770 camera3_stream *camera3Stream = camera3Buffer->stream;
1771 CameraStream *cameraStream = static_cast<CameraStream *>(camera3Stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001772
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001773 std::stringstream ss;
1774 ss << i << " - (" << camera3Stream->width << "x"
1775 << camera3Stream->height << ")"
1776 << "[" << utils::hex(camera3Stream->format) << "] -> "
1777 << "(" << cameraStream->configuration().size.toString() << ")["
1778 << cameraStream->configuration().pixelFormat.toString() << "]";
1779
Jacopo Mondide8304b2020-09-04 17:45:39 +02001780 /*
1781 * Inspect the camera stream type, create buffers opportunely
1782 * and add them to the Request if required.
1783 */
1784 FrameBuffer *buffer = nullptr;
1785 switch (cameraStream->type()) {
1786 case CameraStream::Type::Mapped:
1787 /*
1788 * Mapped streams don't need buffers added to the
1789 * Request.
1790 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001791 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001792 continue;
1793
Jacopo Mondide8304b2020-09-04 17:45:39 +02001794 case CameraStream::Type::Direct:
1795 /*
1796 * Create a libcamera buffer using the dmabuf
1797 * descriptors of the camera3Buffer for each stream and
1798 * associate it with the Camera3RequestDescriptor for
1799 * lifetime management only.
1800 */
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001801 buffer = createFrameBuffer(*camera3Buffer->buffer);
Kieran Bingham37c18c22020-10-21 14:54:11 +01001802 descriptor->frameBuffers_.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001803 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001804 break;
1805
1806 case CameraStream::Type::Internal:
1807 /*
1808 * Get the frame buffer from the CameraStream internal
1809 * buffer pool.
1810 *
1811 * The buffer has to be returned to the CameraStream
1812 * once it has been processed.
1813 */
1814 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001815 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001816 break;
1817 }
1818
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001819 if (!buffer) {
1820 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001821 delete descriptor;
1822 return -ENOMEM;
1823 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001824
Kieran Bingham37c18c22020-10-21 14:54:11 +01001825 descriptor->request_->addBuffer(cameraStream->stream(), buffer,
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001826 camera3Buffer->acquire_fence);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001827 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001828
Jacopo Mondibb2b4002021-01-04 16:20:05 +01001829 /*
1830 * Translate controls from Android to libcamera and queue the request
1831 * to the CameraWorker thread.
1832 */
1833 int ret = processControls(descriptor);
1834 if (ret)
1835 return ret;
1836
Kieran Bingham37c18c22020-10-21 14:54:11 +01001837 worker_.queueRequest(descriptor->request_.get());
Paul Elderc7532232020-09-23 19:05:41 +09001838
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001839 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001840}
1841
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001842void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001843{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001844 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001845 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001846 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001847 Camera3RequestDescriptor *descriptor =
1848 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001849
1850 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001851 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001852 << request->status();
1853 status = CAMERA3_BUFFER_STATUS_ERROR;
1854 }
1855
Jacopo Mondibc644072021-01-28 09:58:06 +01001856 LOG(HAL, Debug) << "Request " << request->cookie() << " completed with "
1857 << descriptor->numBuffers_ << " streams";
1858
Kieran Binghamc09aee42020-07-28 14:01:19 +01001859 /*
1860 * \todo The timestamp used for the metadata is currently always taken
1861 * from the first buffer (which may be the first stream) in the Request.
1862 * It might be appropriate to return a 'correct' (as determined by
1863 * pipeline handlers) timestamp in the Request itself.
1864 */
Hirokazu Honda3a777d82020-10-28 17:57:26 +09001865 uint64_t timestamp = buffers.begin()->second->metadata().timestamp;
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001866 resultMetadata = getResultMetadata(descriptor, timestamp);
Kieran Binghamc09aee42020-07-28 14:01:19 +01001867
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001868 /* Handle any JPEG compression. */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001869 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001870 CameraStream *cameraStream =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001871 static_cast<CameraStream *>(descriptor->buffers_[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001872
Jacopo Mondi160bb092020-10-02 20:48:35 +02001873 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001874 continue;
1875
Jacopo Mondi216030a2020-10-03 11:36:41 +02001876 FrameBuffer *buffer = request->findBuffer(cameraStream->stream());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001877 if (!buffer) {
1878 LOG(HAL, Error) << "Failed to find a source stream buffer";
1879 continue;
1880 }
1881
1882 /*
1883 * \todo Buffer mapping and compression should be moved to a
1884 * separate thread.
1885 */
1886
Kieran Bingham37c18c22020-10-21 14:54:11 +01001887 MappedCamera3Buffer mapped(*descriptor->buffers_[i].buffer,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001888 PROT_READ | PROT_WRITE);
1889 if (!mapped.isValid()) {
1890 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1891 continue;
1892 }
1893
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02001894 int ret = cameraStream->process(*buffer, &mapped,
Paul Elderabfabdd2021-01-23 13:54:28 +09001895 descriptor->settings_,
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02001896 resultMetadata.get());
1897 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001898 status = CAMERA3_BUFFER_STATUS_ERROR;
1899 continue;
1900 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02001901
1902 /*
1903 * Return the FrameBuffer to the CameraStream now that we're
1904 * done processing it.
1905 */
1906 if (cameraStream->type() == CameraStream::Type::Internal)
1907 cameraStream->putBuffer(buffer);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001908 }
1909
1910 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001911 camera3_capture_result_t captureResult = {};
Kieran Bingham37c18c22020-10-21 14:54:11 +01001912 captureResult.frame_number = descriptor->frameNumber_;
1913 captureResult.num_output_buffers = descriptor->numBuffers_;
1914 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
1915 descriptor->buffers_[i].acquire_fence = -1;
1916 descriptor->buffers_[i].release_fence = -1;
1917 descriptor->buffers_[i].status = status;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001918 }
1919 captureResult.output_buffers =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001920 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers_);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001921
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001922
Laurent Pinchart39860092019-09-05 03:12:34 +03001923 if (status == CAMERA3_BUFFER_STATUS_OK) {
Kieran Binghame1f9fdb2020-10-21 15:31:10 +01001924 notifyShutter(descriptor->frameNumber_, timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001925
1926 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001927 captureResult.result = resultMetadata->get();
1928 }
1929
1930 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1931 /* \todo Improve error handling. In case we notify an error
1932 * because the metadata generation fails, a shutter event has
1933 * already been notified for this frame number before the error
1934 * is here signalled. Make sure the error path plays well with
1935 * the camera stack state machine.
1936 */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001937 notifyError(descriptor->frameNumber_,
1938 descriptor->buffers_[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001939 }
1940
1941 callbacks_->process_capture_result(callbacks_, &captureResult);
1942
1943 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001944}
1945
Jacopo Mondia7b92772020-05-26 15:41:41 +02001946std::string CameraDevice::logPrefix() const
1947{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001948 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001949}
1950
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001951void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1952{
1953 camera3_notify_msg_t notify = {};
1954
1955 notify.type = CAMERA3_MSG_SHUTTER;
1956 notify.message.shutter.frame_number = frameNumber;
1957 notify.message.shutter.timestamp = timestamp;
1958
1959 callbacks_->notify(callbacks_, &notify);
1960}
1961
1962void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1963{
1964 camera3_notify_msg_t notify = {};
1965
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001966 /*
1967 * \todo Report and identify the stream number or configuration to
1968 * clarify the stream that failed.
1969 */
1970 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1971 << toPixelFormat(stream->format).toString() << ")";
1972
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001973 notify.type = CAMERA3_MSG_ERROR;
1974 notify.message.error.error_stream = stream;
1975 notify.message.error.frame_number = frameNumber;
1976 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1977
1978 callbacks_->notify(callbacks_, &notify);
1979}
1980
1981/*
1982 * Produce a set of fixed result metadata.
1983 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001984std::unique_ptr<CameraMetadata>
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001985CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor,
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001986 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001987{
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001988 const ControlList &metadata = descriptor->request_->metadata();
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01001989 const CameraMetadata &settings = descriptor->settings_;
Paul Elder958c80a2021-01-26 09:47:33 +09001990 camera_metadata_ro_entry_t entry;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01001991 bool found;
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001992
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001993 /*
1994 * \todo Keep this in sync with the actual number of entries.
Paul Elder12646282021-01-23 13:56:01 +09001995 * Currently: 40 entries, 156 bytes
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001996 *
1997 * Reserve more space for the JPEG metadata set by the post-processor.
Paul Elderabfabdd2021-01-23 13:54:28 +09001998 * Currently:
1999 * ANDROID_JPEG_GPS_COORDINATES (double x 3) = 24 bytes
2000 * ANDROID_JPEG_GPS_PROCESSING_METHOD (byte x 32) = 32 bytes
2001 * ANDROID_JPEG_GPS_TIMESTAMP (int64) = 8 bytes
2002 * ANDROID_JPEG_SIZE (int32_t) = 4 bytes
2003 * ANDROID_JPEG_QUALITY (byte) = 1 byte
2004 * ANDROID_JPEG_ORIENTATION (int32_t) = 4 bytes
Paul Elder12646282021-01-23 13:56:01 +09002005 * ANDROID_JPEG_THUMBNAIL_QUALITY (byte) = 1 byte
2006 * ANDROID_JPEG_THUMBNAIL_SIZE (int32 x 2) = 8 bytes
2007 * Total bytes for JPEG metadata: 82
Jacopo Mondi48504ba2019-09-04 16:18:19 +02002008 */
Laurent Pinchart39860092019-09-05 03:12:34 +03002009 std::unique_ptr<CameraMetadata> resultMetadata =
Jacopo Mondie9c28752021-02-03 14:47:45 +01002010 std::make_unique<CameraMetadata>(42, 161);
Laurent Pinchart39860092019-09-05 03:12:34 +03002011 if (!resultMetadata->isValid()) {
2012 LOG(HAL, Error) << "Failed to allocate static metadata";
2013 return nullptr;
2014 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002015
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002016 /*
2017 * \todo The value of the results metadata copied from the settings
2018 * will have to be passed to the libcamera::Camera and extracted
2019 * from libcamera::Request::metadata.
2020 */
2021
Jacopo Mondi520c3662021-02-03 14:44:34 +01002022 uint8_t value = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
2023 resultMetadata->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
2024 &value, 1);
2025
2026 value = ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF;
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002027 resultMetadata->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002028
Jacopo Mondie9c28752021-02-03 14:47:45 +01002029 int32_t value32 = 0;
2030 resultMetadata->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
2031 &value32, 1);
2032
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002033 value = ANDROID_CONTROL_AE_LOCK_OFF;
2034 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002035
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002036 value = ANDROID_CONTROL_AE_MODE_ON;
2037 resultMetadata->addEntry(ANDROID_CONTROL_AE_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002038
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002039 std::vector<int32_t> aeFpsTarget = { 30, 30 };
2040 resultMetadata->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
2041 aeFpsTarget.data(), aeFpsTarget.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002042
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002043 value = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002044 found = settings.getEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &entry);
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002045 resultMetadata->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002046 found ? entry.data.u8 : &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002047
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002048 value = ANDROID_CONTROL_AE_STATE_CONVERGED;
2049 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &value, 1);
2050
2051 value = ANDROID_CONTROL_AF_MODE_OFF;
2052 resultMetadata->addEntry(ANDROID_CONTROL_AF_MODE, &value, 1);
2053
2054 value = ANDROID_CONTROL_AF_STATE_INACTIVE;
2055 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &value, 1);
2056
2057 value = ANDROID_CONTROL_AF_TRIGGER_IDLE;
2058 resultMetadata->addEntry(ANDROID_CONTROL_AF_TRIGGER, &value, 1);
2059
2060 value = ANDROID_CONTROL_AWB_MODE_AUTO;
2061 resultMetadata->addEntry(ANDROID_CONTROL_AWB_MODE, &value, 1);
2062
2063 value = ANDROID_CONTROL_AWB_LOCK_OFF;
2064 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &value, 1);
2065
2066 value = ANDROID_CONTROL_AWB_STATE_CONVERGED;
2067 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &value, 1);
2068
2069 value = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
2070 resultMetadata->addEntry(ANDROID_CONTROL_CAPTURE_INTENT, &value, 1);
2071
2072 value = ANDROID_CONTROL_EFFECT_MODE_OFF;
2073 resultMetadata->addEntry(ANDROID_CONTROL_EFFECT_MODE, &value, 1);
2074
2075 value = ANDROID_CONTROL_MODE_AUTO;
2076 resultMetadata->addEntry(ANDROID_CONTROL_MODE, &value, 1);
2077
2078 value = ANDROID_CONTROL_SCENE_MODE_DISABLED;
2079 resultMetadata->addEntry(ANDROID_CONTROL_SCENE_MODE, &value, 1);
2080
2081 value = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
2082 resultMetadata->addEntry(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &value, 1);
2083
2084 value = ANDROID_FLASH_MODE_OFF;
2085 resultMetadata->addEntry(ANDROID_FLASH_MODE, &value, 1);
2086
2087 value = ANDROID_FLASH_STATE_UNAVAILABLE;
2088 resultMetadata->addEntry(ANDROID_FLASH_STATE, &value, 1);
2089
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002090 if (settings.getEntry(ANDROID_LENS_APERTURE, &entry))
Paul Elderabfabdd2021-01-23 13:54:28 +09002091 resultMetadata->addEntry(ANDROID_LENS_APERTURE, entry.data.f, 1);
2092
2093 float focal_length = 1.0;
2094 resultMetadata->addEntry(ANDROID_LENS_FOCAL_LENGTH, &focal_length, 1);
2095
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002096 value = ANDROID_LENS_STATE_STATIONARY;
2097 resultMetadata->addEntry(ANDROID_LENS_STATE, &value, 1);
2098
2099 value = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
2100 resultMetadata->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
2101 &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002102
Laurent Pinchart39860092019-09-05 03:12:34 +03002103 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002104
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002105 value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
2106 resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
2107 &value, 1);
2108
2109 value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
2110 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
2111 &value, 1);
2112
2113 value = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
2114 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
2115 &value, 1);
2116
2117 value = ANDROID_NOISE_REDUCTION_MODE_OFF;
2118 resultMetadata->addEntry(ANDROID_NOISE_REDUCTION_MODE, &value, 1);
2119
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002120 /* 33.3 msec */
2121 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03002122 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
2123 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002124
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002125 /* Add metadata tags reported by libcamera. */
2126 if (metadata.contains(controls::draft::PipelineDepth)) {
2127 uint8_t pipeline_depth =
2128 metadata.get<int32_t>(controls::draft::PipelineDepth);
2129 resultMetadata->addEntry(ANDROID_REQUEST_PIPELINE_DEPTH,
2130 &pipeline_depth, 1);
2131 }
2132
Jacopo Mondic9705a52021-01-05 19:30:48 +01002133 if (metadata.contains(controls::ExposureTime)) {
Paul Elder78f49d52021-01-28 17:45:44 +09002134 int64_t exposure = metadata.get(controls::ExposureTime) * 1000ULL;
Jacopo Mondic9705a52021-01-05 19:30:48 +01002135 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
2136 &exposure, 1);
2137 }
2138
Jacopo Mondibb2b4002021-01-04 16:20:05 +01002139 if (metadata.contains(controls::ScalerCrop)) {
2140 Rectangle crop = metadata.get(controls::ScalerCrop);
2141 int32_t cropRect[] = {
2142 crop.x, crop.y, static_cast<int32_t>(crop.width),
2143 static_cast<int32_t>(crop.height),
2144 };
2145 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, cropRect, 4);
2146 }
2147
Laurent Pinchart39860092019-09-05 03:12:34 +03002148 /*
2149 * Return the result metadata pack even is not valid: get() will return
2150 * nullptr.
2151 */
2152 if (!resultMetadata->isValid()) {
2153 LOG(HAL, Error) << "Failed to construct result metadata";
2154 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002155
2156 return resultMetadata;
2157}