[v3,2/2] ipa: rkisp1: Add Lux algorithm module
diff mbox series

Message ID 20241218074601.3552093-3-paul.elder@ideasonboard.com
State Accepted
Headers show
Series
  • ipa: rkisp1: Add lux estimation
Related show

Commit Message

Paul Elder Dec. 18, 2024, 7:46 a.m. UTC
Add a lux algorithm module to rkisp1 IPA for estimating the lux level of
an image. This is reported in metadata, as well as saved in the frame
context so that other algorithms (mainly AGC) can use its value. It does
not set any controls.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

---
Changes in v3:
- remove unnecessary includes
- replace ipa::Lux::bitSize() with ipa::Lux::Lux()
- move frameContext.agc.lux to frameContext.lux.lux

Changes in v2:
- fix bitrot
- fixes corresponding to changes in the previous patch
---
 src/ipa/rkisp1/algorithms/lux.cpp     | 80 +++++++++++++++++++++++++++
 src/ipa/rkisp1/algorithms/lux.h       | 36 ++++++++++++
 src/ipa/rkisp1/algorithms/meson.build |  1 +
 src/ipa/rkisp1/ipa_context.h          |  4 ++
 4 files changed, 121 insertions(+)
 create mode 100644 src/ipa/rkisp1/algorithms/lux.cpp
 create mode 100644 src/ipa/rkisp1/algorithms/lux.h

Comments

Laurent Pinchart Dec. 20, 2024, 10:20 a.m. UTC | #1
Hi Paul,

Thank you for the patch.

