[v3,16/21] ipa: rppx1: lux: Add
diff mbox series

Message ID 20260918120949.191668-17-barnabas.pocze@ideasonboard.com
State New
Headers show
Series
  • libcamera: rcar-gen4 + rpp-x1
Related show

Commit Message

Barnabás Pőcze Sept. 18, 2026, 12:09 p.m. UTC
From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>

Add the algorithm to the rppx1 ipa module based on the corresponding
algorithm in the rkisp1 ipa module.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
 src/ipa/rppx1/algorithms/agc.cpp     |  1 +
 src/ipa/rppx1/algorithms/awb.cpp     |  2 +-
 src/ipa/rppx1/algorithms/lux.cpp     | 76 ++++++++++++++++++++++++++++
 src/ipa/rppx1/algorithms/lux.h       | 36 +++++++++++++
 src/ipa/rppx1/algorithms/meson.build |  1 +
 src/ipa/rppx1/ipa_context.h          |  8 +++
 6 files changed, 123 insertions(+), 1 deletion(-)
 create mode 100644 src/ipa/rppx1/algorithms/lux.cpp
 create mode 100644 src/ipa/rppx1/algorithms/lux.h

Patch
diff mbox series

diff --git a/src/ipa/rppx1/algorithms/agc.cpp b/src/ipa/rppx1/algorithms/agc.cpp
index fd782cea3d..b7b0506463 100644
--- a/src/ipa/rppx1/algorithms/agc.cpp
+++ b/src/ipa/rppx1/algorithms/agc.cpp
@@ -376,6 +376,7 @@  void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
 			},
 			.exposure = frameContext.sensor.exposure,
 			.gain = frameContext.sensor.gain,
+			.lux = frameContext.lux.lux,
 		}}, metadata);
 	} else {
 		agc_.process(context.configuration.agc, context.activeState.agc, frameContext.agc, {}, metadata);
diff --git a/src/ipa/rppx1/algorithms/awb.cpp b/src/ipa/rppx1/algorithms/awb.cpp
index 5e23b88146..fe7d64d77d 100644
--- a/src/ipa/rppx1/algorithms/awb.cpp
+++ b/src/ipa/rppx1/algorithms/awb.cpp
@@ -209,7 +209,7 @@  void Awb::process(IPAContext &context,
 	RppX1AwbStats awbStats = calculateRgbMeans(frameContext, *awb);
 
 	awbAlgo_.process(context.activeState.awb, frameContext.awb, awbStats,
-			 0, metadata);
+			 frameContext.lux.lux, metadata);
 }
 
 RppX1AwbStats Awb::calculateRgbMeans(const IPAFrameContext &frameContext,
diff --git a/src/ipa/rppx1/algorithms/lux.cpp b/src/ipa/rppx1/algorithms/lux.cpp
new file mode 100644
index 0000000000..41ae8e1ab6
--- /dev/null
+++ b/src/ipa/rppx1/algorithms/lux.cpp
@@ -0,0 +1,76 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2026, Ideas On Board
+ *
+ * RPP-X1 Lux estimation
+ */
+
+#include "lux.h"
+
+#include <libcamera/base/utils.h>
+
+#include <libcamera/control_ids.h>
+
+#include "libipa/histogram.h"
+#include "libipa/lux.h"
+
+/**
+ * \file lux.h
+ */
+
+namespace libcamera {
+
+namespace ipa::rppx1::algorithms {
+
+/**
+ * \copydoc libcamera::ipa::Algorithm::init
+ */
+int Lux::init([[maybe_unused]] IPAContext &context, const ValueNode &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]] RppX1Params *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 RppX1Stats *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);
+
+	utils::Duration exposureTime = context.configuration.agc.lineDuration *
+				       frameContext.sensor.exposure;
+	double gain = frameContext.sensor.gain;
+
+	/* \todo Deduplicate the histogram calculation from AGC */
+	const auto histPost = stats->block<StatsType::HistPost>();
+	if (!histPost)
+		return;
+
+	Histogram yHist(histPost->hist_bins, [](uint32_t x) { return x >> 4; });
+
+	context.activeState.lux.lux = lux_.estimateLux(exposureTime, gain, 1.0, yHist);
+}
+
+REGISTER_IPA_ALGORITHM(Lux, "Lux")
+
+} /* namespace ipa::rppx1::algorithms */
+
+} /* namespace libcamera */
diff --git a/src/ipa/rppx1/algorithms/lux.h b/src/ipa/rppx1/algorithms/lux.h
new file mode 100644
index 0000000000..e38835be2b
--- /dev/null
+++ b/src/ipa/rppx1/algorithms/lux.h
@@ -0,0 +1,36 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2026, Ideas On Board
+ *
+ * RPP-X1 Lux estimation
+ */
+
+#pragma once
+
+#include "libipa/lux.h"
+
+#include "algorithm.h"
+
+namespace libcamera {
+
+namespace ipa::rppx1::algorithms {
+
+class Lux : public Algorithm
+{
+public:
+	int init(IPAContext &context, const ValueNode &tuningData) override;
+	void prepare(IPAContext &context, const uint32_t frame,
+		     IPAFrameContext &frameContext,
+		     RppX1Params *params) override;
+	void process(IPAContext &context, const uint32_t frame,
+		     IPAFrameContext &frameContext,
+		     const RppX1Stats *stats,
+		     ControlList &metadata) override;
+
+private:
+	ipa::Lux lux_;
+};
+
+} /* namespace ipa::rppx1::algorithms */
+
+} /* namespace libcamera */
diff --git a/src/ipa/rppx1/algorithms/meson.build b/src/ipa/rppx1/algorithms/meson.build
index 4a2c1b52dd..19688854a3 100644
--- a/src/ipa/rppx1/algorithms/meson.build
+++ b/src/ipa/rppx1/algorithms/meson.build
@@ -4,4 +4,5 @@  rppx1_ipa_algorithms = files([
     'agc.cpp',
     'awb.cpp',
     'blc.cpp',
+    'lux.cpp',
 ])
diff --git a/src/ipa/rppx1/ipa_context.h b/src/ipa/rppx1/ipa_context.h
index 24fbbfaa28..9dfc67f252 100644
--- a/src/ipa/rppx1/ipa_context.h
+++ b/src/ipa/rppx1/ipa_context.h
@@ -42,6 +42,10 @@  struct IPAActiveState {
 	} agc;
 
 	ipa::awb::ActiveState awb;
+
+	struct {
+		double lux;
+	} lux;
 };
 
 struct IPAFrameContext : public FrameContext {
@@ -56,6 +60,10 @@  struct IPAFrameContext : public FrameContext {
 	} agc;
 
 	ipa::awb::FrameContext awb;
+
+	struct {
+		double lux;
+	} lux;
 };
 
 struct IPAContext {