about summary refs log tree commit diff
path: root/users/flokli/ipu6-softisp/libcamera/0016-libcamera-swstats_cpu-Add-support-for-8-10-and-12-bp.patch
diff options
context:
space:
mode:
authorFlorian Klink <flokli@flokli.de>2024-01-30T09·43+0200
committerflokli <flokli@flokli.de>2024-01-30T09·54+0000
commitaf9a8d372b24710bf7fc27c8e81244e1ca6d1658 (patch)
treedf8bee03b202ec5081b9bd7e7b5d7b6ecdd28e1b /users/flokli/ipu6-softisp/libcamera/0016-libcamera-swstats_cpu-Add-support-for-8-10-and-12-bp.patch
parentb38be028d96ce107439f3323026270228a871a13 (diff)
feat(users/flokli/ipu6-softisp): init r/7454
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>
Diffstat (limited to 'users/flokli/ipu6-softisp/libcamera/0016-libcamera-swstats_cpu-Add-support-for-8-10-and-12-bp.patch')
-rw-r--r--users/flokli/ipu6-softisp/libcamera/0016-libcamera-swstats_cpu-Add-support-for-8-10-and-12-bp.patch199
1 files changed, 199 insertions, 0 deletions
diff --git a/users/flokli/ipu6-softisp/libcamera/0016-libcamera-swstats_cpu-Add-support-for-8-10-and-12-bp.patch b/users/flokli/ipu6-softisp/libcamera/0016-libcamera-swstats_cpu-Add-support-for-8-10-and-12-bp.patch
new file mode 100644
index 000000000000..04388859a543
--- /dev/null
+++ b/users/flokli/ipu6-softisp/libcamera/0016-libcamera-swstats_cpu-Add-support-for-8-10-and-12-bp.patch
@@ -0,0 +1,199 @@
+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
+