On Wed, Dec 18, 2024 at 04:46:01PM +0900, Paul Elder wrote:
> Add a lux algorithm module to rkisp1 IPA for estimating the lux level of
> an image. This is reported in metadata, as well as saved in the frame
> context so that other algorithms (mainly AGC) can use its value. It does
> not set any controls.
> 
> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> 
> ---
> Changes in v3:
> - remove unnecessary includes
> - replace ipa::Lux::bitSize() with ipa::Lux::Lux()
> - move frameContext.agc.lux to frameContext.lux.lux
> 
> Changes in v2:
> - fix bitrot
> - fixes corresponding to changes in the previous patch
> ---
>  src/ipa/rkisp1/algorithms/lux.cpp     | 80 +++++++++++++++++++++++++++
>  src/ipa/rkisp1/algorithms/lux.h       | 36 ++++++++++++
>  src/ipa/rkisp1/algorithms/meson.build |  1 +
>  src/ipa/rkisp1/ipa_context.h          |  4 ++
>  4 files changed, 121 insertions(+)
>  create mode 100644 src/ipa/rkisp1/algorithms/lux.cpp
>  create mode 100644 src/ipa/rkisp1/algorithms/lux.h
> 
> diff --git a/src/ipa/rkisp1/algorithms/lux.cpp b/src/ipa/rkisp1/algorithms/lux.cpp
> new file mode 100644
> index 000000000000..a1e3f36b75cb
> --- /dev/null
> +++ b/src/ipa/rkisp1/algorithms/lux.cpp
> @@ -0,0 +1,80 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2024, Ideas On Board
> + *
> + * lux.cpp - RkISP1 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::rkisp1::algorithms {
> +
> +/**
> + * \class Lux
> + * \brief RkISP1 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 an rkisp1 Lux algo module
> + *
> + * The Lux helper is initialized to 65535 as that is the max bin count on the
> + * rkisp1.
> + */
> +Lux::Lux()
> +	: lux_(65535)
> +{
> +}
> +
> +/**
> + * \copydoc libcamera::ipa::Algorithm::init
> + */
> +int Lux::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)
> +{
> +	return lux_.parseTuningData(tuningData);
> +}
> +
> +/**
> + * \copydoc libcamera::ipa::Algorithm::process
> + */
> +void Lux::process(IPAContext &context,
> +		  [[maybe_unused]] const uint32_t frame,
> +		  IPAFrameContext &frameContext,
> +		  const rkisp1_stat_buffer *stats,
> +		  ControlList &metadata)
> +{
> +	utils::Duration exposureTime = context.configuration.sensor.lineDuration
> +				       * frameContext.sensor.exposure;

Align * with =.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +	double gain = frameContext.sensor.gain;
> +
> +	/* \todo Deduplicate the histogram calculation from AGC */
> +	const rkisp1_cif_isp_stat *params = &stats->params;
> +	Histogram yHist({ params->hist.hist_bins, context.hw->numHistogramBins },
> +			[](uint32_t x) { return x >> 4; });
> +
> +	double lux = lux_.estimateLux(exposureTime, gain, 1.0, yHist);
> +	frameContext.lux.lux = lux;
> +	metadata.set(controls::Lux, lux);
> +}
> +
> +REGISTER_IPA_ALGORITHM(Lux, "Lux")
> +
> +} /* namespace ipa::rkisp1::algorithms */
> +
> +} /* namespace libcamera */
> diff --git a/src/ipa/rkisp1/algorithms/lux.h b/src/ipa/rkisp1/algorithms/lux.h
> new file mode 100644
> index 000000000000..8a90de55b8ff
> --- /dev/null
> +++ b/src/ipa/rkisp1/algorithms/lux.h
> @@ -0,0 +1,36 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2024, Ideas On Board
> + *
> + * lux.h - RkISP1 Lux control
> + */
> +
> +#pragma once
> +
> +#include <sys/types.h>
> +
> +#include "libipa/lux.h"
> +
> +#include "algorithm.h"
> +
> +namespace libcamera {
> +
> +namespace ipa::rkisp1::algorithms {
> +
> +class Lux : public Algorithm
> +{
> +public:
> +	Lux();
> +
> +	int init(IPAContext &context, const YamlObject &tuningData) override;
> +	void process(IPAContext &context, const uint32_t frame,
> +		     IPAFrameContext &frameContext,
> +		     const rkisp1_stat_buffer *stats,
> +		     ControlList &metadata) override;
> +
> +private:
> +	ipa::Lux lux_;
> +};
> +
> +} /* namespace ipa::rkisp1::algorithms */
> +} /* namespace libcamera */
> diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build
> index 1734a6675f78..c66b0b70b82f 100644
> --- a/src/ipa/rkisp1/algorithms/meson.build
> +++ b/src/ipa/rkisp1/algorithms/meson.build
> @@ -12,4 +12,5 @@ rkisp1_ipa_algorithms = files([
>      'goc.cpp',
>      'gsl.cpp',
>      'lsc.cpp',
> +    'lux.cpp',
>  ])
> diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
> index deb8c196f1b8..65ba45151611 100644
> --- a/src/ipa/rkisp1/ipa_context.h
> +++ b/src/ipa/rkisp1/ipa_context.h
> @@ -168,6 +168,10 @@ struct IPAFrameContext : public FrameContext {
>  	struct {
>  		Matrix<float, 3, 3> ccm;
>  	} ccm;
> +
> +	struct {
> +		double lux;
> +	} lux;
>  };
>  
>  struct IPAContext {
Isaac Scott Dec. 20, 2024, 4:13 p.m. UTC | #2
On Wed, 2024-12-18 at 16:46 +0900, Paul Elder wrote:
> Add a lux algorithm module to rkisp1 IPA for estimating the lux level
> of
> an image. This is reported in metadata, as well as saved in the frame
> context so that other algorithms (mainly AGC) can use its value. It
> does
> not set any controls.
> 
> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> 
> ---
> Changes in v3:
> - remove unnecessary includes
> - replace ipa::Lux::bitSize() with ipa::Lux::Lux()
> - move frameContext.agc.lux to frameContext.lux.lux
> 
> Changes in v2:
> - fix bitrot
> - fixes corresponding to changes in the previous patch
> ---
>  src/ipa/rkisp1/algorithms/lux.cpp     | 80
> +++++++++++++++++++++++++++
>  src/ipa/rkisp1/algorithms/lux.h       | 36 ++++++++++++
>  src/ipa/rkisp1/algorithms/meson.build |  1 +
>  src/ipa/rkisp1/ipa_context.h          |  4 ++
>  4 files changed, 121 insertions(+)
>  create mode 100644 src/ipa/rkisp1/algorithms/lux.cpp
>  create mode 100644 src/ipa/rkisp1/algorithms/lux.h
> 
> diff --git a/src/ipa/rkisp1/algorithms/lux.cpp
> b/src/ipa/rkisp1/algorithms/lux.cpp
> new file mode 100644
> index 000000000000..a1e3f36b75cb
> --- /dev/null
> +++ b/src/ipa/rkisp1/algorithms/lux.cpp
> @@ -0,0 +1,80 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2024, Ideas On Board
> + *
> + * lux.cpp - RkISP1 Lux control
> + */
> +

Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>

> +#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::rkisp1::algorithms {
> +
> +/**
> + * \class Lux
> + * \brief RkISP1 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 an rkisp1 Lux algo module
> + *
> + * The Lux helper is initialized to 65535 as that is the max bin
> count on the
> + * rkisp1.
> + */
> +Lux::Lux()
> +	: lux_(65535)
> +{
> +}
> +
> +/**
> + * \copydoc libcamera::ipa::Algorithm::init
> + */
> +int Lux::init([[maybe_unused]] IPAContext &context, const YamlObject
> &tuningData)
> +{
> +	return lux_.parseTuningData(tuningData);
> +}
> +
> +/**
> + * \copydoc libcamera::ipa::Algorithm::process
> + */
> +void Lux::process(IPAContext &context,
> +		  [[maybe_unused]] const uint32_t frame,
> +		  IPAFrameContext &frameContext,
> +		  const rkisp1_stat_buffer *stats,
> +		  ControlList &metadata)
> +{
> +	utils::Duration exposureTime =
> context.configuration.sensor.lineDuration
> +				       *
> frameContext.sensor.exposure;
> +	double gain = frameContext.sensor.gain;
> +
> +	/* \todo Deduplicate the histogram calculation from AGC */
> +	const rkisp1_cif_isp_stat *params = &stats->params;
> +	Histogram yHist({ params->hist.hist_bins, context.hw-
> >numHistogramBins },
> +			[](uint32_t x) { return x >> 4; });
> +
> +	double lux = lux_.estimateLux(exposureTime, gain, 1.0,
> yHist);
> +	frameContext.lux.lux = lux;
> +	metadata.set(controls::Lux, lux);
> +}
> +
> +REGISTER_IPA_ALGORITHM(Lux, "Lux")
> +
> +} /* namespace ipa::rkisp1::algorithms */
> +
> +} /* namespace libcamera */
> diff --git a/src/ipa/rkisp1/algorithms/lux.h
> b/src/ipa/rkisp1/algorithms/lux.h
> new file mode 100644
> index 000000000000..8a90de55b8ff
> --- /dev/null
> +++ b/src/ipa/rkisp1/algorithms/lux.h
> @@ -0,0 +1,36 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2024, Ideas On Board
> + *
> + * lux.h - RkISP1 Lux control
> + */
> +
> +#pragma once
> +
> +#include <sys/types.h>
> +
> +#include "libipa/lux.h"
> +
> +#include "algorithm.h"
> +
> +namespace libcamera {
> +
> +namespace ipa::rkisp1::algorithms {
> +
> +class Lux : public Algorithm
> +{
> +public:
> +	Lux();
> +
> +	int init(IPAContext &context, const YamlObject &tuningData)
> override;
> +	void process(IPAContext &context, const uint32_t frame,
> +		     IPAFrameContext &frameContext,
> +		     const rkisp1_stat_buffer *stats,
> +		     ControlList &metadata) override;
> +
> +private:
> +	ipa::Lux lux_;
> +};
> +
> +} /* namespace ipa::rkisp1::algorithms */
> +} /* namespace libcamera */
> diff --git a/src/ipa/rkisp1/algorithms/meson.build
> b/src/ipa/rkisp1/algorithms/meson.build
> index 1734a6675f78..c66b0b70b82f 100644
> --- a/src/ipa/rkisp1/algorithms/meson.build
> +++ b/src/ipa/rkisp1/algorithms/meson.build
> @@ -12,4 +12,5 @@ rkisp1_ipa_algorithms = files([
>      'goc.cpp',
>      'gsl.cpp',
>      'lsc.cpp',
> +    'lux.cpp',
>  ])
> diff --git a/src/ipa/rkisp1/ipa_context.h
> b/src/ipa/rkisp1/ipa_context.h
> index deb8c196f1b8..65ba45151611 100644
> --- a/src/ipa/rkisp1/ipa_context.h
> +++ b/src/ipa/rkisp1/ipa_context.h
> @@ -168,6 +168,10 @@ struct IPAFrameContext : public FrameContext {
>  	struct {
>  		Matrix<float, 3, 3> ccm;
>  	} ccm;
> +
> +	struct {
> +		double lux;
> +	} lux;
>  };
>  
>  struct IPAContext {

Patch
diff mbox series

diff --git a/src/ipa/rkisp1/algorithms/lux.cpp b/src/ipa/rkisp1/algorithms/lux.cpp
new file mode 100644
index 000000000000..a1e3f36b75cb
--- /dev/null
+++ b/src/ipa/rkisp1/algorithms/lux.cpp
@@ -0,0 +1,80 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2024, Ideas On Board
+ *
+ * lux.cpp - RkISP1 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::rkisp1::algorithms {
+
+/**
+ * \class Lux
+ * \brief RkISP1 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 an rkisp1 Lux algo module
+ *
+ * The Lux helper is initialized to 65535 as that is the max bin count on the
+ * rkisp1.
+ */
+Lux::Lux()
+	: lux_(65535)
+{
+}
+
+/**
+ * \copydoc libcamera::ipa::Algorithm::init
+ */
+int Lux::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)
+{
+	return lux_.parseTuningData(tuningData);
+}
+
+/**
+ * \copydoc libcamera::ipa::Algorithm::process
+ */
+void Lux::process(IPAContext &context,
+		  [[maybe_unused]] const uint32_t frame,
+		  IPAFrameContext &frameContext,
+		  const rkisp1_stat_buffer *stats,
+		  ControlList &metadata)
+{
+	utils::Duration exposureTime = context.configuration.sensor.lineDuration
+				       * frameContext.sensor.exposure;
+	double gain = frameContext.sensor.gain;
+
+	/* \todo Deduplicate the histogram calculation from AGC */
+	const rkisp1_cif_isp_stat *params = &stats->params;
+	Histogram yHist({ params->hist.hist_bins, context.hw->numHistogramBins },
+			[](uint32_t x) { return x >> 4; });
+
+	double lux = lux_.estimateLux(exposureTime, gain, 1.0, yHist);
+	frameContext.lux.lux = lux;
+	metadata.set(controls::Lux, lux);
+}
+
+REGISTER_IPA_ALGORITHM(Lux, "Lux")
+
+} /* namespace ipa::rkisp1::algorithms */
+
+} /* namespace libcamera */
diff --git a/src/ipa/rkisp1/algorithms/lux.h b/src/ipa/rkisp1/algorithms/lux.h
new file mode 100644
index 000000000000..8a90de55b8ff
--- /dev/null
+++ b/src/ipa/rkisp1/algorithms/lux.h
@@ -0,0 +1,36 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2024, Ideas On Board
+ *
+ * lux.h - RkISP1 Lux control
+ */
+
+#pragma once
+
+#include <sys/types.h>
+
+#include "libipa/lux.h"
+
+#include "algorithm.h"
+
+namespace libcamera {
+
+namespace ipa::rkisp1::algorithms {
+
+class Lux : public Algorithm
+{
+public:
+	Lux();
+
+	int init(IPAContext &context, const YamlObject &tuningData) override;
+	void process(IPAContext &context, const uint32_t frame,
+		     IPAFrameContext &frameContext,
+		     const rkisp1_stat_buffer *stats,
+		     ControlList &metadata) override;
+
+private:
+	ipa::Lux lux_;
+};
+
+} /* namespace ipa::rkisp1::algorithms */
+} /* namespace libcamera */
diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build
index 1734a6675f78..c66b0b70b82f 100644
--- a/src/ipa/rkisp1/algorithms/meson.build
+++ b/src/ipa/rkisp1/algorithms/meson.build
@@ -12,4 +12,5 @@  rkisp1_ipa_algorithms = files([
     'goc.cpp',
     'gsl.cpp',
     'lsc.cpp',
+    'lux.cpp',
 ])
diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
index deb8c196f1b8..65ba45151611 100644
--- a/src/ipa/rkisp1/ipa_context.h
+++ b/src/ipa/rkisp1/ipa_context.h
@@ -168,6 +168,10 @@  struct IPAFrameContext : public FrameContext {
 	struct {
 		Matrix<float, 3, 3> ccm;
 	} ccm;
+
+	struct {
+		double lux;
+	} lux;
 };
 
 struct IPAContext {