libcamera v0.0.0+1-ab0bf965
Supporting cameras in Linux since 2019
ipa_data_serializer.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2020, Google Inc.
4 *
5 * ipa_data_serializer.h - Image Processing Algorithm data serializer
6 */
7#ifndef __LIBCAMERA_INTERNAL_IPA_DATA_SERIALIZER_H__
8#define __LIBCAMERA_INTERNAL_IPA_DATA_SERIALIZER_H__
9
10#include <deque>
11#include <iostream>
12#include <string.h>
13#include <tuple>
14#include <type_traits>
15#include <vector>
16
17#include <libcamera/base/log.h>
18
21#include <libcamera/geometry.h>
23
27
28namespace libcamera {
29
30LOG_DECLARE_CATEGORY(IPADataSerializer)
31
32namespace {
33
34template<typename T,
35 typename std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
36void appendPOD(std::vector<uint8_t> &vec, T val)
37{
38 constexpr size_t byteWidth = sizeof(val);
39 vec.resize(vec.size() + byteWidth);
40 memcpy(&*(vec.end() - byteWidth), &val, byteWidth);
41}
42
43template<typename T,
44 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
45T readPOD(std::vector<uint8_t>::const_iterator it, size_t pos,
46 std::vector<uint8_t>::const_iterator end)
47{
48 ASSERT(pos + it < end);
49
50 T ret = 0;
51 memcpy(&ret, &(*(it + pos)), sizeof(ret));
52
53 return ret;
54}
55
56template<typename T,
57 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
58T readPOD(std::vector<uint8_t> &vec, size_t pos)
59{
60 return readPOD<T>(vec.cbegin(), pos, vec.end());
61}
62
63} /* namespace */
64
65template<typename T>
67{
68public:
69 static std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
70 serialize(const T &data, ControlSerializer *cs = nullptr);
71
72 static T deserialize(const std::vector<uint8_t> &data,
73 ControlSerializer *cs = nullptr);
74 static T deserialize(std::vector<uint8_t>::const_iterator dataBegin,
75 std::vector<uint8_t>::const_iterator dataEnd,
76 ControlSerializer *cs = nullptr);
77
78 static T deserialize(const std::vector<uint8_t> &data,
79 const std::vector<FileDescriptor> &fds,
80 ControlSerializer *cs = nullptr);
81 static T deserialize(std::vector<uint8_t>::const_iterator dataBegin,
82 std::vector<uint8_t>::const_iterator dataEnd,
83 std::vector<FileDescriptor>::const_iterator fdsBegin,
84 std::vector<FileDescriptor>::const_iterator fdsEnd,
85 ControlSerializer *cs = nullptr);
86};
87
88#ifndef __DOXYGEN__
89
90/*
91 * Serialization format for vector of type V:
92 *
93 * 4 bytes - uint32_t Length of vector, in number of elements
94 *
95 * For every element in the vector:
96 *
97 * 4 bytes - uint32_t Size of element, in bytes
98 * 4 bytes - uint32_t Number of fds for the element
99 * X bytes - Serialized element
100 *
101 * \todo Support elements that are references
102 */
103template<typename V>
104class IPADataSerializer<std::vector<V>>
105{
106public:
107 static std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
108 serialize(const std::vector<V> &data, ControlSerializer *cs = nullptr)
109 {
110 std::vector<uint8_t> dataVec;
111 std::vector<FileDescriptor> fdsVec;
112
113 /* Serialize the length. */
114 uint32_t vecLen = data.size();
115 appendPOD<uint32_t>(dataVec, vecLen);
116
117 /* Serialize the members. */
118 for (auto const &it : data) {
119 std::vector<uint8_t> dvec;
120 std::vector<FileDescriptor> fvec;
121
122 std::tie(dvec, fvec) =
124
125 appendPOD<uint32_t>(dataVec, dvec.size());
126 appendPOD<uint32_t>(dataVec, fvec.size());
127
128 dataVec.insert(dataVec.end(), dvec.begin(), dvec.end());
129 fdsVec.insert(fdsVec.end(), fvec.begin(), fvec.end());
130 }
131
132 return { dataVec, fdsVec };
133 }
134
135 static std::vector<V> deserialize(std::vector<uint8_t> &data, ControlSerializer *cs = nullptr)
136 {
137 return deserialize(data.cbegin(), data.end(), cs);
138 }
139
140 static std::vector<V> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
141 std::vector<uint8_t>::const_iterator dataEnd,
142 ControlSerializer *cs = nullptr)
143 {
144 std::vector<FileDescriptor> fds;
145 return deserialize(dataBegin, dataEnd, fds.cbegin(), fds.end(), cs);
146 }
147
148 static std::vector<V> deserialize(std::vector<uint8_t> &data, std::vector<FileDescriptor> &fds,
149 ControlSerializer *cs = nullptr)
150 {
151 return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs);
152 }
153
154 static std::vector<V> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
155 std::vector<uint8_t>::const_iterator dataEnd,
156 std::vector<FileDescriptor>::const_iterator fdsBegin,
157 [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsEnd,
158 ControlSerializer *cs = nullptr)
159 {
160 uint32_t vecLen = readPOD<uint32_t>(dataBegin, 0, dataEnd);
161 std::vector<V> ret(vecLen);
162
163 std::vector<uint8_t>::const_iterator dataIter = dataBegin + 4;
164 std::vector<FileDescriptor>::const_iterator fdIter = fdsBegin;
165 for (uint32_t i = 0; i < vecLen; i++) {
166 uint32_t sizeofData = readPOD<uint32_t>(dataIter, 0, dataEnd);
167 uint32_t sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
168 dataIter += 8;
169
170 ret[i] = IPADataSerializer<V>::deserialize(dataIter,
171 dataIter + sizeofData,
172 fdIter,
173 fdIter + sizeofFds,
174 cs);
175
176 dataIter += sizeofData;
177 fdIter += sizeofFds;
178 }
179
180 return ret;
181 }
182};
183
184/*
185 * Serialization format for map of key type K and value type V:
186 *
187 * 4 bytes - uint32_t Length of map, in number of pairs
188 *
189 * For every pair in the map:
190 *
191 * 4 bytes - uint32_t Size of key, in bytes
192 * 4 bytes - uint32_t Number of fds for the key
193 * X bytes - Serialized key
194 * 4 bytes - uint32_t Size of value, in bytes
195 * 4 bytes - uint32_t Number of fds for the value
196 * X bytes - Serialized value
197 *
198 * \todo Support keys or values that are references
199 */
200template<typename K, typename V>
201class IPADataSerializer<std::map<K, V>>
202{
203public:
204 static std::tuple<std::vector<uint8_t>, std::vector<FileDescriptor>>
205 serialize(const std::map<K, V> &data, ControlSerializer *cs = nullptr)
206 {
207 std::vector<uint8_t> dataVec;
208 std::vector<FileDescriptor> fdsVec;
209
210 /* Serialize the length. */
211 uint32_t mapLen = data.size();
212 appendPOD<uint32_t>(dataVec, mapLen);
213
214 /* Serialize the members. */
215 for (auto const &it : data) {
216 std::vector<uint8_t> dvec;
217 std::vector<FileDescriptor> fvec;
218
219 std::tie(dvec, fvec) =
221
222 appendPOD<uint32_t>(dataVec, dvec.size());
223 appendPOD<uint32_t>(dataVec, fvec.size());
224
225 dataVec.insert(dataVec.end(), dvec.begin(), dvec.end());
226 fdsVec.insert(fdsVec.end(), fvec.begin(), fvec.end());
227
228 std::tie(dvec, fvec) =
229 IPADataSerializer<V>::serialize(it.second, cs);
230
231 appendPOD<uint32_t>(dataVec, dvec.size());
232 appendPOD<uint32_t>(dataVec, fvec.size());
233
234 dataVec.insert(dataVec.end(), dvec.begin(), dvec.end());
235 fdsVec.insert(fdsVec.end(), fvec.begin(), fvec.end());
236 }
237
238 return { dataVec, fdsVec };
239 }
240
241 static std::map<K, V> deserialize(std::vector<uint8_t> &data, ControlSerializer *cs = nullptr)
242 {
243 return deserialize(data.cbegin(), data.end(), cs);
244 }
245
246 static std::map<K, V> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
247 std::vector<uint8_t>::const_iterator dataEnd,
248 ControlSerializer *cs = nullptr)
249 {
250 std::vector<FileDescriptor> fds;
251 return deserialize(dataBegin, dataEnd, fds.cbegin(), fds.end(), cs);
252 }
253
254 static std::map<K, V> deserialize(std::vector<uint8_t> &data, std::vector<FileDescriptor> &fds,
255 ControlSerializer *cs = nullptr)
256 {
257 return deserialize(data.cbegin(), data.end(), fds.cbegin(), fds.end(), cs);
258 }
259
260 static std::map<K, V> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
261 std::vector<uint8_t>::const_iterator dataEnd,
262 std::vector<FileDescriptor>::const_iterator fdsBegin,
263 [[maybe_unused]] std::vector<FileDescriptor>::const_iterator fdsEnd,
264 ControlSerializer *cs = nullptr)
265 {
266 std::map<K, V> ret;
267
268 uint32_t mapLen = readPOD<uint32_t>(dataBegin, 0, dataEnd);
269
270 std::vector<uint8_t>::const_iterator dataIter = dataBegin + 4;
271 std::vector<FileDescriptor>::const_iterator fdIter = fdsBegin;
272 for (uint32_t i = 0; i < mapLen; i++) {
273 uint32_t sizeofData = readPOD<uint32_t>(dataIter, 0, dataEnd);
274 uint32_t sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
275 dataIter += 8;
276
277 K key = IPADataSerializer<K>::deserialize(dataIter,
278 dataIter + sizeofData,
279 fdIter,
280 fdIter + sizeofFds,
281 cs);
282
283 dataIter += sizeofData;
284 fdIter += sizeofFds;
285 sizeofData = readPOD<uint32_t>(dataIter, 0, dataEnd);
286 sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
287 dataIter += 8;
288
289 const V value = IPADataSerializer<V>::deserialize(dataIter,
290 dataIter + sizeofData,
291 fdIter,
292 fdIter + sizeofFds,
293 cs);
294 ret.insert({ key, value });
295
296 dataIter += sizeofData;
297 fdIter += sizeofFds;
298 }
299
300 return ret;
301 }
302};
303
304#endif /* __DOXYGEN__ */
305
306} /* namespace libcamera */
307
308#endif /* __LIBCAMERA_INTERNAL_IPA_DATA_SERIALIZER_H__ */
Managed memory container for serialized data.
A camera sensor.
Serializer and deserializer for control-related classes.
Definition: control_serializer.h:21
IPA Data Serializer.
Definition: ipa_data_serializer.h:67
static T deserialize(std::vector< uint8_t >::const_iterator dataBegin, std::vector< uint8_t >::const_iterator dataEnd, std::vector< FileDescriptor >::const_iterator fdsBegin, std::vector< FileDescriptor >::const_iterator fdsEnd, ControlSerializer *cs=nullptr)
Deserialize byte vector and fd vector into an object.
static T deserialize(const std::vector< uint8_t > &data, const std::vector< FileDescriptor > &fds, ControlSerializer *cs=nullptr)
Deserialize byte vector and fd vector into an object.
static T deserialize(std::vector< uint8_t >::const_iterator dataBegin, std::vector< uint8_t >::const_iterator dataEnd, ControlSerializer *cs=nullptr)
Deserialize byte vector into an object.
static T deserialize(const std::vector< uint8_t > &data, ControlSerializer *cs=nullptr)
Deserialize byte vector into an object.
static std::tuple< std::vector< uint8_t >, std::vector< FileDescriptor > > serialize(const T &data, ControlSerializer *cs=nullptr)
Serialize an object into byte vector and fd vector.
Camera control identifiers.
Serialization and deserialization helpers for controls.
Frame buffer handling.
Data structures related to geometric objects.
Image Processing Algorithm interface.
Logging infrastructure.
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
#define ASSERT(condition)
Abort program execution if assertion fails.
Top-level libcamera namespace.
Definition: bound_method.h:15