libcamera v0.1.0+127-8e215127-dirty (2023-12-02T01:06:12+00:00)
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
8#pragma once
9
10#include <deque>
11#include <iostream>
12#include <string.h>
13#include <tuple>
14#include <type_traits>
15#include <vector>
16
18#include <libcamera/base/log.h>
19
22#include <libcamera/geometry.h>
24
28
29namespace libcamera {
30
31LOG_DECLARE_CATEGORY(IPADataSerializer)
32
33namespace {
34
35template<typename T,
36 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
37void appendPOD(std::vector<uint8_t> &vec, T val)
38{
39 constexpr size_t byteWidth = sizeof(val);
40 vec.resize(vec.size() + byteWidth);
41 memcpy(&*(vec.end() - byteWidth), &val, byteWidth);
42}
43
44template<typename T,
45 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
46T readPOD(std::vector<uint8_t>::const_iterator it, size_t pos,
47 std::vector<uint8_t>::const_iterator end)
48{
49 ASSERT(pos + it < end);
50
51 T ret = 0;
52 memcpy(&ret, &(*(it + pos)), sizeof(ret));
53
54 return ret;
55}
56
57template<typename T,
58 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
59T readPOD(std::vector<uint8_t> &vec, size_t pos)
60{
61 return readPOD<T>(vec.cbegin(), pos, vec.end());
62}
63
64} /* namespace */
65
66template<typename T>
68{
69public:
70 static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
71 serialize(const T &data, ControlSerializer *cs = nullptr);
72
73 static T deserialize(const std::vector<uint8_t> &data,
74 ControlSerializer *cs = nullptr);
75 static T deserialize(std::vector<uint8_t>::const_iterator dataBegin,
76 std::vector<uint8_t>::const_iterator dataEnd,
77 ControlSerializer *cs = nullptr);
78
79 static T deserialize(const std::vector<uint8_t> &data,
80 const std::vector<SharedFD> &fds,
81 ControlSerializer *cs = nullptr);
82 static T deserialize(std::vector<uint8_t>::const_iterator dataBegin,
83 std::vector<uint8_t>::const_iterator dataEnd,
84 std::vector<SharedFD>::const_iterator fdsBegin,
85 std::vector<SharedFD>::const_iterator fdsEnd,
86 ControlSerializer *cs = nullptr);
87};
88
89#ifndef __DOXYGEN__
90
91/*
92 * Serialization format for vector of type V:
93 *
94 * 4 bytes - uint32_t Length of vector, in number of elements
95 *
96 * For every element in the vector:
97 *
98 * 4 bytes - uint32_t Size of element, in bytes
99 * 4 bytes - uint32_t Number of fds for the element
100 * X bytes - Serialized element
101 *
102 * \todo Support elements that are references
103 */
104template<typename V>
105class IPADataSerializer<std::vector<V>>
106{
107public:
108 static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
109 serialize(const std::vector<V> &data, ControlSerializer *cs = nullptr)
110 {
111 std::vector<uint8_t> dataVec;
112 std::vector<SharedFD> fdsVec;
113
114 /* Serialize the length. */
115 uint32_t vecLen = data.size();
116 appendPOD<uint32_t>(dataVec, vecLen);
117
118 /* Serialize the members. */
119 for (auto const &it : data) {
120 std::vector<uint8_t> dvec;
121 std::vector<SharedFD> fvec;
122
123 std::tie(dvec, fvec) =
125
126 appendPOD<uint32_t>(dataVec, dvec.size());
127 appendPOD<uint32_t>(dataVec, fvec.size());
128
129 dataVec.insert(dataVec.end(), dvec.begin(), dvec.end());
130 fdsVec.insert(fdsVec.end(), fvec.begin(), fvec.end());
131 }
132
133 return { dataVec, fdsVec };
134 }
135
136 static std::vector<V> deserialize(std::vector<uint8_t> &data, ControlSerializer *cs = nullptr)
137 {
138 return deserialize(data.cbegin(), data.cend(), cs);
139 }
140
141 static std::vector<V> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
142 std::vector<uint8_t>::const_iterator dataEnd,
143 ControlSerializer *cs = nullptr)
144 {
145 std::vector<SharedFD> fds;
146 return deserialize(dataBegin, dataEnd, fds.cbegin(), fds.cend(), cs);
147 }
148
149 static std::vector<V> deserialize(std::vector<uint8_t> &data, std::vector<SharedFD> &fds,
150 ControlSerializer *cs = nullptr)
151 {
152 return deserialize(data.cbegin(), data.cend(), fds.cbegin(), fds.cend(), cs);
153 }
154
155 static std::vector<V> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
156 std::vector<uint8_t>::const_iterator dataEnd,
157 std::vector<SharedFD>::const_iterator fdsBegin,
158 [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
159 ControlSerializer *cs = nullptr)
160 {
161 uint32_t vecLen = readPOD<uint32_t>(dataBegin, 0, dataEnd);
162 std::vector<V> ret(vecLen);
163
164 std::vector<uint8_t>::const_iterator dataIter = dataBegin + 4;
165 std::vector<SharedFD>::const_iterator fdIter = fdsBegin;
166 for (uint32_t i = 0; i < vecLen; i++) {
167 uint32_t sizeofData = readPOD<uint32_t>(dataIter, 0, dataEnd);
168 uint32_t sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
169 dataIter += 8;
170
171 ret[i] = IPADataSerializer<V>::deserialize(dataIter,
172 dataIter + sizeofData,
173 fdIter,
174 fdIter + sizeofFds,
175 cs);
176
177 dataIter += sizeofData;
178 fdIter += sizeofFds;
179 }
180
181 return ret;
182 }
183};
184
185/*
186 * Serialization format for map of key type K and value type V:
187 *
188 * 4 bytes - uint32_t Length of map, in number of pairs
189 *
190 * For every pair in the map:
191 *
192 * 4 bytes - uint32_t Size of key, in bytes
193 * 4 bytes - uint32_t Number of fds for the key
194 * X bytes - Serialized key
195 * 4 bytes - uint32_t Size of value, in bytes
196 * 4 bytes - uint32_t Number of fds for the value
197 * X bytes - Serialized value
198 *
199 * \todo Support keys or values that are references
200 */
201template<typename K, typename V>
202class IPADataSerializer<std::map<K, V>>
203{
204public:
205 static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
206 serialize(const std::map<K, V> &data, ControlSerializer *cs = nullptr)
207 {
208 std::vector<uint8_t> dataVec;
209 std::vector<SharedFD> fdsVec;
210
211 /* Serialize the length. */
212 uint32_t mapLen = data.size();
213 appendPOD<uint32_t>(dataVec, mapLen);
214
215 /* Serialize the members. */
216 for (auto const &it : data) {
217 std::vector<uint8_t> dvec;
218 std::vector<SharedFD> fvec;
219
220 std::tie(dvec, fvec) =
222
223 appendPOD<uint32_t>(dataVec, dvec.size());
224 appendPOD<uint32_t>(dataVec, fvec.size());
225
226 dataVec.insert(dataVec.end(), dvec.begin(), dvec.end());
227 fdsVec.insert(fdsVec.end(), fvec.begin(), fvec.end());
228
229 std::tie(dvec, fvec) =
230 IPADataSerializer<V>::serialize(it.second, cs);
231
232 appendPOD<uint32_t>(dataVec, dvec.size());
233 appendPOD<uint32_t>(dataVec, fvec.size());
234
235 dataVec.insert(dataVec.end(), dvec.begin(), dvec.end());
236 fdsVec.insert(fdsVec.end(), fvec.begin(), fvec.end());
237 }
238
239 return { dataVec, fdsVec };
240 }
241
242 static std::map<K, V> deserialize(std::vector<uint8_t> &data, ControlSerializer *cs = nullptr)
243 {
244 return deserialize(data.cbegin(), data.cend(), cs);
245 }
246
247 static std::map<K, V> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
248 std::vector<uint8_t>::const_iterator dataEnd,
249 ControlSerializer *cs = nullptr)
250 {
251 std::vector<SharedFD> fds;
252 return deserialize(dataBegin, dataEnd, fds.cbegin(), fds.cend(), cs);
253 }
254
255 static std::map<K, V> deserialize(std::vector<uint8_t> &data, std::vector<SharedFD> &fds,
256 ControlSerializer *cs = nullptr)
257 {
258 return deserialize(data.cbegin(), data.cend(), fds.cbegin(), fds.cend(), cs);
259 }
260
261 static std::map<K, V> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
262 std::vector<uint8_t>::const_iterator dataEnd,
263 std::vector<SharedFD>::const_iterator fdsBegin,
264 [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
265 ControlSerializer *cs = nullptr)
266 {
267 std::map<K, V> ret;
268
269 uint32_t mapLen = readPOD<uint32_t>(dataBegin, 0, dataEnd);
270
271 std::vector<uint8_t>::const_iterator dataIter = dataBegin + 4;
272 std::vector<SharedFD>::const_iterator fdIter = fdsBegin;
273 for (uint32_t i = 0; i < mapLen; i++) {
274 uint32_t sizeofData = readPOD<uint32_t>(dataIter, 0, dataEnd);
275 uint32_t sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
276 dataIter += 8;
277
278 K key = IPADataSerializer<K>::deserialize(dataIter,
279 dataIter + sizeofData,
280 fdIter,
281 fdIter + sizeofFds,
282 cs);
283
284 dataIter += sizeofData;
285 fdIter += sizeofFds;
286 sizeofData = readPOD<uint32_t>(dataIter, 0, dataEnd);
287 sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
288 dataIter += 8;
289
290 const V value = IPADataSerializer<V>::deserialize(dataIter,
291 dataIter + sizeofData,
292 fdIter,
293 fdIter + sizeofFds,
294 cs);
295 ret.insert({ key, value });
296
297 dataIter += sizeofData;
298 fdIter += sizeofFds;
299 }
300
301 return ret;
302 }
303};
304
305/* Serialization format for Flags is same as for PODs */
306template<typename E>
307class IPADataSerializer<Flags<E>>
308{
309public:
310 static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
311 serialize(const Flags<E> &data, [[maybe_unused]] ControlSerializer *cs = nullptr)
312 {
313 std::vector<uint8_t> dataVec;
314 dataVec.reserve(sizeof(Flags<E>));
315 appendPOD<uint32_t>(dataVec, static_cast<typename Flags<E>::Type>(data));
316
317 return { dataVec, {} };
318 }
319
320 static Flags<E> deserialize(std::vector<uint8_t> &data,
321 [[maybe_unused]] ControlSerializer *cs = nullptr)
322 {
323 return deserialize(data.cbegin(), data.cend());
324 }
325
326 static Flags<E> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
327 std::vector<uint8_t>::const_iterator dataEnd,
328 [[maybe_unused]] ControlSerializer *cs = nullptr)
329 {
330 return Flags<E>{ static_cast<E>(readPOD<uint32_t>(dataBegin, 0, dataEnd)) };
331 }
332
333 static Flags<E> deserialize(std::vector<uint8_t> &data,
334 [[maybe_unused]] std::vector<SharedFD> &fds,
335 [[maybe_unused]] ControlSerializer *cs = nullptr)
336 {
337 return deserialize(data.cbegin(), data.cend());
338 }
339
340 static Flags<E> deserialize(std::vector<uint8_t>::const_iterator dataBegin,
341 std::vector<uint8_t>::const_iterator dataEnd,
342 [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsBegin,
343 [[maybe_unused]] std::vector<SharedFD>::const_iterator fdsEnd,
344 [[maybe_unused]] ControlSerializer *cs = nullptr)
345 {
346 return deserialize(dataBegin, dataEnd);
347 }
348};
349
350#endif /* __DOXYGEN__ */
351
352} /* namespace libcamera */
Managed memory container for serialized data.
A camera sensor.
Serializer and deserializer for control-related classes.
Definition: control_serializer.h:21
std::underlying_type_t< E > Type
The underlying data type of the enum.
Definition: flags.h:21
IPA Data Serializer.
Definition: ipa_data_serializer.h:68
static T deserialize(const std::vector< uint8_t > &data, const std::vector< SharedFD > &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 T deserialize(std::vector< uint8_t >::const_iterator dataBegin, std::vector< uint8_t >::const_iterator dataEnd, std::vector< SharedFD >::const_iterator fdsBegin, std::vector< SharedFD >::const_iterator fdsEnd, ControlSerializer *cs=nullptr)
Deserialize byte vector and fd vector into an object.
static std::tuple< std::vector< uint8_t >, std::vector< SharedFD > > 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.
Enum-based bit fields.
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: backtrace.h:17