[07/13] ipa: simple: Add lux algorithm to the SoftIPA
diff mbox series

Message ID 20260407-kbingham-awb-split-v1-7-a39af3f4dc20@ideasonboard.com
State New
Headers show
Series
  • ipa: simple: Convert to libipa AWB implementation
Related show

Commit Message

Kieran Bingham April 7, 2026, 10:01 p.m. UTC
Utilise the lux component of libipa to map in the lux estimate
process using the yHistgram of the Soft ISP statistics.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 src/ipa/simple/algorithms/lux.cpp     | 93 +++++++++++++++++++++++++++++++++++
 src/ipa/simple/algorithms/lux.h       | 39 +++++++++++++++
 src/ipa/simple/algorithms/meson.build |  1 +
 src/ipa/simple/ipa_context.h          |  5 ++
 4 files changed, 138 insertions(+)

Patch
diff mbox series

diff --git a/src/ipa/simple/algorithms/lux.cpp b/src/ipa/simple/algorithms/lux.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..03b44ac584ae141509e79954159272504cdba17d
--- /dev/null
+++ b/src/ipa/simple/algorithms/lux.cpp
@@ -0,0 +1,93 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2024, Ideas On Board
+ *
+ * Simple Lux control
+ */
+
+#include "lux.h"
+
+#include <libcamera/base/log.h>
+
+#include <libcamera/control_ids.h>
+
+#include "libipa/histogram.h"
+#include "libipa/lux.h"
+
+/**
+ * \file lux.h
+ */
+
+namespace libcamera {
+
+namespace ipa::soft::algorithms {
+
+/**
+ * \class Lux
+ * \brief SoftISP Lux control
+ *
+ * The Lux algorithm is responsible for estimating the lux level of the image.
+ * It doesn't take or generate any controls, but it provides a lux level for
+ * other algorithms (such as AGC) to use.
+ */
+
+/**
+ * \brief Construct a SoftISP Lux algo module
+ */
+Lux::Lux()
+{
+}
+
+/**
+ * \copydoc libcamera::ipa::Algorithm::init
+ */
+int Lux::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)
+{
+	return lux_.parseTuningData(tuningData);
+}
+
+/**
+ * \copydoc libcamera::ipa::Algorithm::prepare
+ */
+void Lux::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,
+		  IPAFrameContext &frameContext,
+		  [[maybe_unused]] DebayerParams *params)
+{
+	frameContext.lux.lux = context.activeState.lux.lux;
+}
+
+/**
+ * \copydoc libcamera::ipa::Algorithm::process
+ */
+void Lux::process(IPAContext &context,
+		  [[maybe_unused]] const uint32_t frame,
+		  IPAFrameContext &frameContext,
+		  const SwIspStats *stats,
+		  ControlList &metadata)
+{
+	/*
+	 * Report the lux level used by algorithms to prepare this frame
+	 * not the lux level *of* this frame.
+	 */
+	metadata.set(controls::Lux, frameContext.lux.lux);
+
+	if (!stats)
+		return;
+
+	/* Todo: Sensor configuration should move out of AGC */
+	utils::Duration exposureTime = context.configuration.agc.lineDuration *
+				       frameContext.sensor.exposure;
+	double gain = frameContext.sensor.gain;
+	double digitalGain = 1.0;
+
+	Histogram yHist(stats->yHistogram);
+
+	context.activeState.lux.lux =
+		lux_.estimateLux(exposureTime, gain, digitalGain, yHist);
+}
+
+REGISTER_IPA_ALGORITHM(Lux, "Lux")
+
+} /* namespace ipa::soft::algorithms */
+
+} /* namespace libcamera */
diff --git a/src/ipa/simple/algorithms/lux.h b/src/ipa/simple/algorithms/lux.h
new file mode 100644
index 0000000000000000000000000000000000000000..04ec4c163ede422369977017cca70d12a8d361fb
--- /dev/null
+++ b/src/ipa/simple/algorithms/lux.h
@@ -0,0 +1,39 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2024, Ideas On Board
+ *
+ * Simple Lux control
+ */
+
+#pragma once
+
+#include <sys/types.h>
+
+#include "libipa/lux.h"
+
+#include "algorithm.h"
+
+namespace libcamera {
+
+namespace ipa::soft::algorithms {
+
+class Lux : public Algorithm
+{
+public:
+	Lux();
+
+	int init(IPAContext &context, const YamlObject &tuningData) override;
+	void prepare(IPAContext &context, const uint32_t frame,
+		     IPAFrameContext &frameContext,
+		     DebayerParams *params) override;
+	void process(IPAContext &context, const uint32_t frame,
+		     IPAFrameContext &frameContext,
+		     const SwIspStats *stats,
+		     ControlList &metadata) override;
+
+private:
+	ipa::Lux lux_;
+};
+
+} /* namespace ipa::soft::algorithms */
+} /* namespace libcamera */
diff --git a/src/ipa/simple/algorithms/meson.build b/src/ipa/simple/algorithms/meson.build
index 73c63722083ff92147253c6b10440ce50743988d..27e73c9a0eea2241cc4a4cefd1594c976fb59318 100644
--- a/src/ipa/simple/algorithms/meson.build
+++ b/src/ipa/simple/algorithms/meson.build
@@ -6,4 +6,5 @@  soft_simple_ipa_algorithms = files([
     'agc.cpp',
     'blc.cpp',
     'ccm.cpp',
+    'lux.cpp',
 ])
diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h
index 8ccfacb46a59cedb5a0ad051d67f7c1f40af4b52..2bd7c4642b118d7bb94b1b16cdf4ede5fb2554b5 100644
--- a/src/ipa/simple/ipa_context.h
+++ b/src/ipa/simple/ipa_context.h
@@ -17,6 +17,7 @@ 
 #include "libcamera/internal/vector.h"
 
 #include <libipa/fc_queue.h>
+#include <libipa/lux.h>
 
 #include "core_ipa_interface.h"
 
@@ -36,6 +37,8 @@  struct IPASessionConfiguration {
 };
 
 struct IPAActiveState {
+	ipa::lux::ActiveState lux;
+
 	struct {
 		int32_t exposure;
 		double again;
@@ -64,6 +67,8 @@  struct IPAActiveState {
 };
 
 struct IPAFrameContext : public FrameContext {
+	ipa::lux::FrameContext lux;
+
 	Matrix<float, 3, 3> ccm;
 
 	struct {