blob: 943981535f74a2a753a626397fa4c078b5469f71 [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"
9
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020010#include "log.h"
Laurent Pinchart39860092019-09-05 03:12:34 +030011#include "utils.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020012
Laurent Pinchart39860092019-09-05 03:12:34 +030013#include "camera_metadata.h"
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020014#include "thread_rpc.h"
15
16using namespace libcamera;
17
18LOG_DECLARE_CATEGORY(HAL);
19
20/*
21 * \struct Camera3RequestDescriptor
22 *
23 * A utility structure that groups information about a capture request to be
24 * later re-used at request complete time to notify the framework.
25 */
26
27CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor(
28 unsigned int frameNumber, unsigned int numBuffers)
29 : frameNumber(frameNumber), numBuffers(numBuffers)
30{
31 buffers = new camera3_stream_buffer_t[numBuffers];
32}
33
34CameraDevice::Camera3RequestDescriptor::~Camera3RequestDescriptor()
35{
36 delete[] buffers;
37}
38
39/*
40 * \class CameraDevice
41 *
42 * The CameraDevice class wraps a libcamera::Camera instance, and implements
43 * the camera_device_t interface by handling RPC requests received from its
44 * associated CameraProxy.
45 *
46 * It translate parameters and operations from Camera HALv3 API to the libcamera
47 * ones to provide static information for a Camera, create request templates
48 * for it, process capture requests and then deliver capture results back
49 * to the framework using the designated callbacks.
50 */
51
Laurent Pinchart0ed40d22019-08-18 01:45:01 +030052CameraDevice::CameraDevice(unsigned int id, const std::shared_ptr<Camera> &camera)
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +020053 : running_(false), camera_(camera), staticMetadata_(nullptr)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020054{
55 camera_->requestCompleted.connect(this, &CameraDevice::requestComplete);
56}
57
58CameraDevice::~CameraDevice()
59{
60 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +030061 delete staticMetadata_;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020062
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +020063 for (auto &it : requestTemplates_)
64 delete it.second;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020065}
66
67/*
68 * Handle RPC request received from the associated proxy.
69 */
Laurent Pinchart0c324332019-08-12 05:30:06 +030070void CameraDevice::call(ThreadRpc *rpc)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020071{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +020072 switch (rpc->tag) {
73 case ThreadRpc::ProcessCaptureRequest:
74 processCaptureRequest(rpc->request);
75 break;
76 case ThreadRpc::Close:
77 close();
78 break;
79 default:
80 LOG(HAL, Error) << "Unknown RPC operation: " << rpc->tag;
81 }
82
83 rpc->notifyReception();
84}
85
86int CameraDevice::open()
87{
88 int ret = camera_->acquire();
89 if (ret) {
90 LOG(HAL, Error) << "Failed to acquire the camera";
91 return ret;
92 }
93
94 return 0;
95}
96
97void CameraDevice::close()
98{
99 camera_->stop();
100
101 camera_->freeBuffers();
102 camera_->release();
103
104 running_ = false;
105}
106
107void CameraDevice::setCallbacks(const camera3_callback_ops_t *callbacks)
108{
109 callbacks_ = callbacks;
110}
111
112/*
113 * Return static information for the camera.
114 */
115camera_metadata_t *CameraDevice::getStaticMetadata()
116{
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200117 if (staticMetadata_)
Laurent Pinchart39860092019-09-05 03:12:34 +0300118 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200119
120 /*
121 * The here reported metadata are enough to implement a basic capture
122 * example application, but a real camera implementation will require
123 * more.
124 */
125
Jacopo Mondi48504ba2019-09-04 16:18:19 +0200126 /*
127 * \todo Keep this in sync with the actual number of entries.
Laurent Pinchart39860092019-09-05 03:12:34 +0300128 * Currently: 47 entries, 390 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +0200129 */
Laurent Pinchart39860092019-09-05 03:12:34 +0300130 staticMetadata_ = new CameraMetadata(50, 500);
131 if (!staticMetadata_->isValid()) {
132 LOG(HAL, Error) << "Failed to allocate static metadata";
133 delete staticMetadata_;
134 staticMetadata_ = nullptr;
135 return nullptr;
136 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200137
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200138 /* Color correction static metadata. */
139 std::vector<uint8_t> aberrationModes = {
140 ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF,
141 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300142 staticMetadata_->addEntry(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
143 aberrationModes.data(),
144 aberrationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200145
146 /* Control static metadata. */
147 std::vector<uint8_t> aeAvailableAntiBandingModes = {
148 ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF,
149 ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ,
150 ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ,
151 ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO,
152 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300153 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
154 aeAvailableAntiBandingModes.data(),
155 aeAvailableAntiBandingModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200156
157 std::vector<uint8_t> aeAvailableModes = {
158 ANDROID_CONTROL_AE_MODE_ON,
159 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300160 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_MODES,
161 aeAvailableModes.data(),
162 aeAvailableModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200163
164 std::vector<int32_t> availableAeFpsTarget = {
165 15, 30,
166 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300167 staticMetadata_->addEntry(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
168 availableAeFpsTarget.data(),
169 availableAeFpsTarget.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200170
171 std::vector<int32_t> aeCompensationRange = {
172 0, 0,
173 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300174 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
175 aeCompensationRange.data(),
176 aeCompensationRange.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200177
178 const camera_metadata_rational_t aeCompensationStep[] = {
179 { 0, 1 }
180 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300181 staticMetadata_->addEntry(ANDROID_CONTROL_AE_COMPENSATION_STEP,
182 aeCompensationStep, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200183
184 std::vector<uint8_t> availableAfModes = {
185 ANDROID_CONTROL_AF_MODE_OFF,
186 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300187 staticMetadata_->addEntry(ANDROID_CONTROL_AF_AVAILABLE_MODES,
188 availableAfModes.data(),
189 availableAfModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200190
191 std::vector<uint8_t> availableEffects = {
192 ANDROID_CONTROL_EFFECT_MODE_OFF,
193 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300194 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_EFFECTS,
195 availableEffects.data(),
196 availableEffects.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200197
198 std::vector<uint8_t> availableSceneModes = {
199 ANDROID_CONTROL_SCENE_MODE_DISABLED,
200 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300201 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
202 availableSceneModes.data(),
203 availableSceneModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200204
205 std::vector<uint8_t> availableStabilizationModes = {
206 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF,
207 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300208 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,
209 availableStabilizationModes.data(),
210 availableStabilizationModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200211
212 std::vector<uint8_t> availableAwbModes = {
213 ANDROID_CONTROL_AWB_MODE_OFF,
214 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300215 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
216 availableAwbModes.data(),
217 availableAwbModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200218
219 std::vector<int32_t> availableMaxRegions = {
220 0, 0, 0,
221 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300222 staticMetadata_->addEntry(ANDROID_CONTROL_MAX_REGIONS,
223 availableMaxRegions.data(),
224 availableMaxRegions.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200225
226 std::vector<uint8_t> sceneModesOverride = {
227 ANDROID_CONTROL_AE_MODE_ON,
228 ANDROID_CONTROL_AWB_MODE_AUTO,
229 ANDROID_CONTROL_AF_MODE_AUTO,
230 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300231 staticMetadata_->addEntry(ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
232 sceneModesOverride.data(),
233 sceneModesOverride.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200234
235 uint8_t aeLockAvailable = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300236 staticMetadata_->addEntry(ANDROID_CONTROL_AE_LOCK_AVAILABLE,
237 &aeLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200238
239 uint8_t awbLockAvailable = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300240 staticMetadata_->addEntry(ANDROID_CONTROL_AWB_LOCK_AVAILABLE,
241 &awbLockAvailable, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200242
243 char availableControlModes = ANDROID_CONTROL_MODE_AUTO;
Laurent Pinchart39860092019-09-05 03:12:34 +0300244 staticMetadata_->addEntry(ANDROID_CONTROL_AVAILABLE_MODES,
245 &availableControlModes, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200246
247 /* JPEG static metadata. */
248 std::vector<int32_t> availableThumbnailSizes = {
249 0, 0,
250 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300251 staticMetadata_->addEntry(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
252 availableThumbnailSizes.data(),
253 availableThumbnailSizes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200254
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200255 /* Sensor static metadata. */
256 int32_t pixelArraySize[] = {
257 2592, 1944,
258 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300259 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
260 &pixelArraySize, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200261
262 int32_t sensorSizes[] = {
263 0, 0, 2560, 1920,
264 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300265 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
266 &sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200267
268 int32_t sensitivityRange[] = {
269 32, 2400,
270 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300271 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
272 &sensitivityRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200273
274 uint16_t filterArr = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG;
Laurent Pinchart39860092019-09-05 03:12:34 +0300275 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
276 &filterArr, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200277
278 int64_t exposureTimeRange[] = {
279 100000, 200000000,
280 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300281 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE,
282 &exposureTimeRange, 2);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200283
284 int32_t orientation = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300285 staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION,
286 &orientation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200287
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200288 std::vector<int32_t> testPatterModes = {
289 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF,
290 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300291 staticMetadata_->addEntry(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES,
292 testPatterModes.data(),
293 testPatterModes.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200294
295 std::vector<float> physicalSize = {
296 2592, 1944,
297 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300298 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
299 physicalSize.data(),
300 physicalSize.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200301
302 uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300303 staticMetadata_->addEntry(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
304 &timestampSource, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200305
306 /* Statistics static metadata. */
307 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300308 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES,
309 &faceDetectMode, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200310
311 int32_t maxFaceCount = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300312 staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
313 &maxFaceCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200314
315 /* Sync static metadata. */
316 int32_t maxLatency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN;
Laurent Pinchart39860092019-09-05 03:12:34 +0300317 staticMetadata_->addEntry(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200318
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200319 /* Flash static metadata. */
320 char flashAvailable = ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300321 staticMetadata_->addEntry(ANDROID_FLASH_INFO_AVAILABLE,
322 &flashAvailable, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200323
324 /* Lens static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200325 std::vector<float> lensApertures = {
326 2.53 / 100,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200327 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300328 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_APERTURES,
329 lensApertures.data(),
330 lensApertures.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200331
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200332 uint8_t lensFacing = ANDROID_LENS_FACING_FRONT;
Laurent Pinchart39860092019-09-05 03:12:34 +0300333 staticMetadata_->addEntry(ANDROID_LENS_FACING, &lensFacing, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200334
335 std::vector<float> lensFocalLenghts = {
336 1,
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200337 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300338 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
339 lensFocalLenghts.data(),
340 lensFocalLenghts.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200341
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200342 std::vector<uint8_t> opticalStabilizations = {
343 ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF,
344 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300345 staticMetadata_->addEntry(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
346 opticalStabilizations.data(),
347 opticalStabilizations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200348
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200349 float hypeFocalDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300350 staticMetadata_->addEntry(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE,
351 &hypeFocalDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200352
353 float minFocusDistance = 0;
Laurent Pinchart39860092019-09-05 03:12:34 +0300354 staticMetadata_->addEntry(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
355 &minFocusDistance, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200356
357 /* Noise reduction modes. */
358 uint8_t noiseReductionModes = ANDROID_NOISE_REDUCTION_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300359 staticMetadata_->addEntry(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
360 &noiseReductionModes, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200361
362 /* Scaler static metadata. */
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200363 float maxDigitalZoom = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300364 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
365 &maxDigitalZoom, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200366
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200367 std::vector<uint32_t> availableStreamFormats = {
368 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
369 ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
370 ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
371 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300372 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_FORMATS,
373 availableStreamFormats.data(),
374 availableStreamFormats.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200375
376 std::vector<uint32_t> availableStreamConfigurations = {
377 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920,
378 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
379 ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888, 2560, 1920,
380 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
381 ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED, 2560, 1920,
382 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT,
383 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300384 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
385 availableStreamConfigurations.data(),
386 availableStreamConfigurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200387
388 std::vector<int64_t> availableStallDurations = {
389 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
390 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300391 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
392 availableStallDurations.data(),
393 availableStallDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200394
395 std::vector<int64_t> minFrameDurations = {
396 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB, 2560, 1920, 33333333,
397 ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED, 2560, 1920, 33333333,
398 ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888, 2560, 1920, 33333333,
399 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300400 staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
401 minFrameDurations.data(),
402 minFrameDurations.size());
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200403
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200404 uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300405 staticMetadata_->addEntry(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200406
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200407 /* Info static metadata. */
408 uint8_t supportedHWLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300409 staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL,
410 &supportedHWLevel, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200411
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200412 /* Request static metadata. */
413 int32_t partialResultCount = 1;
Laurent Pinchart39860092019-09-05 03:12:34 +0300414 staticMetadata_->addEntry(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,
415 &partialResultCount, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200416
417 uint8_t maxPipelineDepth = 2;
Laurent Pinchart39860092019-09-05 03:12:34 +0300418 staticMetadata_->addEntry(ANDROID_REQUEST_PIPELINE_MAX_DEPTH,
419 &maxPipelineDepth, 1);
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200420
421 std::vector<uint8_t> availableCapabilities = {
422 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
423 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300424 staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
425 availableCapabilities.data(),
426 availableCapabilities.size());
Jacopo Mondib4893fc2019-09-04 16:18:18 +0200427
Laurent Pinchart39860092019-09-05 03:12:34 +0300428 if (!staticMetadata_->isValid()) {
429 LOG(HAL, Error) << "Failed to construct static metadata";
430 delete staticMetadata_;
431 staticMetadata_ = nullptr;
432 return nullptr;
433 }
434
435 return staticMetadata_->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200436}
437
438/*
439 * Produce a metadata pack to be used as template for a capture request.
440 */
441const camera_metadata_t *CameraDevice::constructDefaultRequestSettings(int type)
442{
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200443 auto it = requestTemplates_.find(type);
444 if (it != requestTemplates_.end())
445 return it->second->get();
446
447 /* Use the capture intent matching the requested template type. */
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200448 uint8_t captureIntent;
449 switch (type) {
450 case CAMERA3_TEMPLATE_PREVIEW:
451 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
452 break;
453 case CAMERA3_TEMPLATE_STILL_CAPTURE:
454 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
455 break;
456 case CAMERA3_TEMPLATE_VIDEO_RECORD:
457 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
458 break;
459 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
460 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
461 break;
462 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
463 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG;
464 break;
465 case CAMERA3_TEMPLATE_MANUAL:
466 captureIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL;
467 break;
468 default:
469 LOG(HAL, Error) << "Invalid template request type: " << type;
470 return nullptr;
471 }
472
Jacopo Mondi63703472019-09-04 16:18:22 +0200473 /*
474 * \todo Keep this in sync with the actual number of entries.
475 * Currently: 12 entries, 15 bytes
476 */
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200477 CameraMetadata *requestTemplate = new CameraMetadata(15, 20);
478 if (!requestTemplate->isValid()) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200479 LOG(HAL, Error) << "Failed to allocate template metadata";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200480 delete requestTemplate;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200481 return nullptr;
482 }
483
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200484 uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200485 requestTemplate->addEntry(ANDROID_CONTROL_AE_MODE,
486 &aeMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200487
488 int32_t aeExposureCompensation = 0;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200489 requestTemplate->addEntry(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
490 &aeExposureCompensation, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200491
492 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200493 requestTemplate->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
494 &aePrecaptureTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200495
496 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200497 requestTemplate->addEntry(ANDROID_CONTROL_AE_LOCK,
498 &aeLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200499
500 uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200501 requestTemplate->addEntry(ANDROID_CONTROL_AF_TRIGGER,
502 &afTrigger, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200503
504 uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200505 requestTemplate->addEntry(ANDROID_CONTROL_AWB_MODE,
506 &awbMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200507
508 uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200509 requestTemplate->addEntry(ANDROID_CONTROL_AWB_LOCK,
510 &awbLock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200511
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200512 uint8_t flashMode = ANDROID_FLASH_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200513 requestTemplate->addEntry(ANDROID_FLASH_MODE,
514 &flashMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200515
516 uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200517 requestTemplate->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE,
518 &faceDetectMode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200519
Jacopo Mondi9b361dc2019-09-04 16:18:21 +0200520 uint8_t noiseReduction = ANDROID_NOISE_REDUCTION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200521 requestTemplate->addEntry(ANDROID_NOISE_REDUCTION_MODE,
522 &noiseReduction, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +0200523
524 uint8_t aberrationMode = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF;
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200525 requestTemplate->addEntry(ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
526 &aberrationMode, 1);
Jacopo Mondi9b361dc2019-09-04 16:18:21 +0200527
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200528 requestTemplate->addEntry(ANDROID_CONTROL_CAPTURE_INTENT,
529 &captureIntent, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200530
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200531 if (!requestTemplate->isValid()) {
Laurent Pinchart39860092019-09-05 03:12:34 +0300532 LOG(HAL, Error) << "Failed to construct request template";
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200533 delete requestTemplate;
Laurent Pinchart39860092019-09-05 03:12:34 +0300534 return nullptr;
535 }
536
Jacopo Mondifcd5a4f2019-09-04 16:18:23 +0200537 requestTemplates_[type] = requestTemplate;
538 return requestTemplate->get();
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200539}
540
541/*
542 * Inspect the stream_list to produce a list of StreamConfiguration to
543 * be use to configure the Camera.
544 */
545int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
546{
547 for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
548 camera3_stream_t *stream = stream_list->streams[i];
549
550 LOG(HAL, Info) << "Stream #" << i
551 << ", direction: " << stream->stream_type
552 << ", width: " << stream->width
553 << ", height: " << stream->height
554 << ", format: " << std::hex << stream->format;
555 }
556
557 /* Hardcode viewfinder role, collecting sizes from the stream config. */
558 if (stream_list->num_streams != 1) {
559 LOG(HAL, Error) << "Only one stream supported";
560 return -EINVAL;
561 }
562
563 StreamRoles roles = { StreamRole::Viewfinder };
564 config_ = camera_->generateConfiguration(roles);
565 if (!config_ || config_->empty()) {
566 LOG(HAL, Error) << "Failed to generate camera configuration";
567 return -EINVAL;
568 }
569
570 /* Only one stream is supported. */
571 camera3_stream_t *camera3Stream = stream_list->streams[0];
572 StreamConfiguration *streamConfiguration = &config_->at(0);
573 streamConfiguration->size.width = camera3Stream->width;
574 streamConfiguration->size.height = camera3Stream->height;
575 streamConfiguration->memoryType = ExternalMemory;
576
577 /*
578 * \todo We'll need to translate from Android defined pixel format codes
579 * to the libcamera image format codes. For now, do not change the
580 * format returned from Camera::generateConfiguration().
581 */
582
583 switch (config_->validate()) {
584 case CameraConfiguration::Valid:
585 break;
586 case CameraConfiguration::Adjusted:
587 LOG(HAL, Info) << "Camera configuration adjusted";
588 config_.reset();
589 return -EINVAL;
590 case CameraConfiguration::Invalid:
591 LOG(HAL, Info) << "Camera configuration invalid";
592 config_.reset();
593 return -EINVAL;
594 }
595
596 camera3Stream->max_buffers = streamConfiguration->bufferCount;
597
598 /*
599 * Once the CameraConfiguration has been adjusted/validated
600 * it can be applied to the camera.
601 */
602 int ret = camera_->configure(config_.get());
603 if (ret) {
604 LOG(HAL, Error) << "Failed to configure camera '"
605 << camera_->name() << "'";
606 return ret;
607 }
608
609 return 0;
610}
611
612int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
613{
614 StreamConfiguration *streamConfiguration = &config_->at(0);
615 Stream *stream = streamConfiguration->stream();
616
617 if (camera3Request->num_output_buffers != 1) {
618 LOG(HAL, Error) << "Invalid number of output buffers: "
619 << camera3Request->num_output_buffers;
620 return -EINVAL;
621 }
622
623 /* Start the camera if that's the first request we handle. */
624 if (!running_) {
625 int ret = camera_->allocateBuffers();
626 if (ret) {
627 LOG(HAL, Error) << "Failed to allocate buffers";
628 return ret;
629 }
630
631 ret = camera_->start();
632 if (ret) {
633 LOG(HAL, Error) << "Failed to start camera";
634 camera_->freeBuffers();
635 return ret;
636 }
637
638 running_ = true;
639 }
640
641 /*
642 * Queue a request for the Camera with the provided dmabuf file
643 * descriptors.
644 */
645 const camera3_stream_buffer_t *camera3Buffers =
646 camera3Request->output_buffers;
647
648 /*
649 * Save the request descriptors for use at completion time.
650 * The descriptor and the associated memory reserved here are freed
651 * at request complete time.
652 */
653 Camera3RequestDescriptor *descriptor =
654 new Camera3RequestDescriptor(camera3Request->frame_number,
655 camera3Request->num_output_buffers);
656 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
657 /*
658 * Keep track of which stream the request belongs to and store
659 * the native buffer handles.
660 *
661 * \todo Currently we only support one capture buffer. Copy
662 * all of them to be ready once we'll support more.
663 */
664 descriptor->buffers[i].stream = camera3Buffers[i].stream;
665 descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
666 }
667
668 /*
669 * Create a libcamera buffer using the dmabuf descriptors of the first
670 * and (currently) only supported request buffer.
671 */
672 const buffer_handle_t camera3Handle = *camera3Buffers[0].buffer;
673 std::array<int, 3> fds = {
674 camera3Handle->data[0],
675 camera3Handle->data[1],
676 camera3Handle->data[2],
677 };
678
679 std::unique_ptr<Buffer> buffer = stream->createBuffer(fds);
680 if (!buffer) {
681 LOG(HAL, Error) << "Failed to create buffer";
682 delete descriptor;
683 return -EINVAL;
684 }
685
686 Request *request =
687 camera_->createRequest(reinterpret_cast<uint64_t>(descriptor));
688 request->addBuffer(std::move(buffer));
689
690 int ret = camera_->queueRequest(request);
691 if (ret) {
692 LOG(HAL, Error) << "Failed to queue request";
693 goto error;
694 }
695
696 return 0;
697
698error:
699 delete request;
700 delete descriptor;
701
702 return ret;
703}
704
705void CameraDevice::requestComplete(Request *request,
706 const std::map<Stream *, Buffer *> &buffers)
707{
708 Buffer *libcameraBuffer = buffers.begin()->second;
709 camera3_buffer_status status = CAMERA3_BUFFER_STATUS_OK;
Laurent Pinchart39860092019-09-05 03:12:34 +0300710 std::unique_ptr<CameraMetadata> resultMetadata;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200711
712 if (request->status() != Request::RequestComplete) {
713 LOG(HAL, Error) << "Request not succesfully completed: "
714 << request->status();
715 status = CAMERA3_BUFFER_STATUS_ERROR;
716 }
717
718 /* Prepare to call back the Android camera stack. */
719 Camera3RequestDescriptor *descriptor =
720 reinterpret_cast<Camera3RequestDescriptor *>(request->cookie());
721
722 camera3_capture_result_t captureResult = {};
723 captureResult.frame_number = descriptor->frameNumber;
724 captureResult.num_output_buffers = descriptor->numBuffers;
725 for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
726 /*
727 * \todo Currently we only support one capture buffer. Prepare
728 * all of them to be ready once we'll support more.
729 */
730 descriptor->buffers[i].acquire_fence = -1;
731 descriptor->buffers[i].release_fence = -1;
732 descriptor->buffers[i].status = status;
733 }
734 captureResult.output_buffers =
735 const_cast<const camera3_stream_buffer_t *>(descriptor->buffers);
736
Laurent Pinchart39860092019-09-05 03:12:34 +0300737 if (status == CAMERA3_BUFFER_STATUS_OK) {
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200738 notifyShutter(descriptor->frameNumber,
739 libcameraBuffer->timestamp());
740
741 captureResult.partial_result = 1;
742 resultMetadata = getResultMetadata(descriptor->frameNumber,
743 libcameraBuffer->timestamp());
Laurent Pinchart39860092019-09-05 03:12:34 +0300744 captureResult.result = resultMetadata->get();
745 }
746
747 if (status == CAMERA3_BUFFER_STATUS_ERROR || !captureResult.result) {
748 /* \todo Improve error handling. In case we notify an error
749 * because the metadata generation fails, a shutter event has
750 * already been notified for this frame number before the error
751 * is here signalled. Make sure the error path plays well with
752 * the camera stack state machine.
753 */
754 notifyError(descriptor->frameNumber,
755 descriptor->buffers[0].stream);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200756 }
757
758 callbacks_->process_capture_result(callbacks_, &captureResult);
759
760 delete descriptor;
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200761}
762
763void CameraDevice::notifyShutter(uint32_t frameNumber, uint64_t timestamp)
764{
765 camera3_notify_msg_t notify = {};
766
767 notify.type = CAMERA3_MSG_SHUTTER;
768 notify.message.shutter.frame_number = frameNumber;
769 notify.message.shutter.timestamp = timestamp;
770
771 callbacks_->notify(callbacks_, &notify);
772}
773
774void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream)
775{
776 camera3_notify_msg_t notify = {};
777
778 notify.type = CAMERA3_MSG_ERROR;
779 notify.message.error.error_stream = stream;
780 notify.message.error.frame_number = frameNumber;
781 notify.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
782
783 callbacks_->notify(callbacks_, &notify);
784}
785
786/*
787 * Produce a set of fixed result metadata.
788 */
Laurent Pinchart39860092019-09-05 03:12:34 +0300789std::unique_ptr<CameraMetadata> CameraDevice::getResultMetadata(int frame_number,
790 int64_t timestamp)
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200791{
Jacopo Mondi48504ba2019-09-04 16:18:19 +0200792 /*
793 * \todo Keep this in sync with the actual number of entries.
Laurent Pinchart39860092019-09-05 03:12:34 +0300794 * Currently: 12 entries, 36 bytes
Jacopo Mondi48504ba2019-09-04 16:18:19 +0200795 */
Laurent Pinchart39860092019-09-05 03:12:34 +0300796 std::unique_ptr<CameraMetadata> resultMetadata =
797 utils::make_unique<CameraMetadata>(15, 50);
798 if (!resultMetadata->isValid()) {
799 LOG(HAL, Error) << "Failed to allocate static metadata";
800 return nullptr;
801 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200802
803 const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300804 resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200805
806 const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300807 resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200808
809 uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300810 resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200811
812 const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED;
Laurent Pinchart39860092019-09-05 03:12:34 +0300813 resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200814
815 const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300816 resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200817
818 const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;
Laurent Pinchart39860092019-09-05 03:12:34 +0300819 resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200820
821 int32_t sensorSizes[] = {
822 0, 0, 2560, 1920,
823 };
Laurent Pinchart39860092019-09-05 03:12:34 +0300824 resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200825
Laurent Pinchart39860092019-09-05 03:12:34 +0300826 resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200827
828 /* 33.3 msec */
829 const int64_t rolling_shutter_skew = 33300000;
Laurent Pinchart39860092019-09-05 03:12:34 +0300830 resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
831 &rolling_shutter_skew, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200832
833 /* 16.6 msec */
834 const int64_t exposure_time = 16600000;
Laurent Pinchart39860092019-09-05 03:12:34 +0300835 resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME,
836 &exposure_time, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200837
838 const uint8_t lens_shading_map_mode =
839 ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF;
Laurent Pinchart39860092019-09-05 03:12:34 +0300840 resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
841 &lens_shading_map_mode, 1);
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200842
843 const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE;
Laurent Pinchart39860092019-09-05 03:12:34 +0300844 resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER,
845 &scene_flicker, 1);
846
847 /*
848 * Return the result metadata pack even is not valid: get() will return
849 * nullptr.
850 */
851 if (!resultMetadata->isValid()) {
852 LOG(HAL, Error) << "Failed to construct result metadata";
853 }
Jacopo Mondi667d8ea2019-05-10 17:40:02 +0200854
855 return resultMetadata;
856}