about summary refs log tree commit diff
path: root/users/flokli/ipu6-softisp/libcamera/0017-libcamera-debayer_cpu-Add-support-for-8-10-and-12-bp.patch
blob: a5a992f8764d60a9bdc6a651e1f33e9e7ed70e2a (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
From b7b211eb56d98d5b170bd73a23b55aeb45bde8c5 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 14 Dec 2023 19:57:15 +0100
Subject: [PATCH 17/25] libcamera: debayer_cpu: Add support for 8, 10 and 12
 bpp unpacked bayer input

Add support for 8, 10 and 12 bpp unpacked bayer input for all 4 standard
bayer orders.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../internal/software_isp/debayer_cpu.h       |  13 ++
 src/libcamera/software_isp/debayer_cpu.cpp    | 128 ++++++++++++++++++
 2 files changed, 141 insertions(+)

diff --git a/include/libcamera/internal/software_isp/debayer_cpu.h b/include/libcamera/internal/software_isp/debayer_cpu.h
index 78573f44..1147b368 100644
--- a/include/libcamera/internal/software_isp/debayer_cpu.h
+++ b/include/libcamera/internal/software_isp/debayer_cpu.h
@@ -17,6 +17,7 @@
 
 #include <libcamera/base/object.h>
 
+#include "libcamera/internal/bayer_format.h"
 #include "libcamera/internal/software_isp/swstats_cpu.h"
 #include "libcamera/internal/software_isp/debayer.h"
 
@@ -75,11 +76,21 @@ public:
 	 * \return The output frame size.
 	 */
 	unsigned int frameSize() { return outputConfig_.frameSize; }
+
 private:
 	void initLinePointers(const uint8_t *linePointers[], const uint8_t *src);
 	void shiftLinePointers(const uint8_t *linePointers[], const uint8_t *src);
 	void process2(const uint8_t *src, uint8_t *dst);
 	void process4(const uint8_t *src, uint8_t *dst);
+	/* 8-bit raw bayer format */
+	void debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);
+	void debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);
+	/* unpacked 10-bit raw bayer format */
+	void debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);
+	void debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);
+	/* unpacked 12-bit raw bayer format */
+	void debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);
+	void debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);
 	/* CSI-2 packed 10-bit raw bayer format (all the 4 orders) */
 	void debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);
 	void debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);
@@ -103,6 +114,7 @@ private:
 
 	int getInputConfig(PixelFormat inputFormat, DebayerInputConfig &config);
 	int getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config);
+	int setupStandardBayerOrder(BayerFormat::Order order);
 	int setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputFormat);
 
 	uint8_t gamma_[1024];
@@ -119,6 +131,7 @@ private:
 	std::unique_ptr<SwStatsCpu> stats_;
 	uint8_t *lineBuffers_[5];
 	unsigned int lineBufferIndex_;
+	unsigned int x_shift_; /* Offset of 0/1 applied to window_.x */
 	bool enableInputMemcpy_;
 	float gamma_correction_;
 	int measuredFrames_;
diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp
index e0c3c658..7b7623b7 100644
--- a/src/libcamera/software_isp/debayer_cpu.cpp
+++ b/src/libcamera/software_isp/debayer_cpu.cpp
@@ -45,6 +45,11 @@ DebayerCpu::~DebayerCpu()
 		free(lineBuffers_[i]);
 }
 
+#define DECLARE_SRC_POINTERS(pixel_t)                             \
+	const pixel_t *prev = (const pixel_t *)src[0] + x_shift_; \
+	const pixel_t *curr = (const pixel_t *)src[1] + x_shift_; \
+	const pixel_t *next = (const pixel_t *)src[2] + x_shift_;
+
 // RGR
 // GBG
 // RGR
@@ -81,6 +86,70 @@ DebayerCpu::~DebayerCpu()
 	*dst++ = red_[curr[x] / (div)];                                                        \
 	x++;
 
