blob: bbf016c323a7cea11fe9c94bec4f408b7c90dffb [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
Laurent Pinchart39860092019-09-05 03:12:34 +030025#include "camera_metadata.h"
Jacopo Mondi117588b2020-05-23 18:53:54 +020026#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020027
28using namespace libcamera;
29
Hirokazu Honda26d90af2020-12-11 09:53:36 +000030LOG_DECLARE_CATEGORY(HAL)
31
Jacopo Mondi117588b2020-05-23 18:53:54 +020032namespace {
33
34/*
35 * \var camera3Resolutions
36 * \brief The list of image resolutions defined as mandatory to be supported by
37 * the Android Camera3 specification
38 */
39const std::vector<Size> camera3Resolutions = {
40 { 320, 240 },
41 { 640, 480 },
42 { 1280, 720 },
43 { 1920, 1080 }
44};
45
46/*
47 * \struct Camera3Format
48 * \brief Data associated with an Android format identifier
49 * \var libcameraFormats List of libcamera pixel formats compatible with the
50 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020051 * \var name The human-readable representation of the Android format code
52 */
53struct Camera3Format {
54 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020055 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020056 const char *name;
57};
58
59/*
60 * \var camera3FormatsMap
61 * \brief Associate Android format code with ancillary data
62 */
63const std::map<int, const Camera3Format> camera3FormatsMap = {
64 {
65 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030066 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020067 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020068 "BLOB"
69 }
70 }, {
71 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030072 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020073 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020074 "YCbCr_420_888"
75 }
76 }, {
77 /*
78 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
79 * usage flag. For now, copy the YCbCr_420 configuration.
80 */
81 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030082 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020083 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020084 "IMPLEMENTATION_DEFINED"
85 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020086 }, {
87 HAL_PIXEL_FORMAT_RAW10, {
88 {
89 formats::SBGGR10_CSI2P,
90 formats::SGBRG10_CSI2P,
91 formats::SGRBG10_CSI2P,
92 formats::SRGGB10_CSI2P
93 },
94 false,
95 "RAW10"
96 }
97 }, {
98 HAL_PIXEL_FORMAT_RAW12, {
99 {
100 formats::SBGGR12_CSI2P,
101 formats::SGBRG12_CSI2P,
102 formats::SGRBG12_CSI2P,
103 formats::SRGGB12_CSI2P
104 },
105 false,
106 "RAW12"
107 }
108 }, {
109 HAL_PIXEL_FORMAT_RAW16, {
110 {
111 formats::SBGGR16,
112 formats::SGBRG16,
113 formats::SGRBG16,
114 formats::SRGGB16
115 },
116 false,
117 "RAW16"
118 }
119 }, {
120 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
121 {
122 formats::SBGGR10_IPU3,
123 formats::SGBRG10_IPU3,
124 formats::SGRBG10_IPU3,
125 formats::SRGGB10_IPU3
126 },
127 false,
128 "RAW_OPAQUE"
129 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200130 },
131};
132
Hirokazu Hondac2df7432020-12-11 09:53:34 +0000133/*
134 * \struct Camera3StreamConfig
135 * \brief Data to store StreamConfiguration associated with camera3_stream(s)
136 * \var streams List of the pairs of a stream requested by Android HAL client
137 * and CameraStream::Type associated with the stream
138 * \var config StreamConfiguration for streams
139 */
140struct Camera3StreamConfig {
141 struct Camera3Stream {
142 camera3_stream_t *stream;
143 CameraStream::Type type;
144 };
145
146 std::vector<Camera3Stream> streams;
147 StreamConfiguration config;
148};
149
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000150/*
151 * Reorder the configurations so that libcamera::Camera can accept them as much
152 * as possible. The sort rule is as follows.
153 * 1.) The configuration for NV12 request whose resolution is the largest.
154 * 2.) The configuration for JPEG request.
155 * 3.) Others. Larger resolutions and different formats are put earlier.
156 */
157void sortCamera3StreamConfigs(std::vector<Camera3StreamConfig> &unsortedConfigs,
158 const camera3_stream_t *jpegStream)
159{
160 const Camera3StreamConfig *jpegConfig = nullptr;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200161
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000162 std::map<PixelFormat, std::vector<const Camera3StreamConfig *>> formatToConfigs;
163 for (const auto &streamConfig : unsortedConfigs) {
164 if (jpegStream && !jpegConfig) {
165 const auto &streams = streamConfig.streams;
166 if (std::find_if(streams.begin(), streams.end(),
167 [jpegStream](const auto &stream) {
168 return stream.stream == jpegStream;
169 }) != streams.end()) {
170 jpegConfig = &streamConfig;
171 continue;
172 }
173 }
174 formatToConfigs[streamConfig.config.pixelFormat].push_back(&streamConfig);
175 }
176
177 if (jpegStream && !jpegConfig)
178 LOG(HAL, Fatal) << "No Camera3StreamConfig is found for JPEG";
179
180 for (auto &fmt : formatToConfigs) {
181 auto &streamConfigs = fmt.second;
182
183 /* Sorted by resolution. Smaller is put first. */
184 std::sort(streamConfigs.begin(), streamConfigs.end(),
185 [](const auto *streamConfigA, const auto *streamConfigB) {
186 const Size &sizeA = streamConfigA->config.size;
187 const Size &sizeB = streamConfigB->config.size;
188 return sizeA < sizeB;
189 });
190 }
191
192 std::vector<Camera3StreamConfig> sortedConfigs;
193 sortedConfigs.reserve(unsortedConfigs.size());
194
195 /*
196 * NV12 is the most prioritized format. Put the configuration with NV12
197 * and the largest resolution first.
198 */
199 const auto nv12It = formatToConfigs.find(formats::NV12);
200 if (nv12It != formatToConfigs.end()) {
201 auto &nv12Configs = nv12It->second;
Laurent Pinchartbd4894d2020-12-12 05:22:31 +0200202 const Camera3StreamConfig *nv12Largest = nv12Configs.back();
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000203
204 /*
205 * If JPEG will be created from NV12 and the size is larger than
206 * the largest NV12 configurations, then put the NV12
207 * configuration for JPEG first.
208 */
209 if (jpegConfig && jpegConfig->config.pixelFormat == formats::NV12) {
210 const Size &nv12SizeForJpeg = jpegConfig->config.size;
211 const Size &nv12LargestSize = nv12Largest->config.size;
212
213 if (nv12LargestSize < nv12SizeForJpeg) {
214 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
215 sortedConfigs.push_back(std::move(*jpegConfig));
216 jpegConfig = nullptr;
217 }
218 }
219
220 LOG(HAL, Debug) << "Insert " << nv12Largest->config.toString();
221 sortedConfigs.push_back(*nv12Largest);
222 nv12Configs.pop_back();
223
224 if (nv12Configs.empty())
225 formatToConfigs.erase(nv12It);
226 }
227
228 /* If the configuration for JPEG is there, then put it. */
229 if (jpegConfig) {
230 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
231 sortedConfigs.push_back(std::move(*jpegConfig));
232 jpegConfig = nullptr;
233 }
234
235 /*
236 * Put configurations with different formats and larger resolutions
237 * earlier.
238 */
239 while (!formatToConfigs.empty()) {
240 for (auto it = formatToConfigs.begin(); it != formatToConfigs.end();) {
241 auto &configs = it->second;
242 LOG(HAL, Debug) << "Insert " << configs.back()->config.toString();
243 sortedConfigs.push_back(*configs.back());
244 configs.pop_back();
245
246 if (configs.empty())
247 it = formatToConfigs.erase(it);
248 else
249 it++;
250 }
251 }
252
253 ASSERT(sortedConfigs.size() == unsortedConfigs.size());
254
255 unsortedConfigs = sortedConfigs;
256}
257
258} /* namespace */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200259
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100260MappedCamera3Buffer::MappedCamera3Buffer(const buffer_handle_t camera3buffer,
261 int flags)
262{
263 maps_.reserve(camera3buffer->numFds);
264 error_ = 0;
265
266 for (int i = 0; i < camera3buffer->numFds; i++) {
267 if (camera3buffer->data[i] == -1)
268 continue;
269
270 off_t length = lseek(camera3buffer->data[i], 0, SEEK_END);
271 if (length < 0) {
272 error_ = -errno;
273 LOG(HAL, Error) << "Failed to query plane length";
274 break;
275 }
276
277 void *address = mmap(nullptr, length, flags, MAP_SHARED,
278 camera3buffer->data[i], 0);
279 if (address == MAP_FAILED) {
280 error_ = -errno;
281 LOG(HAL, Error) << "Failed to mmap plane";
282 break;
283 }
284
285 maps_.emplace_back(static_cast<uint8_t *>(address),
286 static_cast<size_t>(length));
287 }
288}
289
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200290/*
291 * \struct Camera3RequestDescriptor
292 *
293 * A utility structure that groups information about a capture request to be
294 * later re-used at request complete time to notify the framework.
295 */
296
297CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200298 Camera *camera, unsigned int frameNumber, unsigned int numBuffers)
Kieran Bingham37c18c22020-10-21 14:54:11 +0100299 : frameNumber_(frameNumber), numBuffers_(numBuffers)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200300{
Kieran Bingham37c18c22020-10-21 14:54:11 +0100301 buffers_ = new camera3_stream_buffer_t[numBuffers];
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200302
303 /*
304 * FrameBuffer instances created by wrapping a camera3 provided dmabuf
305 * are emplaced in this vector of unique_ptr<> for lifetime management.
306 */
Kieran Bingham37c18c22020-10-21 14:54:11 +0100307 frameBuffers_.reserve(numBuffers);
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200308
309 /*
310 * Create the libcamera::Request unique_ptr<> to tie its lifetime
311 * to the descriptor's one. Set the descriptor's address as the
312 * request's cookie to retrieve it at completion time.
313 */
Kieran Bingham37c18c22020-10-21 14:54:11 +0100314 request_ = std::make_unique<CaptureRequest>(camera,
315 reinterpret_cast<uint64_t>(this));
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200316}
317
318CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
319{
Kieran Bingham37c18c22020-10-21 14:54:11 +0100320 delete[] buffers_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200321}
322
323/*
324 * \class CameraDevice
325 *
326 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200327 * the camera3_device_t interface, bridging calls received from the Android
328 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200329 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200330 * The class translates parameters and operations from the Camera HALv3 API to
331 * the libcamera API to provide static information for a Camera, create request
332 * templates for it, process capture requests and then deliver capture results
333 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200334 */
335
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300336CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000337 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200338 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200339{
340 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100341
342 /*
343 * \todo Determine a more accurate value for this during
344 * streamConfiguration.
345 */
346 maxJpegBufferSize_ = 13 << 20; /* 13631488 from USB HAL */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200347}
348
349CameraDevice::~CameraDevice()
350{
351 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300352 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200353
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200354 for (auto &it : requestTemplates_)
355 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200356}
357
Umang Jainf8e28132020-08-21 14:46:08 +0000358std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
359 const std::shared_ptr<Camera> &cam)
360{
361 CameraDevice *camera = new CameraDevice(id, cam);
362 return std::shared_ptr<CameraDevice>(camera);
363}
364
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200365/*
366 * Initialize the camera static information.
367 * This method is called before the camera device is opened.
368 */
369int CameraDevice::initialize()
370{
371 /* Initialize orientation and facing side of the camera. */
372 const ControlList &properties = camera_->properties();
373
374 if (properties.contains(properties::Location)) {
375 int32_t location = properties.get(properties::Location);
376 switch (location) {
377 case properties::CameraLocationFront:
378 facing_ = CAMERA_FACING_FRONT;
379 break;
380 case properties::CameraLocationBack:
381 facing_ = CAMERA_FACING_BACK;
382 break;
383 case properties::CameraLocationExternal:
384 facing_ = CAMERA_FACING_EXTERNAL;
385 break;
386 }
387 }
388
389 /*
Umang Jaine9176552020-09-09 16:17:54 +0530390 * The Android orientation metadata specifies its rotation correction
391 * value in clockwise direction whereas libcamera specifies the
392 * rotation property in anticlockwise direction. Read the libcamera's
393 * rotation property (anticlockwise) and compute the corresponding
394 * value for clockwise direction as required by the Android orientation
395 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200396 */
Umang Jaine9176552020-09-09 16:17:54 +0530397 if (properties.contains(properties::Rotation)) {
398 int rotation = properties.get(properties::Rotation);
399 orientation_ = (360 - rotation) % 360;
400 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200401
Jacopo Mondi117588b2020-05-23 18:53:54 +0200402 int ret = camera_->acquire();
403 if (ret) {
404 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
405 return ret;
406 }
407
408 ret = initializeStreamConfigurations();
409 camera_->release();
410 return ret;
411}
412
Jacopo Mondibfee6312020-09-01 17:42:13 +0200413std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
414 const PixelFormat &pixelFormat,
415 const std::vector<Size> &resolutions)
416{
417 std::vector<Size> supportedResolutions;
418
419 StreamConfiguration &cfg = cameraConfig->at(0);
420 for (const Size &res : resolutions) {
421 cfg.pixelFormat = pixelFormat;
422 cfg.size = res;
423
424 CameraConfiguration::Status status = cameraConfig->validate();
425 if (status != CameraConfiguration::Valid) {
426 LOG(HAL, Debug) << cfg.toString() << " not supported";
427 continue;
428 }
429
430 LOG(HAL, Debug) << cfg.toString() << " supported";
431
432 supportedResolutions.push_back(res);
433 }
434
435 return supportedResolutions;
436}
437
Jacopo Mondi49610332020-09-01 18:11:34 +0200438std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
439{
440 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200441 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200442 StreamConfiguration &cfg = cameraConfig->at(0);
443 const StreamFormats &formats = cfg.formats();
444 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
445
446 return supportedResolutions;
447}
448
Jacopo Mondi117588b2020-05-23 18:53:54 +0200449/*
450 * Initialize the format conversion map to translate from Android format
451 * identifier to libcamera pixel formats and fill in the list of supported
452 * stream configurations to be reported to the Android camera framework through
453 * the static stream configuration metadata.
454 */
455int CameraDevice::initializeStreamConfigurations()
456{
457 /*
458 * Get the maximum output resolutions
459 * \todo Get this from the camera properties once defined
460 */
461 std::unique_ptr<CameraConfiguration> cameraConfig =
462 camera_->generateConfiguration({ StillCapture });
463 if (!cameraConfig) {
464 LOG(HAL, Error) << "Failed to get maximum resolution";
465 return -EINVAL;
466 }
467 StreamConfiguration &cfg = cameraConfig->at(0);
468
469 /*
470 * \todo JPEG - Adjust the maximum available resolution by taking the
471 * JPEG encoder requirements into account (alignment and aspect ratio).
472 */
473 const Size maxRes = cfg.size;
474 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
475
476 /*
477 * Build the list of supported image resolutions.
478 *
479 * The resolutions listed in camera3Resolution are mandatory to be
480 * supported, up to the camera maximum resolution.
481 *
482 * Augment the list by adding resolutions calculated from the camera
483 * maximum one.
484 */
485 std::vector<Size> cameraResolutions;
486 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
487 std::back_inserter(cameraResolutions),
488 [&](const Size &res) { return res < maxRes; });
489
490 /*
491 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
492 * resolution.
493 */
494 for (unsigned int divider = 2;; divider <<= 1) {
495 Size derivedSize{
496 maxRes.width / divider,
497 maxRes.height / divider,
498 };
499
500 if (derivedSize.width < 320 ||
501 derivedSize.height < 240)
502 break;
503
504 cameraResolutions.push_back(derivedSize);
505 }
506 cameraResolutions.push_back(maxRes);
507
508 /* Remove duplicated entries from the list of supported resolutions. */
509 std::sort(cameraResolutions.begin(), cameraResolutions.end());
510 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
511 cameraResolutions.erase(last, cameraResolutions.end());
512
513 /*
514 * Build the list of supported camera formats.
515 *
516 * To each Android format a list of compatible libcamera formats is
517 * associated. The first libcamera format that tests successful is added
518 * to the format translation map used when configuring the streams.
519 * It is then tested against the list of supported camera resolutions to
520 * build the stream configuration map reported through the camera static
521 * metadata.
522 */
523 for (const auto &format : camera3FormatsMap) {
524 int androidFormat = format.first;
525 const Camera3Format &camera3Format = format.second;
526 const std::vector<PixelFormat> &libcameraFormats =
527 camera3Format.libcameraFormats;
528
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200529 LOG(HAL, Debug) << "Trying to map Android format "
530 << camera3Format.name;
531
Jacopo Mondi117588b2020-05-23 18:53:54 +0200532 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200533 * JPEG is always supported, either produced directly by the
534 * camera, or encoded in the HAL.
535 */
536 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
537 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200538 LOG(HAL, Debug) << "Mapped Android format "
539 << camera3Format.name << " to "
540 << formats::MJPEG.toString()
541 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200542 continue;
543 }
544
545 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200546 * Test the libcamera formats that can produce images
547 * compatible with the format defined by Android.
548 */
549 PixelFormat mappedFormat;
550 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200551
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200552 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
553
Jacopo Mondi117588b2020-05-23 18:53:54 +0200554 /*
555 * The stream configuration size can be adjusted,
556 * not the pixel format.
557 *
558 * \todo This could be simplified once all pipeline
559 * handlers will report the StreamFormats list of
560 * supported formats.
561 */
562 cfg.pixelFormat = pixelFormat;
563
564 CameraConfiguration::Status status = cameraConfig->validate();
565 if (status != CameraConfiguration::Invalid &&
566 cfg.pixelFormat == pixelFormat) {
567 mappedFormat = pixelFormat;
568 break;
569 }
570 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200571
572 if (!mappedFormat.isValid()) {
573 /* If the format is not mandatory, skip it. */
574 if (!camera3Format.mandatory)
575 continue;
576
577 LOG(HAL, Error)
578 << "Failed to map mandatory Android format "
579 << camera3Format.name << " ("
580 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200581 return -EINVAL;
582 }
583
584 /*
585 * Record the mapping and then proceed to generate the
586 * stream configurations map, by testing the image resolutions.
587 */
588 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200589 LOG(HAL, Debug) << "Mapped Android format "
590 << camera3Format.name << " to "
591 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200592
Jacopo Mondi49610332020-09-01 18:11:34 +0200593 std::vector<Size> resolutions;
594 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
595 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
596 resolutions = getRawResolutions(mappedFormat);
597 else
598 resolutions = getYUVResolutions(cameraConfig.get(),
599 mappedFormat,
600 cameraResolutions);
601
Jacopo Mondibfee6312020-09-01 17:42:13 +0200602 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200603 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200604
605 /*
606 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
607 * from which JPEG is produced, add an entry for
608 * the JPEG stream.
609 *
610 * \todo Wire the JPEG encoder to query the supported
611 * sizes provided a list of formats it can encode.
612 *
613 * \todo Support JPEG streams produced by the Camera
614 * natively.
615 */
616 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888)
617 streamConfigurations_.push_back(
618 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200619 }
620 }
621
622 LOG(HAL, Debug) << "Collected stream configuration map: ";
623 for (const auto &entry : streamConfigurations_)
624 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200625 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200626
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200627 return 0;
628}
629
630/*
631 * Open a camera device. The static information on the camera shall have been
632 * initialized with a call to CameraDevice::initialize().
633 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200634int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200635{
636 int ret = camera_->acquire();
637 if (ret) {
638 LOG(HAL, Error) << "Failed to acquire the camera";
639 return ret;
640 }
641
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200642 /* Initialize the hw_device_t in the instance camera3_module_t. */
643 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
644 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
645 camera3Device_.common.module = (hw_module_t *)hardwareModule;
646 camera3Device_.common.close = hal_dev_close;
647
648 /*
649 * The camera device operations. These actually implement
650 * the Android Camera HALv3 interface.
651 */
652 camera3Device_.ops = &hal_dev_ops;
653 camera3Device_.priv = this;
654
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200655 return 0;
656}
657
658void CameraDevice::close()
659{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200660 streams_.clear();
661
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200662 worker_.stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200663 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200664 camera_->release();
665
666 running_ = false;
667}
668
669void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
670{
671 callbacks_ = callbacks;
672}
673
Jacopo Mondia80d3812020-05-26 12:31:35 +0200674std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
675{
676 /*
677 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondieec6c542020-12-09 18:16:11 +0100678 * Currently: 53 entries, 714 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200679 */
Jacopo Mondieec6c542020-12-09 18:16:11 +0100680 uint32_t numEntries = 53;
681 uint32_t byteSize = 714;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200682
683 /*
684 * Calculate space occupation in bytes for dynamically built metadata
685 * entries.
686 *
687 * Each stream configuration entry requires 52 bytes:
688 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200689 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
690 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200691 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200692
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300693 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200694}
695
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200696/*
697 * Return static information for the camera.
698 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200699const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200700{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200701 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300702 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200703
704 /*
705 * The here reported metadata are enough to implement a basic capture
706 * example application, but a real camera implementation will require
707 * more.
708 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200709 uint32_t numEntries;
710 uint32_t byteSize;
711 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
712 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300713 if (!staticMetadata_->isValid()) {
714 LOG(HAL, Error) << "Failed to allocate static metadata";
715 delete staticMetadata_;
716 staticMetadata_ = nullptr;
717 return nullptr;
718 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200719
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200720 const ControlInfoMap &controlsInfo = camera_->controls();
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100721 const ControlList &properties = camera_->properties();
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200722
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200723 /* Color correction static metadata. */
Jacopo Mondi63336862020-10-08 16:18:26 +0200724 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100725 std::vector<uint8_t> data;
726 data.reserve(3);
Jacopo Mondi63336862020-10-08 16:18:26 +0200727 const auto &infoMap = controlsInfo.find(&controls::draft::ColorCorrectionAberrationMode);
728 if (infoMap != controlsInfo.end()) {
729 for (const auto &value : infoMap->second.values())
730 data.push_back(value.get<int32_t>());
731 } else {
732 data.push_back(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
733 }
734 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
735 data.data(), data.size());
736 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200737
738 /* Control static metadata. */
739 std::vector<uint8_t> aeAvailableAntiBandingModes = {
740 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
741 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
742 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
743 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
744 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300745 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
746 aeAvailableAntiBandingModes.data(),
747 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200748
749 std::vector<uint8_t> aeAvailableModes = {
750 ANDROID_CONTROL_AE_MODE_ON,
751 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300752 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
753 aeAvailableModes.data(),
754 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200755
756 std::vector<int32_t> availableAeFpsTarget = {
757 15, 30,
758 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300759 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
760 availableAeFpsTarget.data(),
761 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200762
763 std::vector<int32_t> aeCompensationRange = {
764 0, 0,
765 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300766 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
767 aeCompensationRange.data(),
768 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200769
770 const camera_metadata_rational_t aeCompensationStep[] = {
771 { 0, 1 }
772 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300773 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
774 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200775
776 std::vector<uint8_t> availableAfModes = {
777 ANDROID_CONTROL_AF_MODE_OFF,
778 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300779 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
780 availableAfModes.data(),
781 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200782
783 std::vector<uint8_t> availableEffects = {
784 ANDROID_CONTROL_EFFECT_MODE_OFF,
785 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300786 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
787 availableEffects.data(),
788 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200789
790 std::vector<uint8_t> availableSceneModes = {
791 ANDROID_CONTROL_SCENE_MODE_DISABLED,
792 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300793 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
794 availableSceneModes.data(),
795 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200796
797 std::vector<uint8_t> availableStabilizationModes = {
798 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
799 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300800 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
801 availableStabilizationModes.data(),
802 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200803
804 std::vector<uint8_t> availableAwbModes = {
805 ANDROID_CONTROL_AWB_MODE_OFF,
806 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300807 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
808 availableAwbModes.data(),
809 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200810
811 std::vector<int32_t> availableMaxRegions = {
812 0, 0, 0,
813 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300814 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
815 availableMaxRegions.data(),
816 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200817
818 std::vector<uint8_t> sceneModesOverride = {
819 ANDROID_CONTROL_AE_MODE_ON,
820 ANDROID_CONTROL_AWB_MODE_AUTO,
821 ANDROID_CONTROL_AF_MODE_AUTO,
822 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300823 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
824 sceneModesOverride.data(),
825 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200826
827 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300828 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
829 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200830
831 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300832 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
833 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200834
835 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300836 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
837 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200838
839 /* JPEG static metadata. */
840 std::vector<int32_t> availableThumbnailSizes = {
841 0, 0,
842 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300843 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
844 availableThumbnailSizes.data(),
845 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200846
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100847 /*
848 * \todo Calculate the maximum JPEG buffer size by asking the encoder
849 * giving the maximum frame size required.
850 */
851 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
852
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200853 /* Sensor static metadata. */
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100854 if (properties.contains(properties::PixelArraySize)) {
855 const Size &size =
856 properties.get<Size>(properties::PixelArraySize);
857 std::vector<int32_t> data{
858 static_cast<int32_t>(size.width),
859 static_cast<int32_t>(size.height),
860 };
861 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
862 data.data(), data.size());
Jacopo Mondi008f2a52020-12-09 18:35:42 +0100863 } else {
864 /*
865 * \todo Drop the default once the ov5670 and ov13858 drivers
866 * are updated to report the pixel array size.
867 */
868 int32_t data[] = { 2592, 1944 };
869 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
870 data, 2);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100871 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200872
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100873 if (properties.contains(properties::PixelArrayActiveAreas)) {
874 const Span<const Rectangle> &rects =
875 properties.get<Span<const Rectangle>>(properties::PixelArrayActiveAreas);
876 std::vector<int32_t> data{
877 static_cast<int32_t>(rects[0].x),
878 static_cast<int32_t>(rects[0].y),
879 static_cast<int32_t>(rects[0].width),
880 static_cast<int32_t>(rects[0].height),
881 };
882 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
883 data.data(), data.size());
Jacopo Mondi008f2a52020-12-09 18:35:42 +0100884 } else {
885 /*
886 * \todo Drop the default once the ov5670 and ov13858 drivers
887 * are updated to report the pixel array size.
888 */
889 int32_t data[] = { 0, 0, 2560, 1920 };
890 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
891 data, 4);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100892 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200893
894 int32_t sensitivityRange[] = {
895 32, 2400,
896 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300897 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
898 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200899
Jacopo Mondicb35ed22020-12-18 16:28:43 +0100900 /* Report the color filter arrangement if the camera reports it. */
901 if (properties.contains(properties::draft::ColorFilterArrangement)) {
902 uint8_t filterArr = properties.get(properties::draft::ColorFilterArrangement);
903 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
904 &filterArr, 1);
905 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200906
907 int64_t exposureTimeRange[] = {
908 100000, 200000000,
909 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300910 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
911 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200912
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200913 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200914
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200915 std::vector<int32_t> testPatterModes = {
916 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
917 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300918 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
919 testPatterModes.data(),
920 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200921
922 std::vector<float> physicalSize = {
923 2592, 1944,
924 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300925 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
926 physicalSize.data(),
927 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200928
929 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300930 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
931 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200932
933 /* Statistics static metadata. */
934 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300935 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
936 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200937
938 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300939 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
940 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200941
Jacopo Mondi2c618502020-10-08 16:47:36 +0200942 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100943 std::vector<uint8_t> data;
944 data.reserve(2);
Jacopo Mondi2c618502020-10-08 16:47:36 +0200945 const auto &infoMap = controlsInfo.find(&controls::draft::LensShadingMapMode);
946 if (infoMap != controlsInfo.end()) {
947 for (const auto &value : infoMap->second.values())
948 data.push_back(value.get<int32_t>());
949 } else {
950 data.push_back(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
951 }
952 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
953 data.data(), data.size());
954 }
955
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200956 /* Sync static metadata. */
957 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300958 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200959
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200960 /* Flash static metadata. */
961 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300962 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
963 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200964
965 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200966 std::vector<float> lensApertures = {
967 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200968 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300969 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
970 lensApertures.data(),
971 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200972
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200973 uint8_t lensFacing;
974 switch (facing_) {
975 default:
976 case CAMERA_FACING_FRONT:
977 lensFacing = ANDROID_LENS_FACING_FRONT;
978 break;
979 case CAMERA_FACING_BACK:
980 lensFacing = ANDROID_LENS_FACING_BACK;
981 break;
982 case CAMERA_FACING_EXTERNAL:
983 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
984 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100985 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300986 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200987
988 std::vector<float> lensFocalLenghts = {
989 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200990 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300991 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
992 lensFocalLenghts.data(),
993 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200994
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200995 std::vector<uint8_t> opticalStabilizations = {
996 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
997 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300998 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
999 opticalStabilizations.data(),
1000 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001001
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001002 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001003 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1004 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001005
1006 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001007 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1008 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001009
1010 /* Noise reduction modes. */
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001011 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001012 std::vector<uint8_t> data;
1013 data.reserve(5);
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001014 const auto &infoMap = controlsInfo.find(&controls::draft::NoiseReductionMode);
1015 if (infoMap != controlsInfo.end()) {
1016 for (const auto &value : infoMap->second.values())
1017 data.push_back(value.get<int32_t>());
1018 } else {
1019 data.push_back(ANDROID_NOISE_REDUCTION_MODE_OFF);
1020 }
1021 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
1022 data.data(), data.size());
1023 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001024
1025 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001026 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001027 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1028 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001029
Jacopo Mondibde7b982020-05-25 17:18:28 +02001030 std::vector<uint32_t> availableStreamConfigurations;
1031 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
1032 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +02001033 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +02001034 availableStreamConfigurations.push_back(entry.resolution.width);
1035 availableStreamConfigurations.push_back(entry.resolution.height);
1036 availableStreamConfigurations.push_back(
1037 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
1038 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001039 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1040 availableStreamConfigurations.data(),
1041 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001042
1043 std::vector<int64_t> availableStallDurations = {
1044 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
1045 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001046 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1047 availableStallDurations.data(),
1048 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001049
Jacopo Mondibde7b982020-05-25 17:18:28 +02001050 /* \todo Collect the minimum frame duration from the camera. */
1051 std::vector<int64_t> minFrameDurations;
1052 minFrameDurations.reserve(streamConfigurations_.size() * 4);
1053 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +02001054 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +02001055 minFrameDurations.push_back(entry.resolution.width);
1056 minFrameDurations.push_back(entry.resolution.height);
1057 minFrameDurations.push_back(33333333);
1058 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001059 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1060 minFrameDurations.data(),
1061 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001062
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001063 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001064 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001065
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001066 /* Info static metadata. */
1067 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001068 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
1069 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001070
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001071 /* Request static metadata. */
1072 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001073 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1074 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001075
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +02001076 {
1077 /* Default the value to 2 if not reported by the camera. */
1078 uint8_t maxPipelineDepth = 2;
1079 const auto &infoMap = controlsInfo.find(&controls::draft::PipelineDepth);
1080 if (infoMap != controlsInfo.end())
1081 maxPipelineDepth = infoMap->second.max().get<int32_t>();
1082 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
1083 &maxPipelineDepth, 1);
1084 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001085
Niklas Söderlunda2a6f952020-07-21 00:16:02 +02001086 /* LIMITED does not support reprocessing. */
1087 uint32_t maxNumInputStreams = 0;
1088 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1089 &maxNumInputStreams, 1);
1090
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001091 std::vector<uint8_t> availableCapabilities = {
1092 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
1093 };
Niklas Söderlund7876d632020-07-21 00:16:24 +02001094
1095 /* Report if camera supports RAW. */
Jacopo Mondieec6c542020-12-09 18:16:11 +01001096 bool rawStreamAvailable = false;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001097 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +02001098 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +02001099 if (cameraConfig && !cameraConfig->empty()) {
1100 const PixelFormatInfo &info =
1101 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
Jacopo Mondieec6c542020-12-09 18:16:11 +01001102 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) {
1103 rawStreamAvailable = true;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001104 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
Jacopo Mondieec6c542020-12-09 18:16:11 +01001105 }
Niklas Söderlund7876d632020-07-21 00:16:24 +02001106 }
1107
Jacopo Mondieec6c542020-12-09 18:16:11 +01001108 /* Number of { RAW, YUV, JPEG } supported output streams */
1109 int32_t numOutStreams[] = { rawStreamAvailable, 2, 1 };
1110 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
1111 &numOutStreams, 3);
1112
Laurent Pinchart39860092019-09-05 03:12:34 +03001113 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1114 availableCapabilities.data(),
1115 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001116
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001117 std::vector<int32_t> availableCharacteristicsKeys = {
1118 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
1119 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
1120 ANDROID_CONTROL_AE_AVAILABLE_MODES,
1121 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1122 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
1123 ANDROID_CONTROL_AE_COMPENSATION_STEP,
1124 ANDROID_CONTROL_AF_AVAILABLE_MODES,
1125 ANDROID_CONTROL_AVAILABLE_EFFECTS,
1126 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
1127 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
1128 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
1129 ANDROID_CONTROL_MAX_REGIONS,
1130 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
1131 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
1132 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
1133 ANDROID_CONTROL_AVAILABLE_MODES,
1134 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001135 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001136 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
1137 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
1138 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
1139 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
1140 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
1141 ANDROID_SENSOR_ORIENTATION,
1142 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
1143 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1144 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1145 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1146 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1147 ANDROID_SYNC_MAX_LATENCY,
1148 ANDROID_FLASH_INFO_AVAILABLE,
1149 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
1150 ANDROID_LENS_FACING,
1151 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1152 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1153 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1154 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1155 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
1156 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001157 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1158 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1159 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1160 ANDROID_SCALER_CROPPING_TYPE,
1161 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
1162 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1163 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Jacopo Mondieec6c542020-12-09 18:16:11 +01001164 ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +02001165 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001166 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1167 };
1168 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
1169 availableCharacteristicsKeys.data(),
1170 availableCharacteristicsKeys.size());
1171
1172 std::vector<int32_t> availableRequestKeys = {
1173 ANDROID_CONTROL_AE_MODE,
1174 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1175 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001176 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1177 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001178 ANDROID_CONTROL_AE_LOCK,
1179 ANDROID_CONTROL_AF_TRIGGER,
1180 ANDROID_CONTROL_AWB_MODE,
1181 ANDROID_CONTROL_AWB_LOCK,
1182 ANDROID_FLASH_MODE,
1183 ANDROID_STATISTICS_FACE_DETECT_MODE,
1184 ANDROID_NOISE_REDUCTION_MODE,
1185 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001186 ANDROID_LENS_APERTURE,
1187 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1188 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001189 ANDROID_CONTROL_CAPTURE_INTENT,
1190 };
1191 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
1192 availableRequestKeys.data(),
1193 availableRequestKeys.size());
1194
1195 std::vector<int32_t> availableResultKeys = {
1196 ANDROID_CONTROL_AE_STATE,
1197 ANDROID_CONTROL_AE_LOCK,
1198 ANDROID_CONTROL_AF_STATE,
1199 ANDROID_CONTROL_AWB_STATE,
1200 ANDROID_CONTROL_AWB_LOCK,
1201 ANDROID_LENS_STATE,
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001202 ANDROID_REQUEST_PIPELINE_DEPTH,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001203 ANDROID_SCALER_CROP_REGION,
1204 ANDROID_SENSOR_TIMESTAMP,
1205 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1206 ANDROID_SENSOR_EXPOSURE_TIME,
1207 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1208 ANDROID_STATISTICS_SCENE_FLICKER,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001209 ANDROID_JPEG_SIZE,
1210 ANDROID_JPEG_QUALITY,
1211 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001212 };
1213 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1214 availableResultKeys.data(),
1215 availableResultKeys.size());
1216
Laurent Pinchart39860092019-09-05 03:12:34 +03001217 if (!staticMetadata_->isValid()) {
1218 LOG(HAL, Error) << "Failed to construct static metadata";
1219 delete staticMetadata_;
1220 staticMetadata_ = nullptr;
1221 return nullptr;
1222 }
1223
1224 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001225}
1226
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001227CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001228{
Jacopo Mondi63703472019-09-04 16:18:22 +02001229 /*
1230 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001231 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001232 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001233 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001234 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001235 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001236 return nullptr;
1237 }
1238
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001239 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001240 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1241 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001242
1243 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001244 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1245 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001246
1247 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001248 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1249 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001250
1251 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001252 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1253 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001254
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001255 std::vector<int32_t> aeFpsTarget = {
1256 15, 30,
1257 };
1258 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1259 aeFpsTarget.data(),
1260 aeFpsTarget.size());
1261
1262 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1263 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1264 &aeAntibandingMode, 1);
1265
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001266 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001267 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1268 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001269
1270 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001271 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1272 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001273
1274 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001275 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1276 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001277
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001278 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001279 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1280 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001281
1282 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001283 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1284 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001285
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001286 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001287 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1288 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001289
1290 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001291 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1292 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001293
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001294 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1295 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1296
1297 float lensAperture = 2.53 / 100;
1298 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1299
1300 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1301 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1302 &opticalStabilization, 1);
1303
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001304 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001305 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1306 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001307
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001308 return requestTemplate;
1309}
1310
1311/*
1312 * Produce a metadata pack to be used as template for a capture request.
1313 */
1314const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1315{
1316 auto it = requestTemplates_.find(type);
1317 if (it != requestTemplates_.end())
1318 return it->second->get();
1319
1320 /* Use the capture intent matching the requested template type. */
1321 CameraMetadata *requestTemplate;
1322 uint8_t captureIntent;
1323 switch (type) {
1324 case CAMERA3_TEMPLATE_PREVIEW:
1325 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1326 break;
1327 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1328 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1329 break;
1330 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1331 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1332 break;
1333 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1334 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1335 break;
1336 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1337 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1338 break;
1339 case CAMERA3_TEMPLATE_MANUAL:
1340 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1341 break;
1342 default:
1343 LOG(HAL, Error) << "Invalid template request type: " << type;
1344 return nullptr;
1345 }
1346
1347 requestTemplate = requestTemplatePreview();
1348 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001349 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001350 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001351 return nullptr;
1352 }
1353
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001354 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1355 &captureIntent, 1);
1356
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001357 requestTemplates_[type] = requestTemplate;
1358 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001359}
1360
Hirokazu Hondac1ae9052020-10-28 18:50:23 +09001361PixelFormat CameraDevice::toPixelFormat(int format) const
Kieran Bingham43e3b802020-06-26 09:58:49 +01001362{
1363 /* Translate Android format code to libcamera pixel format. */
1364 auto it = formatsMap_.find(format);
1365 if (it == formatsMap_.end()) {
1366 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1367 << " not supported";
1368 return PixelFormat();
1369 }
1370
1371 return it->second;
1372}
1373
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001374/*
1375 * Inspect the stream_list to produce a list of StreamConfiguration to
1376 * be use to configure the Camera.
1377 */
1378int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1379{
Jacopo Mondi8fed6132020-12-04 15:26:47 +01001380 /* Before any configuration attempt, stop the camera if it's running. */
1381 if (running_) {
1382 worker_.stop();
1383 camera_->stop();
1384 running_ = false;
1385 }
1386
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001387 /*
1388 * Generate an empty configuration, and construct a StreamConfiguration
1389 * for each camera3_stream to add to it.
1390 */
1391 config_ = camera_->generateConfiguration();
1392 if (!config_) {
1393 LOG(HAL, Error) << "Failed to generate camera configuration";
1394 return -EINVAL;
1395 }
1396
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001397 /*
1398 * Clear and remove any existing configuration from previous calls, and
1399 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001400 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001401 */
1402 streams_.clear();
1403 streams_.reserve(stream_list->num_streams);
1404
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001405 std::vector<Camera3StreamConfig> streamConfigs;
1406 streamConfigs.reserve(stream_list->num_streams);
1407
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001408 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001409 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001410 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1411 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001412 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001413
Kieran Bingham43e3b802020-06-26 09:58:49 +01001414 PixelFormat format = toPixelFormat(stream->format);
1415
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001416 LOG(HAL, Info) << "Stream #" << i
1417 << ", direction: " << stream->stream_type
1418 << ", width: " << stream->width
1419 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001420 << ", format: " << utils::hex(stream->format)
1421 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001422
1423 if (!format.isValid())
1424 return -EINVAL;
1425
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001426 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001427 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1428 if (jpegStream) {
1429 LOG(HAL, Error)
1430 << "Multiple JPEG streams are not supported";
1431 return -EINVAL;
1432 }
1433
1434 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001435 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001436 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001437
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001438 Camera3StreamConfig streamConfig;
1439 streamConfig.streams = { { stream, CameraStream::Type::Direct } };
1440 streamConfig.config.size = size;
1441 streamConfig.config.pixelFormat = format;
1442 streamConfigs.push_back(std::move(streamConfig));
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001443 }
1444
Jacopo Mondic82f9442020-09-02 11:58:00 +02001445 /* Now handle the MJPEG streams, adding a new stream if required. */
1446 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001447 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001448 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001449
Jacopo Mondic82f9442020-09-02 11:58:00 +02001450 /* Search for a compatible stream in the non-JPEG ones. */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001451 for (size_t i = 0; i < streamConfigs.size(); ++i) {
1452 const auto &cfg = streamConfigs[i].config;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001453
1454 /*
1455 * \todo The PixelFormat must also be compatible with
1456 * the encoder.
1457 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001458 if (cfg.size.width != jpegStream->width ||
1459 cfg.size.height != jpegStream->height)
1460 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001461
Jacopo Mondic82f9442020-09-02 11:58:00 +02001462 LOG(HAL, Info)
1463 << "Android JPEG stream mapped to libcamera stream " << i;
1464
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001465 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001466 index = i;
1467 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001468 }
1469
1470 /*
1471 * Without a compatible match for JPEG encoding we must
1472 * introduce a new stream to satisfy the request requirements.
1473 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001474 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001475 /*
1476 * \todo The pixelFormat should be a 'best-fit' choice
1477 * and may require a validation cycle. This is not yet
1478 * handled, and should be considered as part of any
1479 * stream configuration reworks.
1480 */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001481 Camera3StreamConfig streamConfig;
1482 streamConfig.config.size.width = jpegStream->width;
1483 streamConfig.config.size.height = jpegStream->height;
1484 streamConfig.config.pixelFormat = formats::NV12;
1485 streamConfigs.push_back(std::move(streamConfig));
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001486
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001487 LOG(HAL, Info) << "Adding " << streamConfig.config.toString()
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001488 << " for MJPEG support";
1489
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001490 type = CameraStream::Type::Internal;
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001491 index = streamConfigs.size() - 1;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001492 }
1493
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001494 streamConfigs[index].streams.push_back({ jpegStream, type });
1495 }
1496
Hirokazu Honda26d90af2020-12-11 09:53:36 +00001497 sortCamera3StreamConfigs(streamConfigs, jpegStream);
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001498 for (const auto &streamConfig : streamConfigs) {
1499 config_->addConfiguration(streamConfig.config);
1500
1501 for (auto &stream : streamConfig.streams) {
1502 streams_.emplace_back(this, stream.type, stream.stream,
1503 config_->size() - 1);
1504 stream.stream->priv = static_cast<void *>(&streams_.back());
1505 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001506 }
1507
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001508 switch (config_->validate()) {
1509 case CameraConfiguration::Valid:
1510 break;
1511 case CameraConfiguration::Adjusted:
1512 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001513
1514 for (const StreamConfiguration &cfg : *config_)
1515 LOG(HAL, Info) << " - " << cfg.toString();
1516
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001517 config_.reset();
1518 return -EINVAL;
1519 case CameraConfiguration::Invalid:
1520 LOG(HAL, Info) << "Camera configuration invalid";
1521 config_.reset();
1522 return -EINVAL;
1523 }
1524
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001525 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001526 * Once the CameraConfiguration has been adjusted/validated
1527 * it can be applied to the camera.
1528 */
1529 int ret = camera_->configure(config_.get());
1530 if (ret) {
1531 LOG(HAL, Error) << "Failed to configure camera '"
1532 << camera_->id() << "'";
1533 return ret;
1534 }
1535
1536 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001537 * Configure the HAL CameraStream instances using the associated
1538 * StreamConfiguration and set the number of required buffers in
1539 * the Android camera3_stream_t.
1540 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001541 for (CameraStream &cameraStream : streams_) {
Kieran Binghamc7bcae02020-10-13 15:58:26 +01001542 ret = cameraStream.configure();
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001543 if (ret) {
1544 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001545 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001546 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001547 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001548
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001549 return 0;
1550}
1551
Kieran Bingham74ab4422020-07-01 13:25:38 +01001552FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1553{
1554 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001555 for (int i = 0; i < camera3buffer->numFds; i++) {
1556 /* Skip unused planes. */
1557 if (camera3buffer->data[i] == -1)
1558 break;
1559
Kieran Bingham74ab4422020-07-01 13:25:38 +01001560 FrameBuffer::Plane plane;
1561 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001562 if (!plane.fd.isValid()) {
1563 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1564 << camera3buffer->data[i] << ") "
1565 << " on plane " << i;
1566 return nullptr;
1567 }
1568
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001569 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1570 if (length == -1) {
1571 LOG(HAL, Error) << "Failed to query plane length";
1572 return nullptr;
1573 }
1574
1575 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001576 planes.push_back(std::move(plane));
1577 }
1578
1579 return new FrameBuffer(std::move(planes));
1580}
1581
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001582int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001583{
Jacopo Mondic5b732b2020-12-01 17:12:19 +01001584 if (!camera3Request) {
1585 LOG(HAL, Error) << "No capture request provided";
1586 return -EINVAL;
1587 }
1588
Kieran Bingham61f42962020-07-01 13:40:17 +01001589 if (!camera3Request->num_output_buffers) {
1590 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001591 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001592 }
1593
1594 /* Start the camera if that's the first request we handle. */
1595 if (!running_) {
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001596 worker_.start();
1597
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001598 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001599 if (ret) {
1600 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001601 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001602 }
1603
1604 running_ = true;
1605 }
1606
1607 /*
1608 * Queue a request for the Camera with the provided dmabuf file
1609 * descriptors.
1610 */
1611 const camera3_stream_buffer_t *camera3Buffers =
1612 camera3Request->output_buffers;
1613
1614 /*
1615 * Save the request descriptors for use at completion time.
1616 * The descriptor and the associated memory reserved here are freed
1617 * at request complete time.
1618 */
1619 Camera3RequestDescriptor *descriptor =
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001620 new Camera3RequestDescriptor(camera_.get(), camera3Request->frame_number,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001621 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001622
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001623 LOG(HAL, Debug) << "Queueing Request to libcamera with "
Kieran Bingham37c18c22020-10-21 14:54:11 +01001624 << descriptor->numBuffers_ << " HAL streams";
1625 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001626 camera3_stream *camera3Stream = camera3Buffers[i].stream;
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001627 CameraStream *cameraStream =
1628 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1629
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001630 /*
1631 * Keep track of which stream the request belongs to and store
1632 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001633 */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001634 descriptor->buffers_[i].stream = camera3Buffers[i].stream;
1635 descriptor->buffers_[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001636
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001637 std::stringstream ss;
1638 ss << i << " - (" << camera3Stream->width << "x"
1639 << camera3Stream->height << ")"
1640 << "[" << utils::hex(camera3Stream->format) << "] -> "
1641 << "(" << cameraStream->configuration().size.toString() << ")["
1642 << cameraStream->configuration().pixelFormat.toString() << "]";
1643
Jacopo Mondide8304b2020-09-04 17:45:39 +02001644 /*
1645 * Inspect the camera stream type, create buffers opportunely
1646 * and add them to the Request if required.
1647 */
1648 FrameBuffer *buffer = nullptr;
1649 switch (cameraStream->type()) {
1650 case CameraStream::Type::Mapped:
1651 /*
1652 * Mapped streams don't need buffers added to the
1653 * Request.
1654 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001655 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001656 continue;
1657
Jacopo Mondide8304b2020-09-04 17:45:39 +02001658 case CameraStream::Type::Direct:
1659 /*
1660 * Create a libcamera buffer using the dmabuf
1661 * descriptors of the camera3Buffer for each stream and
1662 * associate it with the Camera3RequestDescriptor for
1663 * lifetime management only.
1664 */
1665 buffer = createFrameBuffer(*camera3Buffers[i].buffer);
Kieran Bingham37c18c22020-10-21 14:54:11 +01001666 descriptor->frameBuffers_.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001667 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001668 break;
1669
1670 case CameraStream::Type::Internal:
1671 /*
1672 * Get the frame buffer from the CameraStream internal
1673 * buffer pool.
1674 *
1675 * The buffer has to be returned to the CameraStream
1676 * once it has been processed.
1677 */
1678 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001679 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001680 break;
1681 }
1682
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001683 if (!buffer) {
1684 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001685 delete descriptor;
1686 return -ENOMEM;
1687 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001688
Kieran Bingham37c18c22020-10-21 14:54:11 +01001689 descriptor->request_->addBuffer(cameraStream->stream(), buffer,
1690 camera3Buffers[i].acquire_fence);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001691 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001692
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001693 /* Queue the request to the CameraWorker. */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001694 worker_.queueRequest(descriptor->request_.get());
Paul Elderc7532232020-09-23 19:05:41 +09001695
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001696 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001697}
1698
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001699void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001700{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001701 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001702 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001703 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001704 Camera3RequestDescriptor *descriptor =
1705 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001706
1707 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001708 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001709 << request->status();
1710 status = CAMERA3_BUFFER_STATUS_ERROR;
1711 }
1712
Kieran Binghamc09aee42020-07-28 14:01:19 +01001713 /*
1714 * \todo The timestamp used for the metadata is currently always taken
1715 * from the first buffer (which may be the first stream) in the Request.
1716 * It might be appropriate to return a 'correct' (as determined by
1717 * pipeline handlers) timestamp in the Request itself.
1718 */
Hirokazu Honda3a777d82020-10-28 17:57:26 +09001719 uint64_t timestamp = buffers.begin()->second->metadata().timestamp;
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001720 resultMetadata = getResultMetadata(descriptor, timestamp);
Kieran Binghamc09aee42020-07-28 14:01:19 +01001721
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001722 /* Handle any JPEG compression. */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001723 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001724 CameraStream *cameraStream =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001725 static_cast<CameraStream *>(descriptor->buffers_[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001726
Jacopo Mondi160bb092020-10-02 20:48:35 +02001727 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001728 continue;
1729
Jacopo Mondi216030a2020-10-03 11:36:41 +02001730 FrameBuffer *buffer = request->findBuffer(cameraStream->stream());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001731 if (!buffer) {
1732 LOG(HAL, Error) << "Failed to find a source stream buffer";
1733 continue;
1734 }
1735
1736 /*
1737 * \todo Buffer mapping and compression should be moved to a
1738 * separate thread.
1739 */
1740
Kieran Bingham37c18c22020-10-21 14:54:11 +01001741 MappedCamera3Buffer mapped(*descriptor->buffers_[i].buffer,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001742 PROT_READ | PROT_WRITE);
1743 if (!mapped.isValid()) {
1744 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1745 continue;
1746 }
1747
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02001748 int ret = cameraStream->process(*buffer, &mapped,
1749 resultMetadata.get());
1750 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001751 status = CAMERA3_BUFFER_STATUS_ERROR;
1752 continue;
1753 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02001754
1755 /*
1756 * Return the FrameBuffer to the CameraStream now that we're
1757 * done processing it.
1758 */
1759 if (cameraStream->type() == CameraStream::Type::Internal)
1760 cameraStream->putBuffer(buffer);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001761 }
1762
1763 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001764 camera3_capture_result_t captureResult = {};
Kieran Bingham37c18c22020-10-21 14:54:11 +01001765 captureResult.frame_number = descriptor->frameNumber_;
1766 captureResult.num_output_buffers = descriptor->numBuffers_;
1767 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
1768 descriptor->buffers_[i].acquire_fence = -1;
1769 descriptor->buffers_[i].release_fence = -1;
1770 descriptor->buffers_[i].status = status;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001771 }
1772 captureResult.output_buffers =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001773 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers_);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001774
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001775
Laurent Pinchart39860092019-09-05 03:12:34 +03001776 if (status == CAMERA3_BUFFER_STATUS_OK) {
Kieran Binghame1f9fdb2020-10-21 15:31:10 +01001777 notifyShutter(descriptor->frameNumber_, timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001778
1779 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001780 captureResult.result = resultMetadata->get();
1781 }
1782
1783 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1784 /* \todo Improve error handling. In case we notify an error
1785 * because the metadata generation fails, a shutter event has
1786 * already been notified for this frame number before the error
1787 * is here signalled. Make sure the error path plays well with
1788 * the camera stack state machine.
1789 */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001790 notifyError(descriptor->frameNumber_,
1791 descriptor->buffers_[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001792 }
1793
1794 callbacks_->process_capture_result(callbacks_, &captureResult);
1795
1796 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001797}
1798
Jacopo Mondia7b92772020-05-26 15:41:41 +02001799std::string CameraDevice::logPrefix() const
1800{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001801 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001802}
1803
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001804void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1805{
1806 camera3_notify_msg_t notify = {};
1807
1808 notify.type = CAMERA3_MSG_SHUTTER;
1809 notify.message.shutter.frame_number = frameNumber;
1810 notify.message.shutter.timestamp = timestamp;
1811
1812 callbacks_->notify(callbacks_, &notify);
1813}
1814
1815void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1816{
1817 camera3_notify_msg_t notify = {};
1818
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001819 /*
1820 * \todo Report and identify the stream number or configuration to
1821 * clarify the stream that failed.
1822 */
1823 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1824 << toPixelFormat(stream->format).toString() << ")";
1825
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001826 notify.type = CAMERA3_MSG_ERROR;
1827 notify.message.error.error_stream = stream;
1828 notify.message.error.frame_number = frameNumber;
1829 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1830
1831 callbacks_->notify(callbacks_, &notify);
1832}
1833
1834/*
1835 * Produce a set of fixed result metadata.
1836 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001837std::unique_ptr<CameraMetadata>
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001838CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor,
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001839 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001840{
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001841 const ControlList &metadata = descriptor->request_->metadata();
1842
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001843 /*
1844 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001845 * Currently: 18 entries, 62 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001846 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001847 std::unique_ptr<CameraMetadata> resultMetadata =
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001848 std::make_unique<CameraMetadata>(19, 63);
Laurent Pinchart39860092019-09-05 03:12:34 +03001849 if (!resultMetadata->isValid()) {
1850 LOG(HAL, Error) << "Failed to allocate static metadata";
1851 return nullptr;
1852 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001853
1854 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001855 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001856
1857 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001858 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001859
1860 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001861 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001862
1863 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001864 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001865
1866 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001867 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001868
1869 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001870 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001871
1872 int32_t sensorSizes[] = {
1873 0, 0, 2560, 1920,
1874 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001875 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001876
Laurent Pinchart39860092019-09-05 03:12:34 +03001877 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001878
1879 /* 33.3 msec */
1880 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001881 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1882 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001883
1884 /* 16.6 msec */
1885 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001886 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1887 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001888
1889 const uint8_t lens_shading_map_mode =
1890 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001891 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1892 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001893
1894 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001895 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1896 &scene_flicker, 1);
1897
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01001898 /* Add metadata tags reported by libcamera. */
1899 if (metadata.contains(controls::draft::PipelineDepth)) {
1900 uint8_t pipeline_depth =
1901 metadata.get<int32_t>(controls::draft::PipelineDepth);
1902 resultMetadata->addEntry(ANDROID_REQUEST_PIPELINE_DEPTH,
1903 &pipeline_depth, 1);
1904 }
1905
Laurent Pinchart39860092019-09-05 03:12:34 +03001906 /*
1907 * Return the result metadata pack even is not valid: get() will return
1908 * nullptr.
1909 */
1910 if (!resultMetadata->isValid()) {
1911 LOG(HAL, Error) << "Failed to construct result metadata";
1912 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001913
1914 return resultMetadata;
1915}