blob: 25829918cd290266a4d875135e9265eda20897ec [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"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020010
Kieran Bingham83ae84e2020-07-03 12:34:59 +010011#include <sys/mman.h>
Jacopo Mondia80d3812020-05-26 12:31:35 +020012#include <tuple>
Jacopo Mondi117588b2020-05-23 18:53:54 +020013#include <vector>
14
Jacopo Mondi857a2162019-11-20 17:00:49 +010015#include <libcamera/controls.h>
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030016#include <libcamera/formats.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010017#include <libcamera/property_ids.h>
18
Niklas Söderlund7876d632020-07-21 00:16:24 +020019#include "libcamera/internal/formats.h"
Laurent Pinchart93e72b62020-05-12 00:58:34 +030020#include "libcamera/internal/log.h"
21#include "libcamera/internal/utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020022
Laurent Pinchart39860092019-09-05 03:12:34 +030023#include "camera_metadata.h"
Jacopo Mondi117588b2020-05-23 18:53:54 +020024#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020025
Kieran Bingham83ae84e2020-07-03 12:34:59 +010026#include "jpeg/encoder_libjpeg.h"
27
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020028using 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
131} /* namespace */
132
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200133LOG_DECLARE_CATEGORY(HAL);
134
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100135class MappedCamera3Buffer : public MappedBuffer
136{
137public:
138 MappedCamera3Buffer(const buffer_handle_t camera3buffer, int flags);
139};
140
141MappedCamera3Buffer::MappedCamera3Buffer(const buffer_handle_t camera3buffer,
142 int flags)
143{
144 maps_.reserve(camera3buffer->numFds);
145 error_ = 0;
146
147 for (int i = 0; i < camera3buffer->numFds; i++) {
148 if (camera3buffer->data[i] == -1)
149 continue;
150
151 off_t length = lseek(camera3buffer->data[i], 0, SEEK_END);
152 if (length < 0) {
153 error_ = -errno;
154 LOG(HAL, Error) << "Failed to query plane length";
155 break;
156 }
157
158 void *address = mmap(nullptr, length, flags, MAP_SHARED,
159 camera3buffer->data[i], 0);
160 if (address == MAP_FAILED) {
161 error_ = -errno;
162 LOG(HAL, Error) << "Failed to mmap plane";
163 break;
164 }
165
166 maps_.emplace_back(static_cast<uint8_t *>(address),
167 static_cast<size_t>(length));
168 }
169}
170
171CameraStream::CameraStream(PixelFormat f, Size s)
172 : index(-1), format(f), size(s), jpeg(nullptr)
173{
174}
175
176CameraStream::~CameraStream()
177{
178 delete jpeg;
179};
180
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200181/*
182 * \struct Camera3RequestDescriptor
183 *
184 * A utility structure that groups information about a capture request to be
185 * later re-used at request complete time to notify the framework.
186 */
187
188CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
189 unsigned int frameNumber, unsigned int numBuffers)
190 : frameNumber(frameNumber), numBuffers(numBuffers)
191{
192 buffers = new camera3_stream_buffer_t[numBuffers];
Kieran Bingham0cfdf732020-07-01 13:36:24 +0100193 frameBuffers.reserve(numBuffers);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200194}
195
196CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
197{
198 delete[] buffers;
199}
200
201/*
202 * \class CameraDevice
203 *
204 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200205 * the camera3_device_t interface, bridging calls received from the Android
206 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200207 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200208 * The class translates parameters and operations from the Camera HALv3 API to
209 * the libcamera API to provide static information for a Camera, create request
210 * templates for it, process capture requests and then deliver capture results
211 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200212 */
213
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300214CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000215 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200216 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200217{
218 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100219
220 /*
221 * \todo Determine a more accurate value for this during
222 * streamConfiguration.
223 */
224 maxJpegBufferSize_ = 13 << 20; /* 13631488 from USB HAL */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200225}
226
227CameraDevice::~CameraDevice()
228{
229 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300230 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200231
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200232 for (auto &it : requestTemplates_)
233 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200234}
235
Umang Jainf8e28132020-08-21 14:46:08 +0000236std::shared_ptr<CameraDevice> CameraDevice::create(unsigned int id,
237 const std::shared_ptr<Camera> &cam)
238{
239 CameraDevice *camera = new CameraDevice(id, cam);
240 return std::shared_ptr<CameraDevice>(camera);
241}
242
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200243/*
244 * Initialize the camera static information.
245 * This method is called before the camera device is opened.
246 */
247int CameraDevice::initialize()
248{
249 /* Initialize orientation and facing side of the camera. */
250 const ControlList &properties = camera_->properties();
251
252 if (properties.contains(properties::Location)) {
253 int32_t location = properties.get(properties::Location);
254 switch (location) {
255 case properties::CameraLocationFront:
256 facing_ = CAMERA_FACING_FRONT;
257 break;
258 case properties::CameraLocationBack:
259 facing_ = CAMERA_FACING_BACK;
260 break;
261 case properties::CameraLocationExternal:
262 facing_ = CAMERA_FACING_EXTERNAL;
263 break;
264 }
265 }
266
267 /*
268 * The Android orientation metadata and libcamera rotation property are
269 * defined differently but have identical numerical values for Android
270 * devices such as phones and tablets.
271 */
272 if (properties.contains(properties::Rotation))
273 orientation_ = properties.get(properties::Rotation);
274
Jacopo Mondi117588b2020-05-23 18:53:54 +0200275 int ret = camera_->acquire();
276 if (ret) {
277 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
278 return ret;
279 }
280
281 ret = initializeStreamConfigurations();
282 camera_->release();
283 return ret;
284}
285
286/*
287 * Initialize the format conversion map to translate from Android format
288 * identifier to libcamera pixel formats and fill in the list of supported
289 * stream configurations to be reported to the Android camera framework through
290 * the static stream configuration metadata.
291 */
292int CameraDevice::initializeStreamConfigurations()
293{
294 /*
295 * Get the maximum output resolutions
296 * \todo Get this from the camera properties once defined
297 */
298 std::unique_ptr<CameraConfiguration> cameraConfig =
299 camera_->generateConfiguration({ StillCapture });
300 if (!cameraConfig) {
301 LOG(HAL, Error) << "Failed to get maximum resolution";
302 return -EINVAL;
303 }
304 StreamConfiguration &cfg = cameraConfig->at(0);
305
306 /*
307 * \todo JPEG - Adjust the maximum available resolution by taking the
308 * JPEG encoder requirements into account (alignment and aspect ratio).
309 */
310 const Size maxRes = cfg.size;
311 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
312
313 /*
314 * Build the list of supported image resolutions.
315 *
316 * The resolutions listed in camera3Resolution are mandatory to be
317 * supported, up to the camera maximum resolution.
318 *
319 * Augment the list by adding resolutions calculated from the camera
320 * maximum one.
321 */
322 std::vector<Size> cameraResolutions;
323 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
324 std::back_inserter(cameraResolutions),
325 [&](const Size &res) { return res < maxRes; });
326
327 /*
328 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
329 * resolution.
330 */
331 for (unsigned int divider = 2;; divider <<= 1) {
332 Size derivedSize{
333 maxRes.width / divider,
334 maxRes.height / divider,
335 };
336
337 if (derivedSize.width < 320 ||
338 derivedSize.height < 240)
339 break;
340
341 cameraResolutions.push_back(derivedSize);
342 }
343 cameraResolutions.push_back(maxRes);
344
345 /* Remove duplicated entries from the list of supported resolutions. */
346 std::sort(cameraResolutions.begin(), cameraResolutions.end());
347 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
348 cameraResolutions.erase(last, cameraResolutions.end());
349
350 /*
351 * Build the list of supported camera formats.
352 *
353 * To each Android format a list of compatible libcamera formats is
354 * associated. The first libcamera format that tests successful is added
355 * to the format translation map used when configuring the streams.
356 * It is then tested against the list of supported camera resolutions to
357 * build the stream configuration map reported through the camera static
358 * metadata.
359 */
360 for (const auto &format : camera3FormatsMap) {
361 int androidFormat = format.first;
362 const Camera3Format &camera3Format = format.second;
363 const std::vector<PixelFormat> &libcameraFormats =
364 camera3Format.libcameraFormats;
365
366 /*
367 * Test the libcamera formats that can produce images
368 * compatible with the format defined by Android.
369 */
370 PixelFormat mappedFormat;
371 for (const PixelFormat &pixelFormat : libcameraFormats) {
372 /* \todo Fixed mapping for JPEG. */
373 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +0300374 mappedFormat = formats::MJPEG;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200375 break;
376 }
377
378 /*
379 * The stream configuration size can be adjusted,
380 * not the pixel format.
381 *
382 * \todo This could be simplified once all pipeline
383 * handlers will report the StreamFormats list of
384 * supported formats.
385 */
386 cfg.pixelFormat = pixelFormat;
387
388 CameraConfiguration::Status status = cameraConfig->validate();
389 if (status != CameraConfiguration::Invalid &&
390 cfg.pixelFormat == pixelFormat) {
391 mappedFormat = pixelFormat;
392 break;
393 }
394 }
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +0200395 if (camera3Format.mandatory && !mappedFormat.isValid()) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200396 LOG(HAL, Error) << "Failed to map Android format "
397 << camera3Format.name << " ("
398 << utils::hex(androidFormat) << ")";
399 return -EINVAL;
400 }
401
402 /*
403 * Record the mapping and then proceed to generate the
404 * stream configurations map, by testing the image resolutions.
405 */
406 formatsMap_[androidFormat] = mappedFormat;
407
408 for (const Size &res : cameraResolutions) {
409 cfg.pixelFormat = mappedFormat;
410 cfg.size = res;
411
412 CameraConfiguration::Status status = cameraConfig->validate();
413 /*
414 * Unconditionally report we can produce JPEG.
415 *
416 * \todo The JPEG stream will be implemented as an
417 * HAL-only stream, but some cameras can produce it
418 * directly. As of now, claim support for JPEG without
419 * inspecting where the JPEG stream is produced.
420 */
421 if (androidFormat != HAL_PIXEL_FORMAT_BLOB &&
422 status != CameraConfiguration::Valid)
423 continue;
424
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200425 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200426 }
427 }
428
429 LOG(HAL, Debug) << "Collected stream configuration map: ";
430 for (const auto &entry : streamConfigurations_)
431 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200432 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200433
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200434 return 0;
435}
436
437/*
438 * Open a camera device. The static information on the camera shall have been
439 * initialized with a call to CameraDevice::initialize().
440 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200441int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200442{
443 int ret = camera_->acquire();
444 if (ret) {
445 LOG(HAL, Error) << "Failed to acquire the camera";
446 return ret;
447 }
448
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200449 /* Initialize the hw_device_t in the instance camera3_module_t. */
450 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
451 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
452 camera3Device_.common.module = (hw_module_t *)hardwareModule;
453 camera3Device_.common.close = hal_dev_close;
454
455 /*
456 * The camera device operations. These actually implement
457 * the Android Camera HALv3 interface.
458 */
459 camera3Device_.ops = &hal_dev_ops;
460 camera3Device_.priv = this;
461
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200462 return 0;
463}
464
465void CameraDevice::close()
466{
467 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200468 camera_->release();
469
470 running_ = false;
471}
472
473void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
474{
475 callbacks_ = callbacks;
476}
477
Jacopo Mondia80d3812020-05-26 12:31:35 +0200478std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
479{
480 /*
481 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100482 * Currently: 51 entries, 687 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200483 */
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100484 uint32_t numEntries = 51;
485 uint32_t byteSize = 687;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200486
487 /*
488 * Calculate space occupation in bytes for dynamically built metadata
489 * entries.
490 *
491 * Each stream configuration entry requires 52 bytes:
492 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200493 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
494 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200495 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200496
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300497 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200498}
499
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200500/*
501 * Return static information for the camera.
502 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200503const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200504{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200505 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300506 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200507
508 /*
509 * The here reported metadata are enough to implement a basic capture
510 * example application, but a real camera implementation will require
511 * more.
512 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200513 uint32_t numEntries;
514 uint32_t byteSize;
515 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
516 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300517 if (!staticMetadata_->isValid()) {
518 LOG(HAL, Error) << "Failed to allocate static metadata";
519 delete staticMetadata_;
520 staticMetadata_ = nullptr;
521 return nullptr;
522 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200523
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200524 /* Color correction static metadata. */
525 std::vector<uint8_t> aberrationModes = {
526 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
527 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300528 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
529 aberrationModes.data(),
530 aberrationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200531
532 /* Control static metadata. */
533 std::vector<uint8_t> aeAvailableAntiBandingModes = {
534 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
535 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
536 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
537 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
538 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300539 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
540 aeAvailableAntiBandingModes.data(),
541 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200542
543 std::vector<uint8_t> aeAvailableModes = {
544 ANDROID_CONTROL_AE_MODE_ON,
545 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300546 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
547 aeAvailableModes.data(),
548 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200549
550 std::vector<int32_t> availableAeFpsTarget = {
551 15, 30,
552 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300553 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
554 availableAeFpsTarget.data(),
555 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200556
557 std::vector<int32_t> aeCompensationRange = {
558 0, 0,
559 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300560 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
561 aeCompensationRange.data(),
562 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200563
564 const camera_metadata_rational_t aeCompensationStep[] = {
565 { 0, 1 }
566 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300567 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
568 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200569
570 std::vector<uint8_t> availableAfModes = {
571 ANDROID_CONTROL_AF_MODE_OFF,
572 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300573 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
574 availableAfModes.data(),
575 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200576
577 std::vector<uint8_t> availableEffects = {
578 ANDROID_CONTROL_EFFECT_MODE_OFF,
579 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300580 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
581 availableEffects.data(),
582 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200583
584 std::vector<uint8_t> availableSceneModes = {
585 ANDROID_CONTROL_SCENE_MODE_DISABLED,
586 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300587 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
588 availableSceneModes.data(),
589 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200590
591 std::vector<uint8_t> availableStabilizationModes = {
592 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
593 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300594 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
595 availableStabilizationModes.data(),
596 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200597
598 std::vector<uint8_t> availableAwbModes = {
599 ANDROID_CONTROL_AWB_MODE_OFF,
600 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300601 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
602 availableAwbModes.data(),
603 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200604
605 std::vector<int32_t> availableMaxRegions = {
606 0, 0, 0,
607 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300608 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
609 availableMaxRegions.data(),
610 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200611
612 std::vector<uint8_t> sceneModesOverride = {
613 ANDROID_CONTROL_AE_MODE_ON,
614 ANDROID_CONTROL_AWB_MODE_AUTO,
615 ANDROID_CONTROL_AF_MODE_AUTO,
616 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300617 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
618 sceneModesOverride.data(),
619 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200620
621 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300622 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
623 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200624
625 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300626 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
627 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200628
629 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300630 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
631 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200632
633 /* JPEG static metadata. */
634 std::vector<int32_t> availableThumbnailSizes = {
635 0, 0,
636 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300637 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
638 availableThumbnailSizes.data(),
639 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200640
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100641 /*
642 * \todo Calculate the maximum JPEG buffer size by asking the encoder
643 * giving the maximum frame size required.
644 */
645 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
646
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200647 /* Sensor static metadata. */
648 int32_t pixelArraySize[] = {
649 2592, 1944,
650 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300651 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
652 &pixelArraySize, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200653
654 int32_t sensorSizes[] = {
655 0, 0, 2560, 1920,
656 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300657 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
658 &sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200659
660 int32_t sensitivityRange[] = {
661 32, 2400,
662 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300663 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
664 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200665
666 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300667 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
668 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200669
670 int64_t exposureTimeRange[] = {
671 100000, 200000000,
672 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300673 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
674 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200675
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200676 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200677
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200678 std::vector<int32_t> testPatterModes = {
679 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
680 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300681 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
682 testPatterModes.data(),
683 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200684
685 std::vector<float> physicalSize = {
686 2592, 1944,
687 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300688 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
689 physicalSize.data(),
690 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200691
692 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300693 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
694 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200695
696 /* Statistics static metadata. */
697 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300698 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
699 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200700
701 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300702 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
703 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200704
705 /* Sync static metadata. */
706 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300707 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200708
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200709 /* Flash static metadata. */
710 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300711 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
712 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200713
714 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200715 std::vector<float> lensApertures = {
716 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200717 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300718 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
719 lensApertures.data(),
720 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200721
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200722 uint8_t lensFacing;
723 switch (facing_) {
724 default:
725 case CAMERA_FACING_FRONT:
726 lensFacing = ANDROID_LENS_FACING_FRONT;
727 break;
728 case CAMERA_FACING_BACK:
729 lensFacing = ANDROID_LENS_FACING_BACK;
730 break;
731 case CAMERA_FACING_EXTERNAL:
732 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
733 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100734 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300735 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200736
737 std::vector<float> lensFocalLenghts = {
738 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200739 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300740 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
741 lensFocalLenghts.data(),
742 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200743
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200744 std::vector<uint8_t> opticalStabilizations = {
745 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
746 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300747 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
748 opticalStabilizations.data(),
749 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200750
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200751 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300752 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
753 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200754
755 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300756 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
757 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200758
759 /* Noise reduction modes. */
760 uint8_t noiseReductionModes = ANDROID_NOISE_REDUCTION_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300761 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
762 &noiseReductionModes, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200763
764 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200765 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300766 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
767 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200768
Jacopo Mondibde7b982020-05-25 17:18:28 +0200769 std::vector<uint32_t> availableStreamConfigurations;
770 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
771 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200772 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200773 availableStreamConfigurations.push_back(entry.resolution.width);
774 availableStreamConfigurations.push_back(entry.resolution.height);
775 availableStreamConfigurations.push_back(
776 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
777 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300778 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
779 availableStreamConfigurations.data(),
780 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200781
782 std::vector<int64_t> availableStallDurations = {
783 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
784 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300785 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
786 availableStallDurations.data(),
787 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200788
Jacopo Mondibde7b982020-05-25 17:18:28 +0200789 /* \todo Collect the minimum frame duration from the camera. */
790 std::vector<int64_t> minFrameDurations;
791 minFrameDurations.reserve(streamConfigurations_.size() * 4);
792 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200793 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200794 minFrameDurations.push_back(entry.resolution.width);
795 minFrameDurations.push_back(entry.resolution.height);
796 minFrameDurations.push_back(33333333);
797 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300798 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
799 minFrameDurations.data(),
800 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200801
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200802 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300803 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200804
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200805 /* Info static metadata. */
806 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300807 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
808 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200809
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200810 /* Request static metadata. */
811 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300812 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
813 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200814
815 uint8_t maxPipelineDepth = 2;
Laurent Pinchart39860092019-09-05 03:12:34 +0300816 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
817 &maxPipelineDepth, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200818
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200819 /* LIMITED does not support reprocessing. */
820 uint32_t maxNumInputStreams = 0;
821 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
822 &maxNumInputStreams, 1);
823
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200824 std::vector<uint8_t> availableCapabilities = {
825 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
826 };
Niklas Söderlund7876d632020-07-21 00:16:24 +0200827
828 /* Report if camera supports RAW. */
829 std::unique_ptr<CameraConfiguration> cameraConfig =
830 camera_->generateConfiguration({ StillCaptureRaw });
831 if (cameraConfig && !cameraConfig->empty()) {
832 const PixelFormatInfo &info =
833 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
834 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
835 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
836 }
837
Laurent Pinchart39860092019-09-05 03:12:34 +0300838 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
839 availableCapabilities.data(),
840 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200841
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200842 std::vector<int32_t> availableCharacteristicsKeys = {
843 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
844 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
845 ANDROID_CONTROL_AE_AVAILABLE_MODES,
846 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
847 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
848 ANDROID_CONTROL_AE_COMPENSATION_STEP,
849 ANDROID_CONTROL_AF_AVAILABLE_MODES,
850 ANDROID_CONTROL_AVAILABLE_EFFECTS,
851 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
852 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
853 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
854 ANDROID_CONTROL_MAX_REGIONS,
855 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
856 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
857 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
858 ANDROID_CONTROL_AVAILABLE_MODES,
859 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100860 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200861 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
862 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
863 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
864 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
865 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
866 ANDROID_SENSOR_ORIENTATION,
867 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
868 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
869 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
870 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
871 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
872 ANDROID_SYNC_MAX_LATENCY,
873 ANDROID_FLASH_INFO_AVAILABLE,
874 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
875 ANDROID_LENS_FACING,
876 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
877 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
878 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
879 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
880 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
881 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200882 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
883 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
884 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
885 ANDROID_SCALER_CROPPING_TYPE,
886 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
887 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
888 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200889 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200890 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
891 };
892 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
893 availableCharacteristicsKeys.data(),
894 availableCharacteristicsKeys.size());
895
896 std::vector<int32_t> availableRequestKeys = {
897 ANDROID_CONTROL_AE_MODE,
898 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
899 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200900 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
901 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200902 ANDROID_CONTROL_AE_LOCK,
903 ANDROID_CONTROL_AF_TRIGGER,
904 ANDROID_CONTROL_AWB_MODE,
905 ANDROID_CONTROL_AWB_LOCK,
906 ANDROID_FLASH_MODE,
907 ANDROID_STATISTICS_FACE_DETECT_MODE,
908 ANDROID_NOISE_REDUCTION_MODE,
909 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200910 ANDROID_LENS_APERTURE,
911 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
912 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200913 ANDROID_CONTROL_CAPTURE_INTENT,
914 };
915 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
916 availableRequestKeys.data(),
917 availableRequestKeys.size());
918
919 std::vector<int32_t> availableResultKeys = {
920 ANDROID_CONTROL_AE_STATE,
921 ANDROID_CONTROL_AE_LOCK,
922 ANDROID_CONTROL_AF_STATE,
923 ANDROID_CONTROL_AWB_STATE,
924 ANDROID_CONTROL_AWB_LOCK,
925 ANDROID_LENS_STATE,
926 ANDROID_SCALER_CROP_REGION,
927 ANDROID_SENSOR_TIMESTAMP,
928 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
929 ANDROID_SENSOR_EXPOSURE_TIME,
930 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
931 ANDROID_STATISTICS_SCENE_FLICKER,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100932 ANDROID_JPEG_SIZE,
933 ANDROID_JPEG_QUALITY,
934 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200935 };
936 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
937 availableResultKeys.data(),
938 availableResultKeys.size());
939
Laurent Pinchart39860092019-09-05 03:12:34 +0300940 if (!staticMetadata_->isValid()) {
941 LOG(HAL, Error) << "Failed to construct static metadata";
942 delete staticMetadata_;
943 staticMetadata_ = nullptr;
944 return nullptr;
945 }
946
947 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200948}
949
Jacopo Mondi8a02d442020-07-24 15:47:50 +0200950CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200951{
Jacopo Mondi63703472019-09-04 16:18:22 +0200952 /*
953 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200954 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +0200955 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200956 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200957 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200958 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200959 return nullptr;
960 }
961
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200962 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200963 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
964 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200965
966 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200967 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
968 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200969
970 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200971 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
972 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200973
974 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200975 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
976 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200977
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200978 std::vector<int32_t> aeFpsTarget = {
979 15, 30,
980 };
981 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
982 aeFpsTarget.data(),
983 aeFpsTarget.size());
984
985 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
986 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
987 &aeAntibandingMode, 1);
988
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200989 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200990 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
991 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200992
993 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200994 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
995 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200996
997 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200998 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
999 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001000
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001001 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001002 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1003 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001004
1005 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001006 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1007 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001008
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001009 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001010 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1011 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001012
1013 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001014 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1015 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001016
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001017 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1018 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1019
1020 float lensAperture = 2.53 / 100;
1021 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1022
1023 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1024 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1025 &opticalStabilization, 1);
1026
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001027 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001028 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1029 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001030
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001031 return requestTemplate;
1032}
1033
1034/*
1035 * Produce a metadata pack to be used as template for a capture request.
1036 */
1037const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1038{
1039 auto it = requestTemplates_.find(type);
1040 if (it != requestTemplates_.end())
1041 return it->second->get();
1042
1043 /* Use the capture intent matching the requested template type. */
1044 CameraMetadata *requestTemplate;
1045 uint8_t captureIntent;
1046 switch (type) {
1047 case CAMERA3_TEMPLATE_PREVIEW:
1048 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1049 break;
1050 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1051 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1052 break;
1053 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1054 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1055 break;
1056 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1057 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1058 break;
1059 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1060 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1061 break;
1062 case CAMERA3_TEMPLATE_MANUAL:
1063 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1064 break;
1065 default:
1066 LOG(HAL, Error) << "Invalid template request type: " << type;
1067 return nullptr;
1068 }
1069
1070 requestTemplate = requestTemplatePreview();
1071 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001072 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001073 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001074 return nullptr;
1075 }
1076
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001077 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1078 &captureIntent, 1);
1079
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001080 requestTemplates_[type] = requestTemplate;
1081 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001082}
1083
Kieran Bingham43e3b802020-06-26 09:58:49 +01001084PixelFormat CameraDevice::toPixelFormat(int format)
1085{
1086 /* Translate Android format code to libcamera pixel format. */
1087 auto it = formatsMap_.find(format);
1088 if (it == formatsMap_.end()) {
1089 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1090 << " not supported";
1091 return PixelFormat();
1092 }
1093
1094 return it->second;
1095}
1096
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001097/*
1098 * Inspect the stream_list to produce a list of StreamConfiguration to
1099 * be use to configure the Camera.
1100 */
1101int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1102{
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001103 /*
1104 * Generate an empty configuration, and construct a StreamConfiguration
1105 * for each camera3_stream to add to it.
1106 */
1107 config_ = camera_->generateConfiguration();
1108 if (!config_) {
1109 LOG(HAL, Error) << "Failed to generate camera configuration";
1110 return -EINVAL;
1111 }
1112
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001113 /*
1114 * Clear and remove any existing configuration from previous calls, and
1115 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001116 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001117 */
1118 streams_.clear();
1119 streams_.reserve(stream_list->num_streams);
1120
1121 /*
1122 * Track actually created streams, as there may not be a 1:1 mapping of
1123 * camera3 streams to libcamera streams.
1124 */
1125 unsigned int streamIndex = 0;
1126
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001127 /* First handle all non-MJPEG streams. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001128 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1129 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001130 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001131
Kieran Bingham43e3b802020-06-26 09:58:49 +01001132 PixelFormat format = toPixelFormat(stream->format);
1133
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001134 LOG(HAL, Info) << "Stream #" << i
1135 << ", direction: " << stream->stream_type
1136 << ", width: " << stream->width
1137 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001138 << ", format: " << utils::hex(stream->format)
1139 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001140
1141 if (!format.isValid())
1142 return -EINVAL;
1143
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001144 streams_.emplace_back(format, size);
1145 stream->priv = static_cast<void *>(&streams_[i]);
1146
1147 /* Defer handling of MJPEG streams until all others are known. */
1148 if (format == formats::MJPEG)
1149 continue;
1150
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001151 StreamConfiguration streamConfiguration;
1152
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001153 streamConfiguration.size = size;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001154 streamConfiguration.pixelFormat = format;
1155
1156 config_->addConfiguration(streamConfiguration);
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001157
1158 streams_[i].index = streamIndex++;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001159 }
1160
1161 /* Now handle MJPEG streams, adding a new stream if required. */
1162 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1163 camera3_stream_t *stream = stream_list->streams[i];
1164 bool match = false;
1165
1166 if (streams_[i].format != formats::MJPEG)
1167 continue;
1168
1169 /* Search for a compatible stream */
1170 for (unsigned int j = 0; j < config_->size(); j++) {
1171 StreamConfiguration &cfg = config_->at(j);
1172
1173 /*
1174 * \todo The PixelFormat must also be compatible with
1175 * the encoder.
1176 */
1177 if (cfg.size == streams_[i].size) {
1178 LOG(HAL, Info) << "Stream " << i
1179 << " using libcamera stream " << j;
1180
1181 match = true;
1182 streams_[i].index = j;
1183 }
1184 }
1185
1186 /*
1187 * Without a compatible match for JPEG encoding we must
1188 * introduce a new stream to satisfy the request requirements.
1189 */
1190 if (!match) {
1191 StreamConfiguration streamConfiguration;
1192
1193 /*
1194 * \todo The pixelFormat should be a 'best-fit' choice
1195 * and may require a validation cycle. This is not yet
1196 * handled, and should be considered as part of any
1197 * stream configuration reworks.
1198 */
1199 streamConfiguration.size.width = stream->width;
1200 streamConfiguration.size.height = stream->height;
1201 streamConfiguration.pixelFormat = formats::NV12;
1202
1203 LOG(HAL, Info) << "Adding " << streamConfiguration.toString()
1204 << " for MJPEG support";
1205
1206 config_->addConfiguration(streamConfiguration);
1207 streams_[i].index = streamIndex++;
1208 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001209 }
1210
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001211 switch (config_->validate()) {
1212 case CameraConfiguration::Valid:
1213 break;
1214 case CameraConfiguration::Adjusted:
1215 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001216
1217 for (const StreamConfiguration &cfg : *config_)
1218 LOG(HAL, Info) << " - " << cfg.toString();
1219
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001220 config_.reset();
1221 return -EINVAL;
1222 case CameraConfiguration::Invalid:
1223 LOG(HAL, Info) << "Camera configuration invalid";
1224 config_.reset();
1225 return -EINVAL;
1226 }
1227
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001228 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1229 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001230 CameraStream *cameraStream = &streams_[i];
1231 StreamConfiguration &cfg = config_->at(cameraStream->index);
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001232
1233 /* Use the bufferCount confirmed by the validation process. */
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001234 stream->max_buffers = cfg.bufferCount;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001235
1236 /*
1237 * Construct a software encoder for MJPEG streams from the
1238 * chosen libcamera source stream.
1239 */
1240 if (cameraStream->format == formats::MJPEG) {
1241 cameraStream->jpeg = new EncoderLibJpeg();
1242 int ret = cameraStream->jpeg->configure(cfg);
1243 if (ret) {
1244 LOG(HAL, Error)
1245 << "Failed to configure encoder";
1246 return ret;
1247 }
1248 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001249 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001250
1251 /*
1252 * Once the CameraConfiguration has been adjusted/validated
1253 * it can be applied to the camera.
1254 */
1255 int ret = camera_->configure(config_.get());
1256 if (ret) {
1257 LOG(HAL, Error) << "Failed to configure camera '"
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001258 << camera_->id() << "'";
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001259 return ret;
1260 }
1261
1262 return 0;
1263}
1264
Kieran Bingham74ab4422020-07-01 13:25:38 +01001265FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1266{
1267 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001268 for (int i = 0; i < camera3buffer->numFds; i++) {
1269 /* Skip unused planes. */
1270 if (camera3buffer->data[i] == -1)
1271 break;
1272
Kieran Bingham74ab4422020-07-01 13:25:38 +01001273 FrameBuffer::Plane plane;
1274 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001275 if (!plane.fd.isValid()) {
1276 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1277 << camera3buffer->data[i] << ") "
1278 << " on plane " << i;
1279 return nullptr;
1280 }
1281
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001282 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1283 if (length == -1) {
1284 LOG(HAL, Error) << "Failed to query plane length";
1285 return nullptr;
1286 }
1287
1288 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001289 planes.push_back(std::move(plane));
1290 }
1291
1292 return new FrameBuffer(std::move(planes));
1293}
1294
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001295int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001296{
Kieran Bingham61f42962020-07-01 13:40:17 +01001297 if (!camera3Request->num_output_buffers) {
1298 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001299 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001300 }
1301
1302 /* Start the camera if that's the first request we handle. */
1303 if (!running_) {
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001304 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001305 if (ret) {
1306 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001307 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001308 }
1309
1310 running_ = true;
1311 }
1312
1313 /*
1314 * Queue a request for the Camera with the provided dmabuf file
1315 * descriptors.
1316 */
1317 const camera3_stream_buffer_t *camera3Buffers =
1318 camera3Request->output_buffers;
1319
1320 /*
1321 * Save the request descriptors for use at completion time.
1322 * The descriptor and the associated memory reserved here are freed
1323 * at request complete time.
1324 */
1325 Camera3RequestDescriptor *descriptor =
1326 new Camera3RequestDescriptor(camera3Request->frame_number,
1327 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001328
1329 Request *request =
1330 camera_->createRequest(reinterpret_cast<uint64_t>(descriptor));
1331
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001332 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001333 CameraStream *cameraStream =
1334 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1335
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001336 /*
1337 * Keep track of which stream the request belongs to and store
1338 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001339 */
1340 descriptor->buffers[i].stream = camera3Buffers[i].stream;
1341 descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001342
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001343 /* Software streams are handled after hardware streams complete. */
1344 if (cameraStream->format == formats::MJPEG)
1345 continue;
1346
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001347 /*
1348 * Create a libcamera buffer using the dmabuf descriptors of
1349 * the camera3Buffer for each stream. The FrameBuffer is
1350 * directly associated with the Camera3RequestDescriptor for
1351 * lifetime management only.
1352 */
1353 FrameBuffer *buffer = createFrameBuffer(*camera3Buffers[i].buffer);
1354 if (!buffer) {
1355 LOG(HAL, Error) << "Failed to create buffer";
1356 delete request;
1357 delete descriptor;
1358 return -ENOMEM;
1359 }
1360 descriptor->frameBuffers.emplace_back(buffer);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001361
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001362 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index);
1363 Stream *stream = streamConfiguration->stream();
1364
1365 request->addBuffer(stream, buffer);
1366 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001367
1368 int ret = camera_->queueRequest(request);
1369 if (ret) {
1370 LOG(HAL, Error) << "Failed to queue request";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001371 delete request;
1372 delete descriptor;
1373 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001374 }
1375
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001376 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001377}
1378
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001379void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001380{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02001381 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001382 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001383 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001384 Camera3RequestDescriptor *descriptor =
1385 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001386
1387 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001388 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001389 << request->status();
1390 status = CAMERA3_BUFFER_STATUS_ERROR;
1391 }
1392
Kieran Binghamc09aee42020-07-28 14:01:19 +01001393 /*
1394 * \todo The timestamp used for the metadata is currently always taken
1395 * from the first buffer (which may be the first stream) in the Request.
1396 * It might be appropriate to return a 'correct' (as determined by
1397 * pipeline handlers) timestamp in the Request itself.
1398 */
1399 FrameBuffer *buffer = buffers.begin()->second;
1400 resultMetadata = getResultMetadata(descriptor->frameNumber,
1401 buffer->metadata().timestamp);
1402
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001403 /* Handle any JPEG compression. */
1404 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
1405 CameraStream *cameraStream =
1406 static_cast<CameraStream *>(descriptor->buffers[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001407
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001408 if (cameraStream->format != formats::MJPEG)
1409 continue;
1410
1411 Encoder *encoder = cameraStream->jpeg;
1412 if (!encoder) {
1413 LOG(HAL, Error) << "Failed to identify encoder";
1414 continue;
1415 }
1416
1417 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index);
1418 Stream *stream = streamConfiguration->stream();
1419 FrameBuffer *buffer = request->findBuffer(stream);
1420 if (!buffer) {
1421 LOG(HAL, Error) << "Failed to find a source stream buffer";
1422 continue;
1423 }
1424
1425 /*
1426 * \todo Buffer mapping and compression should be moved to a
1427 * separate thread.
1428 */
1429
1430 MappedCamera3Buffer mapped(*descriptor->buffers[i].buffer,
1431 PROT_READ | PROT_WRITE);
1432 if (!mapped.isValid()) {
1433 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1434 continue;
1435 }
1436
1437 int jpeg_size = encoder->encode(buffer, mapped.maps()[0]);
1438 if (jpeg_size < 0) {
1439 LOG(HAL, Error) << "Failed to encode stream image";
1440 status = CAMERA3_BUFFER_STATUS_ERROR;
1441 continue;
1442 }
1443
1444 /*
1445 * Fill in the JPEG blob header.
1446 *
1447 * The mapped size of the buffer is being returned as
1448 * substantially larger than the requested JPEG_MAX_SIZE
1449 * (which is referenced from maxJpegBufferSize_). Utilise
1450 * this static size to ensure the correct offset of the blob is
1451 * determined.
1452 *
1453 * \todo Investigate if the buffer size mismatch is an issue or
1454 * expected behaviour.
1455 */
1456 uint8_t *resultPtr = mapped.maps()[0].data() +
1457 maxJpegBufferSize_ -
1458 sizeof(struct camera3_jpeg_blob);
1459 auto *blob = reinterpret_cast<struct camera3_jpeg_blob *>(resultPtr);
1460 blob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
1461 blob->jpeg_size = jpeg_size;
1462
1463 /* Update the JPEG result Metadata. */
1464 resultMetadata->addEntry(ANDROID_JPEG_SIZE,
1465 &jpeg_size, 1);
1466
1467 const uint32_t jpeg_quality = 95;
1468 resultMetadata->addEntry(ANDROID_JPEG_QUALITY,
1469 &jpeg_quality, 1);
1470
1471 const uint32_t jpeg_orientation = 0;
1472 resultMetadata->addEntry(ANDROID_JPEG_ORIENTATION,
1473 &jpeg_orientation, 1);
1474 }
1475
1476 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001477 camera3_capture_result_t captureResult = {};
1478 captureResult.frame_number = descriptor->frameNumber;
1479 captureResult.num_output_buffers = descriptor->numBuffers;
1480 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001481 descriptor->buffers[i].acquire_fence = -1;
1482 descriptor->buffers[i].release_fence = -1;
1483 descriptor->buffers[i].status = status;
1484 }
1485 captureResult.output_buffers =
1486 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers);
1487
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001488
Laurent Pinchart39860092019-09-05 03:12:34 +03001489 if (status == CAMERA3_BUFFER_STATUS_OK) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001490 notifyShutter(descriptor->frameNumber,
Niklas Söderlund9217f272019-11-22 16:22:56 +01001491 buffer->metadata().timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001492
1493 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001494 captureResult.result = resultMetadata->get();
1495 }
1496
1497 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1498 /* \todo Improve error handling. In case we notify an error
1499 * because the metadata generation fails, a shutter event has
1500 * already been notified for this frame number before the error
1501 * is here signalled. Make sure the error path plays well with
1502 * the camera stack state machine.
1503 */
1504 notifyError(descriptor->frameNumber,
1505 descriptor->buffers[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001506 }
1507
1508 callbacks_->process_capture_result(callbacks_, &captureResult);
1509
1510 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001511}
1512
Jacopo Mondia7b92772020-05-26 15:41:41 +02001513std::string CameraDevice::logPrefix() const
1514{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001515 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001516}
1517
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001518void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1519{
1520 camera3_notify_msg_t notify = {};
1521
1522 notify.type = CAMERA3_MSG_SHUTTER;
1523 notify.message.shutter.frame_number = frameNumber;
1524 notify.message.shutter.timestamp = timestamp;
1525
1526 callbacks_->notify(callbacks_, &notify);
1527}
1528
1529void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1530{
1531 camera3_notify_msg_t notify = {};
1532
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001533 /*
1534 * \todo Report and identify the stream number or configuration to
1535 * clarify the stream that failed.
1536 */
1537 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1538 << toPixelFormat(stream->format).toString() << ")";
1539
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001540 notify.type = CAMERA3_MSG_ERROR;
1541 notify.message.error.error_stream = stream;
1542 notify.message.error.frame_number = frameNumber;
1543 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1544
1545 callbacks_->notify(callbacks_, &notify);
1546}
1547
1548/*
1549 * Produce a set of fixed result metadata.
1550 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03001551std::unique_ptr<CameraMetadata>
1552CameraDevice::getResultMetadata([[maybe_unused]] int frame_number,
1553 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001554{
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001555 /*
1556 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001557 * Currently: 18 entries, 62 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001558 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001559 std::unique_ptr<CameraMetadata> resultMetadata =
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001560 std::make_unique<CameraMetadata>(18, 62);
Laurent Pinchart39860092019-09-05 03:12:34 +03001561 if (!resultMetadata->isValid()) {
1562 LOG(HAL, Error) << "Failed to allocate static metadata";
1563 return nullptr;
1564 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001565
1566 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001567 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001568
1569 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001570 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001571
1572 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001573 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001574
1575 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001576 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001577
1578 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001579 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001580
1581 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001582 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001583
1584 int32_t sensorSizes[] = {
1585 0, 0, 2560, 1920,
1586 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001587 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001588
Laurent Pinchart39860092019-09-05 03:12:34 +03001589 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001590
1591 /* 33.3 msec */
1592 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001593 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1594 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001595
1596 /* 16.6 msec */
1597 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001598 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1599 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001600
1601 const uint8_t lens_shading_map_mode =
1602 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001603 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1604 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001605
1606 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001607 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1608 &scene_flicker, 1);
1609
1610 /*
1611 * Return the result metadata pack even is not valid: get() will return
1612 * nullptr.
1613 */
1614 if (!resultMetadata->isValid()) {
1615 LOG(HAL, Error) << "Failed to construct result metadata";
1616 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001617
1618 return resultMetadata;
1619}