blob: 0e942390db5dc51686fb639aabffef14c725cfdf [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. */
Hirokazu Honda17a6e782021-03-24 16:07:55 +0900274 const uint32_t numBuffers = camera3Request->num_output_buffers;
275 buffers_.resize(numBuffers);
276 for (uint32_t i = 0; i < numBuffers; i++)
Jacopo Mondi4b18b822021-01-21 11:10:08 +0100277 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 */
Hirokazu Honda17a6e782021-03-24 16:07:55 +0900283 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
Hirokazu Honda17a6e782021-03-24 16:07:55 +0900297CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor() = default;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200298
299/*
300 * \class CameraDevice
301 *
302 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200303 * the camera3_device_t interface, bridging calls received from the Android
304 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200305 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200306 * The class translates parameters and operations from the Camera HALv3 API to
307 * the libcamera API to provide static information for a Camera, create request
308 * templates for it, process capture requests and then deliver capture results
309 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200310 */
311
Hirokazu Honda9538ce42021-03-24 16:07:53 +0900312CameraDevice::CameraDevice(unsigned int id, std::shared_ptr<Camera> camera)
313 : id_(id), running_(false), camera_(std::move(camera)),
Hirokazu Hondadca709c2021-03-24 16:07:56 +0900314 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200315{
316 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100317
Paul Elder229653a2021-01-21 17:44:14 +0900318 maker_ = "libcamera";
319 model_ = "cameraModel";
320
321 /* \todo Support getting properties on Android */
322 std::ifstream fstream("/var/cache/camera/camera.prop");
323 if (!fstream.is_open())
324 return;
325
326 std::string line;
327 while (std::getline(fstream, line)) {
328 std::string::size_type delimPos = line.find("=");
329 if (delimPos == std::string::npos)
330 continue;
331 std::string key = line.substr(0, delimPos);
332 std::string val = line.substr(delimPos + 1);
333
334 if (!key.compare("ro.product.model"))
335 model_ = val;
336 else if (!key.compare("ro.product.manufacturer"))
337 maker_ = val;
338 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200339}
340
Hirokazu Hondaf101cc62021-03-24 16:07:57 +0900341CameraDevice::~CameraDevice() = default;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200342
Hirokazu Honda212f4102021-03-24 16:07:50 +0900343std::unique_ptr<CameraDevice> CameraDevice::create(unsigned int id,
Hirokazu Honda9538ce42021-03-24 16:07:53 +0900344 std::shared_ptr<Camera> cam)
Umang Jainf8e28132020-08-21 14:46:08 +0000345{
Hirokazu Honda9538ce42021-03-24 16:07:53 +0900346 return std::unique_ptr<CameraDevice>(
347 new CameraDevice(id, std::move(cam)));
Umang Jainf8e28132020-08-21 14:46:08 +0000348}
349
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200350/*
351 * Initialize the camera static information.
352 * This method is called before the camera device is opened.
353 */
354int CameraDevice::initialize()
355{
356 /* Initialize orientation and facing side of the camera. */
357 const ControlList &properties = camera_->properties();
358
359 if (properties.contains(properties::Location)) {
360 int32_t location = properties.get(properties::Location);
361 switch (location) {
362 case properties::CameraLocationFront:
363 facing_ = CAMERA_FACING_FRONT;
364 break;
365 case properties::CameraLocationBack:
366 facing_ = CAMERA_FACING_BACK;
367 break;
368 case properties::CameraLocationExternal:
Jacopo Mondi5154e142021-03-10 14:00:50 +0100369 facing_ = CAMERA_FACING_EXTERNAL;
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200370 break;
371 }
Jacopo Mondi5154e142021-03-10 14:00:50 +0100372 } else {
373 /*
374 * \todo Retrieve the camera location from configuration file
375 * if not available from the library.
376 */
377 facing_ = CAMERA_FACING_FRONT;
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200378 }
379
380 /*
Umang Jaine9176552020-09-09 16:17:54 +0530381 * The Android orientation metadata specifies its rotation correction
382 * value in clockwise direction whereas libcamera specifies the
383 * rotation property in anticlockwise direction. Read the libcamera's
384 * rotation property (anticlockwise) and compute the corresponding
385 * value for clockwise direction as required by the Android orientation
386 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200387 */
Umang Jaine9176552020-09-09 16:17:54 +0530388 if (properties.contains(properties::Rotation)) {
389 int rotation = properties.get(properties::Rotation);
390 orientation_ = (360 - rotation) % 360;
391 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200392
Jacopo Mondi117588b2020-05-23 18:53:54 +0200393 int ret = camera_->acquire();
394 if (ret) {
395 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
396 return ret;
397 }
398
399 ret = initializeStreamConfigurations();
400 camera_->release();
401 return ret;
402}
403
Jacopo Mondibfee6312020-09-01 17:42:13 +0200404std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
405 const PixelFormat &pixelFormat,
406 const std::vector<Size> &resolutions)
407{
408 std::vector<Size> supportedResolutions;
409
410 StreamConfiguration &cfg = cameraConfig->at(0);
411 for (const Size &res : resolutions) {
412 cfg.pixelFormat = pixelFormat;
413 cfg.size = res;
414
415 CameraConfiguration::Status status = cameraConfig->validate();
416 if (status != CameraConfiguration::Valid) {
417 LOG(HAL, Debug) << cfg.toString() << " not supported";
418 continue;
419 }
420
421 LOG(HAL, Debug) << cfg.toString() << " supported";
422
423 supportedResolutions.push_back(res);
424 }
425
426 return supportedResolutions;
427}
428
Jacopo Mondi49610332020-09-01 18:11:34 +0200429std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
430{
431 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200432 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200433 StreamConfiguration &cfg = cameraConfig->at(0);
434 const StreamFormats &formats = cfg.formats();
435 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
436
437 return supportedResolutions;
438}
439
Jacopo Mondi117588b2020-05-23 18:53:54 +0200440/*
441 * Initialize the format conversion map to translate from Android format
442 * identifier to libcamera pixel formats and fill in the list of supported
443 * stream configurations to be reported to the Android camera framework through
444 * the static stream configuration metadata.
445 */
446int CameraDevice::initializeStreamConfigurations()
447{
448 /*
449 * Get the maximum output resolutions
450 * \todo Get this from the camera properties once defined
451 */
452 std::unique_ptr<CameraConfiguration> cameraConfig =
453 camera_->generateConfiguration({ StillCapture });
454 if (!cameraConfig) {
455 LOG(HAL, Error) << "Failed to get maximum resolution";
456 return -EINVAL;
457 }
458 StreamConfiguration &cfg = cameraConfig->at(0);
459
460 /*
461 * \todo JPEG - Adjust the maximum available resolution by taking the
462 * JPEG encoder requirements into account (alignment and aspect ratio).
463 */
464 const Size maxRes = cfg.size;
465 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
466
467 /*
468 * Build the list of supported image resolutions.
469 *
470 * The resolutions listed in camera3Resolution are mandatory to be
471 * supported, up to the camera maximum resolution.
472 *
473 * Augment the list by adding resolutions calculated from the camera
474 * maximum one.
475 */
476 std::vector<Size> cameraResolutions;
477 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
478 std::back_inserter(cameraResolutions),
479 [&](const Size &res) { return res < maxRes; });
480
481 /*
482 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
483 * resolution.
484 */
485 for (unsigned int divider = 2;; divider <<= 1) {
486 Size derivedSize{
487 maxRes.width / divider,
488 maxRes.height / divider,
489 };
490
491 if (derivedSize.width < 320 ||
492 derivedSize.height < 240)
493 break;
494
495 cameraResolutions.push_back(derivedSize);
496 }
497 cameraResolutions.push_back(maxRes);
498
499 /* Remove duplicated entries from the list of supported resolutions. */
500 std::sort(cameraResolutions.begin(), cameraResolutions.end());
501 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
502 cameraResolutions.erase(last, cameraResolutions.end());
503
504 /*
505 * Build the list of supported camera formats.
506 *
507 * To each Android format a list of compatible libcamera formats is
508 * associated. The first libcamera format that tests successful is added
509 * to the format translation map used when configuring the streams.
510 * It is then tested against the list of supported camera resolutions to
511 * build the stream configuration map reported through the camera static
512 * metadata.
513 */
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100514 Size maxJpegSize;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200515 for (const auto &format : camera3FormatsMap) {
516 int androidFormat = format.first;
517 const Camera3Format &camera3Format = format.second;
518 const std::vector<PixelFormat> &libcameraFormats =
519 camera3Format.libcameraFormats;
520
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200521 LOG(HAL, Debug) << "Trying to map Android format "
522 << camera3Format.name;
523
Jacopo Mondi117588b2020-05-23 18:53:54 +0200524 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200525 * JPEG is always supported, either produced directly by the
526 * camera, or encoded in the HAL.
527 */
528 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
529 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200530 LOG(HAL, Debug) << "Mapped Android format "
531 << camera3Format.name << " to "
532 << formats::MJPEG.toString()
533 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200534 continue;
535 }
536
537 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200538 * Test the libcamera formats that can produce images
539 * compatible with the format defined by Android.
540 */
541 PixelFormat mappedFormat;
542 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200543
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200544 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
545
Jacopo Mondi117588b2020-05-23 18:53:54 +0200546 /*
547 * The stream configuration size can be adjusted,
548 * not the pixel format.
549 *
550 * \todo This could be simplified once all pipeline
551 * handlers will report the StreamFormats list of
552 * supported formats.
553 */
554 cfg.pixelFormat = pixelFormat;
555
556 CameraConfiguration::Status status = cameraConfig->validate();
557 if (status != CameraConfiguration::Invalid &&
558 cfg.pixelFormat == pixelFormat) {
559 mappedFormat = pixelFormat;
560 break;
561 }
562 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200563
564 if (!mappedFormat.isValid()) {
565 /* If the format is not mandatory, skip it. */
566 if (!camera3Format.mandatory)
567 continue;
568
569 LOG(HAL, Error)
570 << "Failed to map mandatory Android format "
571 << camera3Format.name << " ("
572 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200573 return -EINVAL;
574 }
575
576 /*
577 * Record the mapping and then proceed to generate the
578 * stream configurations map, by testing the image resolutions.
579 */
580 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200581 LOG(HAL, Debug) << "Mapped Android format "
582 << camera3Format.name << " to "
583 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200584
Jacopo Mondi49610332020-09-01 18:11:34 +0200585 std::vector<Size> resolutions;
586 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
587 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
588 resolutions = getRawResolutions(mappedFormat);
589 else
590 resolutions = getYUVResolutions(cameraConfig.get(),
591 mappedFormat,
592 cameraResolutions);
593
Jacopo Mondibfee6312020-09-01 17:42:13 +0200594 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200595 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200596
597 /*
598 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
599 * from which JPEG is produced, add an entry for
600 * the JPEG stream.
601 *
602 * \todo Wire the JPEG encoder to query the supported
603 * sizes provided a list of formats it can encode.
604 *
605 * \todo Support JPEG streams produced by the Camera
606 * natively.
607 */
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100608 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
Jacopo Mondi843565c2020-09-01 15:34:13 +0200609 streamConfigurations_.push_back(
610 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100611 maxJpegSize = std::max(maxJpegSize, res);
612 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200613 }
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100614
615 /*
616 * \todo Calculate the maximum JPEG buffer size by asking the
617 * encoder giving the maximum frame size required.
618 */
619 maxJpegBufferSize_ = maxJpegSize.width * maxJpegSize.height * 1.5;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200620 }
621
622 LOG(HAL, Debug) << "Collected stream configuration map: ";
623 for (const auto &entry : streamConfigurations_)
624 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200625 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200626
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200627 return 0;
628}
629
630/*
631 * Open a camera device. The static information on the camera shall have been
632 * initialized with a call to CameraDevice::initialize().
633 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200634int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200635{
636 int ret = camera_->acquire();
637 if (ret) {
638 LOG(HAL, Error) << "Failed to acquire the camera";
639 return ret;
640 }
641
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200642 /* Initialize the hw_device_t in the instance camera3_module_t. */
643 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
644 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
645 camera3Device_.common.module = (hw_module_t *)hardwareModule;
646 camera3Device_.common.close = hal_dev_close;
647
648 /*
649 * The camera device operations. These actually implement
650 * the Android Camera HALv3 interface.
651 */
652 camera3Device_.ops = &hal_dev_ops;
653 camera3Device_.priv = this;
654
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200655 return 0;
656}
657
658void CameraDevice::close()
659{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200660 streams_.clear();
661
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200662 worker_.stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200663 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200664 camera_->release();
665
666 running_ = false;
667}
668
669void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
670{
671 callbacks_ = callbacks;
672}
673
Jacopo Mondia80d3812020-05-26 12:31:35 +0200674std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
675{
676 /*
677 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100678 * Currently: 54 entries, 874 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200679 */
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100680 uint32_t numEntries = 54;
681 uint32_t byteSize = 874;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200682
683 /*
684 * Calculate space occupation in bytes for dynamically built metadata
685 * entries.
686 *
Jacopo Mondi00982fb2021-02-04 16:57:55 +0100687 * Each stream configuration entry requires 48 bytes:
Jacopo Mondia80d3812020-05-26 12:31:35 +0200688 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200689 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
690 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200691 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200692
Jacopo Mondi9e807052021-02-04 15:32:00 +0100693 /*
694 * 2 32bits integers for each HAL_PIXEL_FORMAT_BLOB for thumbnail sizes
695 * 2 32bits integers for the (0, 0) thumbnail size
696 *
697 * This is a worst case estimates as different configurations with the
698 * same aspect ratio will generate the same size.
699 */
700 for (const auto &entry : streamConfigurations_) {
701 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
702 continue;
703
704 byteSize += 8;
705 }
706 byteSize += 8;
707
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300708 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200709}
710
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200711/*
712 * Return static information for the camera.
713 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200714const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200715{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200716 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300717 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200718
719 /*
720 * The here reported metadata are enough to implement a basic capture
721 * example application, but a real camera implementation will require
722 * more.
723 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200724 uint32_t numEntries;
725 uint32_t byteSize;
726 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
Hirokazu Hondadca709c2021-03-24 16:07:56 +0900727 staticMetadata_ = std::make_unique<CameraMetadata>(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300728 if (!staticMetadata_->isValid()) {
729 LOG(HAL, Error) << "Failed to allocate static metadata";
Hirokazu Hondadca709c2021-03-24 16:07:56 +0900730 staticMetadata_.reset();
Laurent Pinchart39860092019-09-05 03:12:34 +0300731 return nullptr;
732 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200733
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200734 const ControlInfoMap &controlsInfo = camera_->controls();
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100735 const ControlList &properties = camera_->properties();
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200736
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200737 /* Color correction static metadata. */
Jacopo Mondi63336862020-10-08 16:18:26 +0200738 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100739 std::vector<uint8_t> data;
740 data.reserve(3);
Jacopo Mondi63336862020-10-08 16:18:26 +0200741 const auto &infoMap = controlsInfo.find(&controls::draft::ColorCorrectionAberrationMode);
742 if (infoMap != controlsInfo.end()) {
743 for (const auto &value : infoMap->second.values())
744 data.push_back(value.get<int32_t>());
745 } else {
746 data.push_back(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
747 }
748 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
749 data.data(), data.size());
750 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200751
752 /* Control static metadata. */
753 std::vector<uint8_t> aeAvailableAntiBandingModes = {
754 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
755 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
756 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
757 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
758 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300759 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
760 aeAvailableAntiBandingModes.data(),
761 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200762
763 std::vector<uint8_t> aeAvailableModes = {
764 ANDROID_CONTROL_AE_MODE_ON,
765 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300766 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
767 aeAvailableModes.data(),
768 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200769
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100770 int64_t minFrameDurationNsec = -1;
771 int64_t maxFrameDurationNsec = -1;
772 const auto frameDurationsInfo = controlsInfo.find(&controls::FrameDurations);
773 if (frameDurationsInfo != controlsInfo.end()) {
774 minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000;
775 maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000;
776
777 /*
778 * Adjust the minimum frame duration to comply with Android
779 * requirements. The camera service mandates all preview/record
780 * streams to have a minimum frame duration < 33,366 milliseconds
781 * (see MAX_PREVIEW_RECORD_DURATION_NS in the camera service
782 * implementation).
783 *
784 * If we're close enough (+ 500 useconds) to that value, round
785 * the minimum frame duration of the camera to an accepted
786 * value.
787 */
788 static constexpr int64_t MAX_PREVIEW_RECORD_DURATION_NS = 1e9 / 29.97;
789 if (minFrameDurationNsec > MAX_PREVIEW_RECORD_DURATION_NS &&
790 minFrameDurationNsec < MAX_PREVIEW_RECORD_DURATION_NS + 500000)
791 minFrameDurationNsec = MAX_PREVIEW_RECORD_DURATION_NS - 1000;
792
793 /*
794 * The AE routine frame rate limits are computed using the frame
795 * duration limits, as libcamera clips the AE routine to the
796 * frame durations.
797 */
798 int32_t maxFps = std::round(1e9 / minFrameDurationNsec);
799 int32_t minFps = std::round(1e9 / maxFrameDurationNsec);
800 minFps = std::max(1, minFps);
801
802 /*
803 * Register to the camera service {min, max} and {max, max}
804 * intervals as requested by the metadata documentation.
805 */
806 int32_t availableAeFpsTarget[] = {
807 minFps, maxFps, maxFps, maxFps
808 };
809 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
810 availableAeFpsTarget, 4);
811 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200812
813 std::vector<int32_t> aeCompensationRange = {
814 0, 0,
815 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300816 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
817 aeCompensationRange.data(),
818 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200819
820 const camera_metadata_rational_t aeCompensationStep[] = {
821 { 0, 1 }
822 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300823 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
824 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200825
826 std::vector<uint8_t> availableAfModes = {
827 ANDROID_CONTROL_AF_MODE_OFF,
828 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300829 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
830 availableAfModes.data(),
831 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200832
833 std::vector<uint8_t> availableEffects = {
834 ANDROID_CONTROL_EFFECT_MODE_OFF,
835 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300836 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
837 availableEffects.data(),
838 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200839
840 std::vector<uint8_t> availableSceneModes = {
841 ANDROID_CONTROL_SCENE_MODE_DISABLED,
842 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300843 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
844 availableSceneModes.data(),
845 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200846
847 std::vector<uint8_t> availableStabilizationModes = {
848 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
849 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300850 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
851 availableStabilizationModes.data(),
852 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200853
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100854 /*
855 * \todo Inspect the Camera capabilities to report the available
856 * AWB modes. Default to AUTO as CTS tests require it.
857 */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200858 std::vector<uint8_t> availableAwbModes = {
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100859 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200860 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300861 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
862 availableAwbModes.data(),
863 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200864
865 std::vector<int32_t> availableMaxRegions = {
866 0, 0, 0,
867 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300868 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
869 availableMaxRegions.data(),
870 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200871
872 std::vector<uint8_t> sceneModesOverride = {
873 ANDROID_CONTROL_AE_MODE_ON,
874 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondif266c0e2021-02-03 16:34:40 +0100875 ANDROID_CONTROL_AF_MODE_OFF,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200876 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300877 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
878 sceneModesOverride.data(),
879 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200880
881 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300882 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
883 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200884
885 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300886 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
887 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200888
889 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300890 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
891 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200892
893 /* JPEG static metadata. */
Jacopo Mondi9e807052021-02-04 15:32:00 +0100894
895 /*
896 * Create the list of supported thumbnail sizes by inspecting the
897 * available JPEG resolutions collected in streamConfigurations_ and
898 * generate one entry for each aspect ratio.
899 *
900 * The JPEG thumbnailer can freely scale, so pick an arbitrary
901 * (160, 160) size as the bounding rectangle, which is then cropped to
902 * the different supported aspect ratios.
903 */
904 constexpr Size maxJpegThumbnail(160, 160);
905 std::vector<Size> thumbnailSizes;
906 thumbnailSizes.push_back({ 0, 0 });
907 for (const auto &entry : streamConfigurations_) {
908 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
909 continue;
910
911 Size thumbnailSize = maxJpegThumbnail
912 .boundedToAspectRatio({ entry.resolution.width,
913 entry.resolution.height });
914 thumbnailSizes.push_back(thumbnailSize);
915 }
916
917 std::sort(thumbnailSizes.begin(), thumbnailSizes.end());
918 auto last = std::unique(thumbnailSizes.begin(), thumbnailSizes.end());
919 thumbnailSizes.erase(last, thumbnailSizes.end());
920
921 /* Transform sizes in to a list of integers that can be consumed. */
922 std::vector<int32_t> thumbnailEntries;
923 thumbnailEntries.reserve(thumbnailSizes.size() * 2);
924 for (const auto &size : thumbnailSizes) {
925 thumbnailEntries.push_back(size.width);
926 thumbnailEntries.push_back(size.height);
927 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300928 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Jacopo Mondi9e807052021-02-04 15:32:00 +0100929 thumbnailEntries.data(), thumbnailEntries.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200930
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100931 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
932
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200933 /* Sensor static metadata. */
Jacopo Mondicda41ff2020-12-30 17:18:51 +0100934 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100935 const Size &size =
Jacopo Mondi0ed05322020-12-23 18:34:34 +0100936 properties.get(properties::PixelArraySize);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100937 std::vector<int32_t> data{
938 static_cast<int32_t>(size.width),
939 static_cast<int32_t>(size.height),
940 };
941 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
942 data.data(), data.size());
943 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200944
Jacopo Mondicda41ff2020-12-30 17:18:51 +0100945 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100946 const Span<const Rectangle> &rects =
Jacopo Mondi0ed05322020-12-23 18:34:34 +0100947 properties.get(properties::PixelArrayActiveAreas);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100948 std::vector<int32_t> data{
949 static_cast<int32_t>(rects[0].x),
950 static_cast<int32_t>(rects[0].y),
951 static_cast<int32_t>(rects[0].width),
952 static_cast<int32_t>(rects[0].height),
953 };
954 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
955 data.data(), data.size());
956 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200957
958 int32_t sensitivityRange[] = {
959 32, 2400,
960 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300961 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
962 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200963
Jacopo Mondicb35ed22020-12-18 16:28:43 +0100964 /* Report the color filter arrangement if the camera reports it. */
965 if (properties.contains(properties::draft::ColorFilterArrangement)) {
966 uint8_t filterArr = properties.get(properties::draft::ColorFilterArrangement);
967 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
968 &filterArr, 1);
969 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200970
Jacopo Mondi753d7532021-01-02 12:34:06 +0100971 const auto &exposureInfo = controlsInfo.find(&controls::ExposureTime);
972 if (exposureInfo != controlsInfo.end()) {
973 int64_t exposureTimeRange[2] = {
974 exposureInfo->second.min().get<int32_t>() * 1000LL,
975 exposureInfo->second.max().get<int32_t>() * 1000LL,
976 };
977 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
978 &exposureTimeRange, 2);
979 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200980
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200981 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200982
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200983 std::vector<int32_t> testPatterModes = {
984 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
985 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300986 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
987 testPatterModes.data(),
988 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200989
990 std::vector<float> physicalSize = {
991 2592, 1944,
992 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300993 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
994 physicalSize.data(),
995 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200996
997 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300998 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
999 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001000
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001001 if (maxFrameDurationNsec > 0)
1002 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
1003 &maxFrameDurationNsec, 1);
1004
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001005 /* Statistics static metadata. */
1006 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001007 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1008 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001009
1010 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001011 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1012 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001013
Jacopo Mondi2c618502020-10-08 16:47:36 +02001014 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001015 std::vector<uint8_t> data;
1016 data.reserve(2);
Jacopo Mondi2c618502020-10-08 16:47:36 +02001017 const auto &infoMap = controlsInfo.find(&controls::draft::LensShadingMapMode);
1018 if (infoMap != controlsInfo.end()) {
1019 for (const auto &value : infoMap->second.values())
1020 data.push_back(value.get<int32_t>());
1021 } else {
1022 data.push_back(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
1023 }
1024 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
1025 data.data(), data.size());
1026 }
1027
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001028 /* Sync static metadata. */
1029 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +03001030 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001031
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001032 /* Flash static metadata. */
1033 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001034 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
1035 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001036
1037 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001038 std::vector<float> lensApertures = {
1039 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001040 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001041 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
1042 lensApertures.data(),
1043 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001044
Jacopo Mondi64f4f662020-05-25 16:08:22 +02001045 uint8_t lensFacing;
1046 switch (facing_) {
1047 default:
1048 case CAMERA_FACING_FRONT:
1049 lensFacing = ANDROID_LENS_FACING_FRONT;
1050 break;
1051 case CAMERA_FACING_BACK:
1052 lensFacing = ANDROID_LENS_FACING_BACK;
1053 break;
1054 case CAMERA_FACING_EXTERNAL:
1055 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
1056 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +01001057 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001058 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001059
1060 std::vector<float> lensFocalLenghts = {
1061 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001062 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001063 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1064 lensFocalLenghts.data(),
1065 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001066
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001067 std::vector<uint8_t> opticalStabilizations = {
1068 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
1069 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001070 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1071 opticalStabilizations.data(),
1072 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001073
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001074 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001075 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1076 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001077
1078 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001079 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1080 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001081
1082 /* Noise reduction modes. */
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001083 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001084 std::vector<uint8_t> data;
1085 data.reserve(5);
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001086 const auto &infoMap = controlsInfo.find(&controls::draft::NoiseReductionMode);
1087 if (infoMap != controlsInfo.end()) {
1088 for (const auto &value : infoMap->second.values())
1089 data.push_back(value.get<int32_t>());
1090 } else {
1091 data.push_back(ANDROID_NOISE_REDUCTION_MODE_OFF);
1092 }
1093 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
1094 data.data(), data.size());
1095 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001096
1097 /* Scaler static metadata. */
Phi-Bang Nguyen8634c382021-03-29 19:40:46 +02001098
1099 /*
1100 * \todo The digital zoom factor is a property that depends on the
1101 * desired output configuration and the sensor frame size input to the
1102 * ISP. This information is not available to the Android HAL, not at
1103 * initialization time at least.
1104 *
1105 * As a workaround rely on pipeline handlers initializing the
1106 * ScalerCrop control with the camera default configuration and use the
1107 * maximum and minimum crop rectangles to calculate the digital zoom
1108 * factor.
1109 */
1110 float maxZoom = 1.0f;
1111 const auto scalerCrop = controlsInfo.find(&controls::ScalerCrop);
1112 if (scalerCrop != controlsInfo.end()) {
1113 Rectangle min = scalerCrop->second.min().get<Rectangle>();
1114 Rectangle max = scalerCrop->second.max().get<Rectangle>();
1115 maxZoom = std::min(1.0f * max.width / min.width,
1116 1.0f * max.height / min.height);
Jacopo Mondi31a1a622021-01-03 19:57:36 +01001117 }
Phi-Bang Nguyen8634c382021-03-29 19:40:46 +02001118 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1119 &maxZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001120
Jacopo Mondibde7b982020-05-25 17:18:28 +02001121 std::vector<uint32_t> availableStreamConfigurations;
1122 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
1123 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +02001124 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +02001125 availableStreamConfigurations.push_back(entry.resolution.width);
1126 availableStreamConfigurations.push_back(entry.resolution.height);
1127 availableStreamConfigurations.push_back(
1128 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
1129 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001130 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1131 availableStreamConfigurations.data(),
1132 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001133
1134 std::vector<int64_t> availableStallDurations = {
1135 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
1136 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001137 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1138 availableStallDurations.data(),
1139 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001140
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001141 /* Use the minimum frame duration for all the YUV/RGB formats. */
1142 if (minFrameDurationNsec > 0) {
1143 std::vector<int64_t> minFrameDurations;
1144 minFrameDurations.reserve(streamConfigurations_.size() * 4);
1145 for (const auto &entry : streamConfigurations_) {
1146 minFrameDurations.push_back(entry.androidFormat);
1147 minFrameDurations.push_back(entry.resolution.width);
1148 minFrameDurations.push_back(entry.resolution.height);
1149 minFrameDurations.push_back(minFrameDurationNsec);
1150 }
1151 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1152 minFrameDurations.data(),
1153 minFrameDurations.size());
Jacopo Mondibde7b982020-05-25 17:18:28 +02001154 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001155
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001156 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001157 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001158
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001159 /* Info static metadata. */
1160 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001161 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
1162 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001163
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001164 /* Request static metadata. */
1165 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001166 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1167 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001168
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +02001169 {
1170 /* Default the value to 2 if not reported by the camera. */
1171 uint8_t maxPipelineDepth = 2;
1172 const auto &infoMap = controlsInfo.find(&controls::draft::PipelineDepth);
1173 if (infoMap != controlsInfo.end())
1174 maxPipelineDepth = infoMap->second.max().get<int32_t>();
1175 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
1176 &maxPipelineDepth, 1);
1177 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001178
Niklas Söderlunda2a6f952020-07-21 00:16:02 +02001179 /* LIMITED does not support reprocessing. */
1180 uint32_t maxNumInputStreams = 0;
1181 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1182 &maxNumInputStreams, 1);
1183
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001184 std::vector<uint8_t> availableCapabilities = {
1185 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
1186 };
Niklas Söderlund7876d632020-07-21 00:16:24 +02001187
1188 /* Report if camera supports RAW. */
Jacopo Mondieec6c542020-12-09 18:16:11 +01001189 bool rawStreamAvailable = false;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001190 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +02001191 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +02001192 if (cameraConfig && !cameraConfig->empty()) {
1193 const PixelFormatInfo &info =
1194 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
Niklas Söderlund35de31e2020-12-31 00:11:59 +01001195 /* Only advertise RAW support if RAW16 is possible. */
1196 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW &&
1197 info.bitsPerPixel == 16) {
Jacopo Mondieec6c542020-12-09 18:16:11 +01001198 rawStreamAvailable = true;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001199 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
Jacopo Mondieec6c542020-12-09 18:16:11 +01001200 }
Niklas Söderlund7876d632020-07-21 00:16:24 +02001201 }
1202
Jacopo Mondieec6c542020-12-09 18:16:11 +01001203 /* Number of { RAW, YUV, JPEG } supported output streams */
1204 int32_t numOutStreams[] = { rawStreamAvailable, 2, 1 };
1205 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
1206 &numOutStreams, 3);
1207
Laurent Pinchart39860092019-09-05 03:12:34 +03001208 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1209 availableCapabilities.data(),
1210 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001211
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001212 std::vector<int32_t> availableCharacteristicsKeys = {
1213 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
1214 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
1215 ANDROID_CONTROL_AE_AVAILABLE_MODES,
1216 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1217 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
1218 ANDROID_CONTROL_AE_COMPENSATION_STEP,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001219 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001220 ANDROID_CONTROL_AF_AVAILABLE_MODES,
1221 ANDROID_CONTROL_AVAILABLE_EFFECTS,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001222 ANDROID_CONTROL_AVAILABLE_MODES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001223 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
1224 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
1225 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001226 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001227 ANDROID_CONTROL_MAX_REGIONS,
1228 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001229 ANDROID_FLASH_INFO_AVAILABLE,
1230 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001231 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001232 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001233 ANDROID_LENS_FACING,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001234 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001235 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1236 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1237 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1238 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1239 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001240 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1241 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1242 ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001243 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1244 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001245 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1246 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1247 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1248 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1249 ANDROID_SCALER_CROPPING_TYPE,
1250 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
1251 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
1252 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
1253 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001254 ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001255 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1256 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
1257 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
1258 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1259 ANDROID_SENSOR_ORIENTATION,
1260 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1261 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1262 ANDROID_SYNC_MAX_LATENCY,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001263 };
1264 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
1265 availableCharacteristicsKeys.data(),
1266 availableCharacteristicsKeys.size());
1267
1268 std::vector<int32_t> availableRequestKeys = {
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001269 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1270 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001271 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001272 ANDROID_CONTROL_AE_LOCK,
1273 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001274 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001275 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001276 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001277 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001278 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001279 ANDROID_CONTROL_AWB_MODE,
1280 ANDROID_CONTROL_CAPTURE_INTENT,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001281 ANDROID_CONTROL_EFFECT_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001282 ANDROID_CONTROL_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001283 ANDROID_CONTROL_SCENE_MODE,
1284 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001285 ANDROID_FLASH_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001286 ANDROID_JPEG_ORIENTATION,
1287 ANDROID_JPEG_QUALITY,
1288 ANDROID_JPEG_THUMBNAIL_QUALITY,
1289 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001290 ANDROID_LENS_APERTURE,
1291 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001292 ANDROID_NOISE_REDUCTION_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001293 ANDROID_SCALER_CROP_REGION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001294 ANDROID_STATISTICS_FACE_DETECT_MODE
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001295 };
1296 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
1297 availableRequestKeys.data(),
1298 availableRequestKeys.size());
1299
1300 std::vector<int32_t> availableResultKeys = {
Jacopo Mondi520c3662021-02-03 14:44:34 +01001301 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001302 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondie9c28752021-02-03 14:47:45 +01001303 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001304 ANDROID_CONTROL_AE_LOCK,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001305 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001306 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1307 ANDROID_CONTROL_AE_STATE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001308 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001309 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001310 ANDROID_CONTROL_AF_STATE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001311 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001312 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001313 ANDROID_CONTROL_AWB_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001314 ANDROID_CONTROL_AWB_STATE,
1315 ANDROID_CONTROL_CAPTURE_INTENT,
1316 ANDROID_CONTROL_EFFECT_MODE,
1317 ANDROID_CONTROL_MODE,
1318 ANDROID_CONTROL_SCENE_MODE,
1319 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
1320 ANDROID_FLASH_MODE,
1321 ANDROID_FLASH_STATE,
Paul Elderabfabdd2021-01-23 13:54:28 +09001322 ANDROID_JPEG_GPS_COORDINATES,
1323 ANDROID_JPEG_GPS_PROCESSING_METHOD,
1324 ANDROID_JPEG_GPS_TIMESTAMP,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001325 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001326 ANDROID_JPEG_QUALITY,
1327 ANDROID_JPEG_SIZE,
Paul Elder12646282021-01-23 13:56:01 +09001328 ANDROID_JPEG_THUMBNAIL_QUALITY,
1329 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001330 ANDROID_LENS_APERTURE,
1331 ANDROID_LENS_FOCAL_LENGTH,
1332 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1333 ANDROID_LENS_STATE,
1334 ANDROID_NOISE_REDUCTION_MODE,
1335 ANDROID_REQUEST_PIPELINE_DEPTH,
1336 ANDROID_SCALER_CROP_REGION,
1337 ANDROID_SENSOR_EXPOSURE_TIME,
1338 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
Jacopo Mondi5360d802021-02-03 16:43:22 +01001339 ANDROID_SENSOR_TEST_PATTERN_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001340 ANDROID_SENSOR_TIMESTAMP,
1341 ANDROID_STATISTICS_FACE_DETECT_MODE,
1342 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
Jacopo Mondif29601e2021-02-03 16:47:30 +01001343 ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001344 ANDROID_STATISTICS_SCENE_FLICKER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001345 };
1346 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1347 availableResultKeys.data(),
1348 availableResultKeys.size());
1349
Laurent Pinchart39860092019-09-05 03:12:34 +03001350 if (!staticMetadata_->isValid()) {
1351 LOG(HAL, Error) << "Failed to construct static metadata";
Hirokazu Hondadca709c2021-03-24 16:07:56 +09001352 staticMetadata_.reset();
Laurent Pinchart39860092019-09-05 03:12:34 +03001353 return nullptr;
1354 }
1355
1356 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001357}
1358
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001359std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001360{
Jacopo Mondi63703472019-09-04 16:18:22 +02001361 /*
1362 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001363 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001364 */
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001365 auto requestTemplate = std::make_unique<CameraMetadata>(21, 36);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001366 if (!requestTemplate->isValid()) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001367 return nullptr;
1368 }
1369
Jacopo Mondif1796162021-03-08 17:03:14 +01001370 /* Get the FPS range registered in the static metadata. */
1371 camera_metadata_ro_entry_t entry;
1372 bool found = staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1373 &entry);
1374 if (!found) {
1375 LOG(HAL, Error) << "Cannot create capture template without FPS range";
1376 return nullptr;
1377 }
1378
1379 /*
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001380 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
Jacopo Mondif1796162021-03-08 17:03:14 +01001381 * has been assembled as {{min, max} {max, max}}.
1382 */
1383 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1384 entry.data.i32, 2);
1385
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001386 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001387 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1388 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001389
1390 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001391 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1392 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001393
1394 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001395 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1396 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001397
1398 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001399 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1400 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001401
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001402 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1403 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1404 &aeAntibandingMode, 1);
1405
Jacopo Mondi9690d082021-02-03 16:37:20 +01001406 uint8_t afMode = ANDROID_CONTROL_AF_MODE_OFF;
1407 requestTemplate->addEntry(ANDROID_CONTROL_AF_MODE, &afMode, 1);
1408
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001409 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001410 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1411 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001412
1413 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001414 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1415 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001416
1417 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001418 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1419 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001420
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001421 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001422 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1423 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001424
1425 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001426 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1427 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001428
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001429 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001430 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1431 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001432
1433 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001434 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1435 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001436
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001437 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1438 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1439
1440 float lensAperture = 2.53 / 100;
1441 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1442
1443 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1444 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1445 &opticalStabilization, 1);
1446
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001447 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001448 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1449 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001450
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001451 return requestTemplate;
1452}
1453
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001454std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateVideo()
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001455{
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001456 std::unique_ptr<CameraMetadata> previewTemplate = requestTemplatePreview();
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001457 if (!previewTemplate)
1458 return nullptr;
1459
1460 /*
1461 * The video template requires a fixed FPS range. Everything else
1462 * stays the same as the preview template.
1463 */
1464 camera_metadata_ro_entry_t entry;
1465 staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1466 &entry);
1467
1468 /*
1469 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
1470 * has been assembled as {{min, max} {max, max}}.
1471 */
1472 previewTemplate->updateEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1473 entry.data.i32 + 2, 2);
1474
1475 return previewTemplate;
1476}
1477
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001478/*
1479 * Produce a metadata pack to be used as template for a capture request.
1480 */
1481const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1482{
1483 auto it = requestTemplates_.find(type);
1484 if (it != requestTemplates_.end())
1485 return it->second->get();
1486
1487 /* Use the capture intent matching the requested template type. */
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001488 std::unique_ptr<CameraMetadata> requestTemplate;
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001489 uint8_t captureIntent;
1490 switch (type) {
1491 case CAMERA3_TEMPLATE_PREVIEW:
1492 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001493 requestTemplate = requestTemplatePreview();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001494 break;
1495 case CAMERA3_TEMPLATE_STILL_CAPTURE:
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001496 /*
1497 * Use the preview template for still capture, they only differ
1498 * for the torch mode we currently do not support.
1499 */
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001500 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001501 requestTemplate = requestTemplatePreview();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001502 break;
1503 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1504 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001505 requestTemplate = requestTemplateVideo();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001506 break;
1507 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1508 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001509 requestTemplate = requestTemplateVideo();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001510 break;
Jacopo Mondi2c349912021-03-08 16:13:58 +01001511 /* \todo Implement templates generation for the remaining use cases. */
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001512 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001513 case CAMERA3_TEMPLATE_MANUAL:
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001514 default:
Jacopo Mondi2c349912021-03-08 16:13:58 +01001515 LOG(HAL, Error) << "Unsupported template request type: " << type;
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001516 return nullptr;
1517 }
1518
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001519 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001520 LOG(HAL, Error) << "Failed to construct request template";
Laurent Pinchart39860092019-09-05 03:12:34 +03001521 return nullptr;
1522 }
1523
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001524 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1525 &captureIntent, 1);
1526
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001527 requestTemplates_[type] = std::move(requestTemplate);
1528 return requestTemplates_[type]->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001529}
1530
Hirokazu Hondac1ae9052020-10-28 18:50:23 +09001531PixelFormat CameraDevice::toPixelFormat(int format) const
Kieran Bingham43e3b802020-06-26 09:58:49 +01001532{
1533 /* Translate Android format code to libcamera pixel format. */
1534 auto it = formatsMap_.find(format);
1535 if (it == formatsMap_.end()) {
1536 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1537 << " not supported";
1538 return PixelFormat();
1539 }
1540
1541 return it->second;
1542}
1543
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001544/*
1545 * Inspect the stream_list to produce a list of StreamConfiguration to
1546 * be use to configure the Camera.
1547 */
1548int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1549{
Jacopo Mondi8fed6132020-12-04 15:26:47 +01001550 /* Before any configuration attempt, stop the camera if it's running. */
1551 if (running_) {
1552 worker_.stop();
1553 camera_->stop();
1554 running_ = false;
1555 }
1556
Hirokazu Hondad13462f2021-04-03 22:18:28 +09001557 if (stream_list->num_streams == 0) {
1558 LOG(HAL, Error) << "No streams in configuration";
1559 return -EINVAL;
1560 }
1561
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001562 /*
1563 * Generate an empty configuration, and construct a StreamConfiguration
1564 * for each camera3_stream to add to it.
1565 */
1566 config_ = camera_->generateConfiguration();
1567 if (!config_) {
1568 LOG(HAL, Error) << "Failed to generate camera configuration";
1569 return -EINVAL;
1570 }
1571
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001572 /*
1573 * Clear and remove any existing configuration from previous calls, and
1574 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001575 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001576 */
1577 streams_.clear();
1578 streams_.reserve(stream_list->num_streams);
1579
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001580 std::vector<Camera3StreamConfig> streamConfigs;
1581 streamConfigs.reserve(stream_list->num_streams);
1582
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001583 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001584 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001585 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1586 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001587 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001588
Kieran Bingham43e3b802020-06-26 09:58:49 +01001589 PixelFormat format = toPixelFormat(stream->format);
1590
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001591 LOG(HAL, Info) << "Stream #" << i
1592 << ", direction: " << stream->stream_type
1593 << ", width: " << stream->width
1594 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001595 << ", format: " << utils::hex(stream->format)
1596 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001597
1598 if (!format.isValid())
1599 return -EINVAL;
1600
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001601 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001602 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1603 if (jpegStream) {
1604 LOG(HAL, Error)
1605 << "Multiple JPEG streams are not supported";
1606 return -EINVAL;
1607 }
1608
1609 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001610 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001611 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001612
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001613 Camera3StreamConfig streamConfig;
1614 streamConfig.streams = { { stream, CameraStream::Type::Direct } };
1615 streamConfig.config.size = size;
1616 streamConfig.config.pixelFormat = format;
1617 streamConfigs.push_back(std::move(streamConfig));
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001618
1619 /* This stream will be produced by hardware. */
1620 stream->usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001621 }
1622
Jacopo Mondic82f9442020-09-02 11:58:00 +02001623 /* Now handle the MJPEG streams, adding a new stream if required. */
1624 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001625 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001626 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001627
Jacopo Mondic82f9442020-09-02 11:58:00 +02001628 /* Search for a compatible stream in the non-JPEG ones. */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001629 for (size_t i = 0; i < streamConfigs.size(); ++i) {
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001630 Camera3StreamConfig &streamConfig = streamConfigs[i];
1631 const auto &cfg = streamConfig.config;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001632
1633 /*
1634 * \todo The PixelFormat must also be compatible with
1635 * the encoder.
1636 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001637 if (cfg.size.width != jpegStream->width ||
1638 cfg.size.height != jpegStream->height)
1639 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001640
Jacopo Mondic82f9442020-09-02 11:58:00 +02001641 LOG(HAL, Info)
1642 << "Android JPEG stream mapped to libcamera stream " << i;
1643
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001644 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001645 index = i;
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001646
1647 /*
1648 * The source stream will be read by software to
1649 * produce the JPEG stream.
1650 */
1651 camera3_stream_t *stream = streamConfig.streams[0].stream;
1652 stream->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001653 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001654 }
1655
1656 /*
1657 * Without a compatible match for JPEG encoding we must
1658 * introduce a new stream to satisfy the request requirements.
1659 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001660 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001661 /*
1662 * \todo The pixelFormat should be a 'best-fit' choice
1663 * and may require a validation cycle. This is not yet
1664 * handled, and should be considered as part of any
1665 * stream configuration reworks.
1666 */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001667 Camera3StreamConfig streamConfig;
1668 streamConfig.config.size.width = jpegStream->width;
1669 streamConfig.config.size.height = jpegStream->height;
1670 streamConfig.config.pixelFormat = formats::NV12;
1671 streamConfigs.push_back(std::move(streamConfig));
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001672
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001673 LOG(HAL, Info) << "Adding " << streamConfig.config.toString()
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001674 << " for MJPEG support";
1675
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001676 type = CameraStream::Type::Internal;
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001677 index = streamConfigs.size() - 1;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001678 }
1679
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001680 /* The JPEG stream will be produced by software. */
1681 jpegStream->usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
1682
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001683 streamConfigs[index].streams.push_back({ jpegStream, type });
1684 }
1685
Hirokazu Honda26d90af2020-12-11 09:53:36 +00001686 sortCamera3StreamConfigs(streamConfigs, jpegStream);
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001687 for (const auto &streamConfig : streamConfigs) {
1688 config_->addConfiguration(streamConfig.config);
1689
1690 for (auto &stream : streamConfig.streams) {
1691 streams_.emplace_back(this, stream.type, stream.stream,
1692 config_->size() - 1);
1693 stream.stream->priv = static_cast<void *>(&streams_.back());
1694 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001695 }
1696
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001697 switch (config_->validate()) {
1698 case CameraConfiguration::Valid:
1699 break;
1700 case CameraConfiguration::Adjusted:
1701 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001702
1703 for (const StreamConfiguration &cfg : *config_)
1704 LOG(HAL, Info) << " - " << cfg.toString();
1705
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001706 config_.reset();
1707 return -EINVAL;
1708 case CameraConfiguration::Invalid:
1709 LOG(HAL, Info) << "Camera configuration invalid";
1710 config_.reset();
1711 return -EINVAL;
1712 }
1713
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001714 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001715 * Once the CameraConfiguration has been adjusted/validated
1716 * it can be applied to the camera.
1717 */
1718 int ret = camera_->configure(config_.get());
1719 if (ret) {
1720 LOG(HAL, Error) << "Failed to configure camera '"
1721 << camera_->id() << "'";
1722 return ret;
1723 }
1724
1725 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001726 * Configure the HAL CameraStream instances using the associated
1727 * StreamConfiguration and set the number of required buffers in
1728 * the Android camera3_stream_t.
1729 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001730 for (CameraStream &cameraStream : streams_) {
Kieran Binghamc7bcae02020-10-13 15:58:26 +01001731 ret = cameraStream.configure();
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001732 if (ret) {
1733 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001734 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001735 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001736 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001737
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001738 return 0;
1739}
1740
Kieran Bingham74ab4422020-07-01 13:25:38 +01001741FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1742{
1743 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001744 for (int i = 0; i < camera3buffer->numFds; i++) {
1745 /* Skip unused planes. */
1746 if (camera3buffer->data[i] == -1)
1747 break;
1748
Kieran Bingham74ab4422020-07-01 13:25:38 +01001749 FrameBuffer::Plane plane;
1750 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001751 if (!plane.fd.isValid()) {
1752 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1753 << camera3buffer->data[i] << ") "
1754 << " on plane " << i;
1755 return nullptr;
1756 }
1757
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001758 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1759 if (length == -1) {
1760 LOG(HAL, Error) << "Failed to query plane length";
1761 return nullptr;
1762 }
1763
1764 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001765 planes.push_back(std::move(plane));
1766 }
1767
1768 return new FrameBuffer(std::move(planes));
1769}
1770
Jacopo Mondibb2b4002021-01-04 16:20:05 +01001771int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)
1772{
1773 const CameraMetadata &settings = descriptor->settings_;
1774 if (!settings.isValid())
1775 return 0;
1776
1777 /* Translate the Android request settings to libcamera controls. */
1778 camera_metadata_ro_entry_t entry;
1779 if (settings.getEntry(ANDROID_SCALER_CROP_REGION, &entry)) {
1780 const int32_t *data = entry.data.i32;
1781 Rectangle cropRegion{ data[0], data[1],
1782 static_cast<unsigned int>(data[2]),
1783 static_cast<unsigned int>(data[3]) };
1784 ControlList &controls = descriptor->request_->controls();
1785 controls.set(controls::ScalerCrop, cropRegion);
1786 }
1787
1788 return 0;
1789}
1790
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001791int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001792{
Jacopo Mondic5b732b2020-12-01 17:12:19 +01001793 if (!camera3Request) {
1794 LOG(HAL, Error) << "No capture request provided";
1795 return -EINVAL;
1796 }
1797
Kieran Bingham61f42962020-07-01 13:40:17 +01001798 if (!camera3Request->num_output_buffers) {
1799 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001800 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001801 }
1802
1803 /* Start the camera if that's the first request we handle. */
1804 if (!running_) {
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001805 worker_.start();
1806
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001807 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001808 if (ret) {
1809 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001810 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001811 }
1812
1813 running_ = true;
1814 }
1815
1816 /*
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001817 * Save the request descriptors for use at completion time.
1818 * The descriptor and the associated memory reserved here are freed
1819 * at request complete time.
1820 */
1821 Camera3RequestDescriptor *descriptor =
Jacopo Mondidd1cd532021-01-21 10:51:05 +01001822 new Camera3RequestDescriptor(camera_.get(), camera3Request);
Paul Eldera6de3f02021-01-21 18:59:24 +09001823 /*
1824 * \todo The Android request model is incremental, settings passed in
1825 * previous requests are to be effective until overridden explicitly in
1826 * a new request. Do we need to cache settings incrementally here, or is
1827 * it handled by the Android camera service ?
1828 */
1829 if (camera3Request->settings)
1830 lastSettings_ = camera3Request->settings;
1831 else
1832 descriptor->settings_ = lastSettings_;
Kieran Binghameac05422020-07-01 13:28:16 +01001833
Jacopo Mondibc644072021-01-28 09:58:06 +01001834 LOG(HAL, Debug) << "Queueing request " << descriptor->request_->cookie()
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001835 << " with " << descriptor->buffers_.size() << " streams";
1836 for (unsigned int i = 0; i < descriptor->buffers_.size(); ++i) {
1837 const camera3_stream_buffer_t &camera3Buffer = descriptor->buffers_[i];
1838 camera3_stream *camera3Stream = camera3Buffer.stream;
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001839 CameraStream *cameraStream = static_cast<CameraStream *>(camera3Stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001840
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001841 std::stringstream ss;
1842 ss << i << " - (" << camera3Stream->width << "x"
1843 << camera3Stream->height << ")"
1844 << "[" << utils::hex(camera3Stream->format) << "] -> "
1845 << "(" << cameraStream->configuration().size.toString() << ")["
1846 << cameraStream->configuration().pixelFormat.toString() << "]";
1847
Jacopo Mondide8304b2020-09-04 17:45:39 +02001848 /*
1849 * Inspect the camera stream type, create buffers opportunely
1850 * and add them to the Request if required.
1851 */
1852 FrameBuffer *buffer = nullptr;
1853 switch (cameraStream->type()) {
1854 case CameraStream::Type::Mapped:
1855 /*
1856 * Mapped streams don't need buffers added to the
1857 * Request.
1858 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001859 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001860 continue;
1861
Jacopo Mondide8304b2020-09-04 17:45:39 +02001862 case CameraStream::Type::Direct:
1863 /*
1864 * Create a libcamera buffer using the dmabuf
1865 * descriptors of the camera3Buffer for each stream and
1866 * associate it with the Camera3RequestDescriptor for
1867 * lifetime management only.
1868 */
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001869 buffer = createFrameBuffer(*camera3Buffer.buffer);
Kieran Bingham37c18c22020-10-21 14:54:11 +01001870 descriptor->frameBuffers_.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001871 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001872 break;
1873
1874 case CameraStream::Type::Internal:
1875 /*
1876 * Get the frame buffer from the CameraStream internal
1877 * buffer pool.
1878 *
1879 * The buffer has to be returned to the CameraStream
1880 * once it has been processed.
1881 */
1882 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001883 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001884 break;
1885 }
1886
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001887 if (!buffer) {
1888 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001889 delete descriptor;
1890 return -ENOMEM;
1891 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001892
Kieran Bingham37c18c22020-10-21 14:54:11 +01001893 descriptor->request_->addBuffer(cameraStream->stream(), buffer,
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001894 camera3Buffer.acquire_fence);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001895 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001896
Jacopo Mondibb2b4002021-01-04 16:20:05 +01001897 /*
1898 * Translate controls from Android to libcamera and queue the request
1899 * to the CameraWorker thread.
1900 */
1901 int ret = processControls(descriptor);
1902 if (ret)
1903 return ret;
1904
Kieran Bingham37c18c22020-10-21 14:54:11 +01001905 worker_.queueRequest(descriptor->request_.get());
Paul Elderc7532232020-09-23 19:05:41 +09001906
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001907 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001908}
1909
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001910void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001911{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001912 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001913 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001914 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001915 Camera3RequestDescriptor *descriptor =
1916 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001917
1918 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001919 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001920 << request->status();
1921 status = CAMERA3_BUFFER_STATUS_ERROR;
1922 }
1923
Jacopo Mondibc644072021-01-28 09:58:06 +01001924 LOG(HAL, Debug) << "Request " << request->cookie() << " completed with "
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001925 << descriptor->buffers_.size() << " streams";
Jacopo Mondibc644072021-01-28 09:58:06 +01001926
Kieran Binghamc09aee42020-07-28 14:01:19 +01001927 /*
1928 * \todo The timestamp used for the metadata is currently always taken
1929 * from the first buffer (which may be the first stream) in the Request.
1930 * It might be appropriate to return a 'correct' (as determined by
1931 * pipeline handlers) timestamp in the Request itself.
1932 */
Hirokazu Honda3a777d82020-10-28 17:57:26 +09001933 uint64_t timestamp = buffers.begin()->second->metadata().timestamp;
Hirokazu Honda82b81512021-03-25 20:13:56 +09001934 resultMetadata = getResultMetadata(*descriptor, timestamp);
Kieran Binghamc09aee42020-07-28 14:01:19 +01001935
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001936 /* Handle any JPEG compression. */
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001937 for (camera3_stream_buffer_t &buffer : descriptor->buffers_) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001938 CameraStream *cameraStream =
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001939 static_cast<CameraStream *>(buffer.stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001940
Jacopo Mondi160bb092020-10-02 20:48:35 +02001941 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001942 continue;
1943
Jacopo Mondid5473c92021-02-17 16:21:59 +01001944 FrameBuffer *src = request->findBuffer(cameraStream->stream());
1945 if (!src) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001946 LOG(HAL, Error) << "Failed to find a source stream buffer";
1947 continue;
1948 }
1949
Jacopo Mondia725baf2021-02-24 12:50:40 +01001950 int ret = cameraStream->process(*src,
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001951 *buffer.buffer,
Paul Elderabfabdd2021-01-23 13:54:28 +09001952 descriptor->settings_,
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02001953 resultMetadata.get());
1954 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001955 status = CAMERA3_BUFFER_STATUS_ERROR;
1956 continue;
1957 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02001958
1959 /*
1960 * Return the FrameBuffer to the CameraStream now that we're
1961 * done processing it.
1962 */
1963 if (cameraStream->type() == CameraStream::Type::Internal)
Jacopo Mondid5473c92021-02-17 16:21:59 +01001964 cameraStream->putBuffer(src);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001965 }
1966
1967 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001968 camera3_capture_result_t captureResult = {};
Kieran Bingham37c18c22020-10-21 14:54:11 +01001969 captureResult.frame_number = descriptor->frameNumber_;
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001970 captureResult.num_output_buffers = descriptor->buffers_.size();
1971 for (camera3_stream_buffer_t &buffer : descriptor->buffers_) {
1972 buffer.acquire_fence = -1;
1973 buffer.release_fence = -1;
1974 buffer.status = status;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001975 }
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001976 captureResult.output_buffers = descriptor->buffers_.data();
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001977
Laurent Pinchart39860092019-09-05 03:12:34 +03001978 if (status == CAMERA3_BUFFER_STATUS_OK) {
Kieran Binghame1f9fdb2020-10-21 15:31:10 +01001979 notifyShutter(descriptor->frameNumber_, timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001980
1981 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001982 captureResult.result = resultMetadata->get();
1983 }
1984
1985 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1986 /* \todo Improve error handling. In case we notify an error
1987 * because the metadata generation fails, a shutter event has
1988 * already been notified for this frame number before the error
1989 * is here signalled. Make sure the error path plays well with
1990 * the camera stack state machine.
1991 */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001992 notifyError(descriptor->frameNumber_,
1993 descriptor->buffers_[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001994 }
1995
1996 callbacks_->process_capture_result(callbacks_, &captureResult);
1997
1998 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001999}
2000
Jacopo Mondia7b92772020-05-26 15:41:41 +02002001std::string CameraDevice::logPrefix() const
2002{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02002003 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02002004}
2005
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002006void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
2007{
2008 camera3_notify_msg_t notify = {};
2009
2010 notify.type = CAMERA3_MSG_SHUTTER;
2011 notify.message.shutter.frame_number = frameNumber;
2012 notify.message.shutter.timestamp = timestamp;
2013
2014 callbacks_->notify(callbacks_, &notify);
2015}
2016
2017void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
2018{
2019 camera3_notify_msg_t notify = {};
2020
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01002021 /*
2022 * \todo Report and identify the stream number or configuration to
2023 * clarify the stream that failed.
2024 */
2025 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
2026 << toPixelFormat(stream->format).toString() << ")";
2027
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002028 notify.type = CAMERA3_MSG_ERROR;
2029 notify.message.error.error_stream = stream;
2030 notify.message.error.frame_number = frameNumber;
2031 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
2032
2033 callbacks_->notify(callbacks_, &notify);
2034}
2035
2036/*
2037 * Produce a set of fixed result metadata.
2038 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03002039std::unique_ptr<CameraMetadata>
Hirokazu Honda82b81512021-03-25 20:13:56 +09002040CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor,
2041 int64_t timestamp) const
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002042{
Hirokazu Honda82b81512021-03-25 20:13:56 +09002043 const ControlList &metadata = descriptor.request_->metadata();
2044 const CameraMetadata &settings = descriptor.settings_;
Paul Elder958c80a2021-01-26 09:47:33 +09002045 camera_metadata_ro_entry_t entry;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002046 bool found;
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002047
Jacopo Mondi48504ba2019-09-04 16:18:19 +02002048 /*
2049 * \todo Keep this in sync with the actual number of entries.
Paul Elder12646282021-01-23 13:56:01 +09002050 * Currently: 40 entries, 156 bytes
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002051 *
2052 * Reserve more space for the JPEG metadata set by the post-processor.
Paul Elderabfabdd2021-01-23 13:54:28 +09002053 * Currently:
2054 * ANDROID_JPEG_GPS_COORDINATES (double x 3) = 24 bytes
2055 * ANDROID_JPEG_GPS_PROCESSING_METHOD (byte x 32) = 32 bytes
2056 * ANDROID_JPEG_GPS_TIMESTAMP (int64) = 8 bytes
2057 * ANDROID_JPEG_SIZE (int32_t) = 4 bytes
2058 * ANDROID_JPEG_QUALITY (byte) = 1 byte
2059 * ANDROID_JPEG_ORIENTATION (int32_t) = 4 bytes
Paul Elder12646282021-01-23 13:56:01 +09002060 * ANDROID_JPEG_THUMBNAIL_QUALITY (byte) = 1 byte
2061 * ANDROID_JPEG_THUMBNAIL_SIZE (int32 x 2) = 8 bytes
2062 * Total bytes for JPEG metadata: 82
Jacopo Mondi48504ba2019-09-04 16:18:19 +02002063 */
Laurent Pinchart39860092019-09-05 03:12:34 +03002064 std::unique_ptr<CameraMetadata> resultMetadata =
Jacopo Mondif29601e2021-02-03 16:47:30 +01002065 std::make_unique<CameraMetadata>(44, 166);
Laurent Pinchart39860092019-09-05 03:12:34 +03002066 if (!resultMetadata->isValid()) {
2067 LOG(HAL, Error) << "Failed to allocate static metadata";
2068 return nullptr;
2069 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002070
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002071 /*
2072 * \todo The value of the results metadata copied from the settings
2073 * will have to be passed to the libcamera::Camera and extracted
2074 * from libcamera::Request::metadata.
2075 */
2076
Jacopo Mondi520c3662021-02-03 14:44:34 +01002077 uint8_t value = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
2078 resultMetadata->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
2079 &value, 1);
2080
2081 value = ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF;
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002082 resultMetadata->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002083
Jacopo Mondie9c28752021-02-03 14:47:45 +01002084 int32_t value32 = 0;
2085 resultMetadata->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
2086 &value32, 1);
2087
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002088 value = ANDROID_CONTROL_AE_LOCK_OFF;
2089 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002090
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002091 value = ANDROID_CONTROL_AE_MODE_ON;
2092 resultMetadata->addEntry(ANDROID_CONTROL_AE_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002093
Jacopo Mondid1508602021-01-21 18:21:28 +01002094 if (settings.getEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, &entry))
2095 /*
2096 * \todo Retrieve the AE FPS range from the libcamera metadata.
2097 * As libcamera does not support that control, as a temporary
2098 * workaround return what the framework asked.
2099 */
2100 resultMetadata->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
2101 entry.data.i32, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002102
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002103 value = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002104 found = settings.getEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &entry);
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002105 resultMetadata->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002106 found ? entry.data.u8 : &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002107
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002108 value = ANDROID_CONTROL_AE_STATE_CONVERGED;
2109 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &value, 1);
2110
2111 value = ANDROID_CONTROL_AF_MODE_OFF;
2112 resultMetadata->addEntry(ANDROID_CONTROL_AF_MODE, &value, 1);
2113
2114 value = ANDROID_CONTROL_AF_STATE_INACTIVE;
2115 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &value, 1);
2116
2117 value = ANDROID_CONTROL_AF_TRIGGER_IDLE;
2118 resultMetadata->addEntry(ANDROID_CONTROL_AF_TRIGGER, &value, 1);
2119
2120 value = ANDROID_CONTROL_AWB_MODE_AUTO;
2121 resultMetadata->addEntry(ANDROID_CONTROL_AWB_MODE, &value, 1);
2122
2123 value = ANDROID_CONTROL_AWB_LOCK_OFF;
2124 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &value, 1);
2125
2126 value = ANDROID_CONTROL_AWB_STATE_CONVERGED;
2127 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &value, 1);
2128
2129 value = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
2130 resultMetadata->addEntry(ANDROID_CONTROL_CAPTURE_INTENT, &value, 1);
2131
2132 value = ANDROID_CONTROL_EFFECT_MODE_OFF;
2133 resultMetadata->addEntry(ANDROID_CONTROL_EFFECT_MODE, &value, 1);
2134
2135 value = ANDROID_CONTROL_MODE_AUTO;
2136 resultMetadata->addEntry(ANDROID_CONTROL_MODE, &value, 1);
2137
2138 value = ANDROID_CONTROL_SCENE_MODE_DISABLED;
2139 resultMetadata->addEntry(ANDROID_CONTROL_SCENE_MODE, &value, 1);
2140
2141 value = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
2142 resultMetadata->addEntry(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &value, 1);
2143
2144 value = ANDROID_FLASH_MODE_OFF;
2145 resultMetadata->addEntry(ANDROID_FLASH_MODE, &value, 1);
2146
2147 value = ANDROID_FLASH_STATE_UNAVAILABLE;
2148 resultMetadata->addEntry(ANDROID_FLASH_STATE, &value, 1);
2149
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002150 if (settings.getEntry(ANDROID_LENS_APERTURE, &entry))
Paul Elderabfabdd2021-01-23 13:54:28 +09002151 resultMetadata->addEntry(ANDROID_LENS_APERTURE, entry.data.f, 1);
2152
2153 float focal_length = 1.0;
2154 resultMetadata->addEntry(ANDROID_LENS_FOCAL_LENGTH, &focal_length, 1);
2155
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002156 value = ANDROID_LENS_STATE_STATIONARY;
2157 resultMetadata->addEntry(ANDROID_LENS_STATE, &value, 1);
2158
2159 value = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
2160 resultMetadata->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
2161 &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002162
Jacopo Mondi5360d802021-02-03 16:43:22 +01002163 value32 = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
2164 resultMetadata->addEntry(ANDROID_SENSOR_TEST_PATTERN_MODE,
2165 &value32, 1);
2166
Laurent Pinchart39860092019-09-05 03:12:34 +03002167 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002168
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002169 value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
2170 resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
2171 &value, 1);
2172
2173 value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
2174 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
2175 &value, 1);
2176
Jacopo Mondif29601e2021-02-03 16:47:30 +01002177 value = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
2178 resultMetadata->addEntry(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
2179 &value, 1);
2180
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002181 value = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
2182 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
2183 &value, 1);
2184
2185 value = ANDROID_NOISE_REDUCTION_MODE_OFF;
2186 resultMetadata->addEntry(ANDROID_NOISE_REDUCTION_MODE, &value, 1);
2187
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002188 /* 33.3 msec */
2189 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03002190 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
2191 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002192
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002193 /* Add metadata tags reported by libcamera. */
2194 if (metadata.contains(controls::draft::PipelineDepth)) {
2195 uint8_t pipeline_depth =
2196 metadata.get<int32_t>(controls::draft::PipelineDepth);
2197 resultMetadata->addEntry(ANDROID_REQUEST_PIPELINE_DEPTH,
2198 &pipeline_depth, 1);
2199 }
2200
Jacopo Mondic9705a52021-01-05 19:30:48 +01002201 if (metadata.contains(controls::ExposureTime)) {
Paul Elder78f49d52021-01-28 17:45:44 +09002202 int64_t exposure = metadata.get(controls::ExposureTime) * 1000ULL;
Jacopo Mondic9705a52021-01-05 19:30:48 +01002203 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
2204 &exposure, 1);
2205 }
2206
Jacopo Mondibb2b4002021-01-04 16:20:05 +01002207 if (metadata.contains(controls::ScalerCrop)) {
2208 Rectangle crop = metadata.get(controls::ScalerCrop);
2209 int32_t cropRect[] = {
2210 crop.x, crop.y, static_cast<int32_t>(crop.width),
2211 static_cast<int32_t>(crop.height),
2212 };
2213 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, cropRect, 4);
2214 }
2215
Laurent Pinchart39860092019-09-05 03:12:34 +03002216 /*
2217 * Return the result metadata pack even is not valid: get() will return
2218 * nullptr.
2219 */
2220 if (!resultMetadata->isValid()) {
2221 LOG(HAL, Error) << "Failed to construct result metadata";
2222 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002223
2224 return resultMetadata;
2225}