about summary refs log tree commit diff
path: root/users/flokli/ipu6-softisp/libcamera/0007-libcamera-software_isp-Add-SwStats-base-class.patch
blob: 9d6f2ac07fd8a0a6e5e49267b026ac616c45f632 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
From ca3bb6ddf5307537aa05e43d3ec1ff7ffdc0efed Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 7 Dec 2023 13:30:27 +0100
Subject: [PATCH 07/25] libcamera: software_isp: Add SwStats base class

Add a virtual base class for CPU based software statistics gathering
implementations.

The idea is for the implementations to offer a configure function +
functions to gather statistics on a line by line basis. This allows
CPU based software debayering to call into interlace debayering and
statistics gathering on a line by line bases while the input data
is still hot in the cache.

This base class also allows the user of an implementation to specify
a window over which to gather statistics instead of processing the
whole frame; and it allows the implementation to choose to only
process 1/2, 1/4th, etc. of the lines instead of processing all
lines (in the window) by setting y_skip_mask_ from configure().
Skipping columns is left up the line-processing functions provided
by the implementation.

Doxygen documentation by Dennis Bonke.

Co-authored-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
Co-authored-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
---
 include/libcamera/internal/meson.build        |   1 +
 .../internal/software_isp/meson.build         |   6 +
 .../internal/software_isp/swisp_stats.h       |  34 +++
 .../libcamera/internal/software_isp/swstats.h | 215 ++++++++++++++++++
 src/libcamera/meson.build                     |   1 +
 src/libcamera/software_isp/meson.build        |   5 +
 src/libcamera/software_isp/swstats.cpp        |  22 ++
 7 files changed, 284 insertions(+)
 create mode 100644 include/libcamera/internal/software_isp/meson.build
 create mode 100644 include/libcamera/internal/software_isp/swisp_stats.h
 create mode 100644 include/libcamera/internal/software_isp/swstats.h
 create mode 100644 src/libcamera/software_isp/meson.build
 create mode 100644 src/libcamera/software_isp/swstats.cpp

diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build
index 1325941d..caa533c4 100644
--- a/include/libcamera/internal/meson.build
+++ b/include/libcamera/internal/meson.build
@@ -51,3 +51,4 @@ libcamera_internal_headers = files([
 ])
 
 subdir('converter')
