libcamera: include/libcamera/internal/ipa_data_serializer.h Source File

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>
22#include <libcamera/ipa/ipa_interface.h>
23
24#include "libcamera/internal/byte_stream_buffer.h"
25#include "libcamera/internal/camera_sensor.h"
26#include "libcamera/internal/control_serializer.h"
27
28namespace libcamera {
29
30 LOG_DECLARE_CATEGORY(IPADataSerializer)
31
32namespace {
33
34template<typename T,
35 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>
66 class IPADataSerializer
67{
68public:
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 */
103template<typename V>
104class IPADataSerializer<std::vector<V>>
105{
106public:
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) =
123 IPADataSerializer<V>::serialize(it, cs);
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 */
200template<typename K, typename V>
201class IPADataSerializer<std::map<K, V>>
202{
203public:
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 */
byte_stream_buffer.h
Managed memory container for serialized data.
camera_sensor.h
A camera sensor.
libcamera::ControlSerializer
Serializer and deserializer for control-related classes.
Definition: control_serializer.h:21
libcamera::IPADataSerializer
IPA Data Serializer.
Definition: ipa_data_serializer.h:67
libcamera::IPADataSerializer::deserialize
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.
libcamera::IPADataSerializer::deserialize
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.
libcamera::IPADataSerializer::deserialize
static T deserialize(const std::vector< uint8_t > &data, ControlSerializer *cs=nullptr)
Deserialize byte vector into an object.
libcamera::IPADataSerializer::deserialize
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.
libcamera::IPADataSerializer::serialize
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.
control_ids.h
Camera control identifiers.
control_serializer.h
Serialization and deserialization helpers for controls.
framebuffer.h
Frame buffer handling.
geometry.h
Data structures related to geometric objects.
ipa_interface.h
Image Processing Algorithm interface.
log.h
Logging infrastructure.
LOG_DECLARE_CATEGORY
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
ASSERT
#define ASSERT(condition)
Abort program execution if assertion fails.
libcamera
Top-level libcamera namespace.
Definition: backtrace.h:17