blob: 61c7551f6053e094f92ecb9c4b51621beb56c67f [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
Yin-Chia Yehf6e6a8e2021-04-08 11:49:42 -070027// Formats not listed in the public API, but still available to AImageReader
28// Enum value must match corresponding enum in ui/PublicFormat.h (which is not
29// available to VNDK)
30enum AIMAGE_PRIVATE_FORMATS {
31 /**
32 * Unprocessed implementation-dependent raw
33 * depth measurements, opaque with 16 bit
34 * samples.
35 *
36 */
37
38 AIMAGE_FORMAT_RAW_DEPTH = 0x1002,
39
40 /**
41 * Device specific 10 bits depth RAW image format.
42 *
43 * <p>Unprocessed implementation-dependent raw depth measurements, opaque with 10 bit samples
44 * and device specific bit layout.</p>
45 */
46 AIMAGE_FORMAT_RAW_DEPTH10 = 0x1003,
47};
48
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080049/**
50 * ACameraMetadata Implementation
51 */
52ACameraMetadata::ACameraMetadata(camera_metadata_t* buffer, ACAMERA_METADATA_TYPE type) :
Eino-Ville Talvalab949b612020-02-06 11:08:41 -080053 mData(std::make_shared<CameraMetadata>(buffer)),
Jiawen Chen9f713e82020-01-15 11:06:13 -050054 mType(type) {
55 init();
56}
57
Eino-Ville Talvalab949b612020-02-06 11:08:41 -080058ACameraMetadata::ACameraMetadata(const std::shared_ptr<CameraMetadata>& cameraMetadata,
59 ACAMERA_METADATA_TYPE type) :
Jiawen Chen9f713e82020-01-15 11:06:13 -050060 mData(cameraMetadata),
Jiawen Chen9f713e82020-01-15 11:06:13 -050061 mType(type) {
62 init();
63}
64
65ACameraMetadata::ACameraMetadata(const ACameraMetadata& other) :
Eino-Ville Talvalab949b612020-02-06 11:08:41 -080066 mData(std::make_shared<CameraMetadata>(*(other.mData))),
Jiawen Chen9f713e82020-01-15 11:06:13 -050067 mType(other.mType) {
Jiawen Chen9f713e82020-01-15 11:06:13 -050068}
69
70ACameraMetadata::~ACameraMetadata() {
Jiawen Chen9f713e82020-01-15 11:06:13 -050071}
72
73void
74ACameraMetadata::init() {
Yin-Chia Yehead91462016-01-06 16:45:08 -080075 if (mType == ACM_CHARACTERISTICS) {
76 filterUnsupportedFeatures();
Yin-Chia Yehc3603822016-01-18 22:11:19 -080077 filterStreamConfigurations();
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -070078 filterDurations(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
79 filterDurations(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
80 filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS);
81 filterDurations(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080082 filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS);
83 filterDurations(ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS);
Emilian Peev44df34d2019-02-12 09:30:15 -080084 filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS);
85 filterDurations(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS);
Yin-Chia Yehead91462016-01-06 16:45:08 -080086 }
87 // TODO: filter request/result keys
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080088}
89
90bool
91ACameraMetadata::isNdkSupportedCapability(int32_t capability) {
92 switch (capability) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080093 case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING:
94 case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING:
95 case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO:
96 return false;
97 default:
Jayant Chowdhary62899df2019-04-02 16:53:34 -070098 // Assuming every capability passed to this function is actually a
99 // valid capability.
100 return true;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800101 }
102}
103
104void
105ACameraMetadata::filterUnsupportedFeatures() {
106 // Hide unsupported capabilities (reprocessing)
Jiawen Chen9f713e82020-01-15 11:06:13 -0500107 camera_metadata_entry entry = mData->find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800108 if (entry.count == 0 || entry.type != TYPE_BYTE) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800109 ALOGE("%s: malformed available capability key! count %zu, type %d",
110 __FUNCTION__, entry.count, entry.type);
111 return;
112 }
113
114 Vector<uint8_t> capabilities;
115 capabilities.setCapacity(entry.count);
116 for (size_t i = 0; i < entry.count; i++) {
117 uint8_t capability = entry.data.u8[i];
118 if (isNdkSupportedCapability(capability)) {
119 capabilities.push(capability);
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800120
121 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
122 derivePhysicalCameraIds();
123 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800124 }
125 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500126 mData->update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, capabilities);
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800127}
128
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800129void
130ACameraMetadata::derivePhysicalCameraIds() {
131 ACameraMetadata_const_entry entry;
132 auto ret = getConstEntry(ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS, &entry);
133 if (ret != ACAMERA_OK) {
134 ALOGE("%s: Get ACAMERA_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS key failed. ret %d",
135 __FUNCTION__, ret);
136 return;
137 }
138
139 const uint8_t* ids = entry.data.u8;
140 size_t start = 0;
141 for (size_t i = 0; i < entry.count; ++i) {
142 if (ids[i] == '\0') {
143 if (start != i) {
Emilian Peev1da379a2019-02-05 15:36:31 -0800144 mStaticPhysicalCameraIdValues.push_back(String8((const char *)ids+start));
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000145 mStaticPhysicalCameraIds.push_back(mStaticPhysicalCameraIdValues.back().c_str());
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800146 }
147 start = i+1;
148 }
149 }
150
151 if (mStaticPhysicalCameraIds.size() < 2) {
152 ALOGW("%s: Logical multi-camera device only has %zu physical cameras",
153 __FUNCTION__, mStaticPhysicalCameraIds.size());
154 }
155}
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800156
157void
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700158ACameraMetadata::filterDurations(uint32_t tag) {
159 const int STREAM_CONFIGURATION_SIZE = 4;
160 const int STREAM_FORMAT_OFFSET = 0;
161 const int STREAM_WIDTH_OFFSET = 1;
162 const int STREAM_HEIGHT_OFFSET = 2;
163 const int STREAM_DURATION_OFFSET = 3;
Yin-Chia Yeha5b6b2f2020-03-12 11:19:14 -0700164
Jiawen Chen9f713e82020-01-15 11:06:13 -0500165 camera_metadata_entry entry = mData->find(tag);
Yin-Chia Yeha5b6b2f2020-03-12 11:19:14 -0700166
167 if (entry.count == 0) {
168 // Duration keys can be missing when corresponding capture feature is not supported
169 return;
170 }
171
172 if (entry.count % 4 || entry.type != TYPE_INT64) {
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700173 ALOGE("%s: malformed duration key %d! count %zu, type %d",
174 __FUNCTION__, tag, entry.count, entry.type);
175 return;
176 }
Yin-Chia Yeha5b6b2f2020-03-12 11:19:14 -0700177
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700178 Vector<int64_t> filteredDurations;
179 filteredDurations.setCapacity(entry.count * 2);
180
181 for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
182 int64_t format = entry.data.i64[i + STREAM_FORMAT_OFFSET];
183 int64_t width = entry.data.i64[i + STREAM_WIDTH_OFFSET];
184 int64_t height = entry.data.i64[i + STREAM_HEIGHT_OFFSET];
Fang Hui00bf4252021-11-01 22:38:42 +0800185 int64_t duration = entry.data.i64[i + STREAM_DURATION_OFFSET];
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700186
187 // Leave the unfiltered format in so apps depending on previous wrong
188 // filter behavior continue to work
189 filteredDurations.push_back(format);
190 filteredDurations.push_back(width);
191 filteredDurations.push_back(height);
192 filteredDurations.push_back(duration);
193
194 // Translate HAL formats to NDK format
195 switch (tag) {
196 case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS:
197 case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS:
198 if (format == HAL_PIXEL_FORMAT_BLOB) {
199 format = AIMAGE_FORMAT_JPEG;
200 filteredDurations.push_back(format);
201 filteredDurations.push_back(width);
202 filteredDurations.push_back(height);
203 filteredDurations.push_back(duration);
204 }
205 break;
206 case ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS:
207 case ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS:
208 if (format == HAL_PIXEL_FORMAT_BLOB) {
209 format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
210 filteredDurations.push_back(format);
211 filteredDurations.push_back(width);
212 filteredDurations.push_back(height);
213 filteredDurations.push_back(duration);
214 } else if (format == HAL_PIXEL_FORMAT_Y16) {
215 format = AIMAGE_FORMAT_DEPTH16;
216 filteredDurations.push_back(format);
217 filteredDurations.push_back(width);
218 filteredDurations.push_back(height);
219 filteredDurations.push_back(duration);
220 }
221 break;
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800222 case ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS:
223 case ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS:
224 if (format == HAL_PIXEL_FORMAT_BLOB) {
225 format = AIMAGE_FORMAT_HEIC;
226 filteredDurations.push_back(format);
227 filteredDurations.push_back(width);
228 filteredDurations.push_back(height);
229 filteredDurations.push_back(duration);
230 }
231 break;
Emilian Peev44df34d2019-02-12 09:30:15 -0800232 case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS:
233 case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS:
234 if (format == HAL_PIXEL_FORMAT_BLOB) {
235 format = AIMAGE_FORMAT_DEPTH_JPEG;
236 filteredDurations.push_back(format);
237 filteredDurations.push_back(width);
238 filteredDurations.push_back(height);
239 filteredDurations.push_back(duration);
240 }
241 break;
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700242 default:
243 // Should not reach here
244 ALOGE("%s: Unkown tag 0x%x", __FUNCTION__, tag);
245 }
246 }
247
Jiawen Chen9f713e82020-01-15 11:06:13 -0500248 mData->update(tag, filteredDurations);
Yin-Chia Yehe57e9a22018-08-23 15:36:41 -0700249}
250
251void
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800252ACameraMetadata::filterStreamConfigurations() {
253 const int STREAM_CONFIGURATION_SIZE = 4;
254 const int STREAM_FORMAT_OFFSET = 0;
255 const int STREAM_WIDTH_OFFSET = 1;
256 const int STREAM_HEIGHT_OFFSET = 2;
257 const int STREAM_IS_INPUT_OFFSET = 3;
Jiawen Chen9f713e82020-01-15 11:06:13 -0500258 camera_metadata_entry entry = mData->find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800259 if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800260 ALOGE("%s: malformed available stream configuration key! count %zu, type %d",
261 __FUNCTION__, entry.count, entry.type);
262 return;
263 }
264
265 Vector<int32_t> filteredStreamConfigs;
266 filteredStreamConfigs.setCapacity(entry.count);
267
268 for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
269 int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
270 int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
271 int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
272 int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
273 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
274 // Hide input streams
275 continue;
276 }
277 // Translate HAL formats to NDK format
278 if (format == HAL_PIXEL_FORMAT_BLOB) {
279 format = AIMAGE_FORMAT_JPEG;
280 }
281 filteredStreamConfigs.push_back(format);
282 filteredStreamConfigs.push_back(width);
283 filteredStreamConfigs.push_back(height);
284 filteredStreamConfigs.push_back(isInput);
285 }
286
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800287 if (filteredStreamConfigs.size() > 0) {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500288 mData->update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800289 }
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800290
Jiawen Chen9f713e82020-01-15 11:06:13 -0500291 entry = mData->find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800292 if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
293 ALOGE("%s: malformed available depth stream configuration key! count %zu, type %d",
294 __FUNCTION__, entry.count, entry.type);
295 return;
296 }
297
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800298 Vector<int32_t> filteredDepthStreamConfigs;
299 filteredDepthStreamConfigs.setCapacity(entry.count);
300
301 for (size_t i=0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
302 int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
303 int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
304 int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
305 int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
306 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
307 // Hide input streams
308 continue;
309 }
310 // Translate HAL formats to NDK format
311 if (format == HAL_PIXEL_FORMAT_BLOB) {
312 format = AIMAGE_FORMAT_DEPTH_POINT_CLOUD;
313 } else if (format == HAL_PIXEL_FORMAT_Y16) {
314 format = AIMAGE_FORMAT_DEPTH16;
Yin-Chia Yehf6e6a8e2021-04-08 11:49:42 -0700315 } else if (format == HAL_PIXEL_FORMAT_RAW16) {
316 format = static_cast<int32_t>(AIMAGE_FORMAT_RAW_DEPTH);
317 } else if (format == HAL_PIXEL_FORMAT_RAW10) {
318 format = static_cast<int32_t>(AIMAGE_FORMAT_RAW_DEPTH10);
Yin-Chia Yehc3603822016-01-18 22:11:19 -0800319 }
320
321 filteredDepthStreamConfigs.push_back(format);
322 filteredDepthStreamConfigs.push_back(width);
323 filteredDepthStreamConfigs.push_back(height);
324 filteredDepthStreamConfigs.push_back(isInput);
325 }
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800326
327 if (filteredDepthStreamConfigs.size() > 0) {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500328 mData->update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
Yin-Chia Yeh38c13a72019-02-26 14:02:15 -0800329 filteredDepthStreamConfigs);
330 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800331
Jiawen Chen9f713e82020-01-15 11:06:13 -0500332 entry = mData->find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800333 Vector<int32_t> filteredHeicStreamConfigs;
334 filteredHeicStreamConfigs.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_HEIC_AVAILABLE_HEIC_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_HEIC;
348 }
349
350 filteredHeicStreamConfigs.push_back(format);
351 filteredHeicStreamConfigs.push_back(width);
352 filteredHeicStreamConfigs.push_back(height);
353 filteredHeicStreamConfigs.push_back(isInput);
354 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500355 mData->update(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, filteredHeicStreamConfigs);
Emilian Peev44df34d2019-02-12 09:30:15 -0800356
Jiawen Chen9f713e82020-01-15 11:06:13 -0500357 entry = mData->find(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
Emilian Peev44df34d2019-02-12 09:30:15 -0800358 Vector<int32_t> filteredDynamicDepthStreamConfigs;
359 filteredDynamicDepthStreamConfigs.setCapacity(entry.count);
360
361 for (size_t i = 0; i < entry.count; i += STREAM_CONFIGURATION_SIZE) {
362 int32_t format = entry.data.i32[i + STREAM_FORMAT_OFFSET];
363 int32_t width = entry.data.i32[i + STREAM_WIDTH_OFFSET];
364 int32_t height = entry.data.i32[i + STREAM_HEIGHT_OFFSET];
365 int32_t isInput = entry.data.i32[i + STREAM_IS_INPUT_OFFSET];
366 if (isInput == ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT) {
367 // Hide input streams
368 continue;
369 }
370 // Translate HAL formats to NDK format
371 if (format == HAL_PIXEL_FORMAT_BLOB) {
372 format = AIMAGE_FORMAT_DEPTH_JPEG;
373 }
374
375 filteredDynamicDepthStreamConfigs.push_back(format);
376 filteredDynamicDepthStreamConfigs.push_back(width);
377 filteredDynamicDepthStreamConfigs.push_back(height);
378 filteredDynamicDepthStreamConfigs.push_back(isInput);
379 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500380 mData->update(ACAMERA_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
Emilian Peev44df34d2019-02-12 09:30:15 -0800381 filteredDynamicDepthStreamConfigs);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800382}
383
384bool
385ACameraMetadata::isVendorTag(const uint32_t tag) {
386 uint32_t tag_section = tag >> 16;
387 if (tag_section >= VENDOR_SECTION) {
388 return true;
389 }
390 return false;
391}
392
393camera_status_t
394ACameraMetadata::getConstEntry(uint32_t tag, ACameraMetadata_const_entry* entry) const {
395 if (entry == nullptr) {
396 return ACAMERA_ERROR_INVALID_PARAMETER;
397 }
398
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800399 Mutex::Autolock _l(mLock);
400
Eino-Ville Talvalab949b612020-02-06 11:08:41 -0800401 camera_metadata_ro_entry rawEntry = static_cast<const CameraMetadata*>(mData.get())->find(tag);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800402 if (rawEntry.count == 0) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800403 return ACAMERA_ERROR_METADATA_NOT_FOUND;
404 }
405 entry->tag = tag;
406 entry->type = rawEntry.type;
407 entry->count = rawEntry.count;
408 entry->data.u8 = rawEntry.data.u8;
409 return ACAMERA_OK;
410}
411
412camera_status_t
413ACameraMetadata::update(uint32_t tag, uint32_t count, const uint8_t* data) {
414 return updateImpl<uint8_t>(tag, count, data);
415}
416
417camera_status_t
418ACameraMetadata::update(uint32_t tag, uint32_t count, const int32_t* data) {
419 return updateImpl<int32_t>(tag, count, data);
420}
421
422camera_status_t
423ACameraMetadata::update(uint32_t tag, uint32_t count, const float* data) {
424 return updateImpl<float>(tag, count, data);
425}
426
427camera_status_t
428ACameraMetadata::update(uint32_t tag, uint32_t count, const double* data) {
429 return updateImpl<double>(tag, count, data);
430}
431
432camera_status_t
433ACameraMetadata::update(uint32_t tag, uint32_t count, const int64_t* data) {
434 return updateImpl<int64_t>(tag, count, data);
435}
436
437camera_status_t
438ACameraMetadata::update(uint32_t tag, uint32_t count, const ACameraMetadata_rational* data) {
439 return updateImpl<camera_metadata_rational_t>(tag, count, data);
440}
441
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800442camera_status_t
443ACameraMetadata::getTags(/*out*/int32_t* numTags,
444 /*out*/const uint32_t** tags) const {
445 Mutex::Autolock _l(mLock);
446 if (mTags.size() == 0) {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500447 size_t entry_count = mData->entryCount();
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800448 mTags.setCapacity(entry_count);
Jiawen Chen9f713e82020-01-15 11:06:13 -0500449 const camera_metadata_t* rawMetadata = mData->getAndLock();
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800450 for (size_t i = 0; i < entry_count; i++) {
451 camera_metadata_ro_entry_t entry;
452 int ret = get_camera_metadata_ro_entry(rawMetadata, i, &entry);
453 if (ret != 0) {
Lida Wange05c3292020-10-22 22:38:40 -0700454 mData->unlock(rawMetadata);
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800455 ALOGE("%s: error reading metadata index %zu", __FUNCTION__, i);
456 return ACAMERA_ERROR_UNKNOWN;
457 }
458 // Hide system key from users
459 if (sSystemTags.count(entry.tag) == 0) {
460 mTags.push_back(entry.tag);
461 }
462 }
Jiawen Chen9f713e82020-01-15 11:06:13 -0500463 mData->unlock(rawMetadata);
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800464 }
465
466 *numTags = mTags.size();
467 *tags = mTags.array();
468 return ACAMERA_OK;
469}
470
471const CameraMetadata&
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100472ACameraMetadata::getInternalData() const {
Jiawen Chen9f713e82020-01-15 11:06:13 -0500473 return (*mData);
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800474}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800475
Shuzhen Wang0ff9ae32018-12-05 18:06:12 -0800476bool
477ACameraMetadata::isLogicalMultiCamera(size_t* count, const char*const** physicalCameraIds) const {
478 if (mType != ACM_CHARACTERISTICS) {
479 ALOGE("%s must be called for a static metadata!", __FUNCTION__);
480 return false;
481 }
482 if (count == nullptr || physicalCameraIds == nullptr) {
483 ALOGE("%s: Invalid input count: %p, physicalCameraIds: %p", __FUNCTION__,
484 count, physicalCameraIds);
485 return false;
486 }
487
488 if (mStaticPhysicalCameraIds.size() >= 2) {
489 *count = mStaticPhysicalCameraIds.size();
490 *physicalCameraIds = mStaticPhysicalCameraIds.data();
491 return true;
492 }
493
494 return false;
495}
496
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800497// TODO: some of key below should be hidden from user
498// ex: ACAMERA_REQUEST_ID and ACAMERA_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
499/*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
500 * The key entries below this point are generated from metadata
501 * definitions in /system/media/camera/docs. Do not modify by hand or
502 * modify the comment blocks at the start or end.
503 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
504
505bool
506ACameraMetadata::isCaptureRequestTag(const uint32_t tag) {
507 // Skip check for vendor keys
508 if (isVendorTag(tag)) {
509 return true;
510 }
511
512 switch (tag) {
513 case ACAMERA_COLOR_CORRECTION_MODE:
514 case ACAMERA_COLOR_CORRECTION_TRANSFORM:
515 case ACAMERA_COLOR_CORRECTION_GAINS:
516 case ACAMERA_COLOR_CORRECTION_ABERRATION_MODE:
517 case ACAMERA_CONTROL_AE_ANTIBANDING_MODE:
518 case ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION:
519 case ACAMERA_CONTROL_AE_LOCK:
520 case ACAMERA_CONTROL_AE_MODE:
521 case ACAMERA_CONTROL_AE_REGIONS:
522 case ACAMERA_CONTROL_AE_TARGET_FPS_RANGE:
523 case ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER:
524 case ACAMERA_CONTROL_AF_MODE:
525 case ACAMERA_CONTROL_AF_REGIONS:
526 case ACAMERA_CONTROL_AF_TRIGGER:
527 case ACAMERA_CONTROL_AWB_LOCK:
528 case ACAMERA_CONTROL_AWB_MODE:
529 case ACAMERA_CONTROL_AWB_REGIONS:
530 case ACAMERA_CONTROL_CAPTURE_INTENT:
531 case ACAMERA_CONTROL_EFFECT_MODE:
532 case ACAMERA_CONTROL_MODE:
533 case ACAMERA_CONTROL_SCENE_MODE:
534 case ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE:
535 case ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST:
Chien-Yu Chenc0dede92017-01-11 11:10:28 -0800536 case ACAMERA_CONTROL_ENABLE_ZSL:
Shuzhen Wangaa0ae2b2020-03-16 16:00:45 -0700537 case ACAMERA_CONTROL_EXTENDED_SCENE_MODE:
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800538 case ACAMERA_CONTROL_ZOOM_RATIO:
Bharatt Kukreja963325d2022-09-02 22:32:45 +0000539 case ACAMERA_CONTROL_SETTINGS_OVERRIDE:
Bharatt Kukrejabedaadb2022-09-15 20:22:32 +0000540 case ACAMERA_CONTROL_AUTOFRAMING:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800541 case ACAMERA_EDGE_MODE:
542 case ACAMERA_FLASH_MODE:
543 case ACAMERA_HOT_PIXEL_MODE:
544 case ACAMERA_JPEG_GPS_COORDINATES:
545 case ACAMERA_JPEG_GPS_PROCESSING_METHOD:
546 case ACAMERA_JPEG_GPS_TIMESTAMP:
547 case ACAMERA_JPEG_ORIENTATION:
548 case ACAMERA_JPEG_QUALITY:
549 case ACAMERA_JPEG_THUMBNAIL_QUALITY:
550 case ACAMERA_JPEG_THUMBNAIL_SIZE:
551 case ACAMERA_LENS_APERTURE:
552 case ACAMERA_LENS_FILTER_DENSITY:
553 case ACAMERA_LENS_FOCAL_LENGTH:
554 case ACAMERA_LENS_FOCUS_DISTANCE:
555 case ACAMERA_LENS_OPTICAL_STABILIZATION_MODE:
556 case ACAMERA_NOISE_REDUCTION_MODE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800557 case ACAMERA_SCALER_CROP_REGION:
Eino-Ville Talvalae2a88922020-01-06 13:09:21 -0800558 case ACAMERA_SCALER_ROTATE_AND_CROP:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800559 case ACAMERA_SENSOR_EXPOSURE_TIME:
560 case ACAMERA_SENSOR_FRAME_DURATION:
561 case ACAMERA_SENSOR_SENSITIVITY:
562 case ACAMERA_SENSOR_TEST_PATTERN_DATA:
563 case ACAMERA_SENSOR_TEST_PATTERN_MODE:
Jayant Chowdharyb6be3c42020-11-15 10:44:38 -0800564 case ACAMERA_SENSOR_PIXEL_MODE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800565 case ACAMERA_SHADING_MODE:
566 case ACAMERA_STATISTICS_FACE_DETECT_MODE:
567 case ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE:
568 case ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE:
Chien-Yu Chen5ca4a9b2018-01-18 12:23:50 -0800569 case ACAMERA_STATISTICS_OIS_DATA_MODE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800570 case ACAMERA_TONEMAP_CURVE_BLUE:
571 case ACAMERA_TONEMAP_CURVE_GREEN:
572 case ACAMERA_TONEMAP_CURVE_RED:
573 case ACAMERA_TONEMAP_MODE:
574 case ACAMERA_TONEMAP_GAMMA:
575 case ACAMERA_TONEMAP_PRESET_CURVE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800576 case ACAMERA_BLACK_LEVEL_LOCK:
Eino-Ville Talvala2d960922018-03-13 19:46:23 -0700577 case ACAMERA_DISTORTION_CORRECTION_MODE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800578 return true;
579 default:
580 return false;
581 }
582}
583
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800584// System tags that should be hidden from users
585std::unordered_set<uint32_t> ACameraMetadata::sSystemTags ({
586 ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
587 ANDROID_CONTROL_AE_PRECAPTURE_ID,
588 ANDROID_CONTROL_AF_TRIGGER_ID,
Shuzhen Wang3c00b092022-11-08 22:53:07 +0000589 ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER,
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800590 ANDROID_DEMOSAIC_MODE,
591 ANDROID_EDGE_STRENGTH,
592 ANDROID_FLASH_FIRING_POWER,
593 ANDROID_FLASH_FIRING_TIME,
594 ANDROID_FLASH_COLOR_TEMPERATURE,
595 ANDROID_FLASH_MAX_ENERGY,
596 ANDROID_FLASH_INFO_CHARGE_DURATION,
597 ANDROID_JPEG_MAX_SIZE,
598 ANDROID_JPEG_SIZE,
599 ANDROID_NOISE_REDUCTION_STRENGTH,
600 ANDROID_QUIRKS_METERING_CROP_REGION,
601 ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO,
602 ANDROID_QUIRKS_USE_ZSL_FORMAT,
603 ANDROID_REQUEST_INPUT_STREAMS,
604 ANDROID_REQUEST_METADATA_MODE,
605 ANDROID_REQUEST_OUTPUT_STREAMS,
606 ANDROID_REQUEST_TYPE,
607 ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS,
608 ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
609 ANDROID_SCALER_AVAILABLE_RAW_SIZES,
610 ANDROID_SENSOR_BASE_GAIN_FACTOR,
611 ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS,
612 ANDROID_SENSOR_TEMPERATURE,
613 ANDROID_SENSOR_PROFILE_HUE_SAT_MAP,
614 ANDROID_SENSOR_PROFILE_TONE_CURVE,
615 ANDROID_SENSOR_OPAQUE_RAW_SIZE,
Jayant Chowdharyb6be3c42020-11-15 10:44:38 -0800616 ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION,
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800617 ANDROID_SHADING_STRENGTH,
618 ANDROID_STATISTICS_HISTOGRAM_MODE,
619 ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
620 ANDROID_STATISTICS_HISTOGRAM,
621 ANDROID_STATISTICS_SHARPNESS_MAP,
622 ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
623 ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
624 ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
625 ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
Yin-Chia Yeh2be96a22018-09-17 11:51:24 -0700626 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION,
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800627 ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800628 ANDROID_HEIC_INFO_SUPPORTED,
629 ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
Yin-Chia Yeh8aac03f2016-03-03 15:45:23 -0800630});
631
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800632/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
633 * End generated code
634 *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/