blob: c2daa3baeff3691aa9215eb53be3a8f011fb3015 [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
18#define LOG_TAG "MetadataBuilder"
19
20#include "MetadataBuilder.h"
21
22#include <algorithm>
23#include <cstdint>
24#include <iterator>
25#include <memory>
26#include <utility>
27#include <variant>
28#include <vector>
29
30#include "CameraMetadata.h"
31#include "aidl/android/hardware/camera/device/CameraMetadata.h"
32#include "log/log.h"
33#include "system/camera_metadata.h"
34#include "utils/Errors.h"
35
36namespace android {
37namespace companion {
38namespace virtualcamera {
39
40namespace {
41
42using ::android::hardware::camera::common::helper::CameraMetadata;
43
44template <typename To, typename From>
45std::vector<To> convertTo(const std::vector<From>& from) {
46 std::vector<To> to;
47 to.reserve(from.size());
48 std::transform(from.begin(), from.end(), std::back_inserter(to),
49 [](const From& x) { return static_cast<To>(x); });
50 return to;
51}
52
53} // namespace
54
55MetadataBuilder& MetadataBuilder::setSupportedHardwareLevel(
56 camera_metadata_enum_android_info_supported_hardware_level_t hwLevel) {
57 mEntryMap[ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL] =
58 std::vector<uint8_t>({static_cast<uint8_t>(hwLevel)});
59 return *this;
60}
61
62MetadataBuilder& MetadataBuilder::setFlashAvailable(bool flashAvailable) {
63 const uint8_t metadataVal = flashAvailable
64 ? ANDROID_FLASH_INFO_AVAILABLE_TRUE
65 : ANDROID_FLASH_INFO_AVAILABLE_FALSE;
66 mEntryMap[ANDROID_FLASH_INFO_AVAILABLE] = std::vector<uint8_t>({metadataVal});
67 return *this;
68}
69
70MetadataBuilder& MetadataBuilder::setLensFacing(
71 camera_metadata_enum_android_lens_facing lensFacing) {
72 mEntryMap[ANDROID_LENS_FACING] =
73 std::vector<uint8_t>({static_cast<uint8_t>(lensFacing)});
74 return *this;
75}
76
Jan Sebechlebskya984ffb2024-02-01 09:12:37 +010077MetadataBuilder& MetadataBuilder::setSensorReadoutTimestamp(
78 const camera_metadata_enum_android_sensor_readout_timestamp_t
79 sensorReadoutTimestamp) {
80 mEntryMap[ANDROID_SENSOR_READOUT_TIMESTAMP] =
81 std::vector<uint8_t>({static_cast<uint8_t>(sensorReadoutTimestamp)});
82 return *this;
83}
84
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010085MetadataBuilder& MetadataBuilder::setSensorOrientation(int32_t sensorOrientation) {
86 mEntryMap[ANDROID_SENSOR_ORIENTATION] =
87 std::vector<int32_t>({sensorOrientation});
88 return *this;
89}
90
91MetadataBuilder& MetadataBuilder::setSensorTimestamp(
92 std::chrono::nanoseconds timestamp) {
93 mEntryMap[ANDROID_SENSOR_TIMESTAMP] =
94 std::vector<int64_t>({timestamp.count()});
95 return *this;
96}
97
98MetadataBuilder& MetadataBuilder::setAvailableFaceDetectModes(
99 const std::vector<camera_metadata_enum_android_statistics_face_detect_mode_t>&
100 faceDetectModes) {
101 mEntryMap[ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES] =
102 convertTo<uint8_t>(faceDetectModes);
103 return *this;
104}
105
Jan Sebechlebskyb0119fa2023-12-04 10:29:06 +0100106MetadataBuilder& MetadataBuilder::setControlAvailableModes(
107 const std::vector<camera_metadata_enum_android_control_mode_t>&
108 availableModes) {
109 mEntryMap[ANDROID_CONTROL_AVAILABLE_MODES] =
110 convertTo<uint8_t>(availableModes);
111 return *this;
112}
113
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100114MetadataBuilder& MetadataBuilder::setControlAvailableSceneModes(
115 const std::vector<camera_metadata_enum_android_control_scene_mode>&
116 availableSceneModes) {
117 mEntryMap[ANDROID_CONTROL_AVAILABLE_SCENE_MODES] =
118 convertTo<uint8_t>(availableSceneModes);
119 return *this;
120}
121
122MetadataBuilder& MetadataBuilder::setControlAvailableEffects(
123 const std::vector<camera_metadata_enum_android_control_effect_mode>&
124 availableEffects) {
125 mEntryMap[ANDROID_CONTROL_AVAILABLE_EFFECTS] =
126 convertTo<uint8_t>(availableEffects);
127 return *this;
128}
129
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100130MetadataBuilder& MetadataBuilder::setControlAfAvailableModes(
131 const std::vector<camera_metadata_enum_android_control_af_mode_t>&
132 availableModes) {
133 mEntryMap[ANDROID_CONTROL_AF_AVAILABLE_MODES] =
134 convertTo<uint8_t>(availableModes);
135 return *this;
136}
137
138MetadataBuilder& MetadataBuilder::setControlAfMode(
139 const camera_metadata_enum_android_control_af_mode_t mode) {
140 mEntryMap[ANDROID_CONTROL_AF_MODE] =
141 std::vector<uint8_t>({static_cast<uint8_t>(mode)});
142 return *this;
143}
144
145MetadataBuilder& MetadataBuilder::setControlAeAvailableFpsRange(
146 const int32_t minFps, const int32_t maxFps) {
147 mEntryMap[ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES] =
148 std::vector<int32_t>({minFps, maxFps});
149 return *this;
150}
151
152MetadataBuilder& MetadataBuilder::setControlMaxRegions(int32_t maxAeRegions,
153 int32_t maxAwbRegions,
154 int32_t maxAfRegions) {
155 mEntryMap[ANDROID_CONTROL_MAX_REGIONS] =
156 std::vector<int32_t>({maxAeRegions, maxAwbRegions, maxAfRegions});
157 return *this;
158}
159
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100160MetadataBuilder& MetadataBuilder::setControlAvailableAwbModes(
161 const std::vector<camera_metadata_enum_android_control_awb_mode>& awbModes) {
162 mEntryMap[ANDROID_CONTROL_AWB_AVAILABLE_MODES] = convertTo<uint8_t>(awbModes);
163 return *this;
164}
165
166MetadataBuilder& MetadataBuilder::setControlAwbLockAvailable(
167 const bool awbLockAvailable) {
168 const uint8_t lockAvailable = awbLockAvailable
169 ? ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE
170 : ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE;
171 mEntryMap[ANDROID_CONTROL_AWB_LOCK_AVAILABLE] =
172 std::vector<uint8_t>({lockAvailable});
173 return *this;
174}
175
176MetadataBuilder& MetadataBuilder::setControlAeLockAvailable(
177 const bool aeLockAvailable) {
178 const uint8_t lockAvailable = aeLockAvailable
179 ? ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE
180 : ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE;
181 mEntryMap[ANDROID_CONTROL_AE_LOCK_AVAILABLE] =
182 std::vector<uint8_t>({lockAvailable});
183 return *this;
184}
185
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100186MetadataBuilder& MetadataBuilder::setControlAeRegions(
187 const std::vector<ControlRegion>& aeRegions) {
188 std::vector<int32_t> regions;
189 regions.reserve(5 * aeRegions.size());
190 for (const ControlRegion& region : aeRegions) {
191 regions.push_back(region.x0);
192 regions.push_back(region.y0);
193 regions.push_back(region.x1);
194 regions.push_back(region.y1);
195 regions.push_back(region.weight);
196 }
197 mEntryMap[ANDROID_CONTROL_AE_REGIONS] = std::move(regions);
198 return *this;
199}
200
201MetadataBuilder& MetadataBuilder::setControlAfRegions(
202 const std::vector<ControlRegion>& afRegions) {
203 std::vector<int32_t> regions;
204 regions.reserve(5 * afRegions.size());
205 for (const ControlRegion& region : afRegions) {
206 regions.push_back(region.x0);
207 regions.push_back(region.y0);
208 regions.push_back(region.x1);
209 regions.push_back(region.y1);
210 regions.push_back(region.weight);
211 }
212 mEntryMap[ANDROID_CONTROL_AF_REGIONS] = std::move(regions);
213 return *this;
214}
215
216MetadataBuilder& MetadataBuilder::setControlAwbRegions(
217 const std::vector<ControlRegion>& awbRegions) {
218 std::vector<int32_t> regions;
219 regions.reserve(5 * awbRegions.size());
220 for (const ControlRegion& region : awbRegions) {
221 regions.push_back(region.x0);
222 regions.push_back(region.y0);
223 regions.push_back(region.x1);
224 regions.push_back(region.y1);
225 regions.push_back(region.weight);
226 }
227 mEntryMap[ANDROID_CONTROL_AWB_REGIONS] = std::move(regions);
228 return *this;
229}
230
231MetadataBuilder& MetadataBuilder::setControlCaptureIntent(
232 const camera_metadata_enum_android_control_capture_intent_t intent) {
233 mEntryMap[ANDROID_CONTROL_CAPTURE_INTENT] =
234 std::vector<uint8_t>({static_cast<uint8_t>(intent)});
235 return *this;
236}
237
238MetadataBuilder& MetadataBuilder::setMaxJpegSize(const int32_t size) {
239 mEntryMap[ANDROID_JPEG_MAX_SIZE] = std::vector<int32_t>({size});
240 return *this;
241}
242
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100243MetadataBuilder& MetadataBuilder::setSyncMaxLatency(
244 camera_metadata_enum_android_sync_max_latency latency) {
245 mEntryMap[ANDROID_SYNC_MAX_LATENCY] =
246 std::vector<int32_t>({static_cast<int32_t>(latency)});
247 return *this;
248}
249
250MetadataBuilder& MetadataBuilder::setAvailableRequestCapabilities(
251 const std::vector<camera_metadata_enum_android_request_available_capabilities_t>&
252 requestCapabilities) {
253 mEntryMap[ANDROID_REQUEST_AVAILABLE_CAPABILITIES] =
254 convertTo<uint8_t>(requestCapabilities);
255 return *this;
256}
257
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100258MetadataBuilder& MetadataBuilder::setAvailableOutputStreamConfigurations(
259 const std::vector<StreamConfiguration>& streamConfigurations) {
260 std::vector<int32_t> metadataStreamConfigs;
261 std::vector<int64_t> metadataMinFrameDurations;
262 std::vector<int64_t> metadataStallDurations;
263 metadataStreamConfigs.reserve(streamConfigurations.size());
264 metadataMinFrameDurations.reserve(streamConfigurations.size());
265 metadataStallDurations.reserve(streamConfigurations.size());
266
267 for (const auto& config : streamConfigurations) {
268 metadataStreamConfigs.push_back(config.format);
269 metadataStreamConfigs.push_back(config.width);
270 metadataStreamConfigs.push_back(config.height);
271 metadataStreamConfigs.push_back(
272 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
273
274 metadataMinFrameDurations.push_back(config.format);
275 metadataMinFrameDurations.push_back(config.width);
276 metadataMinFrameDurations.push_back(config.height);
277 metadataMinFrameDurations.push_back(config.minFrameDuration.count());
278
279 metadataStallDurations.push_back(config.format);
280 metadataStallDurations.push_back(config.width);
281 metadataStallDurations.push_back(config.height);
282 metadataStallDurations.push_back(config.minStallDuration.count());
283 }
284
285 mEntryMap[ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS] =
286 metadataStreamConfigs;
287 mEntryMap[ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS] =
288 metadataMinFrameDurations;
Biswarup Pal6152a302023-12-19 12:44:09 +0000289 mEntryMap[ANDROID_SCALER_AVAILABLE_STALL_DURATIONS] = metadataStallDurations;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100290
291 return *this;
292}
293
294MetadataBuilder& MetadataBuilder::setAvailableMaxDigitalZoom(const float maxZoom) {
295 mEntryMap[ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM] =
Jan Sebechlebsky4425a732024-01-31 11:31:54 +0100296 std::vector<float>({maxZoom});
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100297 return *this;
298}
299
Jan Sebechlebsky6ab07fe2023-12-05 15:23:34 +0100300MetadataBuilder& MetadataBuilder::setControlZoomRatioRange(const float min,
301 const float max) {
302 mEntryMap[ANDROID_CONTROL_ZOOM_RATIO_RANGE] = std::vector<float>({min, max});
303 return *this;
304}
305
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100306MetadataBuilder& MetadataBuilder::setSensorActiveArraySize(int x0, int y0,
307 int x1, int y1) {
308 mEntryMap[ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE] =
309 std::vector<int32_t>({x0, y0, x1, y1});
310 return *this;
311}
312
313MetadataBuilder& MetadataBuilder::setControlAeCompensationRange(int32_t min,
314 int32_t max) {
315 mEntryMap[ANDROID_CONTROL_AE_COMPENSATION_RANGE] =
316 std::vector<int32_t>({min, max});
317 return *this;
318}
319
320MetadataBuilder& MetadataBuilder::setControlAeCompensationStep(
321 const camera_metadata_rational step) {
322 mEntryMap[ANDROID_CONTROL_AE_COMPENSATION_STEP] =
323 std::vector<camera_metadata_rational>({step});
324 return *this;
325}
326
327MetadataBuilder& MetadataBuilder::setAvailableRequestKeys(
328 const std::vector<int32_t>& keys) {
329 mEntryMap[ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS] = keys;
330 return *this;
331}
332
333MetadataBuilder& MetadataBuilder::setAvailableResultKeys(
334 const std::vector<int32_t>& keys) {
335 mEntryMap[ANDROID_REQUEST_AVAILABLE_RESULT_KEYS] = keys;
336 return *this;
337}
338
339MetadataBuilder& MetadataBuilder::setAvailableCapabilities(
340 const std::vector<camera_metadata_enum_android_request_available_capabilities_t>&
341 capabilities) {
342 mEntryMap[ANDROID_REQUEST_AVAILABLE_CAPABILITIES] =
343 convertTo<uint8_t>(capabilities);
344 return *this;
345}
346
347MetadataBuilder& MetadataBuilder::setAvailableCharacteristicKeys(
348 const std::vector<camera_metadata_tag_t>& keys) {
349 mEntryMap[ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS] =
350 convertTo<int32_t>(keys);
351 return *this;
352}
353
354MetadataBuilder& MetadataBuilder::setAvailableCharacteristicKeys() {
355 std::vector<camera_metadata_tag_t> availableKeys;
356 availableKeys.reserve(mEntryMap.size());
357 for (const auto& [key, _] : mEntryMap) {
358 if (key != ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS) {
359 availableKeys.push_back(key);
360 }
361 }
362 setAvailableCharacteristicKeys(availableKeys);
363 return *this;
364}
365
366std::unique_ptr<aidl::android::hardware::camera::device::CameraMetadata>
367MetadataBuilder::build() const {
368 CameraMetadata metadataHelper;
369 for (const auto& entry : mEntryMap) {
370 status_t ret = std::visit(
371 [&](auto&& arg) {
372 return metadataHelper.update(entry.first, arg.data(), arg.size());
373 },
374 entry.second);
375 if (ret != NO_ERROR) {
376 ALOGE("Failed to update metadata with key %d - %s: %s", entry.first,
377 get_camera_metadata_tag_name(entry.first),
378 ::android::statusToString(ret).c_str());
379 return nullptr;
380 }
381 }
382
383 const camera_metadata_t* metadata = metadataHelper.getAndLock();
384 if (metadata == nullptr) {
385 ALOGE(
386 "Failure when constructing metadata -> CameraMetadata helper returned "
387 "nullptr");
388 return nullptr;
389 }
390
391 auto aidlMetadata =
392 std::make_unique<aidl::android::hardware::camera::device::CameraMetadata>();
393 const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(metadata);
394 aidlMetadata->metadata.assign(data_ptr,
395 data_ptr + get_camera_metadata_size(metadata));
396 metadataHelper.unlock(metadata);
397
398 return aidlMetadata;
399}
400
401} // namespace virtualcamera
402} // namespace companion
403} // namespace android