blob: d9183501228f46425aa367f2e88cf5eb4ca5d1a5 [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
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200236/*
237 * Initialize the camera static information.
238 * This method is called before the camera device is opened.
239 */
240int CameraDevice::initialize()
241{
242 /* Initialize orientation and facing side of the camera. */
243 const ControlList &properties = camera_->properties();
244
245 if (properties.contains(properties::Location)) {
246 int32_t location = properties.get(properties::Location);
247 switch (location) {
248 case properties::CameraLocationFront:
249 facing_ = CAMERA_FACING_FRONT;
250 break;
251 case properties::CameraLocationBack:
252 facing_ = CAMERA_FACING_BACK;
253 break;
254 case properties::CameraLocationExternal:
255 facing_ = CAMERA_FACING_EXTERNAL;
256 break;
257 }
258 }
259
260 /*
261 * The Android orientation metadata and libcamera rotation property are
262 * defined differently but have identical numerical values for Android
263 * devices such as phones and tablets.
264 */
265 if (properties.contains(properties::Rotation))
266 orientation_ = properties.get(properties::Rotation);
267
Jacopo Mondi117588b2020-05-23 18:53:54 +0200268 int ret = camera_->acquire();
269 if (ret) {
270 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
271 return ret;
272 }
273
274 ret = initializeStreamConfigurations();
275 camera_->release();
276 return ret;
277}
278
279/*
280 * Initialize the format conversion map to translate from Android format
281 * identifier to libcamera pixel formats and fill in the list of supported
282 * stream configurations to be reported to the Android camera framework through
283 * the static stream configuration metadata.
284 */
285int CameraDevice::initializeStreamConfigurations()
286{
287 /*
288 * Get the maximum output resolutions
289 * \todo Get this from the camera properties once defined
290 */
291 std::unique_ptr<CameraConfiguration> cameraConfig =
292 camera_->generateConfiguration({ StillCapture });
293 if (!cameraConfig) {
294 LOG(HAL, Error) << "Failed to get maximum resolution";
295 return -EINVAL;
296 }
297 StreamConfiguration &cfg = cameraConfig->at(0);
298
299 /*
300 * \todo JPEG - Adjust the maximum available resolution by taking the
301 * JPEG encoder requirements into account (alignment and aspect ratio).
302 */
303 const Size maxRes = cfg.size;
304 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
305
306 /*
307 * Build the list of supported image resolutions.
308 *
309 * The resolutions listed in camera3Resolution are mandatory to be
310 * supported, up to the camera maximum resolution.
311 *
312 * Augment the list by adding resolutions calculated from the camera
313 * maximum one.
314 */
315 std::vector<Size> cameraResolutions;
316 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
317 std::back_inserter(cameraResolutions),
318 [&](const Size &res) { return res < maxRes; });
319
320 /*
321 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
322 * resolution.
323 */
324 for (unsigned int divider = 2;; divider <<= 1) {
325 Size derivedSize{
326 maxRes.width / divider,
327 maxRes.height / divider,
328 };
329
330 if (derivedSize.width < 320 ||
331 derivedSize.height < 240)
332 break;
333
334 cameraResolutions.push_back(derivedSize);
335 }
336 cameraResolutions.push_back(maxRes);
337
338 /* Remove duplicated entries from the list of supported resolutions. */
339 std::sort(cameraResolutions.begin(), cameraResolutions.end());
340 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
341 cameraResolutions.erase(last, cameraResolutions.end());
342
343 /*
344 * Build the list of supported camera formats.
345 *
346 * To each Android format a list of compatible libcamera formats is
347 * associated. The first libcamera format that tests successful is added
348 * to the format translation map used when configuring the streams.
349 * It is then tested against the list of supported camera resolutions to
350 * build the stream configuration map reported through the camera static
351 * metadata.
352 */
353 for (const auto &format : camera3FormatsMap) {
354 int androidFormat = format.first;
355 const Camera3Format &camera3Format = format.second;
356 const std::vector<PixelFormat> &libcameraFormats =
357 camera3Format.libcameraFormats;
358
359 /*
360 * Test the libcamera formats that can produce images
361 * compatible with the format defined by Android.
362 */
363 PixelFormat mappedFormat;
364 for (const PixelFormat &pixelFormat : libcameraFormats) {
365 /* \todo Fixed mapping for JPEG. */
366 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +0300367 mappedFormat = formats::MJPEG;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200368 break;
369 }
370
371 /*
372 * The stream configuration size can be adjusted,
373 * not the pixel format.
374 *
375 * \todo This could be simplified once all pipeline
376 * handlers will report the StreamFormats list of
377 * supported formats.
378 */
379 cfg.pixelFormat = pixelFormat;
380
381 CameraConfiguration::Status status = cameraConfig->validate();
382 if (status != CameraConfiguration::Invalid &&
383 cfg.pixelFormat == pixelFormat) {
384 mappedFormat = pixelFormat;
385 break;
386 }
387 }
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +0200388 if (camera3Format.mandatory && !mappedFormat.isValid()) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200389 LOG(HAL, Error) << "Failed to map Android format "
390 << camera3Format.name << " ("
391 << utils::hex(androidFormat) << ")";
392 return -EINVAL;
393 }
394
395 /*
396 * Record the mapping and then proceed to generate the
397 * stream configurations map, by testing the image resolutions.
398 */
399 formatsMap_[androidFormat] = mappedFormat;
400
401 for (const Size &res : cameraResolutions) {
402 cfg.pixelFormat = mappedFormat;
403 cfg.size = res;
404
405 CameraConfiguration::Status status = cameraConfig->validate();
406 /*
407 * Unconditionally report we can produce JPEG.
408 *
409 * \todo The JPEG stream will be implemented as an
410 * HAL-only stream, but some cameras can produce it
411 * directly. As of now, claim support for JPEG without
412 * inspecting where the JPEG stream is produced.
413 */
414 if (androidFormat != HAL_PIXEL_FORMAT_BLOB &&
415 status != CameraConfiguration::Valid)
416 continue;
417
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200418 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200419 }
420 }
421
422 LOG(HAL, Debug) << "Collected stream configuration map: ";
423 for (const auto &entry : streamConfigurations_)
424 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200425 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200426
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200427 return 0;
428}
429
430/*
431 * Open a camera device. The static information on the camera shall have been
432 * initialized with a call to CameraDevice::initialize().
433 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200434int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200435{
436 int ret = camera_->acquire();
437 if (ret) {
438 LOG(HAL, Error) << "Failed to acquire the camera";
439 return ret;
440 }
441
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200442 /* Initialize the hw_device_t in the instance camera3_module_t. */
443 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
444 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
445 camera3Device_.common.module = (hw_module_t *)hardwareModule;
446 camera3Device_.common.close = hal_dev_close;
447
448 /*
449 * The camera device operations. These actually implement
450 * the Android Camera HALv3 interface.
451 */
452 camera3Device_.ops = &hal_dev_ops;
453 camera3Device_.priv = this;
454
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200455 return 0;
456}
457
458void CameraDevice::close()
459{
460 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200461 camera_->release();
462
463 running_ = false;
464}
465
466void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
467{
468 callbacks_ = callbacks;
469}
470
Jacopo Mondia80d3812020-05-26 12:31:35 +0200471std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
472{
473 /*
474 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100475 * Currently: 51 entries, 687 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200476 */
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100477 uint32_t numEntries = 51;
478 uint32_t byteSize = 687;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200479
480 /*
481 * Calculate space occupation in bytes for dynamically built metadata
482 * entries.
483 *
484 * Each stream configuration entry requires 52 bytes:
485 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200486 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
487 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200488 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200489
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300490 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200491}
492
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200493/*
494 * Return static information for the camera.
495 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200496const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200497{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200498 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300499 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200500
501 /*
502 * The here reported metadata are enough to implement a basic capture
503 * example application, but a real camera implementation will require
504 * more.
505 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200506 uint32_t numEntries;
507 uint32_t byteSize;
508 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
509 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300510 if (!staticMetadata_->isValid()) {
511 LOG(HAL, Error) << "Failed to allocate static metadata";
512 delete staticMetadata_;
513 staticMetadata_ = nullptr;
514 return nullptr;
515 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200516
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200517 /* Color correction static metadata. */
518 std::vector<uint8_t> aberrationModes = {
519 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
520 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300521 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
522 aberrationModes.data(),
523 aberrationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200524
525 /* Control static metadata. */
526 std::vector<uint8_t> aeAvailableAntiBandingModes = {
527 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
528 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
529 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
530 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
531 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300532 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
533 aeAvailableAntiBandingModes.data(),
534 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200535
536 std::vector<uint8_t> aeAvailableModes = {
537 ANDROID_CONTROL_AE_MODE_ON,
538 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300539 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
540 aeAvailableModes.data(),
541 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200542
543 std::vector<int32_t> availableAeFpsTarget = {
544 15, 30,
545 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300546 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
547 availableAeFpsTarget.data(),
548 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200549
550 std::vector<int32_t> aeCompensationRange = {
551 0, 0,
552 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300553 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
554 aeCompensationRange.data(),
555 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200556
557 const camera_metadata_rational_t aeCompensationStep[] = {
558 { 0, 1 }
559 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300560 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
561 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200562
563 std::vector<uint8_t> availableAfModes = {
564 ANDROID_CONTROL_AF_MODE_OFF,
565 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300566 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
567 availableAfModes.data(),
568 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200569
570 std::vector<uint8_t> availableEffects = {
571 ANDROID_CONTROL_EFFECT_MODE_OFF,
572 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300573 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
574 availableEffects.data(),
575 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200576
577 std::vector<uint8_t> availableSceneModes = {
578 ANDROID_CONTROL_SCENE_MODE_DISABLED,
579 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300580 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
581 availableSceneModes.data(),
582 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200583
584 std::vector<uint8_t> availableStabilizationModes = {
585 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
586 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300587 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
588 availableStabilizationModes.data(),
589 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200590
591 std::vector<uint8_t> availableAwbModes = {
592 ANDROID_CONTROL_AWB_MODE_OFF,
593 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300594 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
595 availableAwbModes.data(),
596 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200597
598 std::vector<int32_t> availableMaxRegions = {
599 0, 0, 0,
600 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300601 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
602 availableMaxRegions.data(),
603 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200604
605 std::vector<uint8_t> sceneModesOverride = {
606 ANDROID_CONTROL_AE_MODE_ON,
607 ANDROID_CONTROL_AWB_MODE_AUTO,
608 ANDROID_CONTROL_AF_MODE_AUTO,
609 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300610 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
611 sceneModesOverride.data(),
612 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200613
614 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300615 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
616 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200617
618 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300619 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
620 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200621
622 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300623 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
624 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200625
626 /* JPEG static metadata. */
627 std::vector<int32_t> availableThumbnailSizes = {
628 0, 0,
629 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300630 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
631 availableThumbnailSizes.data(),
632 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200633
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100634 /*
635 * \todo Calculate the maximum JPEG buffer size by asking the encoder
636 * giving the maximum frame size required.
637 */
638 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
639
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200640 /* Sensor static metadata. */
641 int32_t pixelArraySize[] = {
642 2592, 1944,
643 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300644 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
645 &pixelArraySize, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200646
647 int32_t sensorSizes[] = {
648 0, 0, 2560, 1920,
649 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300650 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
651 &sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200652
653 int32_t sensitivityRange[] = {
654 32, 2400,
655 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300656 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
657 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200658
659 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300660 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
661 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200662
663 int64_t exposureTimeRange[] = {
664 100000, 200000000,
665 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300666 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
667 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200668
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200669 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200670
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200671 std::vector<int32_t> testPatterModes = {
672 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
673 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300674 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
675 testPatterModes.data(),
676 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200677
678 std::vector<float> physicalSize = {
679 2592, 1944,
680 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300681 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
682 physicalSize.data(),
683 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200684
685 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300686 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
687 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200688
689 /* Statistics static metadata. */
690 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300691 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
692 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200693
694 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300695 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
696 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200697
698 /* Sync static metadata. */
699 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300700 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200701
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200702 /* Flash static metadata. */
703 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300704 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
705 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200706
707 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200708 std::vector<float> lensApertures = {
709 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200710 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300711 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
712 lensApertures.data(),
713 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200714
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200715 uint8_t lensFacing;
716 switch (facing_) {
717 default:
718 case CAMERA_FACING_FRONT:
719 lensFacing = ANDROID_LENS_FACING_FRONT;
720 break;
721 case CAMERA_FACING_BACK:
722 lensFacing = ANDROID_LENS_FACING_BACK;
723 break;
724 case CAMERA_FACING_EXTERNAL:
725 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
726 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100727 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300728 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200729
730 std::vector<float> lensFocalLenghts = {
731 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200732 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300733 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
734 lensFocalLenghts.data(),
735 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200736
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200737 std::vector<uint8_t> opticalStabilizations = {
738 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
739 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300740 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
741 opticalStabilizations.data(),
742 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200743
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200744 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300745 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
746 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200747
748 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300749 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
750 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200751
752 /* Noise reduction modes. */
753 uint8_t noiseReductionModes = ANDROID_NOISE_REDUCTION_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300754 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
755 &noiseReductionModes, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200756
757 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200758 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300759 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
760 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200761
Jacopo Mondibde7b982020-05-25 17:18:28 +0200762 std::vector<uint32_t> availableStreamConfigurations;
763 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
764 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200765 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200766 availableStreamConfigurations.push_back(entry.resolution.width);
767 availableStreamConfigurations.push_back(entry.resolution.height);
768 availableStreamConfigurations.push_back(
769 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
770 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300771 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
772 availableStreamConfigurations.data(),
773 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200774
775 std::vector<int64_t> availableStallDurations = {
776 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
777 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300778 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
779 availableStallDurations.data(),
780 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200781
Jacopo Mondibde7b982020-05-25 17:18:28 +0200782 /* \todo Collect the minimum frame duration from the camera. */
783 std::vector<int64_t> minFrameDurations;
784 minFrameDurations.reserve(streamConfigurations_.size() * 4);
785 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200786 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200787 minFrameDurations.push_back(entry.resolution.width);
788 minFrameDurations.push_back(entry.resolution.height);
789 minFrameDurations.push_back(33333333);
790 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300791 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
792 minFrameDurations.data(),
793 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200794
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200795 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300796 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200797
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200798 /* Info static metadata. */
799 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300800 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
801 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200802
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200803 /* Request static metadata. */
804 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300805 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
806 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200807
808 uint8_t maxPipelineDepth = 2;
Laurent Pinchart39860092019-09-05 03:12:34 +0300809 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
810 &maxPipelineDepth, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200811
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200812 /* LIMITED does not support reprocessing. */
813 uint32_t maxNumInputStreams = 0;
814 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
815 &maxNumInputStreams, 1);
816
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200817 std::vector<uint8_t> availableCapabilities = {
818 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
819 };
Niklas Söderlund7876d632020-07-21 00:16:24 +0200820
821 /* Report if camera supports RAW. */
822 std::unique_ptr<CameraConfiguration> cameraConfig =
823 camera_->generateConfiguration({ StillCaptureRaw });
824 if (cameraConfig && !cameraConfig->empty()) {
825 const PixelFormatInfo &info =
826 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
827 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
828 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
829 }
830
Laurent Pinchart39860092019-09-05 03:12:34 +0300831 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
832 availableCapabilities.data(),
833 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200834
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200835 std::vector<int32_t> availableCharacteristicsKeys = {
836 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
837 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
838 ANDROID_CONTROL_AE_AVAILABLE_MODES,
839 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
840 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
841 ANDROID_CONTROL_AE_COMPENSATION_STEP,
842 ANDROID_CONTROL_AF_AVAILABLE_MODES,
843 ANDROID_CONTROL_AVAILABLE_EFFECTS,
844 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
845 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
846 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
847 ANDROID_CONTROL_MAX_REGIONS,
848 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
849 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
850 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
851 ANDROID_CONTROL_AVAILABLE_MODES,
852 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100853 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200854 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
855 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
856 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
857 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
858 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
859 ANDROID_SENSOR_ORIENTATION,
860 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
861 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
862 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
863 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
864 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
865 ANDROID_SYNC_MAX_LATENCY,
866 ANDROID_FLASH_INFO_AVAILABLE,
867 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
868 ANDROID_LENS_FACING,
869 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
870 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
871 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
872 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
873 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
874 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200875 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
876 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
877 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
878 ANDROID_SCALER_CROPPING_TYPE,
879 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
880 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
881 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200882 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200883 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
884 };
885 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
886 availableCharacteristicsKeys.data(),
887 availableCharacteristicsKeys.size());
888
889 std::vector<int32_t> availableRequestKeys = {
890 ANDROID_CONTROL_AE_MODE,
891 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
892 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200893 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
894 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200895 ANDROID_CONTROL_AE_LOCK,
896 ANDROID_CONTROL_AF_TRIGGER,
897 ANDROID_CONTROL_AWB_MODE,
898 ANDROID_CONTROL_AWB_LOCK,
899 ANDROID_FLASH_MODE,
900 ANDROID_STATISTICS_FACE_DETECT_MODE,
901 ANDROID_NOISE_REDUCTION_MODE,
902 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200903 ANDROID_LENS_APERTURE,
904 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
905 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200906 ANDROID_CONTROL_CAPTURE_INTENT,
907 };
908 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
909 availableRequestKeys.data(),
910 availableRequestKeys.size());
911
912 std::vector<int32_t> availableResultKeys = {
913 ANDROID_CONTROL_AE_STATE,
914 ANDROID_CONTROL_AE_LOCK,
915 ANDROID_CONTROL_AF_STATE,
916 ANDROID_CONTROL_AWB_STATE,
917 ANDROID_CONTROL_AWB_LOCK,
918 ANDROID_LENS_STATE,
919 ANDROID_SCALER_CROP_REGION,
920 ANDROID_SENSOR_TIMESTAMP,
921 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
922 ANDROID_SENSOR_EXPOSURE_TIME,
923 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
924 ANDROID_STATISTICS_SCENE_FLICKER,
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100925 ANDROID_JPEG_SIZE,
926 ANDROID_JPEG_QUALITY,
927 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200928 };
929 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
930 availableResultKeys.data(),
931 availableResultKeys.size());
932
Laurent Pinchart39860092019-09-05 03:12:34 +0300933 if (!staticMetadata_->isValid()) {
934 LOG(HAL, Error) << "Failed to construct static metadata";
935 delete staticMetadata_;
936 staticMetadata_ = nullptr;
937 return nullptr;
938 }
939
940 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200941}
942
Jacopo Mondi8a02d442020-07-24 15:47:50 +0200943CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200944{
Jacopo Mondi63703472019-09-04 16:18:22 +0200945 /*
946 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200947 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +0200948 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200949 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200950 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200951 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200952 return nullptr;
953 }
954
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200955 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200956 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
957 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200958
959 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200960 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
961 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200962
963 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200964 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
965 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200966
967 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200968 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
969 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200970
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200971 std::vector<int32_t> aeFpsTarget = {
972 15, 30,
973 };
974 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
975 aeFpsTarget.data(),
976 aeFpsTarget.size());
977
978 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
979 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
980 &aeAntibandingMode, 1);
981
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200982 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200983 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
984 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200985
986 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200987 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
988 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200989
990 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200991 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
992 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200993
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200994 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200995 requestTemplate->addEntry(ANDROID_FLASH_MODE,
996 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200997
998 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200999 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1000 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001001
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001002 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001003 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1004 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001005
1006 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001007 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1008 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001009
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001010 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1011 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1012
1013 float lensAperture = 2.53 / 100;
1014 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1015
1016 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1017 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1018 &opticalStabilization, 1);
1019
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001020 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001021 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1022 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001023
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001024 return requestTemplate;
1025}
1026
1027/*
1028 * Produce a metadata pack to be used as template for a capture request.
1029 */
1030const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1031{
1032 auto it = requestTemplates_.find(type);
1033 if (it != requestTemplates_.end())
1034 return it->second->get();
1035
1036 /* Use the capture intent matching the requested template type. */
1037 CameraMetadata *requestTemplate;
1038 uint8_t captureIntent;
1039 switch (type) {
1040 case CAMERA3_TEMPLATE_PREVIEW:
1041 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
1042 break;
1043 case CAMERA3_TEMPLATE_STILL_CAPTURE:
1044 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
1045 break;
1046 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1047 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
1048 break;
1049 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1050 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
1051 break;
1052 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
1053 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
1054 break;
1055 case CAMERA3_TEMPLATE_MANUAL:
1056 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
1057 break;
1058 default:
1059 LOG(HAL, Error) << "Invalid template request type: " << type;
1060 return nullptr;
1061 }
1062
1063 requestTemplate = requestTemplatePreview();
1064 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001065 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001066 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001067 return nullptr;
1068 }
1069
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001070 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1071 &captureIntent, 1);
1072
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001073 requestTemplates_[type] = requestTemplate;
1074 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001075}
1076
Kieran Bingham43e3b802020-06-26 09:58:49 +01001077PixelFormat CameraDevice::toPixelFormat(int format)
1078{
1079 /* Translate Android format code to libcamera pixel format. */
1080 auto it = formatsMap_.find(format);
1081 if (it == formatsMap_.end()) {
1082 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1083 << " not supported";
1084 return PixelFormat();
1085 }
1086
1087 return it->second;
1088}
1089
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001090/*
1091 * Inspect the stream_list to produce a list of StreamConfiguration to
1092 * be use to configure the Camera.
1093 */
1094int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1095{
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001096 /*
1097 * Generate an empty configuration, and construct a StreamConfiguration
1098 * for each camera3_stream to add to it.
1099 */
1100 config_ = camera_->generateConfiguration();
1101 if (!config_) {
1102 LOG(HAL, Error) << "Failed to generate camera configuration";
1103 return -EINVAL;
1104 }
1105
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001106 /*
1107 * Clear and remove any existing configuration from previous calls, and
1108 * ensure the required entries are available without further
1109 * re-allcoation.
1110 */
1111 streams_.clear();
1112 streams_.reserve(stream_list->num_streams);
1113
1114 /*
1115 * Track actually created streams, as there may not be a 1:1 mapping of
1116 * camera3 streams to libcamera streams.
1117 */
1118 unsigned int streamIndex = 0;
1119
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001120 /* First handle all non-MJPEG streams. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001121 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1122 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001123 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001124
Kieran Bingham43e3b802020-06-26 09:58:49 +01001125 PixelFormat format = toPixelFormat(stream->format);
1126
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001127 LOG(HAL, Info) << "Stream #" << i
1128 << ", direction: " << stream->stream_type
1129 << ", width: " << stream->width
1130 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001131 << ", format: " << utils::hex(stream->format)
1132 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001133
1134 if (!format.isValid())
1135 return -EINVAL;
1136
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001137 streams_.emplace_back(format, size);
1138 stream->priv = static_cast<void *>(&streams_[i]);
1139
1140 /* Defer handling of MJPEG streams until all others are known. */
1141 if (format == formats::MJPEG)
1142 continue;
1143
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001144 StreamConfiguration streamConfiguration;
1145
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001146 streamConfiguration.size = size;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001147 streamConfiguration.pixelFormat = format;
1148
1149 config_->addConfiguration(streamConfiguration);
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001150
1151 streams_[i].index = streamIndex++;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001152 }
1153
1154 /* Now handle MJPEG streams, adding a new stream if required. */
1155 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1156 camera3_stream_t *stream = stream_list->streams[i];
1157 bool match = false;
1158
1159 if (streams_[i].format != formats::MJPEG)
1160 continue;
1161
1162 /* Search for a compatible stream */
1163 for (unsigned int j = 0; j < config_->size(); j++) {
1164 StreamConfiguration &cfg = config_->at(j);
1165
1166 /*
1167 * \todo The PixelFormat must also be compatible with
1168 * the encoder.
1169 */
1170 if (cfg.size == streams_[i].size) {
1171 LOG(HAL, Info) << "Stream " << i
1172 << " using libcamera stream " << j;
1173
1174 match = true;
1175 streams_[i].index = j;
1176 }
1177 }
1178
1179 /*
1180 * Without a compatible match for JPEG encoding we must
1181 * introduce a new stream to satisfy the request requirements.
1182 */
1183 if (!match) {
1184 StreamConfiguration streamConfiguration;
1185
1186 /*
1187 * \todo The pixelFormat should be a 'best-fit' choice
1188 * and may require a validation cycle. This is not yet
1189 * handled, and should be considered as part of any
1190 * stream configuration reworks.
1191 */
1192 streamConfiguration.size.width = stream->width;
1193 streamConfiguration.size.height = stream->height;
1194 streamConfiguration.pixelFormat = formats::NV12;
1195
1196 LOG(HAL, Info) << "Adding " << streamConfiguration.toString()
1197 << " for MJPEG support";
1198
1199 config_->addConfiguration(streamConfiguration);
1200 streams_[i].index = streamIndex++;
1201 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001202 }
1203
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001204 switch (config_->validate()) {
1205 case CameraConfiguration::Valid:
1206 break;
1207 case CameraConfiguration::Adjusted:
1208 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001209
1210 for (const StreamConfiguration &cfg : *config_)
1211 LOG(HAL, Info) << " - " << cfg.toString();
1212
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001213 config_.reset();
1214 return -EINVAL;
1215 case CameraConfiguration::Invalid:
1216 LOG(HAL, Info) << "Camera configuration invalid";
1217 config_.reset();
1218 return -EINVAL;
1219 }
1220
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001221 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1222 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001223 CameraStream *cameraStream = &streams_[i];
1224 StreamConfiguration &cfg = config_->at(cameraStream->index);
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001225
1226 /* Use the bufferCount confirmed by the validation process. */
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001227 stream->max_buffers = cfg.bufferCount;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001228
1229 /*
1230 * Construct a software encoder for MJPEG streams from the
1231 * chosen libcamera source stream.
1232 */
1233 if (cameraStream->format == formats::MJPEG) {
1234 cameraStream->jpeg = new EncoderLibJpeg();
1235 int ret = cameraStream->jpeg->configure(cfg);
1236 if (ret) {
1237 LOG(HAL, Error)
1238 << "Failed to configure encoder";
1239 return ret;
1240 }
1241 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001242 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001243
1244 /*
1245 * Once the CameraConfiguration has been adjusted/validated
1246 * it can be applied to the camera.
1247 */
1248 int ret = camera_->configure(config_.get());
1249 if (ret) {
1250 LOG(HAL, Error) << "Failed to configure camera '"
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001251 << camera_->id() << "'";
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001252 return ret;
1253 }
1254
1255 return 0;
1256}
1257
Kieran Bingham74ab4422020-07-01 13:25:38 +01001258FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1259{
1260 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001261 for (int i = 0; i < camera3buffer->numFds; i++) {
1262 /* Skip unused planes. */
1263 if (camera3buffer->data[i] == -1)
1264 break;
1265
Kieran Bingham74ab4422020-07-01 13:25:38 +01001266 FrameBuffer::Plane plane;
1267 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001268 if (!plane.fd.isValid()) {
1269 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1270 << camera3buffer->data[i] << ") "
1271 << " on plane " << i;
1272 return nullptr;
1273 }
1274
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001275 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1276 if (length == -1) {
1277 LOG(HAL, Error) << "Failed to query plane length";
1278 return nullptr;
1279 }
1280
1281 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001282 planes.push_back(std::move(plane));
1283 }
1284
1285 return new FrameBuffer(std::move(planes));
1286}
1287
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001288int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001289{
Kieran Bingham61f42962020-07-01 13:40:17 +01001290 if (!camera3Request->num_output_buffers) {
1291 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001292 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001293 }
1294
1295 /* Start the camera if that's the first request we handle. */
1296 if (!running_) {
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001297 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001298 if (ret) {
1299 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001300 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001301 }
1302
1303 running_ = true;
1304 }
1305
1306 /*
1307 * Queue a request for the Camera with the provided dmabuf file
1308 * descriptors.
1309 */
1310 const camera3_stream_buffer_t *camera3Buffers =
1311 camera3Request->output_buffers;
1312
1313 /*
1314 * Save the request descriptors for use at completion time.
1315 * The descriptor and the associated memory reserved here are freed
1316 * at request complete time.
1317 */
1318 Camera3RequestDescriptor *descriptor =
1319 new Camera3RequestDescriptor(camera3Request->frame_number,
1320 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001321
1322 Request *request =
1323 camera_->createRequest(reinterpret_cast<uint64_t>(descriptor));
1324
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001325 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001326 CameraStream *cameraStream =
1327 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1328
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001329 /*
1330 * Keep track of which stream the request belongs to and store
1331 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001332 */
1333 descriptor->buffers[i].stream = camera3Buffers[i].stream;
1334 descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001335
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001336 /* Software streams are handled after hardware streams complete. */
1337 if (cameraStream->format == formats::MJPEG)
1338 continue;
1339
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001340 /*
1341 * Create a libcamera buffer using the dmabuf descriptors of
1342 * the camera3Buffer for each stream. The FrameBuffer is
1343 * directly associated with the Camera3RequestDescriptor for
1344 * lifetime management only.
1345 */
1346 FrameBuffer *buffer = createFrameBuffer(*camera3Buffers[i].buffer);
1347 if (!buffer) {
1348 LOG(HAL, Error) << "Failed to create buffer";
1349 delete request;
1350 delete descriptor;
1351 return -ENOMEM;
1352 }
1353 descriptor->frameBuffers.emplace_back(buffer);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001354
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001355 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index);
1356 Stream *stream = streamConfiguration->stream();
1357
1358 request->addBuffer(stream, buffer);
1359 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001360
1361 int ret = camera_->queueRequest(request);
1362 if (ret) {
1363 LOG(HAL, Error) << "Failed to queue request";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001364 delete request;
1365 delete descriptor;
1366 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001367 }
1368
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001369 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001370}
1371
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001372void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001373{
Niklas Söderlund9217f272019-11-22 16:22:56 +01001374 const std::map<Stream *, FrameBuffer *> &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001375 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001376 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001377 Camera3RequestDescriptor *descriptor =
1378 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001379
1380 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001381 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001382 << request->status();
1383 status = CAMERA3_BUFFER_STATUS_ERROR;
1384 }
1385
Kieran Binghamc09aee42020-07-28 14:01:19 +01001386 /*
1387 * \todo The timestamp used for the metadata is currently always taken
1388 * from the first buffer (which may be the first stream) in the Request.
1389 * It might be appropriate to return a 'correct' (as determined by
1390 * pipeline handlers) timestamp in the Request itself.
1391 */
1392 FrameBuffer *buffer = buffers.begin()->second;
1393 resultMetadata = getResultMetadata(descriptor->frameNumber,
1394 buffer->metadata().timestamp);
1395
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001396 /* Handle any JPEG compression. */
1397 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
1398 CameraStream *cameraStream =
1399 static_cast<CameraStream *>(descriptor->buffers[i].stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001400
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001401 if (cameraStream->format != formats::MJPEG)
1402 continue;
1403
1404 Encoder *encoder = cameraStream->jpeg;
1405 if (!encoder) {
1406 LOG(HAL, Error) << "Failed to identify encoder";
1407 continue;
1408 }
1409
1410 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index);
1411 Stream *stream = streamConfiguration->stream();
1412 FrameBuffer *buffer = request->findBuffer(stream);
1413 if (!buffer) {
1414 LOG(HAL, Error) << "Failed to find a source stream buffer";
1415 continue;
1416 }
1417
1418 /*
1419 * \todo Buffer mapping and compression should be moved to a
1420 * separate thread.
1421 */
1422
1423 MappedCamera3Buffer mapped(*descriptor->buffers[i].buffer,
1424 PROT_READ | PROT_WRITE);
1425 if (!mapped.isValid()) {
1426 LOG(HAL, Error) << "Failed to mmap android blob buffer";
1427 continue;
1428 }
1429
1430 int jpeg_size = encoder->encode(buffer, mapped.maps()[0]);
1431 if (jpeg_size < 0) {
1432 LOG(HAL, Error) << "Failed to encode stream image";
1433 status = CAMERA3_BUFFER_STATUS_ERROR;
1434 continue;
1435 }
1436
1437 /*
1438 * Fill in the JPEG blob header.
1439 *
1440 * The mapped size of the buffer is being returned as
1441 * substantially larger than the requested JPEG_MAX_SIZE
1442 * (which is referenced from maxJpegBufferSize_). Utilise
1443 * this static size to ensure the correct offset of the blob is
1444 * determined.
1445 *
1446 * \todo Investigate if the buffer size mismatch is an issue or
1447 * expected behaviour.
1448 */
1449 uint8_t *resultPtr = mapped.maps()[0].data() +
1450 maxJpegBufferSize_ -
1451 sizeof(struct camera3_jpeg_blob);
1452 auto *blob = reinterpret_cast<struct camera3_jpeg_blob *>(resultPtr);
1453 blob->jpeg_blob_id = CAMERA3_JPEG_BLOB_ID;
1454 blob->jpeg_size = jpeg_size;
1455
1456 /* Update the JPEG result Metadata. */
1457 resultMetadata->addEntry(ANDROID_JPEG_SIZE,
1458 &jpeg_size, 1);
1459
1460 const uint32_t jpeg_quality = 95;
1461 resultMetadata->addEntry(ANDROID_JPEG_QUALITY,
1462 &jpeg_quality, 1);
1463
1464 const uint32_t jpeg_orientation = 0;
1465 resultMetadata->addEntry(ANDROID_JPEG_ORIENTATION,
1466 &jpeg_orientation, 1);
1467 }
1468
1469 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001470 camera3_capture_result_t captureResult = {};
1471 captureResult.frame_number = descriptor->frameNumber;
1472 captureResult.num_output_buffers = descriptor->numBuffers;
1473 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001474 descriptor->buffers[i].acquire_fence = -1;
1475 descriptor->buffers[i].release_fence = -1;
1476 descriptor->buffers[i].status = status;
1477 }
1478 captureResult.output_buffers =
1479 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers);
1480
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001481
Laurent Pinchart39860092019-09-05 03:12:34 +03001482 if (status == CAMERA3_BUFFER_STATUS_OK) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001483 notifyShutter(descriptor->frameNumber,
Niklas Söderlund9217f272019-11-22 16:22:56 +01001484 buffer->metadata().timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001485
1486 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001487 captureResult.result = resultMetadata->get();
1488 }
1489
1490 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1491 /* \todo Improve error handling. In case we notify an error
1492 * because the metadata generation fails, a shutter event has
1493 * already been notified for this frame number before the error
1494 * is here signalled. Make sure the error path plays well with
1495 * the camera stack state machine.
1496 */
1497 notifyError(descriptor->frameNumber,
1498 descriptor->buffers[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001499 }
1500
1501 callbacks_->process_capture_result(callbacks_, &captureResult);
1502
1503 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001504}
1505
Jacopo Mondia7b92772020-05-26 15:41:41 +02001506std::string CameraDevice::logPrefix() const
1507{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001508 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001509}
1510
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001511void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1512{
1513 camera3_notify_msg_t notify = {};
1514
1515 notify.type = CAMERA3_MSG_SHUTTER;
1516 notify.message.shutter.frame_number = frameNumber;
1517 notify.message.shutter.timestamp = timestamp;
1518
1519 callbacks_->notify(callbacks_, &notify);
1520}
1521
1522void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1523{
1524 camera3_notify_msg_t notify = {};
1525
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001526 /*
1527 * \todo Report and identify the stream number or configuration to
1528 * clarify the stream that failed.
1529 */
1530 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1531 << toPixelFormat(stream->format).toString() << ")";
1532
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001533 notify.type = CAMERA3_MSG_ERROR;
1534 notify.message.error.error_stream = stream;
1535 notify.message.error.frame_number = frameNumber;
1536 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1537
1538 callbacks_->notify(callbacks_, &notify);
1539}
1540
1541/*
1542 * Produce a set of fixed result metadata.
1543 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001544std::unique_ptr<CameraMetadata> CameraDevice::getResultMetadata(int frame_number,
1545 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001546{
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001547 /*
1548 * \todo Keep this in sync with the actual number of entries.
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001549 * Currently: 18 entries, 62 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001550 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001551 std::unique_ptr<CameraMetadata> resultMetadata =
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001552 std::make_unique<CameraMetadata>(18, 62);
Laurent Pinchart39860092019-09-05 03:12:34 +03001553 if (!resultMetadata->isValid()) {
1554 LOG(HAL, Error) << "Failed to allocate static metadata";
1555 return nullptr;
1556 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001557
1558 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001559 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001560
1561 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001562 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001563
1564 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001565 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001566
1567 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001568 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001569
1570 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001571 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001572
1573 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001574 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001575
1576 int32_t sensorSizes[] = {
1577 0, 0, 2560, 1920,
1578 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001579 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001580
Laurent Pinchart39860092019-09-05 03:12:34 +03001581 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001582
1583 /* 33.3 msec */
1584 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001585 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1586 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001587
1588 /* 16.6 msec */
1589 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001590 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1591 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001592
1593 const uint8_t lens_shading_map_mode =
1594 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001595 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1596 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001597
1598 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001599 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1600 &scene_flicker, 1);
1601
1602 /*
1603 * Return the result metadata pack even is not valid: get() will return
1604 * nullptr.
1605 */
1606 if (!resultMetadata->isValid()) {
1607 LOG(HAL, Error) << "Failed to construct result metadata";
1608 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001609
1610 return resultMetadata;
1611}