blob: 8fdcb85a2f66948d5d5deff48caa7b45228be653 [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
341CameraDevice::~CameraDevice()
342{
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200343 for (auto &it : requestTemplates_)
344 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200345}
346
Hirokazu Honda212f4102021-03-24 16:07:50 +0900347std::unique_ptr<CameraDevice> CameraDevice::create(unsigned int id,
Hirokazu Honda9538ce42021-03-24 16:07:53 +0900348 std::shared_ptr<Camera> cam)
Umang Jainf8e28132020-08-21 14:46:08 +0000349{
Hirokazu Honda9538ce42021-03-24 16:07:53 +0900350 return std::unique_ptr<CameraDevice>(
351 new CameraDevice(id, std::move(cam)));
Umang Jainf8e28132020-08-21 14:46:08 +0000352}
353
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200354/*
355 * Initialize the camera static information.
356 * This method is called before the camera device is opened.
357 */
358int CameraDevice::initialize()
359{
360 /* Initialize orientation and facing side of the camera. */
361 const ControlList &properties = camera_->properties();
362
363 if (properties.contains(properties::Location)) {
364 int32_t location = properties.get(properties::Location);
365 switch (location) {
366 case properties::CameraLocationFront:
367 facing_ = CAMERA_FACING_FRONT;
368 break;
369 case properties::CameraLocationBack:
370 facing_ = CAMERA_FACING_BACK;
371 break;
372 case properties::CameraLocationExternal:
Jacopo Mondi5154e142021-03-10 14:00:50 +0100373 facing_ = CAMERA_FACING_EXTERNAL;
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200374 break;
375 }
Jacopo Mondi5154e142021-03-10 14:00:50 +0100376 } else {
377 /*
378 * \todo Retrieve the camera location from configuration file
379 * if not available from the library.
380 */
381 facing_ = CAMERA_FACING_FRONT;
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200382 }
383
384 /*
Umang Jaine9176552020-09-09 16:17:54 +0530385 * The Android orientation metadata specifies its rotation correction
386 * value in clockwise direction whereas libcamera specifies the
387 * rotation property in anticlockwise direction. Read the libcamera's
388 * rotation property (anticlockwise) and compute the corresponding
389 * value for clockwise direction as required by the Android orientation
390 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200391 */
Umang Jaine9176552020-09-09 16:17:54 +0530392 if (properties.contains(properties::Rotation)) {
393 int rotation = properties.get(properties::Rotation);
394 orientation_ = (360 - rotation) % 360;
395 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200396
Jacopo Mondi117588b2020-05-23 18:53:54 +0200397 int ret = camera_->acquire();
398 if (ret) {
399 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
400 return ret;
401 }
402
403 ret = initializeStreamConfigurations();
404 camera_->release();
405 return ret;
406}
407
Jacopo Mondibfee6312020-09-01 17:42:13 +0200408std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
409 const PixelFormat &pixelFormat,
410 const std::vector<Size> &resolutions)
411{
412 std::vector<Size> supportedResolutions;
413
414 StreamConfiguration &cfg = cameraConfig->at(0);
415 for (const Size &res : resolutions) {
416 cfg.pixelFormat = pixelFormat;
417 cfg.size = res;
418
419 CameraConfiguration::Status status = cameraConfig->validate();
420 if (status != CameraConfiguration::Valid) {
421 LOG(HAL, Debug) << cfg.toString() << " not supported";
422 continue;
423 }
424
425 LOG(HAL, Debug) << cfg.toString() << " supported";
426
427 supportedResolutions.push_back(res);
428 }
429
430 return supportedResolutions;
431}
432
Jacopo Mondi49610332020-09-01 18:11:34 +0200433std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
434{
435 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200436 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200437 StreamConfiguration &cfg = cameraConfig->at(0);
438 const StreamFormats &formats = cfg.formats();
439 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
440
441 return supportedResolutions;
442}
443
Jacopo Mondi117588b2020-05-23 18:53:54 +0200444/*
445 * Initialize the format conversion map to translate from Android format
446 * identifier to libcamera pixel formats and fill in the list of supported
447 * stream configurations to be reported to the Android camera framework through
448 * the static stream configuration metadata.
449 */
450int CameraDevice::initializeStreamConfigurations()
451{
452 /*
453 * Get the maximum output resolutions
454 * \todo Get this from the camera properties once defined
455 */
456 std::unique_ptr<CameraConfiguration> cameraConfig =
457 camera_->generateConfiguration({ StillCapture });
458 if (!cameraConfig) {
459 LOG(HAL, Error) << "Failed to get maximum resolution";
460 return -EINVAL;
461 }
462 StreamConfiguration &cfg = cameraConfig->at(0);
463
464 /*
465 * \todo JPEG - Adjust the maximum available resolution by taking the
466 * JPEG encoder requirements into account (alignment and aspect ratio).
467 */
468 const Size maxRes = cfg.size;
469 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
470
471 /*
472 * Build the list of supported image resolutions.
473 *
474 * The resolutions listed in camera3Resolution are mandatory to be
475 * supported, up to the camera maximum resolution.
476 *
477 * Augment the list by adding resolutions calculated from the camera
478 * maximum one.
479 */
480 std::vector<Size> cameraResolutions;
481 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
482 std::back_inserter(cameraResolutions),
483 [&](const Size &res) { return res < maxRes; });
484
485 /*
486 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
487 * resolution.
488 */
489 for (unsigned int divider = 2;; divider <<= 1) {
490 Size derivedSize{
491 maxRes.width / divider,
492 maxRes.height / divider,
493 };
494
495 if (derivedSize.width < 320 ||
496 derivedSize.height < 240)
497 break;
498
499 cameraResolutions.push_back(derivedSize);
500 }
501 cameraResolutions.push_back(maxRes);
502
503 /* Remove duplicated entries from the list of supported resolutions. */
504 std::sort(cameraResolutions.begin(), cameraResolutions.end());
505 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
506 cameraResolutions.erase(last, cameraResolutions.end());
507
508 /*
509 * Build the list of supported camera formats.
510 *
511 * To each Android format a list of compatible libcamera formats is
512 * associated. The first libcamera format that tests successful is added
513 * to the format translation map used when configuring the streams.
514 * It is then tested against the list of supported camera resolutions to
515 * build the stream configuration map reported through the camera static
516 * metadata.
517 */
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100518 Size maxJpegSize;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200519 for (const auto &format : camera3FormatsMap) {
520 int androidFormat = format.first;
521 const Camera3Format &camera3Format = format.second;
522 const std::vector<PixelFormat> &libcameraFormats =
523 camera3Format.libcameraFormats;
524
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200525 LOG(HAL, Debug) << "Trying to map Android format "
526 << camera3Format.name;
527
Jacopo Mondi117588b2020-05-23 18:53:54 +0200528 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200529 * JPEG is always supported, either produced directly by the
530 * camera, or encoded in the HAL.
531 */
532 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
533 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200534 LOG(HAL, Debug) << "Mapped Android format "
535 << camera3Format.name << " to "
536 << formats::MJPEG.toString()
537 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200538 continue;
539 }
540
541 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200542 * Test the libcamera formats that can produce images
543 * compatible with the format defined by Android.
544 */
545 PixelFormat mappedFormat;
546 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200547
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200548 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
549
Jacopo Mondi117588b2020-05-23 18:53:54 +0200550 /*
551 * The stream configuration size can be adjusted,
552 * not the pixel format.
553 *
554 * \todo This could be simplified once all pipeline
555 * handlers will report the StreamFormats list of
556 * supported formats.
557 */
558 cfg.pixelFormat = pixelFormat;
559
560 CameraConfiguration::Status status = cameraConfig->validate();
561 if (status != CameraConfiguration::Invalid &&
562 cfg.pixelFormat == pixelFormat) {
563 mappedFormat = pixelFormat;
564 break;
565 }
566 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200567
568 if (!mappedFormat.isValid()) {
569 /* If the format is not mandatory, skip it. */
570 if (!camera3Format.mandatory)
571 continue;
572
573 LOG(HAL, Error)
574 << "Failed to map mandatory Android format "
575 << camera3Format.name << " ("
576 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200577 return -EINVAL;
578 }
579
580 /*
581 * Record the mapping and then proceed to generate the
582 * stream configurations map, by testing the image resolutions.
583 */
584 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200585 LOG(HAL, Debug) << "Mapped Android format "
586 << camera3Format.name << " to "
587 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200588
Jacopo Mondi49610332020-09-01 18:11:34 +0200589 std::vector<Size> resolutions;
590 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
591 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
592 resolutions = getRawResolutions(mappedFormat);
593 else
594 resolutions = getYUVResolutions(cameraConfig.get(),
595 mappedFormat,
596 cameraResolutions);
597
Jacopo Mondibfee6312020-09-01 17:42:13 +0200598 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200599 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200600
601 /*
602 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
603 * from which JPEG is produced, add an entry for
604 * the JPEG stream.
605 *
606 * \todo Wire the JPEG encoder to query the supported
607 * sizes provided a list of formats it can encode.
608 *
609 * \todo Support JPEG streams produced by the Camera
610 * natively.
611 */
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100612 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
Jacopo Mondi843565c2020-09-01 15:34:13 +0200613 streamConfigurations_.push_back(
614 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100615 maxJpegSize = std::max(maxJpegSize, res);
616 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200617 }
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100618
619 /*
620 * \todo Calculate the maximum JPEG buffer size by asking the
621 * encoder giving the maximum frame size required.
622 */
623 maxJpegBufferSize_ = maxJpegSize.width * maxJpegSize.height * 1.5;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200624 }
625
626 LOG(HAL, Debug) << "Collected stream configuration map: ";
627 for (const auto &entry : streamConfigurations_)
628 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200629 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200630
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200631 return 0;
632}
633
634/*
635 * Open a camera device. The static information on the camera shall have been
636 * initialized with a call to CameraDevice::initialize().
637 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200638int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200639{
640 int ret = camera_->acquire();
641 if (ret) {
642 LOG(HAL, Error) << "Failed to acquire the camera";
643 return ret;
644 }
645
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200646 /* Initialize the hw_device_t in the instance camera3_module_t. */
647 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
648 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
649 camera3Device_.common.module = (hw_module_t *)hardwareModule;
650 camera3Device_.common.close = hal_dev_close;
651
652 /*
653 * The camera device operations. These actually implement
654 * the Android Camera HALv3 interface.
655 */
656 camera3Device_.ops = &hal_dev_ops;
657 camera3Device_.priv = this;
658
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200659 return 0;
660}
661
662void CameraDevice::close()
663{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200664 streams_.clear();
665
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200666 worker_.stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200667 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200668 camera_->release();
669
670 running_ = false;
671}
672
673void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
674{
675 callbacks_ = callbacks;
676}
677
Jacopo Mondia80d3812020-05-26 12:31:35 +0200678std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
679{
680 /*
681 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100682 * Currently: 54 entries, 874 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200683 */
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100684 uint32_t numEntries = 54;
685 uint32_t byteSize = 874;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200686
687 /*
688 * Calculate space occupation in bytes for dynamically built metadata
689 * entries.
690 *
Jacopo Mondi00982fb2021-02-04 16:57:55 +0100691 * Each stream configuration entry requires 48 bytes:
Jacopo Mondia80d3812020-05-26 12:31:35 +0200692 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200693 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
694 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200695 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200696
Jacopo Mondi9e807052021-02-04 15:32:00 +0100697 /*
698 * 2 32bits integers for each HAL_PIXEL_FORMAT_BLOB for thumbnail sizes
699 * 2 32bits integers for the (0, 0) thumbnail size
700 *
701 * This is a worst case estimates as different configurations with the
702 * same aspect ratio will generate the same size.
703 */
704 for (const auto &entry : streamConfigurations_) {
705 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
706 continue;
707
708 byteSize += 8;
709 }
710 byteSize += 8;
711
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300712 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200713}
714
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200715/*
716 * Return static information for the camera.
717 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200718const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200719{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200720 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300721 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200722
723 /*
724 * The here reported metadata are enough to implement a basic capture
725 * example application, but a real camera implementation will require
726 * more.
727 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200728 uint32_t numEntries;
729 uint32_t byteSize;
730 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
Hirokazu Hondadca709c2021-03-24 16:07:56 +0900731 staticMetadata_ = std::make_unique<CameraMetadata>(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300732 if (!staticMetadata_->isValid()) {
733 LOG(HAL, Error) << "Failed to allocate static metadata";
Hirokazu Hondadca709c2021-03-24 16:07:56 +0900734 staticMetadata_.reset();
Laurent Pinchart39860092019-09-05 03:12:34 +0300735 return nullptr;
736 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200737
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200738 const ControlInfoMap &controlsInfo = camera_->controls();
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100739 const ControlList &properties = camera_->properties();
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200740
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200741 /* Color correction static metadata. */
Jacopo Mondi63336862020-10-08 16:18:26 +0200742 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100743 std::vector<uint8_t> data;
744 data.reserve(3);
Jacopo Mondi63336862020-10-08 16:18:26 +0200745 const auto &infoMap = controlsInfo.find(&controls::draft::ColorCorrectionAberrationMode);
746 if (infoMap != controlsInfo.end()) {
747 for (const auto &value : infoMap->second.values())
748 data.push_back(value.get<int32_t>());
749 } else {
750 data.push_back(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
751 }
752 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
753 data.data(), data.size());
754 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200755
756 /* Control static metadata. */
757 std::vector<uint8_t> aeAvailableAntiBandingModes = {
758 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
759 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
760 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
761 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
762 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300763 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
764 aeAvailableAntiBandingModes.data(),
765 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200766
767 std::vector<uint8_t> aeAvailableModes = {
768 ANDROID_CONTROL_AE_MODE_ON,
769 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300770 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
771 aeAvailableModes.data(),
772 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200773
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100774 int64_t minFrameDurationNsec = -1;
775 int64_t maxFrameDurationNsec = -1;
776 const auto frameDurationsInfo = controlsInfo.find(&controls::FrameDurations);
777 if (frameDurationsInfo != controlsInfo.end()) {
778 minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000;
779 maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000;
780
781 /*
782 * Adjust the minimum frame duration to comply with Android
783 * requirements. The camera service mandates all preview/record
784 * streams to have a minimum frame duration < 33,366 milliseconds
785 * (see MAX_PREVIEW_RECORD_DURATION_NS in the camera service
786 * implementation).
787 *
788 * If we're close enough (+ 500 useconds) to that value, round
789 * the minimum frame duration of the camera to an accepted
790 * value.
791 */
792 static constexpr int64_t MAX_PREVIEW_RECORD_DURATION_NS = 1e9 / 29.97;
793 if (minFrameDurationNsec > MAX_PREVIEW_RECORD_DURATION_NS &&
794 minFrameDurationNsec < MAX_PREVIEW_RECORD_DURATION_NS + 500000)
795 minFrameDurationNsec = MAX_PREVIEW_RECORD_DURATION_NS - 1000;
796
797 /*
798 * The AE routine frame rate limits are computed using the frame
799 * duration limits, as libcamera clips the AE routine to the
800 * frame durations.
801 */
802 int32_t maxFps = std::round(1e9 / minFrameDurationNsec);
803 int32_t minFps = std::round(1e9 / maxFrameDurationNsec);
804 minFps = std::max(1, minFps);
805
806 /*
807 * Register to the camera service {min, max} and {max, max}
808 * intervals as requested by the metadata documentation.
809 */
810 int32_t availableAeFpsTarget[] = {
811 minFps, maxFps, maxFps, maxFps
812 };
813 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
814 availableAeFpsTarget, 4);
815 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200816
817 std::vector<int32_t> aeCompensationRange = {
818 0, 0,
819 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300820 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
821 aeCompensationRange.data(),
822 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200823
824 const camera_metadata_rational_t aeCompensationStep[] = {
825 { 0, 1 }
826 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300827 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
828 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200829
830 std::vector<uint8_t> availableAfModes = {
831 ANDROID_CONTROL_AF_MODE_OFF,
832 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300833 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
834 availableAfModes.data(),
835 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200836
837 std::vector<uint8_t> availableEffects = {
838 ANDROID_CONTROL_EFFECT_MODE_OFF,
839 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300840 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
841 availableEffects.data(),
842 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200843
844 std::vector<uint8_t> availableSceneModes = {
845 ANDROID_CONTROL_SCENE_MODE_DISABLED,
846 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300847 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
848 availableSceneModes.data(),
849 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200850
851 std::vector<uint8_t> availableStabilizationModes = {
852 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
853 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300854 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
855 availableStabilizationModes.data(),
856 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200857
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100858 /*
859 * \todo Inspect the Camera capabilities to report the available
860 * AWB modes. Default to AUTO as CTS tests require it.
861 */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200862 std::vector<uint8_t> availableAwbModes = {
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100863 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200864 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300865 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
866 availableAwbModes.data(),
867 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200868
869 std::vector<int32_t> availableMaxRegions = {
870 0, 0, 0,
871 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300872 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
873 availableMaxRegions.data(),
874 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200875
876 std::vector<uint8_t> sceneModesOverride = {
877 ANDROID_CONTROL_AE_MODE_ON,
878 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondif266c0e2021-02-03 16:34:40 +0100879 ANDROID_CONTROL_AF_MODE_OFF,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200880 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300881 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
882 sceneModesOverride.data(),
883 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200884
885 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300886 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
887 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200888
889 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300890 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
891 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200892
893 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300894 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
895 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200896
897 /* JPEG static metadata. */
Jacopo Mondi9e807052021-02-04 15:32:00 +0100898
899 /*
900 * Create the list of supported thumbnail sizes by inspecting the
901 * available JPEG resolutions collected in streamConfigurations_ and
902 * generate one entry for each aspect ratio.
903 *
904 * The JPEG thumbnailer can freely scale, so pick an arbitrary
905 * (160, 160) size as the bounding rectangle, which is then cropped to
906 * the different supported aspect ratios.
907 */
908 constexpr Size maxJpegThumbnail(160, 160);
909 std::vector<Size> thumbnailSizes;
910 thumbnailSizes.push_back({ 0, 0 });
911 for (const auto &entry : streamConfigurations_) {
912 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
913 continue;
914
915 Size thumbnailSize = maxJpegThumbnail
916 .boundedToAspectRatio({ entry.resolution.width,
917 entry.resolution.height });
918 thumbnailSizes.push_back(thumbnailSize);
919 }
920
921 std::sort(thumbnailSizes.begin(), thumbnailSizes.end());
922 auto last = std::unique(thumbnailSizes.begin(), thumbnailSizes.end());
923 thumbnailSizes.erase(last, thumbnailSizes.end());
924
925 /* Transform sizes in to a list of integers that can be consumed. */
926 std::vector<int32_t> thumbnailEntries;
927 thumbnailEntries.reserve(thumbnailSizes.size() * 2);
928 for (const auto &size : thumbnailSizes) {
929 thumbnailEntries.push_back(size.width);
930 thumbnailEntries.push_back(size.height);
931 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300932 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Jacopo Mondi9e807052021-02-04 15:32:00 +0100933 thumbnailEntries.data(), thumbnailEntries.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200934
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100935 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
936
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200937 /* Sensor static metadata. */
Jacopo Mondicda41ff2020-12-30 17:18:51 +0100938 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100939 const Size &size =
Jacopo Mondi0ed05322020-12-23 18:34:34 +0100940 properties.get(properties::PixelArraySize);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100941 std::vector<int32_t> data{
942 static_cast<int32_t>(size.width),
943 static_cast<int32_t>(size.height),
944 };
945 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
946 data.data(), data.size());
947 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200948
Jacopo Mondicda41ff2020-12-30 17:18:51 +0100949 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100950 const Span<const Rectangle> &rects =
Jacopo Mondi0ed05322020-12-23 18:34:34 +0100951 properties.get(properties::PixelArrayActiveAreas);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100952 std::vector<int32_t> data{
953 static_cast<int32_t>(rects[0].x),
954 static_cast<int32_t>(rects[0].y),
955 static_cast<int32_t>(rects[0].width),
956 static_cast<int32_t>(rects[0].height),
957 };
958 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
959 data.data(), data.size());
960 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200961
962 int32_t sensitivityRange[] = {
963 32, 2400,
964 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300965 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
966 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200967
Jacopo Mondicb35ed22020-12-18 16:28:43 +0100968 /* Report the color filter arrangement if the camera reports it. */
969 if (properties.contains(properties::draft::ColorFilterArrangement)) {
970 uint8_t filterArr = properties.get(properties::draft::ColorFilterArrangement);
971 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
972 &filterArr, 1);
973 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200974
Jacopo Mondi753d7532021-01-02 12:34:06 +0100975 const auto &exposureInfo = controlsInfo.find(&controls::ExposureTime);
976 if (exposureInfo != controlsInfo.end()) {
977 int64_t exposureTimeRange[2] = {
978 exposureInfo->second.min().get<int32_t>() * 1000LL,
979 exposureInfo->second.max().get<int32_t>() * 1000LL,
980 };
981 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
982 &exposureTimeRange, 2);
983 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200984
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200985 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200986
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200987 std::vector<int32_t> testPatterModes = {
988 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
989 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300990 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
991 testPatterModes.data(),
992 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200993
994 std::vector<float> physicalSize = {
995 2592, 1944,
996 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300997 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
998 physicalSize.data(),
999 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001000
1001 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +03001002 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1003 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001004
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001005 if (maxFrameDurationNsec > 0)
1006 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
1007 &maxFrameDurationNsec, 1);
1008
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001009 /* Statistics static metadata. */
1010 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001011 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1012 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001013
1014 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001015 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1016 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001017
Jacopo Mondi2c618502020-10-08 16:47:36 +02001018 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001019 std::vector<uint8_t> data;
1020 data.reserve(2);
Jacopo Mondi2c618502020-10-08 16:47:36 +02001021 const auto &infoMap = controlsInfo.find(&controls::draft::LensShadingMapMode);
1022 if (infoMap != controlsInfo.end()) {
1023 for (const auto &value : infoMap->second.values())
1024 data.push_back(value.get<int32_t>());
1025 } else {
1026 data.push_back(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
1027 }
1028 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
1029 data.data(), data.size());
1030 }
1031
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001032 /* Sync static metadata. */
1033 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +03001034 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001035
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001036 /* Flash static metadata. */
1037 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001038 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
1039 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001040
1041 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001042 std::vector<float> lensApertures = {
1043 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001044 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001045 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
1046 lensApertures.data(),
1047 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001048
Jacopo Mondi64f4f662020-05-25 16:08:22 +02001049 uint8_t lensFacing;
1050 switch (facing_) {
1051 default:
1052 case CAMERA_FACING_FRONT:
1053 lensFacing = ANDROID_LENS_FACING_FRONT;
1054 break;
1055 case CAMERA_FACING_BACK:
1056 lensFacing = ANDROID_LENS_FACING_BACK;
1057 break;
1058 case CAMERA_FACING_EXTERNAL:
1059 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
1060 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +01001061 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001062 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001063
1064 std::vector<float> lensFocalLenghts = {
1065 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001066 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001067 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1068 lensFocalLenghts.data(),
1069 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001070
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001071 std::vector<uint8_t> opticalStabilizations = {
1072 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
1073 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001074 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1075 opticalStabilizations.data(),
1076 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001077
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001078 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001079 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1080 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001081
1082 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001083 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1084 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001085
1086 /* Noise reduction modes. */
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001087 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001088 std::vector<uint8_t> data;
1089 data.reserve(5);
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001090 const auto &infoMap = controlsInfo.find(&controls::draft::NoiseReductionMode);
1091 if (infoMap != controlsInfo.end()) {
1092 for (const auto &value : infoMap->second.values())
1093 data.push_back(value.get<int32_t>());
1094 } else {
1095 data.push_back(ANDROID_NOISE_REDUCTION_MODE_OFF);
1096 }
1097 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
1098 data.data(), data.size());
1099 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001100
1101 /* Scaler static metadata. */
Jacopo Mondi31a1a622021-01-03 19:57:36 +01001102 {
1103 /*
1104 * \todo The digital zoom factor is a property that depends
1105 * on the desired output configuration and the sensor frame size
1106 * input to the ISP. This information is not available to the
1107 * Android HAL, not at initialization time at least.
1108 *
1109 * As a workaround rely on pipeline handlers initializing the
1110 * ScalerCrop control with the camera default configuration and
1111 * use the maximum and minimum crop rectangles to calculate the
1112 * digital zoom factor.
1113 */
1114 const auto info = controlsInfo.find(&controls::ScalerCrop);
1115 Rectangle min = info->second.min().get<Rectangle>();
1116 Rectangle max = info->second.max().get<Rectangle>();
1117 float maxZoom = std::min(1.0f * max.width / min.width,
1118 1.0f * max.height / min.height);
1119 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1120 &maxZoom, 1);
1121 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001122
Jacopo Mondibde7b982020-05-25 17:18:28 +02001123 std::vector<uint32_t> availableStreamConfigurations;
1124 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
1125 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +02001126 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +02001127 availableStreamConfigurations.push_back(entry.resolution.width);
1128 availableStreamConfigurations.push_back(entry.resolution.height);
1129 availableStreamConfigurations.push_back(
1130 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
1131 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001132 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1133 availableStreamConfigurations.data(),
1134 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001135
1136 std::vector<int64_t> availableStallDurations = {
1137 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
1138 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001139 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1140 availableStallDurations.data(),
1141 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001142
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001143 /* Use the minimum frame duration for all the YUV/RGB formats. */
1144 if (minFrameDurationNsec > 0) {
1145 std::vector<int64_t> minFrameDurations;
1146 minFrameDurations.reserve(streamConfigurations_.size() * 4);
1147 for (const auto &entry : streamConfigurations_) {
1148 minFrameDurations.push_back(entry.androidFormat);
1149 minFrameDurations.push_back(entry.resolution.width);
1150 minFrameDurations.push_back(entry.resolution.height);
1151 minFrameDurations.push_back(minFrameDurationNsec);
1152 }
1153 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1154 minFrameDurations.data(),
1155 minFrameDurations.size());
Jacopo Mondibde7b982020-05-25 17:18:28 +02001156 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001157
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001158 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001159 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001160
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001161 /* Info static metadata. */
1162 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001163 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
1164 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001165
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001166 /* Request static metadata. */
1167 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001168 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1169 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001170
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +02001171 {
1172 /* Default the value to 2 if not reported by the camera. */
1173 uint8_t maxPipelineDepth = 2;
1174 const auto &infoMap = controlsInfo.find(&controls::draft::PipelineDepth);
1175 if (infoMap != controlsInfo.end())
1176 maxPipelineDepth = infoMap->second.max().get<int32_t>();
1177 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
1178 &maxPipelineDepth, 1);
1179 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001180
Niklas Söderlunda2a6f952020-07-21 00:16:02 +02001181 /* LIMITED does not support reprocessing. */
1182 uint32_t maxNumInputStreams = 0;
1183 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1184 &maxNumInputStreams, 1);
1185
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001186 std::vector<uint8_t> availableCapabilities = {
1187 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
1188 };
Niklas Söderlund7876d632020-07-21 00:16:24 +02001189
1190 /* Report if camera supports RAW. */
Jacopo Mondieec6c542020-12-09 18:16:11 +01001191 bool rawStreamAvailable = false;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001192 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +02001193 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +02001194 if (cameraConfig && !cameraConfig->empty()) {
1195 const PixelFormatInfo &info =
1196 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
Niklas Söderlund35de31e2020-12-31 00:11:59 +01001197 /* Only advertise RAW support if RAW16 is possible. */
1198 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW &&
1199 info.bitsPerPixel == 16) {
Jacopo Mondieec6c542020-12-09 18:16:11 +01001200 rawStreamAvailable = true;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001201 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
Jacopo Mondieec6c542020-12-09 18:16:11 +01001202 }
Niklas Söderlund7876d632020-07-21 00:16:24 +02001203 }
1204
Jacopo Mondieec6c542020-12-09 18:16:11 +01001205 /* Number of { RAW, YUV, JPEG } supported output streams */
1206 int32_t numOutStreams[] = { rawStreamAvailable, 2, 1 };
1207 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
1208 &numOutStreams, 3);
1209
Laurent Pinchart39860092019-09-05 03:12:34 +03001210 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1211 availableCapabilities.data(),
1212 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001213
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001214 std::vector<int32_t> availableCharacteristicsKeys = {
1215 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
1216 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
1217 ANDROID_CONTROL_AE_AVAILABLE_MODES,
1218 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1219 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
1220 ANDROID_CONTROL_AE_COMPENSATION_STEP,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001221 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001222 ANDROID_CONTROL_AF_AVAILABLE_MODES,
1223 ANDROID_CONTROL_AVAILABLE_EFFECTS,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001224 ANDROID_CONTROL_AVAILABLE_MODES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001225 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
1226 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
1227 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001228 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001229 ANDROID_CONTROL_MAX_REGIONS,
1230 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001231 ANDROID_FLASH_INFO_AVAILABLE,
1232 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001233 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001234 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001235 ANDROID_LENS_FACING,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001236 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001237 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1238 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1239 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1240 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1241 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001242 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1243 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1244 ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001245 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1246 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001247 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1248 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1249 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1250 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1251 ANDROID_SCALER_CROPPING_TYPE,
1252 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
1253 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
1254 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
1255 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001256 ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001257 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1258 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
1259 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
1260 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1261 ANDROID_SENSOR_ORIENTATION,
1262 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1263 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1264 ANDROID_SYNC_MAX_LATENCY,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001265 };
1266 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
1267 availableCharacteristicsKeys.data(),
1268 availableCharacteristicsKeys.size());
1269
1270 std::vector<int32_t> availableRequestKeys = {
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001271 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1272 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001273 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001274 ANDROID_CONTROL_AE_LOCK,
1275 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001276 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001277 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001278 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001279 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001280 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001281 ANDROID_CONTROL_AWB_MODE,
1282 ANDROID_CONTROL_CAPTURE_INTENT,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001283 ANDROID_CONTROL_EFFECT_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001284 ANDROID_CONTROL_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001285 ANDROID_CONTROL_SCENE_MODE,
1286 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001287 ANDROID_FLASH_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001288 ANDROID_JPEG_ORIENTATION,
1289 ANDROID_JPEG_QUALITY,
1290 ANDROID_JPEG_THUMBNAIL_QUALITY,
1291 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001292 ANDROID_LENS_APERTURE,
1293 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001294 ANDROID_NOISE_REDUCTION_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001295 ANDROID_SCALER_CROP_REGION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001296 ANDROID_STATISTICS_FACE_DETECT_MODE
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001297 };
1298 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
1299 availableRequestKeys.data(),
1300 availableRequestKeys.size());
1301
1302 std::vector<int32_t> availableResultKeys = {
Jacopo Mondi520c3662021-02-03 14:44:34 +01001303 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001304 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondie9c28752021-02-03 14:47:45 +01001305 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001306 ANDROID_CONTROL_AE_LOCK,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001307 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001308 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1309 ANDROID_CONTROL_AE_STATE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001310 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001311 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001312 ANDROID_CONTROL_AF_STATE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001313 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001314 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001315 ANDROID_CONTROL_AWB_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001316 ANDROID_CONTROL_AWB_STATE,
1317 ANDROID_CONTROL_CAPTURE_INTENT,
1318 ANDROID_CONTROL_EFFECT_MODE,
1319 ANDROID_CONTROL_MODE,
1320 ANDROID_CONTROL_SCENE_MODE,
1321 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
1322 ANDROID_FLASH_MODE,
1323 ANDROID_FLASH_STATE,
Paul Elderabfabdd2021-01-23 13:54:28 +09001324 ANDROID_JPEG_GPS_COORDINATES,
1325 ANDROID_JPEG_GPS_PROCESSING_METHOD,
1326 ANDROID_JPEG_GPS_TIMESTAMP,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001327 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001328 ANDROID_JPEG_QUALITY,
1329 ANDROID_JPEG_SIZE,
Paul Elder12646282021-01-23 13:56:01 +09001330 ANDROID_JPEG_THUMBNAIL_QUALITY,
1331 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001332 ANDROID_LENS_APERTURE,
1333 ANDROID_LENS_FOCAL_LENGTH,
1334 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1335 ANDROID_LENS_STATE,
1336 ANDROID_NOISE_REDUCTION_MODE,
1337 ANDROID_REQUEST_PIPELINE_DEPTH,
1338 ANDROID_SCALER_CROP_REGION,
1339 ANDROID_SENSOR_EXPOSURE_TIME,
1340 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
Jacopo Mondi5360d802021-02-03 16:43:22 +01001341 ANDROID_SENSOR_TEST_PATTERN_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001342 ANDROID_SENSOR_TIMESTAMP,
1343 ANDROID_STATISTICS_FACE_DETECT_MODE,
1344 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
Jacopo Mondif29601e2021-02-03 16:47:30 +01001345 ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001346 ANDROID_STATISTICS_SCENE_FLICKER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001347 };
1348 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1349 availableResultKeys.data(),
1350 availableResultKeys.size());
1351
Laurent Pinchart39860092019-09-05 03:12:34 +03001352 if (!staticMetadata_->isValid()) {
1353 LOG(HAL, Error) << "Failed to construct static metadata";
Hirokazu Hondadca709c2021-03-24 16:07:56 +09001354 staticMetadata_.reset();
Laurent Pinchart39860092019-09-05 03:12:34 +03001355 return nullptr;
1356 }
1357
1358 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001359}
1360
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001361CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001362{
Jacopo Mondi63703472019-09-04 16:18:22 +02001363 /*
1364 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001365 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001366 */
Jacopo Mondi9690d082021-02-03 16:37:20 +01001367 CameraMetadata *requestTemplate = new CameraMetadata(21, 36);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001368 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001369 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001370 return nullptr;
1371 }
1372
Jacopo Mondif1796162021-03-08 17:03:14 +01001373 /* Get the FPS range registered in the static metadata. */
1374 camera_metadata_ro_entry_t entry;
1375 bool found = staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1376 &entry);
1377 if (!found) {
1378 LOG(HAL, Error) << "Cannot create capture template without FPS range";
1379 return nullptr;
1380 }
1381
1382 /*
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001383 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
Jacopo Mondif1796162021-03-08 17:03:14 +01001384 * has been assembled as {{min, max} {max, max}}.
1385 */
1386 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1387 entry.data.i32, 2);
1388
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001389 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001390 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1391 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001392
1393 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001394 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1395 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001396
1397 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001398 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1399 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001400
1401 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001402 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1403 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001404
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001405 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1406 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1407 &aeAntibandingMode, 1);
1408
Jacopo Mondi9690d082021-02-03 16:37:20 +01001409 uint8_t afMode = ANDROID_CONTROL_AF_MODE_OFF;
1410 requestTemplate->addEntry(ANDROID_CONTROL_AF_MODE, &afMode, 1);
1411
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001412 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001413 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1414 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001415
1416 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001417 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1418 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001419
1420 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001421 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1422 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001423
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001424 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001425 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1426 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001427
1428 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001429 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1430 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001431
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001432 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001433 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1434 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001435
1436 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001437 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1438 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001439
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001440 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1441 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1442
1443 float lensAperture = 2.53 / 100;
1444 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1445
1446 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1447 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1448 &opticalStabilization, 1);
1449
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001450 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001451 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1452 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001453
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001454 return requestTemplate;
1455}
1456
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001457CameraMetadata *CameraDevice::requestTemplateVideo()
1458{
1459 CameraMetadata *previewTemplate = requestTemplatePreview();
1460 if (!previewTemplate)
1461 return nullptr;
1462
1463 /*
1464 * The video template requires a fixed FPS range. Everything else
1465 * stays the same as the preview template.
1466 */
1467 camera_metadata_ro_entry_t entry;
1468 staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1469 &entry);
1470
1471 /*
1472 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
1473 * has been assembled as {{min, max} {max, max}}.
1474 */
1475 previewTemplate->updateEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1476 entry.data.i32 + 2, 2);
1477
1478 return previewTemplate;
1479}
1480
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001481/*
1482 * Produce a metadata pack to be used as template for a capture request.
1483 */
1484const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1485{
1486 auto it = requestTemplates_.find(type);
1487 if (it != requestTemplates_.end())
1488 return it->second->get();
1489
1490 /* Use the capture intent matching the requested template type. */
1491 CameraMetadata *requestTemplate;
1492 uint8_t captureIntent;
1493 switch (type) {
1494 case CAMERA3_TEMPLATE_PREVIEW:
1495 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001496 requestTemplate = requestTemplatePreview();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001497 break;
1498 case CAMERA3_TEMPLATE_STILL_CAPTURE:
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001499 /*
1500 * Use the preview template for still capture, they only differ
1501 * for the torch mode we currently do not support.
1502 */
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001503 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001504 requestTemplate = requestTemplatePreview();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001505 break;
1506 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1507 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001508 requestTemplate = requestTemplateVideo();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001509 break;
1510 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1511 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001512 requestTemplate = requestTemplateVideo();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001513 break;
Jacopo Mondi2c349912021-03-08 16:13:58 +01001514 /* \todo Implement templates generation for the remaining use cases. */
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001515 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001516 case CAMERA3_TEMPLATE_MANUAL:
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001517 default:
Jacopo Mondi2c349912021-03-08 16:13:58 +01001518 LOG(HAL, Error) << "Unsupported template request type: " << type;
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001519 return nullptr;
1520 }
1521
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001522 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001523 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001524 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001525 return nullptr;
1526 }
1527
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001528 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1529 &captureIntent, 1);
1530
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001531 requestTemplates_[type] = requestTemplate;
1532 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001533}
1534
Hirokazu Hondac1ae9052020-10-28 18:50:23 +09001535PixelFormat CameraDevice::toPixelFormat(int format) const
Kieran Bingham43e3b802020-06-26 09:58:49 +01001536{
1537 /* Translate Android format code to libcamera pixel format. */
1538 auto it = formatsMap_.find(format);
1539 if (it == formatsMap_.end()) {
1540 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1541 << " not supported";
1542 return PixelFormat();
1543 }
1544
1545 return it->second;
1546}
1547
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001548/*
1549 * Inspect the stream_list to produce a list of StreamConfiguration to
1550 * be use to configure the Camera.
1551 */
1552int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1553{
Jacopo Mondi8fed6132020-12-04 15:26:47 +01001554 /* Before any configuration attempt, stop the camera if it's running. */
1555 if (running_) {
1556 worker_.stop();
1557 camera_->stop();
1558 running_ = false;
1559 }
1560
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001561 /*
1562 * Generate an empty configuration, and construct a StreamConfiguration
1563 * for each camera3_stream to add to it.
1564 */
1565 config_ = camera_->generateConfiguration();
1566 if (!config_) {
1567 LOG(HAL, Error) << "Failed to generate camera configuration";
1568 return -EINVAL;
1569 }
1570
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001571 /*
1572 * Clear and remove any existing configuration from previous calls, and
1573 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001574 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001575 */
1576 streams_.clear();
1577 streams_.reserve(stream_list->num_streams);
1578
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001579 std::vector<Camera3StreamConfig> streamConfigs;
1580 streamConfigs.reserve(stream_list->num_streams);
1581
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001582 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001583 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001584 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1585 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001586 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001587
Kieran Bingham43e3b802020-06-26 09:58:49 +01001588 PixelFormat format = toPixelFormat(stream->format);
1589
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001590 LOG(HAL, Info) << "Stream #" << i
1591 << ", direction: " << stream->stream_type
1592 << ", width: " << stream->width
1593 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001594 << ", format: " << utils::hex(stream->format)
1595 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001596
1597 if (!format.isValid())
1598 return -EINVAL;
1599
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001600 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001601 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1602 if (jpegStream) {
1603 LOG(HAL, Error)
1604 << "Multiple JPEG streams are not supported";
1605 return -EINVAL;
1606 }
1607
1608 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001609 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001610 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001611
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001612 Camera3StreamConfig streamConfig;
1613 streamConfig.streams = { { stream, CameraStream::Type::Direct } };
1614 streamConfig.config.size = size;
1615 streamConfig.config.pixelFormat = format;
1616 streamConfigs.push_back(std::move(streamConfig));
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001617
1618 /* This stream will be produced by hardware. */
1619 stream->usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001620 }
1621
Jacopo Mondic82f9442020-09-02 11:58:00 +02001622 /* Now handle the MJPEG streams, adding a new stream if required. */
1623 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001624 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001625 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001626
Jacopo Mondic82f9442020-09-02 11:58:00 +02001627 /* Search for a compatible stream in the non-JPEG ones. */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001628 for (size_t i = 0; i < streamConfigs.size(); ++i) {
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001629 Camera3StreamConfig &streamConfig = streamConfigs[i];
1630 const auto &cfg = streamConfig.config;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001631
1632 /*
1633 * \todo The PixelFormat must also be compatible with
1634 * the encoder.
1635 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001636 if (cfg.size.width != jpegStream->width ||
1637 cfg.size.height != jpegStream->height)
1638 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001639
Jacopo Mondic82f9442020-09-02 11:58:00 +02001640 LOG(HAL, Info)
1641 << "Android JPEG stream mapped to libcamera stream " << i;
1642
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001643 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001644 index = i;
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001645
1646 /*
1647 * The source stream will be read by software to
1648 * produce the JPEG stream.
1649 */
1650 camera3_stream_t *stream = streamConfig.streams[0].stream;
1651 stream->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001652 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001653 }
1654
1655 /*
1656 * Without a compatible match for JPEG encoding we must
1657 * introduce a new stream to satisfy the request requirements.
1658 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001659 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001660 /*
1661 * \todo The pixelFormat should be a 'best-fit' choice
1662 * and may require a validation cycle. This is not yet
1663 * handled, and should be considered as part of any
1664 * stream configuration reworks.
1665 */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001666 Camera3StreamConfig streamConfig;
1667 streamConfig.config.size.width = jpegStream->width;
1668 streamConfig.config.size.height = jpegStream->height;
1669 streamConfig.config.pixelFormat = formats::NV12;
1670 streamConfigs.push_back(std::move(streamConfig));
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001671
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001672 LOG(HAL, Info) << "Adding " << streamConfig.config.toString()
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001673 << " for MJPEG support";
1674
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001675 type = CameraStream::Type::Internal;
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001676 index = streamConfigs.size() - 1;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001677 }
1678
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001679 /* The JPEG stream will be produced by software. */
1680 jpegStream->usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
1681
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001682 streamConfigs[index].streams.push_back({ jpegStream, type });
1683 }
1684
Hirokazu Honda26d90af2020-12-11 09:53:36 +00001685 sortCamera3StreamConfigs(streamConfigs, jpegStream);
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001686 for (const auto &streamConfig : streamConfigs) {
1687 config_->addConfiguration(streamConfig.config);
1688
1689 for (auto &stream : streamConfig.streams) {
1690 streams_.emplace_back(this, stream.type, stream.stream,
1691 config_->size() - 1);
1692 stream.stream->priv = static_cast<void *>(&streams_.back());
1693 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001694 }
1695
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001696 switch (config_->validate()) {
1697 case CameraConfiguration::Valid:
1698 break;
1699 case CameraConfiguration::Adjusted:
1700 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001701
1702 for (const StreamConfiguration &cfg : *config_)
1703 LOG(HAL, Info) << " - " << cfg.toString();
1704
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001705 config_.reset();
1706 return -EINVAL;
1707 case CameraConfiguration::Invalid:
1708 LOG(HAL, Info) << "Camera configuration invalid";
1709 config_.reset();
1710 return -EINVAL;
1711 }
1712
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001713 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001714 * Once the CameraConfiguration has been adjusted/validated
1715 * it can be applied to the camera.
1716 */
1717 int ret = camera_->configure(config_.get());
1718 if (ret) {
1719 LOG(HAL, Error) << "Failed to configure camera '"
1720 << camera_->id() << "'";
1721 return ret;
1722 }
1723
1724 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001725 * Configure the HAL CameraStream instances using the associated
1726 * StreamConfiguration and set the number of required buffers in
1727 * the Android camera3_stream_t.
1728 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001729 for (CameraStream &cameraStream : streams_) {
Kieran Binghamc7bcae02020-10-13 15:58:26 +01001730 ret = cameraStream.configure();
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001731 if (ret) {
1732 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001733 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001734 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001735 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001736
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001737 return 0;
1738}
1739
Kieran Bingham74ab4422020-07-01 13:25:38 +01001740FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1741{
1742 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001743 for (int i = 0; i < camera3buffer->numFds; i++) {
1744 /* Skip unused planes. */
1745 if (camera3buffer->data[i] == -1)
1746 break;
1747
Kieran Bingham74ab4422020-07-01 13:25:38 +01001748 FrameBuffer::Plane plane;
1749 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001750 if (!plane.fd.isValid()) {
1751 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1752 << camera3buffer->data[i] << ") "
1753 << " on plane " << i;
1754 return nullptr;
1755 }
1756
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001757 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1758 if (length == -1) {
1759 LOG(HAL, Error) << "Failed to query plane length";
1760 return nullptr;
1761 }
1762
1763 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001764 planes.push_back(std::move(plane));
1765 }
1766
1767 return new FrameBuffer(std::move(planes));
1768}
1769
Jacopo Mondibb2b4002021-01-04 16:20:05 +01001770int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)
1771{
1772 const CameraMetadata &settings = descriptor->settings_;
1773 if (!settings.isValid())
1774 return 0;
1775
1776 /* Translate the Android request settings to libcamera controls. */
1777 camera_metadata_ro_entry_t entry;
1778 if (settings.getEntry(ANDROID_SCALER_CROP_REGION, &entry)) {
1779 const int32_t *data = entry.data.i32;
1780 Rectangle cropRegion{ data[0], data[1],
1781 static_cast<unsigned int>(data[2]),
1782 static_cast<unsigned int>(data[3]) };
1783 ControlList &controls = descriptor->request_->controls();
1784 controls.set(controls::ScalerCrop, cropRegion);
1785 }
1786
1787 return 0;
1788}
1789
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001790int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001791{
Jacopo Mondic5b732b2020-12-01 17:12:19 +01001792 if (!camera3Request) {
1793 LOG(HAL, Error) << "No capture request provided";
1794 return -EINVAL;
1795 }
1796
Kieran Bingham61f42962020-07-01 13:40:17 +01001797 if (!camera3Request->num_output_buffers) {
1798 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001799 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001800 }
1801
1802 /* Start the camera if that's the first request we handle. */
1803 if (!running_) {
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001804 worker_.start();
1805
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001806 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001807 if (ret) {
1808 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001809 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001810 }
1811
1812 running_ = true;
1813 }
1814
1815 /*
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001816 * Save the request descriptors for use at completion time.
1817 * The descriptor and the associated memory reserved here are freed
1818 * at request complete time.
1819 */
1820 Camera3RequestDescriptor *descriptor =
Jacopo Mondidd1cd532021-01-21 10:51:05 +01001821 new Camera3RequestDescriptor(camera_.get(), camera3Request);
Paul Eldera6de3f02021-01-21 18:59:24 +09001822 /*
1823 * \todo The Android request model is incremental, settings passed in
1824 * previous requests are to be effective until overridden explicitly in
1825 * a new request. Do we need to cache settings incrementally here, or is
1826 * it handled by the Android camera service ?
1827 */
1828 if (camera3Request->settings)
1829 lastSettings_ = camera3Request->settings;
1830 else
1831 descriptor->settings_ = lastSettings_;
Kieran Binghameac05422020-07-01 13:28:16 +01001832
Jacopo Mondibc644072021-01-28 09:58:06 +01001833 LOG(HAL, Debug) << "Queueing request " << descriptor->request_->cookie()
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001834 << " with " << descriptor->buffers_.size() << " streams";
1835 for (unsigned int i = 0; i < descriptor->buffers_.size(); ++i) {
1836 const camera3_stream_buffer_t &camera3Buffer = descriptor->buffers_[i];
1837 camera3_stream *camera3Stream = camera3Buffer.stream;
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001838 CameraStream *cameraStream = static_cast<CameraStream *>(camera3Stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001839
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001840 std::stringstream ss;
1841 ss << i << " - (" << camera3Stream->width << "x"
1842 << camera3Stream->height << ")"
1843 << "[" << utils::hex(camera3Stream->format) << "] -> "
1844 << "(" << cameraStream->configuration().size.toString() << ")["
1845 << cameraStream->configuration().pixelFormat.toString() << "]";
1846
Jacopo Mondide8304b2020-09-04 17:45:39 +02001847 /*
1848 * Inspect the camera stream type, create buffers opportunely
1849 * and add them to the Request if required.
1850 */
1851 FrameBuffer *buffer = nullptr;
1852 switch (cameraStream->type()) {
1853 case CameraStream::Type::Mapped:
1854 /*
1855 * Mapped streams don't need buffers added to the
1856 * Request.
1857 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001858 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001859 continue;
1860
Jacopo Mondide8304b2020-09-04 17:45:39 +02001861 case CameraStream::Type::Direct:
1862 /*
1863 * Create a libcamera buffer using the dmabuf
1864 * descriptors of the camera3Buffer for each stream and
1865 * associate it with the Camera3RequestDescriptor for
1866 * lifetime management only.
1867 */
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001868 buffer = createFrameBuffer(*camera3Buffer.buffer);
Kieran Bingham37c18c22020-10-21 14:54:11 +01001869 descriptor->frameBuffers_.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001870 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001871 break;
1872
1873 case CameraStream::Type::Internal:
1874 /*
1875 * Get the frame buffer from the CameraStream internal
1876 * buffer pool.
1877 *
1878 * The buffer has to be returned to the CameraStream
1879 * once it has been processed.
1880 */
1881 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001882 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001883 break;
1884 }
1885
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001886 if (!buffer) {
1887 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001888 delete descriptor;
1889 return -ENOMEM;
1890 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001891
Kieran Bingham37c18c22020-10-21 14:54:11 +01001892 descriptor->request_->addBuffer(cameraStream->stream(), buffer,
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001893 camera3Buffer.acquire_fence);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001894 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001895
Jacopo Mondibb2b4002021-01-04 16:20:05 +01001896 /*
1897 * Translate controls from Android to libcamera and queue the request
1898 * to the CameraWorker thread.
1899 */
1900 int ret = processControls(descriptor);
1901 if (ret)
1902 return ret;
1903
Kieran Bingham37c18c22020-10-21 14:54:11 +01001904 worker_.queueRequest(descriptor->request_.get());
Paul Elderc7532232020-09-23 19:05:41 +09001905
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001906 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001907}
1908
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001909void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001910{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001911 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001912 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001913 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001914 Camera3RequestDescriptor *descriptor =
1915 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001916
1917 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001918 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001919 << request->status();
1920 status = CAMERA3_BUFFER_STATUS_ERROR;
1921 }
1922
Jacopo Mondibc644072021-01-28 09:58:06 +01001923 LOG(HAL, Debug) << "Request " << request->cookie() << " completed with "
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001924 << descriptor->buffers_.size() << " streams";
Jacopo Mondibc644072021-01-28 09:58:06 +01001925
Kieran Binghamc09aee42020-07-28 14:01:19 +01001926 /*
1927 * \todo The timestamp used for the metadata is currently always taken
1928 * from the first buffer (which may be the first stream) in the Request.
1929 * It might be appropriate to return a 'correct' (as determined by
1930 * pipeline handlers) timestamp in the Request itself.
1931 */
Hirokazu Honda3a777d82020-10-28 17:57:26 +09001932 uint64_t timestamp = buffers.begin()->second->metadata().timestamp;
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001933 resultMetadata = getResultMetadata(descriptor, timestamp);
Kieran Binghamc09aee42020-07-28 14:01:19 +01001934
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001935 /* Handle any JPEG compression. */
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001936 for (camera3_stream_buffer_t &buffer : descriptor->buffers_) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001937 CameraStream *cameraStream =
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001938 static_cast<CameraStream *>(buffer.stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001939
Jacopo Mondi160bb092020-10-02 20:48:35 +02001940 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001941 continue;
1942
Jacopo Mondid5473c92021-02-17 16:21:59 +01001943 FrameBuffer *src = request->findBuffer(cameraStream->stream());
1944 if (!src) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001945 LOG(HAL, Error) << "Failed to find a source stream buffer";
1946 continue;
1947 }
1948
Jacopo Mondia725baf2021-02-24 12:50:40 +01001949 int ret = cameraStream->process(*src,
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001950 *buffer.buffer,
Paul Elderabfabdd2021-01-23 13:54:28 +09001951 descriptor->settings_,
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02001952 resultMetadata.get());
1953 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001954 status = CAMERA3_BUFFER_STATUS_ERROR;
1955 continue;
1956 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02001957
1958 /*
1959 * Return the FrameBuffer to the CameraStream now that we're
1960 * done processing it.
1961 */
1962 if (cameraStream->type() == CameraStream::Type::Internal)
Jacopo Mondid5473c92021-02-17 16:21:59 +01001963 cameraStream->putBuffer(src);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001964 }
1965
1966 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001967 camera3_capture_result_t captureResult = {};
Kieran Bingham37c18c22020-10-21 14:54:11 +01001968 captureResult.frame_number = descriptor->frameNumber_;
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001969 captureResult.num_output_buffers = descriptor->buffers_.size();
1970 for (camera3_stream_buffer_t &buffer : descriptor->buffers_) {
1971 buffer.acquire_fence = -1;
1972 buffer.release_fence = -1;
1973 buffer.status = status;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001974 }
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001975 captureResult.output_buffers = descriptor->buffers_.data();
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001976
Laurent Pinchart39860092019-09-05 03:12:34 +03001977 if (status == CAMERA3_BUFFER_STATUS_OK) {
Kieran Binghame1f9fdb2020-10-21 15:31:10 +01001978 notifyShutter(descriptor->frameNumber_, timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001979
1980 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001981 captureResult.result = resultMetadata->get();
1982 }
1983
1984 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1985 /* \todo Improve error handling. In case we notify an error
1986 * because the metadata generation fails, a shutter event has
1987 * already been notified for this frame number before the error
1988 * is here signalled. Make sure the error path plays well with
1989 * the camera stack state machine.
1990 */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001991 notifyError(descriptor->frameNumber_,
1992 descriptor->buffers_[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001993 }
1994
1995 callbacks_->process_capture_result(callbacks_, &captureResult);
1996
1997 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001998}
1999
Jacopo Mondia7b92772020-05-26 15:41:41 +02002000std::string CameraDevice::logPrefix() const
2001{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02002002 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02002003}
2004
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002005void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
2006{
2007 camera3_notify_msg_t notify = {};
2008
2009 notify.type = CAMERA3_MSG_SHUTTER;
2010 notify.message.shutter.frame_number = frameNumber;
2011 notify.message.shutter.timestamp = timestamp;
2012
2013 callbacks_->notify(callbacks_, &notify);
2014}
2015
2016void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
2017{
2018 camera3_notify_msg_t notify = {};
2019
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01002020 /*
2021 * \todo Report and identify the stream number or configuration to
2022 * clarify the stream that failed.
2023 */
2024 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
2025 << toPixelFormat(stream->format).toString() << ")";
2026
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002027 notify.type = CAMERA3_MSG_ERROR;
2028 notify.message.error.error_stream = stream;
2029 notify.message.error.frame_number = frameNumber;
2030 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
2031
2032 callbacks_->notify(callbacks_, &notify);
2033}
2034
2035/*
2036 * Produce a set of fixed result metadata.
2037 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03002038std::unique_ptr<CameraMetadata>
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002039CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor,
Laurent Pinchartdbafe162019-10-27 00:36:13 +03002040 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002041{
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002042 const ControlList &metadata = descriptor->request_->metadata();
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002043 const CameraMetadata &settings = descriptor->settings_;
Paul Elder958c80a2021-01-26 09:47:33 +09002044 camera_metadata_ro_entry_t entry;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002045 bool found;
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002046
Jacopo Mondi48504ba2019-09-04 16:18:19 +02002047 /*
2048 * \todo Keep this in sync with the actual number of entries.
Paul Elder12646282021-01-23 13:56:01 +09002049 * Currently: 40 entries, 156 bytes
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002050 *
2051 * Reserve more space for the JPEG metadata set by the post-processor.
Paul Elderabfabdd2021-01-23 13:54:28 +09002052 * Currently:
2053 * ANDROID_JPEG_GPS_COORDINATES (double x 3) = 24 bytes
2054 * ANDROID_JPEG_GPS_PROCESSING_METHOD (byte x 32) = 32 bytes
2055 * ANDROID_JPEG_GPS_TIMESTAMP (int64) = 8 bytes
2056 * ANDROID_JPEG_SIZE (int32_t) = 4 bytes
2057 * ANDROID_JPEG_QUALITY (byte) = 1 byte
2058 * ANDROID_JPEG_ORIENTATION (int32_t) = 4 bytes
Paul Elder12646282021-01-23 13:56:01 +09002059 * ANDROID_JPEG_THUMBNAIL_QUALITY (byte) = 1 byte
2060 * ANDROID_JPEG_THUMBNAIL_SIZE (int32 x 2) = 8 bytes
2061 * Total bytes for JPEG metadata: 82
Jacopo Mondi48504ba2019-09-04 16:18:19 +02002062 */
Laurent Pinchart39860092019-09-05 03:12:34 +03002063 std::unique_ptr<CameraMetadata> resultMetadata =
Jacopo Mondif29601e2021-02-03 16:47:30 +01002064 std::make_unique<CameraMetadata>(44, 166);
Laurent Pinchart39860092019-09-05 03:12:34 +03002065 if (!resultMetadata->isValid()) {
2066 LOG(HAL, Error) << "Failed to allocate static metadata";
2067 return nullptr;
2068 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002069
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002070 /*
2071 * \todo The value of the results metadata copied from the settings
2072 * will have to be passed to the libcamera::Camera and extracted
2073 * from libcamera::Request::metadata.
2074 */
2075
Jacopo Mondi520c3662021-02-03 14:44:34 +01002076 uint8_t value = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
2077 resultMetadata->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
2078 &value, 1);
2079
2080 value = ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF;
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002081 resultMetadata->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002082
Jacopo Mondie9c28752021-02-03 14:47:45 +01002083 int32_t value32 = 0;
2084 resultMetadata->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
2085 &value32, 1);
2086
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002087 value = ANDROID_CONTROL_AE_LOCK_OFF;
2088 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002089
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002090 value = ANDROID_CONTROL_AE_MODE_ON;
2091 resultMetadata->addEntry(ANDROID_CONTROL_AE_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002092
Jacopo Mondid1508602021-01-21 18:21:28 +01002093 if (settings.getEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, &entry))
2094 /*
2095 * \todo Retrieve the AE FPS range from the libcamera metadata.
2096 * As libcamera does not support that control, as a temporary
2097 * workaround return what the framework asked.
2098 */
2099 resultMetadata->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
2100 entry.data.i32, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002101
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002102 value = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002103 found = settings.getEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &entry);
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002104 resultMetadata->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002105 found ? entry.data.u8 : &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002106
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002107 value = ANDROID_CONTROL_AE_STATE_CONVERGED;
2108 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &value, 1);
2109
2110 value = ANDROID_CONTROL_AF_MODE_OFF;
2111 resultMetadata->addEntry(ANDROID_CONTROL_AF_MODE, &value, 1);
2112
2113 value = ANDROID_CONTROL_AF_STATE_INACTIVE;
2114 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &value, 1);
2115
2116 value = ANDROID_CONTROL_AF_TRIGGER_IDLE;
2117 resultMetadata->addEntry(ANDROID_CONTROL_AF_TRIGGER, &value, 1);
2118
2119 value = ANDROID_CONTROL_AWB_MODE_AUTO;
2120 resultMetadata->addEntry(ANDROID_CONTROL_AWB_MODE, &value, 1);
2121
2122 value = ANDROID_CONTROL_AWB_LOCK_OFF;
2123 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &value, 1);
2124
2125 value = ANDROID_CONTROL_AWB_STATE_CONVERGED;
2126 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &value, 1);
2127
2128 value = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
2129 resultMetadata->addEntry(ANDROID_CONTROL_CAPTURE_INTENT, &value, 1);
2130
2131 value = ANDROID_CONTROL_EFFECT_MODE_OFF;
2132 resultMetadata->addEntry(ANDROID_CONTROL_EFFECT_MODE, &value, 1);
2133
2134 value = ANDROID_CONTROL_MODE_AUTO;
2135 resultMetadata->addEntry(ANDROID_CONTROL_MODE, &value, 1);
2136
2137 value = ANDROID_CONTROL_SCENE_MODE_DISABLED;
2138 resultMetadata->addEntry(ANDROID_CONTROL_SCENE_MODE, &value, 1);
2139
2140 value = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
2141 resultMetadata->addEntry(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &value, 1);
2142
2143 value = ANDROID_FLASH_MODE_OFF;
2144 resultMetadata->addEntry(ANDROID_FLASH_MODE, &value, 1);
2145
2146 value = ANDROID_FLASH_STATE_UNAVAILABLE;
2147 resultMetadata->addEntry(ANDROID_FLASH_STATE, &value, 1);
2148
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002149 if (settings.getEntry(ANDROID_LENS_APERTURE, &entry))
Paul Elderabfabdd2021-01-23 13:54:28 +09002150 resultMetadata->addEntry(ANDROID_LENS_APERTURE, entry.data.f, 1);
2151
2152 float focal_length = 1.0;
2153 resultMetadata->addEntry(ANDROID_LENS_FOCAL_LENGTH, &focal_length, 1);
2154
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002155 value = ANDROID_LENS_STATE_STATIONARY;
2156 resultMetadata->addEntry(ANDROID_LENS_STATE, &value, 1);
2157
2158 value = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
2159 resultMetadata->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
2160 &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002161
Jacopo Mondi5360d802021-02-03 16:43:22 +01002162 value32 = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
2163 resultMetadata->addEntry(ANDROID_SENSOR_TEST_PATTERN_MODE,
2164 &value32, 1);
2165
Laurent Pinchart39860092019-09-05 03:12:34 +03002166 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002167
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002168 value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
2169 resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
2170 &value, 1);
2171
2172 value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
2173 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
2174 &value, 1);
2175
Jacopo Mondif29601e2021-02-03 16:47:30 +01002176 value = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
2177 resultMetadata->addEntry(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
2178 &value, 1);
2179
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002180 value = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
2181 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
2182 &value, 1);
2183
2184 value = ANDROID_NOISE_REDUCTION_MODE_OFF;
2185 resultMetadata->addEntry(ANDROID_NOISE_REDUCTION_MODE, &value, 1);
2186
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002187 /* 33.3 msec */
2188 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03002189 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
2190 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002191
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002192 /* Add metadata tags reported by libcamera. */
2193 if (metadata.contains(controls::draft::PipelineDepth)) {
2194 uint8_t pipeline_depth =
2195 metadata.get<int32_t>(controls::draft::PipelineDepth);
2196 resultMetadata->addEntry(ANDROID_REQUEST_PIPELINE_DEPTH,
2197 &pipeline_depth, 1);
2198 }
2199
Jacopo Mondic9705a52021-01-05 19:30:48 +01002200 if (metadata.contains(controls::ExposureTime)) {
Paul Elder78f49d52021-01-28 17:45:44 +09002201 int64_t exposure = metadata.get(controls::ExposureTime) * 1000ULL;
Jacopo Mondic9705a52021-01-05 19:30:48 +01002202 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
2203 &exposure, 1);
2204 }
2205
Jacopo Mondibb2b4002021-01-04 16:20:05 +01002206 if (metadata.contains(controls::ScalerCrop)) {
2207 Rectangle crop = metadata.get(controls::ScalerCrop);
2208 int32_t cropRect[] = {
2209 crop.x, crop.y, static_cast<int32_t>(crop.width),
2210 static_cast<int32_t>(crop.height),
2211 };
2212 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, cropRect, 4);
2213 }
2214
Laurent Pinchart39860092019-09-05 03:12:34 +03002215 /*
2216 * Return the result metadata pack even is not valid: get() will return
2217 * nullptr.
2218 */
2219 if (!resultMetadata->isValid()) {
2220 LOG(HAL, Error) << "Failed to construct result metadata";
2221 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002222
2223 return resultMetadata;
2224}