blob: 18c5d3c3f3218a96fc5fb9d1e0280ea8e2c8b46f [file] [log] [blame]
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
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 "ACameraMetadata"
19
20#include "ACameraMetadata.h"
21#include <utils/Vector.h>
Yin-Chia Yehc3603822016-01-18 22:11:19 -080022#include <system/graphics.h>
Colin Cross7e8d4ba2017-05-04 16:17:42 -070023#include <media/NdkImage.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080024
25using namespace android;
26
27/**
28 * ACameraMetadata Implementation
29 */
30ACameraMetadata::ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYPE type) :
Jiawen Chen9f713e82020-01-15 11:06:13 -050031 mData(new CameraMetadata(buffer)),
32 mOwnsData(true),
33 mType(type) {
34 init();
35}
36
37ACameraMetadata::ACameraMetadata(CameraMetadata* cameraMetadata, ACAMERA_METADATA_TYPE type) :
38 mData(cameraMetadata),
39 mOwnsData(false),
40 mType(type) {
41 init();
42}
43
44ACameraMetadata::ACameraMetadata(const ACameraMetadata& other) :
45 mOwnsData(other.mOwnsData),
46 mType(other.mType) {
47 if (other.mOwnsData) {
48 mData = new CameraMetadata(*(other.mData));
49 } else {
50 mData = other.mData;
51 }
52}
53
54ACameraMetadata::~ACameraMetadata() {
55 if (mOwnsData) {
56 delete mData;
57 }
58}
59
60void
61ACameraMetadata::init() {
Yin-Chia Yehead91462016-01-06 16:45:08 -080062 if (mType == ACM_CHARACTERISTICS) {
63 filterUnsupportedFeatures();
Yin-Chia Yehc3603822016-01-18 22:11:19 -080064 filterStreamConfigurations();
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -070065 filterDurations(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
66 filterDurations(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
67 filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS);
68 filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080069 filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS);
70 filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS);
Emilian Peev44df34d2019-02-12 09:30:15 -080071 filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS);
72 filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS);
Yin-Chia Yehead91462016-01-06 16:45:08 -080073 }
74 // TODO: filter request/result keys
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080075}
76
77bool
78ACameraMetadata::isNdkSupportedCapability(int32_t capability) {
79 switch (capability) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080080 case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING:
81 case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING:
82 case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO:
83 return false;
84 default:
Jayant Chowdhary62899df2019-04-02 16:53:34 -070085 // Assuming every capability passed to this function is actually a
86 // valid capability.
87 return true;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080088 }
89}
90
91void
92ACameraMetadata::filterUnsupportedFeatures() {
93 // Hide unsupported capabilities (reprocessing)
Jiawen Chen9f713e82020-01-15 11:06:13 -050094 camera_metadata_entry entry = mData->find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
Yin-Chia Yehc3603822016-01-18 22:11:19 -080095 if (entry.count == 0 || entry.type != TYPE_BYTE) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080096 ALOGE("%s: malformed available capability key! count %zu, type %d",
97 __FUNCTION__, entry.count, entry.type);
98 return;
99 }
100
101 Vector<uint8_t> capabilities;
102 capabilities.setCapacity(entry.count);
103 for (size_t i = 0; i < entry.count; i++) {
104 uint8_t capability = entry.data.u8[i];
105 if (isNdkSupportedCapability(capability)) {
106 capabilities.push(capability);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800107
108 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
109 derivePhysicalCameraIds();
110 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800111 }
112 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500113 mData->update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities);
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800114}
115
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800116void
117ACameraMetadata::derivePhysicalCameraIds() {
118 ACameraMetadata_const_entry entry;
119 auto ret = getConstEntry(ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS, &entry);
120 if (ret != ACAMERA_OK) {
121 ALOGE("%s: Get ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS key failed. ret %d",
122 __FUNCTION__, ret);
123 return;
124 }
125
126 const uint8_t* ids = entry.data.u8;
127 size_t start = 0;
128 for (size_t i = 0; i < entry.count; ++i) {
129 if (ids[i] == '\0') {
130 if (start != i) {
Emilian Peev1da379a2019-02-05 15:36:31 -0800131 mStaticPhysicalCameraIdValues.push_back(String8((const char *)ids+start));
132 mStaticPhysicalCameraIds.push_back(mStaticPhysicalCameraIdValues.back().string());
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800133 }
134 start = i+1;
135 }
136 }
137
138 if (mStaticPhysicalCameraIds.size() < 2) {
139 ALOGW("%s: Logical multi-camera device only has %zu physical cameras",
140 __FUNCTION__, mStaticPhysicalCameraIds.size());
141 }
142}
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800143
144void
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700145ACameraMetadata::filterDurations(uint32_t tag) {
146 const int STREAM_CONFIGURATION_SIZE = 4;
147 const int STREAM_FORMAT_OFFSET = 0;
148 const int STREAM_WIDTH_OFFSET = 1;
149 const int STREAM_HEIGHT_OFFSET = 2;
150 const int STREAM_DURATION_OFFSET = 3;
Jiawen Chen9f713e82020-01-15 11:06:13 -0500151 camera_metadata_entry entry = mData->find(tag);
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700152 if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT64) {
153 ALOGE("%s: malformed duration key %d! count %zu, type %d",
154 __FUNCTION__, tag, entry.count, entry.type);
155 return;
156 }
157 Vector<int64_t> filteredDurations;
158 filteredDurations.setCapacity(entry.count * 2);
159
160 for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
161 int64_t format = entry.data.i64[i + STREAM_FORMAT_OFFSET];
162 int64_t width = entry.data.i64[i + STREAM_WIDTH_OFFSET];
163 int64_t height = entry.data.i64[i + STREAM_HEIGHT_OFFSET];
164 int64_t duration = entry.data.i32[i + STREAM_DURATION_OFFSET];
165
166 // Leave the unfiltered format in so apps depending on previous wrong
167 // filter behavior continue to work
168 filteredDurations.push_back(format);
169 filteredDurations.push_back(width);
170 filteredDurations.push_back(height);
171 filteredDurations.push_back(duration);
172
173 // Translate HAL formats to NDK format
174 switch (tag) {
175 case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS:
176 case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS:
177 if (format == HAL_PIXEL_FORMAT_BLOB) {
178 format = AIMAGE_FORMAT_JPEG;
179 filteredDurations.push_back(format);
180 filteredDurations.push_back(width);
181 filteredDurations.push_back(height);
182 filteredDurations.push_back(duration);
183 }
184 break;
185 case ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS:
186 case ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS:
187 if (format == HAL_PIXEL_FORMAT_BLOB) {
188 format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
189 filteredDurations.push_back(format);
190 filteredDurations.push_back(width);
191 filteredDurations.push_back(height);
192 filteredDurations.push_back(duration);
193 } else if (format == HAL_PIXEL_FORMAT_Y16) {
194 format = AIMAGE_FORMAT_DEPTH16;
195 filteredDurations.push_back(format);
196 filteredDurations.push_back(width);
197 filteredDurations.push_back(height);
198 filteredDurations.push_back(duration);
199 }
200 break;
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800201 case ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS:
202 case ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS:
203 if (format == HAL_PIXEL_FORMAT_BLOB) {
204 format = AIMAGE_FORMAT_HEIC;
205 filteredDurations.push_back(format);
206 filteredDurations.push_back(width);
207 filteredDurations.push_back(height);
208 filteredDurations.push_back(duration);
209 }
210 break;
Emilian Peev44df34d2019-02-12 09:30:15 -0800211 case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS:
212 case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS:
213 if (format == HAL_PIXEL_FORMAT_BLOB) {
214 format = AIMAGE_FORMAT_DEPTH_JPEG;
215 filteredDurations.push_back(format);
216 filteredDurations.push_back(width);
217 filteredDurations.push_back(height);
218 filteredDurations.push_back(duration);
219 }
220 break;
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700221 default:
222 // Should not reach here
223 ALOGE("%s: Unkown tag 0x%x", __FUNCTION__, tag);
224 }
225 }
226
Jiawen Chen9f713e82020-01-15 11:06:13 -0500227 mData->update(tag, filteredDurations);
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700228}
229
230void
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800231ACameraMetadata::filterStreamConfigurations() {
232 const int STREAM_CONFIGURATION_SIZE = 4;
233 const int STREAM_FORMAT_OFFSET = 0;
234 const int STREAM_WIDTH_OFFSET = 1;
235 const int STREAM_HEIGHT_OFFSET = 2;
236 const int STREAM_IS_INPUT_OFFSET = 3;
Jiawen Chen9f713e82020-01-15 11:06:13 -0500237 camera_metadata_entry entry = mData->find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800238 if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800239 ALOGE("%s: malformed available stream configuration key! count %zu, type %d",
240 __FUNCTION__, entry.count, entry.type);
241 return;
242 }
243
244 Vector<int32_t> filteredStreamConfigs;
245 filteredStreamConfigs.setCapacity(entry.count);
246
247 for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
248 int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
249 int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
250 int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
251 int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
252 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
253 // Hide input streams
254 continue;
255 }
256 // Translate HAL formats to NDK format
257 if (format == HAL_PIXEL_FORMAT_BLOB) {
258 format = AIMAGE_FORMAT_JPEG;
259 }
260 filteredStreamConfigs.push_back(format);
261 filteredStreamConfigs.push_back(width);
262 filteredStreamConfigs.push_back(height);
263 filteredStreamConfigs.push_back(isInput);
264 }
265
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800266 if (filteredStreamConfigs.size() > 0) {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500267 mData->update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800268 }
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800269
Jiawen Chen9f713e82020-01-15 11:06:13 -0500270 entry = mData->find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800271 if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
272 ALOGE("%s: malformed available depth stream configuration key! count %zu, type %d",
273 __FUNCTION__, entry.count, entry.type);
274 return;
275 }
276
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800277 Vector<int32_t> filteredDepthStreamConfigs;
278 filteredDepthStreamConfigs.setCapacity(entry.count);
279
280 for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
281 int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
282 int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
283 int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
284 int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
285 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
286 // Hide input streams
287 continue;
288 }
289 // Translate HAL formats to NDK format
290 if (format == HAL_PIXEL_FORMAT_BLOB) {
291 format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
292 } else if (format == HAL_PIXEL_FORMAT_Y16) {
293 format = AIMAGE_FORMAT_DEPTH16;
294 }
295
296 filteredDepthStreamConfigs.push_back(format);
297 filteredDepthStreamConfigs.push_back(width);
298 filteredDepthStreamConfigs.push_back(height);
299 filteredDepthStreamConfigs.push_back(isInput);
300 }
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800301
302 if (filteredDepthStreamConfigs.size() > 0) {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500303 mData->update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800304 filteredDepthStreamConfigs);
305 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800306
Jiawen Chen9f713e82020-01-15 11:06:13 -0500307 entry = mData->find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800308 Vector<int32_t> filteredHeicStreamConfigs;
309 filteredHeicStreamConfigs.setCapacity(entry.count);
310
311 for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
312 int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
313 int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
314 int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
315 int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
316 if (isInput == ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT) {
317 // Hide input streams
318 continue;
319 }
320 // Translate HAL formats to NDK format
321 if (format == HAL_PIXEL_FORMAT_BLOB) {
322 format = AIMAGE_FORMAT_HEIC;
323 }
324
325 filteredHeicStreamConfigs.push_back(format);
326 filteredHeicStreamConfigs.push_back(width);
327 filteredHeicStreamConfigs.push_back(height);
328 filteredHeicStreamConfigs.push_back(isInput);
329 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500330 mData->update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs);
Emilian Peev44df34d2019-02-12 09:30:15 -0800331
Jiawen Chen9f713e82020-01-15 11:06:13 -0500332 entry = mData->find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
Emilian Peev44df34d2019-02-12 09:30:15 -0800333 Vector<int32_t> filteredDynamicDepthStreamConfigs;
334 filteredDynamicDepthStreamConfigs.setCapacity(entry.count);
335
336 for (size_t i = 0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
337 int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
338 int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
339 int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
340 int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
341 if (isInput == ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT) {
342 // Hide input streams
343 continue;
344 }
345 // Translate HAL formats to NDK format
346 if (format == HAL_PIXEL_FORMAT_BLOB) {
347 format = AIMAGE_FORMAT_DEPTH_JPEG;
348 }
349
350 filteredDynamicDepthStreamConfigs.push_back(format);
351 filteredDynamicDepthStreamConfigs.push_back(width);
352 filteredDynamicDepthStreamConfigs.push_back(height);
353 filteredDynamicDepthStreamConfigs.push_back(isInput);
354 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500355 mData->update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
Emilian Peev44df34d2019-02-12 09:30:15 -0800356 filteredDynamicDepthStreamConfigs);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800357}
358
359bool
360ACameraMetadata::isVendorTag(const uint32_t tag) {
361 uint32_t tag_section = tag >> 16;
362 if (tag_section >= VENDOR_SECTION) {
363 return true;
364 }
365 return false;
366}
367
368camera_status_t
369ACameraMetadata::getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) const {
370 if (entry == nullptr) {
371 return ACAMERA_ERROR_INVALID_PARAMETER;
372 }
373
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800374 Mutex::Autolock _l(mLock);
375
Jiawen Chen9f713e82020-01-15 11:06:13 -0500376 camera_metadata_ro_entry rawEntry = static_cast<const CameraMetadata*>(mData)->find(tag);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800377 if (rawEntry.count == 0) {
378 ALOGE("%s: cannot find metadata tag %d", __FUNCTION__, tag);
379 return ACAMERA_ERROR_METADATA_NOT_FOUND;
380 }
381 entry->tag = tag;
382 entry->type = rawEntry.type;
383 entry->count = rawEntry.count;
384 entry->data.u8 = rawEntry.data.u8;
385 return ACAMERA_OK;
386}
387
388camera_status_t
389ACameraMetadata::update(uint32_t tag, uint32_t count, const uint8_t* data) {
390 return updateImpl<uint8_t>(tag, count, data);
391}
392
393camera_status_t
394ACameraMetadata::update(uint32_t tag, uint32_t count, const int32_t* data) {
395 return updateImpl<int32_t>(tag, count, data);
396}
397
398camera_status_t
399ACameraMetadata::update(uint32_t tag, uint32_t count, const float* data) {
400 return updateImpl<float>(tag, count, data);
401}
402
403camera_status_t
404ACameraMetadata::update(uint32_t tag, uint32_t count, const double* data) {
405 return updateImpl<double>(tag, count, data);
406}
407
408camera_status_t
409ACameraMetadata::update(uint32_t tag, uint32_t count, const int64_t* data) {
410 return updateImpl<int64_t>(tag, count, data);
411}
412
413camera_status_t
414ACameraMetadata::update(uint32_t tag, uint32_t count, const ACameraMetadata_rational* data) {
415 return updateImpl<camera_metadata_rational_t>(tag, count, data);
416}
417
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800418camera_status_t
419ACameraMetadata::getTags(/*out*/int32_t* numTags,
420 /*out*/const uint32_t** tags) const {
421 Mutex::Autolock _l(mLock);
422 if (mTags.size() == 0) {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500423 size_t entry_count = mData->entryCount();
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800424 mTags.setCapacity(entry_count);
Jiawen Chen9f713e82020-01-15 11:06:13 -0500425 const camera_metadata_t* rawMetadata = mData->getAndLock();
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800426 for (size_t i = 0; i < entry_count; i++) {
427 camera_metadata_ro_entry_t entry;
428 int ret = get_camera_metadata_ro_entry(rawMetadata, i, &entry);
429 if (ret != 0) {
430 ALOGE("%s: error reading metadata index %zu", __FUNCTION__, i);
431 return ACAMERA_ERROR_UNKNOWN;
432 }
433 // Hide system key from users
434 if (sSystemTags.count(entry.tag) == 0) {
435 mTags.push_back(entry.tag);
436 }
437 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500438 mData->unlock(rawMetadata);
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800439 }
440
441 *numTags = mTags.size();
442 *tags = mTags.array();
443 return ACAMERA_OK;
444}
445
446const CameraMetadata&
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100447ACameraMetadata::getInternalData() const {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500448 return (*mData);
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800449}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800450
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800451bool
452ACameraMetadata::isLogicalMultiCamera(size_t* count, const char*const** physicalCameraIds) const {
453 if (mType != ACM_CHARACTERISTICS) {
454 ALOGE("%s must be called for a static metadata!", __FUNCTION__);
455 return false;
456 }
457 if (count == nullptr || physicalCameraIds == nullptr) {
458 ALOGE("%s: Invalid input count: %p, physicalCameraIds: %p", __FUNCTION__,
459 count, physicalCameraIds);
460 return false;
461 }
462
463 if (mStaticPhysicalCameraIds.size() >= 2) {
464 *count = mStaticPhysicalCameraIds.size();
465 *physicalCameraIds = mStaticPhysicalCameraIds.data();
466 return true;
467 }
468
469 return false;
470}
471
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800472// TODO: some of key below should be hidden from user
473// ex: ACAMERA_REQUEST_ID and ACAMERA_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
474/*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
475 * The key entries below this point are generated from metadata
476 * definitions in /system/media/camera/docs. Do not modify by hand or
477 * modify the comment blocks at the start or end.
478 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
479
480bool
481ACameraMetadata::isCaptureRequestTag(const uint32_t tag) {
482 // Skip check for vendor keys
483 if (isVendorTag(tag)) {
484 return true;
485 }
486
487 switch (tag) {
488 case ACAMERA_COLOR_CORRECTION_MODE:
489 case ACAMERA_COLOR_CORRECTION_TRANSFORM:
490 case ACAMERA_COLOR_CORRECTION_GAINS:
491 case ACAMERA_COLOR_CORRECTION_ABERRATION_MODE:
492 case ACAMERA_CONTROL_AE_ANTIBANDING_MODE:
493 case ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION:
494 case ACAMERA_CONTROL_AE_LOCK:
495 case ACAMERA_CONTROL_AE_MODE:
496 case ACAMERA_CONTROL_AE_REGIONS:
497 case ACAMERA_CONTROL_AE_TARGET_FPS_RANGE:
498 case ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER:
499 case ACAMERA_CONTROL_AF_MODE:
500 case ACAMERA_CONTROL_AF_REGIONS:
501 case ACAMERA_CONTROL_AF_TRIGGER:
502 case ACAMERA_CONTROL_AWB_LOCK:
503 case ACAMERA_CONTROL_AWB_MODE:
504 case ACAMERA_CONTROL_AWB_REGIONS:
505 case ACAMERA_CONTROL_CAPTURE_INTENT:
506 case ACAMERA_CONTROL_EFFECT_MODE:
507 case ACAMERA_CONTROL_MODE:
508 case ACAMERA_CONTROL_SCENE_MODE:
509 case ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE:
510 case ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST:
Chien-Yu Chenc0dede92017-01-11 11:10:28 -0800511 case ACAMERA_CONTROL_ENABLE_ZSL:
Shuzhen Wang77e073f2019-07-08 15:09:13 -0700512 case ACAMERA_CONTROL_BOKEH_MODE:
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800513 case ACAMERA_CONTROL_ZOOM_RATIO:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800514 case ACAMERA_EDGE_MODE:
515 case ACAMERA_FLASH_MODE:
516 case ACAMERA_HOT_PIXEL_MODE:
517 case ACAMERA_JPEG_GPS_COORDINATES:
518 case ACAMERA_JPEG_GPS_PROCESSING_METHOD:
519 case ACAMERA_JPEG_GPS_TIMESTAMP:
520 case ACAMERA_JPEG_ORIENTATION:
521 case ACAMERA_JPEG_QUALITY:
522 case ACAMERA_JPEG_THUMBNAIL_QUALITY:
523 case ACAMERA_JPEG_THUMBNAIL_SIZE:
524 case ACAMERA_LENS_APERTURE:
525 case ACAMERA_LENS_FILTER_DENSITY:
526 case ACAMERA_LENS_FOCAL_LENGTH:
527 case ACAMERA_LENS_FOCUS_DISTANCE:
528 case ACAMERA_LENS_OPTICAL_STABILIZATION_MODE:
529 case ACAMERA_NOISE_REDUCTION_MODE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800530 case ACAMERA_SCALER_CROP_REGION:
Eino-Ville Talvalae2a88922020-01-06 13:09:21 -0800531 case ACAMERA_SCALER_ROTATE_AND_CROP:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800532 case ACAMERA_SENSOR_EXPOSURE_TIME:
533 case ACAMERA_SENSOR_FRAME_DURATION:
534 case ACAMERA_SENSOR_SENSITIVITY:
535 case ACAMERA_SENSOR_TEST_PATTERN_DATA:
536 case ACAMERA_SENSOR_TEST_PATTERN_MODE:
537 case ACAMERA_SHADING_MODE:
538 case ACAMERA_STATISTICS_FACE_DETECT_MODE:
539 case ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE:
540 case ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE:
Chien-Yu Chen5ca4a9b2018-01-18 12:23:50 -0800541 case ACAMERA_STATISTICS_OIS_DATA_MODE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800542 case ACAMERA_TONEMAP_CURVE_BLUE:
543 case ACAMERA_TONEMAP_CURVE_GREEN:
544 case ACAMERA_TONEMAP_CURVE_RED:
545 case ACAMERA_TONEMAP_MODE:
546 case ACAMERA_TONEMAP_GAMMA:
547 case ACAMERA_TONEMAP_PRESET_CURVE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800548 case ACAMERA_BLACK_LEVEL_LOCK:
Eino-Ville Talvala2d960922018-03-13 19:46:23 -0700549 case ACAMERA_DISTORTION_CORRECTION_MODE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800550 return true;
551 default:
552 return false;
553 }
554}
555
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800556// System tags that should be hidden from users
557std::unordered_set<uint32_t> ACameraMetadata::sSystemTags ({
558 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
559 ANDROID_CONTROL_AE_PRECAPTURE_ID,
560 ANDROID_CONTROL_AF_TRIGGER_ID,
561 ANDROID_DEMOSAIC_MODE,
562 ANDROID_EDGE_STRENGTH,
563 ANDROID_FLASH_FIRING_POWER,
564 ANDROID_FLASH_FIRING_TIME,
565 ANDROID_FLASH_COLOR_TEMPERATURE,
566 ANDROID_FLASH_MAX_ENERGY,
567 ANDROID_FLASH_INFO_CHARGE_DURATION,
568 ANDROID_JPEG_MAX_SIZE,
569 ANDROID_JPEG_SIZE,
570 ANDROID_NOISE_REDUCTION_STRENGTH,
571 ANDROID_QUIRKS_METERING_CROP_REGION,
572 ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO,
573 ANDROID_QUIRKS_USE_ZSL_FORMAT,
574 ANDROID_REQUEST_INPUT_STREAMS,
575 ANDROID_REQUEST_METADATA_MODE,
576 ANDROID_REQUEST_OUTPUT_STREAMS,
577 ANDROID_REQUEST_TYPE,
578 ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS,
579 ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
580 ANDROID_SCALER_AVAILABLE_RAW_SIZES,
581 ANDROID_SENSOR_BASE_GAIN_FACTOR,
582 ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS,
583 ANDROID_SENSOR_TEMPERATURE,
584 ANDROID_SENSOR_PROFILE_HUE_SAT_MAP,
585 ANDROID_SENSOR_PROFILE_TONE_CURVE,
586 ANDROID_SENSOR_OPAQUE_RAW_SIZE,
587 ANDROID_SHADING_STRENGTH,
588 ANDROID_STATISTICS_HISTOGRAM_MODE,
589 ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
590 ANDROID_STATISTICS_HISTOGRAM,
591 ANDROID_STATISTICS_SHARPNESS_MAP,
592 ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
593 ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
594 ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
595 ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
Yin-Chia Yeh2be96a22018-09-17 11:51:24 -0700596 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION,
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800597 ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800598 ANDROID_HEIC_INFO_SUPPORTED,
599 ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800600});
601
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800602/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
603 * End generated code
604 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/