1 /*
2 * Copyright (C) 2023 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 #include <inttypes.h>
18
19 #include <memory>
20 #include <numeric>
21
22 #include <system/camera_metadata.h>
23
24 #include "debug.h"
25 #include "metadata_utils.h"
26
27 namespace android {
28 namespace hardware {
29 namespace camera {
30 namespace provider {
31 namespace implementation {
32 namespace {
33
34 struct CameraMetadataDeleter {
operator ()android::hardware::camera::provider::implementation::__anon585e4a830111::CameraMetadataDeleter35 void operator()(camera_metadata_t* p) const {
36 free_camera_metadata(p);
37 }
38 };
39
40 using CameraMetadataPtr = std::unique_ptr<camera_metadata_t, CameraMetadataDeleter>;
41
metadataCompactRaw(const camera_metadata_t * raw)42 CameraMetadata metadataCompactRaw(const camera_metadata_t* raw) {
43 const size_t size = get_camera_metadata_compact_size(raw);
44 CameraMetadata r;
45 r.metadata.resize(size);
46 copy_camera_metadata(r.metadata.data(), size, raw);
47 return r;
48 }
49
50 } // namespace
51
metadataCompact(const CameraMetadata & m)52 CameraMetadata metadataCompact(const CameraMetadata& m) {
53 return metadataCompactRaw(reinterpret_cast<const camera_metadata_t*>(m.metadata.data()));
54 }
55
serializeCameraMetadataMap(const CameraMetadataMap & m)56 std::optional<CameraMetadata> serializeCameraMetadataMap(const CameraMetadataMap& m) {
57 const size_t dataSize = std::accumulate(m.begin(), m.end(), 0,
58 [](const size_t z, const CameraMetadataMap::value_type& kv) {
59 return z + ((kv.second.count > 0) ? ((kv.second.data.size() + 7) & ~7U) : 0);
60 }
61 );
62
63 CameraMetadataPtr cm(allocate_camera_metadata(m.size() * 5 / 4, dataSize * 3 / 2));
64
65 unsigned numIncorrectTagDataSize = 0;
66 for (const auto& [tag, value] : m) {
67 if (value.count > 0) {
68 const int tagType = get_camera_metadata_tag_type(tag);
69 const size_t elementSize = camera_metadata_type_size[tagType];
70 const size_t expectedDataSize = value.count * elementSize;
71
72 if (value.data.size() == expectedDataSize) {
73 if (add_camera_metadata_entry(cm.get(), tag, value.data.data(), value.count)) {
74 return FAILURE_V(std::nullopt, "failed to add tag=%s.%s(%u), count=%u",
75 get_camera_metadata_section_name(tag),
76 get_camera_metadata_tag_name(tag), tag,
77 value.count);
78 }
79 } else {
80 ++numIncorrectTagDataSize;
81 ALOGE("%s:%d: Incorrect tag (%s.%s(%u), %s[%u]) data size, "
82 "expected=%zu, actual=%zu", __func__, __LINE__,
83 get_camera_metadata_section_name(tag),
84 get_camera_metadata_tag_name(tag),
85 tag, camera_metadata_type_names[tagType],
86 value.count, expectedDataSize, value.data.size());
87 }
88 }
89 }
90
91 LOG_ALWAYS_FATAL_IF(numIncorrectTagDataSize > 0, "%s:%d: there are %u tags "
92 "with incorrect data size, see the messages above.",
93 __func__, __LINE__, numIncorrectTagDataSize);
94
95 if (sort_camera_metadata(cm.get())) {
96 return FAILURE(std::nullopt);
97 }
98
99 return metadataCompactRaw(cm.get());
100 }
101
parseCameraMetadataMap(const CameraMetadata & m)102 CameraMetadataMap parseCameraMetadataMap(const CameraMetadata& m) {
103 const camera_metadata_t* const raw =
104 reinterpret_cast<const camera_metadata_t*>(m.metadata.data());
105 const size_t n = get_camera_metadata_entry_count(raw);
106
107 CameraMetadataMap r;
108 for (size_t i = 0; i < n; ++i) {
109 camera_metadata_ro_entry_t e;
110 if (get_camera_metadata_ro_entry(raw, i, &e)) {
111 ALOGW("%s:%d get_camera_metadata_ro_entry(%zu) failed",
112 __func__, __LINE__, i);
113 } else {
114 auto& v = r[e.tag];
115 v.count = e.count;
116 const size_t sz = camera_metadata_type_size[e.type] * e.count;
117 v.data.assign(e.data.u8, e.data.u8 + sz);
118 }
119 }
120 return r;
121 }
122
metadataSetShutterTimestamp(CameraMetadata * m,const int64_t shutterTimestampNs)123 void metadataSetShutterTimestamp(CameraMetadata* m, const int64_t shutterTimestampNs) {
124 if (m->metadata.empty()) {
125 return;
126 }
127
128 camera_metadata_t* const raw =
129 reinterpret_cast<camera_metadata_t*>(m->metadata.data());
130
131 camera_metadata_ro_entry_t entry;
132 if (find_camera_metadata_ro_entry(raw, ANDROID_SENSOR_TIMESTAMP, &entry)) {
133 ALOGW("%s:%d: find_camera_metadata_ro_entry(ANDROID_SENSOR_TIMESTAMP) failed",
134 __func__, __LINE__);
135 } else if (update_camera_metadata_entry(raw, entry.index, &shutterTimestampNs, 1, nullptr)) {
136 ALOGW("%s:%d: update_camera_metadata_entry(ANDROID_SENSOR_TIMESTAMP) failed",
137 __func__, __LINE__);
138 }
139 }
140
prettyPrintCameraMetadata(const CameraMetadata & m)141 void prettyPrintCameraMetadata(const CameraMetadata& m) {
142 const camera_metadata_t* const raw =
143 reinterpret_cast<const camera_metadata_t*>(m.metadata.data());
144 const size_t n = get_camera_metadata_entry_count(raw);
145
146 for (size_t i = 0; i < n; ++i) {
147 camera_metadata_ro_entry_t e;
148 get_camera_metadata_ro_entry(raw, i, &e);
149 std::vector<char> value;
150
151 if (e.count > 0) {
152 switch (e.type) {
153 case TYPE_BYTE: {
154 int s = 0;
155 for (unsigned j = 0; j < e.count; ++j) {
156 value.resize(s + 4);
157 s += snprintf(&value[s], value.size() - s, "%s%u",
158 ((j > 0) ? "," : ""), e.data.u8[j]);
159 }
160 }
161 break;
162 case TYPE_INT32: {
163 int s = 0;
164 for (unsigned j = 0; j < e.count; ++j) {
165 value.resize(s + 12);
166 s += snprintf(&value[s], value.size() - s, "%s%d",
167 ((j > 0) ? "," : ""), e.data.i32[j]);
168 }
169 }
170 break;
171 case TYPE_FLOAT: {
172 int s = 0;
173 for (unsigned j = 0; j < e.count; ++j) {
174 value.resize(s + 12);
175 s += snprintf(&value[s], value.size() - s, "%s%g",
176 ((j > 0) ? "," : ""), e.data.f[j]);
177 }
178 }
179 break;
180 case TYPE_INT64: {
181 int s = 0;
182 for (unsigned j = 0; j < e.count; ++j) {
183 value.resize(s + 24);
184 s += snprintf(&value[s], value.size() - s, "%s%" PRId64,
185 ((j > 0) ? "," : ""), e.data.i64[j]);
186 }
187 }
188 break;
189 case TYPE_DOUBLE: {
190 int s = 0;
191 for (unsigned j = 0; j < e.count; ++j) {
192 value.resize(s + 25);
193 s += snprintf(&value[s], value.size() - s, "%s%g",
194 ((j > 0) ? "," : ""), e.data.d[j]);
195 }
196 }
197 break;
198 case TYPE_RATIONAL: {
199 int s = 0;
200 for (unsigned j = 0; j < e.count; ++j) {
201 value.resize(s + 25);
202 s += snprintf(&value[s], value.size() - s, "%s%d/%d",
203 ((j > 0) ? "," : ""),
204 e.data.r[j].numerator,
205 e.data.r[j].denominator);
206 }
207 }
208 break;
209 default:
210 value.resize(12);
211 snprintf(&value[0], value.size(), "%s", "bad type");
212 break;
213 }
214 } else {
215 value.resize(8);
216 snprintf(&value[0], value.size(), "%s", "empty");
217 }
218
219 ALOGD("%s:%d i=%zu tag=%s.%s(%u),%s[%zu]: %s", __func__, __LINE__, i,
220 get_camera_metadata_section_name(e.tag),
221 get_camera_metadata_tag_name(e.tag),
222 e.tag, camera_metadata_type_names[e.type], e.count, value.data());
223 }
224 }
225
226 } // namespace implementation
227 } // namespace provider
228 } // namespace camera
229 } // namespace hardware
230 } // namespace android
231