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