libcamera  v0.0.0+3695-a2c715d8
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 
17 #include <libcamera/base/log.h>
18 
19 #include <libcamera/control_ids.h>
20 #include <libcamera/framebuffer.h>
21 #include <libcamera/geometry.h>
23 
27 
28 namespace libcamera {
29 
30 LOG_DECLARE_CATEGORY(IPADataSerializer)
31 
32 namespace {
33 
34 template<typename T,
35  typename std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
36 void 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 
43 template<typename T,
44  std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
45 T 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 
56 template<typename T,
57  std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
58 T readPOD(std::vector<uint8_t> &vec, size_t pos)
59 {
60  return readPOD<T>(vec.cbegin(), pos, vec.end());
61 }
62 
63 } /* namespace */
64 
65 template<typename T>
67 {
68 public:
69  static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
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<SharedFD> &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<SharedFD>::const_iterator fdsBegin,
84  std::vector<SharedFD>::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  */
103 template<typename V>
104 class IPADataSerializer<std::vector<V>>
105 {
106 public:
107  static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
108  serialize(const std::vector<V> &data, ControlSerializer *cs = nullptr)
109  {
110  std::vector<uint8_t> dataVec;
111  std::vector<SharedFD> 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<SharedFD> 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<SharedFD> 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<SharedFD> &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<SharedFD>::const_iterator fdsBegin,
157  [[maybe_unused]] std::vector<SharedFD>::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<SharedFD>::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  */
200 template<typename K, typename V>
201 class IPADataSerializer<std::map<K, V>>
202 {
203 public:
204  static std::tuple<std::vector<uint8_t>, std::vector<SharedFD>>
205  serialize(const std::map<K, V> &data, ControlSerializer *cs = nullptr)
206  {
207  std::vector<uint8_t> dataVec;
208  std::vector<SharedFD> 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<SharedFD> fvec;
218 
219  std::tie(dvec, fvec) =
220  IPADataSerializer<K>::serialize(it.first, cs);
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<SharedFD> 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<SharedFD> &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<SharedFD>::const_iterator fdsBegin,
263  [[maybe_unused]] std::vector<SharedFD>::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<SharedFD>::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 */
Frame buffer handling.
Managed memory container for serialized data.
Camera control identifiers.
Image Processing Algorithm interface.
Top-level libcamera namespace.
Definition: backtrace.h:17
#define ASSERT(condition)
Abort program execution if assertion fails.
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
A camera sensor.
Serializer and deserializer for control-related classes.
Definition: control_serializer.h:20
static T deserialize(const std::vector< uint8_t > &data, ControlSerializer *cs=nullptr)
Deserialize byte vector into an object.
IPA Data Serializer.
Definition: ipa_data_serializer.h:66
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.
Data structures related to geometric objects.
Logging infrastructure.
Serialization and deserialization helpers for controls.