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>
199 lines
5.8 KiB
Diff
199 lines
5.8 KiB
Diff
From 66ef9f32e67a96655d10ba38f7a830b3bbfe50f2 Mon Sep 17 00:00:00 2001
|
|
From: Hans de Goede <hdegoede@redhat.com>
|
|
Date: Thu, 14 Dec 2023 19:09:44 +0100
|
|
Subject: [PATCH 16/25] libcamera: swstats_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/swstats_cpu.h | 9 ++
|
|
src/libcamera/software_isp/swstats_cpu.cpp | 126 ++++++++++++++++++
|
|
2 files changed, 135 insertions(+)
|
|
|
|
diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h
|
|
index 8bb86e98..e7abc6bb 100644
|
|
--- a/include/libcamera/internal/software_isp/swstats_cpu.h
|
|
+++ b/include/libcamera/internal/software_isp/swstats_cpu.h
|
|
@@ -11,6 +11,7 @@
|
|
|
|
#pragma once
|
|
|
|
+#include "libcamera/internal/bayer_format.h"
|
|
#include "libcamera/internal/shared_mem_object.h"
|
|
#include "libcamera/internal/software_isp/swisp_stats.h"
|
|
#include "libcamera/internal/software_isp/swstats.h"
|
|
@@ -31,6 +32,14 @@ public:
|
|
const SharedFD &getStatsFD() { return sharedStats_.fd(); }
|
|
int configure(const StreamConfiguration &inputCfg);
|
|
private:
|
|
+ int setupStandardBayerOrder(BayerFormat::Order order);
|
|
+ /* Bayer 8 bpp unpacked */
|
|
+ void statsBGGR8Line0(const uint8_t *src[]);
|
|
+ /* Bayer 10 bpp unpacked */
|
|
+ void statsBGGR10Line0(const uint8_t *src[]);
|
|
+ /* Bayer 12 bpp unpacked */
|
|
+ void statsBGGR12Line0(const uint8_t *src[]);
|
|
+ /* Bayer 10 bpp packed */
|
|
void statsBGGR10PLine0(const uint8_t *src[]);
|
|
void statsGBRG10PLine0(const uint8_t *src[]);
|
|
void resetStats(void);
|
|
diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp
|
|
index 59453d07..87550371 100644
|
|
--- a/src/libcamera/software_isp/swstats_cpu.cpp
|
|
+++ b/src/libcamera/software_isp/swstats_cpu.cpp
|
|
@@ -59,6 +59,83 @@ static const unsigned int BLUE_Y_MUL = 29; /* 0.11 * 256 */
|
|
stats_.sumG_ += sumG; \
|
|
stats_.sumB_ += sumB;
|
|
|
|
+void SwStatsCpu::statsBGGR8Line0(const uint8_t *src[])
|
|
+{
|
|
+ const uint8_t *src0 = src[1] + window_.x;
|
|
+ const uint8_t *src1 = src[2] + window_.x;
|
|
+
|
|
+ SWISP_LINARO_START_LINE_STATS(uint8_t)
|
|
+
|
|
+ if (swap_lines_)
|
|
+ std::swap(src0, src1);
|
|
+
|
|
+ /* x += 4 sample every other 2x2 block */
|
|
+ for (int x = 0; x < (int)window_.width; x += 4) {
|
|
+ b = src0[x];
|
|
+ g = src0[x + 1];
|
|
+ g2 = src1[x];
|
|
+ r = src1[x + 1];
|
|
+
|
|
+ g = (g + g2) / 2;
|
|
+
|
|
+ SWISP_LINARO_ACCUMULATE_LINE_STATS(1)
|
|
+ }
|
|
+
|
|
+ SWISP_LINARO_FINISH_LINE_STATS()
|
|
+}
|
|
+
|
|
+void SwStatsCpu::statsBGGR10Line0(const uint8_t *src[])
|
|
+{
|
|
+ const uint16_t *src0 = (const uint16_t *)src[1] + window_.x;
|
|
+ const uint16_t *src1 = (const uint16_t *)src[2] + window_.x;
|
|
+
|
|
+ SWISP_LINARO_START_LINE_STATS(uint16_t)
|
|
+
|
|
+ if (swap_lines_)
|
|
+ std::swap(src0, src1);
|
|
+
|
|
+ /* x += 4 sample every other 2x2 block */
|
|
+ for (int x = 0; x < (int)window_.width; x += 4) {
|
|
+ b = src0[x];
|
|
+ g = src0[x + 1];
|
|
+ g2 = src1[x];
|
|
+ r = src1[x + 1];
|
|
+
|
|
+ g = (g + g2) / 2;
|
|
+
|
|
+ /* divide Y by 4 for 10 -> 8 bpp value */
|
|
+ SWISP_LINARO_ACCUMULATE_LINE_STATS(4)
|
|
+ }
|
|
+
|
|
+ SWISP_LINARO_FINISH_LINE_STATS()
|
|
+}
|
|
+
|
|
+void SwStatsCpu::statsBGGR12Line0(const uint8_t *src[])
|
|
+{
|
|
+ const uint16_t *src0 = (const uint16_t *)src[1] + window_.x;
|
|
+ const uint16_t *src1 = (const uint16_t *)src[2] + window_.x;
|
|
+
|
|
+ SWISP_LINARO_START_LINE_STATS(uint16_t)
|
|
+
|
|
+ if (swap_lines_)
|
|
+ std::swap(src0, src1);
|
|
+
|
|
+ /* x += 4 sample every other 2x2 block */
|
|
+ for (int x = 0; x < (int)window_.width; x += 4) {
|
|
+ b = src0[x];
|
|
+ g = src0[x + 1];
|
|
+ g2 = src1[x];
|
|
+ r = src1[x + 1];
|
|
+
|
|
+ g = (g + g2) / 2;
|
|
+
|
|
+ /* divide Y by 16 for 12 -> 8 bpp value */
|
|
+ SWISP_LINARO_ACCUMULATE_LINE_STATS(16)
|
|
+ }
|
|
+
|
|
+ SWISP_LINARO_FINISH_LINE_STATS()
|
|
+}
|
|
+
|
|
static inline __attribute__((always_inline)) void
|
|
statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bggr, SwIspStats &stats_)
|
|
{
|
|
@@ -124,6 +201,39 @@ void SwStatsCpu::finishStats(void)
|
|
statsReady.emit(0);
|
|
}
|
|
|
|
+/*
|
|
+ * Check if order is a standard Bayer order and setup x_shift_ and swap_lines_
|
|
+ * so that a single BGGR stats function can be used for all 4 standard orders.
|
|
+ */
|
|
+int SwStatsCpu::setupStandardBayerOrder(BayerFormat::Order order)
|
|
+{
|
|
+ switch (order) {
|
|
+ case BayerFormat::BGGR:
|
|
+ x_shift_ = 0;
|
|
+ swap_lines_ = false;
|
|
+ break;
|
|
+ case BayerFormat::GBRG:
|
|
+ x_shift_ = 1; /* BGGR -> GBRG */
|
|
+ swap_lines_ = false;
|
|
+ break;
|
|
+ case BayerFormat::GRBG:
|
|
+ x_shift_ = 0;
|
|
+ swap_lines_ = true; /* BGGR -> GRBG */
|
|
+ break;
|
|
+ case BayerFormat::RGGB:
|
|
+ x_shift_ = 1; /* BGGR -> GBRG */
|
|
+ swap_lines_ = true; /* GBRG -> RGGB */
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ patternSize_.height = 2;
|
|
+ patternSize_.width = 2;
|
|
+ y_skip_mask_ = 0x02; /* Skip every 3th and 4th line */
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int SwStatsCpu::configure(const StreamConfiguration &inputCfg)
|
|
{
|
|
BayerFormat bayerFormat =
|
|
@@ -132,6 +242,22 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)
|
|
startFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::resetStats;
|
|
finishFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::finishStats;
|
|
|
|
+ if (bayerFormat.packing == BayerFormat::Packing::None &&
|
|
+ setupStandardBayerOrder(bayerFormat.order) == 0) {
|
|
+ bpp_ = (bayerFormat.bitDepth + 7) & ~7;
|
|
+ switch (bayerFormat.bitDepth) {
|
|
+ case 8:
|
|
+ stats0_ = (SwStats::statsProcessFn)&SwStatsCpu::statsBGGR8Line0;
|
|
+ return 0;
|
|
+ case 10:
|
|
+ stats0_ = (SwStats::statsProcessFn)&SwStatsCpu::statsBGGR10Line0;
|
|
+ return 0;
|
|
+ case 12:
|
|
+ stats0_ = (SwStats::statsProcessFn)&SwStatsCpu::statsBGGR12Line0;
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
if (bayerFormat.bitDepth == 10 &&
|
|
bayerFormat.packing == BayerFormat::Packing::CSI2) {
|
|
bpp_ = 10;
|
|
--
|
|
2.43.0
|
|
|