about summary refs log tree commit diff
path: root/users/flokli/ipu6-softisp/libcamera/0008-libcamera-software_isp-Add-SwStatsCpu-class.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/0008-libcamera-software_isp-Add-SwStatsCpu-class.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/0008-libcamera-software_isp-Add-SwStatsCpu-class.patch')
-rw-r--r--users/flokli/ipu6-softisp/libcamera/0008-libcamera-software_isp-Add-SwStatsCpu-class.patch272
1 files changed, 272 insertions, 0 deletions
diff --git a/users/flokli/ipu6-softisp/libcamera/0008-libcamera-software_isp-Add-SwStatsCpu-class.patch b/users/flokli/ipu6-softisp/libcamera/0008-libcamera-software_isp-Add-SwStatsCpu-class.patch
new file mode 100644
index 000000000000..d48eadd9949f
--- /dev/null
+++ b/users/flokli/ipu6-softisp/libcamera/0008-libcamera-software_isp-Add-SwStatsCpu-class.patch
@@ -0,0 +1,272 @@
+From c1c43445cd4408010e500fe9d6b6424c77bcf75d Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Fri, 8 Dec 2023 12:50:57 +0100
+Subject: [PATCH 08/25] libcamera: software_isp: Add SwStatsCpu class
+
+Add a CPU based SwStats implementation for SoftwareISP / SoftIPA use.
+
+Co-authored-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Co-authored-by: Pavel Machek <pavel@ucw.cz>
+Signed-off-by: Pavel Machek <pavel@ucw.cz>
+Co-authored-by: Dennis Bonke <admin@dennisbonke.com>
+Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
+Co-authored-by: Marttico <g.martti@gmail.com>
+Signed-off-by: Marttico <g.martti@gmail.com>
+Co-authored-by: Toon Langendam <t.langendam@gmail.com>
+Signed-off-by: Toon Langendam <t.langendam@gmail.com>
+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>
+---
+ .../internal/software_isp/meson.build         |   1 +
+ .../internal/software_isp/swstats_cpu.h       |  44 +++++
+ src/libcamera/software_isp/meson.build        |   1 +
+ src/libcamera/software_isp/swstats_cpu.cpp    | 164 ++++++++++++++++++
+ 4 files changed, 210 insertions(+)
+ create mode 100644 include/libcamera/internal/software_isp/swstats_cpu.h
+ create mode 100644 src/libcamera/software_isp/swstats_cpu.cpp
+
+diff --git a/include/libcamera/internal/software_isp/meson.build b/include/libcamera/internal/software_isp/meson.build
+index 1c43acc4..1d9e4018 100644
+--- a/include/libcamera/internal/software_isp/meson.build
++++ b/include/libcamera/internal/software_isp/meson.build
+@@ -3,4 +3,5 @@
+ libcamera_internal_headers += files([
+     'swisp_stats.h',
+     'swstats.h',
++    'swstats_cpu.h',
+ ])
+diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h
+new file mode 100644
+index 00000000..8bb86e98
+--- /dev/null
++++ b/include/libcamera/internal/software_isp/swstats_cpu.h
+@@ -0,0 +1,44 @@
++/* 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_cpu.h - CPU based software statistics implementation
++ */
++
++#pragma once
++
++#include "libcamera/internal/shared_mem_object.h"
++#include "libcamera/internal/software_isp/swisp_stats.h"
++#include "libcamera/internal/software_isp/swstats.h"
++
++namespace libcamera {
++
++/**
++ * \class SwStatsCpu
++ * \brief Implementation for the Software statistics on the CPU.
++ */
++class SwStatsCpu : public SwStats
++{
++public:
++	SwStatsCpu();
++	~SwStatsCpu() { }
++
++	bool isValid() const { return sharedStats_.fd().isValid(); }
++	const SharedFD &getStatsFD() { return sharedStats_.fd(); }
++	int configure(const StreamConfiguration &inputCfg);
++private:
++	void statsBGGR10PLine0(const uint8_t *src[]);
++	void statsGBRG10PLine0(const uint8_t *src[]);
++	void resetStats(void);
++	void finishStats(void);
++
++	SharedMemObject<SwIspStats> sharedStats_;
++	SwIspStats stats_;
++	bool swap_lines_;
++};
++
++} /* namespace libcamera */
+diff --git a/src/libcamera/software_isp/meson.build b/src/libcamera/software_isp/meson.build
+index 9359075d..d31c6217 100644
+--- a/src/libcamera/software_isp/meson.build
++++ b/src/libcamera/software_isp/meson.build
+@@ -2,4 +2,5 @@
+ 
+ libcamera_sources += files([
+ 	'swstats.cpp',
++	'swstats_cpu.cpp',
+ ])
+diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp
+new file mode 100644
+index 00000000..59453d07
+--- /dev/null
++++ b/src/libcamera/software_isp/swstats_cpu.cpp
+@@ -0,0 +1,164 @@
++/* 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_cpu.cpp - CPU based software statistics implementation
++ */
++
++#include "libcamera/internal/software_isp/swstats_cpu.h"
++
++#include <libcamera/base/log.h>
++
++#include <libcamera/stream.h>
++
++#include "libcamera/internal/bayer_format.h"
++
++namespace libcamera {
++
++SwStatsCpu::SwStatsCpu()
++	: SwStats()
++{
++	sharedStats_ = SharedMemObject<SwIspStats>("softIsp_stats");
++	if (!sharedStats_.fd().isValid())
++		LOG(SwStats, Error)
++			<< "Failed to create shared memory for statistics";
++}
++
++/* for brightness values in the 0 to 255 range: */
++static const unsigned int BRIGHT_LVL = 200U << 8;
++static const unsigned int TOO_BRIGHT_LVL = 240U << 8;
++
++static const unsigned int RED_Y_MUL = 77; /* 0.30 * 256 */
++static const unsigned int GREEN_Y_MUL = 150; /* 0.59 * 256 */
++static const unsigned int BLUE_Y_MUL = 29; /* 0.11 * 256 */
++
++#define SWISP_LINARO_START_LINE_STATS(pixel_t) \
++	pixel_t r, g, g2, b;                   \
++	unsigned int y_val;                    \
++                                               \
++	unsigned int sumR = 0;                 \
++	unsigned int sumG = 0;                 \
++	unsigned int sumB = 0;
++
++#define SWISP_LINARO_ACCUMULATE_LINE_STATS(div) \
++	sumR += r;                              \
++	sumG += g;                              \
++	sumB += b;                              \
++                                                \
++	y_val = r * RED_Y_MUL;                  \
++	y_val += g * GREEN_Y_MUL;               \
++	y_val += b * BLUE_Y_MUL;                \
++	stats_.y_histogram[y_val / (256 * 16 * (div))]++;
++
++#define SWISP_LINARO_FINISH_LINE_STATS() \
++	stats_.sumR_ += sumR;            \
++	stats_.sumG_ += sumG;            \
++	stats_.sumB_ += sumB;
++
++static inline __attribute__((always_inline)) void
++statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bggr, SwIspStats &stats_)
++{
++	const int width_in_bytes = width * 5 / 4;
++
++	SWISP_LINARO_START_LINE_STATS(uint8_t)
++
++	for (int x = 0; x < width_in_bytes; x += 5) {
++		if (bggr) {
++			/* BGGR */
++			b = src0[x];
++			g = src0[x + 1];
++			g2 = src1[x];
++			r = src1[x + 1];
++		} else {
++			/* GBRG */
++			g = src0[x];
++			b = src0[x + 1];
++			r = src1[x];
++			g2 = src1[x + 1];
++		}
++		g = (g + g2) / 2;
++
++		SWISP_LINARO_ACCUMULATE_LINE_STATS(1)
++	}
++
++	SWISP_LINARO_FINISH_LINE_STATS()
++}
++
++void SwStatsCpu::statsBGGR10PLine0(const uint8_t *src[])
++{
++	const uint8_t *src0 = src[1] + window_.x * 5 / 4;
++	const uint8_t *src1 = src[2] + window_.x * 5 / 4;
++
++	if (swap_lines_)
++		std::swap(src0, src1);
++
++	statsBayer10P(window_.width, src0, src1, true, stats_);
++}
++
++void SwStatsCpu::statsGBRG10PLine0(const uint8_t *src[])
++{
++	const uint8_t *src0 = src[1] + window_.x * 5 / 4;
++	const uint8_t *src1 = src[2] + window_.x * 5 / 4;
++
++	if (swap_lines_)
++		std::swap(src0, src1);
++
++	statsBayer10P(window_.width, src0, src1, false, stats_);
++}
++
++void SwStatsCpu::resetStats(void)
++{
++	stats_.sumR_ = 0;
++	stats_.sumB_ = 0;
++	stats_.sumG_ = 0;
++	std::fill_n(stats_.y_histogram, 16, 0);
++}
++
++void SwStatsCpu::finishStats(void)
++{
++	*sharedStats_ = stats_;
++	statsReady.emit(0);
++}
++
++int SwStatsCpu::configure(const StreamConfiguration &inputCfg)
++{
++	BayerFormat bayerFormat =
++		BayerFormat::fromPixelFormat(inputCfg.pixelFormat);
++
++	startFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::resetStats;
++	finishFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::finishStats;
++
++	if (bayerFormat.bitDepth == 10 &&
++	    bayerFormat.packing == BayerFormat::Packing::CSI2) {
++		bpp_ = 10;
++		patternSize_.height = 2;
++		patternSize_.width = 4; /* 5 bytes per *4* pixels */
++		y_skip_mask_ = 0x02; /* Skip every 3th and 4th line */
++		x_shift_ = 0;
++
++		switch (bayerFormat.order) {
++		case BayerFormat::BGGR:
++		case BayerFormat::GRBG:
++			stats0_ = (SwStats::statsProcessFn)&SwStatsCpu::statsBGGR10PLine0;
++			swap_lines_ = bayerFormat.order == BayerFormat::GRBG;
++			return 0;
++		case BayerFormat::GBRG:
++		case BayerFormat::RGGB:
++			stats0_ = (SwStats::statsProcessFn)&SwStatsCpu::statsGBRG10PLine0;
++			swap_lines_ = bayerFormat.order == BayerFormat::RGGB;
++			return 0;
++		default:
++			break;
++		}
++	}
++
++	LOG(SwStats, Info)
++		<< "Unsupported input format " << inputCfg.pixelFormat.toString();
++	return -EINVAL;
++}
++
++} /* namespace libcamera */
+-- 
+2.43.0
+