blob: 1bbb9c22c5ec83a91cb15ea3b6bb005b60d10e05 [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) :
Eino-Ville Talvalab949b612020-02-06 11:08:41 -080031 mData(std::make_shared<CameraMetadata>(buffer)),
Jiawen Chen9f713e82020-01-15 11:06:13 -050032 mType(type) {
33 init();
34}
35
Eino-Ville Talvalab949b612020-02-06 11:08:41 -080036ACameraMetadata::ACameraMetadata(const std::shared_ptr<CameraMetadata>& cameraMetadata,
37 ACAMERA_METADATA_TYPE type) :
Jiawen Chen9f713e82020-01-15 11:06:13 -050038 mData(cameraMetadata),
Jiawen Chen9f713e82020-01-15 11:06:13 -050039 mType(type) {
40 init();
41}
42
43ACameraMetadata::ACameraMetadata(const ACameraMetadata& other) :
Eino-Ville Talvalab949b612020-02-06 11:08:41 -080044 mData(std::make_shared<CameraMetadata>(*(other.mData))),
Jiawen Chen9f713e82020-01-15 11:06:13 -050045 mType(other.mType) {
Jiawen Chen9f713e82020-01-15 11:06:13 -050046}
47
48ACameraMetadata::~ACameraMetadata() {
Jiawen Chen9f713e82020-01-15 11:06:13 -050049}
50
51void
52ACameraMetadata::init() {
Yin-Chia Yehead91462016-01-06 16:45:08 -080053 if (mType == ACM_CHARACTERISTICS) {
54 filterUnsupportedFeatures();
Yin-Chia Yehc3603822016-01-18 22:11:19 -080055 filterStreamConfigurations();
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -070056 filterDurations(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
57 filterDurations(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
58 filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS);
59 filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080060 filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS);
61 filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS);
Emilian Peev44df34d2019-02-12 09:30:15 -080062 filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS);
63 filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS);
Yin-Chia Yehead91462016-01-06 16:45:08 -080064 }
65 // TODO: filter request/result keys
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080066}
67
68bool
69ACameraMetadata::isNdkSupportedCapability(int32_t capability) {
70 switch (capability) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080071 case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING:
72 case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING:
73 case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO:
74 return false;
75 default:
Jayant Chowdhary62899df2019-04-02 16:53:34 -070076 // Assuming every capability passed to this function is actually a
77 // valid capability.
78 return true;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080079 }
80}
81
82void
83ACameraMetadata::filterUnsupportedFeatures() {
84 // Hide unsupported capabilities (reprocessing)
Jiawen Chen9f713e82020-01-15 11:06:13 -050085 camera_metadata_entry entry = mData->find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
Yin-Chia Yehc3603822016-01-18 22:11:19 -080086 if (entry.count == 0 || entry.type != TYPE_BYTE) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080087 ALOGE("%s: malformed available capability key! count %zu, type %d",
88 __FUNCTION__, entry.count, entry.type);
89 return;
90 }
91
92 Vector<uint8_t> capabilities;
93 capabilities.setCapacity(entry.count);
94 for (size_t i = 0; i < entry.count; i++) {
95 uint8_t capability = entry.data.u8[i];
96 if (isNdkSupportedCapability(capability)) {
97 capabilities.push(capability);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -080098
99 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
100 derivePhysicalCameraIds();
101 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800102 }
103 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500104 mData->update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities);
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800105}
106
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800107void
108ACameraMetadata::derivePhysicalCameraIds() {
109 ACameraMetadata_const_entry entry;
110 auto ret = getConstEntry(ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS, &entry);
111 if (ret != ACAMERA_OK) {
112 ALOGE("%s: Get ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS key failed. ret %d",
113 __FUNCTION__, ret);
114 return;
115 }
116
117 const uint8_t* ids = entry.data.u8;
118 size_t start = 0;
119 for (size_t i = 0; i < entry.count; ++i) {
120 if (ids[i] == '\0') {
121 if (start != i) {
Emilian Peev1da379a2019-02-05 15:36:31 -0800122 mStaticPhysicalCameraIdValues.push_back(String8((const char *)ids+start));
123 mStaticPhysicalCameraIds.push_back(mStaticPhysicalCameraIdValues.back().string());
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800124 }
125 start = i+1;
126 }
127 }
128
129 if (mStaticPhysicalCameraIds.size() < 2) {
130 ALOGW("%s: Logical multi-camera device only has %zu physical cameras",
131 __FUNCTION__, mStaticPhysicalCameraIds.size());
132 }
133}
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800134
135void
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700136ACameraMetadata::filterDurations(uint32_t tag) {
137 const int STREAM_CONFIGURATION_SIZE = 4;
138 const int STREAM_FORMAT_OFFSET = 0;
139 const int STREAM_WIDTH_OFFSET = 1;
140 const int STREAM_HEIGHT_OFFSET = 2;
141 const int STREAM_DURATION_OFFSET = 3;
Jiawen Chen9f713e82020-01-15 11:06:13 -0500142 camera_metadata_entry entry = mData->find(tag);
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700143 if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT64) {
144 ALOGE("%s: malformed duration key %d! count %zu, type %d",
145 __FUNCTION__, tag, entry.count, entry.type);
146 return;
147 }
148 Vector<int64_t> filteredDurations;
149 filteredDurations.setCapacity(entry.count * 2);
150
151 for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
152 int64_t format = entry.data.i64[i + STREAM_FORMAT_OFFSET];
153 int64_t width = entry.data.i64[i + STREAM_WIDTH_OFFSET];
154 int64_t height = entry.data.i64[i + STREAM_HEIGHT_OFFSET];
155 int64_t duration = entry.data.i32[i + STREAM_DURATION_OFFSET];
156
157 // Leave the unfiltered format in so apps depending on previous wrong
158 // filter behavior continue to work
159 filteredDurations.push_back(format);
160 filteredDurations.push_back(width);
161 filteredDurations.push_back(height);
162 filteredDurations.push_back(duration);
163
164 // Translate HAL formats to NDK format
165 switch (tag) {
166 case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS:
167 case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS:
168 if (format == HAL_PIXEL_FORMAT_BLOB) {
169 format = AIMAGE_FORMAT_JPEG;
170 filteredDurations.push_back(format);
171 filteredDurations.push_back(width);
172 filteredDurations.push_back(height);
173 filteredDurations.push_back(duration);
174 }
175 break;
176 case ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS:
177 case ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS:
178 if (format == HAL_PIXEL_FORMAT_BLOB) {
179 format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
180 filteredDurations.push_back(format);
181 filteredDurations.push_back(width);
182 filteredDurations.push_back(height);
183 filteredDurations.push_back(duration);
184 } else if (format == HAL_PIXEL_FORMAT_Y16) {
185 format = AIMAGE_FORMAT_DEPTH16;
186 filteredDurations.push_back(format);
187 filteredDurations.push_back(width);
188 filteredDurations.push_back(height);
189 filteredDurations.push_back(duration);
190 }
191 break;
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800192 case ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS:
193 case ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS:
194 if (format == HAL_PIXEL_FORMAT_BLOB) {
195 format = AIMAGE_FORMAT_HEIC;
196 filteredDurations.push_back(format);
197 filteredDurations.push_back(width);
198 filteredDurations.push_back(height);
199 filteredDurations.push_back(duration);
200 }
201 break;
Emilian Peev44df34d2019-02-12 09:30:15 -0800202 case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS:
203 case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS:
204 if (format == HAL_PIXEL_FORMAT_BLOB) {
205 format = AIMAGE_FORMAT_DEPTH_JPEG;
206 filteredDurations.push_back(format);
207 filteredDurations.push_back(width);
208 filteredDurations.push_back(height);
209 filteredDurations.push_back(duration);
210 }
211 break;
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700212 default:
213 // Should not reach here
214 ALOGE("%s: Unkown tag 0x%x", __FUNCTION__, tag);
215 }
216 }
217
Jiawen Chen9f713e82020-01-15 11:06:13 -0500218 mData->update(tag, filteredDurations);
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700219}
220
221void
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800222ACameraMetadata::filterStreamConfigurations() {
223 const int STREAM_CONFIGURATION_SIZE = 4;
224 const int STREAM_FORMAT_OFFSET = 0;
225 const int STREAM_WIDTH_OFFSET = 1;
226 const int STREAM_HEIGHT_OFFSET = 2;
227 const int STREAM_IS_INPUT_OFFSET = 3;
Jiawen Chen9f713e82020-01-15 11:06:13 -0500228 camera_metadata_entry entry = mData->find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800229 if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800230 ALOGE("%s: malformed available stream configuration key! count %zu, type %d",
231 __FUNCTION__, entry.count, entry.type);
232 return;
233 }
234
235 Vector<int32_t> filteredStreamConfigs;
236 filteredStreamConfigs.setCapacity(entry.count);
237
238 for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
239 int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
240 int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
241 int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
242 int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
243 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
244 // Hide input streams
245 continue;
246 }
247 // Translate HAL formats to NDK format
248 if (format == HAL_PIXEL_FORMAT_BLOB) {
249 format = AIMAGE_FORMAT_JPEG;
250 }
251 filteredStreamConfigs.push_back(format);
252 filteredStreamConfigs.push_back(width);
253 filteredStreamConfigs.push_back(height);
254 filteredStreamConfigs.push_back(isInput);
255 }
256
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800257 if (filteredStreamConfigs.size() > 0) {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500258 mData->update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800259 }
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800260
Jiawen Chen9f713e82020-01-15 11:06:13 -0500261 entry = mData->find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800262 if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
263 ALOGE("%s: malformed available depth stream configuration key! count %zu, type %d",
264 __FUNCTION__, entry.count, entry.type);
265 return;
266 }
267
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800268 Vector<int32_t> filteredDepthStreamConfigs;
269 filteredDepthStreamConfigs.setCapacity(entry.count);
270
271 for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
272 int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
273 int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
274 int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
275 int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
276 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
277 // Hide input streams
278 continue;
279 }
280 // Translate HAL formats to NDK format
281 if (format == HAL_PIXEL_FORMAT_BLOB) {
282 format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
283 } else if (format == HAL_PIXEL_FORMAT_Y16) {
284 format = AIMAGE_FORMAT_DEPTH16;
285 }
286
287 filteredDepthStreamConfigs.push_back(format);
288 filteredDepthStreamConfigs.push_back(width);
289 filteredDepthStreamConfigs.push_back(height);
290 filteredDepthStreamConfigs.push_back(isInput);
291 }
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800292
293 if (filteredDepthStreamConfigs.size() > 0) {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500294 mData->update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800295 filteredDepthStreamConfigs);
296 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800297
Jiawen Chen9f713e82020-01-15 11:06:13 -0500298 entry = mData->find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800299 Vector<int32_t> filteredHeicStreamConfigs;
300 filteredHeicStreamConfigs.setCapacity(entry.count);
301
302 for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
303 int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
304 int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
305 int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
306 int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
307 if (isInput == ACAMERA_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT) {
308 // Hide input streams
309 continue;
310 }
311 // Translate HAL formats to NDK format
312 if (format == HAL_PIXEL_FORMAT_BLOB) {
313 format = AIMAGE_FORMAT_HEIC;
314 }
315
316 filteredHeicStreamConfigs.push_back(format);
317 filteredHeicStreamConfigs.push_back(width);
318 filteredHeicStreamConfigs.push_back(height);
319 filteredHeicStreamConfigs.push_back(isInput);
320 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500321 mData->update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs);
Emilian Peev44df34d2019-02-12 09:30:15 -0800322
Jiawen Chen9f713e82020-01-15 11:06:13 -0500323 entry = mData->find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
Emilian Peev44df34d2019-02-12 09:30:15 -0800324 Vector<int32_t> filteredDynamicDepthStreamConfigs;
325 filteredDynamicDepthStreamConfigs.setCapacity(entry.count);
326
327 for (size_t i = 0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
328 int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
329 int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
330 int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
331 int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
332 if (isInput == ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT) {
333 // Hide input streams
334 continue;
335 }
336 // Translate HAL formats to NDK format
337 if (format == HAL_PIXEL_FORMAT_BLOB) {
338 format = AIMAGE_FORMAT_DEPTH_JPEG;
339 }
340
341 filteredDynamicDepthStreamConfigs.push_back(format);
342 filteredDynamicDepthStreamConfigs.push_back(width);
343 filteredDynamicDepthStreamConfigs.push_back(height);
344 filteredDynamicDepthStreamConfigs.push_back(isInput);
345 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500346 mData->update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
Emilian Peev44df34d2019-02-12 09:30:15 -0800347 filteredDynamicDepthStreamConfigs);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800348}
349
350bool
351ACameraMetadata::isVendorTag(const uint32_t tag) {
352 uint32_t tag_section = tag >> 16;
353 if (tag_section >= VENDOR_SECTION) {
354 return true;
355 }
356 return false;
357}
358
359camera_status_t
360ACameraMetadata::getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) const {
361 if (entry == nullptr) {
362 return ACAMERA_ERROR_INVALID_PARAMETER;
363 }
364
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800365 Mutex::Autolock _l(mLock);
366
Eino-Ville Talvalab949b612020-02-06 11:08:41 -0800367 camera_metadata_ro_entry rawEntry = static_cast<const CameraMetadata*>(mData.get())->find(tag);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800368 if (rawEntry.count == 0) {
369 ALOGE("%s: cannot find metadata tag %d", __FUNCTION__, tag);
370 return ACAMERA_ERROR_METADATA_NOT_FOUND;
371 }
372 entry->tag = tag;
373 entry->type = rawEntry.type;
374 entry->count = rawEntry.count;
375 entry->data.u8 = rawEntry.data.u8;
376 return ACAMERA_OK;
377}
378
379camera_status_t
380ACameraMetadata::update(uint32_t tag, uint32_t count, const uint8_t* data) {
381 return updateImpl<uint8_t>(tag, count, data);
382}
383
384camera_status_t
385ACameraMetadata::update(uint32_t tag, uint32_t count, const int32_t* data) {
386 return updateImpl<int32_t>(tag, count, data);
387}
388
389camera_status_t
390ACameraMetadata::update(uint32_t tag, uint32_t count, const float* data) {
391 return updateImpl<float>(tag, count, data);
392}
393
394camera_status_t
395ACameraMetadata::update(uint32_t tag, uint32_t count, const double* data) {
396 return updateImpl<double>(tag, count, data);
397}
398
399camera_status_t
400ACameraMetadata::update(uint32_t tag, uint32_t count, const int64_t* data) {
401 return updateImpl<int64_t>(tag, count, data);
402}
403
404camera_status_t
405ACameraMetadata::update(uint32_t tag, uint32_t count, const ACameraMetadata_rational* data) {
406 return updateImpl<camera_metadata_rational_t>(tag, count, data);
407}
408
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800409camera_status_t
410ACameraMetadata::getTags(/*out*/int32_t* numTags,
411 /*out*/const uint32_t** tags) const {
412 Mutex::Autolock _l(mLock);
413 if (mTags.size() == 0) {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500414 size_t entry_count = mData->entryCount();
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800415 mTags.setCapacity(entry_count);
Jiawen Chen9f713e82020-01-15 11:06:13 -0500416 const camera_metadata_t* rawMetadata = mData->getAndLock();
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800417 for (size_t i = 0; i < entry_count; i++) {
418 camera_metadata_ro_entry_t entry;
419 int ret = get_camera_metadata_ro_entry(rawMetadata, i, &entry);
420 if (ret != 0) {
421 ALOGE("%s: error reading metadata index %zu", __FUNCTION__, i);
422 return ACAMERA_ERROR_UNKNOWN;
423 }
424 // Hide system key from users
425 if (sSystemTags.count(entry.tag) == 0) {
426 mTags.push_back(entry.tag);
427 }
428 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500429 mData->unlock(rawMetadata);
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800430 }
431
432 *numTags = mTags.size();
433 *tags = mTags.array();
434 return ACAMERA_OK;
435}
436
437const CameraMetadata&
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100438ACameraMetadata::getInternalData() const {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500439 return (*mData);
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800440}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800441
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800442bool
443ACameraMetadata::isLogicalMultiCamera(size_t* count, const char*const** physicalCameraIds) const {
444 if (mType != ACM_CHARACTERISTICS) {
445 ALOGE("%s must be called for a static metadata!", __FUNCTION__);
446 return false;
447 }
448 if (count == nullptr || physicalCameraIds == nullptr) {
449 ALOGE("%s: Invalid input count: %p, physicalCameraIds: %p", __FUNCTION__,
450 count, physicalCameraIds);
451 return false;
452 }
453
454 if (mStaticPhysicalCameraIds.size() >= 2) {
455 *count = mStaticPhysicalCameraIds.size();
456 *physicalCameraIds = mStaticPhysicalCameraIds.data();
457 return true;
458 }
459
460 return false;
461}
462
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800463// TODO: some of key below should be hidden from user
464// ex: ACAMERA_REQUEST_ID and ACAMERA_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
465/*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
466 * The key entries below this point are generated from metadata
467 * definitions in /system/media/camera/docs. Do not modify by hand or
468 * modify the comment blocks at the start or end.
469 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
470
471bool
472ACameraMetadata::isCaptureRequestTag(const uint32_t tag) {
473 // Skip check for vendor keys
474 if (isVendorTag(tag)) {
475 return true;
476 }
477
478 switch (tag) {
479 case ACAMERA_COLOR_CORRECTION_MODE:
480 case ACAMERA_COLOR_CORRECTION_TRANSFORM:
481 case ACAMERA_COLOR_CORRECTION_GAINS:
482 case ACAMERA_COLOR_CORRECTION_ABERRATION_MODE:
483 case ACAMERA_CONTROL_AE_ANTIBANDING_MODE:
484 case ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION:
485 case ACAMERA_CONTROL_AE_LOCK:
486 case ACAMERA_CONTROL_AE_MODE:
487 case ACAMERA_CONTROL_AE_REGIONS:
488 case ACAMERA_CONTROL_AE_TARGET_FPS_RANGE:
489 case ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER:
490 case ACAMERA_CONTROL_AF_MODE:
491 case ACAMERA_CONTROL_AF_REGIONS:
492 case ACAMERA_CONTROL_AF_TRIGGER:
493 case ACAMERA_CONTROL_AWB_LOCK:
494 case ACAMERA_CONTROL_AWB_MODE:
495 case ACAMERA_CONTROL_AWB_REGIONS:
496 case ACAMERA_CONTROL_CAPTURE_INTENT:
497 case ACAMERA_CONTROL_EFFECT_MODE:
498 case ACAMERA_CONTROL_MODE:
499 case ACAMERA_CONTROL_SCENE_MODE:
500 case ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE:
501 case ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST:
Chien-Yu Chenc0dede92017-01-11 11:10:28 -0800502 case ACAMERA_CONTROL_ENABLE_ZSL:
Shuzhen Wang77e073f2019-07-08 15:09:13 -0700503 case ACAMERA_CONTROL_BOKEH_MODE:
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800504 case ACAMERA_CONTROL_ZOOM_RATIO:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800505 case ACAMERA_EDGE_MODE:
506 case ACAMERA_FLASH_MODE:
507 case ACAMERA_HOT_PIXEL_MODE:
508 case ACAMERA_JPEG_GPS_COORDINATES:
509 case ACAMERA_JPEG_GPS_PROCESSING_METHOD:
510 case ACAMERA_JPEG_GPS_TIMESTAMP:
511 case ACAMERA_JPEG_ORIENTATION:
512 case ACAMERA_JPEG_QUALITY:
513 case ACAMERA_JPEG_THUMBNAIL_QUALITY:
514 case ACAMERA_JPEG_THUMBNAIL_SIZE:
515 case ACAMERA_LENS_APERTURE:
516 case ACAMERA_LENS_FILTER_DENSITY:
517 case ACAMERA_LENS_FOCAL_LENGTH:
518 case ACAMERA_LENS_FOCUS_DISTANCE:
519 case ACAMERA_LENS_OPTICAL_STABILIZATION_MODE:
520 case ACAMERA_NOISE_REDUCTION_MODE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800521 case ACAMERA_SCALER_CROP_REGION:
Eino-Ville Talvalae2a88922020-01-06 13:09:21 -0800522 case ACAMERA_SCALER_ROTATE_AND_CROP:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800523 case ACAMERA_SENSOR_EXPOSURE_TIME:
524 case ACAMERA_SENSOR_FRAME_DURATION:
525 case ACAMERA_SENSOR_SENSITIVITY:
526 case ACAMERA_SENSOR_TEST_PATTERN_DATA:
527 case ACAMERA_SENSOR_TEST_PATTERN_MODE:
528 case ACAMERA_SHADING_MODE:
529 case ACAMERA_STATISTICS_FACE_DETECT_MODE:
530 case ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE:
531 case ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE:
Chien-Yu Chen5ca4a9b2018-01-18 12:23:50 -0800532 case ACAMERA_STATISTICS_OIS_DATA_MODE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800533 case ACAMERA_TONEMAP_CURVE_BLUE:
534 case ACAMERA_TONEMAP_CURVE_GREEN:
535 case ACAMERA_TONEMAP_CURVE_RED:
536 case ACAMERA_TONEMAP_MODE:
537 case ACAMERA_TONEMAP_GAMMA:
538 case ACAMERA_TONEMAP_PRESET_CURVE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800539 case ACAMERA_BLACK_LEVEL_LOCK:
Eino-Ville Talvala2d960922018-03-13 19:46:23 -0700540 case ACAMERA_DISTORTION_CORRECTION_MODE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800541 return true;
542 default:
543 return false;
544 }
545}
546
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800547// System tags that should be hidden from users
548std::unordered_set<uint32_t> ACameraMetadata::sSystemTags ({
549 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
550 ANDROID_CONTROL_AE_PRECAPTURE_ID,
551 ANDROID_CONTROL_AF_TRIGGER_ID,
552 ANDROID_DEMOSAIC_MODE,
553 ANDROID_EDGE_STRENGTH,
554 ANDROID_FLASH_FIRING_POWER,
555 ANDROID_FLASH_FIRING_TIME,
556 ANDROID_FLASH_COLOR_TEMPERATURE,
557 ANDROID_FLASH_MAX_ENERGY,
558 ANDROID_FLASH_INFO_CHARGE_DURATION,
559 ANDROID_JPEG_MAX_SIZE,
560 ANDROID_JPEG_SIZE,
561 ANDROID_NOISE_REDUCTION_STRENGTH,
562 ANDROID_QUIRKS_METERING_CROP_REGION,
563 ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO,
564 ANDROID_QUIRKS_USE_ZSL_FORMAT,
565 ANDROID_REQUEST_INPUT_STREAMS,
566 ANDROID_REQUEST_METADATA_MODE,
567 ANDROID_REQUEST_OUTPUT_STREAMS,
568 ANDROID_REQUEST_TYPE,
569 ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS,
570 ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
571 ANDROID_SCALER_AVAILABLE_RAW_SIZES,
572 ANDROID_SENSOR_BASE_GAIN_FACTOR,
573 ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS,
574 ANDROID_SENSOR_TEMPERATURE,
575 ANDROID_SENSOR_PROFILE_HUE_SAT_MAP,
576 ANDROID_SENSOR_PROFILE_TONE_CURVE,
577 ANDROID_SENSOR_OPAQUE_RAW_SIZE,
578 ANDROID_SHADING_STRENGTH,
579 ANDROID_STATISTICS_HISTOGRAM_MODE,
580 ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
581 ANDROID_STATISTICS_HISTOGRAM,
582 ANDROID_STATISTICS_SHARPNESS_MAP,
583 ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
584 ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
585 ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
586 ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
Yin-Chia Yeh2be96a22018-09-17 11:51:24 -0700587 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION,
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800588 ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800589 ANDROID_HEIC_INFO_SUPPORTED,
590 ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800591});
592
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800593/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
594 * End generated code
595 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/