blob: b8f51973c035e7864b27ac09a5b355e780d73739 [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
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +010012#include <cmath>
Paul Elder229653a2021-01-21 17:44:14 +090013#include <fstream>
Kieran Bingham83ae84e2020-07-03 12:34:59 +010014#include <sys/mman.h>
Jacopo Mondia80d3812020-05-26 12:31:35 +020015#include <tuple>
Jacopo Mondi117588b2020-05-23 18:53:54 +020016#include <vector>
17
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +020018#include <libcamera/control_ids.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010019#include <libcamera/controls.h>
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030020#include <libcamera/formats.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010021#include <libcamera/property_ids.h>
22
Niklas Söderlund7876d632020-07-21 00:16:24 +020023#include "libcamera/internal/formats.h"
Laurent Pinchart93e72b62020-05-12 00:58:34 +030024#include "libcamera/internal/log.h"
25#include "libcamera/internal/utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020026
Jacopo Mondi117588b2020-05-23 18:53:54 +020027#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020028
29using namespace libcamera;
30
Hirokazu Honda26d90af2020-12-11 09:53:36 +000031LOG_DECLARE_CATEGORY(HAL)
32
Jacopo Mondi117588b2020-05-23 18:53:54 +020033namespace {
34
35/*
36 * \var camera3Resolutions
37 * \brief The list of image resolutions defined as mandatory to be supported by
38 * the Android Camera3 specification
39 */
40const std::vector<Size> camera3Resolutions = {
41 { 320, 240 },
42 { 640, 480 },
43 { 1280, 720 },
44 { 1920, 1080 }
45};
46
47/*
48 * \struct Camera3Format
49 * \brief Data associated with an Android format identifier
50 * \var libcameraFormats List of libcamera pixel formats compatible with the
51 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020052 * \var name The human-readable representation of the Android format code
53 */
54struct Camera3Format {
55 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020056 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020057 const char *name;
58};
59
60/*
61 * \var camera3FormatsMap
62 * \brief Associate Android format code with ancillary data
63 */
64const std::map<int, const Camera3Format> camera3FormatsMap = {
65 {
66 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030067 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020068 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020069 "BLOB"
70 }
71 }, {
72 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030073 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020074 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020075 "YCbCr_420_888"
76 }
77 }, {
78 /*
79 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
80 * usage flag. For now, copy the YCbCr_420 configuration.
81 */
82 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030083 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020084 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020085 "IMPLEMENTATION_DEFINED"
86 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020087 }, {
88 HAL_PIXEL_FORMAT_RAW10, {
89 {
90 formats::SBGGR10_CSI2P,
91 formats::SGBRG10_CSI2P,
92 formats::SGRBG10_CSI2P,
93 formats::SRGGB10_CSI2P
94 },
95 false,
96 "RAW10"
97 }
98 }, {
99 HAL_PIXEL_FORMAT_RAW12, {
100 {
101 formats::SBGGR12_CSI2P,
102 formats::SGBRG12_CSI2P,
103 formats::SGRBG12_CSI2P,
104 formats::SRGGB12_CSI2P
105 },
106 false,
107 "RAW12"
108 }
109 }, {
110 HAL_PIXEL_FORMAT_RAW16, {
111 {
112 formats::SBGGR16,
113 formats::SGBRG16,
114 formats::SGRBG16,
115 formats::SRGGB16
116 },
117 false,
118 "RAW16"
119 }
120 }, {
121 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
122 {
123 formats::SBGGR10_IPU3,
124 formats::SGBRG10_IPU3,
125 formats::SGRBG10_IPU3,
126 formats::SRGGB10_IPU3
127 },
128 false,
129 "RAW_OPAQUE"
130 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200131 },
132};
133
Hirokazu Hondac2df7432020-12-11 09:53:34 +0000134/*
135 * \struct Camera3StreamConfig
136 * \brief Data to store StreamConfiguration associated with camera3_stream(s)
137 * \var streams List of the pairs of a stream requested by Android HAL client
138 * and CameraStream::Type associated with the stream
139 * \var config StreamConfiguration for streams
140 */
141struct Camera3StreamConfig {
142 struct Camera3Stream {
143 camera3_stream_t *stream;
144 CameraStream::Type type;
145 };
146
147 std::vector<Camera3Stream> streams;
148 StreamConfiguration config;
149};
150
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000151/*
152 * Reorder the configurations so that libcamera::Camera can accept them as much
153 * as possible. The sort rule is as follows.
154 * 1.) The configuration for NV12 request whose resolution is the largest.
155 * 2.) The configuration for JPEG request.
156 * 3.) Others. Larger resolutions and different formats are put earlier.
157 */
158void sortCamera3StreamConfigs(std::vector<Camera3StreamConfig> &unsortedConfigs,
159 const camera3_stream_t *jpegStream)
160{
161 const Camera3StreamConfig *jpegConfig = nullptr;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200162
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000163 std::map<PixelFormat, std::vector<const Camera3StreamConfig *>> formatToConfigs;
164 for (const auto &streamConfig : unsortedConfigs) {
165 if (jpegStream && !jpegConfig) {
166 const auto &streams = streamConfig.streams;
167 if (std::find_if(streams.begin(), streams.end(),
168 [jpegStream](const auto &stream) {
169 return stream.stream == jpegStream;
170 }) != streams.end()) {
171 jpegConfig = &streamConfig;
172 continue;
173 }
174 }
175 formatToConfigs[streamConfig.config.pixelFormat].push_back(&streamConfig);
176 }
177
178 if (jpegStream && !jpegConfig)
179 LOG(HAL, Fatal) << "No Camera3StreamConfig is found for JPEG";
180
181 for (auto &fmt : formatToConfigs) {
182 auto &streamConfigs = fmt.second;
183
184 /* Sorted by resolution. Smaller is put first. */
185 std::sort(streamConfigs.begin(), streamConfigs.end(),
186 [](const auto *streamConfigA, const auto *streamConfigB) {
187 const Size &sizeA = streamConfigA->config.size;
188 const Size &sizeB = streamConfigB->config.size;
189 return sizeA < sizeB;
190 });
191 }
192
193 std::vector<Camera3StreamConfig> sortedConfigs;
194 sortedConfigs.reserve(unsortedConfigs.size());
195
196 /*
197 * NV12 is the most prioritized format. Put the configuration with NV12
198 * and the largest resolution first.
199 */
200 const auto nv12It = formatToConfigs.find(formats::NV12);
201 if (nv12It != formatToConfigs.end()) {
202 auto &nv12Configs = nv12It->second;
Laurent Pinchartbd4894d2020-12-12 05:22:31 +0200203 const Camera3StreamConfig *nv12Largest = nv12Configs.back();
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000204
205 /*
206 * If JPEG will be created from NV12 and the size is larger than
207 * the largest NV12 configurations, then put the NV12
208 * configuration for JPEG first.
209 */
210 if (jpegConfig && jpegConfig->config.pixelFormat == formats::NV12) {
211 const Size &nv12SizeForJpeg = jpegConfig->config.size;
212 const Size &nv12LargestSize = nv12Largest->config.size;
213
214 if (nv12LargestSize < nv12SizeForJpeg) {
215 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
216 sortedConfigs.push_back(std::move(*jpegConfig));
217 jpegConfig = nullptr;
218 }
219 }
220
221 LOG(HAL, Debug) << "Insert " << nv12Largest->config.toString();
222 sortedConfigs.push_back(*nv12Largest);
223 nv12Configs.pop_back();
224
225 if (nv12Configs.empty())
226 formatToConfigs.erase(nv12It);
227 }
228
229 /* If the configuration for JPEG is there, then put it. */
230 if (jpegConfig) {
231 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
232 sortedConfigs.push_back(std::move(*jpegConfig));
233 jpegConfig = nullptr;
234 }
235
236 /*
237 * Put configurations with different formats and larger resolutions
238 * earlier.
239 */
240 while (!formatToConfigs.empty()) {
241 for (auto it = formatToConfigs.begin(); it != formatToConfigs.end();) {
242 auto &configs = it->second;
243 LOG(HAL, Debug) << "Insert " << configs.back()->config.toString();
244 sortedConfigs.push_back(*configs.back());
245 configs.pop_back();
246
247 if (configs.empty())
248 it = formatToConfigs.erase(it);
249 else
250 it++;
251 }
252 }
253
254 ASSERT(sortedConfigs.size() == unsortedConfigs.size());
255
256 unsortedConfigs = sortedConfigs;
257}
258
259} /* namespace */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200260
261/*
262 * \struct Camera3RequestDescriptor
263 *
264 * A utility structure that groups information about a capture request to be
265 * later re-used at request complete time to notify the framework.
266 */
267
268CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100269 Camera *camera, const camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200270{
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100271 frameNumber_ = camera3Request->frame_number;
272
Jacopo Mondi4b18b822021-01-21 11:10:08 +0100273 /* Copy the camera3 request stream information for later access. */
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100274 numBuffers_ = camera3Request->num_output_buffers;
275 buffers_ = new camera3_stream_buffer_t[numBuffers_];
Jacopo Mondi4b18b822021-01-21 11:10:08 +0100276 for (unsigned int i = 0; i < numBuffers_; ++i)
277 buffers_[i] = camera3Request->output_buffers[i];
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200278
279 /*
280 * FrameBuffer instances created by wrapping a camera3 provided dmabuf
281 * are emplaced in this vector of unique_ptr<> for lifetime management.
282 */
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100283 frameBuffers_.reserve(numBuffers_);
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200284
Jacopo Mondi9e6eece2021-01-21 12:52:10 +0100285 /* Clone the controls associated with the camera3 request. */
286 settings_ = CameraMetadata(camera3Request->settings);
287
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200288 /*
289 * Create the libcamera::Request unique_ptr<> to tie its lifetime
290 * to the descriptor's one. Set the descriptor's address as the
291 * request's cookie to retrieve it at completion time.
292 */
Kieran Bingham37c18c22020-10-21 14:54:11 +0100293 request_ = std::make_unique<CaptureRequest>(camera,
294 reinterpret_cast<uint64_t>(this));
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200295}
296
297CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
298{
Kieran Bingham37c18c22020-10-21 14:54:11 +0100299 delete[] buffers_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200300}
301
302/*
303 * \class CameraDevice
304 *
305 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200306 * the camera3_device_t interface, bridging calls received from the Android
307 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200308 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200309 * The class translates parameters and operations from the Camera HALv3 API to
310 * the libcamera API to provide static information for a Camera, create request
311 * templates for it, process capture requests and then deliver capture results
312 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200313 */
314
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300315CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000316 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200317 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200318{
319 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100320
Paul Elder229653a2021-01-21 17:44:14 +0900321 maker_ = "libcamera";
322 model_ = "cameraModel";
323
324 /* \todo Support getting properties on Android */
325 std::ifstream fstream("/var/cache/camera/camera.prop");
326 if (!fstream.is_open())
327 return;
328
329 std::string line;
330 while (std::getline(fstream, line)) {
331 std::string::size_type delimPos = line.find("=");
332 if (delimPos == std::string::npos)
333 continue;
334 std::string key = line.substr(0, delimPos);
335 std::string val = line.substr(delimPos + 1);
336
337 if (!key.compare("ro.product.model"))
338 model_ = val;
339 else if (!key.compare("ro.product.manufacturer"))
340 maker_ = val;
341 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200342}
343
344CameraDevice::~CameraDevice()
345{
346 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300347 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200348
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200349 for (auto &it : requestTemplates_)
350 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200351}
352
Umang Jainf8e28132020-08-21 14:46:08 +0000353std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
354 const std::shared_ptr<Camera> &cam)
355{
356 CameraDevice *camera = new CameraDevice(id, cam);
357 return std::shared_ptr<CameraDevice>(camera);
358}
359
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200360/*
361 * Initialize the camera static information.
362 * This method is called before the camera device is opened.
363 */
364int CameraDevice::initialize()
365{
366 /* Initialize orientation and facing side of the camera. */
367 const ControlList &properties = camera_->properties();
368
369 if (properties.contains(properties::Location)) {
370 int32_t location = properties.get(properties::Location);
371 switch (location) {
372 case properties::CameraLocationFront:
373 facing_ = CAMERA_FACING_FRONT;
374 break;
375 case properties::CameraLocationBack:
376 facing_ = CAMERA_FACING_BACK;
377 break;
378 case properties::CameraLocationExternal:
Paul Elder3d39df22021-02-11 17:51:48 +0900379 /*
380 * \todo Set this to EXTERNAL once we support
381 * HARDWARE_LEVEL_EXTERNAL
382 */
383 facing_ = CAMERA_FACING_FRONT;
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200384 break;
385 }
386 }
387
388 /*
Umang Jaine9176552020-09-09 16:17:54 +0530389 * The Android orientation metadata specifies its rotation correction
390 * value in clockwise direction whereas libcamera specifies the
391 * rotation property in anticlockwise direction. Read the libcamera's
392 * rotation property (anticlockwise) and compute the corresponding
393 * value for clockwise direction as required by the Android orientation
394 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200395 */
Umang Jaine9176552020-09-09 16:17:54 +0530396 if (properties.contains(properties::Rotation)) {
397 int rotation = properties.get(properties::Rotation);
398 orientation_ = (360 - rotation) % 360;
399 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200400
Jacopo Mondi117588b2020-05-23 18:53:54 +0200401 int ret = camera_->acquire();
402 if (ret) {
403 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
404 return ret;
405 }
406
407 ret = initializeStreamConfigurations();
408 camera_->release();
409 return ret;
410}
411
Jacopo Mondibfee6312020-09-01 17:42:13 +0200412std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
413 const PixelFormat &pixelFormat,
414 const std::vector<Size> &resolutions)
415{
416 std::vector<Size> supportedResolutions;
417
418 StreamConfiguration &cfg = cameraConfig->at(0);
419 for (const Size &res : resolutions) {
420 cfg.pixelFormat = pixelFormat;
421 cfg.size = res;
422
423 CameraConfiguration::Status status = cameraConfig->validate();
424 if (status != CameraConfiguration::Valid) {
425 LOG(HAL, Debug) << cfg.toString() << " not supported";
426 continue;
427 }
428
429 LOG(HAL, Debug) << cfg.toString() << " supported";
430
431 supportedResolutions.push_back(res);
432 }
433
434 return supportedResolutions;
435}
436
Jacopo Mondi49610332020-09-01 18:11:34 +0200437std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
438{
439 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200440 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200441 StreamConfiguration &cfg = cameraConfig->at(0);
442 const StreamFormats &formats = cfg.formats();
443 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
444
445 return supportedResolutions;
446}
447
Jacopo Mondi117588b2020-05-23 18:53:54 +0200448/*
449 * Initialize the format conversion map to translate from Android format
450 * identifier to libcamera pixel formats and fill in the list of supported
451 * stream configurations to be reported to the Android camera framework through
452 * the static stream configuration metadata.
453 */
454int CameraDevice::initializeStreamConfigurations()
455{
456 /*
457 * Get the maximum output resolutions
458 * \todo Get this from the camera properties once defined
459 */
460 std::unique_ptr<CameraConfiguration> cameraConfig =
461 camera_->generateConfiguration({ StillCapture });
462 if (!cameraConfig) {
463 LOG(HAL, Error) << "Failed to get maximum resolution";
464 return -EINVAL;
465 }
466 StreamConfiguration &cfg = cameraConfig->at(0);
467
468 /*
469 * \todo JPEG - Adjust the maximum available resolution by taking the
470 * JPEG encoder requirements into account (alignment and aspect ratio).
471 */
472 const Size maxRes = cfg.size;
473 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
474
475 /*
476 * Build the list of supported image resolutions.
477 *
478 * The resolutions listed in camera3Resolution are mandatory to be
479 * supported, up to the camera maximum resolution.
480 *
481 * Augment the list by adding resolutions calculated from the camera
482 * maximum one.
483 */
484 std::vector<Size> cameraResolutions;
485 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
486 std::back_inserter(cameraResolutions),
487 [&](const Size &res) { return res < maxRes; });
488
489 /*
490 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
491 * resolution.
492 */
493 for (unsigned int divider = 2;; divider <<= 1) {
494 Size derivedSize{
495 maxRes.width / divider,
496 maxRes.height / divider,
497 };
498
499 if (derivedSize.width < 320 ||
500 derivedSize.height < 240)
501 break;
502
503 cameraResolutions.push_back(derivedSize);
504 }
505 cameraResolutions.push_back(maxRes);
506
507 /* Remove duplicated entries from the list of supported resolutions. */
508 std::sort(cameraResolutions.begin(), cameraResolutions.end());
509 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
510 cameraResolutions.erase(last, cameraResolutions.end());
511
512 /*
513 * Build the list of supported camera formats.
514 *
515 * To each Android format a list of compatible libcamera formats is
516 * associated. The first libcamera format that tests successful is added
517 * to the format translation map used when configuring the streams.
518 * It is then tested against the list of supported camera resolutions to
519 * build the stream configuration map reported through the camera static
520 * metadata.
521 */
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100522 Size maxJpegSize;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200523 for (const auto &format : camera3FormatsMap) {
524 int androidFormat = format.first;
525 const Camera3Format &camera3Format = format.second;
526 const std::vector<PixelFormat> &libcameraFormats =
527 camera3Format.libcameraFormats;
528
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200529 LOG(HAL, Debug) << "Trying to map Android format "
530 << camera3Format.name;
531
Jacopo Mondi117588b2020-05-23 18:53:54 +0200532 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200533 * JPEG is always supported, either produced directly by the
534 * camera, or encoded in the HAL.
535 */
536 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
537 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200538 LOG(HAL, Debug) << "Mapped Android format "
539 << camera3Format.name << " to "
540 << formats::MJPEG.toString()
541 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200542 continue;
543 }
544
545 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200546 * Test the libcamera formats that can produce images
547 * compatible with the format defined by Android.
548 */
549 PixelFormat mappedFormat;
550 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200551
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200552 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
553
Jacopo Mondi117588b2020-05-23 18:53:54 +0200554 /*
555 * The stream configuration size can be adjusted,
556 * not the pixel format.
557 *
558 * \todo This could be simplified once all pipeline
559 * handlers will report the StreamFormats list of
560 * supported formats.
561 */
562 cfg.pixelFormat = pixelFormat;
563
564 CameraConfiguration::Status status = cameraConfig->validate();
565 if (status != CameraConfiguration::Invalid &&
566 cfg.pixelFormat == pixelFormat) {
567 mappedFormat = pixelFormat;
568 break;
569 }
570 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200571
572 if (!mappedFormat.isValid()) {
573 /* If the format is not mandatory, skip it. */
574 if (!camera3Format.mandatory)
575 continue;
576
577 LOG(HAL, Error)
578 << "Failed to map mandatory Android format "
579 << camera3Format.name << " ("
580 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200581 return -EINVAL;
582 }
583
584 /*
585 * Record the mapping and then proceed to generate the
586 * stream configurations map, by testing the image resolutions.
587 */
588 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200589 LOG(HAL, Debug) << "Mapped Android format "
590 << camera3Format.name << " to "
591 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200592
Jacopo Mondi49610332020-09-01 18:11:34 +0200593 std::vector<Size> resolutions;
594 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
595 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
596 resolutions = getRawResolutions(mappedFormat);
597 else
598 resolutions = getYUVResolutions(cameraConfig.get(),
599 mappedFormat,
600 cameraResolutions);
601
Jacopo Mondibfee6312020-09-01 17:42:13 +0200602 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200603 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200604
605 /*
606 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
607 * from which JPEG is produced, add an entry for
608 * the JPEG stream.
609 *
610 * \todo Wire the JPEG encoder to query the supported
611 * sizes provided a list of formats it can encode.
612 *
613 * \todo Support JPEG streams produced by the Camera
614 * natively.
615 */
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100616 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
Jacopo Mondi843565c2020-09-01 15:34:13 +0200617 streamConfigurations_.push_back(
618 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100619 maxJpegSize = std::max(maxJpegSize, res);
620 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200621 }
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100622
623 /*
624 * \todo Calculate the maximum JPEG buffer size by asking the
625 * encoder giving the maximum frame size required.
626 */
627 maxJpegBufferSize_ = maxJpegSize.width * maxJpegSize.height * 1.5;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200628 }
629
630 LOG(HAL, Debug) << "Collected stream configuration map: ";
631 for (const auto &entry : streamConfigurations_)
632 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200633 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200634
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200635 return 0;
636}
637
638/*
639 * Open a camera device. The static information on the camera shall have been
640 * initialized with a call to CameraDevice::initialize().
641 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200642int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200643{
644 int ret = camera_->acquire();
645 if (ret) {
646 LOG(HAL, Error) << "Failed to acquire the camera";
647 return ret;
648 }
649
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200650 /* Initialize the hw_device_t in the instance camera3_module_t. */
651 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
652 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
653 camera3Device_.common.module = (hw_module_t *)hardwareModule;
654 camera3Device_.common.close = hal_dev_close;
655
656 /*
657 * The camera device operations. These actually implement
658 * the Android Camera HALv3 interface.
659 */
660 camera3Device_.ops = &hal_dev_ops;
661 camera3Device_.priv = this;
662
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200663 return 0;
664}
665
666void CameraDevice::close()
667{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200668 streams_.clear();
669
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200670 worker_.stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200671 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200672 camera_->release();
673
674 running_ = false;
675}
676
677void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
678{
679 callbacks_ = callbacks;
680}
681
Jacopo Mondia80d3812020-05-26 12:31:35 +0200682std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
683{
684 /*
685 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100686 * Currently: 54 entries, 874 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200687 */
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100688 uint32_t numEntries = 54;
689 uint32_t byteSize = 874;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200690
691 /*
692 * Calculate space occupation in bytes for dynamically built metadata
693 * entries.
694 *
Jacopo Mondi00982fb2021-02-04 16:57:55 +0100695 * Each stream configuration entry requires 48 bytes:
Jacopo Mondia80d3812020-05-26 12:31:35 +0200696 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200697 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
698 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200699 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200700
Jacopo Mondi9e807052021-02-04 15:32:00 +0100701 /*
702 * 2 32bits integers for each HAL_PIXEL_FORMAT_BLOB for thumbnail sizes
703 * 2 32bits integers for the (0, 0) thumbnail size
704 *
705 * This is a worst case estimates as different configurations with the
706 * same aspect ratio will generate the same size.
707 */
708 for (const auto &entry : streamConfigurations_) {
709 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
710 continue;
711
712 byteSize += 8;
713 }
714 byteSize += 8;
715
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300716 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200717}
718
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200719/*
720 * Return static information for the camera.
721 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200722const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200723{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200724 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300725 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200726
727 /*
728 * The here reported metadata are enough to implement a basic capture
729 * example application, but a real camera implementation will require
730 * more.
731 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200732 uint32_t numEntries;
733 uint32_t byteSize;
734 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
735 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300736 if (!staticMetadata_->isValid()) {
737 LOG(HAL, Error) << "Failed to allocate static metadata";
738 delete staticMetadata_;
739 staticMetadata_ = nullptr;
740 return nullptr;
741 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200742
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200743 const ControlInfoMap &controlsInfo = camera_->controls();
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100744 const ControlList &properties = camera_->properties();
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200745
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200746 /* Color correction static metadata. */
Jacopo Mondi63336862020-10-08 16:18:26 +0200747 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100748 std::vector<uint8_t> data;
749 data.reserve(3);
Jacopo Mondi63336862020-10-08 16:18:26 +0200750 const auto &infoMap = controlsInfo.find(&controls::draft::ColorCorrectionAberrationMode);
751 if (infoMap != controlsInfo.end()) {
752 for (const auto &value : infoMap->second.values())
753 data.push_back(value.get<int32_t>());
754 } else {
755 data.push_back(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
756 }
757 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
758 data.data(), data.size());
759 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200760
761 /* Control static metadata. */
762 std::vector<uint8_t> aeAvailableAntiBandingModes = {
763 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
764 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
765 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
766 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
767 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300768 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
769 aeAvailableAntiBandingModes.data(),
770 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200771
772 std::vector<uint8_t> aeAvailableModes = {
773 ANDROID_CONTROL_AE_MODE_ON,
774 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300775 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
776 aeAvailableModes.data(),
777 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200778
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100779 int64_t minFrameDurationNsec = -1;
780 int64_t maxFrameDurationNsec = -1;
781 const auto frameDurationsInfo = controlsInfo.find(&controls::FrameDurations);
782 if (frameDurationsInfo != controlsInfo.end()) {
783 minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000;
784 maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000;
785
786 /*
787 * Adjust the minimum frame duration to comply with Android
788 * requirements. The camera service mandates all preview/record
789 * streams to have a minimum frame duration < 33,366 milliseconds
790 * (see MAX_PREVIEW_RECORD_DURATION_NS in the camera service
791 * implementation).
792 *
793 * If we're close enough (+ 500 useconds) to that value, round
794 * the minimum frame duration of the camera to an accepted
795 * value.
796 */
797 static constexpr int64_t MAX_PREVIEW_RECORD_DURATION_NS = 1e9 / 29.97;
798 if (minFrameDurationNsec > MAX_PREVIEW_RECORD_DURATION_NS &&
799 minFrameDurationNsec < MAX_PREVIEW_RECORD_DURATION_NS + 500000)
800 minFrameDurationNsec = MAX_PREVIEW_RECORD_DURATION_NS - 1000;
801
802 /*
803 * The AE routine frame rate limits are computed using the frame
804 * duration limits, as libcamera clips the AE routine to the
805 * frame durations.
806 */
807 int32_t maxFps = std::round(1e9 / minFrameDurationNsec);
808 int32_t minFps = std::round(1e9 / maxFrameDurationNsec);
809 minFps = std::max(1, minFps);
810
811 /*
812 * Register to the camera service {min, max} and {max, max}
813 * intervals as requested by the metadata documentation.
814 */
815 int32_t availableAeFpsTarget[] = {
816 minFps, maxFps, maxFps, maxFps
817 };
818 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
819 availableAeFpsTarget, 4);
820 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200821
822 std::vector<int32_t> aeCompensationRange = {
823 0, 0,
824 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300825 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
826 aeCompensationRange.data(),
827 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200828
829 const camera_metadata_rational_t aeCompensationStep[] = {
830 { 0, 1 }
831 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300832 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
833 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200834
835 std::vector<uint8_t> availableAfModes = {
836 ANDROID_CONTROL_AF_MODE_OFF,
837 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300838 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
839 availableAfModes.data(),
840 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200841
842 std::vector<uint8_t> availableEffects = {
843 ANDROID_CONTROL_EFFECT_MODE_OFF,
844 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300845 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
846 availableEffects.data(),
847 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200848
849 std::vector<uint8_t> availableSceneModes = {
850 ANDROID_CONTROL_SCENE_MODE_DISABLED,
851 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300852 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
853 availableSceneModes.data(),
854 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200855
856 std::vector<uint8_t> availableStabilizationModes = {
857 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
858 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300859 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
860 availableStabilizationModes.data(),
861 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200862
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100863 /*
864 * \todo Inspect the Camera capabilities to report the available
865 * AWB modes. Default to AUTO as CTS tests require it.
866 */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200867 std::vector<uint8_t> availableAwbModes = {
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100868 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200869 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300870 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
871 availableAwbModes.data(),
872 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200873
874 std::vector<int32_t> availableMaxRegions = {
875 0, 0, 0,
876 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300877 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
878 availableMaxRegions.data(),
879 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200880
881 std::vector<uint8_t> sceneModesOverride = {
882 ANDROID_CONTROL_AE_MODE_ON,
883 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondif266c0e2021-02-03 16:34:40 +0100884 ANDROID_CONTROL_AF_MODE_OFF,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200885 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300886 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
887 sceneModesOverride.data(),
888 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200889
890 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300891 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
892 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200893
894 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300895 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
896 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200897
898 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300899 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
900 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200901
902 /* JPEG static metadata. */
Jacopo Mondi9e807052021-02-04 15:32:00 +0100903
904 /*
905 * Create the list of supported thumbnail sizes by inspecting the
906 * available JPEG resolutions collected in streamConfigurations_ and
907 * generate one entry for each aspect ratio.
908 *
909 * The JPEG thumbnailer can freely scale, so pick an arbitrary
910 * (160, 160) size as the bounding rectangle, which is then cropped to
911 * the different supported aspect ratios.
912 */
913 constexpr Size maxJpegThumbnail(160, 160);
914 std::vector<Size> thumbnailSizes;
915 thumbnailSizes.push_back({ 0, 0 });
916 for (const auto &entry : streamConfigurations_) {
917 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
918 continue;
919
920 Size thumbnailSize = maxJpegThumbnail
921 .boundedToAspectRatio({ entry.resolution.width,
922 entry.resolution.height });
923 thumbnailSizes.push_back(thumbnailSize);
924 }
925
926 std::sort(thumbnailSizes.begin(), thumbnailSizes.end());
927 auto last = std::unique(thumbnailSizes.begin(), thumbnailSizes.end());
928 thumbnailSizes.erase(last, thumbnailSizes.end());
929
930 /* Transform sizes in to a list of integers that can be consumed. */
931 std::vector<int32_t> thumbnailEntries;
932 thumbnailEntries.reserve(thumbnailSizes.size() * 2);
933 for (const auto &size : thumbnailSizes) {
934 thumbnailEntries.push_back(size.width);
935 thumbnailEntries.push_back(size.height);
936 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300937 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Jacopo Mondi9e807052021-02-04 15:32:00 +0100938 thumbnailEntries.data(), thumbnailEntries.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200939
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100940 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
941
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200942 /* Sensor static metadata. */
Jacopo Mondicda41ff2020-12-30 17:18:51 +0100943 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100944 const Size &size =
Jacopo Mondi0ed05322020-12-23 18:34:34 +0100945 properties.get(properties::PixelArraySize);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100946 std::vector<int32_t> data{
947 static_cast<int32_t>(size.width),
948 static_cast<int32_t>(size.height),
949 };
950 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
951 data.data(), data.size());
952 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200953
Jacopo Mondicda41ff2020-12-30 17:18:51 +0100954 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100955 const Span<const Rectangle> &rects =
Jacopo Mondi0ed05322020-12-23 18:34:34 +0100956 properties.get(properties::PixelArrayActiveAreas);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100957 std::vector<int32_t> data{
958 static_cast<int32_t>(rects[0].x),
959 static_cast<int32_t>(rects[0].y),
960 static_cast<int32_t>(rects[0].width),
961 static_cast<int32_t>(rects[0].height),
962 };
963 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
964 data.data(), data.size());
965 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200966
967 int32_t sensitivityRange[] = {
968 32, 2400,
969 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300970 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
971 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200972
Jacopo Mondicb35ed22020-12-18 16:28:43 +0100973 /* Report the color filter arrangement if the camera reports it. */
974 if (properties.contains(properties::draft::ColorFilterArrangement)) {
975 uint8_t filterArr = properties.get(properties::draft::ColorFilterArrangement);
976 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
977 &filterArr, 1);
978 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200979
Jacopo Mondi753d7532021-01-02 12:34:06 +0100980 const auto &exposureInfo = controlsInfo.find(&controls::ExposureTime);
981 if (exposureInfo != controlsInfo.end()) {
982 int64_t exposureTimeRange[2] = {
983 exposureInfo->second.min().get<int32_t>() * 1000LL,
984 exposureInfo->second.max().get<int32_t>() * 1000LL,
985 };
986 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
987 &exposureTimeRange, 2);
988 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200989
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200990 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200991
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200992 std::vector<int32_t> testPatterModes = {
993 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
994 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300995 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
996 testPatterModes.data(),
997 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200998
999 std::vector<float> physicalSize = {
1000 2592, 1944,
1001 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001002 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1003 physicalSize.data(),
1004 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001005
1006 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +03001007 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1008 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001009
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001010 if (maxFrameDurationNsec > 0)
1011 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
1012 &maxFrameDurationNsec, 1);
1013
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001014 /* Statistics static metadata. */
1015 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001016 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1017 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001018
1019 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001020 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1021 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001022
Jacopo Mondi2c618502020-10-08 16:47:36 +02001023 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001024 std::vector<uint8_t> data;
1025 data.reserve(2);
Jacopo Mondi2c618502020-10-08 16:47:36 +02001026 const auto &infoMap = controlsInfo.find(&controls::draft::LensShadingMapMode);
1027 if (infoMap != controlsInfo.end()) {
1028 for (const auto &value : infoMap->second.values())
1029 data.push_back(value.get<int32_t>());
1030 } else {
1031 data.push_back(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
1032 }
1033 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
1034 data.data(), data.size());
1035 }
1036
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001037 /* Sync static metadata. */
1038 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +03001039 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001040
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001041 /* Flash static metadata. */
1042 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001043 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
1044 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001045
1046 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001047 std::vector<float> lensApertures = {
1048 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001049 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001050 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
1051 lensApertures.data(),
1052 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001053
Jacopo Mondi64f4f662020-05-25 16:08:22 +02001054 uint8_t lensFacing;
1055 switch (facing_) {
1056 default:
1057 case CAMERA_FACING_FRONT:
1058 lensFacing = ANDROID_LENS_FACING_FRONT;
1059 break;
1060 case CAMERA_FACING_BACK:
1061 lensFacing = ANDROID_LENS_FACING_BACK;
1062 break;
1063 case CAMERA_FACING_EXTERNAL:
1064 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
1065 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +01001066 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001067 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001068
1069 std::vector<float> lensFocalLenghts = {
1070 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001071 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001072 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1073 lensFocalLenghts.data(),
1074 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001075
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001076 std::vector<uint8_t> opticalStabilizations = {
1077 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
1078 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001079 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1080 opticalStabilizations.data(),
1081 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001082
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001083 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001084 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1085 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001086
1087 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001088 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1089 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001090
1091 /* Noise reduction modes. */
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001092 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001093 std::vector<uint8_t> data;
1094 data.reserve(5);
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001095 const auto &infoMap = controlsInfo.find(&controls::draft::NoiseReductionMode);
1096 if (infoMap != controlsInfo.end()) {
1097 for (const auto &value : infoMap->second.values())
1098 data.push_back(value.get<int32_t>());
1099 } else {
1100 data.push_back(ANDROID_NOISE_REDUCTION_MODE_OFF);
1101 }
1102 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
1103 data.data(), data.size());
1104 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001105
1106 /* Scaler static metadata. */
Jacopo Mondi31a1a622021-01-03 19:57:36 +01001107 {
1108 /*
1109 * \todo The digital zoom factor is a property that depends
1110 * on the desired output configuration and the sensor frame size
1111 * input to the ISP. This information is not available to the
1112 * Android HAL, not at initialization time at least.
1113 *
1114 * As a workaround rely on pipeline handlers initializing the
1115 * ScalerCrop control with the camera default configuration and
1116 * use the maximum and minimum crop rectangles to calculate the
1117 * digital zoom factor.
1118 */
1119 const auto info = controlsInfo.find(&controls::ScalerCrop);
1120 Rectangle min = info->second.min().get<Rectangle>();
1121 Rectangle max = info->second.max().get<Rectangle>();
1122 float maxZoom = std::min(1.0f * max.width / min.width,
1123 1.0f * max.height / min.height);
1124 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1125 &maxZoom, 1);
1126 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001127
Jacopo Mondibde7b982020-05-25 17:18:28 +02001128 std::vector<uint32_t> availableStreamConfigurations;
1129 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
1130 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +02001131 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +02001132 availableStreamConfigurations.push_back(entry.resolution.width);
1133 availableStreamConfigurations.push_back(entry.resolution.height);
1134 availableStreamConfigurations.push_back(
1135 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
1136 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001137 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1138 availableStreamConfigurations.data(),
1139 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001140
1141 std::vector<int64_t> availableStallDurations = {
1142 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
1143 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001144 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1145 availableStallDurations.data(),
1146 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001147
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001148 /* Use the minimum frame duration for all the YUV/RGB formats. */
1149 if (minFrameDurationNsec > 0) {
1150 std::vector<int64_t> minFrameDurations;
1151 minFrameDurations.reserve(streamConfigurations_.size() * 4);
1152 for (const auto &entry : streamConfigurations_) {
1153 minFrameDurations.push_back(entry.androidFormat);
1154 minFrameDurations.push_back(entry.resolution.width);
1155 minFrameDurations.push_back(entry.resolution.height);
1156 minFrameDurations.push_back(minFrameDurationNsec);
1157 }
1158 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1159 minFrameDurations.data(),
1160 minFrameDurations.size());
Jacopo Mondibde7b982020-05-25 17:18:28 +02001161 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001162
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001163 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001164 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001165
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001166 /* Info static metadata. */
1167 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001168 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
1169 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001170
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001171 /* Request static metadata. */
1172 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001173 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1174 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001175
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +02001176 {
1177 /* Default the value to 2 if not reported by the camera. */
1178 uint8_t maxPipelineDepth = 2;
1179 const auto &infoMap = controlsInfo.find(&controls::draft::PipelineDepth);
1180 if (infoMap != controlsInfo.end())
1181 maxPipelineDepth = infoMap->second.max().get<int32_t>();
1182 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
1183 &maxPipelineDepth, 1);
1184 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001185
Niklas Söderlunda2a6f952020-07-21 00:16:02 +02001186 /* LIMITED does not support reprocessing. */
1187 uint32_t maxNumInputStreams = 0;
1188 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1189 &maxNumInputStreams, 1);
1190
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001191 std::vector<uint8_t> availableCapabilities = {
1192 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
1193 };
Niklas Söderlund7876d632020-07-21 00:16:24 +02001194
1195 /* Report if camera supports RAW. */
Jacopo Mondieec6c542020-12-09 18:16:11 +01001196 bool rawStreamAvailable = false;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001197 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +02001198 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +02001199 if (cameraConfig && !cameraConfig->empty()) {
1200 const PixelFormatInfo &info =
1201 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
Niklas Söderlund35de31e2020-12-31 00:11:59 +01001202 /* Only advertise RAW support if RAW16 is possible. */
1203 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW &&
1204 info.bitsPerPixel == 16) {
Jacopo Mondieec6c542020-12-09 18:16:11 +01001205 rawStreamAvailable = true;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001206 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
Jacopo Mondieec6c542020-12-09 18:16:11 +01001207 }
Niklas Söderlund7876d632020-07-21 00:16:24 +02001208 }
1209
Jacopo Mondieec6c542020-12-09 18:16:11 +01001210 /* Number of { RAW, YUV, JPEG } supported output streams */
1211 int32_t numOutStreams[] = { rawStreamAvailable, 2, 1 };
1212 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
1213 &numOutStreams, 3);
1214
Laurent Pinchart39860092019-09-05 03:12:34 +03001215 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1216 availableCapabilities.data(),
1217 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001218
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001219 std::vector<int32_t> availableCharacteristicsKeys = {
1220 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
1221 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
1222 ANDROID_CONTROL_AE_AVAILABLE_MODES,
1223 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1224 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
1225 ANDROID_CONTROL_AE_COMPENSATION_STEP,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001226 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001227 ANDROID_CONTROL_AF_AVAILABLE_MODES,
1228 ANDROID_CONTROL_AVAILABLE_EFFECTS,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001229 ANDROID_CONTROL_AVAILABLE_MODES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001230 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
1231 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
1232 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001233 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001234 ANDROID_CONTROL_MAX_REGIONS,
1235 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001236 ANDROID_FLASH_INFO_AVAILABLE,
1237 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001238 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001239 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001240 ANDROID_LENS_FACING,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001241 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001242 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1243 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1244 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1245 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1246 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001247 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1248 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1249 ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001250 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1251 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001252 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1253 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1254 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1255 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1256 ANDROID_SCALER_CROPPING_TYPE,
1257 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
1258 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
1259 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
1260 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001261 ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001262 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1263 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
1264 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
1265 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1266 ANDROID_SENSOR_ORIENTATION,
1267 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1268 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1269 ANDROID_SYNC_MAX_LATENCY,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001270 };
1271 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
1272 availableCharacteristicsKeys.data(),
1273 availableCharacteristicsKeys.size());
1274
1275 std::vector<int32_t> availableRequestKeys = {
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001276 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1277 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001278 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001279 ANDROID_CONTROL_AE_LOCK,
1280 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001281 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001282 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001283 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001284 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001285 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001286 ANDROID_CONTROL_AWB_MODE,
1287 ANDROID_CONTROL_CAPTURE_INTENT,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001288 ANDROID_CONTROL_EFFECT_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001289 ANDROID_CONTROL_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001290 ANDROID_CONTROL_SCENE_MODE,
1291 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001292 ANDROID_FLASH_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001293 ANDROID_JPEG_ORIENTATION,
1294 ANDROID_JPEG_QUALITY,
1295 ANDROID_JPEG_THUMBNAIL_QUALITY,
1296 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001297 ANDROID_LENS_APERTURE,
1298 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001299 ANDROID_NOISE_REDUCTION_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001300 ANDROID_SCALER_CROP_REGION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001301 ANDROID_STATISTICS_FACE_DETECT_MODE
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001302 };
1303 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
1304 availableRequestKeys.data(),
1305 availableRequestKeys.size());
1306
1307 std::vector<int32_t> availableResultKeys = {
Jacopo Mondi520c3662021-02-03 14:44:34 +01001308 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001309 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondie9c28752021-02-03 14:47:45 +01001310 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001311 ANDROID_CONTROL_AE_LOCK,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001312 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001313 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1314 ANDROID_CONTROL_AE_STATE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001315 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001316 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001317 ANDROID_CONTROL_AF_STATE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001318 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001319 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001320 ANDROID_CONTROL_AWB_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001321 ANDROID_CONTROL_AWB_STATE,
1322 ANDROID_CONTROL_CAPTURE_INTENT,
1323 ANDROID_CONTROL_EFFECT_MODE,
1324 ANDROID_CONTROL_MODE,
1325 ANDROID_CONTROL_SCENE_MODE,
1326 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
1327 ANDROID_FLASH_MODE,
1328 ANDROID_FLASH_STATE,
Paul Elderabfabdd2021-01-23 13:54:28 +09001329 ANDROID_JPEG_GPS_COORDINATES,
1330 ANDROID_JPEG_GPS_PROCESSING_METHOD,
1331 ANDROID_JPEG_GPS_TIMESTAMP,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001332 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001333 ANDROID_JPEG_QUALITY,
1334 ANDROID_JPEG_SIZE,
Paul Elder12646282021-01-23 13:56:01 +09001335 ANDROID_JPEG_THUMBNAIL_QUALITY,
1336 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001337 ANDROID_LENS_APERTURE,
1338 ANDROID_LENS_FOCAL_LENGTH,
1339 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1340 ANDROID_LENS_STATE,
1341 ANDROID_NOISE_REDUCTION_MODE,
1342 ANDROID_REQUEST_PIPELINE_DEPTH,
1343 ANDROID_SCALER_CROP_REGION,
1344 ANDROID_SENSOR_EXPOSURE_TIME,
1345 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
Jacopo Mondi5360d802021-02-03 16:43:22 +01001346 ANDROID_SENSOR_TEST_PATTERN_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001347 ANDROID_SENSOR_TIMESTAMP,
1348 ANDROID_STATISTICS_FACE_DETECT_MODE,
1349 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
Jacopo Mondif29601e2021-02-03 16:47:30 +01001350 ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001351 ANDROID_STATISTICS_SCENE_FLICKER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001352 };
1353 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1354 availableResultKeys.data(),
1355 availableResultKeys.size());
1356
Laurent Pinchart39860092019-09-05 03:12:34 +03001357 if (!staticMetadata_->isValid()) {
1358 LOG(HAL, Error) << "Failed to construct static metadata";
1359 delete staticMetadata_;
1360 staticMetadata_ = nullptr;
1361 return nullptr;
1362 }
1363
1364 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001365}
1366
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001367CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001368{
Jacopo Mondi63703472019-09-04 16:18:22 +02001369 /*
1370 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001371 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001372 */
Jacopo Mondi9690d082021-02-03 16:37:20 +01001373 CameraMetadata *requestTemplate = new CameraMetadata(21, 36);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001374 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001375 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001376 return nullptr;
1377 }
1378
Jacopo Mondif1796162021-03-08 17:03:14 +01001379 /* Get the FPS range registered in the static metadata. */
1380 camera_metadata_ro_entry_t entry;
1381 bool found = staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1382 &entry);
1383 if (!found) {
1384 LOG(HAL, Error) << "Cannot create capture template without FPS range";
1385 return nullptr;
1386 }
1387
1388 /*
1389 * \todo Depending on the requested CaptureIntent, the FPS range
1390 * needs to be adjusted. For example, the capture template for
1391 * video capture intent shall report a fixed value.
1392 *
1393 * Also assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
1394 * has been assembled as {{min, max} {max, max}}.
1395 */
1396 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1397 entry.data.i32, 2);
1398
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001399 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001400 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1401 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001402
1403 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001404 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1405 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001406
1407 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001408 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1409 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001410
1411 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001412 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1413 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001414
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001415 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1416 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1417 &aeAntibandingMode, 1);
1418
Jacopo Mondi9690d082021-02-03 16:37:20 +01001419 uint8_t afMode = ANDROID_CONTROL_AF_MODE_OFF;
1420 requestTemplate->addEntry(ANDROID_CONTROL_AF_MODE, &afMode, 1);
1421
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001422 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001423 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1424 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001425
1426 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001427 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1428 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001429
1430 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001431 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1432 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001433
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001434 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001435 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1436 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001437
1438 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001439 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1440 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001441
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001442 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001443 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1444 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001445
1446 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001447 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1448 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001449
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001450 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1451 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1452
1453 float lensAperture = 2.53 / 100;
1454 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1455
1456 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1457 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1458 &opticalStabilization, 1);
1459
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001460 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001461 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1462 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001463
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001464 return requestTemplate;
1465}
1466
1467/*
1468 * Produce a metadata pack to be used as template for a capture request.
1469 */
1470const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1471{
1472 auto it = requestTemplates_.find(type);
1473 if (it != requestTemplates_.end())
1474 return it->second->get();
1475
1476 /* Use the capture intent matching the requested template type. */
1477 CameraMetadata *requestTemplate;
1478 uint8_t captureIntent;
1479 switch (type) {
1480 case CAMERA3_TEMPLATE_PREVIEW:
1481 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1482 break;
1483 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1484 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1485 break;
1486 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1487 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1488 break;
1489 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1490 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1491 break;
Jacopo Mondi2c349912021-03-08 16:13:58 +01001492 /* \todo Implement templates generation for the remaining use cases. */
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001493 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001494 case CAMERA3_TEMPLATE_MANUAL:
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001495 default:
Jacopo Mondi2c349912021-03-08 16:13:58 +01001496 LOG(HAL, Error) << "Unsupported template request type: " << type;
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001497 return nullptr;
1498 }
1499
1500 requestTemplate = requestTemplatePreview();
1501 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001502 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001503 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001504 return nullptr;
1505 }
1506
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001507 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1508 &captureIntent, 1);
1509
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001510 requestTemplates_[type] = requestTemplate;
1511 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001512}
1513
Hirokazu Hondac1ae9052020-10-28 18:50:23 +09001514PixelFormat CameraDevice::toPixelFormat(int format) const
Kieran Bingham43e3b802020-06-26 09:58:49 +01001515{
1516 /* Translate Android format code to libcamera pixel format. */
1517 auto it = formatsMap_.find(format);
1518 if (it == formatsMap_.end()) {
1519 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1520 << " not supported";
1521 return PixelFormat();
1522 }
1523
1524 return it->second;
1525}
1526
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001527/*
1528 * Inspect the stream_list to produce a list of StreamConfiguration to
1529 * be use to configure the Camera.
1530 */
1531int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1532{
Jacopo Mondi8fed6132020-12-04 15:26:47 +01001533 /* Before any configuration attempt, stop the camera if it's running. */
1534 if (running_) {
1535 worker_.stop();
1536 camera_->stop();
1537 running_ = false;
1538 }
1539
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001540 /*
1541 * Generate an empty configuration, and construct a StreamConfiguration
1542 * for each camera3_stream to add to it.
1543 */
1544 config_ = camera_->generateConfiguration();
1545 if (!config_) {
1546 LOG(HAL, Error) << "Failed to generate camera configuration";
1547 return -EINVAL;
1548 }
1549
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001550 /*
1551 * Clear and remove any existing configuration from previous calls, and
1552 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001553 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001554 */
1555 streams_.clear();
1556 streams_.reserve(stream_list->num_streams);
1557
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001558 std::vector<Camera3StreamConfig> streamConfigs;
1559 streamConfigs.reserve(stream_list->num_streams);
1560
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001561 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001562 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001563 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1564 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001565 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001566
Kieran Bingham43e3b802020-06-26 09:58:49 +01001567 PixelFormat format = toPixelFormat(stream->format);
1568
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001569 LOG(HAL, Info) << "Stream #" << i
1570 << ", direction: " << stream->stream_type
1571 << ", width: " << stream->width
1572 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001573 << ", format: " << utils::hex(stream->format)
1574 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001575
1576 if (!format.isValid())
1577 return -EINVAL;
1578
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001579 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001580 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1581 if (jpegStream) {
1582 LOG(HAL, Error)
1583 << "Multiple JPEG streams are not supported";
1584 return -EINVAL;
1585 }
1586
1587 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001588 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001589 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001590
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001591 Camera3StreamConfig streamConfig;
1592 streamConfig.streams = { { stream, CameraStream::Type::Direct } };
1593 streamConfig.config.size = size;
1594 streamConfig.config.pixelFormat = format;
1595 streamConfigs.push_back(std::move(streamConfig));
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001596
1597 /* This stream will be produced by hardware. */
1598 stream->usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001599 }
1600
Jacopo Mondic82f9442020-09-02 11:58:00 +02001601 /* Now handle the MJPEG streams, adding a new stream if required. */
1602 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001603 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001604 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001605
Jacopo Mondic82f9442020-09-02 11:58:00 +02001606 /* Search for a compatible stream in the non-JPEG ones. */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001607 for (size_t i = 0; i < streamConfigs.size(); ++i) {
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001608 Camera3StreamConfig &streamConfig = streamConfigs[i];
1609 const auto &cfg = streamConfig.config;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001610
1611 /*
1612 * \todo The PixelFormat must also be compatible with
1613 * the encoder.
1614 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001615 if (cfg.size.width != jpegStream->width ||
1616 cfg.size.height != jpegStream->height)
1617 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001618
Jacopo Mondic82f9442020-09-02 11:58:00 +02001619 LOG(HAL, Info)
1620 << "Android JPEG stream mapped to libcamera stream " << i;
1621
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001622 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001623 index = i;
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001624
1625 /*
1626 * The source stream will be read by software to
1627 * produce the JPEG stream.
1628 */
1629 camera3_stream_t *stream = streamConfig.streams[0].stream;
1630 stream->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001631 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001632 }
1633
1634 /*
1635 * Without a compatible match for JPEG encoding we must
1636 * introduce a new stream to satisfy the request requirements.
1637 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001638 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001639 /*
1640 * \todo The pixelFormat should be a 'best-fit' choice
1641 * and may require a validation cycle. This is not yet
1642 * handled, and should be considered as part of any
1643 * stream configuration reworks.
1644 */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001645 Camera3StreamConfig streamConfig;
1646 streamConfig.config.size.width = jpegStream->width;
1647 streamConfig.config.size.height = jpegStream->height;
1648 streamConfig.config.pixelFormat = formats::NV12;
1649 streamConfigs.push_back(std::move(streamConfig));
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001650
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001651 LOG(HAL, Info) << "Adding " << streamConfig.config.toString()
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001652 << " for MJPEG support";
1653
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001654 type = CameraStream::Type::Internal;
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001655 index = streamConfigs.size() - 1;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001656 }
1657
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001658 /* The JPEG stream will be produced by software. */
1659 jpegStream->usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
1660
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001661 streamConfigs[index].streams.push_back({ jpegStream, type });
1662 }
1663
Hirokazu Honda26d90af2020-12-11 09:53:36 +00001664 sortCamera3StreamConfigs(streamConfigs, jpegStream);
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001665 for (const auto &streamConfig : streamConfigs) {
1666 config_->addConfiguration(streamConfig.config);
1667
1668 for (auto &stream : streamConfig.streams) {
1669 streams_.emplace_back(this, stream.type, stream.stream,
1670 config_->size() - 1);
1671 stream.stream->priv = static_cast<void *>(&streams_.back());
1672 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001673 }
1674
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001675 switch (config_->validate()) {
1676 case CameraConfiguration::Valid:
1677 break;
1678 case CameraConfiguration::Adjusted:
1679 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001680
1681 for (const StreamConfiguration &cfg : *config_)
1682 LOG(HAL, Info) << " - " << cfg.toString();
1683
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001684 config_.reset();
1685 return -EINVAL;
1686 case CameraConfiguration::Invalid:
1687 LOG(HAL, Info) << "Camera configuration invalid";
1688 config_.reset();
1689 return -EINVAL;
1690 }
1691
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001692 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001693 * Once the CameraConfiguration has been adjusted/validated
1694 * it can be applied to the camera.
1695 */
1696 int ret = camera_->configure(config_.get());
1697 if (ret) {
1698 LOG(HAL, Error) << "Failed to configure camera '"
1699 << camera_->id() << "'";
1700 return ret;
1701 }
1702
1703 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001704 * Configure the HAL CameraStream instances using the associated
1705 * StreamConfiguration and set the number of required buffers in
1706 * the Android camera3_stream_t.
1707 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001708 for (CameraStream &cameraStream : streams_) {
Kieran Binghamc7bcae02020-10-13 15:58:26 +01001709 ret = cameraStream.configure();
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001710 if (ret) {
1711 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001712 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001713 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001714 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001715
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001716 return 0;
1717}
1718
Kieran Bingham74ab4422020-07-01 13:25:38 +01001719FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1720{
1721 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001722 for (int i = 0; i < camera3buffer->numFds; i++) {
1723 /* Skip unused planes. */
1724 if (camera3buffer->data[i] == -1)
1725 break;
1726
Kieran Bingham74ab4422020-07-01 13:25:38 +01001727 FrameBuffer::Plane plane;
1728 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001729 if (!plane.fd.isValid()) {
1730 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1731 << camera3buffer->data[i] << ") "
1732 << " on plane " << i;
1733 return nullptr;
1734 }
1735
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001736 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1737 if (length == -1) {
1738 LOG(HAL, Error) << "Failed to query plane length";
1739 return nullptr;
1740 }
1741
1742 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001743 planes.push_back(std::move(plane));
1744 }
1745
1746 return new FrameBuffer(std::move(planes));
1747}
1748
Jacopo Mondibb2b4002021-01-04 16:20:05 +01001749int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)
1750{
1751 const CameraMetadata &settings = descriptor->settings_;
1752 if (!settings.isValid())
1753 return 0;
1754
1755 /* Translate the Android request settings to libcamera controls. */
1756 camera_metadata_ro_entry_t entry;
1757 if (settings.getEntry(ANDROID_SCALER_CROP_REGION, &entry)) {
1758 const int32_t *data = entry.data.i32;
1759 Rectangle cropRegion{ data[0], data[1],
1760 static_cast<unsigned int>(data[2]),
1761 static_cast<unsigned int>(data[3]) };
1762 ControlList &controls = descriptor->request_->controls();
1763 controls.set(controls::ScalerCrop, cropRegion);
1764 }
1765
1766 return 0;
1767}
1768
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001769int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001770{
Jacopo Mondic5b732b2020-12-01 17:12:19 +01001771 if (!camera3Request) {
1772 LOG(HAL, Error) << "No capture request provided";
1773 return -EINVAL;
1774 }
1775
Kieran Bingham61f42962020-07-01 13:40:17 +01001776 if (!camera3Request->num_output_buffers) {
1777 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001778 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001779 }
1780
1781 /* Start the camera if that's the first request we handle. */
1782 if (!running_) {
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001783 worker_.start();
1784
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001785 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001786 if (ret) {
1787 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001788 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001789 }
1790
1791 running_ = true;
1792 }
1793
1794 /*
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001795 * Save the request descriptors for use at completion time.
1796 * The descriptor and the associated memory reserved here are freed
1797 * at request complete time.
1798 */
1799 Camera3RequestDescriptor *descriptor =
Jacopo Mondidd1cd532021-01-21 10:51:05 +01001800 new Camera3RequestDescriptor(camera_.get(), camera3Request);
Paul Eldera6de3f02021-01-21 18:59:24 +09001801 /*
1802 * \todo The Android request model is incremental, settings passed in
1803 * previous requests are to be effective until overridden explicitly in
1804 * a new request. Do we need to cache settings incrementally here, or is
1805 * it handled by the Android camera service ?
1806 */
1807 if (camera3Request->settings)
1808 lastSettings_ = camera3Request->settings;
1809 else
1810 descriptor->settings_ = lastSettings_;
Kieran Binghameac05422020-07-01 13:28:16 +01001811
Jacopo Mondibc644072021-01-28 09:58:06 +01001812 LOG(HAL, Debug) << "Queueing request " << descriptor->request_->cookie()
1813 << " with " << descriptor->numBuffers_ << " streams";
Kieran Bingham37c18c22020-10-21 14:54:11 +01001814 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001815 const camera3_stream_buffer_t *camera3Buffer = &descriptor->buffers_[i];
1816 camera3_stream *camera3Stream = camera3Buffer->stream;
1817 CameraStream *cameraStream = static_cast<CameraStream *>(camera3Stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001818
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001819 std::stringstream ss;
1820 ss << i << " - (" << camera3Stream->width << "x"
1821 << camera3Stream->height << ")"
1822 << "[" << utils::hex(camera3Stream->format) << "] -> "
1823 << "(" << cameraStream->configuration().size.toString() << ")["
1824 << cameraStream->configuration().pixelFormat.toString() << "]";
1825
Jacopo Mondide8304b2020-09-04 17:45:39 +02001826 /*
1827 * Inspect the camera stream type, create buffers opportunely
1828 * and add them to the Request if required.
1829 */
1830 FrameBuffer *buffer = nullptr;
1831 switch (cameraStream->type()) {
1832 case CameraStream::Type::Mapped:
1833 /*
1834 * Mapped streams don't need buffers added to the
1835 * Request.
1836 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001837 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001838 continue;
1839
Jacopo Mondide8304b2020-09-04 17:45:39 +02001840 case CameraStream::Type::Direct:
1841 /*
1842 * Create a libcamera buffer using the dmabuf
1843 * descriptors of the camera3Buffer for each stream and
1844 * associate it with the Camera3RequestDescriptor for
1845 * lifetime management only.
1846 */
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001847 buffer = createFrameBuffer(*camera3Buffer->buffer);
Kieran Bingham37c18c22020-10-21 14:54:11 +01001848 descriptor->frameBuffers_.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001849 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001850 break;
1851
1852 case CameraStream::Type::Internal:
1853 /*
1854 * Get the frame buffer from the CameraStream internal
1855 * buffer pool.
1856 *
1857 * The buffer has to be returned to the CameraStream
1858 * once it has been processed.
1859 */
1860 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001861 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001862 break;
1863 }
1864
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001865 if (!buffer) {
1866 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001867 delete descriptor;
1868 return -ENOMEM;
1869 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001870
Kieran Bingham37c18c22020-10-21 14:54:11 +01001871 descriptor->request_->addBuffer(cameraStream->stream(), buffer,
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001872 camera3Buffer->acquire_fence);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001873 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001874
Jacopo Mondibb2b4002021-01-04 16:20:05 +01001875 /*
1876 * Translate controls from Android to libcamera and queue the request
1877 * to the CameraWorker thread.
1878 */
1879 int ret = processControls(descriptor);
1880 if (ret)
1881 return ret;
1882
Kieran Bingham37c18c22020-10-21 14:54:11 +01001883 worker_.queueRequest(descriptor->request_.get());
Paul Elderc7532232020-09-23 19:05:41 +09001884
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001885 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001886}
1887
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001888void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001889{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001890 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001891 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001892 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001893 Camera3RequestDescriptor *descriptor =
1894 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001895
1896 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001897 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001898 << request->status();
1899 status = CAMERA3_BUFFER_STATUS_ERROR;
1900 }
1901
Jacopo Mondibc644072021-01-28 09:58:06 +01001902 LOG(HAL, Debug) << "Request " << request->cookie() << " completed with "
1903 << descriptor->numBuffers_ << " streams";
1904
Kieran Binghamc09aee42020-07-28 14:01:19 +01001905 /*
1906 * \todo The timestamp used for the metadata is currently always taken
1907 * from the first buffer (which may be the first stream) in the Request.
1908 * It might be appropriate to return a 'correct' (as determined by
1909 * pipeline handlers) timestamp in the Request itself.
1910 */
Hirokazu Honda3a777d82020-10-28 17:57:26 +09001911 uint64_t timestamp = buffers.begin()->second->metadata().timestamp;
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001912 resultMetadata = getResultMetadata(descriptor, timestamp);
Kieran Binghamc09aee42020-07-28 14:01:19 +01001913
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001914 /* Handle any JPEG compression. */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001915 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001916 CameraStream *cameraStream =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001917 static_cast<CameraStream *>(descriptor->buffers_[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001918
Jacopo Mondi160bb092020-10-02 20:48:35 +02001919 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001920 continue;
1921
Jacopo Mondid5473c92021-02-17 16:21:59 +01001922 FrameBuffer *src = request->findBuffer(cameraStream->stream());
1923 if (!src) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001924 LOG(HAL, Error) << "Failed to find a source stream buffer";
1925 continue;
1926 }
1927
Jacopo Mondia725baf2021-02-24 12:50:40 +01001928 int ret = cameraStream->process(*src,
1929 *descriptor->buffers_[i].buffer,
Paul Elderabfabdd2021-01-23 13:54:28 +09001930 descriptor->settings_,
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02001931 resultMetadata.get());
1932 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001933 status = CAMERA3_BUFFER_STATUS_ERROR;
1934 continue;
1935 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02001936
1937 /*
1938 * Return the FrameBuffer to the CameraStream now that we're
1939 * done processing it.
1940 */
1941 if (cameraStream->type() == CameraStream::Type::Internal)
Jacopo Mondid5473c92021-02-17 16:21:59 +01001942 cameraStream->putBuffer(src);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001943 }
1944
1945 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001946 camera3_capture_result_t captureResult = {};
Kieran Bingham37c18c22020-10-21 14:54:11 +01001947 captureResult.frame_number = descriptor->frameNumber_;
1948 captureResult.num_output_buffers = descriptor->numBuffers_;
1949 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
1950 descriptor->buffers_[i].acquire_fence = -1;
1951 descriptor->buffers_[i].release_fence = -1;
1952 descriptor->buffers_[i].status = status;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001953 }
1954 captureResult.output_buffers =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001955 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers_);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001956
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001957
Laurent Pinchart39860092019-09-05 03:12:34 +03001958 if (status == CAMERA3_BUFFER_STATUS_OK) {
Kieran Binghame1f9fdb2020-10-21 15:31:10 +01001959 notifyShutter(descriptor->frameNumber_, timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001960
1961 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001962 captureResult.result = resultMetadata->get();
1963 }
1964
1965 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1966 /* \todo Improve error handling. In case we notify an error
1967 * because the metadata generation fails, a shutter event has
1968 * already been notified for this frame number before the error
1969 * is here signalled. Make sure the error path plays well with
1970 * the camera stack state machine.
1971 */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001972 notifyError(descriptor->frameNumber_,
1973 descriptor->buffers_[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001974 }
1975
1976 callbacks_->process_capture_result(callbacks_, &captureResult);
1977
1978 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001979}
1980
Jacopo Mondia7b92772020-05-26 15:41:41 +02001981std::string CameraDevice::logPrefix() const
1982{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001983 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001984}
1985
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001986void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1987{
1988 camera3_notify_msg_t notify = {};
1989
1990 notify.type = CAMERA3_MSG_SHUTTER;
1991 notify.message.shutter.frame_number = frameNumber;
1992 notify.message.shutter.timestamp = timestamp;
1993
1994 callbacks_->notify(callbacks_, &notify);
1995}
1996
1997void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1998{
1999 camera3_notify_msg_t notify = {};
2000
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01002001 /*
2002 * \todo Report and identify the stream number or configuration to
2003 * clarify the stream that failed.
2004 */
2005 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
2006 << toPixelFormat(stream->format).toString() << ")";
2007
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002008 notify.type = CAMERA3_MSG_ERROR;
2009 notify.message.error.error_stream = stream;
2010 notify.message.error.frame_number = frameNumber;
2011 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
2012
2013 callbacks_->notify(callbacks_, &notify);
2014}
2015
2016/*
2017 * Produce a set of fixed result metadata.
2018 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03002019std::unique_ptr<CameraMetadata>
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002020CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor,
Laurent Pinchartdbafe162019-10-27 00:36:13 +03002021 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002022{
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002023 const ControlList &metadata = descriptor->request_->metadata();
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002024 const CameraMetadata &settings = descriptor->settings_;
Paul Elder958c80a2021-01-26 09:47:33 +09002025 camera_metadata_ro_entry_t entry;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002026 bool found;
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002027
Jacopo Mondi48504ba2019-09-04 16:18:19 +02002028 /*
2029 * \todo Keep this in sync with the actual number of entries.
Paul Elder12646282021-01-23 13:56:01 +09002030 * Currently: 40 entries, 156 bytes
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002031 *
2032 * Reserve more space for the JPEG metadata set by the post-processor.
Paul Elderabfabdd2021-01-23 13:54:28 +09002033 * Currently:
2034 * ANDROID_JPEG_GPS_COORDINATES (double x 3) = 24 bytes
2035 * ANDROID_JPEG_GPS_PROCESSING_METHOD (byte x 32) = 32 bytes
2036 * ANDROID_JPEG_GPS_TIMESTAMP (int64) = 8 bytes
2037 * ANDROID_JPEG_SIZE (int32_t) = 4 bytes
2038 * ANDROID_JPEG_QUALITY (byte) = 1 byte
2039 * ANDROID_JPEG_ORIENTATION (int32_t) = 4 bytes
Paul Elder12646282021-01-23 13:56:01 +09002040 * ANDROID_JPEG_THUMBNAIL_QUALITY (byte) = 1 byte
2041 * ANDROID_JPEG_THUMBNAIL_SIZE (int32 x 2) = 8 bytes
2042 * Total bytes for JPEG metadata: 82
Jacopo Mondi48504ba2019-09-04 16:18:19 +02002043 */
Laurent Pinchart39860092019-09-05 03:12:34 +03002044 std::unique_ptr<CameraMetadata> resultMetadata =
Jacopo Mondif29601e2021-02-03 16:47:30 +01002045 std::make_unique<CameraMetadata>(44, 166);
Laurent Pinchart39860092019-09-05 03:12:34 +03002046 if (!resultMetadata->isValid()) {
2047 LOG(HAL, Error) << "Failed to allocate static metadata";
2048 return nullptr;
2049 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002050
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002051 /*
2052 * \todo The value of the results metadata copied from the settings
2053 * will have to be passed to the libcamera::Camera and extracted
2054 * from libcamera::Request::metadata.
2055 */
2056
Jacopo Mondi520c3662021-02-03 14:44:34 +01002057 uint8_t value = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
2058 resultMetadata->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
2059 &value, 1);
2060
2061 value = ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF;
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002062 resultMetadata->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002063
Jacopo Mondie9c28752021-02-03 14:47:45 +01002064 int32_t value32 = 0;
2065 resultMetadata->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
2066 &value32, 1);
2067
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002068 value = ANDROID_CONTROL_AE_LOCK_OFF;
2069 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002070
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002071 value = ANDROID_CONTROL_AE_MODE_ON;
2072 resultMetadata->addEntry(ANDROID_CONTROL_AE_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002073
Jacopo Mondid1508602021-01-21 18:21:28 +01002074 if (settings.getEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, &entry))
2075 /*
2076 * \todo Retrieve the AE FPS range from the libcamera metadata.
2077 * As libcamera does not support that control, as a temporary
2078 * workaround return what the framework asked.
2079 */
2080 resultMetadata->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
2081 entry.data.i32, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002082
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002083 value = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002084 found = settings.getEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &entry);
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002085 resultMetadata->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002086 found ? entry.data.u8 : &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002087
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002088 value = ANDROID_CONTROL_AE_STATE_CONVERGED;
2089 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &value, 1);
2090
2091 value = ANDROID_CONTROL_AF_MODE_OFF;
2092 resultMetadata->addEntry(ANDROID_CONTROL_AF_MODE, &value, 1);
2093
2094 value = ANDROID_CONTROL_AF_STATE_INACTIVE;
2095 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &value, 1);
2096
2097 value = ANDROID_CONTROL_AF_TRIGGER_IDLE;
2098 resultMetadata->addEntry(ANDROID_CONTROL_AF_TRIGGER, &value, 1);
2099
2100 value = ANDROID_CONTROL_AWB_MODE_AUTO;
2101 resultMetadata->addEntry(ANDROID_CONTROL_AWB_MODE, &value, 1);
2102
2103 value = ANDROID_CONTROL_AWB_LOCK_OFF;
2104 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &value, 1);
2105
2106 value = ANDROID_CONTROL_AWB_STATE_CONVERGED;
2107 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &value, 1);
2108
2109 value = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
2110 resultMetadata->addEntry(ANDROID_CONTROL_CAPTURE_INTENT, &value, 1);
2111
2112 value = ANDROID_CONTROL_EFFECT_MODE_OFF;
2113 resultMetadata->addEntry(ANDROID_CONTROL_EFFECT_MODE, &value, 1);
2114
2115 value = ANDROID_CONTROL_MODE_AUTO;
2116 resultMetadata->addEntry(ANDROID_CONTROL_MODE, &value, 1);
2117
2118 value = ANDROID_CONTROL_SCENE_MODE_DISABLED;
2119 resultMetadata->addEntry(ANDROID_CONTROL_SCENE_MODE, &value, 1);
2120
2121 value = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
2122 resultMetadata->addEntry(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &value, 1);
2123
2124 value = ANDROID_FLASH_MODE_OFF;
2125 resultMetadata->addEntry(ANDROID_FLASH_MODE, &value, 1);
2126
2127 value = ANDROID_FLASH_STATE_UNAVAILABLE;
2128 resultMetadata->addEntry(ANDROID_FLASH_STATE, &value, 1);
2129
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002130 if (settings.getEntry(ANDROID_LENS_APERTURE, &entry))
Paul Elderabfabdd2021-01-23 13:54:28 +09002131 resultMetadata->addEntry(ANDROID_LENS_APERTURE, entry.data.f, 1);
2132
2133 float focal_length = 1.0;
2134 resultMetadata->addEntry(ANDROID_LENS_FOCAL_LENGTH, &focal_length, 1);
2135
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002136 value = ANDROID_LENS_STATE_STATIONARY;
2137 resultMetadata->addEntry(ANDROID_LENS_STATE, &value, 1);
2138
2139 value = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
2140 resultMetadata->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
2141 &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002142
Jacopo Mondi5360d802021-02-03 16:43:22 +01002143 value32 = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
2144 resultMetadata->addEntry(ANDROID_SENSOR_TEST_PATTERN_MODE,
2145 &value32, 1);
2146
Laurent Pinchart39860092019-09-05 03:12:34 +03002147 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002148
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002149 value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
2150 resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
2151 &value, 1);
2152
2153 value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
2154 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
2155 &value, 1);
2156
Jacopo Mondif29601e2021-02-03 16:47:30 +01002157 value = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
2158 resultMetadata->addEntry(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
2159 &value, 1);
2160
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002161 value = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
2162 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
2163 &value, 1);
2164
2165 value = ANDROID_NOISE_REDUCTION_MODE_OFF;
2166 resultMetadata->addEntry(ANDROID_NOISE_REDUCTION_MODE, &value, 1);
2167
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002168 /* 33.3 msec */
2169 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03002170 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
2171 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002172
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002173 /* Add metadata tags reported by libcamera. */
2174 if (metadata.contains(controls::draft::PipelineDepth)) {
2175 uint8_t pipeline_depth =
2176 metadata.get<int32_t>(controls::draft::PipelineDepth);
2177 resultMetadata->addEntry(ANDROID_REQUEST_PIPELINE_DEPTH,
2178 &pipeline_depth, 1);
2179 }
2180
Jacopo Mondic9705a52021-01-05 19:30:48 +01002181 if (metadata.contains(controls::ExposureTime)) {
Paul Elder78f49d52021-01-28 17:45:44 +09002182 int64_t exposure = metadata.get(controls::ExposureTime) * 1000ULL;
Jacopo Mondic9705a52021-01-05 19:30:48 +01002183 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
2184 &exposure, 1);
2185 }
2186
Jacopo Mondibb2b4002021-01-04 16:20:05 +01002187 if (metadata.contains(controls::ScalerCrop)) {
2188 Rectangle crop = metadata.get(controls::ScalerCrop);
2189 int32_t cropRect[] = {
2190 crop.x, crop.y, static_cast<int32_t>(crop.width),
2191 static_cast<int32_t>(crop.height),
2192 };
2193 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, cropRect, 4);
2194 }
2195
Laurent Pinchart39860092019-09-05 03:12:34 +03002196 /*
2197 * Return the result metadata pack even is not valid: get() will return
2198 * nullptr.
2199 */
2200 if (!resultMetadata->isValid()) {
2201 LOG(HAL, Error) << "Failed to construct result metadata";
2202 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002203
2204 return resultMetadata;
2205}