blob: 822862b660b0378ad11b23d5dd08615101903b4b [file] [log] [blame]
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01001/*
Biswarup Pal6152a302023-12-19 12:44:09 +00002 * Copyright 2023 The Android Open Source Project
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// #define LOG_NDEBUG 0
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010018#define LOG_TAG "MetadataUtil"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010019
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010020#include "MetadataUtil.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010021
22#include <algorithm>
23#include <cstdint>
24#include <iterator>
25#include <memory>
Vadim Caen11dfd932024-03-05 09:57:20 +010026#include <optional>
Vadim Caenc0aff132024-03-12 17:20:07 +010027#include <string>
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010028#include <utility>
29#include <variant>
30#include <vector>
31
32#include "CameraMetadata.h"
33#include "aidl/android/hardware/camera/device/CameraMetadata.h"
34#include "log/log.h"
35#include "system/camera_metadata.h"
Jan Sebechlebskyad8d35f2024-02-05 11:58:59 +010036#include "util/Util.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010037#include "utils/Errors.h"
38
39namespace android {
40namespace companion {
41namespace virtualcamera {
42
43namespace {
44
45using ::android::hardware::camera::common::helper::CameraMetadata;
46
47template <typename To, typename From>
48std::vector<To> convertTo(const std::vector<From>& from) {
49 std::vector<To> to;
50 to.reserve(from.size());
51 std::transform(from.begin(), from.end(), std::back_inserter(to),
52 [](const From& x) { return static_cast<To>(x); });
53 return to;
54}
55
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +010056template <typename To, typename From>
57std::vector<To> asVectorOf(const From from) {
58 return std::vector<To>({static_cast<To>(from)});
59}
60
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010061} // namespace
62
63MetadataBuilder& MetadataBuilder::setSupportedHardwareLevel(
Vadim Caen11dfd932024-03-05 09:57:20 +010064 const camera_metadata_enum_android_info_supported_hardware_level_t hwLevel) {
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010065 mEntryMap[ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL] =
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +010066 asVectorOf<uint8_t>(hwLevel);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010067 return *this;
68}
69
70MetadataBuilder& MetadataBuilder::setFlashAvailable(bool flashAvailable) {
71 const uint8_t metadataVal = flashAvailable
72 ? ANDROID_FLASH_INFO_AVAILABLE_TRUE
73 : ANDROID_FLASH_INFO_AVAILABLE_FALSE;
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +010074 mEntryMap[ANDROID_FLASH_INFO_AVAILABLE] = asVectorOf<uint8_t>(metadataVal);
75 return *this;
76}
77
78MetadataBuilder& MetadataBuilder::setFlashState(
79 const camera_metadata_enum_android_flash_state_t flashState) {
80 mEntryMap[ANDROID_FLASH_STATE] = asVectorOf<uint8_t>(flashState);
81 return *this;
82}
83
84MetadataBuilder& MetadataBuilder::setFlashMode(
85 const camera_metadata_enum_android_flash_mode_t flashMode) {
86 mEntryMap[ANDROID_FLASH_MODE] = asVectorOf<uint8_t>(flashMode);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010087 return *this;
88}
89
90MetadataBuilder& MetadataBuilder::setLensFacing(
Vadim Caen11dfd932024-03-05 09:57:20 +010091 const camera_metadata_enum_android_lens_facing lensFacing) {
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +010092 mEntryMap[ANDROID_LENS_FACING] = asVectorOf<uint8_t>(lensFacing);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010093 return *this;
94}
95
Jan Sebechlebskya984ffb2024-02-01 09:12:37 +010096MetadataBuilder& MetadataBuilder::setSensorReadoutTimestamp(
97 const camera_metadata_enum_android_sensor_readout_timestamp_t
98 sensorReadoutTimestamp) {
99 mEntryMap[ANDROID_SENSOR_READOUT_TIMESTAMP] =
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100100 asVectorOf<uint8_t>(sensorReadoutTimestamp);
Jan Sebechlebskya984ffb2024-02-01 09:12:37 +0100101 return *this;
102}
103
Biswarup Pal8ad8bc52024-02-08 13:41:44 +0000104MetadataBuilder& MetadataBuilder::setAvailableFocalLengths(
105 const std::vector<float>& focalLengths) {
Biswarup Pald9be04d2024-01-31 14:35:15 +0000106 mEntryMap[ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS] = focalLengths;
107 return *this;
108}
109
Biswarup Pal8ad8bc52024-02-08 13:41:44 +0000110MetadataBuilder& MetadataBuilder::setFocalLength(float focalLength) {
111 mEntryMap[ANDROID_LENS_FOCAL_LENGTH] = asVectorOf<float>(focalLength);
112 return *this;
113}
114
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100115MetadataBuilder& MetadataBuilder::setSensorOrientation(int32_t sensorOrientation) {
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100116 mEntryMap[ANDROID_SENSOR_ORIENTATION] = asVectorOf<int32_t>(sensorOrientation);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100117 return *this;
118}
119
Jan Sebechlebskyad8d35f2024-02-05 11:58:59 +0100120MetadataBuilder& MetadataBuilder::setSensorTimestampSource(
121 const camera_metadata_enum_android_sensor_info_timestamp_source_t
122 timestampSource) {
123 mEntryMap[ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE] =
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100124 asVectorOf<uint8_t>(timestampSource);
Jan Sebechlebskyad8d35f2024-02-05 11:58:59 +0100125 return *this;
126}
127
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100128MetadataBuilder& MetadataBuilder::setSensorTimestamp(
129 std::chrono::nanoseconds timestamp) {
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100130 mEntryMap[ANDROID_SENSOR_TIMESTAMP] = asVectorOf<int64_t>(timestamp.count());
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100131 return *this;
132}
133
134MetadataBuilder& MetadataBuilder::setAvailableFaceDetectModes(
135 const std::vector<camera_metadata_enum_android_statistics_face_detect_mode_t>&
136 faceDetectModes) {
137 mEntryMap[ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES] =
138 convertTo<uint8_t>(faceDetectModes);
139 return *this;
140}
141
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100142MetadataBuilder& MetadataBuilder::setAvailableTestPatternModes(
143 const std::vector<camera_metadata_enum_android_sensor_test_pattern_mode>&
144 testPatternModes) {
145 mEntryMap[ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES] =
146 convertTo<int32_t>(testPatternModes);
147 return *this;
148}
149
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100150MetadataBuilder& MetadataBuilder::setFaceDetectMode(
151 const camera_metadata_enum_android_statistics_face_detect_mode_t
152 faceDetectMode) {
153 mEntryMap[ANDROID_STATISTICS_FACE_DETECT_MODE] =
154 asVectorOf<uint8_t>(faceDetectMode);
155 return *this;
156}
157
Jan Sebechlebskyb0119fa2023-12-04 10:29:06 +0100158MetadataBuilder& MetadataBuilder::setControlAvailableModes(
159 const std::vector<camera_metadata_enum_android_control_mode_t>&
160 availableModes) {
161 mEntryMap[ANDROID_CONTROL_AVAILABLE_MODES] =
162 convertTo<uint8_t>(availableModes);
163 return *this;
164}
165
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100166MetadataBuilder& MetadataBuilder::setControlMode(
167 const camera_metadata_enum_android_control_mode_t mode) {
168 mEntryMap[ANDROID_CONTROL_MODE] = asVectorOf<uint8_t>(mode);
169 return *this;
170}
171
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100172MetadataBuilder& MetadataBuilder::setControlAvailableSceneModes(
173 const std::vector<camera_metadata_enum_android_control_scene_mode>&
174 availableSceneModes) {
175 mEntryMap[ANDROID_CONTROL_AVAILABLE_SCENE_MODES] =
176 convertTo<uint8_t>(availableSceneModes);
177 return *this;
178}
179
Vadim Caen11dfd932024-03-05 09:57:20 +0100180MetadataBuilder& MetadataBuilder::setControlSceneMode(
181 const camera_metadata_enum_android_control_scene_mode sceneMode) {
182 mEntryMap[ANDROID_CONTROL_SCENE_MODE] = asVectorOf<uint8_t>(sceneMode);
183 return *this;
184}
185
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100186MetadataBuilder& MetadataBuilder::setControlAvailableEffects(
187 const std::vector<camera_metadata_enum_android_control_effect_mode>&
188 availableEffects) {
189 mEntryMap[ANDROID_CONTROL_AVAILABLE_EFFECTS] =
190 convertTo<uint8_t>(availableEffects);
191 return *this;
192}
193
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100194MetadataBuilder& MetadataBuilder::setControlEffectMode(
195 const camera_metadata_enum_android_control_effect_mode_t effectMode) {
196 mEntryMap[ANDROID_CONTROL_EFFECT_MODE] = asVectorOf<uint8_t>(effectMode);
197 return *this;
198}
199
200MetadataBuilder& MetadataBuilder::setControlAvailableVideoStabilizationModes(
201 const std::vector<
202 camera_metadata_enum_android_control_video_stabilization_mode_t>&
203 videoStabilizationModes) {
204 mEntryMap[ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES] =
205 convertTo<uint8_t>(videoStabilizationModes);
206 return *this;
207}
208
Vadim Caen11dfd932024-03-05 09:57:20 +0100209MetadataBuilder& MetadataBuilder::setControlVideoStabilizationMode(
210 const camera_metadata_enum_android_control_video_stabilization_mode
211 stabilizationMode) {
212 mEntryMap[ANDROID_CONTROL_VIDEO_STABILIZATION_MODE] =
213 asVectorOf<uint8_t>(stabilizationMode);
214 return *this;
215}
216
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100217MetadataBuilder& MetadataBuilder::setControlAfAvailableModes(
218 const std::vector<camera_metadata_enum_android_control_af_mode_t>&
219 availableModes) {
220 mEntryMap[ANDROID_CONTROL_AF_AVAILABLE_MODES] =
221 convertTo<uint8_t>(availableModes);
222 return *this;
223}
224
225MetadataBuilder& MetadataBuilder::setControlAfMode(
226 const camera_metadata_enum_android_control_af_mode_t mode) {
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100227 mEntryMap[ANDROID_CONTROL_AF_MODE] = asVectorOf<uint8_t>(mode);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100228 return *this;
229}
230
Vadim Caen11dfd932024-03-05 09:57:20 +0100231MetadataBuilder& MetadataBuilder::setControlAfState(
232 const camera_metadata_enum_android_control_af_state afState) {
233 mEntryMap[ANDROID_CONTROL_AF_STATE] = asVectorOf<uint8_t>(afState);
234 return *this;
235}
236
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100237// See ANDROID_CONTROL_AF_TRIGGER_MODE in CameraMetadataTag.aidl.
238MetadataBuilder& MetadataBuilder::setControlAfTrigger(
239 const camera_metadata_enum_android_control_af_trigger_t trigger) {
240 mEntryMap[ANDROID_CONTROL_AF_TRIGGER] = asVectorOf<uint8_t>(trigger);
241 return *this;
242}
243
244MetadataBuilder& MetadataBuilder::setControlAeAvailableFpsRanges(
245 const std::vector<FpsRange>& fpsRanges) {
246 std::vector<int32_t> ranges;
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100247 ranges.reserve(2 * fpsRanges.size());
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100248 for (const FpsRange fpsRange : fpsRanges) {
249 ranges.push_back(fpsRange.minFps);
250 ranges.push_back(fpsRange.maxFps);
251 }
252 mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES] = std::move(ranges);
253 return *this;
254}
255
256MetadataBuilder& MetadataBuilder::setControlAeTargetFpsRange(
Vadim Caen11dfd932024-03-05 09:57:20 +0100257 const FpsRange fpsRange) {
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100258 mEntryMap[ANDROID_CONTROL_AE_TARGET_FPS_RANGE] =
Vadim Caen11dfd932024-03-05 09:57:20 +0100259 std::vector<int32_t>({fpsRange.minFps, fpsRange.maxFps});
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100260 return *this;
261}
262
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100263MetadataBuilder& MetadataBuilder::setControlAeMode(
Vadim Caen11dfd932024-03-05 09:57:20 +0100264 const camera_metadata_enum_android_control_ae_mode_t mode) {
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100265 mEntryMap[ANDROID_CONTROL_AE_MODE] = asVectorOf<uint8_t>(mode);
266 return *this;
267}
268
269MetadataBuilder& MetadataBuilder::setControlAeAvailableModes(
270 const std::vector<camera_metadata_enum_android_control_ae_mode_t>& modes) {
271 mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_MODES] = convertTo<uint8_t>(modes);
272 return *this;
273}
274
275MetadataBuilder& MetadataBuilder::setControlAePrecaptureTrigger(
276 const camera_metadata_enum_android_control_ae_precapture_trigger_t trigger) {
277 mEntryMap[ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER] =
278 asVectorOf<uint8_t>(trigger);
279 return *this;
280}
281
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100282MetadataBuilder& MetadataBuilder::setControlMaxRegions(int32_t maxAeRegions,
283 int32_t maxAwbRegions,
284 int32_t maxAfRegions) {
285 mEntryMap[ANDROID_CONTROL_MAX_REGIONS] =
286 std::vector<int32_t>({maxAeRegions, maxAwbRegions, maxAfRegions});
287 return *this;
288}
289
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100290MetadataBuilder& MetadataBuilder::setControlAvailableAwbModes(
291 const std::vector<camera_metadata_enum_android_control_awb_mode>& awbModes) {
292 mEntryMap[ANDROID_CONTROL_AWB_AVAILABLE_MODES] = convertTo<uint8_t>(awbModes);
293 return *this;
294}
295
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100296MetadataBuilder& MetadataBuilder::setControlAwbMode(
297 const camera_metadata_enum_android_control_awb_mode awbMode) {
298 mEntryMap[ANDROID_CONTROL_AWB_MODE] = asVectorOf<uint8_t>(awbMode);
299 return *this;
300}
301
Vadim Caen11dfd932024-03-05 09:57:20 +0100302MetadataBuilder& MetadataBuilder::setControlAwbState(
303 const camera_metadata_enum_android_control_awb_state awbState) {
304 mEntryMap[ANDROID_CONTROL_AWB_STATE] = asVectorOf<uint8_t>(awbState);
305 return *this;
306}
307
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100308MetadataBuilder& MetadataBuilder::setControlAwbLockAvailable(
309 const bool awbLockAvailable) {
310 const uint8_t lockAvailable = awbLockAvailable
311 ? ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE
312 : ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
313 mEntryMap[ANDROID_CONTROL_AWB_LOCK_AVAILABLE] =
314 std::vector<uint8_t>({lockAvailable});
315 return *this;
316}
317
Vadim Caen11dfd932024-03-05 09:57:20 +0100318MetadataBuilder& MetadataBuilder::setControlAwbLock(
319 const camera_metadata_enum_android_control_awb_lock awbLock) {
320 mEntryMap[ANDROID_CONTROL_AWB_LOCK] = asVectorOf<uint8_t>(awbLock);
321 return *this;
322}
323
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100324MetadataBuilder& MetadataBuilder::setControlAeAvailableAntibandingModes(
325 const std::vector<camera_metadata_enum_android_control_ae_antibanding_mode_t>&
326 antibandingModes) {
327 mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES] =
328 convertTo<uint8_t>(antibandingModes);
329 return *this;
330}
331
332MetadataBuilder& MetadataBuilder::setControlAeAntibandingMode(
333 const camera_metadata_enum_android_control_ae_antibanding_mode_t
334 antibandingMode) {
335 mEntryMap[ANDROID_CONTROL_AE_ANTIBANDING_MODE] =
336 asVectorOf<uint8_t>(antibandingMode);
337 return *this;
338}
339
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100340MetadataBuilder& MetadataBuilder::setControlAeLockAvailable(
341 const bool aeLockAvailable) {
342 const uint8_t lockAvailable = aeLockAvailable
343 ? ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE
344 : ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
345 mEntryMap[ANDROID_CONTROL_AE_LOCK_AVAILABLE] =
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100346 asVectorOf<uint8_t>(lockAvailable);
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100347 return *this;
348}
349
Vadim Caen11dfd932024-03-05 09:57:20 +0100350MetadataBuilder& MetadataBuilder::setControlAeLock(
351 const camera_metadata_enum_android_control_ae_lock aeLock) {
352 mEntryMap[ANDROID_CONTROL_AE_LOCK] = asVectorOf<uint8_t>(aeLock);
353 return *this;
354}
355
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100356MetadataBuilder& MetadataBuilder::setControlAeRegions(
357 const std::vector<ControlRegion>& aeRegions) {
358 std::vector<int32_t> regions;
359 regions.reserve(5 * aeRegions.size());
360 for (const ControlRegion& region : aeRegions) {
361 regions.push_back(region.x0);
362 regions.push_back(region.y0);
363 regions.push_back(region.x1);
364 regions.push_back(region.y1);
365 regions.push_back(region.weight);
366 }
367 mEntryMap[ANDROID_CONTROL_AE_REGIONS] = std::move(regions);
368 return *this;
369}
370
371MetadataBuilder& MetadataBuilder::setControlAfRegions(
372 const std::vector<ControlRegion>& afRegions) {
373 std::vector<int32_t> regions;
374 regions.reserve(5 * afRegions.size());
375 for (const ControlRegion& region : afRegions) {
376 regions.push_back(region.x0);
377 regions.push_back(region.y0);
378 regions.push_back(region.x1);
379 regions.push_back(region.y1);
380 regions.push_back(region.weight);
381 }
382 mEntryMap[ANDROID_CONTROL_AF_REGIONS] = std::move(regions);
383 return *this;
384}
385
386MetadataBuilder& MetadataBuilder::setControlAwbRegions(
387 const std::vector<ControlRegion>& awbRegions) {
388 std::vector<int32_t> regions;
389 regions.reserve(5 * awbRegions.size());
390 for (const ControlRegion& region : awbRegions) {
391 regions.push_back(region.x0);
392 regions.push_back(region.y0);
393 regions.push_back(region.x1);
394 regions.push_back(region.y1);
395 regions.push_back(region.weight);
396 }
397 mEntryMap[ANDROID_CONTROL_AWB_REGIONS] = std::move(regions);
398 return *this;
399}
400
401MetadataBuilder& MetadataBuilder::setControlCaptureIntent(
402 const camera_metadata_enum_android_control_capture_intent_t intent) {
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100403 mEntryMap[ANDROID_CONTROL_CAPTURE_INTENT] = asVectorOf<uint8_t>(intent);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100404 return *this;
405}
406
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100407MetadataBuilder& MetadataBuilder::setCropRegion(const int32_t x, const int32_t y,
408 const int32_t width,
409 const int32_t height) {
410 mEntryMap[ANDROID_SCALER_CROP_REGION] =
411 std::vector<int32_t>({x, y, width, height});
412 return *this;
413}
414
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100415MetadataBuilder& MetadataBuilder::setMaxJpegSize(const int32_t size) {
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100416 mEntryMap[ANDROID_JPEG_MAX_SIZE] = asVectorOf<int32_t>(size);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100417 return *this;
418}
419
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100420MetadataBuilder& MetadataBuilder::setMaxFrameDuration(
421 const std::chrono::nanoseconds duration) {
422 mEntryMap[ANDROID_SENSOR_INFO_MAX_FRAME_DURATION] =
423 asVectorOf<int64_t>(duration.count());
424 return *this;
425}
426
Jan Sebechlebskyad8d35f2024-02-05 11:58:59 +0100427MetadataBuilder& MetadataBuilder::setJpegAvailableThumbnailSizes(
428 const std::vector<Resolution>& thumbnailSizes) {
429 std::vector<int32_t> sizes;
430 sizes.reserve(thumbnailSizes.size() * 2);
431 for (const Resolution& resolution : thumbnailSizes) {
432 sizes.push_back(resolution.width);
433 sizes.push_back(resolution.height);
434 }
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100435 mEntryMap[ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES] = std::move(sizes);
Jan Sebechlebskyad8d35f2024-02-05 11:58:59 +0100436 return *this;
437}
438
Vadim Caenc0aff132024-03-12 17:20:07 +0100439MetadataBuilder& MetadataBuilder::setJpegGpsCoordinates(
440 const GpsCoordinates& gpsCoordinates) {
441 mEntryMap[ANDROID_JPEG_GPS_COORDINATES] =
442 std::vector<double>({gpsCoordinates.latitude, gpsCoordinates.longitude,
443 gpsCoordinates.altitude});
444
445 if (!gpsCoordinates.provider.empty()) {
446 mEntryMap[ANDROID_JPEG_GPS_PROCESSING_METHOD] = std::vector<uint8_t>{
447 gpsCoordinates.provider.begin(), gpsCoordinates.provider.end()};
448 }
449
450 if (gpsCoordinates.timestamp.has_value()) {
451 mEntryMap[ANDROID_JPEG_GPS_TIMESTAMP] =
452 asVectorOf<int64_t>(gpsCoordinates.timestamp.value());
453 }
454 return *this;
455}
456
457MetadataBuilder& MetadataBuilder::setJpegOrientation(const int32_t orientation) {
458 mEntryMap[ANDROID_JPEG_ORIENTATION] = asVectorOf<int32_t>(orientation);
459 return *this;
460}
461
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100462MetadataBuilder& MetadataBuilder::setJpegQuality(const uint8_t quality) {
463 mEntryMap[ANDROID_JPEG_QUALITY] = asVectorOf<uint8_t>(quality);
464 return *this;
465}
466
467MetadataBuilder& MetadataBuilder::setJpegThumbnailSize(const int width,
468 const int height) {
469 mEntryMap[ANDROID_JPEG_THUMBNAIL_SIZE] = std::vector<int32_t>({width, height});
470 return *this;
471}
472
473MetadataBuilder& MetadataBuilder::setJpegThumbnailQuality(const uint8_t quality) {
474 mEntryMap[ANDROID_JPEG_THUMBNAIL_QUALITY] = asVectorOf<uint8_t>(quality);
475 return *this;
476}
477
Jan Sebechlebsky8ae23592024-02-02 16:08:18 +0100478MetadataBuilder& MetadataBuilder::setMaxNumberOutputStreams(
479 const int32_t maxRawStreams, const int32_t maxProcessedStreams,
480 const int32_t maxStallStreams) {
481 mEntryMap[ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS] = std::vector<int32_t>(
482 {maxRawStreams, maxProcessedStreams, maxStallStreams});
483 return *this;
484}
485
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100486MetadataBuilder& MetadataBuilder::setSyncMaxLatency(
Vadim Caen11dfd932024-03-05 09:57:20 +0100487 const camera_metadata_enum_android_sync_max_latency latency) {
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100488 mEntryMap[ANDROID_SYNC_MAX_LATENCY] = asVectorOf<int32_t>(latency);
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100489 return *this;
490}
491
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100492MetadataBuilder& MetadataBuilder::setPipelineMaxDepth(const uint8_t maxDepth) {
493 mEntryMap[ANDROID_REQUEST_PIPELINE_MAX_DEPTH] = asVectorOf<uint8_t>(maxDepth);
494 return *this;
495}
496
497MetadataBuilder& MetadataBuilder::setPipelineDepth(const uint8_t depth) {
498 mEntryMap[ANDROID_REQUEST_PIPELINE_DEPTH] = asVectorOf<uint8_t>(depth);
499 return *this;
500}
501
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100502MetadataBuilder& MetadataBuilder::setAvailableRequestCapabilities(
503 const std::vector<camera_metadata_enum_android_request_available_capabilities_t>&
504 requestCapabilities) {
505 mEntryMap[ANDROID_REQUEST_AVAILABLE_CAPABILITIES] =
506 convertTo<uint8_t>(requestCapabilities);
507 return *this;
508}
509
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100510MetadataBuilder& MetadataBuilder::setAvailableOutputStreamConfigurations(
511 const std::vector<StreamConfiguration>& streamConfigurations) {
512 std::vector<int32_t> metadataStreamConfigs;
513 std::vector<int64_t> metadataMinFrameDurations;
514 std::vector<int64_t> metadataStallDurations;
515 metadataStreamConfigs.reserve(streamConfigurations.size());
516 metadataMinFrameDurations.reserve(streamConfigurations.size());
517 metadataStallDurations.reserve(streamConfigurations.size());
518
519 for (const auto& config : streamConfigurations) {
520 metadataStreamConfigs.push_back(config.format);
521 metadataStreamConfigs.push_back(config.width);
522 metadataStreamConfigs.push_back(config.height);
523 metadataStreamConfigs.push_back(
524 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
525
526 metadataMinFrameDurations.push_back(config.format);
527 metadataMinFrameDurations.push_back(config.width);
528 metadataMinFrameDurations.push_back(config.height);
529 metadataMinFrameDurations.push_back(config.minFrameDuration.count());
530
531 metadataStallDurations.push_back(config.format);
532 metadataStallDurations.push_back(config.width);
533 metadataStallDurations.push_back(config.height);
534 metadataStallDurations.push_back(config.minStallDuration.count());
535 }
536
537 mEntryMap[ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS] =
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100538 std::move(metadataStreamConfigs);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100539 mEntryMap[ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS] =
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100540 std::move(metadataMinFrameDurations);
541 mEntryMap[ANDROID_SCALER_AVAILABLE_STALL_DURATIONS] =
542 std::move(metadataStallDurations);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100543
544 return *this;
545}
546
Jan Sebechlebskyab378202024-02-26 10:50:42 +0100547MetadataBuilder& MetadataBuilder::setAvailableAberrationCorrectionModes(
548 const std::vector<camera_metadata_enum_android_color_correction_aberration_mode>&
549 aberrationCorectionModes) {
550 mEntryMap[ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES] =
551 convertTo<uint8_t>(aberrationCorectionModes);
552 return *this;
553}
554
Jan Sebechlebsky4be2bd02024-02-26 18:35:18 +0100555MetadataBuilder& MetadataBuilder::setAberrationCorrectionMode(
556 const camera_metadata_enum_android_color_correction_aberration_mode
557 aberrationCorrectionMode) {
558 mEntryMap[ANDROID_COLOR_CORRECTION_ABERRATION_MODE] =
559 asVectorOf<uint8_t>(aberrationCorrectionMode);
560 return *this;
561}
562
Jan Sebechlebskyab378202024-02-26 10:50:42 +0100563MetadataBuilder& MetadataBuilder::setAvailableNoiseReductionModes(
564 const std::vector<camera_metadata_enum_android_noise_reduction_mode>&
565 noiseReductionModes) {
566 mEntryMap[ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES] =
567 convertTo<uint8_t>(noiseReductionModes);
568 return *this;
569}
570
Jan Sebechlebsky4be2bd02024-02-26 18:35:18 +0100571MetadataBuilder& MetadataBuilder::setNoiseReductionMode(
Vadim Caen11dfd932024-03-05 09:57:20 +0100572 const camera_metadata_enum_android_noise_reduction_mode noiseReductionMode) {
Jan Sebechlebsky4be2bd02024-02-26 18:35:18 +0100573 mEntryMap[ANDROID_NOISE_REDUCTION_MODE] =
574 asVectorOf<uint8_t>(noiseReductionMode);
575 return *this;
576}
577
Jan Sebechlebskyab378202024-02-26 10:50:42 +0100578MetadataBuilder& MetadataBuilder::setRequestPartialResultCount(
579 const int partialResultCount) {
580 mEntryMap[ANDROID_REQUEST_PARTIAL_RESULT_COUNT] =
581 asVectorOf<int32_t>(partialResultCount);
582 return *this;
583}
584
585MetadataBuilder& MetadataBuilder::setCroppingType(
586 const camera_metadata_enum_android_scaler_cropping_type croppingType) {
587 mEntryMap[ANDROID_SCALER_CROPPING_TYPE] = asVectorOf<uint8_t>(croppingType);
588 return *this;
589}
590
591MetadataBuilder& MetadataBuilder::setMaxFaceCount(const int maxFaceCount) {
592 mEntryMap[ANDROID_STATISTICS_INFO_MAX_FACE_COUNT] =
593 asVectorOf<int32_t>(maxFaceCount);
594 return *this;
595}
596
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100597MetadataBuilder& MetadataBuilder::setAvailableMaxDigitalZoom(const float maxZoom) {
598 mEntryMap[ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM] =
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100599 asVectorOf<float>(maxZoom);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100600 return *this;
601}
602
Jan Sebechlebsky6ab07fe2023-12-05 15:23:34 +0100603MetadataBuilder& MetadataBuilder::setControlZoomRatioRange(const float min,
604 const float max) {
605 mEntryMap[ANDROID_CONTROL_ZOOM_RATIO_RANGE] = std::vector<float>({min, max});
606 return *this;
607}
608
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100609MetadataBuilder& MetadataBuilder::setSensorActiveArraySize(int x0, int y0,
610 int x1, int y1) {
611 mEntryMap[ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE] =
612 std::vector<int32_t>({x0, y0, x1, y1});
613 return *this;
614}
615
Biswarup Pald9be04d2024-01-31 14:35:15 +0000616MetadataBuilder& MetadataBuilder::setSensorPixelArraySize(int width,
617 int height) {
618 mEntryMap[ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE] =
619 std::vector<int32_t>({width, height});
620 return *this;
621}
622
623MetadataBuilder& MetadataBuilder::setSensorPhysicalSize(float width,
624 float height) {
625 mEntryMap[ANDROID_SENSOR_INFO_PHYSICAL_SIZE] =
626 std::vector<float>({width, height});
627 return *this;
628}
629
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100630MetadataBuilder& MetadataBuilder::setControlAeCompensationRange(int32_t min,
631 int32_t max) {
632 mEntryMap[ANDROID_CONTROL_AE_COMPENSATION_RANGE] =
633 std::vector<int32_t>({min, max});
634 return *this;
635}
636
637MetadataBuilder& MetadataBuilder::setControlAeCompensationStep(
638 const camera_metadata_rational step) {
639 mEntryMap[ANDROID_CONTROL_AE_COMPENSATION_STEP] =
Jan Sebechlebskyc3e1a632024-02-06 14:19:05 +0100640 asVectorOf<camera_metadata_rational>(step);
641 return *this;
642}
643
644MetadataBuilder& MetadataBuilder::setControlAeExposureCompensation(
645 const int32_t exposureCompensation) {
646 mEntryMap[ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION] =
647 asVectorOf<int32_t>(exposureCompensation);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100648 return *this;
649}
650
Vadim Caen11dfd932024-03-05 09:57:20 +0100651MetadataBuilder& MetadataBuilder::setControlAeState(
652 const camera_metadata_enum_android_control_ae_state aeState) {
653 mEntryMap[ANDROID_CONTROL_AE_STATE] = asVectorOf<uint8_t>(aeState);
654 return *this;
655}
656
657MetadataBuilder& MetadataBuilder::setStatisticsSceneFlicker(
658 const camera_metadata_enum_android_statistics_scene_flicker sceneFlicker) {
659 mEntryMap[ANDROID_STATISTICS_SCENE_FLICKER] =
660 asVectorOf<uint8_t>(sceneFlicker);
661 return *this;
662}
663
664MetadataBuilder& MetadataBuilder::setStatisticsHotPixelMapMode(
665 const camera_metadata_enum_android_statistics_hot_pixel_map_mode
666 hotPixelMapMode) {
667 mEntryMap[ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE] =
668 asVectorOf<uint8_t>(hotPixelMapMode);
669 return *this;
670}
671
672MetadataBuilder& MetadataBuilder::setStatisticsLensShadingMapMode(
673 const camera_metadata_enum_android_statistics_lens_shading_map_mode
674 lensShadingMapMode) {
675 mEntryMap[ANDROID_STATISTICS_LENS_SHADING_MAP_MODE] =
676 asVectorOf<uint8_t>(lensShadingMapMode);
677 return *this;
678}
679
680MetadataBuilder& MetadataBuilder::setLensOpticalStabilizationMode(
681 const camera_metadata_enum_android_lens_optical_stabilization_mode_t
682 opticalStabilizationMode) {
683 mEntryMap[ANDROID_LENS_OPTICAL_STABILIZATION_MODE] =
684 asVectorOf<uint8_t>(opticalStabilizationMode);
685 return *this;
686}
687
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100688MetadataBuilder& MetadataBuilder::setAvailableRequestKeys(
689 const std::vector<int32_t>& keys) {
690 mEntryMap[ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS] = keys;
691 return *this;
692}
693
694MetadataBuilder& MetadataBuilder::setAvailableResultKeys(
695 const std::vector<int32_t>& keys) {
696 mEntryMap[ANDROID_REQUEST_AVAILABLE_RESULT_KEYS] = keys;
697 return *this;
698}
699
700MetadataBuilder& MetadataBuilder::setAvailableCapabilities(
701 const std::vector<camera_metadata_enum_android_request_available_capabilities_t>&
702 capabilities) {
703 mEntryMap[ANDROID_REQUEST_AVAILABLE_CAPABILITIES] =
704 convertTo<uint8_t>(capabilities);
705 return *this;
706}
707
708MetadataBuilder& MetadataBuilder::setAvailableCharacteristicKeys(
709 const std::vector<camera_metadata_tag_t>& keys) {
710 mEntryMap[ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS] =
711 convertTo<int32_t>(keys);
712 return *this;
713}
714
715MetadataBuilder& MetadataBuilder::setAvailableCharacteristicKeys() {
Jan Sebechlebskyad8d35f2024-02-05 11:58:59 +0100716 mExtendWithAvailableCharacteristicsKeys = true;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100717 return *this;
718}
719
720std::unique_ptr<aidl::android::hardware::camera::device::CameraMetadata>
Jan Sebechlebskyad8d35f2024-02-05 11:58:59 +0100721MetadataBuilder::build() {
722 if (mExtendWithAvailableCharacteristicsKeys) {
723 std::vector<camera_metadata_tag_t> availableKeys;
724 availableKeys.reserve(mEntryMap.size());
725 for (const auto& [key, _] : mEntryMap) {
726 if (key != ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS) {
727 availableKeys.push_back(key);
728 }
729 }
730 setAvailableCharacteristicKeys(availableKeys);
731 }
732
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100733 CameraMetadata metadataHelper;
734 for (const auto& entry : mEntryMap) {
735 status_t ret = std::visit(
736 [&](auto&& arg) {
737 return metadataHelper.update(entry.first, arg.data(), arg.size());
738 },
739 entry.second);
740 if (ret != NO_ERROR) {
741 ALOGE("Failed to update metadata with key %d - %s: %s", entry.first,
742 get_camera_metadata_tag_name(entry.first),
743 ::android::statusToString(ret).c_str());
744 return nullptr;
745 }
746 }
747
748 const camera_metadata_t* metadata = metadataHelper.getAndLock();
749 if (metadata == nullptr) {
750 ALOGE(
751 "Failure when constructing metadata -> CameraMetadata helper returned "
752 "nullptr");
753 return nullptr;
754 }
755
756 auto aidlMetadata =
757 std::make_unique<aidl::android::hardware::camera::device::CameraMetadata>();
758 const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(metadata);
759 aidlMetadata->metadata.assign(data_ptr,
760 data_ptr + get_camera_metadata_size(metadata));
761 metadataHelper.unlock(metadata);
762
763 return aidlMetadata;
764}
765
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100766std::optional<int32_t> getJpegQuality(
767 const aidl::android::hardware::camera::device::CameraMetadata& cameraMetadata) {
768 auto metadata =
769 reinterpret_cast<const camera_metadata_t*>(cameraMetadata.metadata.data());
770
771 camera_metadata_ro_entry_t entry;
772 if (find_camera_metadata_ro_entry(metadata, ANDROID_JPEG_QUALITY, &entry) !=
773 OK) {
774 return std::nullopt;
775 }
776
777 return *entry.data.i32;
778}
779
Vadim Caenc0aff132024-03-12 17:20:07 +0100780int32_t getJpegOrientation(
781 const aidl::android::hardware::camera::device::CameraMetadata& cameraMetadata) {
782 auto metadata =
783 reinterpret_cast<const camera_metadata_t*>(cameraMetadata.metadata.data());
784
785 camera_metadata_ro_entry_t entry;
786 if (find_camera_metadata_ro_entry(metadata, ANDROID_JPEG_ORIENTATION,
787 &entry) != OK) {
788 return 0;
789 }
790
791 return *entry.data.i32;
792}
793
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100794std::optional<Resolution> getJpegThumbnailSize(
795 const aidl::android::hardware::camera::device::CameraMetadata& cameraMetadata) {
796 auto metadata =
797 reinterpret_cast<const camera_metadata_t*>(cameraMetadata.metadata.data());
798
799 camera_metadata_ro_entry_t entry;
800 if (find_camera_metadata_ro_entry(metadata, ANDROID_JPEG_THUMBNAIL_SIZE,
801 &entry) != OK) {
802 return std::nullopt;
803 }
804
805 return Resolution(entry.data.i32[0], entry.data.i32[1]);
806}
807
808std::optional<int32_t> getJpegThumbnailQuality(
809 const aidl::android::hardware::camera::device::CameraMetadata& cameraMetadata) {
810 auto metadata =
811 reinterpret_cast<const camera_metadata_t*>(cameraMetadata.metadata.data());
812
813 camera_metadata_ro_entry_t entry;
814 if (find_camera_metadata_ro_entry(metadata, ANDROID_JPEG_THUMBNAIL_QUALITY,
815 &entry) != OK) {
816 return std::nullopt;
817 }
818
819 return *entry.data.i32;
820}
821
822std::vector<Resolution> getJpegAvailableThumbnailSizes(
823 const aidl::android::hardware::camera::device::CameraMetadata& cameraMetadata) {
824 auto metadata =
825 reinterpret_cast<const camera_metadata_t*>(cameraMetadata.metadata.data());
826
827 camera_metadata_ro_entry_t entry;
828 if (find_camera_metadata_ro_entry(
829 metadata, ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, &entry) != OK) {
830 return {};
831 }
832
833 std::vector<Resolution> thumbnailSizes;
834 thumbnailSizes.reserve(entry.count / 2);
835 for (int i = 0; i < entry.count; i += 2) {
836 thumbnailSizes.emplace_back(entry.data.i32[i], entry.data.i32[i + 1]);
837 }
838 return thumbnailSizes;
839}
840
Vadim Caen11dfd932024-03-05 09:57:20 +0100841std::optional<FpsRange> getFpsRange(
842 const aidl::android::hardware::camera::device::CameraMetadata& cameraMetadata) {
843 auto metadata =
844 reinterpret_cast<const camera_metadata_t*>(cameraMetadata.metadata.data());
845
846 camera_metadata_ro_entry_t entry;
847 if (find_camera_metadata_ro_entry(
848 metadata, ANDROID_CONTROL_AE_TARGET_FPS_RANGE, &entry) != OK ||
849 entry.count != 2) {
850 return {};
851 }
852
853 FpsRange range{.minFps = entry.data.i32[0], .maxFps = entry.data.i32[1]};
854 return range;
855}
856
857std::optional<camera_metadata_enum_android_control_capture_intent>
858getCaptureIntent(const aidl::android::hardware::camera::device::CameraMetadata&
859 cameraMetadata) {
860 auto metadata =
861 reinterpret_cast<const camera_metadata_t*>(cameraMetadata.metadata.data());
862
863 camera_metadata_ro_entry_t entry;
864 if (find_camera_metadata_ro_entry(metadata, ANDROID_CONTROL_CAPTURE_INTENT,
865 &entry) != OK) {
866 return {};
867 }
868
869 return static_cast<camera_metadata_enum_android_control_capture_intent>(
870 entry.data.u8[0]);
871}
872
Vadim Caenc0aff132024-03-12 17:20:07 +0100873std::optional<GpsCoordinates> getGpsCoordinates(
874 const aidl::android::hardware::camera::device::CameraMetadata& cameraMetadata) {
875 auto metadata =
876 reinterpret_cast<const camera_metadata_t*>(cameraMetadata.metadata.data());
877
878 camera_metadata_ro_entry_t entry;
879 if (find_camera_metadata_ro_entry(metadata, ANDROID_JPEG_GPS_COORDINATES,
880 &entry) != OK) {
881 return std::nullopt;
882 }
883
884 GpsCoordinates coordinates{.latitude = entry.data.d[0],
885 .longitude = entry.data.d[1],
886 .altitude = entry.data.d[2]};
887
888 if (find_camera_metadata_ro_entry(metadata, ANDROID_JPEG_GPS_TIMESTAMP,
889 &entry) == OK) {
890 coordinates.timestamp = entry.data.i64[0];
891 }
892
893 // According to types.hal, the string describing the GPS processing method has
894 // a 32 characters size
895 static constexpr float kGpsProviderStringLength = 32;
896 if (find_camera_metadata_ro_entry(
897 metadata, ANDROID_JPEG_GPS_PROCESSING_METHOD, &entry) == OK) {
898 coordinates.provider.assign(
899 reinterpret_cast<const char*>(entry.data.u8),
900 std::min(entry.count, static_cast<size_t>(kGpsProviderStringLength)));
901 }
902
903 return coordinates;
904}
905
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100906std::optional<camera_metadata_enum_android_lens_facing> getLensFacing(
907 const aidl::android::hardware::camera::device::CameraMetadata& cameraMetadata) {
908 auto metadata =
909 reinterpret_cast<const camera_metadata_t*>(cameraMetadata.metadata.data());
910
911 camera_metadata_ro_entry_t entry;
912 if (find_camera_metadata_ro_entry(metadata, ANDROID_LENS_FACING, &entry) !=
913 OK) {
914 return std::nullopt;
915 }
916
917 return static_cast<camera_metadata_enum_android_lens_facing>(entry.data.u8[0]);
918}
919
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100920} // namespace virtualcamera
921} // namespace companion
922} // namespace android