blob: 822de254e56770f7a245ee7c5d7cd444ab185cbc [file] [log] [blame]
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2019, Google Inc.
4 *
5 * camera_device.cpp - libcamera Android Camera Device
6 */
7
8#include "camera_device.h"
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02009#include "camera_ops.h"
Umang Jainb2b8c4d2020-10-16 11:07:54 +053010#include "post_processor.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020011
Kieran Bingham83ae84e2020-07-03 12:34:59 +010012#include <sys/mman.h>
Jacopo Mondia80d3812020-05-26 12:31:35 +020013#include <tuple>
Jacopo Mondi117588b2020-05-23 18:53:54 +020014#include <vector>
15
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +020016#include <libcamera/control_ids.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010017#include <libcamera/controls.h>
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030018#include <libcamera/formats.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010019#include <libcamera/property_ids.h>
20
Niklas Söderlund7876d632020-07-21 00:16:24 +020021#include "libcamera/internal/formats.h"
Laurent Pinchart93e72b62020-05-12 00:58:34 +030022#include "libcamera/internal/log.h"
23#include "libcamera/internal/utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020024
Jacopo Mondi117588b2020-05-23 18:53:54 +020025#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020026
27using namespace libcamera;
28
Hirokazu Honda26d90af2020-12-11 09:53:36 +000029LOG_DECLARE_CATEGORY(HAL)
30
Jacopo Mondi117588b2020-05-23 18:53:54 +020031namespace {
32
33/*
34 * \var camera3Resolutions
35 * \brief The list of image resolutions defined as mandatory to be supported by
36 * the Android Camera3 specification
37 */
38const std::vector<Size> camera3Resolutions = {
39 { 320, 240 },
40 { 640, 480 },
41 { 1280, 720 },
42 { 1920, 1080 }
43};
44
45/*
46 * \struct Camera3Format
47 * \brief Data associated with an Android format identifier
48 * \var libcameraFormats List of libcamera pixel formats compatible with the
49 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020050 * \var name The human-readable representation of the Android format code
51 */
52struct Camera3Format {
53 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020054 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020055 const char *name;
56};
57
58/*
59 * \var camera3FormatsMap
60 * \brief Associate Android format code with ancillary data
61 */
62const std::map<int, const Camera3Format> camera3FormatsMap = {
63 {
64 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030065 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020066 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020067 "BLOB"
68 }
69 }, {
70 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030071 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020072 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020073 "YCbCr_420_888"
74 }
75 }, {
76 /*
77 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
78 * usage flag. For now, copy the YCbCr_420 configuration.
79 */
80 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030081 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020082 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020083 "IMPLEMENTATION_DEFINED"
84 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020085 }, {
86 HAL_PIXEL_FORMAT_RAW10, {
87 {
88 formats::SBGGR10_CSI2P,
89 formats::SGBRG10_CSI2P,
90 formats::SGRBG10_CSI2P,
91 formats::SRGGB10_CSI2P
92 },
93 false,
94 "RAW10"
95 }
96 }, {
97 HAL_PIXEL_FORMAT_RAW12, {
98 {
99 formats::SBGGR12_CSI2P,
100 formats::SGBRG12_CSI2P,
101 formats::SGRBG12_CSI2P,
102 formats::SRGGB12_CSI2P
103 },
104 false,
105 "RAW12"
106 }
107 }, {
108 HAL_PIXEL_FORMAT_RAW16, {
109 {
110 formats::SBGGR16,
111 formats::SGBRG16,
112 formats::SGRBG16,
113 formats::SRGGB16
114 },
115 false,
116 "RAW16"
117 }
118 }, {
119 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
120 {
121 formats::SBGGR10_IPU3,
122 formats::SGBRG10_IPU3,
123 formats::SGRBG10_IPU3,
124 formats::SRGGB10_IPU3
125 },
126 false,
127 "RAW_OPAQUE"
128 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200129 },
130};
131
Hirokazu Hondac2df7432020-12-11 09:53:34 +0000132/*
133 * \struct Camera3StreamConfig
134 * \brief Data to store StreamConfiguration associated with camera3_stream(s)
135 * \var streams List of the pairs of a stream requested by Android HAL client
136 * and CameraStream::Type associated with the stream
137 * \var config StreamConfiguration for streams
138 */
139struct Camera3StreamConfig {
140 struct Camera3Stream {
141 camera3_stream_t *stream;
142 CameraStream::Type type;
143 };
144
145 std::vector<Camera3Stream> streams;
146 StreamConfiguration config;
147};
148
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000149/*
150 * Reorder the configurations so that libcamera::Camera can accept them as much
151 * as possible. The sort rule is as follows.
152 * 1.) The configuration for NV12 request whose resolution is the largest.
153 * 2.) The configuration for JPEG request.
154 * 3.) Others. Larger resolutions and different formats are put earlier.
155 */
156void sortCamera3StreamConfigs(std::vector<Camera3StreamConfig> &unsortedConfigs,
157 const camera3_stream_t *jpegStream)
158{
159 const Camera3StreamConfig *jpegConfig = nullptr;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200160
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000161 std::map<PixelFormat, std::vector<const Camera3StreamConfig *>> formatToConfigs;
162 for (const auto &streamConfig : unsortedConfigs) {
163 if (jpegStream && !jpegConfig) {
164 const auto &streams = streamConfig.streams;
165 if (std::find_if(streams.begin(), streams.end(),
166 [jpegStream](const auto &stream) {
167 return stream.stream == jpegStream;
168 }) != streams.end()) {
169 jpegConfig = &streamConfig;
170 continue;
171 }
172 }
173 formatToConfigs[streamConfig.config.pixelFormat].push_back(&streamConfig);
174 }
175
176 if (jpegStream && !jpegConfig)
177 LOG(HAL, Fatal) << "No Camera3StreamConfig is found for JPEG";
178
179 for (auto &fmt : formatToConfigs) {
180 auto &streamConfigs = fmt.second;
181
182 /* Sorted by resolution. Smaller is put first. */
183 std::sort(streamConfigs.begin(), streamConfigs.end(),
184 [](const auto *streamConfigA, const auto *streamConfigB) {
185 const Size &sizeA = streamConfigA->config.size;
186 const Size &sizeB = streamConfigB->config.size;
187 return sizeA < sizeB;
188 });
189 }
190
191 std::vector<Camera3StreamConfig> sortedConfigs;
192 sortedConfigs.reserve(unsortedConfigs.size());
193
194 /*
195 * NV12 is the most prioritized format. Put the configuration with NV12
196 * and the largest resolution first.
197 */
198 const auto nv12It = formatToConfigs.find(formats::NV12);
199 if (nv12It != formatToConfigs.end()) {
200 auto &nv12Configs = nv12It->second;
Laurent Pinchartbd4894d2020-12-12 05:22:31 +0200201 const Camera3StreamConfig *nv12Largest = nv12Configs.back();
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000202
203 /*
204 * If JPEG will be created from NV12 and the size is larger than
205 * the largest NV12 configurations, then put the NV12
206 * configuration for JPEG first.
207 */
208 if (jpegConfig && jpegConfig->config.pixelFormat == formats::NV12) {
209 const Size &nv12SizeForJpeg = jpegConfig->config.size;
210 const Size &nv12LargestSize = nv12Largest->config.size;
211
212 if (nv12LargestSize < nv12SizeForJpeg) {
213 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
214 sortedConfigs.push_back(std::move(*jpegConfig));
215 jpegConfig = nullptr;
216 }
217 }
218
219 LOG(HAL, Debug) << "Insert " << nv12Largest->config.toString();
220 sortedConfigs.push_back(*nv12Largest);
221 nv12Configs.pop_back();
222
223 if (nv12Configs.empty())
224 formatToConfigs.erase(nv12It);
225 }
226
227 /* If the configuration for JPEG is there, then put it. */
228 if (jpegConfig) {
229 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
230 sortedConfigs.push_back(std::move(*jpegConfig));
231 jpegConfig = nullptr;
232 }
233
234 /*
235 * Put configurations with different formats and larger resolutions
236 * earlier.
237 */
238 while (!formatToConfigs.empty()) {
239 for (auto it = formatToConfigs.begin(); it != formatToConfigs.end();) {
240 auto &configs = it->second;
241 LOG(HAL, Debug) << "Insert " << configs.back()->config.toString();
242 sortedConfigs.push_back(*configs.back());
243 configs.pop_back();
244
245 if (configs.empty())
246 it = formatToConfigs.erase(it);
247 else
248 it++;
249 }
250 }
251
252 ASSERT(sortedConfigs.size() == unsortedConfigs.size());
253
254 unsortedConfigs = sortedConfigs;
255}
256
257} /* namespace */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200258
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100259MappedCamera3Buffer::MappedCamera3Buffer(const buffer_handle_t camera3buffer,
260 int flags)
261{
262 maps_.reserve(camera3buffer->numFds);
263 error_ = 0;
264
265 for (int i = 0; i < camera3buffer->numFds; i++) {
266 if (camera3buffer->data[i] == -1)
267 continue;
268
269 off_t length = lseek(camera3buffer->data[i], 0, SEEK_END);
270 if (length < 0) {
271 error_ = -errno;
272 LOG(HAL, Error) << "Failed to query plane length";
273 break;
274 }
275
276 void *address = mmap(nullptr, length, flags, MAP_SHARED,
277 camera3buffer->data[i], 0);
278 if (address == MAP_FAILED) {
279 error_ = -errno;
280 LOG(HAL, Error) << "Failed to mmap plane";
281 break;
282 }
283
284 maps_.emplace_back(static_cast<uint8_t *>(address),
285 static_cast<size_t>(length));
286 }
287}
288
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200289/*
290 * \struct Camera3RequestDescriptor
291 *
292 * A utility structure that groups information about a capture request to be
293 * later re-used at request complete time to notify the framework.
294 */
295
296CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100297 Camera *camera, const camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200298{
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100299 frameNumber_ = camera3Request->frame_number;
300
Jacopo Mondi4b18b822021-01-21 11:10:08 +0100301 /* Copy the camera3 request stream information for later access. */
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100302 numBuffers_ = camera3Request->num_output_buffers;
303 buffers_ = new camera3_stream_buffer_t[numBuffers_];
Jacopo Mondi4b18b822021-01-21 11:10:08 +0100304 for (unsigned int i = 0; i < numBuffers_; ++i)
305 buffers_[i] = camera3Request->output_buffers[i];
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200306
307 /*
308 * FrameBuffer instances created by wrapping a camera3 provided dmabuf
309 * are emplaced in this vector of unique_ptr<> for lifetime management.
310 */
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100311 frameBuffers_.reserve(numBuffers_);
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200312
Jacopo Mondi9e6eece2021-01-21 12:52:10 +0100313 /* Clone the controls associated with the camera3 request. */
314 settings_ = CameraMetadata(camera3Request->settings);
315
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200316 /*
317 * Create the libcamera::Request unique_ptr<> to tie its lifetime
318 * to the descriptor's one. Set the descriptor's address as the
319 * request's cookie to retrieve it at completion time.
320 */
Kieran Bingham37c18c22020-10-21 14:54:11 +0100321 request_ = std::make_unique<CaptureRequest>(camera,
322 reinterpret_cast<uint64_t>(this));
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200323}
324
325CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
326{
Kieran Bingham37c18c22020-10-21 14:54:11 +0100327 delete[] buffers_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200328}
329
330/*
331 * \class CameraDevice
332 *
333 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200334 * the camera3_device_t interface, bridging calls received from the Android
335 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200336 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200337 * The class translates parameters and operations from the Camera HALv3 API to
338 * the libcamera API to provide static information for a Camera, create request
339 * templates for it, process capture requests and then deliver capture results
340 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200341 */
342
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300343CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000344 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200345 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200346{
347 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100348
349 /*
350 * \todo Determine a more accurate value for this during
351 * streamConfiguration.
352 */
353 maxJpegBufferSize_ = 13 << 20; /* 13631488 from USB HAL */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200354}
355
356CameraDevice::~CameraDevice()
357{
358 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300359 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200360
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200361 for (auto &it : requestTemplates_)
362 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200363}
364
Umang Jainf8e28132020-08-21 14:46:08 +0000365std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
366 const std::shared_ptr<Camera> &cam)
367{
368 CameraDevice *camera = new CameraDevice(id, cam);
369 return std::shared_ptr<CameraDevice>(camera);
370}
371
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200372/*
373 * Initialize the camera static information.
374 * This method is called before the camera device is opened.
375 */
376int CameraDevice::initialize()
377{
378 /* Initialize orientation and facing side of the camera. */
379 const ControlList &properties = camera_->properties();
380
381 if (properties.contains(properties::Location)) {
382 int32_t location = properties.get(properties::Location);
383 switch (location) {
384 case properties::CameraLocationFront:
385 facing_ = CAMERA_FACING_FRONT;
386 break;
387 case properties::CameraLocationBack:
388 facing_ = CAMERA_FACING_BACK;
389 break;
390 case properties::CameraLocationExternal:
391 facing_ = CAMERA_FACING_EXTERNAL;
392 break;
393 }
394 }
395
396 /*
Umang Jaine9176552020-09-09 16:17:54 +0530397 * The Android orientation metadata specifies its rotation correction
398 * value in clockwise direction whereas libcamera specifies the
399 * rotation property in anticlockwise direction. Read the libcamera's
400 * rotation property (anticlockwise) and compute the corresponding
401 * value for clockwise direction as required by the Android orientation
402 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200403 */
Umang Jaine9176552020-09-09 16:17:54 +0530404 if (properties.contains(properties::Rotation)) {
405 int rotation = properties.get(properties::Rotation);
406 orientation_ = (360 - rotation) % 360;
407 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200408
Jacopo Mondi117588b2020-05-23 18:53:54 +0200409 int ret = camera_->acquire();
410 if (ret) {
411 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
412 return ret;
413 }
414
415 ret = initializeStreamConfigurations();
416 camera_->release();
417 return ret;
418}
419
Jacopo Mondibfee6312020-09-01 17:42:13 +0200420std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
421 const PixelFormat &pixelFormat,
422 const std::vector<Size> &resolutions)
423{
424 std::vector<Size> supportedResolutions;
425
426 StreamConfiguration &cfg = cameraConfig->at(0);
427 for (const Size &res : resolutions) {
428 cfg.pixelFormat = pixelFormat;
429 cfg.size = res;
430
431 CameraConfiguration::Status status = cameraConfig->validate();
432 if (status != CameraConfiguration::Valid) {
433 LOG(HAL, Debug) << cfg.toString() << " not supported";
434 continue;
435 }
436
437 LOG(HAL, Debug) << cfg.toString() << " supported";
438
439 supportedResolutions.push_back(res);
440 }
441
442 return supportedResolutions;
443}
444
Jacopo Mondi49610332020-09-01 18:11:34 +0200445std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
446{
447 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200448 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200449 StreamConfiguration &cfg = cameraConfig->at(0);
450 const StreamFormats &formats = cfg.formats();
451 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
452
453 return supportedResolutions;
454}
455
Jacopo Mondi117588b2020-05-23 18:53:54 +0200456/*
457 * Initialize the format conversion map to translate from Android format
458 * identifier to libcamera pixel formats and fill in the list of supported
459 * stream configurations to be reported to the Android camera framework through
460 * the static stream configuration metadata.
461 */
462int CameraDevice::initializeStreamConfigurations()
463{
464 /*
465 * Get the maximum output resolutions
466 * \todo Get this from the camera properties once defined
467 */
468 std::unique_ptr<CameraConfiguration> cameraConfig =
469 camera_->generateConfiguration({ StillCapture });
470 if (!cameraConfig) {
471 LOG(HAL, Error) << "Failed to get maximum resolution";
472 return -EINVAL;
473 }
474 StreamConfiguration &cfg = cameraConfig->at(0);
475
476 /*
477 * \todo JPEG - Adjust the maximum available resolution by taking the
478 * JPEG encoder requirements into account (alignment and aspect ratio).
479 */
480 const Size maxRes = cfg.size;
481 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
482
483 /*
484 * Build the list of supported image resolutions.
485 *
486 * The resolutions listed in camera3Resolution are mandatory to be
487 * supported, up to the camera maximum resolution.
488 *
489 * Augment the list by adding resolutions calculated from the camera
490 * maximum one.
491 */
492 std::vector<Size> cameraResolutions;
493 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
494 std::back_inserter(cameraResolutions),
495 [&](const Size &res) { return res < maxRes; });
496
497 /*
498 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
499 * resolution.
500 */
501 for (unsigned int divider = 2;; divider <<= 1) {
502 Size derivedSize{
503 maxRes.width / divider,
504 maxRes.height / divider,
505 };
506
507 if (derivedSize.width < 320 ||
508 derivedSize.height < 240)
509 break;
510
511 cameraResolutions.push_back(derivedSize);
512 }
513 cameraResolutions.push_back(maxRes);
514
515 /* Remove duplicated entries from the list of supported resolutions. */
516 std::sort(cameraResolutions.begin(), cameraResolutions.end());
517 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
518 cameraResolutions.erase(last, cameraResolutions.end());
519
520 /*
521 * Build the list of supported camera formats.
522 *
523 * To each Android format a list of compatible libcamera formats is
524 * associated. The first libcamera format that tests successful is added
525 * to the format translation map used when configuring the streams.
526 * It is then tested against the list of supported camera resolutions to
527 * build the stream configuration map reported through the camera static
528 * metadata.
529 */
530 for (const auto &format : camera3FormatsMap) {
531 int androidFormat = format.first;
532 const Camera3Format &camera3Format = format.second;
533 const std::vector<PixelFormat> &libcameraFormats =
534 camera3Format.libcameraFormats;
535
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200536 LOG(HAL, Debug) << "Trying to map Android format "
537 << camera3Format.name;
538
Jacopo Mondi117588b2020-05-23 18:53:54 +0200539 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200540 * JPEG is always supported, either produced directly by the
541 * camera, or encoded in the HAL.
542 */
543 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
544 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200545 LOG(HAL, Debug) << "Mapped Android format "
546 << camera3Format.name << " to "
547 << formats::MJPEG.toString()
548 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200549 continue;
550 }
551
552 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200553 * Test the libcamera formats that can produce images
554 * compatible with the format defined by Android.
555 */
556 PixelFormat mappedFormat;
557 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200558
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200559 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
560
Jacopo Mondi117588b2020-05-23 18:53:54 +0200561 /*
562 * The stream configuration size can be adjusted,
563 * not the pixel format.
564 *
565 * \todo This could be simplified once all pipeline
566 * handlers will report the StreamFormats list of
567 * supported formats.
568 */
569 cfg.pixelFormat = pixelFormat;
570
571 CameraConfiguration::Status status = cameraConfig->validate();
572 if (status != CameraConfiguration::Invalid &&
573 cfg.pixelFormat == pixelFormat) {
574 mappedFormat = pixelFormat;
575 break;
576 }
577 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200578
579 if (!mappedFormat.isValid()) {
580 /* If the format is not mandatory, skip it. */
581 if (!camera3Format.mandatory)
582 continue;
583
584 LOG(HAL, Error)
585 << "Failed to map mandatory Android format "
586 << camera3Format.name << " ("
587 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200588 return -EINVAL;
589 }
590
591 /*
592 * Record the mapping and then proceed to generate the
593 * stream configurations map, by testing the image resolutions.
594 */
595 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200596 LOG(HAL, Debug) << "Mapped Android format "
597 << camera3Format.name << " to "
598 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200599
Jacopo Mondi49610332020-09-01 18:11:34 +0200600 std::vector<Size> resolutions;
601 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
602 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
603 resolutions = getRawResolutions(mappedFormat);
604 else
605 resolutions = getYUVResolutions(cameraConfig.get(),
606 mappedFormat,
607 cameraResolutions);
608
Jacopo Mondibfee6312020-09-01 17:42:13 +0200609 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200610 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200611
612 /*
613 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
614 * from which JPEG is produced, add an entry for
615 * the JPEG stream.
616 *
617 * \todo Wire the JPEG encoder to query the supported
618 * sizes provided a list of formats it can encode.
619 *
620 * \todo Support JPEG streams produced by the Camera
621 * natively.
622 */
623 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888)
624 streamConfigurations_.push_back(
625 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200626 }
627 }
628
629 LOG(HAL, Debug) << "Collected stream configuration map: ";
630 for (const auto &entry : streamConfigurations_)
631 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200632 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200633
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200634 return 0;
635}
636
637/*
638 * Open a camera device. The static information on the camera shall have been
639 * initialized with a call to CameraDevice::initialize().
640 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200641int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200642{
643 int ret = camera_->acquire();
644 if (ret) {
645 LOG(HAL, Error) << "Failed to acquire the camera";
646 return ret;
647 }
648
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200649 /* Initialize the hw_device_t in the instance camera3_module_t. */
650 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
651 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
652 camera3Device_.common.module = (hw_module_t *)hardwareModule;
653 camera3Device_.common.close = hal_dev_close;
654
655 /*
656 * The camera device operations. These actually implement
657 * the Android Camera HALv3 interface.
658 */
659 camera3Device_.ops = &hal_dev_ops;
660 camera3Device_.priv = this;
661
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200662 return 0;
663}
664
665void CameraDevice::close()
666{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200667 streams_.clear();
668
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200669 worker_.stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200670 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200671 camera_->release();
672
673 running_ = false;
674}
675
676void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
677{
678 callbacks_ = callbacks;
679}
680
Jacopo Mondia80d3812020-05-26 12:31:35 +0200681std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
682{
683 /*
684 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondieec6c542020-12-09 18:16:11 +0100685 * Currently: 53 entries, 714 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200686 */
Jacopo Mondieec6c542020-12-09 18:16:11 +0100687 uint32_t numEntries = 53;
688 uint32_t byteSize = 714;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200689
690 /*
691 * Calculate space occupation in bytes for dynamically built metadata
692 * entries.
693 *
694 * Each stream configuration entry requires 52 bytes:
695 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200696 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
697 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200698 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200699
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300700 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200701}
702
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200703/*
704 * Return static information for the camera.
705 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200706const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200707{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200708 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300709 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200710
711 /*
712 * The here reported metadata are enough to implement a basic capture
713 * example application, but a real camera implementation will require
714 * more.
715 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200716 uint32_t numEntries;
717 uint32_t byteSize;
718 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
719 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300720 if (!staticMetadata_->isValid()) {
721 LOG(HAL, Error) << "Failed to allocate static metadata";
722 delete staticMetadata_;
723 staticMetadata_ = nullptr;
724 return nullptr;
725 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200726
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200727 const ControlInfoMap &controlsInfo = camera_->controls();
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100728 const ControlList &properties = camera_->properties();
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200729
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200730 /* Color correction static metadata. */
Jacopo Mondi63336862020-10-08 16:18:26 +0200731 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100732 std::vector<uint8_t> data;
733 data.reserve(3);
Jacopo Mondi63336862020-10-08 16:18:26 +0200734 const auto &infoMap = controlsInfo.find(&controls::draft::ColorCorrectionAberrationMode);
735 if (infoMap != controlsInfo.end()) {
736 for (const auto &value : infoMap->second.values())
737 data.push_back(value.get<int32_t>());
738 } else {
739 data.push_back(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
740 }
741 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
742 data.data(), data.size());
743 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200744
745 /* Control static metadata. */
746 std::vector<uint8_t> aeAvailableAntiBandingModes = {
747 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
748 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
749 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
750 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
751 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300752 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
753 aeAvailableAntiBandingModes.data(),
754 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200755
756 std::vector<uint8_t> aeAvailableModes = {
757 ANDROID_CONTROL_AE_MODE_ON,
758 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300759 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
760 aeAvailableModes.data(),
761 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200762
763 std::vector<int32_t> availableAeFpsTarget = {
764 15, 30,
765 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300766 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
767 availableAeFpsTarget.data(),
768 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200769
770 std::vector<int32_t> aeCompensationRange = {
771 0, 0,
772 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300773 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
774 aeCompensationRange.data(),
775 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200776
777 const camera_metadata_rational_t aeCompensationStep[] = {
778 { 0, 1 }
779 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300780 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
781 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200782
783 std::vector<uint8_t> availableAfModes = {
784 ANDROID_CONTROL_AF_MODE_OFF,
785 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300786 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
787 availableAfModes.data(),
788 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200789
790 std::vector<uint8_t> availableEffects = {
791 ANDROID_CONTROL_EFFECT_MODE_OFF,
792 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300793 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
794 availableEffects.data(),
795 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200796
797 std::vector<uint8_t> availableSceneModes = {
798 ANDROID_CONTROL_SCENE_MODE_DISABLED,
799 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300800 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
801 availableSceneModes.data(),
802 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200803
804 std::vector<uint8_t> availableStabilizationModes = {
805 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
806 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300807 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
808 availableStabilizationModes.data(),
809 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200810
811 std::vector<uint8_t> availableAwbModes = {
812 ANDROID_CONTROL_AWB_MODE_OFF,
813 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300814 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
815 availableAwbModes.data(),
816 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200817
818 std::vector<int32_t> availableMaxRegions = {
819 0, 0, 0,
820 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300821 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
822 availableMaxRegions.data(),
823 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200824
825 std::vector<uint8_t> sceneModesOverride = {
826 ANDROID_CONTROL_AE_MODE_ON,
827 ANDROID_CONTROL_AWB_MODE_AUTO,
828 ANDROID_CONTROL_AF_MODE_AUTO,
829 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300830 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
831 sceneModesOverride.data(),
832 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200833
834 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300835 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
836 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200837
838 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300839 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
840 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200841
842 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300843 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
844 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200845
846 /* JPEG static metadata. */
847 std::vector<int32_t> availableThumbnailSizes = {
848 0, 0,
849 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300850 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
851 availableThumbnailSizes.data(),
852 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200853
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100854 /*
855 * \todo Calculate the maximum JPEG buffer size by asking the encoder
856 * giving the maximum frame size required.
857 */
858 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
859
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200860 /* Sensor static metadata. */
Jacopo Mondicda41ff2020-12-30 17:18:51 +0100861 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100862 const Size &size =
Jacopo Mondi0ed05322020-12-23 18:34:34 +0100863 properties.get(properties::PixelArraySize);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100864 std::vector<int32_t> data{
865 static_cast<int32_t>(size.width),
866 static_cast<int32_t>(size.height),
867 };
868 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
869 data.data(), data.size());
870 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200871
Jacopo Mondicda41ff2020-12-30 17:18:51 +0100872 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100873 const Span<const Rectangle> &rects =
Jacopo Mondi0ed05322020-12-23 18:34:34 +0100874 properties.get(properties::PixelArrayActiveAreas);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100875 std::vector<int32_t> data{
876 static_cast<int32_t>(rects[0].x),
877 static_cast<int32_t>(rects[0].y),
878 static_cast<int32_t>(rects[0].width),
879 static_cast<int32_t>(rects[0].height),
880 };
881 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
882 data.data(), data.size());
883 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200884
885 int32_t sensitivityRange[] = {
886 32, 2400,
887 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300888 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
889 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200890
Jacopo Mondicb35ed22020-12-18 16:28:43 +0100891 /* Report the color filter arrangement if the camera reports it. */
892 if (properties.contains(properties::draft::ColorFilterArrangement)) {
893 uint8_t filterArr = properties.get(properties::draft::ColorFilterArrangement);
894 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
895 &filterArr, 1);
896 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200897
898 int64_t exposureTimeRange[] = {
899 100000, 200000000,
900 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300901 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
902 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200903
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200904 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200905
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200906 std::vector<int32_t> testPatterModes = {
907 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
908 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300909 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
910 testPatterModes.data(),
911 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200912
913 std::vector<float> physicalSize = {
914 2592, 1944,
915 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300916 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
917 physicalSize.data(),
918 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200919
920 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300921 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
922 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200923
924 /* Statistics static metadata. */
925 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300926 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
927 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200928
929 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300930 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
931 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200932
Jacopo Mondi2c618502020-10-08 16:47:36 +0200933 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100934 std::vector<uint8_t> data;
935 data.reserve(2);
Jacopo Mondi2c618502020-10-08 16:47:36 +0200936 const auto &infoMap = controlsInfo.find(&controls::draft::LensShadingMapMode);
937 if (infoMap != controlsInfo.end()) {
938 for (const auto &value : infoMap->second.values())
939 data.push_back(value.get<int32_t>());
940 } else {
941 data.push_back(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
942 }
943 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
944 data.data(), data.size());
945 }
946
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200947 /* Sync static metadata. */
948 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300949 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200950
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200951 /* Flash static metadata. */
952 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300953 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
954 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200955
956 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200957 std::vector<float> lensApertures = {
958 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200959 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300960 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
961 lensApertures.data(),
962 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200963
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200964 uint8_t lensFacing;
965 switch (facing_) {
966 default:
967 case CAMERA_FACING_FRONT:
968 lensFacing = ANDROID_LENS_FACING_FRONT;
969 break;
970 case CAMERA_FACING_BACK:
971 lensFacing = ANDROID_LENS_FACING_BACK;
972 break;
973 case CAMERA_FACING_EXTERNAL:
974 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
975 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100976 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300977 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200978
979 std::vector<float> lensFocalLenghts = {
980 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200981 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300982 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
983 lensFocalLenghts.data(),
984 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200985
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200986 std::vector<uint8_t> opticalStabilizations = {
987 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
988 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300989 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
990 opticalStabilizations.data(),
991 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200992
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200993 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300994 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
995 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200996
997 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300998 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
999 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001000
1001 /* Noise reduction modes. */
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001002 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001003 std::vector<uint8_t> data;
1004 data.reserve(5);
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001005 const auto &infoMap = controlsInfo.find(&controls::draft::NoiseReductionMode);
1006 if (infoMap != controlsInfo.end()) {
1007 for (const auto &value : infoMap->second.values())
1008 data.push_back(value.get<int32_t>());
1009 } else {
1010 data.push_back(ANDROID_NOISE_REDUCTION_MODE_OFF);
1011 }
1012 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
1013 data.data(), data.size());
1014 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001015
1016 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001017 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001018 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1019 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001020
Jacopo Mondibde7b982020-05-25 17:18:28 +02001021 std::vector<uint32_t> availableStreamConfigurations;
1022 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
1023 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +02001024 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +02001025 availableStreamConfigurations.push_back(entry.resolution.width);
1026 availableStreamConfigurations.push_back(entry.resolution.height);
1027 availableStreamConfigurations.push_back(
1028 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
1029 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001030 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1031 availableStreamConfigurations.data(),
1032 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001033
1034 std::vector<int64_t> availableStallDurations = {
1035 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
1036 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001037 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1038 availableStallDurations.data(),
1039 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001040
Jacopo Mondibde7b982020-05-25 17:18:28 +02001041 /* \todo Collect the minimum frame duration from the camera. */
1042 std::vector<int64_t> minFrameDurations;
1043 minFrameDurations.reserve(streamConfigurations_.size() * 4);
1044 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +02001045 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +02001046 minFrameDurations.push_back(entry.resolution.width);
1047 minFrameDurations.push_back(entry.resolution.height);
1048 minFrameDurations.push_back(33333333);
1049 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001050 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1051 minFrameDurations.data(),
1052 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001053
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001054 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001055 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001056
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001057 /* Info static metadata. */
1058 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001059 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
1060 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001061
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001062 /* Request static metadata. */
1063 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001064 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1065 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001066
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +02001067 {
1068 /* Default the value to 2 if not reported by the camera. */
1069 uint8_t maxPipelineDepth = 2;
1070 const auto &infoMap = controlsInfo.find(&controls::draft::PipelineDepth);
1071 if (infoMap != controlsInfo.end())
1072 maxPipelineDepth = infoMap->second.max().get<int32_t>();
1073 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
1074 &maxPipelineDepth, 1);
1075 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001076
Niklas Söderlunda2a6f952020-07-21 00:16:02 +02001077 /* LIMITED does not support reprocessing. */
1078 uint32_t maxNumInputStreams = 0;
1079 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1080 &maxNumInputStreams, 1);
1081
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001082 std::vector<uint8_t> availableCapabilities = {
1083 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
1084 };
Niklas Söderlund7876d632020-07-21 00:16:24 +02001085
1086 /* Report if camera supports RAW. */
Jacopo Mondieec6c542020-12-09 18:16:11 +01001087 bool rawStreamAvailable = false;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001088 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +02001089 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +02001090 if (cameraConfig && !cameraConfig->empty()) {
1091 const PixelFormatInfo &info =
1092 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
Niklas Söderlund35de31e2020-12-31 00:11:59 +01001093 /* Only advertise RAW support if RAW16 is possible. */
1094 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW &&
1095 info.bitsPerPixel == 16) {
Jacopo Mondieec6c542020-12-09 18:16:11 +01001096 rawStreamAvailable = true;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001097 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
Jacopo Mondieec6c542020-12-09 18:16:11 +01001098 }
Niklas Söderlund7876d632020-07-21 00:16:24 +02001099 }
1100
Jacopo Mondieec6c542020-12-09 18:16:11 +01001101 /* Number of { RAW, YUV, JPEG } supported output streams */
1102 int32_t numOutStreams[] = { rawStreamAvailable, 2, 1 };
1103 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
1104 &numOutStreams, 3);
1105
Laurent Pinchart39860092019-09-05 03:12:34 +03001106 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1107 availableCapabilities.data(),
1108 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001109
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001110 std::vector<int32_t> availableCharacteristicsKeys = {
1111 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
1112 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
1113 ANDROID_CONTROL_AE_AVAILABLE_MODES,
1114 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1115 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
1116 ANDROID_CONTROL_AE_COMPENSATION_STEP,
1117 ANDROID_CONTROL_AF_AVAILABLE_MODES,
1118 ANDROID_CONTROL_AVAILABLE_EFFECTS,
1119 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
1120 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
1121 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
1122 ANDROID_CONTROL_MAX_REGIONS,
1123 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
1124 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
1125 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
1126 ANDROID_CONTROL_AVAILABLE_MODES,
1127 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001128 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001129 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
1130 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
1131 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
1132 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
1133 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
1134 ANDROID_SENSOR_ORIENTATION,
1135 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
1136 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1137 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1138 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1139 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1140 ANDROID_SYNC_MAX_LATENCY,
1141 ANDROID_FLASH_INFO_AVAILABLE,
1142 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
1143 ANDROID_LENS_FACING,
1144 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1145 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1146 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1147 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1148 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
1149 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001150 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1151 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1152 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1153 ANDROID_SCALER_CROPPING_TYPE,
1154 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
1155 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1156 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Jacopo Mondieec6c542020-12-09 18:16:11 +01001157 ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +02001158 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001159 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1160 };
1161 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
1162 availableCharacteristicsKeys.data(),
1163 availableCharacteristicsKeys.size());
1164
1165 std::vector<int32_t> availableRequestKeys = {
1166 ANDROID_CONTROL_AE_MODE,
1167 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1168 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001169 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1170 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001171 ANDROID_CONTROL_AE_LOCK,
1172 ANDROID_CONTROL_AF_TRIGGER,
1173 ANDROID_CONTROL_AWB_MODE,
1174 ANDROID_CONTROL_AWB_LOCK,
1175 ANDROID_FLASH_MODE,
1176 ANDROID_STATISTICS_FACE_DETECT_MODE,
1177 ANDROID_NOISE_REDUCTION_MODE,
1178 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001179 ANDROID_LENS_APERTURE,
1180 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1181 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001182 ANDROID_CONTROL_CAPTURE_INTENT,
1183 };
1184 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
1185 availableRequestKeys.data(),
1186 availableRequestKeys.size());
1187
1188 std::vector<int32_t> availableResultKeys = {
1189 ANDROID_CONTROL_AE_STATE,
1190 ANDROID_CONTROL_AE_LOCK,
1191 ANDROID_CONTROL_AF_STATE,
1192 ANDROID_CONTROL_AWB_STATE,
1193 ANDROID_CONTROL_AWB_LOCK,
1194 ANDROID_LENS_STATE,
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001195 ANDROID_REQUEST_PIPELINE_DEPTH,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001196 ANDROID_SCALER_CROP_REGION,
1197 ANDROID_SENSOR_TIMESTAMP,
1198 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1199 ANDROID_SENSOR_EXPOSURE_TIME,
1200 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1201 ANDROID_STATISTICS_SCENE_FLICKER,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001202 ANDROID_JPEG_SIZE,
1203 ANDROID_JPEG_QUALITY,
1204 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001205 };
1206 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1207 availableResultKeys.data(),
1208 availableResultKeys.size());
1209
Laurent Pinchart39860092019-09-05 03:12:34 +03001210 if (!staticMetadata_->isValid()) {
1211 LOG(HAL, Error) << "Failed to construct static metadata";
1212 delete staticMetadata_;
1213 staticMetadata_ = nullptr;
1214 return nullptr;
1215 }
1216
1217 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001218}
1219
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001220CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001221{
Jacopo Mondi63703472019-09-04 16:18:22 +02001222 /*
1223 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001224 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001225 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001226 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001227 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001228 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001229 return nullptr;
1230 }
1231
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001232 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001233 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1234 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001235
1236 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001237 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1238 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001239
1240 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001241 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1242 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001243
1244 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001245 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1246 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001247
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001248 std::vector<int32_t> aeFpsTarget = {
1249 15, 30,
1250 };
1251 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1252 aeFpsTarget.data(),
1253 aeFpsTarget.size());
1254
1255 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1256 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1257 &aeAntibandingMode, 1);
1258
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001259 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001260 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1261 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001262
1263 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001264 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1265 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001266
1267 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001268 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1269 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001270
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001271 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001272 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1273 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001274
1275 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001276 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1277 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001278
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001279 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001280 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1281 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001282
1283 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001284 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1285 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001286
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001287 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1288 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1289
1290 float lensAperture = 2.53 / 100;
1291 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1292
1293 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1294 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1295 &opticalStabilization, 1);
1296
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001297 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001298 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1299 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001300
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001301 return requestTemplate;
1302}
1303
1304/*
1305 * Produce a metadata pack to be used as template for a capture request.
1306 */
1307const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1308{
1309 auto it = requestTemplates_.find(type);
1310 if (it != requestTemplates_.end())
1311 return it->second->get();
1312
1313 /* Use the capture intent matching the requested template type. */
1314 CameraMetadata *requestTemplate;
1315 uint8_t captureIntent;
1316 switch (type) {
1317 case CAMERA3_TEMPLATE_PREVIEW:
1318 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1319 break;
1320 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1321 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1322 break;
1323 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1324 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1325 break;
1326 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1327 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1328 break;
1329 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1330 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1331 break;
1332 case CAMERA3_TEMPLATE_MANUAL:
1333 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1334 break;
1335 default:
1336 LOG(HAL, Error) << "Invalid template request type: " << type;
1337 return nullptr;
1338 }
1339
1340 requestTemplate = requestTemplatePreview();
1341 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001342 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001343 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001344 return nullptr;
1345 }
1346
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001347 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1348 &captureIntent, 1);
1349
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001350 requestTemplates_[type] = requestTemplate;
1351 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001352}
1353
Hirokazu Hondac1ae9052020-10-28 18:50:23 +09001354PixelFormat CameraDevice::toPixelFormat(int format) const
Kieran Bingham43e3b802020-06-26 09:58:49 +01001355{
1356 /* Translate Android format code to libcamera pixel format. */
1357 auto it = formatsMap_.find(format);
1358 if (it == formatsMap_.end()) {
1359 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1360 << " not supported";
1361 return PixelFormat();
1362 }
1363
1364 return it->second;
1365}
1366
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001367/*
1368 * Inspect the stream_list to produce a list of StreamConfiguration to
1369 * be use to configure the Camera.
1370 */
1371int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1372{
Jacopo Mondi8fed6132020-12-04 15:26:47 +01001373 /* Before any configuration attempt, stop the camera if it's running. */
1374 if (running_) {
1375 worker_.stop();
1376 camera_->stop();
1377 running_ = false;
1378 }
1379
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001380 /*
1381 * Generate an empty configuration, and construct a StreamConfiguration
1382 * for each camera3_stream to add to it.
1383 */
1384 config_ = camera_->generateConfiguration();
1385 if (!config_) {
1386 LOG(HAL, Error) << "Failed to generate camera configuration";
1387 return -EINVAL;
1388 }
1389
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001390 /*
1391 * Clear and remove any existing configuration from previous calls, and
1392 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001393 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001394 */
1395 streams_.clear();
1396 streams_.reserve(stream_list->num_streams);
1397
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001398 std::vector<Camera3StreamConfig> streamConfigs;
1399 streamConfigs.reserve(stream_list->num_streams);
1400
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001401 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001402 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001403 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1404 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001405 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001406
Kieran Bingham43e3b802020-06-26 09:58:49 +01001407 PixelFormat format = toPixelFormat(stream->format);
1408
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001409 LOG(HAL, Info) << "Stream #" << i
1410 << ", direction: " << stream->stream_type
1411 << ", width: " << stream->width
1412 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001413 << ", format: " << utils::hex(stream->format)
1414 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001415
1416 if (!format.isValid())
1417 return -EINVAL;
1418
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001419 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001420 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1421 if (jpegStream) {
1422 LOG(HAL, Error)
1423 << "Multiple JPEG streams are not supported";
1424 return -EINVAL;
1425 }
1426
1427 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001428 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001429 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001430
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001431 Camera3StreamConfig streamConfig;
1432 streamConfig.streams = { { stream, CameraStream::Type::Direct } };
1433 streamConfig.config.size = size;
1434 streamConfig.config.pixelFormat = format;
1435 streamConfigs.push_back(std::move(streamConfig));
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001436 }
1437
Jacopo Mondic82f9442020-09-02 11:58:00 +02001438 /* Now handle the MJPEG streams, adding a new stream if required. */
1439 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001440 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001441 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001442
Jacopo Mondic82f9442020-09-02 11:58:00 +02001443 /* Search for a compatible stream in the non-JPEG ones. */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001444 for (size_t i = 0; i < streamConfigs.size(); ++i) {
1445 const auto &cfg = streamConfigs[i].config;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001446
1447 /*
1448 * \todo The PixelFormat must also be compatible with
1449 * the encoder.
1450 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001451 if (cfg.size.width != jpegStream->width ||
1452 cfg.size.height != jpegStream->height)
1453 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001454
Jacopo Mondic82f9442020-09-02 11:58:00 +02001455 LOG(HAL, Info)
1456 << "Android JPEG stream mapped to libcamera stream " << i;
1457
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001458 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001459 index = i;
1460 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001461 }
1462
1463 /*
1464 * Without a compatible match for JPEG encoding we must
1465 * introduce a new stream to satisfy the request requirements.
1466 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001467 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001468 /*
1469 * \todo The pixelFormat should be a 'best-fit' choice
1470 * and may require a validation cycle. This is not yet
1471 * handled, and should be considered as part of any
1472 * stream configuration reworks.
1473 */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001474 Camera3StreamConfig streamConfig;
1475 streamConfig.config.size.width = jpegStream->width;
1476 streamConfig.config.size.height = jpegStream->height;
1477 streamConfig.config.pixelFormat = formats::NV12;
1478 streamConfigs.push_back(std::move(streamConfig));
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001479
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001480 LOG(HAL, Info) << "Adding " << streamConfig.config.toString()
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001481 << " for MJPEG support";
1482
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001483 type = CameraStream::Type::Internal;
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001484 index = streamConfigs.size() - 1;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001485 }
1486
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001487 streamConfigs[index].streams.push_back({ jpegStream, type });
1488 }
1489
Hirokazu Honda26d90af2020-12-11 09:53:36 +00001490 sortCamera3StreamConfigs(streamConfigs, jpegStream);
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001491 for (const auto &streamConfig : streamConfigs) {
1492 config_->addConfiguration(streamConfig.config);
1493
1494 for (auto &stream : streamConfig.streams) {
1495 streams_.emplace_back(this, stream.type, stream.stream,
1496 config_->size() - 1);
1497 stream.stream->priv = static_cast<void *>(&streams_.back());
1498 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001499 }
1500
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001501 switch (config_->validate()) {
1502 case CameraConfiguration::Valid:
1503 break;
1504 case CameraConfiguration::Adjusted:
1505 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001506
1507 for (const StreamConfiguration &cfg : *config_)
1508 LOG(HAL, Info) << " - " << cfg.toString();
1509
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001510 config_.reset();
1511 return -EINVAL;
1512 case CameraConfiguration::Invalid:
1513 LOG(HAL, Info) << "Camera configuration invalid";
1514 config_.reset();
1515 return -EINVAL;
1516 }
1517
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001518 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001519 * Once the CameraConfiguration has been adjusted/validated
1520 * it can be applied to the camera.
1521 */
1522 int ret = camera_->configure(config_.get());
1523 if (ret) {
1524 LOG(HAL, Error) << "Failed to configure camera '"
1525 << camera_->id() << "'";
1526 return ret;
1527 }
1528
1529 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001530 * Configure the HAL CameraStream instances using the associated
1531 * StreamConfiguration and set the number of required buffers in
1532 * the Android camera3_stream_t.
1533 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001534 for (CameraStream &cameraStream : streams_) {
Kieran Binghamc7bcae02020-10-13 15:58:26 +01001535 ret = cameraStream.configure();
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001536 if (ret) {
1537 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001538 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001539 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001540 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001541
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001542 return 0;
1543}
1544
Kieran Bingham74ab4422020-07-01 13:25:38 +01001545FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1546{
1547 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001548 for (int i = 0; i < camera3buffer->numFds; i++) {
1549 /* Skip unused planes. */
1550 if (camera3buffer->data[i] == -1)
1551 break;
1552
Kieran Bingham74ab4422020-07-01 13:25:38 +01001553 FrameBuffer::Plane plane;
1554 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001555 if (!plane.fd.isValid()) {
1556 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1557 << camera3buffer->data[i] << ") "
1558 << " on plane " << i;
1559 return nullptr;
1560 }
1561
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001562 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1563 if (length == -1) {
1564 LOG(HAL, Error) << "Failed to query plane length";
1565 return nullptr;
1566 }
1567
1568 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001569 planes.push_back(std::move(plane));
1570 }
1571
1572 return new FrameBuffer(std::move(planes));
1573}
1574
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001575int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001576{
Jacopo Mondic5b732b2020-12-01 17:12:19 +01001577 if (!camera3Request) {
1578 LOG(HAL, Error) << "No capture request provided";
1579 return -EINVAL;
1580 }
1581
Kieran Bingham61f42962020-07-01 13:40:17 +01001582 if (!camera3Request->num_output_buffers) {
1583 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001584 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001585 }
1586
1587 /* Start the camera if that's the first request we handle. */
1588 if (!running_) {
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001589 worker_.start();
1590
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001591 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001592 if (ret) {
1593 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001594 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001595 }
1596
1597 running_ = true;
1598 }
1599
1600 /*
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001601 * Save the request descriptors for use at completion time.
1602 * The descriptor and the associated memory reserved here are freed
1603 * at request complete time.
1604 */
1605 Camera3RequestDescriptor *descriptor =
Jacopo Mondidd1cd532021-01-21 10:51:05 +01001606 new Camera3RequestDescriptor(camera_.get(), camera3Request);
Kieran Binghameac05422020-07-01 13:28:16 +01001607
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001608 LOG(HAL, Debug) << "Queueing Request to libcamera with "
Kieran Bingham37c18c22020-10-21 14:54:11 +01001609 << descriptor->numBuffers_ << " HAL streams";
1610 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001611 const camera3_stream_buffer_t *camera3Buffer = &descriptor->buffers_[i];
1612 camera3_stream *camera3Stream = camera3Buffer->stream;
1613 CameraStream *cameraStream = static_cast<CameraStream *>(camera3Stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001614
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001615 std::stringstream ss;
1616 ss << i << " - (" << camera3Stream->width << "x"
1617 << camera3Stream->height << ")"
1618 << "[" << utils::hex(camera3Stream->format) << "] -> "
1619 << "(" << cameraStream->configuration().size.toString() << ")["
1620 << cameraStream->configuration().pixelFormat.toString() << "]";
1621
Jacopo Mondide8304b2020-09-04 17:45:39 +02001622 /*
1623 * Inspect the camera stream type, create buffers opportunely
1624 * and add them to the Request if required.
1625 */
1626 FrameBuffer *buffer = nullptr;
1627 switch (cameraStream->type()) {
1628 case CameraStream::Type::Mapped:
1629 /*
1630 * Mapped streams don't need buffers added to the
1631 * Request.
1632 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001633 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001634 continue;
1635
Jacopo Mondide8304b2020-09-04 17:45:39 +02001636 case CameraStream::Type::Direct:
1637 /*
1638 * Create a libcamera buffer using the dmabuf
1639 * descriptors of the camera3Buffer for each stream and
1640 * associate it with the Camera3RequestDescriptor for
1641 * lifetime management only.
1642 */
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001643 buffer = createFrameBuffer(*camera3Buffer->buffer);
Kieran Bingham37c18c22020-10-21 14:54:11 +01001644 descriptor->frameBuffers_.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001645 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001646 break;
1647
1648 case CameraStream::Type::Internal:
1649 /*
1650 * Get the frame buffer from the CameraStream internal
1651 * buffer pool.
1652 *
1653 * The buffer has to be returned to the CameraStream
1654 * once it has been processed.
1655 */
1656 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001657 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001658 break;
1659 }
1660
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001661 if (!buffer) {
1662 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001663 delete descriptor;
1664 return -ENOMEM;
1665 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001666
Kieran Bingham37c18c22020-10-21 14:54:11 +01001667 descriptor->request_->addBuffer(cameraStream->stream(), buffer,
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001668 camera3Buffer->acquire_fence);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001669 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001670
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001671 /* Queue the request to the CameraWorker. */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001672 worker_.queueRequest(descriptor->request_.get());
Paul Elderc7532232020-09-23 19:05:41 +09001673
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001674 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001675}
1676
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001677void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001678{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001679 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001680 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001681 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001682 Camera3RequestDescriptor *descriptor =
1683 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001684
1685 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001686 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001687 << request->status();
1688 status = CAMERA3_BUFFER_STATUS_ERROR;
1689 }
1690
Kieran Binghamc09aee42020-07-28 14:01:19 +01001691 /*
1692 * \todo The timestamp used for the metadata is currently always taken
1693 * from the first buffer (which may be the first stream) in the Request.
1694 * It might be appropriate to return a 'correct' (as determined by
1695 * pipeline handlers) timestamp in the Request itself.
1696 */
Hirokazu Honda3a777d82020-10-28 17:57:26 +09001697 uint64_t timestamp = buffers.begin()->second->metadata().timestamp;
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001698 resultMetadata = getResultMetadata(descriptor, timestamp);
Kieran Binghamc09aee42020-07-28 14:01:19 +01001699
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001700 /* Handle any JPEG compression. */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001701 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001702 CameraStream *cameraStream =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001703 static_cast<CameraStream *>(descriptor->buffers_[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001704
Jacopo Mondi160bb092020-10-02 20:48:35 +02001705 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001706 continue;
1707
Jacopo Mondi216030a2020-10-03 11:36:41 +02001708 FrameBuffer *buffer = request->findBuffer(cameraStream->stream());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001709 if (!buffer) {
1710 LOG(HAL, Error) << "Failed to find a source stream buffer";
1711 continue;
1712 }
1713
1714 /*
1715 * \todo Buffer mapping and compression should be moved to a
1716 * separate thread.
1717 */
1718
Kieran Bingham37c18c22020-10-21 14:54:11 +01001719 MappedCamera3Buffer mapped(*descriptor->buffers_[i].buffer,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001720 PROT_READ | PROT_WRITE);
1721 if (!mapped.isValid()) {
1722 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1723 continue;
1724 }
1725
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02001726 int ret = cameraStream->process(*buffer, &mapped,
1727 resultMetadata.get());
1728 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001729 status = CAMERA3_BUFFER_STATUS_ERROR;
1730 continue;
1731 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02001732
1733 /*
1734 * Return the FrameBuffer to the CameraStream now that we're
1735 * done processing it.
1736 */
1737 if (cameraStream->type() == CameraStream::Type::Internal)
1738 cameraStream->putBuffer(buffer);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001739 }
1740
1741 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001742 camera3_capture_result_t captureResult = {};
Kieran Bingham37c18c22020-10-21 14:54:11 +01001743 captureResult.frame_number = descriptor->frameNumber_;
1744 captureResult.num_output_buffers = descriptor->numBuffers_;
1745 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
1746 descriptor->buffers_[i].acquire_fence = -1;
1747 descriptor->buffers_[i].release_fence = -1;
1748 descriptor->buffers_[i].status = status;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001749 }
1750 captureResult.output_buffers =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001751 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers_);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001752
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001753
Laurent Pinchart39860092019-09-05 03:12:34 +03001754 if (status == CAMERA3_BUFFER_STATUS_OK) {
Kieran Binghame1f9fdb2020-10-21 15:31:10 +01001755 notifyShutter(descriptor->frameNumber_, timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001756
1757 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001758 captureResult.result = resultMetadata->get();
1759 }
1760
1761 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1762 /* \todo Improve error handling. In case we notify an error
1763 * because the metadata generation fails, a shutter event has
1764 * already been notified for this frame number before the error
1765 * is here signalled. Make sure the error path plays well with
1766 * the camera stack state machine.
1767 */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001768 notifyError(descriptor->frameNumber_,
1769 descriptor->buffers_[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001770 }
1771
1772 callbacks_->process_capture_result(callbacks_, &captureResult);
1773
1774 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001775}
1776
Jacopo Mondia7b92772020-05-26 15:41:41 +02001777std::string CameraDevice::logPrefix() const
1778{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001779 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001780}
1781
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001782void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1783{
1784 camera3_notify_msg_t notify = {};
1785
1786 notify.type = CAMERA3_MSG_SHUTTER;
1787 notify.message.shutter.frame_number = frameNumber;
1788 notify.message.shutter.timestamp = timestamp;
1789
1790 callbacks_->notify(callbacks_, &notify);
1791}
1792
1793void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1794{
1795 camera3_notify_msg_t notify = {};
1796
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001797 /*
1798 * \todo Report and identify the stream number or configuration to
1799 * clarify the stream that failed.
1800 */
1801 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1802 << toPixelFormat(stream->format).toString() << ")";
1803
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001804 notify.type = CAMERA3_MSG_ERROR;
1805 notify.message.error.error_stream = stream;
1806 notify.message.error.frame_number = frameNumber;
1807 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1808
1809 callbacks_->notify(callbacks_, &notify);
1810}
1811
1812/*
1813 * Produce a set of fixed result metadata.
1814 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001815std::unique_ptr<CameraMetadata>
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001816CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor,
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001817 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001818{
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001819 const ControlList &metadata = descriptor->request_->metadata();
1820
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001821 /*
1822 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001823 * Currently: 18 entries, 62 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001824 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001825 std::unique_ptr<CameraMetadata> resultMetadata =
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001826 std::make_unique<CameraMetadata>(19, 63);
Laurent Pinchart39860092019-09-05 03:12:34 +03001827 if (!resultMetadata->isValid()) {
1828 LOG(HAL, Error) << "Failed to allocate static metadata";
1829 return nullptr;
1830 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001831
1832 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001833 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001834
1835 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001836 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001837
1838 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001839 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001840
1841 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001842 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001843
1844 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001845 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001846
1847 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001848 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001849
1850 int32_t sensorSizes[] = {
1851 0, 0, 2560, 1920,
1852 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001853 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001854
Laurent Pinchart39860092019-09-05 03:12:34 +03001855 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001856
1857 /* 33.3 msec */
1858 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001859 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1860 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001861
1862 /* 16.6 msec */
1863 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001864 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1865 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001866
1867 const uint8_t lens_shading_map_mode =
1868 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001869 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1870 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001871
1872 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001873 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1874 &scene_flicker, 1);
1875
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001876 /* Add metadata tags reported by libcamera. */
1877 if (metadata.contains(controls::draft::PipelineDepth)) {
1878 uint8_t pipeline_depth =
1879 metadata.get<int32_t>(controls::draft::PipelineDepth);
1880 resultMetadata->addEntry(ANDROID_REQUEST_PIPELINE_DEPTH,
1881 &pipeline_depth, 1);
1882 }
1883
Laurent Pinchart39860092019-09-05 03:12:34 +03001884 /*
1885 * Return the result metadata pack even is not valid: get() will return
1886 * nullptr.
1887 */
1888 if (!resultMetadata->isValid()) {
1889 LOG(HAL, Error) << "Failed to construct result metadata";
1890 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001891
1892 return resultMetadata;
1893}