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