blob: c219ea84d113f904c207a514d9fc168fdf7f8419 [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
Jacopo Mondi117588b2020-05-23 18:53:54 +020030namespace {
31
32/*
33 * \var camera3Resolutions
34 * \brief The list of image resolutions defined as mandatory to be supported by
35 * the Android Camera3 specification
36 */
37const std::vector<Size> camera3Resolutions = {
38 { 320, 240 },
39 { 640, 480 },
40 { 1280, 720 },
41 { 1920, 1080 }
42};
43
44/*
45 * \struct Camera3Format
46 * \brief Data associated with an Android format identifier
47 * \var libcameraFormats List of libcamera pixel formats compatible with the
48 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020049 * \var name The human-readable representation of the Android format code
50 */
51struct Camera3Format {
52 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020053 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020054 const char *name;
55};
56
57/*
58 * \var camera3FormatsMap
59 * \brief Associate Android format code with ancillary data
60 */
61const std::map<int, const Camera3Format> camera3FormatsMap = {
62 {
63 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030064 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020065 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020066 "BLOB"
67 }
68 }, {
69 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030070 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020071 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020072 "YCbCr_420_888"
73 }
74 }, {
75 /*
76 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
77 * usage flag. For now, copy the YCbCr_420 configuration.
78 */
79 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030080 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020081 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020082 "IMPLEMENTATION_DEFINED"
83 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020084 }, {
85 HAL_PIXEL_FORMAT_RAW10, {
86 {
87 formats::SBGGR10_CSI2P,
88 formats::SGBRG10_CSI2P,
89 formats::SGRBG10_CSI2P,
90 formats::SRGGB10_CSI2P
91 },
92 false,
93 "RAW10"
94 }
95 }, {
96 HAL_PIXEL_FORMAT_RAW12, {
97 {
98 formats::SBGGR12_CSI2P,
99 formats::SGBRG12_CSI2P,
100 formats::SGRBG12_CSI2P,
101 formats::SRGGB12_CSI2P
102 },
103 false,
104 "RAW12"
105 }
106 }, {
107 HAL_PIXEL_FORMAT_RAW16, {
108 {
109 formats::SBGGR16,
110 formats::SGBRG16,
111 formats::SGRBG16,
112 formats::SRGGB16
113 },
114 false,
115 "RAW16"
116 }
117 }, {
118 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
119 {
120 formats::SBGGR10_IPU3,
121 formats::SGBRG10_IPU3,
122 formats::SGRBG10_IPU3,
123 formats::SRGGB10_IPU3
124 },
125 false,
126 "RAW_OPAQUE"
127 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200128 },
129};
130
Hirokazu Hondac2df7432020-12-11 09:53:34 +0000131/*
132 * \struct Camera3StreamConfig
133 * \brief Data to store StreamConfiguration associated with camera3_stream(s)
134 * \var streams List of the pairs of a stream requested by Android HAL client
135 * and CameraStream::Type associated with the stream
136 * \var config StreamConfiguration for streams
137 */
138struct Camera3StreamConfig {
139 struct Camera3Stream {
140 camera3_stream_t *stream;
141 CameraStream::Type type;
142 };
143
144 std::vector<Camera3Stream> streams;
145 StreamConfiguration config;
146};
147
Jacopo Mondi117588b2020-05-23 18:53:54 +0200148} /* namespace */
149
Hirokazu Honda6c5792f2020-10-20 18:15:01 +0900150LOG_DECLARE_CATEGORY(HAL)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200151
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100152MappedCamera3Buffer::MappedCamera3Buffer(const buffer_handle_t camera3buffer,
153 int flags)
154{
155 maps_.reserve(camera3buffer->numFds);
156 error_ = 0;
157
158 for (int i = 0; i < camera3buffer->numFds; i++) {
159 if (camera3buffer->data[i] == -1)
160 continue;
161
162 off_t length = lseek(camera3buffer->data[i], 0, SEEK_END);
163 if (length < 0) {
164 error_ = -errno;
165 LOG(HAL, Error) << "Failed to query plane length";
166 break;
167 }
168
169 void *address = mmap(nullptr, length, flags, MAP_SHARED,
170 camera3buffer->data[i], 0);
171 if (address == MAP_FAILED) {
172 error_ = -errno;
173 LOG(HAL, Error) << "Failed to mmap plane";
174 break;
175 }
176
177 maps_.emplace_back(static_cast<uint8_t *>(address),
178 static_cast<size_t>(length));
179 }
180}
181
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200182/*
183 * \struct Camera3RequestDescriptor
184 *
185 * A utility structure that groups information about a capture request to be
186 * later re-used at request complete time to notify the framework.
187 */
188
189CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200190 Camera *camera, unsigned int frameNumber, unsigned int numBuffers)
Kieran Bingham37c18c22020-10-21 14:54:11 +0100191 : frameNumber_(frameNumber), numBuffers_(numBuffers)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200192{
Kieran Bingham37c18c22020-10-21 14:54:11 +0100193 buffers_ = new camera3_stream_buffer_t[numBuffers];
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200194
195 /*
196 * FrameBuffer instances created by wrapping a camera3 provided dmabuf
197 * are emplaced in this vector of unique_ptr<> for lifetime management.
198 */
Kieran Bingham37c18c22020-10-21 14:54:11 +0100199 frameBuffers_.reserve(numBuffers);
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200200
201 /*
202 * Create the libcamera::Request unique_ptr<> to tie its lifetime
203 * to the descriptor's one. Set the descriptor's address as the
204 * request's cookie to retrieve it at completion time.
205 */
Kieran Bingham37c18c22020-10-21 14:54:11 +0100206 request_ = std::make_unique<CaptureRequest>(camera,
207 reinterpret_cast<uint64_t>(this));
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200208}
209
210CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
211{
Kieran Bingham37c18c22020-10-21 14:54:11 +0100212 delete[] buffers_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200213}
214
215/*
216 * \class CameraDevice
217 *
218 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200219 * the camera3_device_t interface, bridging calls received from the Android
220 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200221 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200222 * The class translates parameters and operations from the Camera HALv3 API to
223 * the libcamera API to provide static information for a Camera, create request
224 * templates for it, process capture requests and then deliver capture results
225 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200226 */
227
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300228CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000229 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200230 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200231{
232 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100233
234 /*
235 * \todo Determine a more accurate value for this during
236 * streamConfiguration.
237 */
238 maxJpegBufferSize_ = 13 << 20; /* 13631488 from USB HAL */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200239}
240
241CameraDevice::~CameraDevice()
242{
243 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300244 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200245
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200246 for (auto &it : requestTemplates_)
247 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200248}
249
Umang Jainf8e28132020-08-21 14:46:08 +0000250std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
251 const std::shared_ptr<Camera> &cam)
252{
253 CameraDevice *camera = new CameraDevice(id, cam);
254 return std::shared_ptr<CameraDevice>(camera);
255}
256
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200257/*
258 * Initialize the camera static information.
259 * This method is called before the camera device is opened.
260 */
261int CameraDevice::initialize()
262{
263 /* Initialize orientation and facing side of the camera. */
264 const ControlList &properties = camera_->properties();
265
266 if (properties.contains(properties::Location)) {
267 int32_t location = properties.get(properties::Location);
268 switch (location) {
269 case properties::CameraLocationFront:
270 facing_ = CAMERA_FACING_FRONT;
271 break;
272 case properties::CameraLocationBack:
273 facing_ = CAMERA_FACING_BACK;
274 break;
275 case properties::CameraLocationExternal:
276 facing_ = CAMERA_FACING_EXTERNAL;
277 break;
278 }
279 }
280
281 /*
Umang Jaine9176552020-09-09 16:17:54 +0530282 * The Android orientation metadata specifies its rotation correction
283 * value in clockwise direction whereas libcamera specifies the
284 * rotation property in anticlockwise direction. Read the libcamera's
285 * rotation property (anticlockwise) and compute the corresponding
286 * value for clockwise direction as required by the Android orientation
287 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200288 */
Umang Jaine9176552020-09-09 16:17:54 +0530289 if (properties.contains(properties::Rotation)) {
290 int rotation = properties.get(properties::Rotation);
291 orientation_ = (360 - rotation) % 360;
292 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200293
Jacopo Mondi117588b2020-05-23 18:53:54 +0200294 int ret = camera_->acquire();
295 if (ret) {
296 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
297 return ret;
298 }
299
300 ret = initializeStreamConfigurations();
301 camera_->release();
302 return ret;
303}
304
Jacopo Mondibfee6312020-09-01 17:42:13 +0200305std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
306 const PixelFormat &pixelFormat,
307 const std::vector<Size> &resolutions)
308{
309 std::vector<Size> supportedResolutions;
310
311 StreamConfiguration &cfg = cameraConfig->at(0);
312 for (const Size &res : resolutions) {
313 cfg.pixelFormat = pixelFormat;
314 cfg.size = res;
315
316 CameraConfiguration::Status status = cameraConfig->validate();
317 if (status != CameraConfiguration::Valid) {
318 LOG(HAL, Debug) << cfg.toString() << " not supported";
319 continue;
320 }
321
322 LOG(HAL, Debug) << cfg.toString() << " supported";
323
324 supportedResolutions.push_back(res);
325 }
326
327 return supportedResolutions;
328}
329
Jacopo Mondi49610332020-09-01 18:11:34 +0200330std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
331{
332 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200333 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200334 StreamConfiguration &cfg = cameraConfig->at(0);
335 const StreamFormats &formats = cfg.formats();
336 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
337
338 return supportedResolutions;
339}
340
Jacopo Mondi117588b2020-05-23 18:53:54 +0200341/*
342 * Initialize the format conversion map to translate from Android format
343 * identifier to libcamera pixel formats and fill in the list of supported
344 * stream configurations to be reported to the Android camera framework through
345 * the static stream configuration metadata.
346 */
347int CameraDevice::initializeStreamConfigurations()
348{
349 /*
350 * Get the maximum output resolutions
351 * \todo Get this from the camera properties once defined
352 */
353 std::unique_ptr<CameraConfiguration> cameraConfig =
354 camera_->generateConfiguration({ StillCapture });
355 if (!cameraConfig) {
356 LOG(HAL, Error) << "Failed to get maximum resolution";
357 return -EINVAL;
358 }
359 StreamConfiguration &cfg = cameraConfig->at(0);
360
361 /*
362 * \todo JPEG - Adjust the maximum available resolution by taking the
363 * JPEG encoder requirements into account (alignment and aspect ratio).
364 */
365 const Size maxRes = cfg.size;
366 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
367
368 /*
369 * Build the list of supported image resolutions.
370 *
371 * The resolutions listed in camera3Resolution are mandatory to be
372 * supported, up to the camera maximum resolution.
373 *
374 * Augment the list by adding resolutions calculated from the camera
375 * maximum one.
376 */
377 std::vector<Size> cameraResolutions;
378 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
379 std::back_inserter(cameraResolutions),
380 [&](const Size &res) { return res < maxRes; });
381
382 /*
383 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
384 * resolution.
385 */
386 for (unsigned int divider = 2;; divider <<= 1) {
387 Size derivedSize{
388 maxRes.width / divider,
389 maxRes.height / divider,
390 };
391
392 if (derivedSize.width < 320 ||
393 derivedSize.height < 240)
394 break;
395
396 cameraResolutions.push_back(derivedSize);
397 }
398 cameraResolutions.push_back(maxRes);
399
400 /* Remove duplicated entries from the list of supported resolutions. */
401 std::sort(cameraResolutions.begin(), cameraResolutions.end());
402 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
403 cameraResolutions.erase(last, cameraResolutions.end());
404
405 /*
406 * Build the list of supported camera formats.
407 *
408 * To each Android format a list of compatible libcamera formats is
409 * associated. The first libcamera format that tests successful is added
410 * to the format translation map used when configuring the streams.
411 * It is then tested against the list of supported camera resolutions to
412 * build the stream configuration map reported through the camera static
413 * metadata.
414 */
415 for (const auto &format : camera3FormatsMap) {
416 int androidFormat = format.first;
417 const Camera3Format &camera3Format = format.second;
418 const std::vector<PixelFormat> &libcameraFormats =
419 camera3Format.libcameraFormats;
420
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200421 LOG(HAL, Debug) << "Trying to map Android format "
422 << camera3Format.name;
423
Jacopo Mondi117588b2020-05-23 18:53:54 +0200424 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200425 * JPEG is always supported, either produced directly by the
426 * camera, or encoded in the HAL.
427 */
428 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
429 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200430 LOG(HAL, Debug) << "Mapped Android format "
431 << camera3Format.name << " to "
432 << formats::MJPEG.toString()
433 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200434 continue;
435 }
436
437 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200438 * Test the libcamera formats that can produce images
439 * compatible with the format defined by Android.
440 */
441 PixelFormat mappedFormat;
442 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200443
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200444 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
445
Jacopo Mondi117588b2020-05-23 18:53:54 +0200446 /*
447 * The stream configuration size can be adjusted,
448 * not the pixel format.
449 *
450 * \todo This could be simplified once all pipeline
451 * handlers will report the StreamFormats list of
452 * supported formats.
453 */
454 cfg.pixelFormat = pixelFormat;
455
456 CameraConfiguration::Status status = cameraConfig->validate();
457 if (status != CameraConfiguration::Invalid &&
458 cfg.pixelFormat == pixelFormat) {
459 mappedFormat = pixelFormat;
460 break;
461 }
462 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200463
464 if (!mappedFormat.isValid()) {
465 /* If the format is not mandatory, skip it. */
466 if (!camera3Format.mandatory)
467 continue;
468
469 LOG(HAL, Error)
470 << "Failed to map mandatory Android format "
471 << camera3Format.name << " ("
472 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200473 return -EINVAL;
474 }
475
476 /*
477 * Record the mapping and then proceed to generate the
478 * stream configurations map, by testing the image resolutions.
479 */
480 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200481 LOG(HAL, Debug) << "Mapped Android format "
482 << camera3Format.name << " to "
483 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200484
Jacopo Mondi49610332020-09-01 18:11:34 +0200485 std::vector<Size> resolutions;
486 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
487 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
488 resolutions = getRawResolutions(mappedFormat);
489 else
490 resolutions = getYUVResolutions(cameraConfig.get(),
491 mappedFormat,
492 cameraResolutions);
493
Jacopo Mondibfee6312020-09-01 17:42:13 +0200494 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200495 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200496
497 /*
498 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
499 * from which JPEG is produced, add an entry for
500 * the JPEG stream.
501 *
502 * \todo Wire the JPEG encoder to query the supported
503 * sizes provided a list of formats it can encode.
504 *
505 * \todo Support JPEG streams produced by the Camera
506 * natively.
507 */
508 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888)
509 streamConfigurations_.push_back(
510 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200511 }
512 }
513
514 LOG(HAL, Debug) << "Collected stream configuration map: ";
515 for (const auto &entry : streamConfigurations_)
516 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200517 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200518
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200519 return 0;
520}
521
522/*
523 * Open a camera device. The static information on the camera shall have been
524 * initialized with a call to CameraDevice::initialize().
525 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200526int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200527{
528 int ret = camera_->acquire();
529 if (ret) {
530 LOG(HAL, Error) << "Failed to acquire the camera";
531 return ret;
532 }
533
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200534 /* Initialize the hw_device_t in the instance camera3_module_t. */
535 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
536 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
537 camera3Device_.common.module = (hw_module_t *)hardwareModule;
538 camera3Device_.common.close = hal_dev_close;
539
540 /*
541 * The camera device operations. These actually implement
542 * the Android Camera HALv3 interface.
543 */
544 camera3Device_.ops = &hal_dev_ops;
545 camera3Device_.priv = this;
546
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200547 return 0;
548}
549
550void CameraDevice::close()
551{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200552 streams_.clear();
553
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200554 worker_.stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200555 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200556 camera_->release();
557
558 running_ = false;
559}
560
561void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
562{
563 callbacks_ = callbacks;
564}
565
Jacopo Mondia80d3812020-05-26 12:31:35 +0200566std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
567{
568 /*
569 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100570 * Currently: 51 entries, 687 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200571 */
Jacopo Mondi2c618502020-10-08 16:47:36 +0200572 uint32_t numEntries = 52;
573 uint32_t byteSize = 694;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200574
575 /*
576 * Calculate space occupation in bytes for dynamically built metadata
577 * entries.
578 *
579 * Each stream configuration entry requires 52 bytes:
580 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200581 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
582 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200583 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200584
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300585 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200586}
587
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200588/*
589 * Return static information for the camera.
590 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200591const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200592{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200593 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300594 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200595
596 /*
597 * The here reported metadata are enough to implement a basic capture
598 * example application, but a real camera implementation will require
599 * more.
600 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200601 uint32_t numEntries;
602 uint32_t byteSize;
603 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
604 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300605 if (!staticMetadata_->isValid()) {
606 LOG(HAL, Error) << "Failed to allocate static metadata";
607 delete staticMetadata_;
608 staticMetadata_ = nullptr;
609 return nullptr;
610 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200611
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200612 const ControlInfoMap &controlsInfo = camera_->controls();
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100613 const ControlList &properties = camera_->properties();
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200614
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200615 /* Color correction static metadata. */
Jacopo Mondi63336862020-10-08 16:18:26 +0200616 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100617 std::vector<uint8_t> data;
618 data.reserve(3);
Jacopo Mondi63336862020-10-08 16:18:26 +0200619 const auto &infoMap = controlsInfo.find(&controls::draft::ColorCorrectionAberrationMode);
620 if (infoMap != controlsInfo.end()) {
621 for (const auto &value : infoMap->second.values())
622 data.push_back(value.get<int32_t>());
623 } else {
624 data.push_back(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
625 }
626 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
627 data.data(), data.size());
628 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200629
630 /* Control static metadata. */
631 std::vector<uint8_t> aeAvailableAntiBandingModes = {
632 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
633 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
634 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
635 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
636 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300637 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
638 aeAvailableAntiBandingModes.data(),
639 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200640
641 std::vector<uint8_t> aeAvailableModes = {
642 ANDROID_CONTROL_AE_MODE_ON,
643 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300644 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
645 aeAvailableModes.data(),
646 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200647
648 std::vector<int32_t> availableAeFpsTarget = {
649 15, 30,
650 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300651 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
652 availableAeFpsTarget.data(),
653 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200654
655 std::vector<int32_t> aeCompensationRange = {
656 0, 0,
657 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300658 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
659 aeCompensationRange.data(),
660 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200661
662 const camera_metadata_rational_t aeCompensationStep[] = {
663 { 0, 1 }
664 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300665 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
666 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200667
668 std::vector<uint8_t> availableAfModes = {
669 ANDROID_CONTROL_AF_MODE_OFF,
670 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300671 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
672 availableAfModes.data(),
673 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200674
675 std::vector<uint8_t> availableEffects = {
676 ANDROID_CONTROL_EFFECT_MODE_OFF,
677 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300678 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
679 availableEffects.data(),
680 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200681
682 std::vector<uint8_t> availableSceneModes = {
683 ANDROID_CONTROL_SCENE_MODE_DISABLED,
684 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300685 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
686 availableSceneModes.data(),
687 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200688
689 std::vector<uint8_t> availableStabilizationModes = {
690 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
691 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300692 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
693 availableStabilizationModes.data(),
694 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200695
696 std::vector<uint8_t> availableAwbModes = {
697 ANDROID_CONTROL_AWB_MODE_OFF,
698 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300699 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
700 availableAwbModes.data(),
701 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200702
703 std::vector<int32_t> availableMaxRegions = {
704 0, 0, 0,
705 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300706 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
707 availableMaxRegions.data(),
708 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200709
710 std::vector<uint8_t> sceneModesOverride = {
711 ANDROID_CONTROL_AE_MODE_ON,
712 ANDROID_CONTROL_AWB_MODE_AUTO,
713 ANDROID_CONTROL_AF_MODE_AUTO,
714 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300715 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
716 sceneModesOverride.data(),
717 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200718
719 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300720 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
721 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200722
723 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300724 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
725 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200726
727 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300728 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
729 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200730
731 /* JPEG static metadata. */
732 std::vector<int32_t> availableThumbnailSizes = {
733 0, 0,
734 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300735 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
736 availableThumbnailSizes.data(),
737 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200738
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100739 /*
740 * \todo Calculate the maximum JPEG buffer size by asking the encoder
741 * giving the maximum frame size required.
742 */
743 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
744
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200745 /* Sensor static metadata. */
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100746 if (properties.contains(properties::PixelArraySize)) {
747 const Size &size =
748 properties.get<Size>(properties::PixelArraySize);
749 std::vector<int32_t> data{
750 static_cast<int32_t>(size.width),
751 static_cast<int32_t>(size.height),
752 };
753 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
754 data.data(), data.size());
755 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200756
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100757 if (properties.contains(properties::PixelArrayActiveAreas)) {
758 const Span<const Rectangle> &rects =
759 properties.get<Span<const Rectangle>>(properties::PixelArrayActiveAreas);
760 std::vector<int32_t> data{
761 static_cast<int32_t>(rects[0].x),
762 static_cast<int32_t>(rects[0].y),
763 static_cast<int32_t>(rects[0].width),
764 static_cast<int32_t>(rects[0].height),
765 };
766 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
767 data.data(), data.size());
768 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200769
770 int32_t sensitivityRange[] = {
771 32, 2400,
772 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300773 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
774 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200775
776 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300777 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
778 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200779
780 int64_t exposureTimeRange[] = {
781 100000, 200000000,
782 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300783 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
784 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200785
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200786 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200787
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200788 std::vector<int32_t> testPatterModes = {
789 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
790 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300791 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
792 testPatterModes.data(),
793 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200794
795 std::vector<float> physicalSize = {
796 2592, 1944,
797 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300798 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
799 physicalSize.data(),
800 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200801
802 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300803 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
804 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200805
806 /* Statistics static metadata. */
807 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300808 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
809 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200810
811 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300812 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
813 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200814
Jacopo Mondi2c618502020-10-08 16:47:36 +0200815 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100816 std::vector<uint8_t> data;
817 data.reserve(2);
Jacopo Mondi2c618502020-10-08 16:47:36 +0200818 const auto &infoMap = controlsInfo.find(&controls::draft::LensShadingMapMode);
819 if (infoMap != controlsInfo.end()) {
820 for (const auto &value : infoMap->second.values())
821 data.push_back(value.get<int32_t>());
822 } else {
823 data.push_back(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
824 }
825 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
826 data.data(), data.size());
827 }
828
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200829 /* Sync static metadata. */
830 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300831 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200832
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200833 /* Flash static metadata. */
834 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300835 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
836 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200837
838 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200839 std::vector<float> lensApertures = {
840 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200841 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300842 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
843 lensApertures.data(),
844 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200845
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200846 uint8_t lensFacing;
847 switch (facing_) {
848 default:
849 case CAMERA_FACING_FRONT:
850 lensFacing = ANDROID_LENS_FACING_FRONT;
851 break;
852 case CAMERA_FACING_BACK:
853 lensFacing = ANDROID_LENS_FACING_BACK;
854 break;
855 case CAMERA_FACING_EXTERNAL:
856 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
857 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100858 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300859 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200860
861 std::vector<float> lensFocalLenghts = {
862 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200863 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300864 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
865 lensFocalLenghts.data(),
866 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200867
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200868 std::vector<uint8_t> opticalStabilizations = {
869 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
870 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300871 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
872 opticalStabilizations.data(),
873 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200874
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200875 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300876 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
877 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200878
879 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300880 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
881 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200882
883 /* Noise reduction modes. */
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +0200884 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100885 std::vector<uint8_t> data;
886 data.reserve(5);
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +0200887 const auto &infoMap = controlsInfo.find(&controls::draft::NoiseReductionMode);
888 if (infoMap != controlsInfo.end()) {
889 for (const auto &value : infoMap->second.values())
890 data.push_back(value.get<int32_t>());
891 } else {
892 data.push_back(ANDROID_NOISE_REDUCTION_MODE_OFF);
893 }
894 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
895 data.data(), data.size());
896 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200897
898 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200899 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300900 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
901 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200902
Jacopo Mondibde7b982020-05-25 17:18:28 +0200903 std::vector<uint32_t> availableStreamConfigurations;
904 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
905 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200906 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200907 availableStreamConfigurations.push_back(entry.resolution.width);
908 availableStreamConfigurations.push_back(entry.resolution.height);
909 availableStreamConfigurations.push_back(
910 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
911 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300912 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
913 availableStreamConfigurations.data(),
914 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200915
916 std::vector<int64_t> availableStallDurations = {
917 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
918 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300919 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
920 availableStallDurations.data(),
921 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200922
Jacopo Mondibde7b982020-05-25 17:18:28 +0200923 /* \todo Collect the minimum frame duration from the camera. */
924 std::vector<int64_t> minFrameDurations;
925 minFrameDurations.reserve(streamConfigurations_.size() * 4);
926 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200927 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200928 minFrameDurations.push_back(entry.resolution.width);
929 minFrameDurations.push_back(entry.resolution.height);
930 minFrameDurations.push_back(33333333);
931 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300932 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
933 minFrameDurations.data(),
934 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200935
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200936 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300937 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200938
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200939 /* Info static metadata. */
940 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300941 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
942 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200943
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200944 /* Request static metadata. */
945 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300946 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
947 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200948
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200949 {
950 /* Default the value to 2 if not reported by the camera. */
951 uint8_t maxPipelineDepth = 2;
952 const auto &infoMap = controlsInfo.find(&controls::draft::PipelineDepth);
953 if (infoMap != controlsInfo.end())
954 maxPipelineDepth = infoMap->second.max().get<int32_t>();
955 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
956 &maxPipelineDepth, 1);
957 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200958
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200959 /* LIMITED does not support reprocessing. */
960 uint32_t maxNumInputStreams = 0;
961 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
962 &maxNumInputStreams, 1);
963
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200964 std::vector<uint8_t> availableCapabilities = {
965 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
966 };
Niklas Söderlund7876d632020-07-21 00:16:24 +0200967
968 /* Report if camera supports RAW. */
969 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200970 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +0200971 if (cameraConfig && !cameraConfig->empty()) {
972 const PixelFormatInfo &info =
973 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
974 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
975 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
976 }
977
Laurent Pinchart39860092019-09-05 03:12:34 +0300978 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
979 availableCapabilities.data(),
980 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200981
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200982 std::vector<int32_t> availableCharacteristicsKeys = {
983 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
984 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
985 ANDROID_CONTROL_AE_AVAILABLE_MODES,
986 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
987 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
988 ANDROID_CONTROL_AE_COMPENSATION_STEP,
989 ANDROID_CONTROL_AF_AVAILABLE_MODES,
990 ANDROID_CONTROL_AVAILABLE_EFFECTS,
991 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
992 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
993 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
994 ANDROID_CONTROL_MAX_REGIONS,
995 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
996 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
997 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
998 ANDROID_CONTROL_AVAILABLE_MODES,
999 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001000 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001001 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
1002 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
1003 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
1004 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
1005 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
1006 ANDROID_SENSOR_ORIENTATION,
1007 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
1008 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1009 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1010 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1011 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1012 ANDROID_SYNC_MAX_LATENCY,
1013 ANDROID_FLASH_INFO_AVAILABLE,
1014 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
1015 ANDROID_LENS_FACING,
1016 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1017 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1018 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1019 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1020 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
1021 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001022 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1023 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1024 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1025 ANDROID_SCALER_CROPPING_TYPE,
1026 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
1027 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1028 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +02001029 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001030 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1031 };
1032 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
1033 availableCharacteristicsKeys.data(),
1034 availableCharacteristicsKeys.size());
1035
1036 std::vector<int32_t> availableRequestKeys = {
1037 ANDROID_CONTROL_AE_MODE,
1038 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1039 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001040 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1041 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001042 ANDROID_CONTROL_AE_LOCK,
1043 ANDROID_CONTROL_AF_TRIGGER,
1044 ANDROID_CONTROL_AWB_MODE,
1045 ANDROID_CONTROL_AWB_LOCK,
1046 ANDROID_FLASH_MODE,
1047 ANDROID_STATISTICS_FACE_DETECT_MODE,
1048 ANDROID_NOISE_REDUCTION_MODE,
1049 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001050 ANDROID_LENS_APERTURE,
1051 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1052 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001053 ANDROID_CONTROL_CAPTURE_INTENT,
1054 };
1055 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
1056 availableRequestKeys.data(),
1057 availableRequestKeys.size());
1058
1059 std::vector<int32_t> availableResultKeys = {
1060 ANDROID_CONTROL_AE_STATE,
1061 ANDROID_CONTROL_AE_LOCK,
1062 ANDROID_CONTROL_AF_STATE,
1063 ANDROID_CONTROL_AWB_STATE,
1064 ANDROID_CONTROL_AWB_LOCK,
1065 ANDROID_LENS_STATE,
1066 ANDROID_SCALER_CROP_REGION,
1067 ANDROID_SENSOR_TIMESTAMP,
1068 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1069 ANDROID_SENSOR_EXPOSURE_TIME,
1070 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1071 ANDROID_STATISTICS_SCENE_FLICKER,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001072 ANDROID_JPEG_SIZE,
1073 ANDROID_JPEG_QUALITY,
1074 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001075 };
1076 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1077 availableResultKeys.data(),
1078 availableResultKeys.size());
1079
Laurent Pinchart39860092019-09-05 03:12:34 +03001080 if (!staticMetadata_->isValid()) {
1081 LOG(HAL, Error) << "Failed to construct static metadata";
1082 delete staticMetadata_;
1083 staticMetadata_ = nullptr;
1084 return nullptr;
1085 }
1086
1087 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001088}
1089
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001090CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001091{
Jacopo Mondi63703472019-09-04 16:18:22 +02001092 /*
1093 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001094 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001095 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001096 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001097 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001098 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001099 return nullptr;
1100 }
1101
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001102 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001103 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1104 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001105
1106 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001107 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1108 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001109
1110 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001111 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1112 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001113
1114 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001115 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1116 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001117
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001118 std::vector<int32_t> aeFpsTarget = {
1119 15, 30,
1120 };
1121 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1122 aeFpsTarget.data(),
1123 aeFpsTarget.size());
1124
1125 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1126 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1127 &aeAntibandingMode, 1);
1128
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001129 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001130 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1131 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001132
1133 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001134 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1135 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001136
1137 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001138 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1139 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001140
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001141 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001142 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1143 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001144
1145 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001146 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1147 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001148
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001149 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001150 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1151 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001152
1153 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001154 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1155 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001156
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001157 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1158 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1159
1160 float lensAperture = 2.53 / 100;
1161 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1162
1163 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1164 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1165 &opticalStabilization, 1);
1166
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001167 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001168 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1169 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001170
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001171 return requestTemplate;
1172}
1173
1174/*
1175 * Produce a metadata pack to be used as template for a capture request.
1176 */
1177const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1178{
1179 auto it = requestTemplates_.find(type);
1180 if (it != requestTemplates_.end())
1181 return it->second->get();
1182
1183 /* Use the capture intent matching the requested template type. */
1184 CameraMetadata *requestTemplate;
1185 uint8_t captureIntent;
1186 switch (type) {
1187 case CAMERA3_TEMPLATE_PREVIEW:
1188 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1189 break;
1190 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1191 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1192 break;
1193 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1194 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1195 break;
1196 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1197 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1198 break;
1199 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1200 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1201 break;
1202 case CAMERA3_TEMPLATE_MANUAL:
1203 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1204 break;
1205 default:
1206 LOG(HAL, Error) << "Invalid template request type: " << type;
1207 return nullptr;
1208 }
1209
1210 requestTemplate = requestTemplatePreview();
1211 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001212 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001213 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001214 return nullptr;
1215 }
1216
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001217 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1218 &captureIntent, 1);
1219
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001220 requestTemplates_[type] = requestTemplate;
1221 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001222}
1223
Hirokazu Hondac1ae9052020-10-28 18:50:23 +09001224PixelFormat CameraDevice::toPixelFormat(int format) const
Kieran Bingham43e3b802020-06-26 09:58:49 +01001225{
1226 /* Translate Android format code to libcamera pixel format. */
1227 auto it = formatsMap_.find(format);
1228 if (it == formatsMap_.end()) {
1229 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1230 << " not supported";
1231 return PixelFormat();
1232 }
1233
1234 return it->second;
1235}
1236
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001237/*
1238 * Inspect the stream_list to produce a list of StreamConfiguration to
1239 * be use to configure the Camera.
1240 */
1241int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1242{
Jacopo Mondi8fed6132020-12-04 15:26:47 +01001243 /* Before any configuration attempt, stop the camera if it's running. */
1244 if (running_) {
1245 worker_.stop();
1246 camera_->stop();
1247 running_ = false;
1248 }
1249
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001250 /*
1251 * Generate an empty configuration, and construct a StreamConfiguration
1252 * for each camera3_stream to add to it.
1253 */
1254 config_ = camera_->generateConfiguration();
1255 if (!config_) {
1256 LOG(HAL, Error) << "Failed to generate camera configuration";
1257 return -EINVAL;
1258 }
1259
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001260 /*
1261 * Clear and remove any existing configuration from previous calls, and
1262 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001263 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001264 */
1265 streams_.clear();
1266 streams_.reserve(stream_list->num_streams);
1267
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001268 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001269 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001270 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1271 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001272 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001273
Kieran Bingham43e3b802020-06-26 09:58:49 +01001274 PixelFormat format = toPixelFormat(stream->format);
1275
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001276 LOG(HAL, Info) << "Stream #" << i
1277 << ", direction: " << stream->stream_type
1278 << ", width: " << stream->width
1279 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001280 << ", format: " << utils::hex(stream->format)
1281 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001282
1283 if (!format.isValid())
1284 return -EINVAL;
1285
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001286 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001287 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1288 if (jpegStream) {
1289 LOG(HAL, Error)
1290 << "Multiple JPEG streams are not supported";
1291 return -EINVAL;
1292 }
1293
1294 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001295 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001296 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001297
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001298 StreamConfiguration streamConfiguration;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001299 streamConfiguration.size = size;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001300 streamConfiguration.pixelFormat = format;
1301
1302 config_->addConfiguration(streamConfiguration);
Jacopo Mondie3393f12020-10-03 12:00:54 +02001303 streams_.emplace_back(this, CameraStream::Type::Direct,
1304 stream, config_->size() - 1);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001305 stream->priv = static_cast<void *>(&streams_.back());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001306 }
1307
Jacopo Mondic82f9442020-09-02 11:58:00 +02001308 /* Now handle the MJPEG streams, adding a new stream if required. */
1309 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001310 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001311 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001312
Jacopo Mondic82f9442020-09-02 11:58:00 +02001313 /* Search for a compatible stream in the non-JPEG ones. */
1314 for (unsigned int i = 0; i < config_->size(); i++) {
1315 StreamConfiguration &cfg = config_->at(i);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001316
1317 /*
1318 * \todo The PixelFormat must also be compatible with
1319 * the encoder.
1320 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001321 if (cfg.size.width != jpegStream->width ||
1322 cfg.size.height != jpegStream->height)
1323 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001324
Jacopo Mondic82f9442020-09-02 11:58:00 +02001325 LOG(HAL, Info)
1326 << "Android JPEG stream mapped to libcamera stream " << i;
1327
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001328 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001329 index = i;
1330 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001331 }
1332
1333 /*
1334 * Without a compatible match for JPEG encoding we must
1335 * introduce a new stream to satisfy the request requirements.
1336 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001337 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001338 StreamConfiguration streamConfiguration;
1339
1340 /*
1341 * \todo The pixelFormat should be a 'best-fit' choice
1342 * and may require a validation cycle. This is not yet
1343 * handled, and should be considered as part of any
1344 * stream configuration reworks.
1345 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001346 streamConfiguration.size.width = jpegStream->width;
1347 streamConfiguration.size.height = jpegStream->height;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001348 streamConfiguration.pixelFormat = formats::NV12;
1349
1350 LOG(HAL, Info) << "Adding " << streamConfiguration.toString()
1351 << " for MJPEG support";
1352
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001353 type = CameraStream::Type::Internal;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001354 config_->addConfiguration(streamConfiguration);
Jacopo Mondic82f9442020-09-02 11:58:00 +02001355 index = config_->size() - 1;
1356 }
1357
Jacopo Mondie3393f12020-10-03 12:00:54 +02001358 streams_.emplace_back(this, type, jpegStream, index);
Jacopo Mondifacadb12020-09-02 12:11:46 +02001359 jpegStream->priv = static_cast<void *>(&streams_.back());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001360 }
1361
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001362 switch (config_->validate()) {
1363 case CameraConfiguration::Valid:
1364 break;
1365 case CameraConfiguration::Adjusted:
1366 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001367
1368 for (const StreamConfiguration &cfg : *config_)
1369 LOG(HAL, Info) << " - " << cfg.toString();
1370
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001371 config_.reset();
1372 return -EINVAL;
1373 case CameraConfiguration::Invalid:
1374 LOG(HAL, Info) << "Camera configuration invalid";
1375 config_.reset();
1376 return -EINVAL;
1377 }
1378
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001379 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001380 * Once the CameraConfiguration has been adjusted/validated
1381 * it can be applied to the camera.
1382 */
1383 int ret = camera_->configure(config_.get());
1384 if (ret) {
1385 LOG(HAL, Error) << "Failed to configure camera '"
1386 << camera_->id() << "'";
1387 return ret;
1388 }
1389
1390 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001391 * Configure the HAL CameraStream instances using the associated
1392 * StreamConfiguration and set the number of required buffers in
1393 * the Android camera3_stream_t.
1394 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001395 for (CameraStream &cameraStream : streams_) {
Kieran Binghamc7bcae02020-10-13 15:58:26 +01001396 ret = cameraStream.configure();
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001397 if (ret) {
1398 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001399 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001400 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001401 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001402
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001403 return 0;
1404}
1405
Kieran Bingham74ab4422020-07-01 13:25:38 +01001406FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1407{
1408 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001409 for (int i = 0; i < camera3buffer->numFds; i++) {
1410 /* Skip unused planes. */
1411 if (camera3buffer->data[i] == -1)
1412 break;
1413
Kieran Bingham74ab4422020-07-01 13:25:38 +01001414 FrameBuffer::Plane plane;
1415 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001416 if (!plane.fd.isValid()) {
1417 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1418 << camera3buffer->data[i] << ") "
1419 << " on plane " << i;
1420 return nullptr;
1421 }
1422
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001423 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1424 if (length == -1) {
1425 LOG(HAL, Error) << "Failed to query plane length";
1426 return nullptr;
1427 }
1428
1429 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001430 planes.push_back(std::move(plane));
1431 }
1432
1433 return new FrameBuffer(std::move(planes));
1434}
1435
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001436int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001437{
Jacopo Mondic5b732b2020-12-01 17:12:19 +01001438 if (!camera3Request) {
1439 LOG(HAL, Error) << "No capture request provided";
1440 return -EINVAL;
1441 }
1442
Kieran Bingham61f42962020-07-01 13:40:17 +01001443 if (!camera3Request->num_output_buffers) {
1444 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001445 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001446 }
1447
1448 /* Start the camera if that's the first request we handle. */
1449 if (!running_) {
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001450 worker_.start();
1451
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001452 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001453 if (ret) {
1454 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001455 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001456 }
1457
1458 running_ = true;
1459 }
1460
1461 /*
1462 * Queue a request for the Camera with the provided dmabuf file
1463 * descriptors.
1464 */
1465 const camera3_stream_buffer_t *camera3Buffers =
1466 camera3Request->output_buffers;
1467
1468 /*
1469 * Save the request descriptors for use at completion time.
1470 * The descriptor and the associated memory reserved here are freed
1471 * at request complete time.
1472 */
1473 Camera3RequestDescriptor *descriptor =
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001474 new Camera3RequestDescriptor(camera_.get(), camera3Request->frame_number,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001475 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001476
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001477 LOG(HAL, Debug) << "Queueing Request to libcamera with "
Kieran Bingham37c18c22020-10-21 14:54:11 +01001478 << descriptor->numBuffers_ << " HAL streams";
1479 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001480 camera3_stream *camera3Stream = camera3Buffers[i].stream;
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001481 CameraStream *cameraStream =
1482 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1483
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001484 /*
1485 * Keep track of which stream the request belongs to and store
1486 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001487 */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001488 descriptor->buffers_[i].stream = camera3Buffers[i].stream;
1489 descriptor->buffers_[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001490
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001491 std::stringstream ss;
1492 ss << i << " - (" << camera3Stream->width << "x"
1493 << camera3Stream->height << ")"
1494 << "[" << utils::hex(camera3Stream->format) << "] -> "
1495 << "(" << cameraStream->configuration().size.toString() << ")["
1496 << cameraStream->configuration().pixelFormat.toString() << "]";
1497
Jacopo Mondide8304b2020-09-04 17:45:39 +02001498 /*
1499 * Inspect the camera stream type, create buffers opportunely
1500 * and add them to the Request if required.
1501 */
1502 FrameBuffer *buffer = nullptr;
1503 switch (cameraStream->type()) {
1504 case CameraStream::Type::Mapped:
1505 /*
1506 * Mapped streams don't need buffers added to the
1507 * Request.
1508 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001509 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001510 continue;
1511
Jacopo Mondide8304b2020-09-04 17:45:39 +02001512 case CameraStream::Type::Direct:
1513 /*
1514 * Create a libcamera buffer using the dmabuf
1515 * descriptors of the camera3Buffer for each stream and
1516 * associate it with the Camera3RequestDescriptor for
1517 * lifetime management only.
1518 */
1519 buffer = createFrameBuffer(*camera3Buffers[i].buffer);
Kieran Bingham37c18c22020-10-21 14:54:11 +01001520 descriptor->frameBuffers_.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001521 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001522 break;
1523
1524 case CameraStream::Type::Internal:
1525 /*
1526 * Get the frame buffer from the CameraStream internal
1527 * buffer pool.
1528 *
1529 * The buffer has to be returned to the CameraStream
1530 * once it has been processed.
1531 */
1532 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001533 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001534 break;
1535 }
1536
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001537 if (!buffer) {
1538 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001539 delete descriptor;
1540 return -ENOMEM;
1541 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001542
Kieran Bingham37c18c22020-10-21 14:54:11 +01001543 descriptor->request_->addBuffer(cameraStream->stream(), buffer,
1544 camera3Buffers[i].acquire_fence);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001545 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001546
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001547 /* Queue the request to the CameraWorker. */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001548 worker_.queueRequest(descriptor->request_.get());
Paul Elderc7532232020-09-23 19:05:41 +09001549
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001550 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001551}
1552
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001553void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001554{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001555 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001556 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001557 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001558 Camera3RequestDescriptor *descriptor =
1559 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001560
1561 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001562 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001563 << request->status();
1564 status = CAMERA3_BUFFER_STATUS_ERROR;
1565 }
1566
Kieran Binghamc09aee42020-07-28 14:01:19 +01001567 /*
1568 * \todo The timestamp used for the metadata is currently always taken
1569 * from the first buffer (which may be the first stream) in the Request.
1570 * It might be appropriate to return a 'correct' (as determined by
1571 * pipeline handlers) timestamp in the Request itself.
1572 */
Hirokazu Honda3a777d82020-10-28 17:57:26 +09001573 uint64_t timestamp = buffers.begin()->second->metadata().timestamp;
Kieran Binghame1f9fdb2020-10-21 15:31:10 +01001574 resultMetadata = getResultMetadata(descriptor->frameNumber_, timestamp);
Kieran Binghamc09aee42020-07-28 14:01:19 +01001575
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001576 /* Handle any JPEG compression. */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001577 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001578 CameraStream *cameraStream =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001579 static_cast<CameraStream *>(descriptor->buffers_[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001580
Jacopo Mondi160bb092020-10-02 20:48:35 +02001581 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001582 continue;
1583
Jacopo Mondi216030a2020-10-03 11:36:41 +02001584 FrameBuffer *buffer = request->findBuffer(cameraStream->stream());
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001585 if (!buffer) {
1586 LOG(HAL, Error) << "Failed to find a source stream buffer";
1587 continue;
1588 }
1589
1590 /*
1591 * \todo Buffer mapping and compression should be moved to a
1592 * separate thread.
1593 */
1594
Kieran Bingham37c18c22020-10-21 14:54:11 +01001595 MappedCamera3Buffer mapped(*descriptor->buffers_[i].buffer,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001596 PROT_READ | PROT_WRITE);
1597 if (!mapped.isValid()) {
1598 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1599 continue;
1600 }
1601
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02001602 int ret = cameraStream->process(*buffer, &mapped,
1603 resultMetadata.get());
1604 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001605 status = CAMERA3_BUFFER_STATUS_ERROR;
1606 continue;
1607 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02001608
1609 /*
1610 * Return the FrameBuffer to the CameraStream now that we're
1611 * done processing it.
1612 */
1613 if (cameraStream->type() == CameraStream::Type::Internal)
1614 cameraStream->putBuffer(buffer);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001615 }
1616
1617 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001618 camera3_capture_result_t captureResult = {};
Kieran Bingham37c18c22020-10-21 14:54:11 +01001619 captureResult.frame_number = descriptor->frameNumber_;
1620 captureResult.num_output_buffers = descriptor->numBuffers_;
1621 for (unsigned int i = 0; i < descriptor->numBuffers_; ++i) {
1622 descriptor->buffers_[i].acquire_fence = -1;
1623 descriptor->buffers_[i].release_fence = -1;
1624 descriptor->buffers_[i].status = status;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001625 }
1626 captureResult.output_buffers =
Kieran Bingham37c18c22020-10-21 14:54:11 +01001627 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers_);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001628
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001629
Laurent Pinchart39860092019-09-05 03:12:34 +03001630 if (status == CAMERA3_BUFFER_STATUS_OK) {
Kieran Binghame1f9fdb2020-10-21 15:31:10 +01001631 notifyShutter(descriptor->frameNumber_, timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001632
1633 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001634 captureResult.result = resultMetadata->get();
1635 }
1636
1637 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1638 /* \todo Improve error handling. In case we notify an error
1639 * because the metadata generation fails, a shutter event has
1640 * already been notified for this frame number before the error
1641 * is here signalled. Make sure the error path plays well with
1642 * the camera stack state machine.
1643 */
Kieran Bingham37c18c22020-10-21 14:54:11 +01001644 notifyError(descriptor->frameNumber_,
1645 descriptor->buffers_[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001646 }
1647
1648 callbacks_->process_capture_result(callbacks_, &captureResult);
1649
1650 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001651}
1652
Jacopo Mondia7b92772020-05-26 15:41:41 +02001653std::string CameraDevice::logPrefix() const
1654{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001655 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001656}
1657
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001658void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1659{
1660 camera3_notify_msg_t notify = {};
1661
1662 notify.type = CAMERA3_MSG_SHUTTER;
1663 notify.message.shutter.frame_number = frameNumber;
1664 notify.message.shutter.timestamp = timestamp;
1665
1666 callbacks_->notify(callbacks_, &notify);
1667}
1668
1669void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1670{
1671 camera3_notify_msg_t notify = {};
1672
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001673 /*
1674 * \todo Report and identify the stream number or configuration to
1675 * clarify the stream that failed.
1676 */
1677 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1678 << toPixelFormat(stream->format).toString() << ")";
1679
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001680 notify.type = CAMERA3_MSG_ERROR;
1681 notify.message.error.error_stream = stream;
1682 notify.message.error.frame_number = frameNumber;
1683 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1684
1685 callbacks_->notify(callbacks_, &notify);
1686}
1687
1688/*
1689 * Produce a set of fixed result metadata.
1690 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001691std::unique_ptr<CameraMetadata>
1692CameraDevice::getResultMetadata([[maybe_unused]] int frame_number,
1693 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001694{
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001695 /*
1696 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001697 * Currently: 18 entries, 62 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001698 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001699 std::unique_ptr<CameraMetadata> resultMetadata =
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001700 std::make_unique<CameraMetadata>(18, 62);
Laurent Pinchart39860092019-09-05 03:12:34 +03001701 if (!resultMetadata->isValid()) {
1702 LOG(HAL, Error) << "Failed to allocate static metadata";
1703 return nullptr;
1704 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001705
1706 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001707 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001708
1709 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001710 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001711
1712 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001713 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001714
1715 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001716 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001717
1718 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001719 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001720
1721 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001722 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001723
1724 int32_t sensorSizes[] = {
1725 0, 0, 2560, 1920,
1726 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001727 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001728
Laurent Pinchart39860092019-09-05 03:12:34 +03001729 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001730
1731 /* 33.3 msec */
1732 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001733 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1734 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001735
1736 /* 16.6 msec */
1737 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001738 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1739 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001740
1741 const uint8_t lens_shading_map_mode =
1742 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001743 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1744 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001745
1746 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001747 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1748 &scene_flicker, 1);
1749
1750 /*
1751 * Return the result metadata pack even is not valid: get() will return
1752 * nullptr.
1753 */
1754 if (!resultMetadata->isValid()) {
1755 LOG(HAL, Error) << "Failed to construct result metadata";
1756 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001757
1758 return resultMetadata;
1759}