af9a8d372b
This code adds support for the ipu6 webcams via libcamera, based on the work in https://copr.fedorainfracloud.org/coprs/jwrdegoede/ipu6-softisp/. It's supposed to be included in your NixOS configuration imports. Change-Id: Ifb71999ad61161fa23506b97cb449f73fb1270e3 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10709 Tested-by: BuildkiteCI Reviewed-by: flokli <flokli@flokli.de> Autosubmit: flokli <flokli@flokli.de>
315 lines
9.5 KiB
Diff
315 lines
9.5 KiB
Diff
From e3638943a8bd3f93b8d81c3996035c60755b97f6 Mon Sep 17 00:00:00 2001
|
|
From: Marttico <g.martti@gmail.com>
|
|
Date: Wed, 20 Dec 2023 20:28:12 +0100
|
|
Subject: [PATCH 22/25] libcamera: debayer_cpu: Add support for 10bpp
|
|
IGIG_GBGR_IGIG_GRGB input
|
|
|
|
Add support to DebayerCpu for 10bpp IGIG_GBGR_IGIG_GRGB input
|
|
generated by the Omnivision ov01a1s sensor.
|
|
|
|
Co-authored-by: Dennis Bonke <admin@dennisbonke.com>
|
|
Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
|
|
Co-authored-by: Toon Langendam <t.langendam@gmail.com>
|
|
Signed-off-by: Toon Langendam <t.langendam@gmail.com>
|
|
Signed-off-by: Marttico <g.martti@gmail.com>
|
|
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
---
|
|
.../internal/software_isp/debayer_cpu.h | 5 +
|
|
src/libcamera/software_isp/debayer_cpu.cpp | 251 ++++++++++++++++++
|
|
2 files changed, 256 insertions(+)
|
|
|
|
diff --git a/include/libcamera/internal/software_isp/debayer_cpu.h b/include/libcamera/internal/software_isp/debayer_cpu.h
|
|
index bdeab7c0..52af117f 100644
|
|
--- a/include/libcamera/internal/software_isp/debayer_cpu.h
|
|
+++ b/include/libcamera/internal/software_isp/debayer_cpu.h
|
|
@@ -96,6 +96,11 @@ private:
|
|
void debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);
|
|
void debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]);
|
|
void debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]);
|
|
+ /* IGIG_GBGR_IGIG_GRGB unpacked 10-bit raw bayer format */
|
|
+ void debayerIGIG10Line0(uint8_t *dst, const uint8_t *src[]);
|
|
+ void debayerGBGR10Line1(uint8_t *dst, const uint8_t *src[]);
|
|
+ void debayerIGIG10Line2(uint8_t *dst, const uint8_t *src[]);
|
|
+ void debayerGRGB10Line3(uint8_t *dst, const uint8_t *src[]);
|
|
|
|
typedef void (DebayerCpu::*debayerFn)(uint8_t *dst, const uint8_t *src[]);
|
|
|
|
diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp
|
|
index 0edea4d3..41c8805f 100644
|
|
--- a/src/libcamera/software_isp/debayer_cpu.cpp
|
|
+++ b/src/libcamera/software_isp/debayer_cpu.cpp
|
|
@@ -228,6 +228,238 @@ void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])
|
|
}
|
|
}
|
|
|
|
+void DebayerCpu::debayerIGIG10Line0(uint8_t *dst, const uint8_t *src[])
|
|
+{
|
|
+ const uint16_t *prev = (const uint16_t *)src[1];
|
|
+ const uint16_t *curr = (const uint16_t *)src[2];
|
|
+ const uint16_t *next = (const uint16_t *)src[3];
|
|
+
|
|
+ for (int x = 0; x < (int)window_.width;) {
|
|
+ /*
|
|
+ * IGIG line pixel 0: IGIGI
|
|
+ * GBGRG
|
|
+ * IGIGI
|
|
+ * GRGBG
|
|
+ * IGIGI
|
|
+ */
|
|
+ *dst++ = blue_[(prev[x - 1] + next[x + 1]) / 8];
|
|
+ *dst++ = green_[(curr[x - 1] + curr[x + 1] + prev[x] + next[x]) / 16];
|
|
+ *dst++ = red_[(prev[x + 1] + next[x - 1]) / 8];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * IGIG line pixel 1: GIGIG
|
|
+ * BGRGB
|
|
+ * GIGIG
|
|
+ * RGBGR
|
|
+ * GIGIG
|
|
+ */
|
|
+ *dst++ = blue_[next[x] / 4];
|
|
+ *dst++ = green_[curr[x] / 4];
|
|
+ *dst++ = red_[prev[x] / 4];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * IGIG line pixel 2: IGIGI
|
|
+ * GRGBG
|
|
+ * IGIGI
|
|
+ * GBGRG
|
|
+ * IGIGI
|
|
+ */
|
|
+ *dst++ = blue_[(prev[x + 1] + next[x - 1]) / 8];
|
|
+ *dst++ = green_[(curr[x - 1] + curr[x + 1] + prev[x] + next[x]) / 16];
|
|
+ *dst++ = red_[(prev[x - 1] + next[x + 1]) / 8];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * IGIG line pixel 3: GIGIG
|
|
+ * RGBGR
|
|
+ * GIGIG
|
|
+ * BGRGB
|
|
+ * GIGIG
|
|
+ */
|
|
+ *dst++ = blue_[prev[x] / 4];
|
|
+ *dst++ = green_[curr[x] / 4];
|
|
+ *dst++ = red_[next[x] / 4];
|
|
+ x++;
|
|
+ }
|
|
+}
|
|
+
|
|
+void DebayerCpu::debayerGBGR10Line1(uint8_t *dst, const uint8_t *src[])
|
|
+{
|
|
+ const uint16_t *prev2 = (const uint16_t *)src[0];
|
|
+ const uint16_t *prev = (const uint16_t *)src[1];
|
|
+ const uint16_t *curr = (const uint16_t *)src[2];
|
|
+ const uint16_t *next = (const uint16_t *)src[3];
|
|
+ const uint16_t *next2 = (const uint16_t *)src[4];
|
|
+
|
|
+ for (int x = 0; x < (int)window_.width;) {
|
|
+ /*
|
|
+ * GBGR line pixel 0: GBGRG
|
|
+ * IGIGI
|
|
+ * GRGBG
|
|
+ * IGIGI
|
|
+ * GBGRG
|
|
+ */
|
|
+ *dst++ = blue_[curr[x + 1] / 4];
|
|
+ *dst++ = green_[curr[x] / 4];
|
|
+ *dst++ = red_[curr[x - 1] / 4];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * GBGR line pixel 1: BGRGB
|
|
+ * GIGIG
|
|
+ * RGBGR
|
|
+ * GIGIG
|
|
+ * BGRGB
|
|
+ */
|
|
+ *dst++ = blue_[curr[x] / 4];
|
|
+ *dst++ = green_[(curr[x - 1] + curr[x + 1] + prev[x] + next[x]) / 16];
|
|
+ *dst++ = red_[(curr[x - 2] + curr[x + 2] + prev2[x] + next2[x]) / 16];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * GBGR line pixel 2: GRGBG
|
|
+ * IGIGI
|
|
+ * GBGRG
|
|
+ * IGIGI
|
|
+ * GRGBG
|
|
+ */
|
|
+ *dst++ = blue_[curr[x - 1] / 4];
|
|
+ *dst++ = green_[curr[x] / 4];
|
|
+ *dst++ = red_[curr[x + 1] / 4];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * GBGR line pixel 3: RGBGR
|
|
+ * GIGIG
|
|
+ * BGRGB
|
|
+ * GIGIG
|
|
+ * RGBGR
|
|
+ */
|
|
+ *dst++ = blue_[(curr[x - 2] + curr[x + 2] + prev2[x] + next2[x]) / 16];
|
|
+ *dst++ = green_[(curr[x - 1] + curr[x + 1] + prev[x] + next[x]) / 16];
|
|
+ *dst++ = red_[curr[x] / 4];
|
|
+ x++;
|
|
+ }
|
|
+}
|
|
+
|
|
+void DebayerCpu::debayerIGIG10Line2(uint8_t *dst, const uint8_t *src[])
|
|
+{
|
|
+ const uint16_t *prev = (const uint16_t *)src[1];
|
|
+ const uint16_t *curr = (const uint16_t *)src[2];
|
|
+ const uint16_t *next = (const uint16_t *)src[3];
|
|
+
|
|
+ for (int x = 0; x < (int)window_.width;) {
|
|
+ /*
|
|
+ * IGIG line pixel 0: IGIGI
|
|
+ * GRGBG
|
|
+ * IGIGI
|
|
+ * GBGRG
|
|
+ * IGIGI
|
|
+ */
|
|
+ *dst++ = blue_[(prev[x + 1] + next[x - 1]) / 8];
|
|
+ *dst++ = green_[(curr[x - 1] + curr[x + 1] + prev[x] + next[x]) / 16];
|
|
+ *dst++ = red_[(prev[x - 1] + next[x + 1]) / 8];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * IGIG line pixel 1: GIGIG
|
|
+ * RGBGR
|
|
+ * GIGIG
|
|
+ * BGRGB
|
|
+ * GIGIG
|
|
+ */
|
|
+ *dst++ = blue_[prev[x] / 4];
|
|
+ *dst++ = green_[curr[x] / 4];
|
|
+ *dst++ = red_[next[x] / 4];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * IGIG line pixel 2: IGIGI
|
|
+ * GBGRG
|
|
+ * IGIGI
|
|
+ * GRGBG
|
|
+ * IGIGI
|
|
+ */
|
|
+ *dst++ = blue_[(prev[x - 1] + next[x + 1]) / 8];
|
|
+ *dst++ = green_[(curr[x - 1] + curr[x + 1] + prev[x] + next[x]) / 16];
|
|
+ *dst++ = red_[(prev[x + 1] + next[x - 1]) / 8];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * IGIG line pixel 3: GIGIG
|
|
+ * BGRGB
|
|
+ * GIGIG
|
|
+ * RGBGR
|
|
+ * GIGIG
|
|
+ */
|
|
+ *dst++ = blue_[next[x] / 4];
|
|
+ *dst++ = green_[curr[x] / 4];
|
|
+ *dst++ = red_[prev[x] / 4];
|
|
+ x++;
|
|
+ }
|
|
+}
|
|
+
|
|
+void DebayerCpu::debayerGRGB10Line3(uint8_t *dst, const uint8_t *src[])
|
|
+{
|
|
+ const uint16_t *prev2 = (const uint16_t *)src[0];
|
|
+ const uint16_t *prev = (const uint16_t *)src[1];
|
|
+ const uint16_t *curr = (const uint16_t *)src[2];
|
|
+ const uint16_t *next = (const uint16_t *)src[3];
|
|
+ const uint16_t *next2 = (const uint16_t *)src[4];
|
|
+
|
|
+ for (int x = 0; x < (int)window_.width;) {
|
|
+ /*
|
|
+ * GRGB line pixel 0: GRGBG
|
|
+ * IGIGI
|
|
+ * GBGRG
|
|
+ * IGIGI
|
|
+ * GRGBG
|
|
+ */
|
|
+ *dst++ = blue_[curr[x - 1] / 4];
|
|
+ *dst++ = green_[curr[x] / 4];
|
|
+ *dst++ = red_[curr[x + 1] / 4];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * GRGB line pixel 1: RGBGR
|
|
+ * GIGIG
|
|
+ * BGRGB
|
|
+ * GIGIG
|
|
+ * RGBGR
|
|
+ */
|
|
+ *dst++ = blue_[(curr[x - 2] + curr[x + 2] + prev2[x] + next2[x]) / 16];
|
|
+ *dst++ = green_[(curr[x - 1] + curr[x + 1] + prev[x] + next[x]) / 16];
|
|
+ *dst++ = red_[curr[x] / 4];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * GRGB line pixel 2: GBGRG
|
|
+ * IGIGI
|
|
+ * GRGBG
|
|
+ * IGIGI
|
|
+ * GBGRG
|
|
+ */
|
|
+ *dst++ = blue_[curr[x + 1] / 4];
|
|
+ *dst++ = green_[curr[x] / 4];
|
|
+ *dst++ = red_[curr[x - 1] / 4];
|
|
+ x++;
|
|
+
|
|
+ /*
|
|
+ * GRGB line pixel 3: BGRGB
|
|
+ * GIGIG
|
|
+ * RGBGR
|
|
+ * GIGIG
|
|
+ * BGRGB
|
|
+ */
|
|
+ *dst++ = blue_[curr[x] / 4];
|
|
+ *dst++ = green_[(curr[x - 1] + curr[x + 1] + prev[x] + next[x]) / 16];
|
|
+ *dst++ = red_[(curr[x - 2] + curr[x + 2] + prev2[x] + next2[x]) / 16];
|
|
+ x++;
|
|
+ }
|
|
+}
|
|
+
|
|
static bool isStandardBayerOrder(BayerFormat::Order order)
|
|
{
|
|
return order == BayerFormat::BGGR || order == BayerFormat::GBRG ||
|
|
@@ -259,6 +491,15 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf
|
|
return 0;
|
|
}
|
|
|
|
+ if (bayerFormat.bitDepth == 10 && bayerFormat.packing == BayerFormat::Packing::None &&
|
|
+ bayerFormat.order == BayerFormat::IGIG_GBGR_IGIG_GRGB) {
|
|
+ config.bpp = 16;
|
|
+ config.patternSize.height = 4;
|
|
+ config.patternSize.width = 4;
|
|
+ config.outputFormats = std::vector<PixelFormat>({ formats::RGB888 });
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
LOG(Debayer, Info)
|
|
<< "Unsupported input format " << inputFormat.toString();
|
|
return -EINVAL;
|
|
@@ -384,6 +625,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF
|
|
}
|
|
}
|
|
|
|
+ if (bayerFormat.bitDepth == 10 &&
|
|
+ bayerFormat.packing == BayerFormat::Packing::None &&
|
|
+ bayerFormat.order == BayerFormat::IGIG_GBGR_IGIG_GRGB) {
|
|
+ debayer0_ = &DebayerCpu::debayerIGIG10Line0;
|
|
+ debayer1_ = &DebayerCpu::debayerGBGR10Line1;
|
|
+ debayer2_ = &DebayerCpu::debayerIGIG10Line2;
|
|
+ debayer3_ = &DebayerCpu::debayerGRGB10Line3;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
invalid_fmt:
|
|
LOG(Debayer, Error) << "Unsupported input output format combination";
|
|
return -EINVAL;
|
|
--
|
|
2.43.0
|
|
|