+void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])
+{
+	DECLARE_SRC_POINTERS(uint8_t)
+
+	for (int x = 0; x < (int)window_.width;) {
+		BGGR_BGR888(1, 1, 1)
+		GBRG_BGR888(1, 1, 1)
+	}
+}
+
+void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])
+{
+	DECLARE_SRC_POINTERS(uint8_t)
+
+	for (int x = 0; x < (int)window_.width;) {
+		GRBG_BGR888(1, 1, 1)
+		RGGB_BGR888(1, 1, 1)
+	}
+}
+
+void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])
+{
+	DECLARE_SRC_POINTERS(uint16_t)
+
+	for (int x = 0; x < (int)window_.width;) {
+		/* divide values by 4 for 10 -> 8 bpp value */
+		BGGR_BGR888(1, 1, 4)
+		GBRG_BGR888(1, 1, 4)
+	}
+}
+
+void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])
+{
+	DECLARE_SRC_POINTERS(uint16_t)
+
+	for (int x = 0; x < (int)window_.width;) {
+		/* divide values by 4 for 10 -> 8 bpp value */
+		GRBG_BGR888(1, 1, 4)
+		RGGB_BGR888(1, 1, 4)
+	}
+}
+
+void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])
+{
+	DECLARE_SRC_POINTERS(uint16_t)
+
+	for (int x = 0; x < (int)window_.width;) {
+		/* divide values by 16 for 12 -> 8 bpp value */
+		BGGR_BGR888(1, 1, 16)
+		GBRG_BGR888(1, 1, 16)
+	}
+}
+
+void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])
+{
+	DECLARE_SRC_POINTERS(uint16_t)
+
+	for (int x = 0; x < (int)window_.width;) {
+		/* divide values by 16 for 12 -> 8 bpp value */
+		GRBG_BGR888(1, 1, 16)
+		RGGB_BGR888(1, 1, 16)
+	}
+}
+
 void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])
 {
 	const int width_in_bytes = window_.width * 5 / 4;
@@ -170,6 +239,16 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf
 	BayerFormat bayerFormat =
 		BayerFormat::fromPixelFormat(inputFormat);
 
+	if ((bayerFormat.bitDepth == 8 || bayerFormat.bitDepth == 10 || bayerFormat.bitDepth == 12) &&
+	    bayerFormat.packing == BayerFormat::Packing::None &&
+	    isStandardBayerOrder(bayerFormat.order)) {
+		config.bpp = (bayerFormat.bitDepth + 7) & ~7;
+		config.patternSize.width = 2;
+		config.patternSize.height = 2;
+		config.outputFormats = std::vector<PixelFormat>({ formats::RGB888 });
+		return 0;
+	}
+
 	if (bayerFormat.bitDepth == 10 &&
 	    bayerFormat.packing == BayerFormat::Packing::CSI2 &&
 	    isStandardBayerOrder(bayerFormat.order)) {
@@ -197,12 +276,61 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c
 	return -EINVAL;
 }
 
+/*
+ * Check for standard Bayer orders and set x_shift_ and swap debayer0/1, so that
+ * a single pair of BGGR debayer functions can be used for all 4 standard orders.
+ */
+int DebayerCpu::setupStandardBayerOrder(BayerFormat::Order order)
+{
+	switch (order) {
+	case BayerFormat::BGGR:
+		break;
+	case BayerFormat::GBRG:
+		x_shift_ = 1; /* BGGR -> GBRG */
+		break;
+	case BayerFormat::GRBG:
+		std::swap(debayer0_, debayer1_); /* BGGR -> GRBG */
+		break;
+	case BayerFormat::RGGB:
+		x_shift_ = 1; /* BGGR -> GBRG */
+		std::swap(debayer0_, debayer1_); /* GBRG -> RGGB */
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /* TODO: this ignores outputFormat since there is only 1 supported outputFormat for now */
 int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, [[maybe_unused]] PixelFormat outputFormat)
 {
 	BayerFormat bayerFormat =
 		BayerFormat::fromPixelFormat(inputFormat);
 
+	x_shift_ = 0;
+
+	if ((bayerFormat.bitDepth == 8 || bayerFormat.bitDepth == 10 || bayerFormat.bitDepth == 12) &&
+	    bayerFormat.packing == BayerFormat::Packing::None &&
+	    isStandardBayerOrder(bayerFormat.order)) {
+		switch (bayerFormat.bitDepth) {
+		case 8:
+			debayer0_ = &DebayerCpu::debayer8_BGBG_BGR888;
+			debayer1_ = &DebayerCpu::debayer8_GRGR_BGR888;
+			break;
+		case 10:
+			debayer0_ = &DebayerCpu::debayer10_BGBG_BGR888;
+			debayer1_ = &DebayerCpu::debayer10_GRGR_BGR888;
+			break;
+		case 12:
+			debayer0_ = &DebayerCpu::debayer12_BGBG_BGR888;
+			debayer1_ = &DebayerCpu::debayer12_GRGR_BGR888;
+			break;
+		}
+		setupStandardBayerOrder(bayerFormat.order);
+		return 0;
+	}
+
 	if (bayerFormat.bitDepth == 10 &&
 	    bayerFormat.packing == BayerFormat::Packing::CSI2) {
 		switch (bayerFormat.order) {
-- 
2.43.0