blob: a71aee2fc734d21f1d24c96d5704c13473cae6ab [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 Mondiedd4b1d2021-01-04 16:18:29 +010012#include <cmath>
Paul Elder229653a2021-01-21 17:44:14 +090013#include <fstream>
Kieran Bingham83ae84e2020-07-03 12:34:59 +010014#include <sys/mman.h>
Jacopo Mondia80d3812020-05-26 12:31:35 +020015#include <tuple>
Jacopo Mondi117588b2020-05-23 18:53:54 +020016#include <vector>
17
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +020018#include <libcamera/control_ids.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010019#include <libcamera/controls.h>
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030020#include <libcamera/formats.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010021#include <libcamera/property_ids.h>
22
Niklas Söderlund7876d632020-07-21 00:16:24 +020023#include "libcamera/internal/formats.h"
Laurent Pinchart93e72b62020-05-12 00:58:34 +030024#include "libcamera/internal/log.h"
25#include "libcamera/internal/utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020026
Jacopo Mondi117588b2020-05-23 18:53:54 +020027#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020028
29using namespace libcamera;
30
Hirokazu Honda26d90af2020-12-11 09:53:36 +000031LOG_DECLARE_CATEGORY(HAL)
32
Jacopo Mondi117588b2020-05-23 18:53:54 +020033namespace {
34
35/*
36 * \var camera3Resolutions
37 * \brief The list of image resolutions defined as mandatory to be supported by
38 * the Android Camera3 specification
39 */
40const std::vector<Size> camera3Resolutions = {
41 { 320, 240 },
42 { 640, 480 },
43 { 1280, 720 },
44 { 1920, 1080 }
45};
46
47/*
48 * \struct Camera3Format
49 * \brief Data associated with an Android format identifier
50 * \var libcameraFormats List of libcamera pixel formats compatible with the
51 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020052 * \var name The human-readable representation of the Android format code
53 */
54struct Camera3Format {
55 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020056 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020057 const char *name;
58};
59
60/*
61 * \var camera3FormatsMap
62 * \brief Associate Android format code with ancillary data
63 */
64const std::map<int, const Camera3Format> camera3FormatsMap = {
65 {
66 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030067 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020068 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020069 "BLOB"
70 }
71 }, {
72 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030073 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020074 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020075 "YCbCr_420_888"
76 }
77 }, {
78 /*
79 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
80 * usage flag. For now, copy the YCbCr_420 configuration.
81 */
82 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030083 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020084 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020085 "IMPLEMENTATION_DEFINED"
86 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020087 }, {
88 HAL_PIXEL_FORMAT_RAW10, {
89 {
90 formats::SBGGR10_CSI2P,
91 formats::SGBRG10_CSI2P,
92 formats::SGRBG10_CSI2P,
93 formats::SRGGB10_CSI2P
94 },
95 false,
96 "RAW10"
97 }
98 }, {
99 HAL_PIXEL_FORMAT_RAW12, {
100 {
101 formats::SBGGR12_CSI2P,
102 formats::SGBRG12_CSI2P,
103 formats::SGRBG12_CSI2P,
104 formats::SRGGB12_CSI2P
105 },
106 false,
107 "RAW12"
108 }
109 }, {
110 HAL_PIXEL_FORMAT_RAW16, {
111 {
112 formats::SBGGR16,
113 formats::SGBRG16,
114 formats::SGRBG16,
115 formats::SRGGB16
116 },
117 false,
118 "RAW16"
119 }
120 }, {
121 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
122 {
123 formats::SBGGR10_IPU3,
124 formats::SGBRG10_IPU3,
125 formats::SGRBG10_IPU3,
126 formats::SRGGB10_IPU3
127 },
128 false,
129 "RAW_OPAQUE"
130 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200131 },
132};
133
Hirokazu Hondac2df7432020-12-11 09:53:34 +0000134/*
135 * \struct Camera3StreamConfig
136 * \brief Data to store StreamConfiguration associated with camera3_stream(s)
137 * \var streams List of the pairs of a stream requested by Android HAL client
138 * and CameraStream::Type associated with the stream
139 * \var config StreamConfiguration for streams
140 */
141struct Camera3StreamConfig {
142 struct Camera3Stream {
143 camera3_stream_t *stream;
144 CameraStream::Type type;
145 };
146
147 std::vector<Camera3Stream> streams;
148 StreamConfiguration config;
149};
150
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000151/*
152 * Reorder the configurations so that libcamera::Camera can accept them as much
153 * as possible. The sort rule is as follows.
154 * 1.) The configuration for NV12 request whose resolution is the largest.
155 * 2.) The configuration for JPEG request.
156 * 3.) Others. Larger resolutions and different formats are put earlier.
157 */
158void sortCamera3StreamConfigs(std::vector<Camera3StreamConfig> &unsortedConfigs,
159 const camera3_stream_t *jpegStream)
160{
161 const Camera3StreamConfig *jpegConfig = nullptr;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200162
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000163 std::map<PixelFormat, std::vector<const Camera3StreamConfig *>> formatToConfigs;
164 for (const auto &streamConfig : unsortedConfigs) {
165 if (jpegStream && !jpegConfig) {
166 const auto &streams = streamConfig.streams;
167 if (std::find_if(streams.begin(), streams.end(),
168 [jpegStream](const auto &stream) {
169 return stream.stream == jpegStream;
170 }) != streams.end()) {
171 jpegConfig = &streamConfig;
172 continue;
173 }
174 }
175 formatToConfigs[streamConfig.config.pixelFormat].push_back(&streamConfig);
176 }
177
178 if (jpegStream && !jpegConfig)
179 LOG(HAL, Fatal) << "No Camera3StreamConfig is found for JPEG";
180
181 for (auto &fmt : formatToConfigs) {
182 auto &streamConfigs = fmt.second;
183
184 /* Sorted by resolution. Smaller is put first. */
185 std::sort(streamConfigs.begin(), streamConfigs.end(),
186 [](const auto *streamConfigA, const auto *streamConfigB) {
187 const Size &sizeA = streamConfigA->config.size;
188 const Size &sizeB = streamConfigB->config.size;
189 return sizeA < sizeB;
190 });
191 }
192
193 std::vector<Camera3StreamConfig> sortedConfigs;
194 sortedConfigs.reserve(unsortedConfigs.size());
195
196 /*
197 * NV12 is the most prioritized format. Put the configuration with NV12
198 * and the largest resolution first.
199 */
200 const auto nv12It = formatToConfigs.find(formats::NV12);
201 if (nv12It != formatToConfigs.end()) {
202 auto &nv12Configs = nv12It->second;
Laurent Pinchartbd4894d2020-12-12 05:22:31 +0200203 const Camera3StreamConfig *nv12Largest = nv12Configs.back();
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000204
205 /*
206 * If JPEG will be created from NV12 and the size is larger than
207 * the largest NV12 configurations, then put the NV12
208 * configuration for JPEG first.
209 */
210 if (jpegConfig && jpegConfig->config.pixelFormat == formats::NV12) {
211 const Size &nv12SizeForJpeg = jpegConfig->config.size;
212 const Size &nv12LargestSize = nv12Largest->config.size;
213
214 if (nv12LargestSize < nv12SizeForJpeg) {
215 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
216 sortedConfigs.push_back(std::move(*jpegConfig));
217 jpegConfig = nullptr;
218 }
219 }
220
221 LOG(HAL, Debug) << "Insert " << nv12Largest->config.toString();
222 sortedConfigs.push_back(*nv12Largest);
223 nv12Configs.pop_back();
224
225 if (nv12Configs.empty())
226 formatToConfigs.erase(nv12It);
227 }
228
229 /* If the configuration for JPEG is there, then put it. */
230 if (jpegConfig) {
231 LOG(HAL, Debug) << "Insert " << jpegConfig->config.toString();
232 sortedConfigs.push_back(std::move(*jpegConfig));
233 jpegConfig = nullptr;
234 }
235
236 /*
237 * Put configurations with different formats and larger resolutions
238 * earlier.
239 */
240 while (!formatToConfigs.empty()) {
241 for (auto it = formatToConfigs.begin(); it != formatToConfigs.end();) {
242 auto &configs = it->second;
243 LOG(HAL, Debug) << "Insert " << configs.back()->config.toString();
244 sortedConfigs.push_back(*configs.back());
245 configs.pop_back();
246
247 if (configs.empty())
248 it = formatToConfigs.erase(it);
249 else
250 it++;
251 }
252 }
253
254 ASSERT(sortedConfigs.size() == unsortedConfigs.size());
255
256 unsortedConfigs = sortedConfigs;
257}
258
Hirokazu Honda7633a2d2021-04-03 22:37:40 +0900259bool isValidRequest(camera3_capture_request_t *camera3Request)
260{
261 if (!camera3Request) {
262 LOG(HAL, Error) << "No capture request provided";
263 return false;
264 }
265
Hirokazu Honda90a04302021-04-03 22:37:41 +0900266 if (!camera3Request->num_output_buffers ||
267 !camera3Request->output_buffers) {
Hirokazu Honda7633a2d2021-04-03 22:37:40 +0900268 LOG(HAL, Error) << "No output buffers provided";
269 return false;
270 }
271
Hirokazu Honda90a04302021-04-03 22:37:41 +0900272 for (uint32_t i = 0; i < camera3Request->num_output_buffers; i++) {
273 const camera3_stream_buffer_t &outputBuffer =
274 camera3Request->output_buffers[i];
275 if (!outputBuffer.buffer || !(*outputBuffer.buffer)) {
276 LOG(HAL, Error) << "Invalid native handle";
277 return false;
278 }
279
280 const native_handle_t *handle = *outputBuffer.buffer;
281 constexpr int kNativeHandleMaxFds = 1024;
282 if (handle->numFds < 0 || handle->numFds > kNativeHandleMaxFds) {
283 LOG(HAL, Error)
284 << "Invalid number of fds (" << handle->numFds
285 << ") in buffer " << i;
286 return false;
287 }
288
289 constexpr int kNativeHandleMaxInts = 1024;
290 if (handle->numInts < 0 || handle->numInts > kNativeHandleMaxInts) {
291 LOG(HAL, Error)
292 << "Invalid number of ints (" << handle->numInts
293 << ") in buffer " << i;
294 return false;
295 }
296 }
297
Hirokazu Honda7633a2d2021-04-03 22:37:40 +0900298 return true;
299}
300
Hirokazu Hondaac209ef2021-04-03 22:10:14 +0900301const char *rotationToString(int rotation)
302{
303 switch (rotation) {
304 case CAMERA3_STREAM_ROTATION_0:
305 return "0";
306 case CAMERA3_STREAM_ROTATION_90:
307 return "90";
308 case CAMERA3_STREAM_ROTATION_180:
309 return "180";
310 case CAMERA3_STREAM_ROTATION_270:
311 return "270";
312 }
313 return "INVALID";
314}
315
Hirokazu Honda4ae2a752021-04-03 22:10:13 +0900316#if defined(OS_CHROMEOS)
317/*
318 * Check whether the crop_rotate_scale_degrees values for all streams in
319 * the list are valid according to the Chrome OS camera HAL API.
320 */
321bool validateCropRotate(const camera3_stream_configuration_t &streamList)
322{
323 ASSERT(streamList.num_streams > 0);
324 const int cropRotateScaleDegrees =
325 streamList.streams[0]->crop_rotate_scale_degrees;
326 for (unsigned int i = 0; i < streamList.num_streams; ++i) {
327 const camera3_stream_t &stream = *streamList.streams[i];
328
329 switch (stream.crop_rotate_scale_degrees) {
330 case CAMERA3_STREAM_ROTATION_0:
331 case CAMERA3_STREAM_ROTATION_90:
332 case CAMERA3_STREAM_ROTATION_270:
333 break;
334
335 /* 180° rotation is specified by Chrome OS as invalid. */
336 case CAMERA3_STREAM_ROTATION_180:
337 default:
338 LOG(HAL, Error) << "Invalid crop_rotate_scale_degrees: "
339 << stream.crop_rotate_scale_degrees;
340 return false;
341 }
342
343 if (cropRotateScaleDegrees != stream.crop_rotate_scale_degrees) {
344 LOG(HAL, Error) << "crop_rotate_scale_degrees in all "
345 << "streams are not identical";
346 return false;
347 }
348 }
349
350 return true;
351}
352#endif
353
Hirokazu Honda26d90af2020-12-11 09:53:36 +0000354} /* namespace */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200355
356/*
357 * \struct Camera3RequestDescriptor
358 *
359 * A utility structure that groups information about a capture request to be
360 * later re-used at request complete time to notify the framework.
361 */
362
363CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100364 Camera *camera, const camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200365{
Jacopo Mondidd1cd532021-01-21 10:51:05 +0100366 frameNumber_ = camera3Request->frame_number;
367
Jacopo Mondi4b18b822021-01-21 11:10:08 +0100368 /* Copy the camera3 request stream information for later access. */
Hirokazu Honda17a6e782021-03-24 16:07:55 +0900369 const uint32_t numBuffers = camera3Request->num_output_buffers;
370 buffers_.resize(numBuffers);
371 for (uint32_t i = 0; i < numBuffers; i++)
Jacopo Mondi4b18b822021-01-21 11:10:08 +0100372 buffers_[i] = camera3Request->output_buffers[i];
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200373
374 /*
375 * FrameBuffer instances created by wrapping a camera3 provided dmabuf
376 * are emplaced in this vector of unique_ptr<> for lifetime management.
377 */
Hirokazu Honda17a6e782021-03-24 16:07:55 +0900378 frameBuffers_.reserve(numBuffers);
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200379
Jacopo Mondi9e6eece2021-01-21 12:52:10 +0100380 /* Clone the controls associated with the camera3 request. */
381 settings_ = CameraMetadata(camera3Request->settings);
382
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200383 /*
Hirokazu Hondad4043012021-04-03 22:57:34 +0900384 * Create the CaptureRequest, stored as a unique_ptr<> to tie its
385 * lifetime to the descriptor.
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200386 */
Hirokazu Hondad4043012021-04-03 22:57:34 +0900387 request_ = std::make_unique<CaptureRequest>(camera);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200388}
389
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200390/*
391 * \class CameraDevice
392 *
393 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200394 * the camera3_device_t interface, bridging calls received from the Android
395 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200396 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200397 * The class translates parameters and operations from the Camera HALv3 API to
398 * the libcamera API to provide static information for a Camera, create request
399 * templates for it, process capture requests and then deliver capture results
400 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200401 */
402
Hirokazu Honda9538ce42021-03-24 16:07:53 +0900403CameraDevice::CameraDevice(unsigned int id, std::shared_ptr<Camera> camera)
404 : id_(id), running_(false), camera_(std::move(camera)),
Hirokazu Hondadca709c2021-03-24 16:07:56 +0900405 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200406{
407 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
Kieran Bingham83ae84e2020-07-03 12:34:59 +0100408
Paul Elder229653a2021-01-21 17:44:14 +0900409 maker_ = "libcamera";
410 model_ = "cameraModel";
411
412 /* \todo Support getting properties on Android */
413 std::ifstream fstream("/var/cache/camera/camera.prop");
414 if (!fstream.is_open())
415 return;
416
417 std::string line;
418 while (std::getline(fstream, line)) {
419 std::string::size_type delimPos = line.find("=");
420 if (delimPos == std::string::npos)
421 continue;
422 std::string key = line.substr(0, delimPos);
423 std::string val = line.substr(delimPos + 1);
424
425 if (!key.compare("ro.product.model"))
426 model_ = val;
427 else if (!key.compare("ro.product.manufacturer"))
428 maker_ = val;
429 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200430}
431
Hirokazu Hondaf101cc62021-03-24 16:07:57 +0900432CameraDevice::~CameraDevice() = default;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200433
Hirokazu Honda212f4102021-03-24 16:07:50 +0900434std::unique_ptr<CameraDevice> CameraDevice::create(unsigned int id,
Hirokazu Honda9538ce42021-03-24 16:07:53 +0900435 std::shared_ptr<Camera> cam)
Umang Jainf8e28132020-08-21 14:46:08 +0000436{
Hirokazu Honda9538ce42021-03-24 16:07:53 +0900437 return std::unique_ptr<CameraDevice>(
438 new CameraDevice(id, std::move(cam)));
Umang Jainf8e28132020-08-21 14:46:08 +0000439}
440
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200441/*
442 * Initialize the camera static information.
443 * This method is called before the camera device is opened.
444 */
445int CameraDevice::initialize()
446{
447 /* Initialize orientation and facing side of the camera. */
448 const ControlList &properties = camera_->properties();
449
450 if (properties.contains(properties::Location)) {
451 int32_t location = properties.get(properties::Location);
452 switch (location) {
453 case properties::CameraLocationFront:
454 facing_ = CAMERA_FACING_FRONT;
455 break;
456 case properties::CameraLocationBack:
457 facing_ = CAMERA_FACING_BACK;
458 break;
459 case properties::CameraLocationExternal:
Jacopo Mondi5154e142021-03-10 14:00:50 +0100460 facing_ = CAMERA_FACING_EXTERNAL;
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200461 break;
462 }
Jacopo Mondi5154e142021-03-10 14:00:50 +0100463 } else {
464 /*
465 * \todo Retrieve the camera location from configuration file
466 * if not available from the library.
467 */
468 facing_ = CAMERA_FACING_FRONT;
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200469 }
470
471 /*
Umang Jaine9176552020-09-09 16:17:54 +0530472 * The Android orientation metadata specifies its rotation correction
473 * value in clockwise direction whereas libcamera specifies the
474 * rotation property in anticlockwise direction. Read the libcamera's
475 * rotation property (anticlockwise) and compute the corresponding
476 * value for clockwise direction as required by the Android orientation
477 * metadata.
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200478 */
Umang Jaine9176552020-09-09 16:17:54 +0530479 if (properties.contains(properties::Rotation)) {
480 int rotation = properties.get(properties::Rotation);
481 orientation_ = (360 - rotation) % 360;
482 }
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200483
Jacopo Mondi117588b2020-05-23 18:53:54 +0200484 int ret = camera_->acquire();
485 if (ret) {
486 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
487 return ret;
488 }
489
490 ret = initializeStreamConfigurations();
491 camera_->release();
492 return ret;
493}
494
Jacopo Mondibfee6312020-09-01 17:42:13 +0200495std::vector<Size> CameraDevice::getYUVResolutions(CameraConfiguration *cameraConfig,
496 const PixelFormat &pixelFormat,
497 const std::vector<Size> &resolutions)
498{
499 std::vector<Size> supportedResolutions;
500
501 StreamConfiguration &cfg = cameraConfig->at(0);
502 for (const Size &res : resolutions) {
503 cfg.pixelFormat = pixelFormat;
504 cfg.size = res;
505
506 CameraConfiguration::Status status = cameraConfig->validate();
507 if (status != CameraConfiguration::Valid) {
508 LOG(HAL, Debug) << cfg.toString() << " not supported";
509 continue;
510 }
511
512 LOG(HAL, Debug) << cfg.toString() << " supported";
513
514 supportedResolutions.push_back(res);
515 }
516
517 return supportedResolutions;
518}
519
Jacopo Mondi49610332020-09-01 18:11:34 +0200520std::vector<Size> CameraDevice::getRawResolutions(const libcamera::PixelFormat &pixelFormat)
521{
522 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +0200523 camera_->generateConfiguration({ StreamRole::Raw });
Jacopo Mondi49610332020-09-01 18:11:34 +0200524 StreamConfiguration &cfg = cameraConfig->at(0);
525 const StreamFormats &formats = cfg.formats();
526 std::vector<Size> supportedResolutions = formats.sizes(pixelFormat);
527
528 return supportedResolutions;
529}
530
Jacopo Mondi117588b2020-05-23 18:53:54 +0200531/*
532 * Initialize the format conversion map to translate from Android format
533 * identifier to libcamera pixel formats and fill in the list of supported
534 * stream configurations to be reported to the Android camera framework through
535 * the static stream configuration metadata.
536 */
537int CameraDevice::initializeStreamConfigurations()
538{
539 /*
540 * Get the maximum output resolutions
541 * \todo Get this from the camera properties once defined
542 */
543 std::unique_ptr<CameraConfiguration> cameraConfig =
544 camera_->generateConfiguration({ StillCapture });
545 if (!cameraConfig) {
546 LOG(HAL, Error) << "Failed to get maximum resolution";
547 return -EINVAL;
548 }
549 StreamConfiguration &cfg = cameraConfig->at(0);
550
551 /*
552 * \todo JPEG - Adjust the maximum available resolution by taking the
553 * JPEG encoder requirements into account (alignment and aspect ratio).
554 */
555 const Size maxRes = cfg.size;
556 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
557
558 /*
559 * Build the list of supported image resolutions.
560 *
561 * The resolutions listed in camera3Resolution are mandatory to be
562 * supported, up to the camera maximum resolution.
563 *
564 * Augment the list by adding resolutions calculated from the camera
565 * maximum one.
566 */
567 std::vector<Size> cameraResolutions;
568 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
569 std::back_inserter(cameraResolutions),
570 [&](const Size &res) { return res < maxRes; });
571
572 /*
573 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
574 * resolution.
575 */
576 for (unsigned int divider = 2;; divider <<= 1) {
577 Size derivedSize{
578 maxRes.width / divider,
579 maxRes.height / divider,
580 };
581
582 if (derivedSize.width < 320 ||
583 derivedSize.height < 240)
584 break;
585
586 cameraResolutions.push_back(derivedSize);
587 }
588 cameraResolutions.push_back(maxRes);
589
590 /* Remove duplicated entries from the list of supported resolutions. */
591 std::sort(cameraResolutions.begin(), cameraResolutions.end());
592 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
593 cameraResolutions.erase(last, cameraResolutions.end());
594
595 /*
596 * Build the list of supported camera formats.
597 *
598 * To each Android format a list of compatible libcamera formats is
599 * associated. The first libcamera format that tests successful is added
600 * to the format translation map used when configuring the streams.
601 * It is then tested against the list of supported camera resolutions to
602 * build the stream configuration map reported through the camera static
603 * metadata.
604 */
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100605 Size maxJpegSize;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200606 for (const auto &format : camera3FormatsMap) {
607 int androidFormat = format.first;
608 const Camera3Format &camera3Format = format.second;
609 const std::vector<PixelFormat> &libcameraFormats =
610 camera3Format.libcameraFormats;
611
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200612 LOG(HAL, Debug) << "Trying to map Android format "
613 << camera3Format.name;
614
Jacopo Mondi117588b2020-05-23 18:53:54 +0200615 /*
Jacopo Mondi843565c2020-09-01 15:34:13 +0200616 * JPEG is always supported, either produced directly by the
617 * camera, or encoded in the HAL.
618 */
619 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
620 formatsMap_[androidFormat] = formats::MJPEG;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200621 LOG(HAL, Debug) << "Mapped Android format "
622 << camera3Format.name << " to "
623 << formats::MJPEG.toString()
624 << " (fixed mapping)";
Jacopo Mondi843565c2020-09-01 15:34:13 +0200625 continue;
626 }
627
628 /*
Jacopo Mondi117588b2020-05-23 18:53:54 +0200629 * Test the libcamera formats that can produce images
630 * compatible with the format defined by Android.
631 */
632 PixelFormat mappedFormat;
633 for (const PixelFormat &pixelFormat : libcameraFormats) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200634
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200635 LOG(HAL, Debug) << "Testing " << pixelFormat.toString();
636
Jacopo Mondi117588b2020-05-23 18:53:54 +0200637 /*
638 * The stream configuration size can be adjusted,
639 * not the pixel format.
640 *
641 * \todo This could be simplified once all pipeline
642 * handlers will report the StreamFormats list of
643 * supported formats.
644 */
645 cfg.pixelFormat = pixelFormat;
646
647 CameraConfiguration::Status status = cameraConfig->validate();
648 if (status != CameraConfiguration::Invalid &&
649 cfg.pixelFormat == pixelFormat) {
650 mappedFormat = pixelFormat;
651 break;
652 }
653 }
Jacopo Mondi3533fd42020-09-01 15:31:56 +0200654
655 if (!mappedFormat.isValid()) {
656 /* If the format is not mandatory, skip it. */
657 if (!camera3Format.mandatory)
658 continue;
659
660 LOG(HAL, Error)
661 << "Failed to map mandatory Android format "
662 << camera3Format.name << " ("
663 << utils::hex(androidFormat) << "): aborting";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200664 return -EINVAL;
665 }
666
667 /*
668 * Record the mapping and then proceed to generate the
669 * stream configurations map, by testing the image resolutions.
670 */
671 formatsMap_[androidFormat] = mappedFormat;
Jacopo Mondiaf264ec2020-09-01 15:40:49 +0200672 LOG(HAL, Debug) << "Mapped Android format "
673 << camera3Format.name << " to "
674 << mappedFormat.toString();
Jacopo Mondi117588b2020-05-23 18:53:54 +0200675
Jacopo Mondi49610332020-09-01 18:11:34 +0200676 std::vector<Size> resolutions;
677 const PixelFormatInfo &info = PixelFormatInfo::info(mappedFormat);
678 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
679 resolutions = getRawResolutions(mappedFormat);
680 else
681 resolutions = getYUVResolutions(cameraConfig.get(),
682 mappedFormat,
683 cameraResolutions);
684
Jacopo Mondibfee6312020-09-01 17:42:13 +0200685 for (const Size &res : resolutions) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200686 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi843565c2020-09-01 15:34:13 +0200687
688 /*
689 * If the format is HAL_PIXEL_FORMAT_YCbCr_420_888
690 * from which JPEG is produced, add an entry for
691 * the JPEG stream.
692 *
693 * \todo Wire the JPEG encoder to query the supported
694 * sizes provided a list of formats it can encode.
695 *
696 * \todo Support JPEG streams produced by the Camera
697 * natively.
698 */
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100699 if (androidFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
Jacopo Mondi843565c2020-09-01 15:34:13 +0200700 streamConfigurations_.push_back(
701 { res, HAL_PIXEL_FORMAT_BLOB });
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100702 maxJpegSize = std::max(maxJpegSize, res);
703 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200704 }
Jacopo Mondi756fcba2021-01-28 15:26:20 +0100705
706 /*
707 * \todo Calculate the maximum JPEG buffer size by asking the
708 * encoder giving the maximum frame size required.
709 */
710 maxJpegBufferSize_ = maxJpegSize.width * maxJpegSize.height * 1.5;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200711 }
712
713 LOG(HAL, Debug) << "Collected stream configuration map: ";
714 for (const auto &entry : streamConfigurations_)
715 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200716 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200717
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200718 return 0;
719}
720
721/*
722 * Open a camera device. The static information on the camera shall have been
723 * initialized with a call to CameraDevice::initialize().
724 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200725int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200726{
727 int ret = camera_->acquire();
728 if (ret) {
729 LOG(HAL, Error) << "Failed to acquire the camera";
730 return ret;
731 }
732
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200733 /* Initialize the hw_device_t in the instance camera3_module_t. */
734 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
735 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
736 camera3Device_.common.module = (hw_module_t *)hardwareModule;
737 camera3Device_.common.close = hal_dev_close;
738
739 /*
740 * The camera device operations. These actually implement
741 * the Android Camera HALv3 interface.
742 */
743 camera3Device_.ops = &hal_dev_ops;
744 camera3Device_.priv = this;
745
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200746 return 0;
747}
748
749void CameraDevice::close()
750{
Jacopo Mondi6c4999e2020-10-03 16:06:34 +0200751 streams_.clear();
752
Hirokazu Honda0b661d72021-04-02 11:12:37 +0900753 stop();
754
755 camera_->release();
756}
757
758void CameraDevice::stop()
759{
760 if (!running_)
761 return;
762
Jacopo Mondi4b1aa212020-10-06 17:56:50 +0200763 worker_.stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200764 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200765
Hirokazu Hondad4043012021-04-03 22:57:34 +0900766 descriptors_.clear();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200767 running_ = false;
768}
769
770void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
771{
772 callbacks_ = callbacks;
773}
774
Jacopo Mondia80d3812020-05-26 12:31:35 +0200775std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
776{
777 /*
778 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100779 * Currently: 54 entries, 874 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200780 */
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100781 uint32_t numEntries = 54;
782 uint32_t byteSize = 874;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200783
784 /*
785 * Calculate space occupation in bytes for dynamically built metadata
786 * entries.
787 *
Jacopo Mondi00982fb2021-02-04 16:57:55 +0100788 * Each stream configuration entry requires 48 bytes:
Jacopo Mondia80d3812020-05-26 12:31:35 +0200789 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200790 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
791 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200792 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200793
Jacopo Mondi9e807052021-02-04 15:32:00 +0100794 /*
795 * 2 32bits integers for each HAL_PIXEL_FORMAT_BLOB for thumbnail sizes
796 * 2 32bits integers for the (0, 0) thumbnail size
797 *
798 * This is a worst case estimates as different configurations with the
799 * same aspect ratio will generate the same size.
800 */
801 for (const auto &entry : streamConfigurations_) {
802 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
803 continue;
804
805 byteSize += 8;
806 }
807 byteSize += 8;
808
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300809 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200810}
811
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200812/*
813 * Return static information for the camera.
814 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200815const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200816{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200817 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300818 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200819
820 /*
821 * The here reported metadata are enough to implement a basic capture
822 * example application, but a real camera implementation will require
823 * more.
824 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200825 uint32_t numEntries;
826 uint32_t byteSize;
827 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
Hirokazu Hondadca709c2021-03-24 16:07:56 +0900828 staticMetadata_ = std::make_unique<CameraMetadata>(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300829 if (!staticMetadata_->isValid()) {
830 LOG(HAL, Error) << "Failed to allocate static metadata";
Hirokazu Hondadca709c2021-03-24 16:07:56 +0900831 staticMetadata_.reset();
Laurent Pinchart39860092019-09-05 03:12:34 +0300832 return nullptr;
833 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200834
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200835 const ControlInfoMap &controlsInfo = camera_->controls();
Jacopo Mondi1889cdc2020-11-06 16:08:16 +0100836 const ControlList &properties = camera_->properties();
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +0200837
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200838 /* Color correction static metadata. */
Jacopo Mondi63336862020-10-08 16:18:26 +0200839 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +0100840 std::vector<uint8_t> data;
841 data.reserve(3);
Jacopo Mondi63336862020-10-08 16:18:26 +0200842 const auto &infoMap = controlsInfo.find(&controls::draft::ColorCorrectionAberrationMode);
843 if (infoMap != controlsInfo.end()) {
844 for (const auto &value : infoMap->second.values())
845 data.push_back(value.get<int32_t>());
846 } else {
847 data.push_back(ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF);
848 }
849 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
850 data.data(), data.size());
851 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200852
853 /* Control static metadata. */
854 std::vector<uint8_t> aeAvailableAntiBandingModes = {
855 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
856 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
857 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
858 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
859 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300860 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
861 aeAvailableAntiBandingModes.data(),
862 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200863
864 std::vector<uint8_t> aeAvailableModes = {
865 ANDROID_CONTROL_AE_MODE_ON,
866 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300867 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
868 aeAvailableModes.data(),
869 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200870
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +0100871 int64_t minFrameDurationNsec = -1;
872 int64_t maxFrameDurationNsec = -1;
873 const auto frameDurationsInfo = controlsInfo.find(&controls::FrameDurations);
874 if (frameDurationsInfo != controlsInfo.end()) {
875 minFrameDurationNsec = frameDurationsInfo->second.min().get<int64_t>() * 1000;
876 maxFrameDurationNsec = frameDurationsInfo->second.max().get<int64_t>() * 1000;
877
878 /*
879 * Adjust the minimum frame duration to comply with Android
880 * requirements. The camera service mandates all preview/record
881 * streams to have a minimum frame duration < 33,366 milliseconds
882 * (see MAX_PREVIEW_RECORD_DURATION_NS in the camera service
883 * implementation).
884 *
885 * If we're close enough (+ 500 useconds) to that value, round
886 * the minimum frame duration of the camera to an accepted
887 * value.
888 */
889 static constexpr int64_t MAX_PREVIEW_RECORD_DURATION_NS = 1e9 / 29.97;
890 if (minFrameDurationNsec > MAX_PREVIEW_RECORD_DURATION_NS &&
891 minFrameDurationNsec < MAX_PREVIEW_RECORD_DURATION_NS + 500000)
892 minFrameDurationNsec = MAX_PREVIEW_RECORD_DURATION_NS - 1000;
893
894 /*
895 * The AE routine frame rate limits are computed using the frame
896 * duration limits, as libcamera clips the AE routine to the
897 * frame durations.
898 */
899 int32_t maxFps = std::round(1e9 / minFrameDurationNsec);
900 int32_t minFps = std::round(1e9 / maxFrameDurationNsec);
901 minFps = std::max(1, minFps);
902
903 /*
904 * Register to the camera service {min, max} and {max, max}
905 * intervals as requested by the metadata documentation.
906 */
907 int32_t availableAeFpsTarget[] = {
908 minFps, maxFps, maxFps, maxFps
909 };
910 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
911 availableAeFpsTarget, 4);
912 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200913
914 std::vector<int32_t> aeCompensationRange = {
915 0, 0,
916 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300917 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
918 aeCompensationRange.data(),
919 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200920
921 const camera_metadata_rational_t aeCompensationStep[] = {
922 { 0, 1 }
923 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300924 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
925 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200926
927 std::vector<uint8_t> availableAfModes = {
928 ANDROID_CONTROL_AF_MODE_OFF,
929 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300930 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
931 availableAfModes.data(),
932 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200933
934 std::vector<uint8_t> availableEffects = {
935 ANDROID_CONTROL_EFFECT_MODE_OFF,
936 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300937 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
938 availableEffects.data(),
939 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200940
941 std::vector<uint8_t> availableSceneModes = {
942 ANDROID_CONTROL_SCENE_MODE_DISABLED,
943 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300944 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
945 availableSceneModes.data(),
946 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200947
948 std::vector<uint8_t> availableStabilizationModes = {
949 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
950 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300951 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
952 availableStabilizationModes.data(),
953 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200954
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100955 /*
956 * \todo Inspect the Camera capabilities to report the available
957 * AWB modes. Default to AUTO as CTS tests require it.
958 */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200959 std::vector<uint8_t> availableAwbModes = {
Jacopo Mondiaf088b82021-01-04 18:26:28 +0100960 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200961 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300962 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
963 availableAwbModes.data(),
964 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200965
966 std::vector<int32_t> availableMaxRegions = {
967 0, 0, 0,
968 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300969 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
970 availableMaxRegions.data(),
971 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200972
973 std::vector<uint8_t> sceneModesOverride = {
974 ANDROID_CONTROL_AE_MODE_ON,
975 ANDROID_CONTROL_AWB_MODE_AUTO,
Jacopo Mondif266c0e2021-02-03 16:34:40 +0100976 ANDROID_CONTROL_AF_MODE_OFF,
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200977 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300978 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
979 sceneModesOverride.data(),
980 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200981
982 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300983 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
984 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200985
986 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300987 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
988 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200989
990 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300991 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
992 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200993
994 /* JPEG static metadata. */
Jacopo Mondi9e807052021-02-04 15:32:00 +0100995
996 /*
997 * Create the list of supported thumbnail sizes by inspecting the
998 * available JPEG resolutions collected in streamConfigurations_ and
999 * generate one entry for each aspect ratio.
1000 *
1001 * The JPEG thumbnailer can freely scale, so pick an arbitrary
1002 * (160, 160) size as the bounding rectangle, which is then cropped to
1003 * the different supported aspect ratios.
1004 */
1005 constexpr Size maxJpegThumbnail(160, 160);
1006 std::vector<Size> thumbnailSizes;
1007 thumbnailSizes.push_back({ 0, 0 });
1008 for (const auto &entry : streamConfigurations_) {
1009 if (entry.androidFormat != HAL_PIXEL_FORMAT_BLOB)
1010 continue;
1011
1012 Size thumbnailSize = maxJpegThumbnail
1013 .boundedToAspectRatio({ entry.resolution.width,
1014 entry.resolution.height });
1015 thumbnailSizes.push_back(thumbnailSize);
1016 }
1017
1018 std::sort(thumbnailSizes.begin(), thumbnailSizes.end());
1019 auto last = std::unique(thumbnailSizes.begin(), thumbnailSizes.end());
1020 thumbnailSizes.erase(last, thumbnailSizes.end());
1021
1022 /* Transform sizes in to a list of integers that can be consumed. */
1023 std::vector<int32_t> thumbnailEntries;
1024 thumbnailEntries.reserve(thumbnailSizes.size() * 2);
1025 for (const auto &size : thumbnailSizes) {
1026 thumbnailEntries.push_back(size.width);
1027 thumbnailEntries.push_back(size.height);
1028 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001029 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Jacopo Mondi9e807052021-02-04 15:32:00 +01001030 thumbnailEntries.data(), thumbnailEntries.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001031
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001032 staticMetadata_->addEntry(ANDROID_JPEG_MAX_SIZE, &maxJpegBufferSize_, 1);
1033
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001034 /* Sensor static metadata. */
Jacopo Mondicda41ff2020-12-30 17:18:51 +01001035 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +01001036 const Size &size =
Jacopo Mondi0ed05322020-12-23 18:34:34 +01001037 properties.get(properties::PixelArraySize);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +01001038 std::vector<int32_t> data{
1039 static_cast<int32_t>(size.width),
1040 static_cast<int32_t>(size.height),
1041 };
1042 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
1043 data.data(), data.size());
1044 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001045
Jacopo Mondicda41ff2020-12-30 17:18:51 +01001046 {
Jacopo Mondi1889cdc2020-11-06 16:08:16 +01001047 const Span<const Rectangle> &rects =
Jacopo Mondi0ed05322020-12-23 18:34:34 +01001048 properties.get(properties::PixelArrayActiveAreas);
Jacopo Mondi1889cdc2020-11-06 16:08:16 +01001049 std::vector<int32_t> data{
1050 static_cast<int32_t>(rects[0].x),
1051 static_cast<int32_t>(rects[0].y),
1052 static_cast<int32_t>(rects[0].width),
1053 static_cast<int32_t>(rects[0].height),
1054 };
1055 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
1056 data.data(), data.size());
1057 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001058
1059 int32_t sensitivityRange[] = {
1060 32, 2400,
1061 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001062 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
1063 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001064
Jacopo Mondicb35ed22020-12-18 16:28:43 +01001065 /* Report the color filter arrangement if the camera reports it. */
1066 if (properties.contains(properties::draft::ColorFilterArrangement)) {
1067 uint8_t filterArr = properties.get(properties::draft::ColorFilterArrangement);
1068 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
1069 &filterArr, 1);
1070 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001071
Jacopo Mondi753d7532021-01-02 12:34:06 +01001072 const auto &exposureInfo = controlsInfo.find(&controls::ExposureTime);
1073 if (exposureInfo != controlsInfo.end()) {
1074 int64_t exposureTimeRange[2] = {
1075 exposureInfo->second.min().get<int32_t>() * 1000LL,
1076 exposureInfo->second.max().get<int32_t>() * 1000LL,
1077 };
1078 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
1079 &exposureTimeRange, 2);
1080 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001081
Jacopo Mondi64f4f662020-05-25 16:08:22 +02001082 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001083
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001084 std::vector<int32_t> testPatterModes = {
1085 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
1086 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001087 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
1088 testPatterModes.data(),
1089 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001090
1091 std::vector<float> physicalSize = {
1092 2592, 1944,
1093 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001094 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1095 physicalSize.data(),
1096 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001097
1098 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +03001099 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1100 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001101
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001102 if (maxFrameDurationNsec > 0)
1103 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
1104 &maxFrameDurationNsec, 1);
1105
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001106 /* Statistics static metadata. */
1107 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001108 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1109 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001110
1111 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001112 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1113 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001114
Jacopo Mondi2c618502020-10-08 16:47:36 +02001115 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001116 std::vector<uint8_t> data;
1117 data.reserve(2);
Jacopo Mondi2c618502020-10-08 16:47:36 +02001118 const auto &infoMap = controlsInfo.find(&controls::draft::LensShadingMapMode);
1119 if (infoMap != controlsInfo.end()) {
1120 for (const auto &value : infoMap->second.values())
1121 data.push_back(value.get<int32_t>());
1122 } else {
1123 data.push_back(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF);
1124 }
1125 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,
1126 data.data(), data.size());
1127 }
1128
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001129 /* Sync static metadata. */
1130 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +03001131 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001132
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001133 /* Flash static metadata. */
1134 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001135 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
1136 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001137
1138 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001139 std::vector<float> lensApertures = {
1140 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001141 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001142 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
1143 lensApertures.data(),
1144 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001145
Jacopo Mondi64f4f662020-05-25 16:08:22 +02001146 uint8_t lensFacing;
1147 switch (facing_) {
1148 default:
1149 case CAMERA_FACING_FRONT:
1150 lensFacing = ANDROID_LENS_FACING_FRONT;
1151 break;
1152 case CAMERA_FACING_BACK:
1153 lensFacing = ANDROID_LENS_FACING_BACK;
1154 break;
1155 case CAMERA_FACING_EXTERNAL:
1156 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
1157 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +01001158 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001159 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001160
1161 std::vector<float> lensFocalLenghts = {
1162 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001163 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001164 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1165 lensFocalLenghts.data(),
1166 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001167
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001168 std::vector<uint8_t> opticalStabilizations = {
1169 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
1170 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001171 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1172 opticalStabilizations.data(),
1173 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001174
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001175 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001176 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1177 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001178
1179 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +03001180 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1181 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001182
1183 /* Noise reduction modes. */
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001184 {
Jacopo Mondic268e4f2020-12-01 15:42:15 +01001185 std::vector<uint8_t> data;
1186 data.reserve(5);
Jacopo Mondi0b5fecc2020-10-08 16:01:35 +02001187 const auto &infoMap = controlsInfo.find(&controls::draft::NoiseReductionMode);
1188 if (infoMap != controlsInfo.end()) {
1189 for (const auto &value : infoMap->second.values())
1190 data.push_back(value.get<int32_t>());
1191 } else {
1192 data.push_back(ANDROID_NOISE_REDUCTION_MODE_OFF);
1193 }
1194 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
1195 data.data(), data.size());
1196 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001197
1198 /* Scaler static metadata. */
Phi-Bang Nguyen8634c382021-03-29 19:40:46 +02001199
1200 /*
1201 * \todo The digital zoom factor is a property that depends on the
1202 * desired output configuration and the sensor frame size input to the
1203 * ISP. This information is not available to the Android HAL, not at
1204 * initialization time at least.
1205 *
1206 * As a workaround rely on pipeline handlers initializing the
1207 * ScalerCrop control with the camera default configuration and use the
1208 * maximum and minimum crop rectangles to calculate the digital zoom
1209 * factor.
1210 */
1211 float maxZoom = 1.0f;
1212 const auto scalerCrop = controlsInfo.find(&controls::ScalerCrop);
1213 if (scalerCrop != controlsInfo.end()) {
1214 Rectangle min = scalerCrop->second.min().get<Rectangle>();
1215 Rectangle max = scalerCrop->second.max().get<Rectangle>();
1216 maxZoom = std::min(1.0f * max.width / min.width,
1217 1.0f * max.height / min.height);
Jacopo Mondi31a1a622021-01-03 19:57:36 +01001218 }
Phi-Bang Nguyen8634c382021-03-29 19:40:46 +02001219 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1220 &maxZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001221
Jacopo Mondibde7b982020-05-25 17:18:28 +02001222 std::vector<uint32_t> availableStreamConfigurations;
1223 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
1224 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +02001225 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +02001226 availableStreamConfigurations.push_back(entry.resolution.width);
1227 availableStreamConfigurations.push_back(entry.resolution.height);
1228 availableStreamConfigurations.push_back(
1229 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
1230 }
Laurent Pinchart39860092019-09-05 03:12:34 +03001231 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1232 availableStreamConfigurations.data(),
1233 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001234
1235 std::vector<int64_t> availableStallDurations = {
1236 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
1237 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001238 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1239 availableStallDurations.data(),
1240 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001241
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001242 /* Use the minimum frame duration for all the YUV/RGB formats. */
1243 if (minFrameDurationNsec > 0) {
1244 std::vector<int64_t> minFrameDurations;
1245 minFrameDurations.reserve(streamConfigurations_.size() * 4);
1246 for (const auto &entry : streamConfigurations_) {
1247 minFrameDurations.push_back(entry.androidFormat);
1248 minFrameDurations.push_back(entry.resolution.width);
1249 minFrameDurations.push_back(entry.resolution.height);
1250 minFrameDurations.push_back(minFrameDurationNsec);
1251 }
1252 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1253 minFrameDurations.data(),
1254 minFrameDurations.size());
Jacopo Mondibde7b982020-05-25 17:18:28 +02001255 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001256
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001257 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001258 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001259
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001260 /* Info static metadata. */
1261 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001262 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
1263 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001264
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001265 /* Request static metadata. */
1266 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001267 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1268 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001269
Jacopo Mondi5d91c8d2020-09-23 09:41:52 +02001270 {
1271 /* Default the value to 2 if not reported by the camera. */
1272 uint8_t maxPipelineDepth = 2;
1273 const auto &infoMap = controlsInfo.find(&controls::draft::PipelineDepth);
1274 if (infoMap != controlsInfo.end())
1275 maxPipelineDepth = infoMap->second.max().get<int32_t>();
1276 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
1277 &maxPipelineDepth, 1);
1278 }
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001279
Niklas Söderlunda2a6f952020-07-21 00:16:02 +02001280 /* LIMITED does not support reprocessing. */
1281 uint32_t maxNumInputStreams = 0;
1282 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1283 &maxNumInputStreams, 1);
1284
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001285 std::vector<uint8_t> availableCapabilities = {
1286 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
1287 };
Niklas Söderlund7876d632020-07-21 00:16:24 +02001288
1289 /* Report if camera supports RAW. */
Jacopo Mondieec6c542020-12-09 18:16:11 +01001290 bool rawStreamAvailable = false;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001291 std::unique_ptr<CameraConfiguration> cameraConfig =
Niklas Söderlunddbe8d272020-05-26 15:04:47 +02001292 camera_->generateConfiguration({ StreamRole::Raw });
Niklas Söderlund7876d632020-07-21 00:16:24 +02001293 if (cameraConfig && !cameraConfig->empty()) {
1294 const PixelFormatInfo &info =
1295 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
Niklas Söderlund35de31e2020-12-31 00:11:59 +01001296 /* Only advertise RAW support if RAW16 is possible. */
1297 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW &&
1298 info.bitsPerPixel == 16) {
Jacopo Mondieec6c542020-12-09 18:16:11 +01001299 rawStreamAvailable = true;
Niklas Söderlund7876d632020-07-21 00:16:24 +02001300 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
Jacopo Mondieec6c542020-12-09 18:16:11 +01001301 }
Niklas Söderlund7876d632020-07-21 00:16:24 +02001302 }
1303
Jacopo Mondieec6c542020-12-09 18:16:11 +01001304 /* Number of { RAW, YUV, JPEG } supported output streams */
1305 int32_t numOutStreams[] = { rawStreamAvailable, 2, 1 };
1306 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
1307 &numOutStreams, 3);
1308
Laurent Pinchart39860092019-09-05 03:12:34 +03001309 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1310 availableCapabilities.data(),
1311 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +02001312
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001313 std::vector<int32_t> availableCharacteristicsKeys = {
1314 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
1315 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
1316 ANDROID_CONTROL_AE_AVAILABLE_MODES,
1317 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1318 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
1319 ANDROID_CONTROL_AE_COMPENSATION_STEP,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001320 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001321 ANDROID_CONTROL_AF_AVAILABLE_MODES,
1322 ANDROID_CONTROL_AVAILABLE_EFFECTS,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001323 ANDROID_CONTROL_AVAILABLE_MODES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001324 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
1325 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
1326 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001327 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001328 ANDROID_CONTROL_MAX_REGIONS,
1329 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001330 ANDROID_FLASH_INFO_AVAILABLE,
1331 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001332 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001333 ANDROID_JPEG_MAX_SIZE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001334 ANDROID_LENS_FACING,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001335 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001336 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
1337 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
1338 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
1339 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
1340 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001341 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
1342 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
1343 ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001344 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
1345 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001346 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
1347 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
1348 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
1349 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
1350 ANDROID_SCALER_CROPPING_TYPE,
1351 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
1352 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
1353 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
1354 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
Jacopo Mondiedd4b1d2021-01-04 16:18:29 +01001355 ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001356 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
1357 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
1358 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
1359 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
1360 ANDROID_SENSOR_ORIENTATION,
1361 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
1362 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
1363 ANDROID_SYNC_MAX_LATENCY,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001364 };
1365 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
1366 availableCharacteristicsKeys.data(),
1367 availableCharacteristicsKeys.size());
1368
1369 std::vector<int32_t> availableRequestKeys = {
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001370 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1371 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001372 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001373 ANDROID_CONTROL_AE_LOCK,
1374 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001375 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001376 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001377 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001378 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001379 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001380 ANDROID_CONTROL_AWB_MODE,
1381 ANDROID_CONTROL_CAPTURE_INTENT,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001382 ANDROID_CONTROL_EFFECT_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001383 ANDROID_CONTROL_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001384 ANDROID_CONTROL_SCENE_MODE,
1385 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001386 ANDROID_FLASH_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001387 ANDROID_JPEG_ORIENTATION,
1388 ANDROID_JPEG_QUALITY,
1389 ANDROID_JPEG_THUMBNAIL_QUALITY,
1390 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001391 ANDROID_LENS_APERTURE,
1392 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001393 ANDROID_NOISE_REDUCTION_MODE,
Jacopo Mondida4b3252021-01-29 14:21:56 +01001394 ANDROID_SCALER_CROP_REGION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001395 ANDROID_STATISTICS_FACE_DETECT_MODE
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001396 };
1397 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
1398 availableRequestKeys.data(),
1399 availableRequestKeys.size());
1400
1401 std::vector<int32_t> availableResultKeys = {
Jacopo Mondi520c3662021-02-03 14:44:34 +01001402 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001403 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondie9c28752021-02-03 14:47:45 +01001404 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001405 ANDROID_CONTROL_AE_LOCK,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001406 ANDROID_CONTROL_AE_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001407 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1408 ANDROID_CONTROL_AE_STATE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001409 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001410 ANDROID_CONTROL_AF_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001411 ANDROID_CONTROL_AF_STATE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001412 ANDROID_CONTROL_AF_TRIGGER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001413 ANDROID_CONTROL_AWB_LOCK,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001414 ANDROID_CONTROL_AWB_MODE,
Jacopo Mondi3e979d72021-01-04 16:28:24 +01001415 ANDROID_CONTROL_AWB_STATE,
1416 ANDROID_CONTROL_CAPTURE_INTENT,
1417 ANDROID_CONTROL_EFFECT_MODE,
1418 ANDROID_CONTROL_MODE,
1419 ANDROID_CONTROL_SCENE_MODE,
1420 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
1421 ANDROID_FLASH_MODE,
1422 ANDROID_FLASH_STATE,
Paul Elderabfabdd2021-01-23 13:54:28 +09001423 ANDROID_JPEG_GPS_COORDINATES,
1424 ANDROID_JPEG_GPS_PROCESSING_METHOD,
1425 ANDROID_JPEG_GPS_TIMESTAMP,
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001426 ANDROID_JPEG_ORIENTATION,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001427 ANDROID_JPEG_QUALITY,
1428 ANDROID_JPEG_SIZE,
Paul Elder12646282021-01-23 13:56:01 +09001429 ANDROID_JPEG_THUMBNAIL_QUALITY,
1430 ANDROID_JPEG_THUMBNAIL_SIZE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001431 ANDROID_LENS_APERTURE,
1432 ANDROID_LENS_FOCAL_LENGTH,
1433 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1434 ANDROID_LENS_STATE,
1435 ANDROID_NOISE_REDUCTION_MODE,
1436 ANDROID_REQUEST_PIPELINE_DEPTH,
1437 ANDROID_SCALER_CROP_REGION,
1438 ANDROID_SENSOR_EXPOSURE_TIME,
1439 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
Jacopo Mondi5360d802021-02-03 16:43:22 +01001440 ANDROID_SENSOR_TEST_PATTERN_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001441 ANDROID_SENSOR_TIMESTAMP,
1442 ANDROID_STATISTICS_FACE_DETECT_MODE,
1443 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
Jacopo Mondif29601e2021-02-03 16:47:30 +01001444 ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
Jacopo Mondi6741ab82021-01-29 14:15:17 +01001445 ANDROID_STATISTICS_SCENE_FLICKER,
Jacopo Mondi19f85f42019-09-04 16:18:25 +02001446 };
1447 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
1448 availableResultKeys.data(),
1449 availableResultKeys.size());
1450
Laurent Pinchart39860092019-09-05 03:12:34 +03001451 if (!staticMetadata_->isValid()) {
1452 LOG(HAL, Error) << "Failed to construct static metadata";
Hirokazu Hondadca709c2021-03-24 16:07:56 +09001453 staticMetadata_.reset();
Laurent Pinchart39860092019-09-05 03:12:34 +03001454 return nullptr;
1455 }
1456
1457 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001458}
1459
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001460std::unique_ptr<CameraMetadata> CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001461{
Jacopo Mondi63703472019-09-04 16:18:22 +02001462 /*
1463 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001464 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +02001465 */
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001466 auto requestTemplate = std::make_unique<CameraMetadata>(21, 36);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001467 if (!requestTemplate->isValid()) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001468 return nullptr;
1469 }
1470
Jacopo Mondif1796162021-03-08 17:03:14 +01001471 /* Get the FPS range registered in the static metadata. */
1472 camera_metadata_ro_entry_t entry;
1473 bool found = staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1474 &entry);
1475 if (!found) {
1476 LOG(HAL, Error) << "Cannot create capture template without FPS range";
1477 return nullptr;
1478 }
1479
1480 /*
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001481 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
Jacopo Mondif1796162021-03-08 17:03:14 +01001482 * has been assembled as {{min, max} {max, max}}.
1483 */
1484 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1485 entry.data.i32, 2);
1486
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001487 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001488 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
1489 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001490
1491 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001492 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
1493 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001494
1495 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001496 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1497 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001498
1499 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001500 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
1501 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001502
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001503 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
1504 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
1505 &aeAntibandingMode, 1);
1506
Jacopo Mondi9690d082021-02-03 16:37:20 +01001507 uint8_t afMode = ANDROID_CONTROL_AF_MODE_OFF;
1508 requestTemplate->addEntry(ANDROID_CONTROL_AF_MODE, &afMode, 1);
1509
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001510 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001511 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
1512 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001513
1514 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001515 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
1516 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001517
1518 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001519 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
1520 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001521
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001522 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001523 requestTemplate->addEntry(ANDROID_FLASH_MODE,
1524 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001525
1526 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001527 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
1528 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001529
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001530 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001531 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
1532 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001533
1534 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001535 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
1536 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +02001537
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +02001538 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
1539 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
1540
1541 float lensAperture = 2.53 / 100;
1542 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
1543
1544 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
1545 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
1546 &opticalStabilization, 1);
1547
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001548 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001549 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1550 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001551
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001552 return requestTemplate;
1553}
1554
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001555std::unique_ptr<CameraMetadata> CameraDevice::requestTemplateVideo()
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001556{
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001557 std::unique_ptr<CameraMetadata> previewTemplate = requestTemplatePreview();
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001558 if (!previewTemplate)
1559 return nullptr;
1560
1561 /*
1562 * The video template requires a fixed FPS range. Everything else
1563 * stays the same as the preview template.
1564 */
1565 camera_metadata_ro_entry_t entry;
1566 staticMetadata_->getEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
1567 &entry);
1568
1569 /*
1570 * Assume the AE_AVAILABLE_TARGET_FPS_RANGE static metadata
1571 * has been assembled as {{min, max} {max, max}}.
1572 */
1573 previewTemplate->updateEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1574 entry.data.i32 + 2, 2);
1575
1576 return previewTemplate;
1577}
1578
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001579/*
1580 * Produce a metadata pack to be used as template for a capture request.
1581 */
1582const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
1583{
1584 auto it = requestTemplates_.find(type);
1585 if (it != requestTemplates_.end())
1586 return it->second->get();
1587
1588 /* Use the capture intent matching the requested template type. */
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001589 std::unique_ptr<CameraMetadata> requestTemplate;
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001590 uint8_t captureIntent;
1591 switch (type) {
1592 case CAMERA3_TEMPLATE_PREVIEW:
1593 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001594 requestTemplate = requestTemplatePreview();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001595 break;
1596 case CAMERA3_TEMPLATE_STILL_CAPTURE:
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001597 /*
1598 * Use the preview template for still capture, they only differ
1599 * for the torch mode we currently do not support.
1600 */
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001601 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001602 requestTemplate = requestTemplatePreview();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001603 break;
1604 case CAMERA3_TEMPLATE_VIDEO_RECORD:
1605 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001606 requestTemplate = requestTemplateVideo();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001607 break;
1608 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
1609 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
Jacopo Mondieb5a9d82021-03-08 17:00:39 +01001610 requestTemplate = requestTemplateVideo();
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001611 break;
Jacopo Mondi2c349912021-03-08 16:13:58 +01001612 /* \todo Implement templates generation for the remaining use cases. */
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001613 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001614 case CAMERA3_TEMPLATE_MANUAL:
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001615 default:
Jacopo Mondi2c349912021-03-08 16:13:58 +01001616 LOG(HAL, Error) << "Unsupported template request type: " << type;
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001617 return nullptr;
1618 }
1619
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001620 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001621 LOG(HAL, Error) << "Failed to construct request template";
Laurent Pinchart39860092019-09-05 03:12:34 +03001622 return nullptr;
1623 }
1624
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001625 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1626 &captureIntent, 1);
1627
Hirokazu Hondaf101cc62021-03-24 16:07:57 +09001628 requestTemplates_[type] = std::move(requestTemplate);
1629 return requestTemplates_[type]->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001630}
1631
Hirokazu Hondac1ae9052020-10-28 18:50:23 +09001632PixelFormat CameraDevice::toPixelFormat(int format) const
Kieran Bingham43e3b802020-06-26 09:58:49 +01001633{
1634 /* Translate Android format code to libcamera pixel format. */
1635 auto it = formatsMap_.find(format);
1636 if (it == formatsMap_.end()) {
1637 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1638 << " not supported";
1639 return PixelFormat();
1640 }
1641
1642 return it->second;
1643}
1644
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001645/*
1646 * Inspect the stream_list to produce a list of StreamConfiguration to
1647 * be use to configure the Camera.
1648 */
1649int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1650{
Hirokazu Honda0b661d72021-04-02 11:12:37 +09001651 /* Before any configuration attempt, stop the camera. */
1652 stop();
Jacopo Mondi8fed6132020-12-04 15:26:47 +01001653
Hirokazu Hondad13462f2021-04-03 22:18:28 +09001654 if (stream_list->num_streams == 0) {
1655 LOG(HAL, Error) << "No streams in configuration";
1656 return -EINVAL;
1657 }
1658
Hirokazu Honda4ae2a752021-04-03 22:10:13 +09001659#if defined(OS_CHROMEOS)
1660 if (!validateCropRotate(*stream_list))
1661 return -EINVAL;
1662#endif
1663
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001664 /*
1665 * Generate an empty configuration, and construct a StreamConfiguration
1666 * for each camera3_stream to add to it.
1667 */
1668 config_ = camera_->generateConfiguration();
1669 if (!config_) {
1670 LOG(HAL, Error) << "Failed to generate camera configuration";
1671 return -EINVAL;
1672 }
1673
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001674 /*
1675 * Clear and remove any existing configuration from previous calls, and
1676 * ensure the required entries are available without further
Jacopo Mondi9ac8f3e2020-09-04 15:25:55 +02001677 * reallocation.
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001678 */
1679 streams_.clear();
1680 streams_.reserve(stream_list->num_streams);
1681
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001682 std::vector<Camera3StreamConfig> streamConfigs;
1683 streamConfigs.reserve(stream_list->num_streams);
1684
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001685 /* First handle all non-MJPEG streams. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001686 camera3_stream_t *jpegStream = nullptr;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001687 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1688 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001689 Size size(stream->width, stream->height);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001690
Kieran Bingham43e3b802020-06-26 09:58:49 +01001691 PixelFormat format = toPixelFormat(stream->format);
1692
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001693 LOG(HAL, Info) << "Stream #" << i
1694 << ", direction: " << stream->stream_type
1695 << ", width: " << stream->width
1696 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001697 << ", format: " << utils::hex(stream->format)
Hirokazu Hondaac209ef2021-04-03 22:10:14 +09001698 << ", rotation: " << rotationToString(stream->rotation)
1699#if defined(OS_CHROMEOS)
1700 << ", crop_rotate_scale_degrees: "
1701 << rotationToString(stream->crop_rotate_scale_degrees)
1702#endif
Kieran Bingham43e3b802020-06-26 09:58:49 +01001703 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001704
1705 if (!format.isValid())
1706 return -EINVAL;
1707
Hirokazu Hondac85b6c82021-04-03 22:10:15 +09001708 /* \todo Support rotation. */
1709 if (stream->rotation != CAMERA3_STREAM_ROTATION_0) {
1710 LOG(HAL, Error) << "Rotation is not supported";
1711 return -EINVAL;
1712 }
1713#if defined(OS_CHROMEOS)
1714 if (stream->crop_rotate_scale_degrees != CAMERA3_STREAM_ROTATION_0) {
1715 LOG(HAL, Error) << "Rotation is not supported";
1716 return -EINVAL;
1717 }
1718#endif
1719
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001720 /* Defer handling of MJPEG streams until all others are known. */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001721 if (stream->format == HAL_PIXEL_FORMAT_BLOB) {
1722 if (jpegStream) {
1723 LOG(HAL, Error)
1724 << "Multiple JPEG streams are not supported";
1725 return -EINVAL;
1726 }
1727
1728 jpegStream = stream;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001729 continue;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001730 }
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001731
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001732 Camera3StreamConfig streamConfig;
1733 streamConfig.streams = { { stream, CameraStream::Type::Direct } };
1734 streamConfig.config.size = size;
1735 streamConfig.config.pixelFormat = format;
1736 streamConfigs.push_back(std::move(streamConfig));
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001737
1738 /* This stream will be produced by hardware. */
1739 stream->usage |= GRALLOC_USAGE_HW_CAMERA_WRITE;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001740 }
1741
Jacopo Mondic82f9442020-09-02 11:58:00 +02001742 /* Now handle the MJPEG streams, adding a new stream if required. */
1743 if (jpegStream) {
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001744 CameraStream::Type type;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001745 int index = -1;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001746
Jacopo Mondic82f9442020-09-02 11:58:00 +02001747 /* Search for a compatible stream in the non-JPEG ones. */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001748 for (size_t i = 0; i < streamConfigs.size(); ++i) {
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001749 Camera3StreamConfig &streamConfig = streamConfigs[i];
1750 const auto &cfg = streamConfig.config;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001751
1752 /*
1753 * \todo The PixelFormat must also be compatible with
1754 * the encoder.
1755 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001756 if (cfg.size.width != jpegStream->width ||
1757 cfg.size.height != jpegStream->height)
1758 continue;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001759
Jacopo Mondic82f9442020-09-02 11:58:00 +02001760 LOG(HAL, Info)
1761 << "Android JPEG stream mapped to libcamera stream " << i;
1762
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001763 type = CameraStream::Type::Mapped;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001764 index = i;
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001765
1766 /*
1767 * The source stream will be read by software to
1768 * produce the JPEG stream.
1769 */
1770 camera3_stream_t *stream = streamConfig.streams[0].stream;
1771 stream->usage |= GRALLOC_USAGE_SW_READ_OFTEN;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001772 break;
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001773 }
1774
1775 /*
1776 * Without a compatible match for JPEG encoding we must
1777 * introduce a new stream to satisfy the request requirements.
1778 */
Jacopo Mondic82f9442020-09-02 11:58:00 +02001779 if (index < 0) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001780 /*
1781 * \todo The pixelFormat should be a 'best-fit' choice
1782 * and may require a validation cycle. This is not yet
1783 * handled, and should be considered as part of any
1784 * stream configuration reworks.
1785 */
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001786 Camera3StreamConfig streamConfig;
1787 streamConfig.config.size.width = jpegStream->width;
1788 streamConfig.config.size.height = jpegStream->height;
1789 streamConfig.config.pixelFormat = formats::NV12;
1790 streamConfigs.push_back(std::move(streamConfig));
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001791
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001792 LOG(HAL, Info) << "Adding " << streamConfig.config.toString()
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001793 << " for MJPEG support";
1794
Jacopo Mondi94c4d492020-09-04 16:06:11 +02001795 type = CameraStream::Type::Internal;
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001796 index = streamConfigs.size() - 1;
Jacopo Mondic82f9442020-09-02 11:58:00 +02001797 }
1798
Laurent Pinchartde1b9942021-03-05 13:53:53 +02001799 /* The JPEG stream will be produced by software. */
1800 jpegStream->usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
1801
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001802 streamConfigs[index].streams.push_back({ jpegStream, type });
1803 }
1804
Hirokazu Honda26d90af2020-12-11 09:53:36 +00001805 sortCamera3StreamConfigs(streamConfigs, jpegStream);
Hirokazu Honda2bc6ba22020-12-11 09:53:35 +00001806 for (const auto &streamConfig : streamConfigs) {
1807 config_->addConfiguration(streamConfig.config);
1808
1809 for (auto &stream : streamConfig.streams) {
1810 streams_.emplace_back(this, stream.type, stream.stream,
1811 config_->size() - 1);
1812 stream.stream->priv = static_cast<void *>(&streams_.back());
1813 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001814 }
1815
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001816 switch (config_->validate()) {
1817 case CameraConfiguration::Valid:
1818 break;
1819 case CameraConfiguration::Adjusted:
1820 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001821
1822 for (const StreamConfiguration &cfg : *config_)
1823 LOG(HAL, Info) << " - " << cfg.toString();
1824
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001825 config_.reset();
1826 return -EINVAL;
1827 case CameraConfiguration::Invalid:
1828 LOG(HAL, Info) << "Camera configuration invalid";
1829 config_.reset();
1830 return -EINVAL;
1831 }
1832
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001833 /*
Jacopo Mondib84e35d2020-10-03 13:21:50 +02001834 * Once the CameraConfiguration has been adjusted/validated
1835 * it can be applied to the camera.
1836 */
1837 int ret = camera_->configure(config_.get());
1838 if (ret) {
1839 LOG(HAL, Error) << "Failed to configure camera '"
1840 << camera_->id() << "'";
1841 return ret;
1842 }
1843
1844 /*
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001845 * Configure the HAL CameraStream instances using the associated
1846 * StreamConfiguration and set the number of required buffers in
1847 * the Android camera3_stream_t.
1848 */
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001849 for (CameraStream &cameraStream : streams_) {
Kieran Binghamc7bcae02020-10-13 15:58:26 +01001850 ret = cameraStream.configure();
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001851 if (ret) {
1852 LOG(HAL, Error) << "Failed to configure camera stream";
Jacopo Mondi3c84d882020-10-02 19:40:42 +02001853 return ret;
Jacopo Mondi6c8837d2020-10-03 13:45:29 +02001854 }
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001855 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001856
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001857 return 0;
1858}
1859
Kieran Bingham74ab4422020-07-01 13:25:38 +01001860FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1861{
1862 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001863 for (int i = 0; i < camera3buffer->numFds; i++) {
1864 /* Skip unused planes. */
1865 if (camera3buffer->data[i] == -1)
1866 break;
1867
Kieran Bingham74ab4422020-07-01 13:25:38 +01001868 FrameBuffer::Plane plane;
1869 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001870 if (!plane.fd.isValid()) {
1871 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1872 << camera3buffer->data[i] << ") "
1873 << " on plane " << i;
1874 return nullptr;
1875 }
1876
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001877 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1878 if (length == -1) {
1879 LOG(HAL, Error) << "Failed to query plane length";
1880 return nullptr;
1881 }
1882
1883 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001884 planes.push_back(std::move(plane));
1885 }
1886
1887 return new FrameBuffer(std::move(planes));
1888}
1889
Jacopo Mondibb2b4002021-01-04 16:20:05 +01001890int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)
1891{
1892 const CameraMetadata &settings = descriptor->settings_;
1893 if (!settings.isValid())
1894 return 0;
1895
1896 /* Translate the Android request settings to libcamera controls. */
1897 camera_metadata_ro_entry_t entry;
1898 if (settings.getEntry(ANDROID_SCALER_CROP_REGION, &entry)) {
1899 const int32_t *data = entry.data.i32;
1900 Rectangle cropRegion{ data[0], data[1],
1901 static_cast<unsigned int>(data[2]),
1902 static_cast<unsigned int>(data[3]) };
1903 ControlList &controls = descriptor->request_->controls();
1904 controls.set(controls::ScalerCrop, cropRegion);
1905 }
1906
1907 return 0;
1908}
1909
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001910int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001911{
Hirokazu Honda7633a2d2021-04-03 22:37:40 +09001912 if (!isValidRequest(camera3Request))
Jacopo Mondic5b732b2020-12-01 17:12:19 +01001913 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001914
1915 /* Start the camera if that's the first request we handle. */
1916 if (!running_) {
Jacopo Mondi4b1aa212020-10-06 17:56:50 +02001917 worker_.start();
1918
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001919 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001920 if (ret) {
1921 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001922 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001923 }
1924
1925 running_ = true;
1926 }
1927
1928 /*
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001929 * Save the request descriptors for use at completion time.
1930 * The descriptor and the associated memory reserved here are freed
1931 * at request complete time.
1932 */
Hirokazu Hondad4043012021-04-03 22:57:34 +09001933 Camera3RequestDescriptor descriptor(camera_.get(), camera3Request);
1934
Paul Eldera6de3f02021-01-21 18:59:24 +09001935 /*
1936 * \todo The Android request model is incremental, settings passed in
1937 * previous requests are to be effective until overridden explicitly in
1938 * a new request. Do we need to cache settings incrementally here, or is
1939 * it handled by the Android camera service ?
1940 */
1941 if (camera3Request->settings)
1942 lastSettings_ = camera3Request->settings;
1943 else
Hirokazu Hondad4043012021-04-03 22:57:34 +09001944 descriptor.settings_ = lastSettings_;
Kieran Binghameac05422020-07-01 13:28:16 +01001945
Hirokazu Hondad4043012021-04-03 22:57:34 +09001946 LOG(HAL, Debug) << "Queueing request " << descriptor.request_->cookie()
1947 << " with " << descriptor.buffers_.size() << " streams";
1948 for (unsigned int i = 0; i < descriptor.buffers_.size(); ++i) {
1949 const camera3_stream_buffer_t &camera3Buffer = descriptor.buffers_[i];
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001950 camera3_stream *camera3Stream = camera3Buffer.stream;
Jacopo Mondi4b18b822021-01-21 11:10:08 +01001951 CameraStream *cameraStream = static_cast<CameraStream *>(camera3Stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001952
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001953 std::stringstream ss;
1954 ss << i << " - (" << camera3Stream->width << "x"
1955 << camera3Stream->height << ")"
1956 << "[" << utils::hex(camera3Stream->format) << "] -> "
1957 << "(" << cameraStream->configuration().size.toString() << ")["
1958 << cameraStream->configuration().pixelFormat.toString() << "]";
1959
Jacopo Mondide8304b2020-09-04 17:45:39 +02001960 /*
1961 * Inspect the camera stream type, create buffers opportunely
1962 * and add them to the Request if required.
1963 */
1964 FrameBuffer *buffer = nullptr;
1965 switch (cameraStream->type()) {
1966 case CameraStream::Type::Mapped:
1967 /*
1968 * Mapped streams don't need buffers added to the
1969 * Request.
1970 */
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001971 LOG(HAL, Debug) << ss.str() << " (mapped)";
Kieran Bingham83ae84e2020-07-03 12:34:59 +01001972 continue;
1973
Jacopo Mondide8304b2020-09-04 17:45:39 +02001974 case CameraStream::Type::Direct:
1975 /*
1976 * Create a libcamera buffer using the dmabuf
1977 * descriptors of the camera3Buffer for each stream and
1978 * associate it with the Camera3RequestDescriptor for
1979 * lifetime management only.
1980 */
Hirokazu Honda17a6e782021-03-24 16:07:55 +09001981 buffer = createFrameBuffer(*camera3Buffer.buffer);
Hirokazu Hondad4043012021-04-03 22:57:34 +09001982 descriptor.frameBuffers_.emplace_back(buffer);
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001983 LOG(HAL, Debug) << ss.str() << " (direct)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001984 break;
1985
1986 case CameraStream::Type::Internal:
1987 /*
1988 * Get the frame buffer from the CameraStream internal
1989 * buffer pool.
1990 *
1991 * The buffer has to be returned to the CameraStream
1992 * once it has been processed.
1993 */
1994 buffer = cameraStream->getBuffer();
Jacopo Mondi35f726d2020-09-04 18:32:48 +02001995 LOG(HAL, Debug) << ss.str() << " (internal)";
Jacopo Mondide8304b2020-09-04 17:45:39 +02001996 break;
1997 }
1998
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001999 if (!buffer) {
2000 LOG(HAL, Error) << "Failed to create buffer";
Kieran Bingham0cfdf732020-07-01 13:36:24 +01002001 return -ENOMEM;
2002 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002003
Hirokazu Hondad4043012021-04-03 22:57:34 +09002004 descriptor.request_->addBuffer(cameraStream->stream(), buffer,
Hirokazu Honda17a6e782021-03-24 16:07:55 +09002005 camera3Buffer.acquire_fence);
Kieran Bingham0cfdf732020-07-01 13:36:24 +01002006 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002007
Jacopo Mondibb2b4002021-01-04 16:20:05 +01002008 /*
2009 * Translate controls from Android to libcamera and queue the request
2010 * to the CameraWorker thread.
2011 */
Hirokazu Hondad4043012021-04-03 22:57:34 +09002012 int ret = processControls(&descriptor);
Jacopo Mondibb2b4002021-01-04 16:20:05 +01002013 if (ret)
2014 return ret;
2015
Hirokazu Hondad4043012021-04-03 22:57:34 +09002016 worker_.queueRequest(descriptor.request_.get());
2017
2018 {
2019 std::scoped_lock<std::mutex> lock(mutex_);
2020 descriptors_[descriptor.request_->cookie()] = std::move(descriptor);
2021 }
Paul Elderc7532232020-09-23 19:05:41 +09002022
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02002023 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002024}
2025
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02002026void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002027{
Niklas Söderlunddac8e952020-08-11 00:56:13 +02002028 const Request::BufferMap &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002029 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03002030 std::unique_ptr<CameraMetadata> resultMetadata;
Hirokazu Hondad4043012021-04-03 22:57:34 +09002031
2032 decltype(descriptors_)::node_type node;
2033 {
2034 std::scoped_lock<std::mutex> lock(mutex_);
2035 auto it = descriptors_.find(request->cookie());
2036 if (it == descriptors_.end()) {
2037 LOG(HAL, Fatal)
2038 << "Unknown request: " << request->cookie();
2039 status = CAMERA3_BUFFER_STATUS_ERROR;
2040 return;
2041 }
2042
2043 node = descriptors_.extract(it);
2044 }
2045 Camera3RequestDescriptor &descriptor = node.mapped();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002046
2047 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01002048 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002049 << request->status();
2050 status = CAMERA3_BUFFER_STATUS_ERROR;
2051 }
2052
Jacopo Mondibc644072021-01-28 09:58:06 +01002053 LOG(HAL, Debug) << "Request " << request->cookie() << " completed with "
Hirokazu Hondad4043012021-04-03 22:57:34 +09002054 << descriptor.buffers_.size() << " streams";
Jacopo Mondibc644072021-01-28 09:58:06 +01002055
Kieran Binghamc09aee42020-07-28 14:01:19 +01002056 /*
2057 * \todo The timestamp used for the metadata is currently always taken
2058 * from the first buffer (which may be the first stream) in the Request.
2059 * It might be appropriate to return a 'correct' (as determined by
2060 * pipeline handlers) timestamp in the Request itself.
2061 */
Hirokazu Honda3a777d82020-10-28 17:57:26 +09002062 uint64_t timestamp = buffers.begin()->second->metadata().timestamp;
Hirokazu Hondad4043012021-04-03 22:57:34 +09002063 resultMetadata = getResultMetadata(descriptor, timestamp);
Kieran Binghamc09aee42020-07-28 14:01:19 +01002064
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002065 /* Handle any JPEG compression. */
Hirokazu Hondad4043012021-04-03 22:57:34 +09002066 for (camera3_stream_buffer_t &buffer : descriptor.buffers_) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002067 CameraStream *cameraStream =
Hirokazu Honda17a6e782021-03-24 16:07:55 +09002068 static_cast<CameraStream *>(buffer.stream->priv);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002069
Jacopo Mondi160bb092020-10-02 20:48:35 +02002070 if (cameraStream->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB)
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002071 continue;
2072
Jacopo Mondid5473c92021-02-17 16:21:59 +01002073 FrameBuffer *src = request->findBuffer(cameraStream->stream());
2074 if (!src) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002075 LOG(HAL, Error) << "Failed to find a source stream buffer";
2076 continue;
2077 }
2078
Jacopo Mondia725baf2021-02-24 12:50:40 +01002079 int ret = cameraStream->process(*src,
Hirokazu Honda17a6e782021-03-24 16:07:55 +09002080 *buffer.buffer,
Hirokazu Hondad4043012021-04-03 22:57:34 +09002081 descriptor.settings_,
Jacopo Mondi9e95d5e2020-10-03 11:28:47 +02002082 resultMetadata.get());
2083 if (ret) {
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002084 status = CAMERA3_BUFFER_STATUS_ERROR;
2085 continue;
2086 }
Jacopo Mondide8304b2020-09-04 17:45:39 +02002087
2088 /*
2089 * Return the FrameBuffer to the CameraStream now that we're
2090 * done processing it.
2091 */
2092 if (cameraStream->type() == CameraStream::Type::Internal)
Jacopo Mondid5473c92021-02-17 16:21:59 +01002093 cameraStream->putBuffer(src);
Kieran Bingham83ae84e2020-07-03 12:34:59 +01002094 }
2095
2096 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002097 camera3_capture_result_t captureResult = {};
Hirokazu Hondad4043012021-04-03 22:57:34 +09002098 captureResult.frame_number = descriptor.frameNumber_;
2099 captureResult.num_output_buffers = descriptor.buffers_.size();
2100 for (camera3_stream_buffer_t &buffer : descriptor.buffers_) {
Hirokazu Honda17a6e782021-03-24 16:07:55 +09002101 buffer.acquire_fence = -1;
2102 buffer.release_fence = -1;
2103 buffer.status = status;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002104 }
Hirokazu Hondad4043012021-04-03 22:57:34 +09002105 captureResult.output_buffers = descriptor.buffers_.data();
Kieran Bingham0cfdf732020-07-01 13:36:24 +01002106
Laurent Pinchart39860092019-09-05 03:12:34 +03002107 if (status == CAMERA3_BUFFER_STATUS_OK) {
Hirokazu Hondad4043012021-04-03 22:57:34 +09002108 notifyShutter(descriptor.frameNumber_, timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002109
2110 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03002111 captureResult.result = resultMetadata->get();
2112 }
2113
2114 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
2115 /* \todo Improve error handling. In case we notify an error
2116 * because the metadata generation fails, a shutter event has
2117 * already been notified for this frame number before the error
2118 * is here signalled. Make sure the error path plays well with
2119 * the camera stack state machine.
2120 */
Hirokazu Hondad4043012021-04-03 22:57:34 +09002121 notifyError(descriptor.frameNumber_,
2122 descriptor.buffers_[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002123 }
2124
2125 callbacks_->process_capture_result(callbacks_, &captureResult);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002126}
2127
Jacopo Mondia7b92772020-05-26 15:41:41 +02002128std::string CameraDevice::logPrefix() const
2129{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02002130 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02002131}
2132
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002133void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
2134{
2135 camera3_notify_msg_t notify = {};
2136
2137 notify.type = CAMERA3_MSG_SHUTTER;
2138 notify.message.shutter.frame_number = frameNumber;
2139 notify.message.shutter.timestamp = timestamp;
2140
2141 callbacks_->notify(callbacks_, &notify);
2142}
2143
2144void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
2145{
2146 camera3_notify_msg_t notify = {};
2147
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01002148 /*
2149 * \todo Report and identify the stream number or configuration to
2150 * clarify the stream that failed.
2151 */
2152 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
2153 << toPixelFormat(stream->format).toString() << ")";
2154
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002155 notify.type = CAMERA3_MSG_ERROR;
2156 notify.message.error.error_stream = stream;
2157 notify.message.error.frame_number = frameNumber;
2158 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
2159
2160 callbacks_->notify(callbacks_, &notify);
2161}
2162
2163/*
2164 * Produce a set of fixed result metadata.
2165 */
Laurent Pinchartdbafe162019-10-27 00:36:13 +03002166std::unique_ptr<CameraMetadata>
Hirokazu Honda82b81512021-03-25 20:13:56 +09002167CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor,
2168 int64_t timestamp) const
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002169{
Hirokazu Honda82b81512021-03-25 20:13:56 +09002170 const ControlList &metadata = descriptor.request_->metadata();
2171 const CameraMetadata &settings = descriptor.settings_;
Paul Elder958c80a2021-01-26 09:47:33 +09002172 camera_metadata_ro_entry_t entry;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002173 bool found;
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002174
Jacopo Mondi48504ba2019-09-04 16:18:19 +02002175 /*
2176 * \todo Keep this in sync with the actual number of entries.
Paul Elder12646282021-01-23 13:56:01 +09002177 * Currently: 40 entries, 156 bytes
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002178 *
2179 * Reserve more space for the JPEG metadata set by the post-processor.
Paul Elderabfabdd2021-01-23 13:54:28 +09002180 * Currently:
2181 * ANDROID_JPEG_GPS_COORDINATES (double x 3) = 24 bytes
2182 * ANDROID_JPEG_GPS_PROCESSING_METHOD (byte x 32) = 32 bytes
2183 * ANDROID_JPEG_GPS_TIMESTAMP (int64) = 8 bytes
2184 * ANDROID_JPEG_SIZE (int32_t) = 4 bytes
2185 * ANDROID_JPEG_QUALITY (byte) = 1 byte
2186 * ANDROID_JPEG_ORIENTATION (int32_t) = 4 bytes
Paul Elder12646282021-01-23 13:56:01 +09002187 * ANDROID_JPEG_THUMBNAIL_QUALITY (byte) = 1 byte
2188 * ANDROID_JPEG_THUMBNAIL_SIZE (int32 x 2) = 8 bytes
2189 * Total bytes for JPEG metadata: 82
Jacopo Mondi48504ba2019-09-04 16:18:19 +02002190 */
Laurent Pinchart39860092019-09-05 03:12:34 +03002191 std::unique_ptr<CameraMetadata> resultMetadata =
Jacopo Mondif29601e2021-02-03 16:47:30 +01002192 std::make_unique<CameraMetadata>(44, 166);
Laurent Pinchart39860092019-09-05 03:12:34 +03002193 if (!resultMetadata->isValid()) {
2194 LOG(HAL, Error) << "Failed to allocate static metadata";
2195 return nullptr;
2196 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002197
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002198 /*
2199 * \todo The value of the results metadata copied from the settings
2200 * will have to be passed to the libcamera::Camera and extracted
2201 * from libcamera::Request::metadata.
2202 */
2203
Jacopo Mondi520c3662021-02-03 14:44:34 +01002204 uint8_t value = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
2205 resultMetadata->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
2206 &value, 1);
2207
2208 value = ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF;
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002209 resultMetadata->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002210
Jacopo Mondie9c28752021-02-03 14:47:45 +01002211 int32_t value32 = 0;
2212 resultMetadata->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
2213 &value32, 1);
2214
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002215 value = ANDROID_CONTROL_AE_LOCK_OFF;
2216 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002217
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002218 value = ANDROID_CONTROL_AE_MODE_ON;
2219 resultMetadata->addEntry(ANDROID_CONTROL_AE_MODE, &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002220
Jacopo Mondid1508602021-01-21 18:21:28 +01002221 if (settings.getEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, &entry))
2222 /*
2223 * \todo Retrieve the AE FPS range from the libcamera metadata.
2224 * As libcamera does not support that control, as a temporary
2225 * workaround return what the framework asked.
2226 */
2227 resultMetadata->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
2228 entry.data.i32, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002229
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002230 value = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002231 found = settings.getEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &entry);
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002232 resultMetadata->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002233 found ? entry.data.u8 : &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002234
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002235 value = ANDROID_CONTROL_AE_STATE_CONVERGED;
2236 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &value, 1);
2237
2238 value = ANDROID_CONTROL_AF_MODE_OFF;
2239 resultMetadata->addEntry(ANDROID_CONTROL_AF_MODE, &value, 1);
2240
2241 value = ANDROID_CONTROL_AF_STATE_INACTIVE;
2242 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &value, 1);
2243
2244 value = ANDROID_CONTROL_AF_TRIGGER_IDLE;
2245 resultMetadata->addEntry(ANDROID_CONTROL_AF_TRIGGER, &value, 1);
2246
2247 value = ANDROID_CONTROL_AWB_MODE_AUTO;
2248 resultMetadata->addEntry(ANDROID_CONTROL_AWB_MODE, &value, 1);
2249
2250 value = ANDROID_CONTROL_AWB_LOCK_OFF;
2251 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &value, 1);
2252
2253 value = ANDROID_CONTROL_AWB_STATE_CONVERGED;
2254 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &value, 1);
2255
2256 value = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
2257 resultMetadata->addEntry(ANDROID_CONTROL_CAPTURE_INTENT, &value, 1);
2258
2259 value = ANDROID_CONTROL_EFFECT_MODE_OFF;
2260 resultMetadata->addEntry(ANDROID_CONTROL_EFFECT_MODE, &value, 1);
2261
2262 value = ANDROID_CONTROL_MODE_AUTO;
2263 resultMetadata->addEntry(ANDROID_CONTROL_MODE, &value, 1);
2264
2265 value = ANDROID_CONTROL_SCENE_MODE_DISABLED;
2266 resultMetadata->addEntry(ANDROID_CONTROL_SCENE_MODE, &value, 1);
2267
2268 value = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
2269 resultMetadata->addEntry(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &value, 1);
2270
2271 value = ANDROID_FLASH_MODE_OFF;
2272 resultMetadata->addEntry(ANDROID_FLASH_MODE, &value, 1);
2273
2274 value = ANDROID_FLASH_STATE_UNAVAILABLE;
2275 resultMetadata->addEntry(ANDROID_FLASH_STATE, &value, 1);
2276
Jacopo Mondi94d42ce2021-01-29 14:54:39 +01002277 if (settings.getEntry(ANDROID_LENS_APERTURE, &entry))
Paul Elderabfabdd2021-01-23 13:54:28 +09002278 resultMetadata->addEntry(ANDROID_LENS_APERTURE, entry.data.f, 1);
2279
2280 float focal_length = 1.0;
2281 resultMetadata->addEntry(ANDROID_LENS_FOCAL_LENGTH, &focal_length, 1);
2282
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002283 value = ANDROID_LENS_STATE_STATIONARY;
2284 resultMetadata->addEntry(ANDROID_LENS_STATE, &value, 1);
2285
2286 value = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
2287 resultMetadata->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
2288 &value, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002289
Jacopo Mondi5360d802021-02-03 16:43:22 +01002290 value32 = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
2291 resultMetadata->addEntry(ANDROID_SENSOR_TEST_PATTERN_MODE,
2292 &value32, 1);
2293
Laurent Pinchart39860092019-09-05 03:12:34 +03002294 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002295
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002296 value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
2297 resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
2298 &value, 1);
2299
2300 value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
2301 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
2302 &value, 1);
2303
Jacopo Mondif29601e2021-02-03 16:47:30 +01002304 value = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF;
2305 resultMetadata->addEntry(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
2306 &value, 1);
2307
Jacopo Mondi3e979d72021-01-04 16:28:24 +01002308 value = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
2309 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
2310 &value, 1);
2311
2312 value = ANDROID_NOISE_REDUCTION_MODE_OFF;
2313 resultMetadata->addEntry(ANDROID_NOISE_REDUCTION_MODE, &value, 1);
2314
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002315 /* 33.3 msec */
2316 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03002317 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
2318 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002319
Jacopo Mondi3535e0c2020-12-09 17:51:57 +01002320 /* Add metadata tags reported by libcamera. */
2321 if (metadata.contains(controls::draft::PipelineDepth)) {
2322 uint8_t pipeline_depth =
2323 metadata.get<int32_t>(controls::draft::PipelineDepth);
2324 resultMetadata->addEntry(ANDROID_REQUEST_PIPELINE_DEPTH,
2325 &pipeline_depth, 1);
2326 }
2327
Jacopo Mondic9705a52021-01-05 19:30:48 +01002328 if (metadata.contains(controls::ExposureTime)) {
Paul Elder78f49d52021-01-28 17:45:44 +09002329 int64_t exposure = metadata.get(controls::ExposureTime) * 1000ULL;
Jacopo Mondic9705a52021-01-05 19:30:48 +01002330 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
2331 &exposure, 1);
2332 }
2333
Jacopo Mondibb2b4002021-01-04 16:20:05 +01002334 if (metadata.contains(controls::ScalerCrop)) {
2335 Rectangle crop = metadata.get(controls::ScalerCrop);
2336 int32_t cropRect[] = {
2337 crop.x, crop.y, static_cast<int32_t>(crop.width),
2338 static_cast<int32_t>(crop.height),
2339 };
2340 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, cropRect, 4);
2341 }
2342
Laurent Pinchart39860092019-09-05 03:12:34 +03002343 /*
2344 * Return the result metadata pack even is not valid: get() will return
2345 * nullptr.
2346 */
2347 if (!resultMetadata->isValid()) {
2348 LOG(HAL, Error) << "Failed to construct result metadata";
2349 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02002350
2351 return resultMetadata;
2352}