blob: e78fecf46f8d0148f1fd1db59a49143380dd8a27 [file] [log] [blame]
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2019, Google Inc.
4 *
5 * camera_device.cpp - libcamera Android Camera Device
6 */
7
8#include "camera_device.h"
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02009#include "camera_ops.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020010
Jacopo Mondia80d3812020-05-26 12:31:35 +020011#include <tuple>
Jacopo Mondi117588b2020-05-23 18:53:54 +020012#include <vector>
13
Jacopo Mondi857a2162019-11-20 17:00:49 +010014#include <libcamera/controls.h>
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030015#include <libcamera/formats.h>
Jacopo Mondi857a2162019-11-20 17:00:49 +010016#include <libcamera/property_ids.h>
17
Niklas Söderlund7876d632020-07-21 00:16:24 +020018#include "libcamera/internal/formats.h"
Laurent Pinchart93e72b62020-05-12 00:58:34 +030019#include "libcamera/internal/log.h"
20#include "libcamera/internal/utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020021
Laurent Pinchart39860092019-09-05 03:12:34 +030022#include "camera_metadata.h"
Jacopo Mondi117588b2020-05-23 18:53:54 +020023#include "system/graphics.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020024
25using namespace libcamera;
26
Jacopo Mondi117588b2020-05-23 18:53:54 +020027namespace {
28
29/*
30 * \var camera3Resolutions
31 * \brief The list of image resolutions defined as mandatory to be supported by
32 * the Android Camera3 specification
33 */
34const std::vector<Size> camera3Resolutions = {
35 { 320, 240 },
36 { 640, 480 },
37 { 1280, 720 },
38 { 1920, 1080 }
39};
40
41/*
42 * \struct Camera3Format
43 * \brief Data associated with an Android format identifier
44 * \var libcameraFormats List of libcamera pixel formats compatible with the
45 * Android format
Jacopo Mondi117588b2020-05-23 18:53:54 +020046 * \var name The human-readable representation of the Android format code
47 */
48struct Camera3Format {
49 std::vector<PixelFormat> libcameraFormats;
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020050 bool mandatory;
Jacopo Mondi117588b2020-05-23 18:53:54 +020051 const char *name;
52};
53
54/*
55 * \var camera3FormatsMap
56 * \brief Associate Android format code with ancillary data
57 */
58const std::map<int, const Camera3Format> camera3FormatsMap = {
59 {
60 HAL_PIXEL_FORMAT_BLOB, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030061 { formats::MJPEG },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020062 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020063 "BLOB"
64 }
65 }, {
66 HAL_PIXEL_FORMAT_YCbCr_420_888, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030067 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020068 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020069 "YCbCr_420_888"
70 }
71 }, {
72 /*
73 * \todo Translate IMPLEMENTATION_DEFINED inspecting the gralloc
74 * usage flag. For now, copy the YCbCr_420 configuration.
75 */
76 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +030077 { formats::NV12, formats::NV21 },
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +020078 true,
Jacopo Mondi117588b2020-05-23 18:53:54 +020079 "IMPLEMENTATION_DEFINED"
80 }
Niklas Söderlundd4de0372020-07-21 00:16:14 +020081 }, {
82 HAL_PIXEL_FORMAT_RAW10, {
83 {
84 formats::SBGGR10_CSI2P,
85 formats::SGBRG10_CSI2P,
86 formats::SGRBG10_CSI2P,
87 formats::SRGGB10_CSI2P
88 },
89 false,
90 "RAW10"
91 }
92 }, {
93 HAL_PIXEL_FORMAT_RAW12, {
94 {
95 formats::SBGGR12_CSI2P,
96 formats::SGBRG12_CSI2P,
97 formats::SGRBG12_CSI2P,
98 formats::SRGGB12_CSI2P
99 },
100 false,
101 "RAW12"
102 }
103 }, {
104 HAL_PIXEL_FORMAT_RAW16, {
105 {
106 formats::SBGGR16,
107 formats::SGBRG16,
108 formats::SGRBG16,
109 formats::SRGGB16
110 },
111 false,
112 "RAW16"
113 }
114 }, {
115 HAL_PIXEL_FORMAT_RAW_OPAQUE, {
116 {
117 formats::SBGGR10_IPU3,
118 formats::SGBRG10_IPU3,
119 formats::SGRBG10_IPU3,
120 formats::SRGGB10_IPU3
121 },
122 false,
123 "RAW_OPAQUE"
124 }
Jacopo Mondi117588b2020-05-23 18:53:54 +0200125 },
126};
127
128} /* namespace */
129
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200130LOG_DECLARE_CATEGORY(HAL);
131
132/*
133 * \struct Camera3RequestDescriptor
134 *
135 * A utility structure that groups information about a capture request to be
136 * later re-used at request complete time to notify the framework.
137 */
138
139CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
140 unsigned int frameNumber, unsigned int numBuffers)
141 : frameNumber(frameNumber), numBuffers(numBuffers)
142{
143 buffers = new camera3_stream_buffer_t[numBuffers];
Kieran Bingham0cfdf732020-07-01 13:36:24 +0100144 frameBuffers.reserve(numBuffers);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200145}
146
147CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
148{
149 delete[] buffers;
150}
151
152/*
153 * \class CameraDevice
154 *
155 * The CameraDevice class wraps a libcamera::Camera instance, and implements
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200156 * the camera3_device_t interface, bridging calls received from the Android
157 * camera service to the CameraDevice.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200158 *
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200159 * The class translates parameters and operations from the Camera HALv3 API to
160 * the libcamera API to provide static information for a Camera, create request
161 * templates for it, process capture requests and then deliver capture results
162 * back to the framework using the designated callbacks.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200163 */
164
Laurent Pinchart0ed40d22019-08-18 01:45:01 +0300165CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Umang Jain035ee232020-08-05 12:53:49 +0000166 : id_(id), running_(false), camera_(camera), staticMetadata_(nullptr),
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200167 facing_(CAMERA_FACING_FRONT), orientation_(0)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200168{
169 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
170}
171
172CameraDevice::~CameraDevice()
173{
174 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300175 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200176
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200177 for (auto &it : requestTemplates_)
178 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200179}
180
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200181/*
182 * Initialize the camera static information.
183 * This method is called before the camera device is opened.
184 */
185int CameraDevice::initialize()
186{
187 /* Initialize orientation and facing side of the camera. */
188 const ControlList &properties = camera_->properties();
189
190 if (properties.contains(properties::Location)) {
191 int32_t location = properties.get(properties::Location);
192 switch (location) {
193 case properties::CameraLocationFront:
194 facing_ = CAMERA_FACING_FRONT;
195 break;
196 case properties::CameraLocationBack:
197 facing_ = CAMERA_FACING_BACK;
198 break;
199 case properties::CameraLocationExternal:
200 facing_ = CAMERA_FACING_EXTERNAL;
201 break;
202 }
203 }
204
205 /*
206 * The Android orientation metadata and libcamera rotation property are
207 * defined differently but have identical numerical values for Android
208 * devices such as phones and tablets.
209 */
210 if (properties.contains(properties::Rotation))
211 orientation_ = properties.get(properties::Rotation);
212
Jacopo Mondi117588b2020-05-23 18:53:54 +0200213 int ret = camera_->acquire();
214 if (ret) {
215 LOG(HAL, Error) << "Failed to temporarily acquire the camera";
216 return ret;
217 }
218
219 ret = initializeStreamConfigurations();
220 camera_->release();
221 return ret;
222}
223
224/*
225 * Initialize the format conversion map to translate from Android format
226 * identifier to libcamera pixel formats and fill in the list of supported
227 * stream configurations to be reported to the Android camera framework through
228 * the static stream configuration metadata.
229 */
230int CameraDevice::initializeStreamConfigurations()
231{
232 /*
233 * Get the maximum output resolutions
234 * \todo Get this from the camera properties once defined
235 */
236 std::unique_ptr<CameraConfiguration> cameraConfig =
237 camera_->generateConfiguration({ StillCapture });
238 if (!cameraConfig) {
239 LOG(HAL, Error) << "Failed to get maximum resolution";
240 return -EINVAL;
241 }
242 StreamConfiguration &cfg = cameraConfig->at(0);
243
244 /*
245 * \todo JPEG - Adjust the maximum available resolution by taking the
246 * JPEG encoder requirements into account (alignment and aspect ratio).
247 */
248 const Size maxRes = cfg.size;
249 LOG(HAL, Debug) << "Maximum supported resolution: " << maxRes.toString();
250
251 /*
252 * Build the list of supported image resolutions.
253 *
254 * The resolutions listed in camera3Resolution are mandatory to be
255 * supported, up to the camera maximum resolution.
256 *
257 * Augment the list by adding resolutions calculated from the camera
258 * maximum one.
259 */
260 std::vector<Size> cameraResolutions;
261 std::copy_if(camera3Resolutions.begin(), camera3Resolutions.end(),
262 std::back_inserter(cameraResolutions),
263 [&](const Size &res) { return res < maxRes; });
264
265 /*
266 * The Camera3 specification suggests adding 1/2 and 1/4 of the maximum
267 * resolution.
268 */
269 for (unsigned int divider = 2;; divider <<= 1) {
270 Size derivedSize{
271 maxRes.width / divider,
272 maxRes.height / divider,
273 };
274
275 if (derivedSize.width < 320 ||
276 derivedSize.height < 240)
277 break;
278
279 cameraResolutions.push_back(derivedSize);
280 }
281 cameraResolutions.push_back(maxRes);
282
283 /* Remove duplicated entries from the list of supported resolutions. */
284 std::sort(cameraResolutions.begin(), cameraResolutions.end());
285 auto last = std::unique(cameraResolutions.begin(), cameraResolutions.end());
286 cameraResolutions.erase(last, cameraResolutions.end());
287
288 /*
289 * Build the list of supported camera formats.
290 *
291 * To each Android format a list of compatible libcamera formats is
292 * associated. The first libcamera format that tests successful is added
293 * to the format translation map used when configuring the streams.
294 * It is then tested against the list of supported camera resolutions to
295 * build the stream configuration map reported through the camera static
296 * metadata.
297 */
298 for (const auto &format : camera3FormatsMap) {
299 int androidFormat = format.first;
300 const Camera3Format &camera3Format = format.second;
301 const std::vector<PixelFormat> &libcameraFormats =
302 camera3Format.libcameraFormats;
303
304 /*
305 * Test the libcamera formats that can produce images
306 * compatible with the format defined by Android.
307 */
308 PixelFormat mappedFormat;
309 for (const PixelFormat &pixelFormat : libcameraFormats) {
310 /* \todo Fixed mapping for JPEG. */
311 if (androidFormat == HAL_PIXEL_FORMAT_BLOB) {
Laurent Pinchart8b7e0732020-05-22 04:02:06 +0300312 mappedFormat = formats::MJPEG;
Jacopo Mondi117588b2020-05-23 18:53:54 +0200313 break;
314 }
315
316 /*
317 * The stream configuration size can be adjusted,
318 * not the pixel format.
319 *
320 * \todo This could be simplified once all pipeline
321 * handlers will report the StreamFormats list of
322 * supported formats.
323 */
324 cfg.pixelFormat = pixelFormat;
325
326 CameraConfiguration::Status status = cameraConfig->validate();
327 if (status != CameraConfiguration::Invalid &&
328 cfg.pixelFormat == pixelFormat) {
329 mappedFormat = pixelFormat;
330 break;
331 }
332 }
Niklas Söderlund8c1fedc2020-07-28 19:43:12 +0200333 if (camera3Format.mandatory && !mappedFormat.isValid()) {
Jacopo Mondi117588b2020-05-23 18:53:54 +0200334 LOG(HAL, Error) << "Failed to map Android format "
335 << camera3Format.name << " ("
336 << utils::hex(androidFormat) << ")";
337 return -EINVAL;
338 }
339
340 /*
341 * Record the mapping and then proceed to generate the
342 * stream configurations map, by testing the image resolutions.
343 */
344 formatsMap_[androidFormat] = mappedFormat;
345
346 for (const Size &res : cameraResolutions) {
347 cfg.pixelFormat = mappedFormat;
348 cfg.size = res;
349
350 CameraConfiguration::Status status = cameraConfig->validate();
351 /*
352 * Unconditionally report we can produce JPEG.
353 *
354 * \todo The JPEG stream will be implemented as an
355 * HAL-only stream, but some cameras can produce it
356 * directly. As of now, claim support for JPEG without
357 * inspecting where the JPEG stream is produced.
358 */
359 if (androidFormat != HAL_PIXEL_FORMAT_BLOB &&
360 status != CameraConfiguration::Valid)
361 continue;
362
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200363 streamConfigurations_.push_back({ res, androidFormat });
Jacopo Mondi117588b2020-05-23 18:53:54 +0200364 }
365 }
366
367 LOG(HAL, Debug) << "Collected stream configuration map: ";
368 for (const auto &entry : streamConfigurations_)
369 LOG(HAL, Debug) << "{ " << entry.resolution.toString() << " - "
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200370 << utils::hex(entry.androidFormat) << " }";
Jacopo Mondi117588b2020-05-23 18:53:54 +0200371
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200372 return 0;
373}
374
375/*
376 * Open a camera device. The static information on the camera shall have been
377 * initialized with a call to CameraDevice::initialize().
378 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200379int CameraDevice::open(const hw_module_t *hardwareModule)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200380{
381 int ret = camera_->acquire();
382 if (ret) {
383 LOG(HAL, Error) << "Failed to acquire the camera";
384 return ret;
385 }
386
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200387 /* Initialize the hw_device_t in the instance camera3_module_t. */
388 camera3Device_.common.tag = HARDWARE_DEVICE_TAG;
389 camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3;
390 camera3Device_.common.module = (hw_module_t *)hardwareModule;
391 camera3Device_.common.close = hal_dev_close;
392
393 /*
394 * The camera device operations. These actually implement
395 * the Android Camera HALv3 interface.
396 */
397 camera3Device_.ops = &hal_dev_ops;
398 camera3Device_.priv = this;
399
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200400 return 0;
401}
402
403void CameraDevice::close()
404{
405 camera_->stop();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200406 camera_->release();
407
408 running_ = false;
409}
410
411void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
412{
413 callbacks_ = callbacks;
414}
415
Jacopo Mondia80d3812020-05-26 12:31:35 +0200416std::tuple<uint32_t, uint32_t> CameraDevice::calculateStaticMetadataSize()
417{
418 /*
419 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200420 * Currently: 50 entries, 671 bytes of static metadata
Jacopo Mondia80d3812020-05-26 12:31:35 +0200421 */
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200422 uint32_t numEntries = 50;
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200423 uint32_t byteSize = 671;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200424
425 /*
426 * Calculate space occupation in bytes for dynamically built metadata
427 * entries.
428 *
429 * Each stream configuration entry requires 52 bytes:
430 * 4 32bits integers for ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
Jacopo Mondia80d3812020-05-26 12:31:35 +0200431 * 4 64bits integers for ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS
432 */
Niklas Söderlund35306142020-07-23 18:25:04 +0200433 byteSize += streamConfigurations_.size() * 48;
Jacopo Mondia80d3812020-05-26 12:31:35 +0200434
Laurent Pinchart7a88b212020-06-10 00:07:59 +0300435 return std::make_tuple(numEntries, byteSize);
Jacopo Mondia80d3812020-05-26 12:31:35 +0200436}
437
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200438/*
439 * Return static information for the camera.
440 */
Laurent Pinchartda3f50e2020-01-20 01:09:34 +0200441const camera_metadata_t *CameraDevice::getStaticMetadata()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200442{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200443 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300444 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200445
446 /*
447 * The here reported metadata are enough to implement a basic capture
448 * example application, but a real camera implementation will require
449 * more.
450 */
Jacopo Mondia80d3812020-05-26 12:31:35 +0200451 uint32_t numEntries;
452 uint32_t byteSize;
453 std::tie(numEntries, byteSize) = calculateStaticMetadataSize();
454 staticMetadata_ = new CameraMetadata(numEntries, byteSize);
Laurent Pinchart39860092019-09-05 03:12:34 +0300455 if (!staticMetadata_->isValid()) {
456 LOG(HAL, Error) << "Failed to allocate static metadata";
457 delete staticMetadata_;
458 staticMetadata_ = nullptr;
459 return nullptr;
460 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200461
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200462 /* Color correction static metadata. */
463 std::vector<uint8_t> aberrationModes = {
464 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
465 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300466 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
467 aberrationModes.data(),
468 aberrationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200469
470 /* Control static metadata. */
471 std::vector<uint8_t> aeAvailableAntiBandingModes = {
472 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
473 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
474 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
475 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
476 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300477 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
478 aeAvailableAntiBandingModes.data(),
479 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200480
481 std::vector<uint8_t> aeAvailableModes = {
482 ANDROID_CONTROL_AE_MODE_ON,
483 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300484 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
485 aeAvailableModes.data(),
486 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200487
488 std::vector<int32_t> availableAeFpsTarget = {
489 15, 30,
490 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300491 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
492 availableAeFpsTarget.data(),
493 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200494
495 std::vector<int32_t> aeCompensationRange = {
496 0, 0,
497 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300498 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
499 aeCompensationRange.data(),
500 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200501
502 const camera_metadata_rational_t aeCompensationStep[] = {
503 { 0, 1 }
504 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300505 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
506 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200507
508 std::vector<uint8_t> availableAfModes = {
509 ANDROID_CONTROL_AF_MODE_OFF,
510 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300511 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
512 availableAfModes.data(),
513 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200514
515 std::vector<uint8_t> availableEffects = {
516 ANDROID_CONTROL_EFFECT_MODE_OFF,
517 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300518 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
519 availableEffects.data(),
520 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200521
522 std::vector<uint8_t> availableSceneModes = {
523 ANDROID_CONTROL_SCENE_MODE_DISABLED,
524 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300525 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
526 availableSceneModes.data(),
527 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200528
529 std::vector<uint8_t> availableStabilizationModes = {
530 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
531 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300532 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
533 availableStabilizationModes.data(),
534 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200535
536 std::vector<uint8_t> availableAwbModes = {
537 ANDROID_CONTROL_AWB_MODE_OFF,
538 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300539 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
540 availableAwbModes.data(),
541 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200542
543 std::vector<int32_t> availableMaxRegions = {
544 0, 0, 0,
545 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300546 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
547 availableMaxRegions.data(),
548 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200549
550 std::vector<uint8_t> sceneModesOverride = {
551 ANDROID_CONTROL_AE_MODE_ON,
552 ANDROID_CONTROL_AWB_MODE_AUTO,
553 ANDROID_CONTROL_AF_MODE_AUTO,
554 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300555 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
556 sceneModesOverride.data(),
557 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200558
559 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300560 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
561 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200562
563 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300564 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
565 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200566
567 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300568 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
569 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200570
571 /* JPEG static metadata. */
572 std::vector<int32_t> availableThumbnailSizes = {
573 0, 0,
574 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300575 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
576 availableThumbnailSizes.data(),
577 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200578
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200579 /* Sensor static metadata. */
580 int32_t pixelArraySize[] = {
581 2592, 1944,
582 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300583 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
584 &pixelArraySize, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200585
586 int32_t sensorSizes[] = {
587 0, 0, 2560, 1920,
588 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300589 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
590 &sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200591
592 int32_t sensitivityRange[] = {
593 32, 2400,
594 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300595 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
596 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200597
598 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300599 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
600 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200601
602 int64_t exposureTimeRange[] = {
603 100000, 200000000,
604 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300605 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
606 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200607
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200608 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200609
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200610 std::vector<int32_t> testPatterModes = {
611 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
612 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300613 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
614 testPatterModes.data(),
615 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200616
617 std::vector<float> physicalSize = {
618 2592, 1944,
619 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300620 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
621 physicalSize.data(),
622 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200623
624 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300625 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
626 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200627
628 /* Statistics static metadata. */
629 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300630 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
631 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200632
633 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300634 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
635 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200636
637 /* Sync static metadata. */
638 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300639 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200640
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200641 /* Flash static metadata. */
642 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300643 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
644 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200645
646 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200647 std::vector<float> lensApertures = {
648 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200649 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300650 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
651 lensApertures.data(),
652 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200653
Jacopo Mondi64f4f662020-05-25 16:08:22 +0200654 uint8_t lensFacing;
655 switch (facing_) {
656 default:
657 case CAMERA_FACING_FRONT:
658 lensFacing = ANDROID_LENS_FACING_FRONT;
659 break;
660 case CAMERA_FACING_BACK:
661 lensFacing = ANDROID_LENS_FACING_BACK;
662 break;
663 case CAMERA_FACING_EXTERNAL:
664 lensFacing = ANDROID_LENS_FACING_EXTERNAL;
665 break;
Jacopo Mondi857a2162019-11-20 17:00:49 +0100666 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300667 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200668
669 std::vector<float> lensFocalLenghts = {
670 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200671 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300672 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
673 lensFocalLenghts.data(),
674 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200675
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200676 std::vector<uint8_t> opticalStabilizations = {
677 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
678 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300679 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
680 opticalStabilizations.data(),
681 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200682
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200683 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300684 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
685 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200686
687 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300688 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
689 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200690
691 /* Noise reduction modes. */
692 uint8_t noiseReductionModes = ANDROID_NOISE_REDUCTION_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300693 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
694 &noiseReductionModes, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200695
696 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200697 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300698 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
699 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200700
Jacopo Mondibde7b982020-05-25 17:18:28 +0200701 std::vector<uint32_t> availableStreamConfigurations;
702 availableStreamConfigurations.reserve(streamConfigurations_.size() * 4);
703 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200704 availableStreamConfigurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200705 availableStreamConfigurations.push_back(entry.resolution.width);
706 availableStreamConfigurations.push_back(entry.resolution.height);
707 availableStreamConfigurations.push_back(
708 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
709 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300710 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
711 availableStreamConfigurations.data(),
712 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200713
714 std::vector<int64_t> availableStallDurations = {
715 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
716 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300717 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
718 availableStallDurations.data(),
719 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200720
Jacopo Mondibde7b982020-05-25 17:18:28 +0200721 /* \todo Collect the minimum frame duration from the camera. */
722 std::vector<int64_t> minFrameDurations;
723 minFrameDurations.reserve(streamConfigurations_.size() * 4);
724 for (const auto &entry : streamConfigurations_) {
Niklas Söderlund142a9ee2020-07-23 18:32:23 +0200725 minFrameDurations.push_back(entry.androidFormat);
Jacopo Mondibde7b982020-05-25 17:18:28 +0200726 minFrameDurations.push_back(entry.resolution.width);
727 minFrameDurations.push_back(entry.resolution.height);
728 minFrameDurations.push_back(33333333);
729 }
Laurent Pinchart39860092019-09-05 03:12:34 +0300730 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
731 minFrameDurations.data(),
732 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200733
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200734 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300735 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200736
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200737 /* Info static metadata. */
738 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300739 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
740 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200741
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200742 /* Request static metadata. */
743 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300744 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
745 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200746
747 uint8_t maxPipelineDepth = 2;
Laurent Pinchart39860092019-09-05 03:12:34 +0300748 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
749 &maxPipelineDepth, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200750
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200751 /* LIMITED does not support reprocessing. */
752 uint32_t maxNumInputStreams = 0;
753 staticMetadata_->addEntry(ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
754 &maxNumInputStreams, 1);
755
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200756 std::vector<uint8_t> availableCapabilities = {
757 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
758 };
Niklas Söderlund7876d632020-07-21 00:16:24 +0200759
760 /* Report if camera supports RAW. */
761 std::unique_ptr<CameraConfiguration> cameraConfig =
762 camera_->generateConfiguration({ StillCaptureRaw });
763 if (cameraConfig && !cameraConfig->empty()) {
764 const PixelFormatInfo &info =
765 PixelFormatInfo::info(cameraConfig->at(0).pixelFormat);
766 if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
767 availableCapabilities.push_back(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW);
768 }
769
Laurent Pinchart39860092019-09-05 03:12:34 +0300770 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
771 availableCapabilities.data(),
772 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200773
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200774 std::vector<int32_t> availableCharacteristicsKeys = {
775 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
776 ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
777 ANDROID_CONTROL_AE_AVAILABLE_MODES,
778 ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
779 ANDROID_CONTROL_AE_COMPENSATION_RANGE,
780 ANDROID_CONTROL_AE_COMPENSATION_STEP,
781 ANDROID_CONTROL_AF_AVAILABLE_MODES,
782 ANDROID_CONTROL_AVAILABLE_EFFECTS,
783 ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
784 ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
785 ANDROID_CONTROL_AWB_AVAILABLE_MODES,
786 ANDROID_CONTROL_MAX_REGIONS,
787 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
788 ANDROID_CONTROL_AE_LOCK_AVAILABLE,
789 ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
790 ANDROID_CONTROL_AVAILABLE_MODES,
791 ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
792 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
793 ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
794 ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
795 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
796 ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
797 ANDROID_SENSOR_ORIENTATION,
798 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
799 ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
800 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
801 ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
802 ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
803 ANDROID_SYNC_MAX_LATENCY,
804 ANDROID_FLASH_INFO_AVAILABLE,
805 ANDROID_LENS_INFO_AVAILABLE_APERTURES,
806 ANDROID_LENS_FACING,
807 ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
808 ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
809 ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
810 ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
811 ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
812 ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200813 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
814 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
815 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
816 ANDROID_SCALER_CROPPING_TYPE,
817 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
818 ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
819 ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
Niklas Söderlunda2a6f952020-07-21 00:16:02 +0200820 ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200821 ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
822 };
823 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
824 availableCharacteristicsKeys.data(),
825 availableCharacteristicsKeys.size());
826
827 std::vector<int32_t> availableRequestKeys = {
828 ANDROID_CONTROL_AE_MODE,
829 ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
830 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200831 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
832 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200833 ANDROID_CONTROL_AE_LOCK,
834 ANDROID_CONTROL_AF_TRIGGER,
835 ANDROID_CONTROL_AWB_MODE,
836 ANDROID_CONTROL_AWB_LOCK,
837 ANDROID_FLASH_MODE,
838 ANDROID_STATISTICS_FACE_DETECT_MODE,
839 ANDROID_NOISE_REDUCTION_MODE,
840 ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200841 ANDROID_LENS_APERTURE,
842 ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
843 ANDROID_CONTROL_MODE,
Jacopo Mondi19f85f42019-09-04 16:18:25 +0200844 ANDROID_CONTROL_CAPTURE_INTENT,
845 };
846 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS,
847 availableRequestKeys.data(),
848 availableRequestKeys.size());
849
850 std::vector<int32_t> availableResultKeys = {
851 ANDROID_CONTROL_AE_STATE,
852 ANDROID_CONTROL_AE_LOCK,
853 ANDROID_CONTROL_AF_STATE,
854 ANDROID_CONTROL_AWB_STATE,
855 ANDROID_CONTROL_AWB_LOCK,
856 ANDROID_LENS_STATE,
857 ANDROID_SCALER_CROP_REGION,
858 ANDROID_SENSOR_TIMESTAMP,
859 ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
860 ANDROID_SENSOR_EXPOSURE_TIME,
861 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
862 ANDROID_STATISTICS_SCENE_FLICKER,
863 };
864 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS,
865 availableResultKeys.data(),
866 availableResultKeys.size());
867
Laurent Pinchart39860092019-09-05 03:12:34 +0300868 if (!staticMetadata_->isValid()) {
869 LOG(HAL, Error) << "Failed to construct static metadata";
870 delete staticMetadata_;
871 staticMetadata_ = nullptr;
872 return nullptr;
873 }
874
875 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200876}
877
Jacopo Mondi8a02d442020-07-24 15:47:50 +0200878CameraMetadata *CameraDevice::requestTemplatePreview()
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200879{
Jacopo Mondi63703472019-09-04 16:18:22 +0200880 /*
881 * \todo Keep this in sync with the actual number of entries.
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200882 * Currently: 20 entries, 35 bytes
Jacopo Mondi63703472019-09-04 16:18:22 +0200883 */
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200884 CameraMetadata *requestTemplate = new CameraMetadata(20, 35);
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200885 if (!requestTemplate->isValid()) {
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200886 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200887 return nullptr;
888 }
889
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200890 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200891 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
892 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200893
894 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200895 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
896 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200897
898 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200899 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
900 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200901
902 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200903 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
904 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200905
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200906 std::vector<int32_t> aeFpsTarget = {
907 15, 30,
908 };
909 requestTemplate->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
910 aeFpsTarget.data(),
911 aeFpsTarget.size());
912
913 uint8_t aeAntibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
914 requestTemplate->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
915 &aeAntibandingMode, 1);
916
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200917 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200918 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
919 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200920
921 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200922 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
923 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200924
925 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200926 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
927 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200928
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200929 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200930 requestTemplate->addEntry(ANDROID_FLASH_MODE,
931 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200932
933 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200934 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
935 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200936
Jacopo Mondi9b361dc2019-09-04 16:18:21 +0200937 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200938 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
939 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +0200940
941 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200942 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
943 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +0200944
Jacopo Mondi09b1d0f2020-07-24 16:10:23 +0200945 uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
946 requestTemplate->addEntry(ANDROID_CONTROL_MODE, &controlMode, 1);
947
948 float lensAperture = 2.53 / 100;
949 requestTemplate->addEntry(ANDROID_LENS_APERTURE, &lensAperture, 1);
950
951 uint8_t opticalStabilization = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF;
952 requestTemplate->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
953 &opticalStabilization, 1);
954
Jacopo Mondi8a02d442020-07-24 15:47:50 +0200955 uint8_t captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200956 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
957 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200958
Jacopo Mondi8a02d442020-07-24 15:47:50 +0200959 return requestTemplate;
960}
961
962/*
963 * Produce a metadata pack to be used as template for a capture request.
964 */
965const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
966{
967 auto it = requestTemplates_.find(type);
968 if (it != requestTemplates_.end())
969 return it->second->get();
970
971 /* Use the capture intent matching the requested template type. */
972 CameraMetadata *requestTemplate;
973 uint8_t captureIntent;
974 switch (type) {
975 case CAMERA3_TEMPLATE_PREVIEW:
976 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
977 break;
978 case CAMERA3_TEMPLATE_STILL_CAPTURE:
979 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
980 break;
981 case CAMERA3_TEMPLATE_VIDEO_RECORD:
982 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
983 break;
984 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
985 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
986 break;
987 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
988 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
989 break;
990 case CAMERA3_TEMPLATE_MANUAL:
991 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
992 break;
993 default:
994 LOG(HAL, Error) << "Invalid template request type: " << type;
995 return nullptr;
996 }
997
998 requestTemplate = requestTemplatePreview();
999 if (!requestTemplate || !requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +03001000 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001001 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +03001002 return nullptr;
1003 }
1004
Jacopo Mondi8a02d442020-07-24 15:47:50 +02001005 requestTemplate->updateEntry(ANDROID_CONTROL_CAPTURE_INTENT,
1006 &captureIntent, 1);
1007
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +02001008 requestTemplates_[type] = requestTemplate;
1009 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001010}
1011
Kieran Bingham43e3b802020-06-26 09:58:49 +01001012PixelFormat CameraDevice::toPixelFormat(int format)
1013{
1014 /* Translate Android format code to libcamera pixel format. */
1015 auto it = formatsMap_.find(format);
1016 if (it == formatsMap_.end()) {
1017 LOG(HAL, Error) << "Requested format " << utils::hex(format)
1018 << " not supported";
1019 return PixelFormat();
1020 }
1021
1022 return it->second;
1023}
1024
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001025/*
1026 * Inspect the stream_list to produce a list of StreamConfiguration to
1027 * be use to configure the Camera.
1028 */
1029int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
1030{
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001031 /*
1032 * Generate an empty configuration, and construct a StreamConfiguration
1033 * for each camera3_stream to add to it.
1034 */
1035 config_ = camera_->generateConfiguration();
1036 if (!config_) {
1037 LOG(HAL, Error) << "Failed to generate camera configuration";
1038 return -EINVAL;
1039 }
1040
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001041 /*
1042 * Clear and remove any existing configuration from previous calls, and
1043 * ensure the required entries are available without further
1044 * re-allcoation.
1045 */
1046 streams_.clear();
1047 streams_.reserve(stream_list->num_streams);
1048
1049 /*
1050 * Track actually created streams, as there may not be a 1:1 mapping of
1051 * camera3 streams to libcamera streams.
1052 */
1053 unsigned int streamIndex = 0;
1054
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001055 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1056 camera3_stream_t *stream = stream_list->streams[i];
1057
Kieran Bingham43e3b802020-06-26 09:58:49 +01001058 PixelFormat format = toPixelFormat(stream->format);
1059
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001060 LOG(HAL, Info) << "Stream #" << i
1061 << ", direction: " << stream->stream_type
1062 << ", width: " << stream->width
1063 << ", height: " << stream->height
Kieran Bingham43e3b802020-06-26 09:58:49 +01001064 << ", format: " << utils::hex(stream->format)
1065 << " (" << format.toString() << ")";
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001066
1067 if (!format.isValid())
1068 return -EINVAL;
1069
1070 StreamConfiguration streamConfiguration;
1071
1072 streamConfiguration.size.width = stream->width;
1073 streamConfiguration.size.height = stream->height;
1074 streamConfiguration.pixelFormat = format;
1075
1076 config_->addConfiguration(streamConfiguration);
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001077
1078 streams_[i].index = streamIndex++;
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001079 stream->priv = static_cast<void *>(&streams_[i]);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001080 }
1081
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001082 switch (config_->validate()) {
1083 case CameraConfiguration::Valid:
1084 break;
1085 case CameraConfiguration::Adjusted:
1086 LOG(HAL, Info) << "Camera configuration adjusted";
Kieran Bingham9f07aeb2020-07-20 22:52:14 +01001087
1088 for (const StreamConfiguration &cfg : *config_)
1089 LOG(HAL, Info) << " - " << cfg.toString();
1090
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001091 config_.reset();
1092 return -EINVAL;
1093 case CameraConfiguration::Invalid:
1094 LOG(HAL, Info) << "Camera configuration invalid";
1095 config_.reset();
1096 return -EINVAL;
1097 }
1098
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001099 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
1100 camera3_stream_t *stream = stream_list->streams[i];
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001101 CameraStream *cameraStream = &streams_[i];
1102 StreamConfiguration &cfg = config_->at(cameraStream->index);
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001103
1104 /* Use the bufferCount confirmed by the validation process. */
Kieran Bingham2f34f5e2020-07-01 16:42:13 +01001105 stream->max_buffers = cfg.bufferCount;
Kieran Bingham0a9244e2020-06-26 20:19:10 +01001106 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001107
1108 /*
1109 * Once the CameraConfiguration has been adjusted/validated
1110 * it can be applied to the camera.
1111 */
1112 int ret = camera_->configure(config_.get());
1113 if (ret) {
1114 LOG(HAL, Error) << "Failed to configure camera '"
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001115 << camera_->id() << "'";
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001116 return ret;
1117 }
1118
1119 return 0;
1120}
1121
Kieran Bingham74ab4422020-07-01 13:25:38 +01001122FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer)
1123{
1124 std::vector<FrameBuffer::Plane> planes;
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001125 for (int i = 0; i < camera3buffer->numFds; i++) {
1126 /* Skip unused planes. */
1127 if (camera3buffer->data[i] == -1)
1128 break;
1129
Kieran Bingham74ab4422020-07-01 13:25:38 +01001130 FrameBuffer::Plane plane;
1131 plane.fd = FileDescriptor(camera3buffer->data[i]);
Kieran Binghamf4c65be2020-07-06 16:12:03 +01001132 if (!plane.fd.isValid()) {
1133 LOG(HAL, Error) << "Failed to obtain FileDescriptor ("
1134 << camera3buffer->data[i] << ") "
1135 << " on plane " << i;
1136 return nullptr;
1137 }
1138
Kieran Bingham6bc652e2020-07-17 16:18:32 +01001139 off_t length = lseek(plane.fd.fd(), 0, SEEK_END);
1140 if (length == -1) {
1141 LOG(HAL, Error) << "Failed to query plane length";
1142 return nullptr;
1143 }
1144
1145 plane.length = length;
Kieran Bingham74ab4422020-07-01 13:25:38 +01001146 planes.push_back(std::move(plane));
1147 }
1148
1149 return new FrameBuffer(std::move(planes));
1150}
1151
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001152int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001153{
Kieran Bingham61f42962020-07-01 13:40:17 +01001154 if (!camera3Request->num_output_buffers) {
1155 LOG(HAL, Error) << "No output buffers provided";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001156 return -EINVAL;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001157 }
1158
1159 /* Start the camera if that's the first request we handle. */
1160 if (!running_) {
Niklas Söderlunda1c54502019-11-25 17:51:06 +01001161 int ret = camera_->start();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001162 if (ret) {
1163 LOG(HAL, Error) << "Failed to start camera";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001164 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001165 }
1166
1167 running_ = true;
1168 }
1169
1170 /*
1171 * Queue a request for the Camera with the provided dmabuf file
1172 * descriptors.
1173 */
1174 const camera3_stream_buffer_t *camera3Buffers =
1175 camera3Request->output_buffers;
1176
1177 /*
1178 * Save the request descriptors for use at completion time.
1179 * The descriptor and the associated memory reserved here are freed
1180 * at request complete time.
1181 */
1182 Camera3RequestDescriptor *descriptor =
1183 new Camera3RequestDescriptor(camera3Request->frame_number,
1184 camera3Request->num_output_buffers);
Kieran Binghameac05422020-07-01 13:28:16 +01001185
1186 Request *request =
1187 camera_->createRequest(reinterpret_cast<uint64_t>(descriptor));
1188
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001189 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001190 CameraStream *cameraStream =
1191 static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
1192
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001193 /*
1194 * Keep track of which stream the request belongs to and store
1195 * the native buffer handles.
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001196 */
1197 descriptor->buffers[i].stream = camera3Buffers[i].stream;
1198 descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001199
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001200 /*
1201 * Create a libcamera buffer using the dmabuf descriptors of
1202 * the camera3Buffer for each stream. The FrameBuffer is
1203 * directly associated with the Camera3RequestDescriptor for
1204 * lifetime management only.
1205 */
1206 FrameBuffer *buffer = createFrameBuffer(*camera3Buffers[i].buffer);
1207 if (!buffer) {
1208 LOG(HAL, Error) << "Failed to create buffer";
1209 delete request;
1210 delete descriptor;
1211 return -ENOMEM;
1212 }
1213 descriptor->frameBuffers.emplace_back(buffer);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001214
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001215 StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index);
1216 Stream *stream = streamConfiguration->stream();
1217
1218 request->addBuffer(stream, buffer);
1219 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001220
1221 int ret = camera_->queueRequest(request);
1222 if (ret) {
1223 LOG(HAL, Error) << "Failed to queue request";
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001224 delete request;
1225 delete descriptor;
1226 return ret;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001227 }
1228
Laurent Pinchartda3f50e2020-01-20 01:09:34 +02001229 return 0;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001230}
1231
Niklas Söderlundf7ddfd42019-10-21 20:01:19 +02001232void CameraDevice::requestComplete(Request *request)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001233{
Niklas Söderlund9217f272019-11-22 16:22:56 +01001234 const std::map<Stream *, FrameBuffer *> &buffers = request->buffers();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001235 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +03001236 std::unique_ptr<CameraMetadata> resultMetadata;
Kieran Binghamc09aee42020-07-28 14:01:19 +01001237 Camera3RequestDescriptor *descriptor =
1238 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001239
1240 if (request->status() != Request::RequestComplete) {
Kieran Bingham98986e02020-08-03 14:34:11 +01001241 LOG(HAL, Error) << "Request not successfully completed: "
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001242 << request->status();
1243 status = CAMERA3_BUFFER_STATUS_ERROR;
1244 }
1245
Kieran Binghamc09aee42020-07-28 14:01:19 +01001246 /*
1247 * \todo The timestamp used for the metadata is currently always taken
1248 * from the first buffer (which may be the first stream) in the Request.
1249 * It might be appropriate to return a 'correct' (as determined by
1250 * pipeline handlers) timestamp in the Request itself.
1251 */
1252 FrameBuffer *buffer = buffers.begin()->second;
1253 resultMetadata = getResultMetadata(descriptor->frameNumber,
1254 buffer->metadata().timestamp);
1255
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001256 /* Prepare to call back the Android camera stack. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001257
1258 camera3_capture_result_t captureResult = {};
1259 captureResult.frame_number = descriptor->frameNumber;
1260 captureResult.num_output_buffers = descriptor->numBuffers;
1261 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001262 descriptor->buffers[i].acquire_fence = -1;
1263 descriptor->buffers[i].release_fence = -1;
1264 descriptor->buffers[i].status = status;
1265 }
1266 captureResult.output_buffers =
1267 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers);
1268
Kieran Bingham0cfdf732020-07-01 13:36:24 +01001269
Laurent Pinchart39860092019-09-05 03:12:34 +03001270 if (status == CAMERA3_BUFFER_STATUS_OK) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001271 notifyShutter(descriptor->frameNumber,
Niklas Söderlund9217f272019-11-22 16:22:56 +01001272 buffer->metadata().timestamp);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001273
1274 captureResult.partial_result = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +03001275 captureResult.result = resultMetadata->get();
1276 }
1277
1278 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
1279 /* \todo Improve error handling. In case we notify an error
1280 * because the metadata generation fails, a shutter event has
1281 * already been notified for this frame number before the error
1282 * is here signalled. Make sure the error path plays well with
1283 * the camera stack state machine.
1284 */
1285 notifyError(descriptor->frameNumber,
1286 descriptor->buffers[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001287 }
1288
1289 callbacks_->process_capture_result(callbacks_, &captureResult);
1290
1291 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001292}
1293
Jacopo Mondia7b92772020-05-26 15:41:41 +02001294std::string CameraDevice::logPrefix() const
1295{
Niklas Söderlund2e7c80a2020-08-02 23:57:17 +02001296 return "'" + camera_->id() + "'";
Jacopo Mondia7b92772020-05-26 15:41:41 +02001297}
1298
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001299void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
1300{
1301 camera3_notify_msg_t notify = {};
1302
1303 notify.type = CAMERA3_MSG_SHUTTER;
1304 notify.message.shutter.frame_number = frameNumber;
1305 notify.message.shutter.timestamp = timestamp;
1306
1307 callbacks_->notify(callbacks_, &notify);
1308}
1309
1310void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
1311{
1312 camera3_notify_msg_t notify = {};
1313
Kieran Bingham8ad1b9c2020-07-01 16:47:58 +01001314 /*
1315 * \todo Report and identify the stream number or configuration to
1316 * clarify the stream that failed.
1317 */
1318 LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " ("
1319 << toPixelFormat(stream->format).toString() << ")";
1320
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001321 notify.type = CAMERA3_MSG_ERROR;
1322 notify.message.error.error_stream = stream;
1323 notify.message.error.frame_number = frameNumber;
1324 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
1325
1326 callbacks_->notify(callbacks_, &notify);
1327}
1328
1329/*
1330 * Produce a set of fixed result metadata.
1331 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001332std::unique_ptr<CameraMetadata> CameraDevice::getResultMetadata(int frame_number,
1333 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001334{
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001335 /*
1336 * \todo Keep this in sync with the actual number of entries.
Laurent Pinchart39860092019-09-05 03:12:34 +03001337 * Currently: 12 entries, 36 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +02001338 */
Laurent Pinchart39860092019-09-05 03:12:34 +03001339 std::unique_ptr<CameraMetadata> resultMetadata =
Laurent Pinchartacf18e42020-01-14 01:35:22 +02001340 std::make_unique<CameraMetadata>(15, 50);
Laurent Pinchart39860092019-09-05 03:12:34 +03001341 if (!resultMetadata->isValid()) {
1342 LOG(HAL, Error) << "Failed to allocate static metadata";
1343 return nullptr;
1344 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001345
1346 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001347 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001348
1349 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001350 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001351
1352 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001353 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001354
1355 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +03001356 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001357
1358 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001359 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001360
1361 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +03001362 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001363
1364 int32_t sensorSizes[] = {
1365 0, 0, 2560, 1920,
1366 };
Laurent Pinchart39860092019-09-05 03:12:34 +03001367 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001368
Laurent Pinchart39860092019-09-05 03:12:34 +03001369 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001370
1371 /* 33.3 msec */
1372 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001373 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
1374 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001375
1376 /* 16.6 msec */
1377 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +03001378 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
1379 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001380
1381 const uint8_t lens_shading_map_mode =
1382 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +03001383 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
1384 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001385
1386 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +03001387 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
1388 &scene_flicker, 1);
1389
1390 /*
1391 * Return the result metadata pack even is not valid: get() will return
1392 * nullptr.
1393 */
1394 if (!resultMetadata->isValid()) {
1395 LOG(HAL, Error) << "Failed to construct result metadata";
1396 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +02001397
1398 return resultMetadata;
1399}