libcamera  v0.0.1
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  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 */
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(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.
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