+subdir('software_isp')
diff --git a/include/libcamera/internal/software_isp/meson.build b/include/libcamera/internal/software_isp/meson.build
new file mode 100644
index 00000000..1c43acc4
--- /dev/null
+++ b/include/libcamera/internal/software_isp/meson.build
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: CC0-1.0
+
+libcamera_internal_headers += files([
+    'swisp_stats.h',
+    'swstats.h',
+])
diff --git a/include/libcamera/internal/software_isp/swisp_stats.h b/include/libcamera/internal/software_isp/swisp_stats.h
new file mode 100644
index 00000000..07ba7d6a
--- /dev/null
+++ b/include/libcamera/internal/software_isp/swisp_stats.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2023, Linaro Ltd
+ *
+ * swisp_stats.h - Statistics data format used by the software ISP and software IPA
+ */
+
+#pragma once
+
+namespace libcamera {
+
+/**
+ * \brief Struct that holds the statistics for the Software ISP.
+ */
+struct SwIspStats {
+	/**
+	 * \brief Holds the sum of all sampled red pixels.
+	 */
+	unsigned long sumR_;
+	/**
+	 * \brief Holds the sum of all sampled green pixels.
+	 */
+	unsigned long sumG_;
+	/**
+	 * \brief Holds the sum of all sampled blue pixels.
+	 */
+	unsigned long sumB_;
+	/**
+	 * \brief A histogram of luminance values.
+	 */
+	unsigned int y_histogram[16];
+};
+
+} /* namespace libcamera */
diff --git a/include/libcamera/internal/software_isp/swstats.h b/include/libcamera/internal/software_isp/swstats.h
new file mode 100644
index 00000000..dcac7064
--- /dev/null
+++ b/include/libcamera/internal/software_isp/swstats.h
@@ -0,0 +1,215 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2023, Linaro Ltd
+ * Copyright (C) 2023, Red Hat Inc.
+ *
+ * Authors:
+ * Hans de Goede <hdegoede@redhat.com> 
+ *
+ * swstats.h - software statistics base class
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <libcamera/base/log.h>
+#include <libcamera/base/signal.h>
+
+#include <libcamera/geometry.h>
+
+namespace libcamera {
+
+class PixelFormat;
+struct SharedFD;
+struct StreamConfiguration;
+
+LOG_DECLARE_CATEGORY(SwStats)
+
+/**
+ * \class SwStats
+ * \brief Base class for the software ISP statistics.
+ *
+ * Base class for the software ISP statistics.
+ */
+class SwStats
+{
+public:
+	virtual ~SwStats() = 0;
+
+	/**
+	 * \brief Gets wether the statistics object is valid.
+	 * 
+	 * \return true if it's valid, false otherwise.
+	 */
+	virtual bool isValid() const = 0;
+
+	/**
+	 * \brief Configure the statistics object for the passed in input format.
+	 * \param[in] inputCfg The input format
+	 *
+	 * \return 0 on success, a negative errno value on failure.
+	 */
+	virtual int configure(const StreamConfiguration &inputCfg) = 0;
+
+	/**
+	 * \brief Get the file descriptor for the statistics.
+	 *
+	 * \return the file descriptor
+	 */
+	virtual const SharedFD &getStatsFD() = 0;
+
+protected:
+	/**
+	 * \brief Called when there is data to get statistics from.
+	 * \param[in] src The input data
+	 */
+	typedef void (SwStats::*statsProcessFn)(const uint8_t *src[]);
+	/**
+	 * \brief Called when the statistics gathering is done or when a new frame starts.
+	 */
+	typedef void (SwStats::*statsVoidFn)();
+
+	/* Variables set by configure(), used every line */
+	/**
+	 * \brief The function called when a line is ready for statistics processing.
+	 *
+	 * Used for line 0 and 1, repeating if there isn't a 3rd and a 4th line in the bayer order.
+	 */
+	statsProcessFn stats0_;
+	/**
+	 * \brief The function called when a line is ready for statistics processing.
+	 *
+	 * Used for line 3 and 4, only needed if the bayer order has 4 different lines.
+	 */
+	statsProcessFn stats2_;
+
+	/**
+	 * \brief The memory used per pixel in bits.
+	 */
+	unsigned int bpp_;
+	/**
+	 * \brief Skip lines where this bitmask is set in y.
+	 */
+	unsigned int y_skip_mask_;
+
+	/**
+	 * \brief Statistics window, set by setWindow(), used ever line.
+	 */
+	Rectangle window_;
+
+	/**
+	 * \brief The function called at the start of a frame.
+	 */
+	statsVoidFn startFrame_;
+	/**
+	 * \brief The function called at the end of a frame.
+	 */
+	statsVoidFn finishFrame_;
+	/**
+	 * \brief The size of the bayer pattern.
+	 */
+	Size patternSize_;
+	/**
+	 * \brief The offset of x, applied to window_.x for bayer variants.
+	 *
+	 * This can either be 0 or 1.
+	 */
+	unsigned int x_shift_;
+
+public:
+	/**
+	 * \brief Get the pattern size.
+	 *
+	 * For some input-formats, e.g. Bayer data, processing is done multiple lines
+	 * and/or columns at a time. Get width and height at which the (bayer) pattern
+	 * repeats. Window values are rounded down to a multiple of this and the height
+	 * also indicates if processLine2() should be called or not.
+	 * This may only be called after a successful configure() call.
+	 *
+	 * \return the pattern size.
+	 */
+	const Size &patternSize() { return patternSize_; }
+
+	/**
+	 * \brief Specify window coordinates over which to gather statistics.
+	 * \param[in] window The window object.
+	 */
+	void setWindow(Rectangle window)
+	{
+		window_ = window;
+
+		window_.x &= ~(patternSize_.width - 1);
+		window_.x += x_shift_;
+		window_.y &= ~(patternSize_.height - 1);
+
+		/* width_ - x_shift_ to make sure the window fits */
+		window_.width -= x_shift_;
+		window_.width &= ~(patternSize_.width - 1);
+		window_.height &= ~(patternSize_.height - 1);
+	}
+
+	/**
+	 * \brief Reset state to start statistics gathering for a new frame.
+	 * 
+	 * This may only be called after a successful setWindow() call.
+	 */
+	void startFrame()
+	{
+		(this->*startFrame_)();
+	}
+
+	/**
+	 * \brief Process line 0.
+	 * \param[in] y The y coordinate.
+	 * \param[in] src The input data.
+	 *
+	 * This function processes line 0 for input formats with patternSize height == 1.
+	 * It'll process line 0 and 1 for input formats with patternSize height >= 2.
+	 * This function may only be called after a successful setWindow() call.
+	 */
+	void processLine0(unsigned int y, const uint8_t *src[])
+	{
+		if ((y & y_skip_mask_) || y < (unsigned int)window_.y ||
+		    y >= (window_.y + window_.height))
+			return;
+
+		(this->*stats0_)(src);
+	}
+
+	/**
+	 * \brief Process line 2 and 3.
+	 * \param[in] y The y coordinate.
+	 * \param[in] src The input data.
+	 *
+	 * This function processes line 2 and 3 for input formats with patternSize height == 4.
+	 * This function may only be called after a successful setWindow() call.
+	 */
+	void processLine2(unsigned int y, const uint8_t *src[])
+	{
+		if ((y & y_skip_mask_) || y < (unsigned int)window_.y ||
+		    y >= (window_.y + window_.height))
+			return;
+
+		(this->*stats2_)(src);
+	}
+
+	/**
+	 * \brief Finish statistics calculation for the current frame.
+	 * 
+	 * This may only be called after a successful setWindow() call.
+	 */
+	void finishFrame()
+	{
+		(this->*finishFrame_)();
+	}
+
+	/**
+	 * \brief Signals that the statistics are ready.
+	 *
+	 * The int parameter isn't actually used.
+	 */
+	Signal<int> statsReady;
+};
+
+} /* namespace libcamera */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 86494663..3d63e8a2 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -71,6 +71,7 @@ subdir('converter')
 subdir('ipa')
 subdir('pipeline')
 subdir('proxy')
+subdir('software_isp')
 
 null_dep = dependency('', required : false)
 
diff --git a/src/libcamera/software_isp/meson.build b/src/libcamera/software_isp/meson.build
new file mode 100644
index 00000000..9359075d
--- /dev/null
+++ b/src/libcamera/software_isp/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: CC0-1.0
+
+libcamera_sources += files([
+	'swstats.cpp',
+])
diff --git a/src/libcamera/software_isp/swstats.cpp b/src/libcamera/software_isp/swstats.cpp
new file mode 100644
index 00000000..e65a7ada
--- /dev/null
+++ b/src/libcamera/software_isp/swstats.cpp
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2023, Linaro Ltd
+ * Copyright (C) 2023, Red Hat Inc.
+ *
+ * Authors:
+ * Hans de Goede <hdegoede@redhat.com> 
+ *
+ * swstats.cpp - software statistics base class
+ */
+
+#include "libcamera/internal/software_isp/swstats.h"
+
+namespace libcamera {
+
+LOG_DEFINE_CATEGORY(SwStats)
+
+SwStats::~SwStats()
+{
+}
+
+} /* namespace libcamera */
-- 
2.43.0