blob: 7fc6868e34442d9fbb97e1763a51f60f2dca8838 [file] [log] [blame]
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2019, Google Inc.
4 *
5 * camera_device.cpp - libcamera Android Camera Device
6 */
7
8#include "camera_device.h"
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02009#include "camera_ops.h"
Umang Jainb2b8c4d2020-10-16 11:07:54 +053010#include "post_processor.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020011
Jacopo Mondi45c6a7e2020-12-18 16:35:35 +010012#include <array>
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +010013#include <cmath>
Paul Elder229653a2021-01-21 17:44:14 +090014#include <fstream>
Kieran Bingham83ae84e2020-07-03 12:34:59 +010015#include <sys/mman.h>
Jacopo Mondia80d3812020-05-26 12:31:35 +020016#include <tuple>
Jacopo Mondi117588b2020-05-23 18:53:54 +020017#include <vector>
18
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +020019#include <libcamera/control_ids.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010020#include <libcamera/controls.h>
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030021#include <libcamera/formats.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010022#include <libcamera/property_ids.h>
23
Niklas Söderlund7876d632020-07-21 00:16:24 +020024#include "libcamera/internal/formats.h"
Laurent Pinchart93e72b62020-05-12 00:58:34 +030025#include "libcamera/internal/log.h"
26#include "libcamera/internal/utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020027
Jacopo Mondi117588b2020-05-23 18:53:54 +020028#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020029
30using namespace libcamera;
31
Hirokazu Honda26d90af2020-12-11 09:53:36 +000032LOG_DECLARE_CATEGORY(HAL)
33
Jacopo Mondi117588b2020-05-23 18:53:54 +020034namespace {
35
36/*
37 * \var camera3Resolutions
38 * \brief The list of image resolutions defined as mandatory to be supported by
39 * the Android Camera3 specification
40 */
41const std::vector<Size> camera3Resolutions = {
42 { 320, 240 },
43 { 640, 480 },
44 { 1280, 720 },
45 { 1920, 1080 }
46};
47
48/*
49 * \struct Camera3Format
50 * \brief Data associated with an Android format identifier
51 * \var libcameraFormats List of libcamera pixel formats compatible with the
52 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020053 * \var name The human-readable representation of the Android format code
54 */
55struct Camera3Format {
56 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020057 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020058 const char *name;
59};
60
61/*
62 * \var camera3FormatsMap
63 * \brief Associate Android format code with ancillary data
64 */
65const std::map<int, const Camera3Format> camera3FormatsMap = {
66 {
67 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030068 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020069 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020070 "BLOB"
71 }
72 }, {
73 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030074 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020075 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020076 "YCbCr_420_888"
77 }
78 }, {
79 /*
80 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
81 * usage flag. For now, copy the YCbCr_420 configuration.
82 */
83 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030084 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020085 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020086 "IMPLEMENTATION_DEFINED"
87 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020088 }, {
89 HAL_PIXEL_FORMAT_RAW10, {
90 {
91 formats::SBGGR10_CSI2P,
92 formats::SGBRG10_CSI2P,
93 formats::SGRBG10_CSI2P,
94 formats::SRGGB10_CSI2P
95 },
96 false,
97 "RAW10"
98 }
99 }, {
100 HAL_PIXEL_FORMAT_RAW12, {
101 {
102 formats::SBGGR12_CSI2P,
103 formats::SGBRG12_CSI2P,
104 formats::SGRBG12_CSI2P,
105 formats::SRGGB12_CSI2P
106 },
107 false,
108 "RAW12"
109 }
110 }, {
111 HAL_PIXEL_FORMAT_RAW16, {
112 {
113 formats::SBGGR16,
114 formats::SGBRG16,
115 formats::SGRBG16,
116 formats::SRGGB16
117 },
118 false,
119 "RAW16"
120 }
121 }, {
122 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
123 {
124 formats::SBGGR10_IPU3,
125 formats::SGBRG10_IPU3,
126 formats::SGRBG10_IPU3,
127 formats::SRGGB10_IPU3
128 },
129 false,
130 "RAW_OPAQUE"
131 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200132 },
133};
134
Hirokazu Hondac2df7432020-12-11 09:53:34 +0000135/*
136 * \struct Camera3StreamConfig
137 * \brief Data to store StreamConfiguration associated with camera3_stream(s)
138 * \var streams List of the pairs of a stream requested by Android HAL client
139 * and CameraStream::Type associated with the stream
140 * \var config StreamConfiguration for streams
141 */
142struct Camera3StreamConfig {
143 struct Camera3Stream {
144 camera3_stream_t *stream;
145 CameraStream::Type type;
146 };
147
148 std::vector<Camera3Stream> streams;
149 StreamConfiguration config;
150};
151
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000152/*
153 * Reorder the configurations so that libcamera::Camera can accept them as much
154 * as possible. The sort rule is as follows.
155 * 1.) The configuration for NV12 request whose resolution is the largest.
156 * 2.) The configuration for JPEG request.
157 * 3.) Others. Larger resolutions and different formats are put earlier.
158 */
159void sortCamera3StreamConfigs(std::vector<Camera3StreamConfig> &unsortedConfigs,
160 const camera3_stream_t *jpegStream)
161{
162 const Camera3StreamConfig *jpegConfig = nullptr;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200163
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000164 std::map<PixelFormat, std::vector<const Camera3StreamConfig *>> formatToConfigs;
165 for (const auto &streamConfig : unsortedConfigs) {
166 if (jpegStream && !jpegConfig) {
167 const auto &streams = streamConfig.streams;
168 if (std::find_if(streams.begin(), streams.end(),
169 [jpegStream](const auto &stream) {
170 return stream.stream == jpegStream;
171 }) != streams.end()) {
172 jpegConfig = &streamConfig;
173 continue;
174 }
175 }
176 formatToConfigs[streamConfig.config.pixelFormat].push_back(&streamConfig);
177 }
178
179 if (jpegStream && !jpegConfig)
180 LOG(HAL, Fatal) << "No Camera3StreamConfig is found for JPEG";
181
182 for (auto &fmt : formatToConfigs) {
183 auto &streamConfigs = fmt.second;
184
185 /* Sorted by resolution. Smaller is put first. */
186 std::sort(streamConfigs.begin(), streamConfigs.end(),
187 [](const auto *streamConfigA, const auto *streamConfigB) {
188 const Size &sizeA = streamConfigA->config.size;
189 const Size &sizeB = streamConfigB->config.size;
190 return sizeA < sizeB;
191 });
192 }
193
194 std::vector<Camera3StreamConfig> sortedConfigs;
195 sortedConfigs.reserve(unsortedConfigs.size());
196
197 /*
198 * NV12 is the most prioritized format. Put the configuration with NV12
199 * and the largest resolution first.
200 */
201 const auto nv12It = formatToConfigs.find(formats::NV12);
202 if (nv12It != formatToConfigs.end()) {
203 auto &nv12Configs = nv12It->second;
Laurent Pinchartbd4894d2020-12-12 05:22:31 +0200204 const Camera3StreamConfig *nv12Largest = nv12Configs.back();
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000205
206 /*
207 * If JPEG will be created from NV12 and the size is larger than
208 * the largest NV12 configurations, then put the NV12
209 * configuration for JPEG first.
210 */
211 if (jpegConfig && jpegConfig->config.pixelFormat == formats::NV12) {
212 const Size &nv12SizeForJpeg = jpegConfig->config.size;
213 const Size &nv12LargestSize = nv12Largest->config.size;
214
215 if (nv12LargestSize < nv12SizeForJpeg) {
216 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
217 sortedConfigs.push_back(std::move(*jpegConfig));
218 jpegConfig = nullptr;
219 }
220 }
221
222 LOG(HAL, Debug) << "Insert " << nv12Largest->config.toString();
223 sortedConfigs.push_back(*nv12Largest);
224 nv12Configs.pop_back();
225
226 if (nv12Configs.empty())
227 formatToConfigs.erase(nv12It);
228 }
229
230 /* If the configuration for JPEG is there, then put it. */
231 if (jpegConfig) {
232 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
233 sortedConfigs.push_back(std::move(*jpegConfig));
234 jpegConfig = nullptr;
235 }
236
237 /*
238 * Put configurations with different formats and larger resolutions
239 * earlier.
240 */
241 while (!formatToConfigs.empty()) {
242 for (auto it = formatToConfigs.begin(); it != formatToConfigs.end();) {
243 auto &configs = it->second;
244 LOG(HAL, Debug) << "Insert " << configs.back()->config.toString();
245 sortedConfigs.push_back(*configs.back());
246 configs.pop_back();
247
248 if (configs.empty())
249 it = formatToConfigs.erase(it);
250 else
251 it++;
252 }
253 }
254
255 ASSERT(sortedConfigs.size() == unsortedConfigs.size());
256
257 unsortedConfigs = sortedConfigs;
258}
259
Hirokazu Honda7633a2d2021-04-03 22:37:40 +0900260bool isValidRequest(camera3_capture_request_t *camera3Request)
261{
262 if (!camera3Request) {
263 LOG(HAL, Error) << "No capture request provided";
264 return false;
265 }
266
Hirokazu Honda90a04302021-04-03 22:37:41 +0900267 if (!camera3Request->num_output_buffers ||
268 !camera3Request->output_buffers) {
Hirokazu Honda7633a2d2021-04-03 22:37:40 +0900269 LOG(HAL, Error) << "No output buffers provided";
270 return false;
271 }
272
Hirokazu Honda90a04302021-04-03 22:37:41 +0900273 for (uint32_t i = 0; i < camera3Request->num_output_buffers; i++) {
274 const camera3_stream_buffer_t &outputBuffer =
275 camera3Request->output_buffers[i];
276 if (!outputBuffer.buffer || !(*outputBuffer.buffer)) {
277 LOG(HAL, Error) << "Invalid native handle";
278 return false;
279 }
280
281 const native_handle_t *handle = *outputBuffer.buffer;
282 constexpr int kNativeHandleMaxFds = 1024;
283 if (handle->numFds < 0 || handle->numFds > kNativeHandleMaxFds) {
284 LOG(HAL, Error)
285 << "Invalid number of fds (" << handle->numFds
286 << ") in buffer " << i;
287 return false;
288 }
289
290 constexpr int kNativeHandleMaxInts = 1024;
291 if (handle->numInts < 0 || handle->numInts > kNativeHandleMaxInts) {
292 LOG(HAL, Error)
293 << "Invalid number of ints (" << handle->numInts
294 << ") in buffer " << i;
295 return false;
296 }
297 }
298
Hirokazu Honda7633a2d2021-04-03 22:37:40 +0900299 return true;
300}
301
Hirokazu Hondaac209ef2021-04-03 22:10:14 +0900302const char *rotationToString(int rotation)
303{
304 switch (rotation) {
305 case CAMERA3_STREAM_ROTATION_0:
306 return "0";
307 case CAMERA3_STREAM_ROTATION_90:
308 return "90";
309 case CAMERA3_STREAM_ROTATION_180:
310 return "180";
311 case CAMERA3_STREAM_ROTATION_270:
312 return "270";
313 }
314 return "INVALID";
315}
316
Hirokazu Honda4ae2a752021-04-03 22:10:13 +0900317#if defined(OS_CHROMEOS)
318/*
319 * Check whether the crop_rotate_scale_degrees values for all streams in
320 * the list are valid according to the Chrome OS camera HAL API.
321 */
322bool validateCropRotate(const camera3_stream_configuration_t &streamList)
323{
324 ASSERT(streamList.num_streams > 0);
325 const int cropRotateScaleDegrees =
326 streamList.streams[0]->crop_rotate_scale_degrees;
327 for (unsigned int i = 0; i < streamList.num_streams; ++i) {
328 const camera3_stream_t &stream = *streamList.streams[i];
329
330 switch (stream.crop_rotate_scale_degrees) {
331 case CAMERA3_STREAM_ROTATION_0:
332 case CAMERA3_STREAM_ROTATION_90:
333 case CAMERA3_STREAM_ROTATION_270:
334 break;
335
336 /* 180° rotation is specified by Chrome OS as invalid. */
337 case CAMERA3_STREAM_ROTATION_180:
338 default:
339 LOG(HAL, Error) << "Invalid crop_rotate_scale_degrees: "
340 << stream.crop_rotate_scale_degrees;
341 return false;
342 }
343
344 if (cropRotateScaleDegrees != stream.crop_rotate_scale_degrees) {
345 LOG(HAL, Error) << "crop_rotate_scale_degrees in all "
346 << "streams are not identical";
347 return false;
348 }
349 }
350
351 return true;
352}
353#endif
354
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000355} /* namespace */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200356
357/*
358 * \struct Camera3RequestDescriptor
359 *
360 * A utility structure that groups information about a capture request to be
361 * later re-used at request complete time to notify the framework.
362 */
363
364CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100365 Camera *camera, const camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200366{
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100367 frameNumber_ = camera3Request->frame_number;
368
Jacopo Mondi4b18b822021-01-21 11:10:08 +0100369 /* Copy the camera3 request stream information for later access. */
Hirokazu Honda17a6e782021-03-24 16:07:55 +0900370 const uint32_t numBuffers = camera3Request->num_output_buffers;
371 buffers_.resize(numBuffers);
372 for (uint32_t i = 0; i < numBuffers; i++)
Jacopo Mondi4b18b822021-01-21 11:10:08 +0100373 buffers_[i] = camera3Request->output_buffers[i];
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200374
375 /*
376 * FrameBuffer instances created by wrapping a camera3 provided dmabuf
377 * are emplaced in this vector of unique_ptr<> for lifetime management.
378 */
Hirokazu Honda17a6e782021-03-24 16:07:55 +0900379 frameBuffers_.reserve(numBuffers);
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200380
Jacopo Mondi9e6eece2021-01-21 12:52:10 +0100381 /* Clone the controls associated with the camera3 request. */
382 settings_ = CameraMetadata(camera3Request->settings);
383
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200384 /*
Hirokazu Hondad4043012021-04-03 22:57:34 +0900385 * Create the CaptureRequest, stored as a unique_ptr<> to tie its
386 * lifetime to the descriptor.
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200387 */
Hirokazu Hondad4043012021-04-03 22:57:34 +0900388 request_ = std::make_unique<CaptureRequest>(camera);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200389}
390
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200391/*
392 * \class CameraDevice
393 *
394 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200395 * the camera3_device_t interface, bridging calls received from the Android
396 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200397 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200398 * The class translates parameters and operations from the Camera HALv3 API to
399 * the libcamera API to provide static information for a Camera, create request
400 * templates for it, process capture requests and then deliver capture results
401 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200402 */
403
Hirokazu Honda9538ce42021-03-24 16:07:53 +0900404CameraDevice::CameraDevice(unsigned int id, std::shared_ptr<Camera> camera)
405 : id_(id), running_(false), camera_(std::move(camera)),
Hirokazu Hondadca709c2021-03-24 16:07:56 +0900406 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200407{
408 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100409
Paul Elder229653a2021-01-21 17:44:14 +0900410 maker_ = "libcamera";
411 model_ = "cameraModel";
412
413 /* \todo Support getting properties on Android */
414 std::ifstream fstream("/var/cache/camera/camera.prop");
415 if (!fstream.is_open())
416 return;
417
418 std::string line;
419 while (std::getline(fstream, line)) {
420 std::string::size_type delimPos = line.find("=");
421 if (delimPos == std::string::npos)
422 continue;
423 std::string key = line.substr(0, delimPos);
424 std::string val = line.substr(delimPos + 1);
425
426 if (!key.compare("ro.product.model"))
427 model_ = val;
428 else if (!key.compare("ro.product.manufacturer"))
429 maker_ = val;
430 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200431}
432
Hirokazu Hondaf101cc62021-03-24 16:07:57 +0900433CameraDevice::~CameraDevice() = default;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200434
Hirokazu Honda212f4102021-03-24 16:07:50 +0900435std::unique_ptr<CameraDevice> CameraDevice::create(unsigned int id,
Hirokazu Honda9538ce42021-03-24 16:07:53 +0900436 std::shared_ptr<Camera> cam)
Umang Jainf8e28132020-08-21 14:46:08 +0000437{
Hirokazu Honda9538ce42021-03-24 16:07:53 +0900438 return std::unique_ptr<CameraDevice>(
439 new CameraDevice(id, std::move(cam)));
Umang Jainf8e28132020-08-21 14:46:08 +0000440}
441
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200442/*
443 * Initialize the camera static information.
444 * This method is called before the camera device is opened.
445 */
446int CameraDevice::initialize()
447{
448 /* Initialize orientation and facing side of the camera. */
449 const ControlList &properties = camera_->properties();
450
451 if (properties.contains(properties::Location)) {
452 int32_t location = properties.get(properties::Location);
453 switch (location) {
454 case properties::CameraLocationFront:
455 facing_ = CAMERA_FACING_FRONT;
456 break;
457 case properties::CameraLocationBack:
458 facing_ = CAMERA_FACING_BACK;
459 break;
460 case properties::CameraLocationExternal:
Jacopo Mondi5154e142021-03-10 14:00:50 +0100461 facing_ = CAMERA_FACING_EXTERNAL;
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200462 break;
463 }
Jacopo Mondi5154e142021-03-10 14:00:50 +0100464 } else {
465 /*
466 * \todo Retrieve the camera location from configuration file
467 * if not available from the library.
468 */
469 facing_ = CAMERA_FACING_FRONT;
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200470 }
471
472 /*
Umang Jaine9176552020-09-09 16:17:54 +0530473 * The Android orientation metadata specifies its rotation correction
474 * value in clockwise direction whereas libcamera specifies the
475 * rotation property in anticlockwise direction. Read the libcamera's
476 * rotation property (anticlockwise) and compute the corresponding
477 * value for clockwise direction as required by the Android orientation
478 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200479 */
Umang Jaine9176552020-09-09 16:17:54 +0530480 if (properties.contains(properties::Rotation)) {
481 int rotation = properties.get(properties::Rotation);
482 orientation_ = (360 - rotation) % 360;
483 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200484
Jacopo Mondi117588b2020-05-23 18:53:54 +0200485 int ret = camera_->acquire();
486 if (ret) {
487 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
488 return ret;
489 }
490
491 ret = initializeStreamConfigurations();
492 camera_->release();
493 return ret;
494}
495
Jacopo Mondibfee6312020-09-01 17:42:13 +0200496std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
497 const PixelFormat &pixelFormat,
498 const std::vector<Size> &resolutions)
499{
500 std::vector<Size> supportedResolutions;
501
502 StreamConfiguration &cfg = cameraConfig->at(0);
503 for (const Size &res : resolutions) {
504 cfg.pixelFormat = pixelFormat;
505 cfg.size = res;
506
507 CameraConfiguration::Status status = cameraConfig->validate();
508 if (status != CameraConfiguration::Valid) {
509 LOG(HAL, Debug) << cfg.toString() << " not supported";
510 continue;
511 }
512
513 LOG(HAL, Debug) << cfg.toString() << " supported";
514
515 supportedResolutions.push_back(res);
516 }
517
518 return supportedResolutions;
519}
520
Jacopo Mondi49610332020-09-01 18:11:34 +0200521std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
522{
523 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200524 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200525 StreamConfiguration &cfg = cameraConfig->at(0);
526 const StreamFormats &formats = cfg.formats();
527 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
528
529 return supportedResolutions;
530}
531
Jacopo Mondi117588b2020-05-23 18:53:54 +0200532/*
533 * Initialize the format conversion map to translate from Android format
534 * identifier to libcamera pixel formats and fill in the list of supported
535 * stream configurations to be reported to the Android camera framework through
536 * the static stream configuration metadata.
537 */
538int CameraDevice::initializeStreamConfigurations()
539{
540 /*
541 * Get the maximum output resolutions
542 * \todo Get this from the camera properties once defined
543 */
544 std::unique_ptr<CameraConfiguration> cameraConfig =
545 camera_->generateConfiguration({ StillCapture });
546 if (!cameraConfig) {
547 LOG(HAL, Error) << "Failed to get maximum resolution";
548 return -EINVAL;
549 }
550 StreamConfiguration &cfg = cameraConfig->at(0);
551
552 /*
553 * \todo JPEG - Adjust the maximum available resolution by taking the
554 * JPEG encoder requirements into account (alignment and aspect ratio).
555 */
556 const Size maxRes = cfg.size;
557 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
558
559 /*
560 * Build the list of supported image resolutions.
561 *
562 * The resolutions listed in camera3Resolution are mandatory to be
563 * supported, up to the camera maximum resolution.
564 *
565 * Augment the list by adding resolutions calculated from the camera
566 * maximum one.
567 */
568 std::vector<Size> cameraResolutions;
569 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
570 std::back_inserter(cameraResolutions),
571 [&](const Size &res) { return res < maxRes; });
572
573 /*
574 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
575 * resolution.
576 */
577 for (unsigned int divider = 2;; divider <<= 1) {
578 Size derivedSize{
579 maxRes.width / divider,
580 maxRes.height / divider,
581 };
582
583 if (derivedSize.width < 320 ||
584 derivedSize.height < 240)
585 break;
586
587 cameraResolutions.push_back(derivedSize);
588 }
589 cameraResolutions.push_back(maxRes);
590
591 /* Remove duplicated entries from the list of supported resolutions. */
592 std::sort(cameraResolutions.begin(), cameraResolutions.end());
593 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
594 cameraResolutions.erase(last, cameraResolutions.end());
595
596 /*
597 * Build the list of supported camera formats.
598 *
599 * To each Android format a list of compatible libcamera formats is
600 * associated. The first libcamera format that tests successful is added
601 * to the format translation map used when configuring the streams.
602 * It is then tested against the list of supported camera resolutions to
603 * build the stream configuration map reported through the camera static
604 * metadata.
605 */
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100606 Size maxJpegSize;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200607 for (const auto &format : camera3FormatsMap) {
608 int androidFormat = format.first;
609 const Camera3Format &camera3Format = format.second;
610 const std::vector<PixelFormat> &libcameraFormats =
611 camera3Format.libcameraFormats;
612
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200613 LOG(HAL, Debug) << "Trying to map Android format "
614 << camera3Format.name;
615
Jacopo Mondi117588b2020-05-23 18:53:54 +0200616 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200617 * JPEG is always supported, either produced directly by the
618 * camera, or encoded in the HAL.
619 */
620 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
621 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200622 LOG(HAL, Debug) << "Mapped Android format "
623 << camera3Format.name << " to "
624 << formats::MJPEG.toString()
625 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200626 continue;
627 }
628
629 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200630 * Test the libcamera formats that can produce images
631 * compatible with the format defined by Android.
632 */
633 PixelFormat mappedFormat;
634 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200635
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200636 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
637
Jacopo Mondi117588b2020-05-23 18:53:54 +0200638 /*
639 * The stream configuration size can be adjusted,
640 * not the pixel format.
641 *
642 * \todo This could be simplified once all pipeline
643 * handlers will report the StreamFormats list of
644 * supported formats.
645 */
646 cfg.pixelFormat = pixelFormat;
647
648 CameraConfiguration::Status status = cameraConfig->validate();
649 if (status != CameraConfiguration::Invalid &&
650 cfg.pixelFormat == pixelFormat) {
651 mappedFormat = pixelFormat;
652 break;
653 }
654 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200655
656 if (!mappedFormat.isValid()) {
657 /* If the format is not mandatory, skip it. */
658 if (!camera3Format.mandatory)
659 continue;
660
661 LOG(HAL, Error)
662 << "Failed to map mandatory Android format "
663 << camera3Format.name << " ("
664 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200665 return -EINVAL;
666 }
667
668 /*
669 * Record the mapping and then proceed to generate the
670 * stream configurations map, by testing the image resolutions.
671 */
672 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200673 LOG(HAL, Debug) << "Mapped Android format "
674 << camera3Format.name << " to "
675 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200676
Jacopo Mondi49610332020-09-01 18:11:34 +0200677 std::vector<Size> resolutions;
678 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
679 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
680 resolutions = getRawResolutions(mappedFormat);
681 else
682 resolutions = getYUVResolutions(cameraConfig.get(),
683 mappedFormat,
684 cameraResolutions);
685
Jacopo Mondibfee6312020-09-01 17:42:13 +0200686 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200687 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200688
689 /*
690 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
691 * from which JPEG is produced, add an entry for
692 * the JPEG stream.
693 *
694 * \todo Wire the JPEG encoder to query the supported
695 * sizes provided a list of formats it can encode.
696 *
697 * \todo Support JPEG streams produced by the Camera
698 * natively.
699 */
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100700 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
Jacopo Mondi843565c2020-09-01 15:34:13 +0200701 streamConfigurations_.push_back(
702 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100703 maxJpegSize = std::max(maxJpegSize, res);
704 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200705 }
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100706
707 /*
708 * \todo Calculate the maximum JPEG buffer size by asking the
709 * encoder giving the maximum frame size required.
710 */
711 maxJpegBufferSize_ = maxJpegSize.width * maxJpegSize.height * 1.5;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200712 }
713
714 LOG(HAL, Debug) << "Collected stream configuration map: ";
715 for (const auto &entry : streamConfigurations_)
716 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200717 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200718
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200719 return 0;
720}
721
722/*
723 * Open a camera device. The static information on the camera shall have been
724 * initialized with a call to CameraDevice::initialize().
725 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200726int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200727{
728 int ret = camera_->acquire();
729 if (ret) {
730 LOG(HAL, Error) << "Failed to acquire the camera";
731 return ret;
732 }
733
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200734 /* Initialize the hw_device_t in the instance camera3_module_t. */
735 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
736 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
737 camera3Device_.common.module = (hw_module_t *)hardwareModule;
738 camera3Device_.common.close = hal_dev_close;
739
740 /*
741 * The camera device operations. These actually implement
742 * the Android Camera HALv3 interface.
743 */
744 camera3Device_.ops = &hal_dev_ops;
745 camera3Device_.priv = this;
746
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200747 return 0;
748}
749
750void CameraDevice::close()
751{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200752 streams_.clear();
753
Hirokazu Honda0b661d72021-04-02 11:12:37 +0900754 stop();
755
756 camera_->release();
757}
758
759void CameraDevice::stop()
760{
761 if (!running_)
762 return;
763
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200764 worker_.stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200765 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200766
Hirokazu Hondad4043012021-04-03 22:57:34 +0900767 descriptors_.clear();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200768 running_ = false;
769}
770
771void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
772{
773 callbacks_ = callbacks;
774}
775
Jacopo Mondia80d3812020-05-26 12:31:35 +0200776std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
777{
778 /*
779 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100780 * Currently: 54 entries, 874 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200781 */
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100782 uint32_t numEntries = 54;
783 uint32_t byteSize = 874;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200784
785 /*
786 * Calculate space occupation in bytes for dynamically built metadata
787 * entries.
788 *
Jacopo Mondi00982fb2021-02-04 16:57:55 +0100789 * Each stream configuration entry requires 48 bytes:
Jacopo Mondia80d3812020-05-26 12:31:35 +0200790 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200791 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
792 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200793 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200794
Jacopo Mondi9e807052021-02-04 15:32:00 +0100795 /*
796 * 2 32bits integers for each HAL_PIXEL_FORMAT_BLOB for thumbnail sizes
797 * 2 32bits integers for the (0, 0) thumbnail size
798 *
799 * This is a worst case estimates as different configurations with the
800 * same aspect ratio will generate the same size.
801 */
802 for (const auto &entry : streamConfigurations_) {
803 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
804 continue;
805
806 byteSize += 8;
807 }
808 byteSize += 8;
809
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300810 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200811}
812
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200813/*
814 * Return static information for the camera.
815 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200816const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200817{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200818 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300819 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200820
821 /*
822 * The here reported metadata are enough to implement a basic capture
823 * example application, but a real camera implementation will require
824 * more.
825 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200826 uint32_t numEntries;
827 uint32_t byteSize;
828 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
Hirokazu Hondadca709c2021-03-24 16:07:56 +0900829 staticMetadata_ = std::make_unique<CameraMetadata>(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300830 if (!staticMetadata_->isValid()) {
831 LOG(HAL, Error) << "Failed to allocate static metadata";
Hirokazu Hondadca709c2021-03-24 16:07:56 +0900832 staticMetadata_.reset();
Laurent Pinchart39860092019-09-05 03:12:34 +0300833 return nullptr;
834 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200835
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200836 const ControlInfoMap &controlsInfo = camera_->controls();
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100837 const ControlList &properties = camera_->properties();
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200838
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200839 /* Color correction static metadata. */
Jacopo Mondi63336862020-10-08 16:18:26 +0200840 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100841 std::vector<uint8_t> data;
842 data.reserve(3);
Jacopo Mondi63336862020-10-08 16:18:26 +0200843 const auto &infoMap = controlsInfo.find(&controls::draft::ColorCorrectionAberrationMode);
844 if (infoMap != controlsInfo.end()) {
845 for (const auto &value : infoMap->second.values())
846 data.push_back(value.get<int32_t>());
847 } else {
848 data.push_back(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
849 }
850 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
851 data.data(), data.size());
852 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200853
854 /* Control static metadata. */
855 std::vector<uint8_t> aeAvailableAntiBandingModes = {
856 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
857 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
858 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
859 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
860 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300861 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
862 aeAvailableAntiBandingModes.data(),
863 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200864
865 std::vector<uint8_t> aeAvailableModes = {
866 ANDROID_CONTROL_AE_MODE_ON,
867 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300868 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
869 aeAvailableModes.data(),
870 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200871
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100872 int64_t minFrameDurationNsec = -1;
873 int64_t maxFrameDurationNsec = -1;
874 const auto frameDurationsInfo = controlsInfo.find(&controls::FrameDurations);
875 if (frameDurationsInfo != controlsInfo.end()) {
876 minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000;
877 maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000;
878
879 /*
880 * Adjust the minimum frame duration to comply with Android
881 * requirements. The camera service mandates all preview/record
882 * streams to have a minimum frame duration < 33,366 milliseconds
883 * (see MAX_PREVIEW_RECORD_DURATION_NS in the camera service
884 * implementation).
885 *
886 * If we're close enough (+ 500 useconds) to that value, round
887 * the minimum frame duration of the camera to an accepted
888 * value.
889 */
890 static constexpr int64_t MAX_PREVIEW_RECORD_DURATION_NS = 1e9 / 29.97;
891 if (minFrameDurationNsec > MAX_PREVIEW_RECORD_DURATION_NS &&
892 minFrameDurationNsec < MAX_PREVIEW_RECORD_DURATION_NS + 500000)
893 minFrameDurationNsec = MAX_PREVIEW_RECORD_DURATION_NS - 1000;
894
895 /*
896 * The AE routine frame rate limits are computed using the frame
897 * duration limits, as libcamera clips the AE routine to the
898 * frame durations.
899 */
900 int32_t maxFps = std::round(1e9 / minFrameDurationNsec);
901 int32_t minFps = std::round(1e9 / maxFrameDurationNsec);
902 minFps = std::max(1, minFps);
903
904 /*
905 * Register to the camera service {min, max} and {max, max}
906 * intervals as requested by the metadata documentation.
907 */
908 int32_t availableAeFpsTarget[] = {
909 minFps, maxFps, maxFps, maxFps
910 };
911 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
912 availableAeFpsTarget, 4);
913 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200914
915 std::vector<int32_t> aeCompensationRange = {
916 0, 0,
917 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300918 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
919 aeCompensationRange.data(),
920 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200921
922 const camera_metadata_rational_t aeCompensationStep[] = {
923 { 0, 1 }
924 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300925 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
926 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200927
928 std::vector<uint8_t> availableAfModes = {
929 ANDROID_CONTROL_AF_MODE_OFF,
930 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300931 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
932 availableAfModes.data(),
933 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200934
935 std::vector<uint8_t> availableEffects = {
936 ANDROID_CONTROL_EFFECT_MODE_OFF,
937 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300938 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
939 availableEffects.data(),
940 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200941
942 std::vector<uint8_t> availableSceneModes = {
943 ANDROID_CONTROL_SCENE_MODE_DISABLED,
944 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300945 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
946 availableSceneModes.data(),
947 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200948
949 std::vector<uint8_t> availableStabilizationModes = {
950 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
951 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300952 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
953 availableStabilizationModes.data(),
954 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200955
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100956 /*
957 * \todo Inspect the Camera capabilities to report the available
958 * AWB modes. Default to AUTO as CTS tests require it.
959 */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200960 std::vector<uint8_t> availableAwbModes = {
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100961 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200962 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300963 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
964 availableAwbModes.data(),
965 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200966
967 std::vector<int32_t> availableMaxRegions = {
968 0, 0, 0,
969 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300970 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
971 availableMaxRegions.data(),
972 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200973
974 std::vector<uint8_t> sceneModesOverride = {
975 ANDROID_CONTROL_AE_MODE_ON,
976 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondif266c0e2021-02-03 16:34:40 +0100977 ANDROID_CONTROL_AF_MODE_OFF,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200978 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300979 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
980 sceneModesOverride.data(),
981 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200982
983 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300984 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
985 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200986
987 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300988 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
989 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200990
991 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300992 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
993 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200994
995 /* JPEG static metadata. */
Jacopo Mondi9e807052021-02-04 15:32:00 +0100996
997 /*
998 * Create the list of supported thumbnail sizes by inspecting the
999 * available JPEG resolutions collected in streamConfigurations_ and
1000 * generate one entry for each aspect ratio.
1001 *
1002 * The JPEG thumbnailer can freely scale, so pick an arbitrary
1003 * (160, 160) size as the bounding rectangle, which is then cropped to
1004 * the different supported aspect ratios.
1005 */
1006 constexpr Size maxJpegThumbnail(160, 160);
1007 std::vector<Size> thumbnailSizes;
1008 thumbnailSizes.push_back({ 0, 0 });
1009 for (const auto &entry : streamConfigurations_) {
1010 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
1011 continue;
1012
1013 Size thumbnailSize = maxJpegThumbnail
1014 .boundedToAspectRatio({ entry.resolution.width,
1015 entry.resolution.height });
1016 thumbnailSizes.push_back(thumbnailSize);
1017 }
1018
1019 std::sort(thumbnailSizes.begin(), thumbnailSizes.end());
1020 auto last = std::unique(thumbnailSizes.begin(), thumbnailSizes.end());
1021 thumbnailSizes.erase(last, thumbnailSizes.end());
1022
1023 /* Transform sizes in to a list of integers that can be consumed. */
1024 std::vector<int32_t> thumbnailEntries;
1025 thumbnailEntries.reserve(thumbnailSizes.size() * 2);
1026 for (const auto &size : thumbnailSizes) {
1027 thumbnailEntries.push_back(size.width);
1028 thumbnailEntries.push_back(size.height);
1029 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001030 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Jacopo Mondi9e807052021-02-04 15:32:00 +01001031 thumbnailEntries.data(), thumbnailEntries.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001032
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001033 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
1034
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001035 /* Sensor static metadata. */
Jacopo Mondi45c6a7e2020-12-18 16:35:35 +01001036 std::array<int32_t, 2> pixelArraySize;
Jacopo Mondicda41ff2020-12-30 17:18:51 +01001037 {
Jacopo Mondi45c6a7e2020-12-18 16:35:35 +01001038 const Size &size = properties.get(properties::PixelArraySize);
1039 pixelArraySize[0] = size.width;
1040 pixelArraySize[1] = size.height;
Jacopo Mondi1889cdc2020-11-06 16:08:16 +01001041 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
Jacopo Mondi45c6a7e2020-12-18 16:35:35 +01001042 pixelArraySize.data(), pixelArraySize.size());
1043 }
1044
1045 if (properties.contains(properties::UnitCellSize)) {
1046 const Size &cellSize = properties.get<Size>(properties::UnitCellSize);
1047 std::array<float, 2> physicalSize{
1048 cellSize.width * pixelArraySize[0] / 1e6f,
1049 cellSize.height * pixelArraySize[1] / 1e6f
1050 };
1051 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1052 physicalSize.data(), physicalSize.size());
Jacopo Mondi1889cdc2020-11-06 16:08:16 +01001053 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001054
Jacopo Mondicda41ff2020-12-30 17:18:51 +01001055 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +01001056 const Span<const Rectangle> &rects =
Jacopo Mondi0ed05322020-12-23 18:34:34 +01001057 properties.get(properties::PixelArrayActiveAreas);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +01001058 std::vector<int32_t> data{
1059 static_cast<int32_t>(rects[0].x),
1060 static_cast<int32_t>(rects[0].y),
1061 static_cast<int32_t>(rects[0].width),
1062 static_cast<int32_t>(rects[0].height),
1063 };
1064 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
1065 data.data(), data.size());
1066 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001067
1068 int32_t sensitivityRange[] = {
1069 32, 2400,
1070 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001071 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
1072 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001073
Jacopo Mondicb35ed22020-12-18 16:28:43 +01001074 /* Report the color filter arrangement if the camera reports it. */
1075 if (properties.contains(properties::draft::ColorFilterArrangement)) {
1076 uint8_t filterArr = properties.get(properties::draft::ColorFilterArrangement);
1077 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
1078 &filterArr, 1);
1079 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001080
Jacopo Mondi753d7532021-01-02 12:34:06 +01001081 const auto &exposureInfo = controlsInfo.find(&controls::ExposureTime);
1082 if (exposureInfo != controlsInfo.end()) {
1083 int64_t exposureTimeRange[2] = {
1084 exposureInfo->second.min().get<int32_t>() * 1000LL,
1085 exposureInfo->second.max().get<int32_t>() * 1000LL,
1086 };
1087 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
1088 &exposureTimeRange, 2);
1089 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001090
Jacopo Mondi64f4f662020-05-25 16:08:22 +02001091 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001092
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001093 std::vector<int32_t> testPatterModes = {
1094 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
1095 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001096 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
1097 testPatterModes.data(),
1098 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001099
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001100 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +03001101 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1102 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001103
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001104 if (maxFrameDurationNsec > 0)
1105 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
1106 &maxFrameDurationNsec, 1);
1107
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001108 /* Statistics static metadata. */
1109 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001110 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1111 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001112
1113 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001114 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1115 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001116
Jacopo Mondi2c618502020-10-08 16:47:36 +02001117 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001118 std::vector<uint8_t> data;
1119 data.reserve(2);
Jacopo Mondi2c618502020-10-08 16:47:36 +02001120 const auto &infoMap = controlsInfo.find(&controls::draft::LensShadingMapMode);
1121 if (infoMap != controlsInfo.end()) {
1122 for (const auto &value : infoMap->second.values())
1123 data.push_back(value.get<int32_t>());
1124 } else {
1125 data.push_back(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
1126 }
1127 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
1128 data.data(), data.size());
1129 }
1130
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001131 /* Sync static metadata. */
1132 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +03001133 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001134
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001135 /* Flash static metadata. */
1136 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001137 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
1138 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001139
1140 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001141 std::vector<float> lensApertures = {
1142 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001143 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001144 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
1145 lensApertures.data(),
1146 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001147
Jacopo Mondi64f4f662020-05-25 16:08:22 +02001148 uint8_t lensFacing;
1149 switch (facing_) {
1150 default:
1151 case CAMERA_FACING_FRONT:
1152 lensFacing = ANDROID_LENS_FACING_FRONT;
1153 break;
1154 case CAMERA_FACING_BACK:
1155 lensFacing = ANDROID_LENS_FACING_BACK;
1156 break;
1157 case CAMERA_FACING_EXTERNAL:
1158 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
1159 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +01001160 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001161 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001162
1163 std::vector<float> lensFocalLenghts = {
1164 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001165 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001166 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1167 lensFocalLenghts.data(),
1168 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001169
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001170 std::vector<uint8_t> opticalStabilizations = {
1171 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
1172 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001173 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1174 opticalStabilizations.data(),
1175 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001176
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001177 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001178 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1179 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001180
1181 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001182 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1183 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001184
1185 /* Noise reduction modes. */
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001186 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001187 std::vector<uint8_t> data;
1188 data.reserve(5);
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001189 const auto &infoMap = controlsInfo.find(&controls::draft::NoiseReductionMode);
1190 if (infoMap != controlsInfo.end()) {
1191 for (const auto &value : infoMap->second.values())
1192 data.push_back(value.get<int32_t>());
1193 } else {
1194 data.push_back(ANDROID_NOISE_REDUCTION_MODE_OFF);
1195 }
1196 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
1197 data.data(), data.size());
1198 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001199
1200 /* Scaler static metadata. */
Phi-Bang Nguyen8634c382021-03-29 19:40:46 +02001201
1202 /*
1203 * \todo The digital zoom factor is a property that depends on the
1204 * desired output configuration and the sensor frame size input to the
1205 * ISP. This information is not available to the Android HAL, not at
1206 * initialization time at least.
1207 *
1208 * As a workaround rely on pipeline handlers initializing the
1209 * ScalerCrop control with the camera default configuration and use the
1210 * maximum and minimum crop rectangles to calculate the digital zoom
1211 * factor.
1212 */
1213 float maxZoom = 1.0f;
1214 const auto scalerCrop = controlsInfo.find(&controls::ScalerCrop);
1215 if (scalerCrop != controlsInfo.end()) {
1216 Rectangle min = scalerCrop->second.min().get<Rectangle>();
1217 Rectangle max = scalerCrop->second.max().get<Rectangle>();
1218 maxZoom = std::min(1.0f * max.width / min.width,
1219 1.0f * max.height / min.height);
Jacopo Mondi31a1a622021-01-03 19:57:36 +01001220 }
Phi-Bang Nguyen8634c382021-03-29 19:40:46 +02001221 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1222 &maxZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001223
Jacopo Mondibde7b982020-05-25 17:18:28 +02001224 std::vector<uint32_t> availableStreamConfigurations;
1225 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
1226 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +02001227 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +02001228 availableStreamConfigurations.push_back(entry.resolution.width);
1229 availableStreamConfigurations.push_back(entry.resolution.height);
1230 availableStreamConfigurations.push_back(
1231 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
1232 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001233 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1234 availableStreamConfigurations.data(),
1235 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001236
1237 std::vector<int64_t> availableStallDurations = {
1238 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
1239 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001240 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1241 availableStallDurations.data(),
1242 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001243
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001244 /* Use the minimum frame duration for all the YUV/RGB formats. */
1245 if (minFrameDurationNsec > 0) {
1246 std::vector<int64_t> minFrameDurations;
1247 minFrameDurations.reserve(streamConfigurations_.size() * 4);
1248 for (const auto &entry : streamConfigurations_) {
1249 minFrameDurations.push_back(entry.androidFormat);
1250 minFrameDurations.push_back(entry.resolution.width);
1251 minFrameDurations.push_back(entry.resolution.height);
1252 minFrameDurations.push_back(minFrameDurationNsec);
1253 }
1254 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1255 minFrameDurations.data(),
1256 minFrameDurations.size());
Jacopo Mondibde7b982020-05-25 17:18:28 +02001257 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001258
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001259 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001260 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001261
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001262 /* Info static metadata. */
1263 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001264 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
1265 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001266
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001267 /* Request static metadata. */
1268 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001269 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1270 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001271
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +02001272 {
1273 /* Default the value to 2 if not reported by the camera. */
1274 uint8_t maxPipelineDepth = 2;
1275 const auto &infoMap = controlsInfo.find(&controls::draft::PipelineDepth);
1276 if (infoMap != controlsInfo.end())
1277 maxPipelineDepth = infoMap->second.max().get<int32_t>();
1278 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
1279 &maxPipelineDepth, 1);
1280 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001281
Niklas Söderlunda2a6f952020-07-21 00:16:02 +02001282 /* LIMITED does not support reprocessing. */
1283 uint32_t maxNumInputStreams = 0;
1284 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1285 &maxNumInputStreams, 1);
1286
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001287 std::vector<uint8_t> availableCapabilities = {
1288 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
1289 };
Niklas Söderlund7876d632020-07-21 00:16:24 +02001290
1291 /* Report if camera supports RAW. */
Jacopo Mondieec6c542020-12-09 18:16:11 +01001292 bool rawStreamAvailable = false;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001293 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +02001294 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +02001295 if (cameraConfig && !cameraConfig->empty()) {
1296 const PixelFormatInfo &info =
1297 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
Niklas Söderlund35de31e2020-12-31 00:11:59 +01001298 /* Only advertise RAW support if RAW16 is possible. */
1299 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW &&
1300 info.bitsPerPixel == 16) {
Jacopo Mondieec6c542020-12-09 18:16:11 +01001301 rawStreamAvailable = true;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001302 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
Jacopo Mondieec6c542020-12-09 18:16:11 +01001303 }
Niklas Söderlund7876d632020-07-21 00:16:24 +02001304 }
1305
Jacopo Mondieec6c542020-12-09 18:16:11 +01001306 /* Number of { RAW, YUV, JPEG } supported output streams */
1307 int32_t numOutStreams[] = { rawStreamAvailable, 2, 1 };
1308 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
1309 &numOutStreams, 3);
1310
Laurent Pinchart39860092019-09-05 03:12:34 +03001311 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1312 availableCapabilities.data(),
1313 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001314
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001315 std::vector<int32_t> availableCharacteristicsKeys = {
1316 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
1317 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
1318 ANDROID_CONTROL_AE_AVAILABLE_MODES,
1319 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1320 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
1321 ANDROID_CONTROL_AE_COMPENSATION_STEP,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001322 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001323 ANDROID_CONTROL_AF_AVAILABLE_MODES,
1324 ANDROID_CONTROL_AVAILABLE_EFFECTS,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001325 ANDROID_CONTROL_AVAILABLE_MODES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001326 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
1327 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
1328 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001329 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001330 ANDROID_CONTROL_MAX_REGIONS,
1331 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001332 ANDROID_FLASH_INFO_AVAILABLE,
1333 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001334 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001335 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001336 ANDROID_LENS_FACING,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001337 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001338 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1339 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1340 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1341 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1342 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001343 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1344 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1345 ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001346 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1347 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001348 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1349 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1350 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1351 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1352 ANDROID_SCALER_CROPPING_TYPE,
1353 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
1354 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
1355 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
1356 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001357 ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001358 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1359 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
1360 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
1361 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1362 ANDROID_SENSOR_ORIENTATION,
1363 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1364 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1365 ANDROID_SYNC_MAX_LATENCY,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001366 };
1367 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
1368 availableCharacteristicsKeys.data(),
1369 availableCharacteristicsKeys.size());
1370
1371 std::vector<int32_t> availableRequestKeys = {
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001372 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1373 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001374 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001375 ANDROID_CONTROL_AE_LOCK,
1376 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001377 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001378 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001379 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001380 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001381 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001382 ANDROID_CONTROL_AWB_MODE,
1383 ANDROID_CONTROL_CAPTURE_INTENT,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001384 ANDROID_CONTROL_EFFECT_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001385 ANDROID_CONTROL_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001386 ANDROID_CONTROL_SCENE_MODE,
1387 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001388 ANDROID_FLASH_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001389 ANDROID_JPEG_ORIENTATION,
1390 ANDROID_JPEG_QUALITY,
1391 ANDROID_JPEG_THUMBNAIL_QUALITY,
1392 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001393 ANDROID_LENS_APERTURE,
1394 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001395 ANDROID_NOISE_REDUCTION_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001396 ANDROID_SCALER_CROP_REGION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001397 ANDROID_STATISTICS_FACE_DETECT_MODE
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001398 };
1399 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
1400 availableRequestKeys.data(),
1401 availableRequestKeys.size());
1402
1403 std::vector<int32_t> availableResultKeys = {
Jacopo Mondi520c3662021-02-03 14:44:34 +01001404 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001405 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondie9c28752021-02-03 14:47:45 +01001406 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001407 ANDROID_CONTROL_AE_LOCK,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001408 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001409 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1410 ANDROID_CONTROL_AE_STATE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001411 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001412 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001413 ANDROID_CONTROL_AF_STATE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001414 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001415 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001416 ANDROID_CONTROL_AWB_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001417 ANDROID_CONTROL_AWB_STATE,
1418 ANDROID_CONTROL_CAPTURE_INTENT,
1419 ANDROID_CONTROL_EFFECT_MODE,
1420 ANDROID_CONTROL_MODE,
1421 ANDROID_CONTROL_SCENE_MODE,
1422 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
1423 ANDROID_FLASH_MODE,
1424 ANDROID_FLASH_STATE,
Paul Elderabfabdd2021-01-23 13:54:28 +09001425 ANDROID_JPEG_GPS_COORDINATES,
1426 ANDROID_JPEG_GPS_PROCESSING_METHOD,
1427 ANDROID_JPEG_GPS_TIMESTAMP,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001428 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001429 ANDROID_JPEG_QUALITY,
1430 ANDROID_JPEG_SIZE,
Paul Elder12646282021-01-23 13:56:01 +09001431 ANDROID_JPEG_THUMBNAIL_QUALITY,
1432 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001433 ANDROID_LENS_APERTURE,
1434 ANDROID_LENS_FOCAL_LENGTH,
1435 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1436 ANDROID_LENS_STATE,
1437 ANDROID_NOISE_REDUCTION_MODE,
1438 ANDROID_REQUEST_PIPELINE_DEPTH,
1439 ANDROID_SCALER_CROP_REGION,
1440 ANDROID_SENSOR_EXPOSURE_TIME,
1441 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
Jacopo Mondi5360d802021-02-03 16:43:22 +01001442 ANDROID_SENSOR_TEST_PATTERN_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001443 ANDROID_SENSOR_TIMESTAMP,
1444 ANDROID_STATISTICS_FACE_DETECT_MODE,
1445 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
Jacopo Mondif29601e2021-02-03 16:47:30 +01001446 ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001447 ANDROID_STATISTICS_SCENE_FLICKER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001448 };
1449 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1450 availableResultKeys.data(),
1451 availableResultKeys.size());
1452
Laurent Pinchart39860092019-09-05 03:12:34 +03001453 if (!staticMetadata_->isValid()) {
1454 LOG(HAL, Error) << "Failed to construct static metadata";
Hirokazu Hondadca709c2021-03-24 16:07:56 +09001455 staticMetadata_.reset();
Laurent Pinchart39860092019-09-05 03:12:34 +03001456 return nullptr;
1457 }
1458
1459 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001460}
1461
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001462std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001463{
Jacopo Mondi63703472019-09-04 16:18:22 +02001464 /*
1465 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001466 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001467 */
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001468 auto requestTemplate = std::make_unique<CameraMetadata>(21, 36);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001469 if (!requestTemplate->isValid()) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001470 return nullptr;
1471 }
1472
Jacopo Mondif1796162021-03-08 17:03:14 +01001473 /* Get the FPS range registered in the static metadata. */
1474 camera_metadata_ro_entry_t entry;
1475 bool found = staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1476 &entry);
1477 if (!found) {
1478 LOG(HAL, Error) << "Cannot create capture template without FPS range";
1479 return nullptr;
1480 }
1481
1482 /*
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001483 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
Jacopo Mondif1796162021-03-08 17:03:14 +01001484 * has been assembled as {{min, max} {max, max}}.
1485 */
1486 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1487 entry.data.i32, 2);
1488
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001489 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001490 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1491 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001492
1493 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001494 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1495 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001496
1497 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001498 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1499 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001500
1501 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001502 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1503 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001504
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001505 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1506 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1507 &aeAntibandingMode, 1);
1508
Jacopo Mondi9690d082021-02-03 16:37:20 +01001509 uint8_t afMode = ANDROID_CONTROL_AF_MODE_OFF;
1510 requestTemplate->addEntry(ANDROID_CONTROL_AF_MODE, &afMode, 1);
1511
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001512 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001513 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1514 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001515
1516 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001517 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1518 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001519
1520 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001521 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1522 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001523
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001524 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001525 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1526 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001527
1528 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001529 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1530 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001531
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001532 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001533 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1534 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001535
1536 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001537 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1538 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001539
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001540 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1541 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1542
1543 float lensAperture = 2.53 / 100;
1544 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1545
1546 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1547 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1548 &opticalStabilization, 1);
1549
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001550 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001551 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1552 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001553
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001554 return requestTemplate;
1555}
1556
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001557std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateVideo()
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001558{
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001559 std::unique_ptr<CameraMetadata> previewTemplate = requestTemplatePreview();
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001560 if (!previewTemplate)
1561 return nullptr;
1562
1563 /*
1564 * The video template requires a fixed FPS range. Everything else
1565 * stays the same as the preview template.
1566 */
1567 camera_metadata_ro_entry_t entry;
1568 staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1569 &entry);
1570
1571 /*
1572 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
1573 * has been assembled as {{min, max} {max, max}}.
1574 */
1575 previewTemplate->updateEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1576 entry.data.i32 + 2, 2);
1577
1578 return previewTemplate;
1579}
1580
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001581/*
1582 * Produce a metadata pack to be used as template for a capture request.
1583 */
1584const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1585{
1586 auto it = requestTemplates_.find(type);
1587 if (it != requestTemplates_.end())
1588 return it->second->get();
1589
1590 /* Use the capture intent matching the requested template type. */
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001591 std::unique_ptr<CameraMetadata> requestTemplate;
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001592 uint8_t captureIntent;
1593 switch (type) {
1594 case CAMERA3_TEMPLATE_PREVIEW:
1595 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001596 requestTemplate = requestTemplatePreview();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001597 break;
1598 case CAMERA3_TEMPLATE_STILL_CAPTURE:
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001599 /*
1600 * Use the preview template for still capture, they only differ
1601 * for the torch mode we currently do not support.
1602 */
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001603 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001604 requestTemplate = requestTemplatePreview();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001605 break;
1606 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1607 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001608 requestTemplate = requestTemplateVideo();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001609 break;
1610 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1611 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001612 requestTemplate = requestTemplateVideo();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001613 break;
Jacopo Mondi2c349912021-03-08 16:13:58 +01001614 /* \todo Implement templates generation for the remaining use cases. */
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001615 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001616 case CAMERA3_TEMPLATE_MANUAL:
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001617 default:
Jacopo Mondi2c349912021-03-08 16:13:58 +01001618 LOG(HAL, Error) << "Unsupported template request type: " << type;
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001619 return nullptr;
1620 }
1621
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001622 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001623 LOG(HAL, Error) << "Failed to construct request template";
Laurent Pinchart39860092019-09-05 03:12:34 +03001624 return nullptr;
1625 }
1626
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001627 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1628 &captureIntent, 1);
1629
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001630 requestTemplates_[type] = std::move(requestTemplate);
1631 return requestTemplates_[type]->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001632}
1633
Hirokazu Hondac1ae9052020-10-28 18:50:23 +09001634PixelFormat CameraDevice::toPixelFormat(int format) const
Kieran Bingham43e3b802020-06-26 09:58:49 +01001635{
1636 /* Translate Android format code to libcamera pixel format. */
1637 auto it = formatsMap_.find(format);
1638 if (it == formatsMap_.end()) {
1639 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1640 << " not supported";
1641 return PixelFormat();
1642 }
1643
1644 return it->second;
1645}
1646
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001647/*
1648 * Inspect the stream_list to produce a list of StreamConfiguration to
1649 * be use to configure the Camera.
1650 */
1651int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1652{
Hirokazu Honda0b661d72021-04-02 11:12:37 +09001653 /* Before any configuration attempt, stop the camera. */
1654 stop();
Jacopo Mondi8fed6132020-12-04 15:26:47 +01001655
Hirokazu Hondad13462f2021-04-03 22:18:28 +09001656 if (stream_list->num_streams == 0) {
1657 LOG(HAL, Error) << "No streams in configuration";
1658 return -EINVAL;
1659 }
1660
Hirokazu Honda4ae2a752021-04-03 22:10:13 +09001661#if defined(OS_CHROMEOS)
1662 if (!validateCropRotate(*stream_list))
1663 return -EINVAL;
1664#endif
1665
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001666 /*
1667 * Generate an empty configuration, and construct a StreamConfiguration
1668 * for each camera3_stream to add to it.
1669 */
1670 config_ = camera_->generateConfiguration();
1671 if (!config_) {
1672 LOG(HAL, Error) << "Failed to generate camera configuration";
1673 return -EINVAL;
1674 }
1675
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001676 /*
1677 * Clear and remove any existing configuration from previous calls, and
1678 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001679 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001680 */
1681 streams_.clear();
1682 streams_.reserve(stream_list->num_streams);
1683
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001684 std::vector<Camera3StreamConfig> streamConfigs;
1685 streamConfigs.reserve(stream_list->num_streams);
1686
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001687 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001688 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001689 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1690 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001691 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001692
Kieran Bingham43e3b802020-06-26 09:58:49 +01001693 PixelFormat format = toPixelFormat(stream->format);
1694
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001695 LOG(HAL, Info) << "Stream #" << i
1696 << ", direction: " << stream->stream_type
1697 << ", width: " << stream->width
1698 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001699 << ", format: " << utils::hex(stream->format)
Hirokazu Hondaac209ef2021-04-03 22:10:14 +09001700 << ", rotation: " << rotationToString(stream->rotation)
1701#if defined(OS_CHROMEOS)
1702 << ", crop_rotate_scale_degrees: "
1703 << rotationToString(stream->crop_rotate_scale_degrees)
1704#endif
Kieran Bingham43e3b802020-06-26 09:58:49 +01001705 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001706
1707 if (!format.isValid())
1708 return -EINVAL;
1709
Hirokazu Hondac85b6c82021-04-03 22:10:15 +09001710 /* \todo Support rotation. */
1711 if (stream->rotation != CAMERA3_STREAM_ROTATION_0) {
1712 LOG(HAL, Error) << "Rotation is not supported";
1713 return -EINVAL;
1714 }
1715#if defined(OS_CHROMEOS)
1716 if (stream->crop_rotate_scale_degrees != CAMERA3_STREAM_ROTATION_0) {
1717 LOG(HAL, Error) << "Rotation is not supported";
1718 return -EINVAL;
1719 }
1720#endif
1721
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001722 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001723 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1724 if (jpegStream) {
1725 LOG(HAL, Error)
1726 << "Multiple JPEG streams are not supported";
1727 return -EINVAL;
1728 }
1729
1730 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001731 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001732 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001733
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001734 Camera3StreamConfig streamConfig;
1735 streamConfig.streams = { { stream, CameraStream::Type::Direct } };
1736 streamConfig.config.size = size;
1737 streamConfig.config.pixelFormat = format;
1738 streamConfigs.push_back(std::move(streamConfig));
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001739
1740 /* This stream will be produced by hardware. */
1741 stream->usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001742 }
1743
Jacopo Mondic82f9442020-09-02 11:58:00 +02001744 /* Now handle the MJPEG streams, adding a new stream if required. */
1745 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001746 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001747 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001748
Jacopo Mondic82f9442020-09-02 11:58:00 +02001749 /* Search for a compatible stream in the non-JPEG ones. */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001750 for (size_t i = 0; i < streamConfigs.size(); ++i) {
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001751 Camera3StreamConfig &streamConfig = streamConfigs[i];
1752 const auto &cfg = streamConfig.config;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001753
1754 /*
1755 * \todo The PixelFormat must also be compatible with
1756 * the encoder.
1757 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001758 if (cfg.size.width != jpegStream->width ||
1759 cfg.size.height != jpegStream->height)
1760 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001761
Jacopo Mondic82f9442020-09-02 11:58:00 +02001762 LOG(HAL, Info)
1763 << "Android JPEG stream mapped to libcamera stream " << i;
1764
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001765 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001766 index = i;
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001767
1768 /*
1769 * The source stream will be read by software to
1770 * produce the JPEG stream.
1771 */
1772 camera3_stream_t *stream = streamConfig.streams[0].stream;
1773 stream->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001774 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001775 }
1776
1777 /*
1778 * Without a compatible match for JPEG encoding we must
1779 * introduce a new stream to satisfy the request requirements.
1780 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001781 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001782 /*
1783 * \todo The pixelFormat should be a 'best-fit' choice
1784 * and may require a validation cycle. This is not yet
1785 * handled, and should be considered as part of any
1786 * stream configuration reworks.
1787 */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001788 Camera3StreamConfig streamConfig;
1789 streamConfig.config.size.width = jpegStream->width;
1790 streamConfig.config.size.height = jpegStream->height;
1791 streamConfig.config.pixelFormat = formats::NV12;
1792 streamConfigs.push_back(std::move(streamConfig));
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001793
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001794 LOG(HAL, Info) << "Adding " << streamConfig.config.toString()
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001795 << " for MJPEG support";
1796
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001797 type = CameraStream::Type::Internal;
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001798 index = streamConfigs.size() - 1;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001799 }
1800
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001801 /* The JPEG stream will be produced by software. */
1802 jpegStream->usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
1803
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001804 streamConfigs[index].streams.push_back({ jpegStream, type });
1805 }
1806
Hirokazu Honda26d90af2020-12-11 09:53:36 +00001807 sortCamera3StreamConfigs(streamConfigs, jpegStream);
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001808 for (const auto &streamConfig : streamConfigs) {
1809 config_->addConfiguration(streamConfig.config);
1810
1811 for (auto &stream : streamConfig.streams) {
1812 streams_.emplace_back(this, stream.type, stream.stream,
1813 config_->size() - 1);
1814 stream.stream->priv = static_cast<void *>(&streams_.back());
1815 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001816 }
1817
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001818 switch (config_->validate()) {
1819 case CameraConfiguration::Valid:
1820 break;
1821 case CameraConfiguration::Adjusted:
1822 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001823
1824 for (const StreamConfiguration &cfg : *config_)
1825 LOG(HAL, Info) << " - " << cfg.toString();
1826
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001827 config_.reset();
1828 return -EINVAL;
1829 case CameraConfiguration::Invalid:
1830 LOG(HAL, Info) << "Camera configuration invalid";
1831 config_.reset();
1832 return -EINVAL;
1833 }
1834
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001835 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001836 * Once the CameraConfiguration has been adjusted/validated
1837 * it can be applied to the camera.
1838 */
1839 int ret = camera_->configure(config_.get());
1840 if (ret) {
1841 LOG(HAL, Error) << "Failed to configure camera '"
1842 << camera_->id() << "'";
1843 return ret;
1844 }
1845
1846 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001847 * Configure the HAL CameraStream instances using the associated
1848 * StreamConfiguration and set the number of required buffers in
1849 * the Android camera3_stream_t.
1850 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001851 for (CameraStream &cameraStream : streams_) {
Kieran Binghamc7bcae02020-10-13 15:58:26 +01001852 ret = cameraStream.configure();
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001853 if (ret) {
1854 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001855 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001856 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001857 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001858
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001859 return 0;
1860}
1861
Kieran Bingham74ab4422020-07-01 13:25:38 +01001862FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1863{
1864 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001865 for (int i = 0; i < camera3buffer->numFds; i++) {
1866 /* Skip unused planes. */
1867 if (camera3buffer->data[i] == -1)
1868 break;
1869
Kieran Bingham74ab4422020-07-01 13:25:38 +01001870 FrameBuffer::Plane plane;
1871 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001872 if (!plane.fd.isValid()) {
1873 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1874 << camera3buffer->data[i] << ") "
1875 << " on plane " << i;
1876 return nullptr;
1877 }
1878
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001879 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1880 if (length == -1) {
1881 LOG(HAL, Error) << "Failed to query plane length";
1882 return nullptr;
1883 }
1884
1885 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001886 planes.push_back(std::move(plane));
1887 }
1888
1889 return new FrameBuffer(std::move(planes));
1890}
1891
Jacopo Mondibb2b4002021-01-04 16:20:05 +01001892int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)
1893{
1894 const CameraMetadata &settings = descriptor->settings_;
1895 if (!settings.isValid())
1896 return 0;
1897
1898 /* Translate the Android request settings to libcamera controls. */
1899 camera_metadata_ro_entry_t entry;
1900 if (settings.getEntry(ANDROID_SCALER_CROP_REGION, &entry)) {
1901 const int32_t *data = entry.data.i32;
1902 Rectangle cropRegion{ data[0], data[1],
1903 static_cast<unsigned int>(data[2]),
1904 static_cast<unsigned int>(data[3]) };
1905 ControlList &controls = descriptor->request_->controls();
1906 controls.set(controls::ScalerCrop, cropRegion);
1907 }
1908
1909 return 0;
1910}
1911
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001912int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001913{
Hirokazu Honda7633a2d2021-04-03 22:37:40 +09001914 if (!isValidRequest(camera3Request))
Jacopo Mondic5b732b2020-12-01 17:12:19 +01001915 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001916
1917 /* Start the camera if that's the first request we handle. */
1918 if (!running_) {
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001919 worker_.start();
1920
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001921 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001922 if (ret) {
1923 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001924 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001925 }
1926
1927 running_ = true;
1928 }
1929
1930 /*
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001931 * Save the request descriptors for use at completion time.
1932 * The descriptor and the associated memory reserved here are freed
1933 * at request complete time.
1934 */
Hirokazu Hondad4043012021-04-03 22:57:34 +09001935 Camera3RequestDescriptor descriptor(camera_.get(), camera3Request);
1936
Paul Eldera6de3f02021-01-21 18:59:24 +09001937 /*
1938 * \todo The Android request model is incremental, settings passed in
1939 * previous requests are to be effective until overridden explicitly in
1940 * a new request. Do we need to cache settings incrementally here, or is
1941 * it handled by the Android camera service ?
1942 */
1943 if (camera3Request->settings)
1944 lastSettings_ = camera3Request->settings;
1945 else
Hirokazu Hondad4043012021-04-03 22:57:34 +09001946 descriptor.settings_ = lastSettings_;
Kieran Binghameac05422020-07-01 13:28:16 +01001947
Hirokazu Hondad4043012021-04-03 22:57:34 +09001948 LOG(HAL, Debug) << "Queueing request " << descriptor.request_->cookie()
1949 << " with " << descriptor.buffers_.size() << " streams";
1950 for (unsigned int i = 0; i < descriptor.buffers_.size(); ++i) {
1951 const camera3_stream_buffer_t &camera3Buffer = descriptor.buffers_[i];
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001952 camera3_stream *camera3Stream = camera3Buffer.stream;
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001953 CameraStream *cameraStream = static_cast<CameraStream *>(camera3Stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001954
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001955 std::stringstream ss;
1956 ss << i << " - (" << camera3Stream->width << "x"
1957 << camera3Stream->height << ")"
1958 << "[" << utils::hex(camera3Stream->format) << "] -> "
1959 << "(" << cameraStream->configuration().size.toString() << ")["
1960 << cameraStream->configuration().pixelFormat.toString() << "]";
1961
Jacopo Mondide8304b2020-09-04 17:45:39 +02001962 /*
1963 * Inspect the camera stream type, create buffers opportunely
1964 * and add them to the Request if required.
1965 */
1966 FrameBuffer *buffer = nullptr;
1967 switch (cameraStream->type()) {
1968 case CameraStream::Type::Mapped:
1969 /*
1970 * Mapped streams don't need buffers added to the
1971 * Request.
1972 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001973 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001974 continue;
1975
Jacopo Mondide8304b2020-09-04 17:45:39 +02001976 case CameraStream::Type::Direct:
1977 /*
1978 * Create a libcamera buffer using the dmabuf
1979 * descriptors of the camera3Buffer for each stream and
1980 * associate it with the Camera3RequestDescriptor for
1981 * lifetime management only.
1982 */
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001983 buffer = createFrameBuffer(*camera3Buffer.buffer);
Hirokazu Hondad4043012021-04-03 22:57:34 +09001984 descriptor.frameBuffers_.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001985 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001986 break;
1987
1988 case CameraStream::Type::Internal:
1989 /*
1990 * Get the frame buffer from the CameraStream internal
1991 * buffer pool.
1992 *
1993 * The buffer has to be returned to the CameraStream
1994 * once it has been processed.
1995 */
1996 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001997 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001998 break;
1999 }
2000
Kieran Bingham0cfdf732020-07-01 13:36:24 +01002001 if (!buffer) {
2002 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01002003 return -ENOMEM;
2004 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002005
Hirokazu Hondad4043012021-04-03 22:57:34 +09002006 descriptor.request_->addBuffer(cameraStream->stream(), buffer,
Hirokazu Honda17a6e782021-03-24 16:07:55 +09002007 camera3Buffer.acquire_fence);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01002008 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002009
Jacopo Mondibb2b4002021-01-04 16:20:05 +01002010 /*
2011 * Translate controls from Android to libcamera and queue the request
2012 * to the CameraWorker thread.
2013 */
Hirokazu Hondad4043012021-04-03 22:57:34 +09002014 int ret = processControls(&descriptor);
Jacopo Mondibb2b4002021-01-04 16:20:05 +01002015 if (ret)
2016 return ret;
2017
Hirokazu Hondad4043012021-04-03 22:57:34 +09002018 worker_.queueRequest(descriptor.request_.get());
2019
2020 {
2021 std::scoped_lock<std::mutex> lock(mutex_);
2022 descriptors_[descriptor.request_->cookie()] = std::move(descriptor);
2023 }
Paul Elderc7532232020-09-23 19:05:41 +09002024
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02002025 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002026}
2027
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02002028void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002029{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002030 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03002031 std::unique_ptr<CameraMetadata> resultMetadata;
Hirokazu Hondad4043012021-04-03 22:57:34 +09002032
2033 decltype(descriptors_)::node_type node;
2034 {
2035 std::scoped_lock<std::mutex> lock(mutex_);
2036 auto it = descriptors_.find(request->cookie());
2037 if (it == descriptors_.end()) {
2038 LOG(HAL, Fatal)
2039 << "Unknown request: " << request->cookie();
2040 status = CAMERA3_BUFFER_STATUS_ERROR;
2041 return;
2042 }
2043
2044 node = descriptors_.extract(it);
2045 }
2046 Camera3RequestDescriptor &descriptor = node.mapped();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002047
2048 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01002049 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002050 << request->status();
2051 status = CAMERA3_BUFFER_STATUS_ERROR;
2052 }
2053
Jacopo Mondibc644072021-01-28 09:58:06 +01002054 LOG(HAL, Debug) << "Request " << request->cookie() << " completed with "
Hirokazu Hondad4043012021-04-03 22:57:34 +09002055 << descriptor.buffers_.size() << " streams";
Jacopo Mondibc644072021-01-28 09:58:06 +01002056
Jacopo Mondid66fd812021-04-07 16:25:32 +02002057 resultMetadata = getResultMetadata(descriptor);
Kieran Binghamc09aee42020-07-28 14:01:19 +01002058
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002059 /* Handle any JPEG compression. */
Hirokazu Hondad4043012021-04-03 22:57:34 +09002060 for (camera3_stream_buffer_t &buffer : descriptor.buffers_) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002061 CameraStream *cameraStream =
Hirokazu Honda17a6e782021-03-24 16:07:55 +09002062 static_cast<CameraStream *>(buffer.stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002063
Jacopo Mondi160bb092020-10-02 20:48:35 +02002064 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002065 continue;
2066
Jacopo Mondid5473c92021-02-17 16:21:59 +01002067 FrameBuffer *src = request->findBuffer(cameraStream->stream());
2068 if (!src) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002069 LOG(HAL, Error) << "Failed to find a source stream buffer";
2070 continue;
2071 }
2072
Jacopo Mondia725baf2021-02-24 12:50:40 +01002073 int ret = cameraStream->process(*src,
Hirokazu Honda17a6e782021-03-24 16:07:55 +09002074 *buffer.buffer,
Hirokazu Hondad4043012021-04-03 22:57:34 +09002075 descriptor.settings_,
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02002076 resultMetadata.get());
2077 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002078 status = CAMERA3_BUFFER_STATUS_ERROR;
2079 continue;
2080 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02002081
2082 /*
2083 * Return the FrameBuffer to the CameraStream now that we're
2084 * done processing it.
2085 */
2086 if (cameraStream->type() == CameraStream::Type::Internal)
Jacopo Mondid5473c92021-02-17 16:21:59 +01002087 cameraStream->putBuffer(src);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002088 }
2089
2090 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002091 camera3_capture_result_t captureResult = {};
Hirokazu Hondad4043012021-04-03 22:57:34 +09002092 captureResult.frame_number = descriptor.frameNumber_;
2093 captureResult.num_output_buffers = descriptor.buffers_.size();
2094 for (camera3_stream_buffer_t &buffer : descriptor.buffers_) {
Hirokazu Honda17a6e782021-03-24 16:07:55 +09002095 buffer.acquire_fence = -1;
2096 buffer.release_fence = -1;
2097 buffer.status = status;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002098 }
Hirokazu Hondad4043012021-04-03 22:57:34 +09002099 captureResult.output_buffers = descriptor.buffers_.data();
Kieran Bingham0cfdf732020-07-01 13:36:24 +01002100
Laurent Pinchart39860092019-09-05 03:12:34 +03002101 if (status == CAMERA3_BUFFER_STATUS_OK) {
Jacopo Mondid66fd812021-04-07 16:25:32 +02002102 uint64_t timestamp =
2103 static_cast<uint64_t>(request->metadata()
2104 .get(controls::SensorTimestamp));
Hirokazu Hondad4043012021-04-03 22:57:34 +09002105 notifyShutter(descriptor.frameNumber_, timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002106
2107 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03002108 captureResult.result = resultMetadata->get();
2109 }
2110
2111 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
2112 /* \todo Improve error handling. In case we notify an error
2113 * because the metadata generation fails, a shutter event has
2114 * already been notified for this frame number before the error
2115 * is here signalled. Make sure the error path plays well with
2116 * the camera stack state machine.
2117 */
Hirokazu Hondad4043012021-04-03 22:57:34 +09002118 notifyError(descriptor.frameNumber_,
2119 descriptor.buffers_[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002120 }
2121
2122 callbacks_->process_capture_result(callbacks_, &captureResult);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002123}
2124
Jacopo Mondia7b92772020-05-26 15:41:41 +02002125std::string CameraDevice::logPrefix() const
2126{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02002127 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02002128}
2129
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002130void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
2131{
2132 camera3_notify_msg_t notify = {};
2133
2134 notify.type = CAMERA3_MSG_SHUTTER;
2135 notify.message.shutter.frame_number = frameNumber;
2136 notify.message.shutter.timestamp = timestamp;
2137
2138 callbacks_->notify(callbacks_, &notify);
2139}
2140
2141void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
2142{
2143 camera3_notify_msg_t notify = {};
2144
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01002145 /*
2146 * \todo Report and identify the stream number or configuration to
2147 * clarify the stream that failed.
2148 */
2149 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
2150 << toPixelFormat(stream->format).toString() << ")";
2151
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002152 notify.type = CAMERA3_MSG_ERROR;
2153 notify.message.error.error_stream = stream;
2154 notify.message.error.frame_number = frameNumber;
2155 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
2156
2157 callbacks_->notify(callbacks_, &notify);
2158}
2159
2160/*
2161 * Produce a set of fixed result metadata.
2162 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03002163std::unique_ptr<CameraMetadata>
Jacopo Mondid66fd812021-04-07 16:25:32 +02002164CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) const
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002165{
Hirokazu Honda82b81512021-03-25 20:13:56 +09002166 const ControlList &metadata = descriptor.request_->metadata();
2167 const CameraMetadata &settings = descriptor.settings_;
Paul Elder958c80a2021-01-26 09:47:33 +09002168 camera_metadata_ro_entry_t entry;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002169 bool found;
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002170
Jacopo Mondi48504ba2019-09-04 16:18:19 +02002171 /*
2172 * \todo Keep this in sync with the actual number of entries.
Paul Elder12646282021-01-23 13:56:01 +09002173 * Currently: 40 entries, 156 bytes
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002174 *
2175 * Reserve more space for the JPEG metadata set by the post-processor.
Paul Elderabfabdd2021-01-23 13:54:28 +09002176 * Currently:
2177 * ANDROID_JPEG_GPS_COORDINATES (double x 3) = 24 bytes
2178 * ANDROID_JPEG_GPS_PROCESSING_METHOD (byte x 32) = 32 bytes
2179 * ANDROID_JPEG_GPS_TIMESTAMP (int64) = 8 bytes
2180 * ANDROID_JPEG_SIZE (int32_t) = 4 bytes
2181 * ANDROID_JPEG_QUALITY (byte) = 1 byte
2182 * ANDROID_JPEG_ORIENTATION (int32_t) = 4 bytes
Paul Elder12646282021-01-23 13:56:01 +09002183 * ANDROID_JPEG_THUMBNAIL_QUALITY (byte) = 1 byte
2184 * ANDROID_JPEG_THUMBNAIL_SIZE (int32 x 2) = 8 bytes
2185 * Total bytes for JPEG metadata: 82
Jacopo Mondi48504ba2019-09-04 16:18:19 +02002186 */
Laurent Pinchart39860092019-09-05 03:12:34 +03002187 std::unique_ptr<CameraMetadata> resultMetadata =
Jacopo Mondif29601e2021-02-03 16:47:30 +01002188 std::make_unique<CameraMetadata>(44, 166);
Laurent Pinchart39860092019-09-05 03:12:34 +03002189 if (!resultMetadata->isValid()) {
2190 LOG(HAL, Error) << "Failed to allocate static metadata";
2191 return nullptr;
2192 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002193
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002194 /*
2195 * \todo The value of the results metadata copied from the settings
2196 * will have to be passed to the libcamera::Camera and extracted
2197 * from libcamera::Request::metadata.
2198 */
2199
Jacopo Mondi520c3662021-02-03 14:44:34 +01002200 uint8_t value = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
2201 resultMetadata->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
2202 &value, 1);
2203
2204 value = ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF;
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002205 resultMetadata->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002206
Jacopo Mondie9c28752021-02-03 14:47:45 +01002207 int32_t value32 = 0;
2208 resultMetadata->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
2209 &value32, 1);
2210
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002211 value = ANDROID_CONTROL_AE_LOCK_OFF;
2212 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002213
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002214 value = ANDROID_CONTROL_AE_MODE_ON;
2215 resultMetadata->addEntry(ANDROID_CONTROL_AE_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002216
Jacopo Mondid1508602021-01-21 18:21:28 +01002217 if (settings.getEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, &entry))
2218 /*
2219 * \todo Retrieve the AE FPS range from the libcamera metadata.
2220 * As libcamera does not support that control, as a temporary
2221 * workaround return what the framework asked.
2222 */
2223 resultMetadata->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
2224 entry.data.i32, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002225
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002226 value = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002227 found = settings.getEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &entry);
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002228 resultMetadata->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002229 found ? entry.data.u8 : &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002230
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002231 value = ANDROID_CONTROL_AE_STATE_CONVERGED;
2232 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &value, 1);
2233
2234 value = ANDROID_CONTROL_AF_MODE_OFF;
2235 resultMetadata->addEntry(ANDROID_CONTROL_AF_MODE, &value, 1);
2236
2237 value = ANDROID_CONTROL_AF_STATE_INACTIVE;
2238 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &value, 1);
2239
2240 value = ANDROID_CONTROL_AF_TRIGGER_IDLE;
2241 resultMetadata->addEntry(ANDROID_CONTROL_AF_TRIGGER, &value, 1);
2242
2243 value = ANDROID_CONTROL_AWB_MODE_AUTO;
2244 resultMetadata->addEntry(ANDROID_CONTROL_AWB_MODE, &value, 1);
2245
2246 value = ANDROID_CONTROL_AWB_LOCK_OFF;
2247 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &value, 1);
2248
2249 value = ANDROID_CONTROL_AWB_STATE_CONVERGED;
2250 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &value, 1);
2251
2252 value = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
2253 resultMetadata->addEntry(ANDROID_CONTROL_CAPTURE_INTENT, &value, 1);
2254
2255 value = ANDROID_CONTROL_EFFECT_MODE_OFF;
2256 resultMetadata->addEntry(ANDROID_CONTROL_EFFECT_MODE, &value, 1);
2257
2258 value = ANDROID_CONTROL_MODE_AUTO;
2259 resultMetadata->addEntry(ANDROID_CONTROL_MODE, &value, 1);
2260
2261 value = ANDROID_CONTROL_SCENE_MODE_DISABLED;
2262 resultMetadata->addEntry(ANDROID_CONTROL_SCENE_MODE, &value, 1);
2263
2264 value = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
2265 resultMetadata->addEntry(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &value, 1);
2266
2267 value = ANDROID_FLASH_MODE_OFF;
2268 resultMetadata->addEntry(ANDROID_FLASH_MODE, &value, 1);
2269
2270 value = ANDROID_FLASH_STATE_UNAVAILABLE;
2271 resultMetadata->addEntry(ANDROID_FLASH_STATE, &value, 1);
2272
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002273 if (settings.getEntry(ANDROID_LENS_APERTURE, &entry))
Paul Elderabfabdd2021-01-23 13:54:28 +09002274 resultMetadata->addEntry(ANDROID_LENS_APERTURE, entry.data.f, 1);
2275
2276 float focal_length = 1.0;
2277 resultMetadata->addEntry(ANDROID_LENS_FOCAL_LENGTH, &focal_length, 1);
2278
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002279 value = ANDROID_LENS_STATE_STATIONARY;
2280 resultMetadata->addEntry(ANDROID_LENS_STATE, &value, 1);
2281
2282 value = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
2283 resultMetadata->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
2284 &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002285
Jacopo Mondi5360d802021-02-03 16:43:22 +01002286 value32 = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
2287 resultMetadata->addEntry(ANDROID_SENSOR_TEST_PATTERN_MODE,
2288 &value32, 1);
2289
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002290 value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
2291 resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
2292 &value, 1);
2293
2294 value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
2295 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
2296 &value, 1);
2297
Jacopo Mondif29601e2021-02-03 16:47:30 +01002298 value = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
2299 resultMetadata->addEntry(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
2300 &value, 1);
2301
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002302 value = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
2303 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
2304 &value, 1);
2305
2306 value = ANDROID_NOISE_REDUCTION_MODE_OFF;
2307 resultMetadata->addEntry(ANDROID_NOISE_REDUCTION_MODE, &value, 1);
2308
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002309 /* 33.3 msec */
2310 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03002311 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
2312 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002313
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002314 /* Add metadata tags reported by libcamera. */
Jacopo Mondid66fd812021-04-07 16:25:32 +02002315 const int64_t timestamp = metadata.get(controls::SensorTimestamp);
2316 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
2317
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002318 if (metadata.contains(controls::draft::PipelineDepth)) {
2319 uint8_t pipeline_depth =
2320 metadata.get<int32_t>(controls::draft::PipelineDepth);
2321 resultMetadata->addEntry(ANDROID_REQUEST_PIPELINE_DEPTH,
2322 &pipeline_depth, 1);
2323 }
2324
Jacopo Mondic9705a52021-01-05 19:30:48 +01002325 if (metadata.contains(controls::ExposureTime)) {
Paul Elder78f49d52021-01-28 17:45:44 +09002326 int64_t exposure = metadata.get(controls::ExposureTime) * 1000ULL;
Jacopo Mondic9705a52021-01-05 19:30:48 +01002327 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
2328 &exposure, 1);
2329 }
2330
Jacopo Mondibb2b4002021-01-04 16:20:05 +01002331 if (metadata.contains(controls::ScalerCrop)) {
2332 Rectangle crop = metadata.get(controls::ScalerCrop);
2333 int32_t cropRect[] = {
2334 crop.x, crop.y, static_cast<int32_t>(crop.width),
2335 static_cast<int32_t>(crop.height),
2336 };
2337 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, cropRect, 4);
2338 }
2339
Laurent Pinchart39860092019-09-05 03:12:34 +03002340 /*
2341 * Return the result metadata pack even is not valid: get() will return
2342 * nullptr.
2343 */
2344 if (!resultMetadata->isValid()) {
2345 LOG(HAL, Error) << "Failed to construct result metadata";
2346 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002347
2348 return resultMetadata;
2349}