summaryrefslogtreecommitdiff
path: root/src/ipa
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipa')
-rw-r--r--src/ipa/ipu3/algorithms/af.cpp3
-rw-r--r--src/ipa/ipu3/algorithms/agc.cpp3
-rw-r--r--src/ipa/ipu3/algorithms/blc.cpp6
-rw-r--r--src/ipa/ipu3/ipu3.cpp20
-rw-r--r--src/ipa/ipu3/meson.build3
-rw-r--r--src/ipa/libipa/camera_sensor_helper.cpp140
-rw-r--r--src/ipa/libipa/camera_sensor_helper.h6
-rw-r--r--src/ipa/libipa/histogram.h1
-rw-r--r--src/ipa/libipa/matrix.h1
-rw-r--r--src/ipa/libipa/matrix_interpolator.cpp7
-rw-r--r--src/ipa/libipa/matrix_interpolator.h2
-rw-r--r--src/ipa/libipa/pwl.cpp2
-rw-r--r--src/ipa/libipa/pwl.h3
-rw-r--r--src/ipa/libipa/vector.h4
-rw-r--r--src/ipa/rkisp1/algorithms/agc.cpp48
-rw-r--r--src/ipa/rkisp1/algorithms/agc.h3
-rw-r--r--src/ipa/rkisp1/algorithms/awb.cpp87
-rw-r--r--src/ipa/rkisp1/algorithms/awb.h2
-rw-r--r--src/ipa/rkisp1/algorithms/blc.cpp135
-rw-r--r--src/ipa/rkisp1/algorithms/blc.h11
-rw-r--r--src/ipa/rkisp1/algorithms/ccm.cpp28
-rw-r--r--src/ipa/rkisp1/algorithms/ccm.h4
-rw-r--r--src/ipa/rkisp1/algorithms/cproc.cpp14
-rw-r--r--src/ipa/rkisp1/algorithms/cproc.h2
-rw-r--r--src/ipa/rkisp1/algorithms/dpcc.cpp10
-rw-r--r--src/ipa/rkisp1/algorithms/dpcc.h2
-rw-r--r--src/ipa/rkisp1/algorithms/dpf.cpp31
-rw-r--r--src/ipa/rkisp1/algorithms/dpf.h2
-rw-r--r--src/ipa/rkisp1/algorithms/filter.cpp56
-rw-r--r--src/ipa/rkisp1/algorithms/filter.h2
-rw-r--r--src/ipa/rkisp1/algorithms/goc.cpp17
-rw-r--r--src/ipa/rkisp1/algorithms/goc.h2
-rw-r--r--src/ipa/rkisp1/algorithms/gsl.cpp20
-rw-r--r--src/ipa/rkisp1/algorithms/gsl.h2
-rw-r--r--src/ipa/rkisp1/algorithms/lsc.cpp29
-rw-r--r--src/ipa/rkisp1/algorithms/lsc.h4
-rw-r--r--src/ipa/rkisp1/data/imx219.yaml4
-rw-r--r--src/ipa/rkisp1/data/imx258.yaml1
-rw-r--r--src/ipa/rkisp1/data/meson.build4
-rw-r--r--src/ipa/rkisp1/data/ov4689.yaml4
-rw-r--r--src/ipa/rkisp1/data/ov5640.yaml4
-rw-r--r--src/ipa/rkisp1/data/uncalibrated.yaml1
-rw-r--r--src/ipa/rkisp1/ipa_context.cpp5
-rw-r--r--src/ipa/rkisp1/ipa_context.h13
-rw-r--r--src/ipa/rkisp1/meson.build4
-rw-r--r--src/ipa/rkisp1/module.h3
-rw-r--r--src/ipa/rkisp1/params.cpp222
-rw-r--r--src/ipa/rkisp1/params.h163
-rw-r--r--src/ipa/rkisp1/rkisp1.cpp67
-rw-r--r--src/ipa/rkisp1/utils.h1
-rw-r--r--src/ipa/rpi/controller/rpi/alsc.cpp6
-rw-r--r--src/ipa/rpi/vc4/meson.build3
-rw-r--r--src/ipa/simple/meson.build3
-rw-r--r--src/ipa/vimc/meson.build3
-rw-r--r--src/ipa/vimc/vimc.cpp1
55 files changed, 913 insertions, 311 deletions
diff --git a/src/ipa/ipu3/algorithms/af.cpp b/src/ipa/ipu3/algorithms/af.cpp
index 29eb7355..cf68fb59 100644
--- a/src/ipa/ipu3/algorithms/af.cpp
+++ b/src/ipa/ipu3/algorithms/af.cpp
@@ -11,7 +11,6 @@
#include <chrono>
#include <cmath>
#include <fcntl.h>
-#include <numeric>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -23,8 +22,6 @@
#include <libcamera/ipa/core_ipa_interface.h>
-#include "libipa/histogram.h"
-
/**
* \file af.h
*/
diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp
index 0e0114f6..c5f3d8f0 100644
--- a/src/ipa/ipu3/algorithms/agc.cpp
+++ b/src/ipa/ipu3/algorithms/agc.cpp
@@ -9,12 +9,12 @@
#include <algorithm>
#include <chrono>
-#include <cmath>
#include <libcamera/base/log.h>
#include <libcamera/base/utils.h>
#include <libcamera/control_ids.h>
+
#include <libcamera/ipa/core_ipa_interface.h>
#include "libipa/histogram.h"
@@ -247,7 +247,6 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
utils::Duration frameDuration = context.configuration.sensor.lineDuration
* vTotal;
metadata.set(controls::FrameDuration, frameDuration.get<std::micro>());
-
}
REGISTER_IPA_ALGORITHM(Agc, "Agc")
diff --git a/src/ipa/ipu3/algorithms/blc.cpp b/src/ipa/ipu3/algorithms/blc.cpp
index 257f40e2..35748fb2 100644
--- a/src/ipa/ipu3/algorithms/blc.cpp
+++ b/src/ipa/ipu3/algorithms/blc.cpp
@@ -7,8 +7,6 @@
#include "blc.h"
-#include <string.h>
-
/**
* \file blc.h
* \brief IPU3 Black Level Correction control
@@ -57,8 +55,8 @@ void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,
* tuning processes. This is a first rough approximation.
*/
params->obgrid_param.gr = 64;
- params->obgrid_param.r = 64;
- params->obgrid_param.b = 64;
+ params->obgrid_param.r = 64;
+ params->obgrid_param.b = 64;
params->obgrid_param.gb = 64;
/* Enable the custom black level correction processing */
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index cdcdf1fb..10a8c86d 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -23,24 +23,22 @@
#include <libcamera/base/utils.h>
#include <libcamera/control_ids.h>
+#include <libcamera/controls.h>
#include <libcamera/framebuffer.h>
+#include <libcamera/geometry.h>
+#include <libcamera/request.h>
+
#include <libcamera/ipa/ipa_interface.h>
#include <libcamera/ipa/ipa_module_info.h>
#include <libcamera/ipa/ipu3_ipa_interface.h>
-#include <libcamera/request.h>
#include "libcamera/internal/mapped_framebuffer.h"
#include "libcamera/internal/yaml_parser.h"
-#include "algorithms/af.h"
-#include "algorithms/agc.h"
-#include "algorithms/algorithm.h"
-#include "algorithms/awb.h"
-#include "algorithms/blc.h"
-#include "algorithms/tone_mapping.h"
#include "libipa/camera_sensor_helper.h"
#include "ipa_context.h"
+#include "module.h"
/* Minimum grid width, expressed as a number of cells */
static constexpr uint32_t kMinGridWidth = 16;
@@ -313,8 +311,8 @@ int IPAIPU3::init(const IPASettings &settings,
/* Clean context */
context_.configuration = {};
- context_.configuration.sensor.lineDuration = sensorInfo.minLineLength
- * 1.0s / sensorInfo.pixelRate;
+ context_.configuration.sensor.lineDuration =
+ sensorInfo.minLineLength * 1.0s / sensorInfo.pixelRate;
/* Load the tuning data file. */
File file(settings.configurationFile);
@@ -477,8 +475,8 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo,
context_.frameContexts.clear();
/* Initialise the sensor configuration. */
- context_.configuration.sensor.lineDuration = sensorInfo_.minLineLength
- * 1.0s / sensorInfo_.pixelRate;
+ context_.configuration.sensor.lineDuration =
+ sensorInfo_.minLineLength * 1.0s / sensorInfo_.pixelRate;
context_.configuration.sensor.size = sensorInfo_.outputSize;
/*
diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build
index e76f97c0..34de6213 100644
--- a/src/ipa/ipu3/meson.build
+++ b/src/ipa/ipu3/meson.build
@@ -12,8 +12,7 @@ ipu3_ipa_sources = files([
ipu3_ipa_sources += ipu3_ipa_algorithms
-mod = shared_module(ipa_name,
- [ipu3_ipa_sources, libcamera_generated_ipa_headers],
+mod = shared_module(ipa_name, ipu3_ipa_sources,
name_prefix : '',
include_directories : [ipa_includes],
dependencies : [libcamera_private, libipa_dep],
diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp
index 782ff990..ffc7c1d7 100644
--- a/src/ipa/libipa/camera_sensor_helper.cpp
+++ b/src/ipa/libipa/camera_sensor_helper.cpp
@@ -8,6 +8,7 @@
#include "camera_sensor_helper.h"
#include <cmath>
+#include <limits>
#include <libcamera/base/log.h>
@@ -40,6 +41,7 @@ namespace ipa {
*/
/**
+ * \fn CameraSensorHelper::CameraSensorHelper()
* \brief Construct a CameraSensorHelper instance
*
* CameraSensorHelper derived class instances shall never be constructed
@@ -48,6 +50,33 @@ namespace ipa {
*/
/**
+ * \fn CameraSensorHelper::blackLevel()
+ * \brief Fetch the black level of the sensor
+ *
+ * This function returns the black level of the sensor scaled to a 16bit pixel
+ * width. If it is unknown an empty optional is returned.
+ *
+ * \todo Fill the blanks and add pedestal values for all supported sensors. Once
+ * done, drop the std::optional<>.
+ *
+ * Black levels are typically the result of the following phenomena:
+ * - Pedestal added by the sensor to pixel values. They are typically fixed,
+ * sometimes programmable and should be reported in datasheets (but
+ * documentation is not always available).
+ * - Dark currents and other physical effects that add charge to pixels in the
+ * absence of light. Those can depend on the integration time and the sensor
+ * die temperature, and their contribution to pixel values depend on the
+ * sensor gains.
+ *
+ * The pedestal is usually the value with the biggest contribution to the
+ * overall black level. In most cases it is either known before or in rare cases
+ * (there is not a single driver with such a control in the linux kernel) can be
+ * queried from the sensor. This function provides that fixed, known value.
+ *
+ * \return The black level of the sensor, or std::nullopt if not known
+ */
+
+/**
* \brief Compute gain code from the analogue gain absolute value
* \param[in] gain The real gain to pass
*
@@ -205,6 +234,12 @@ double CameraSensorHelper::gain(uint32_t gainCode) const
*/
/**
+ * \var CameraSensorHelper::blackLevel_
+ * \brief The black level of the sensor
+ * \sa CameraSensorHelper::blackLevel()
+ */
+
+/**
* \var CameraSensorHelper::gainType_
* \brief The analogue gain model type
*/
@@ -366,6 +401,99 @@ static constexpr double expGainDb(double step)
return log2_10 * step / 20;
}
+class CameraSensorHelperAr0144 : public CameraSensorHelper
+{
+public:
+ CameraSensorHelperAr0144()
+ {
+ /* Power-on default value: 168 at 12bits. */
+ blackLevel_ = 2688;
+ }
+
+ uint32_t gainCode(double gain) const override
+ {
+ /* The recommended minimum gain is 1.6842 to avoid artifacts. */
+ gain = std::clamp(gain, 1.0 / (1.0 - 13.0 / 32.0), 18.45);
+
+ /*
+ * The analogue gain is made of a coarse exponential gain in
+ * the range [2^0, 2^4] and a fine inversely linear gain in the
+ * range [1.0, 2.0[. There is an additional fixed 1.153125
+ * multiplier when the coarse gain reaches 2^2.
+ */
+
+ if (gain > 4.0)
+ gain /= 1.153125;
+
+ unsigned int coarse = std::log2(gain);
+ unsigned int fine = (1 - (1 << coarse) / gain) * 32;
+
+ /* The fine gain rounding depends on the coarse gain. */
+ if (coarse == 1 || coarse == 3)
+ fine &= ~1;
+ else if (coarse == 4)
+ fine &= ~3;
+
+ return (coarse << 4) | (fine & 0xf);
+ }
+
+ double gain(uint32_t gainCode) const override
+ {
+ unsigned int coarse = gainCode >> 4;
+ unsigned int fine = gainCode & 0xf;
+ unsigned int d1;
+ double d2, m;
+
+ switch (coarse) {
+ default:
+ case 0:
+ d1 = 1;
+ d2 = 32.0;
+ m = 1.0;
+ break;
+ case 1:
+ d1 = 2;
+ d2 = 16.0;
+ m = 1.0;
+ break;
+ case 2:
+ d1 = 1;
+ d2 = 32.0;
+ m = 1.153125;
+ break;
+ case 3:
+ d1 = 2;
+ d2 = 16.0;
+ m = 1.153125;
+ break;
+ case 4:
+ d1 = 4;
+ d2 = 8.0;
+ m = 1.153125;
+ break;
+ }
+
+ /*
+ * With infinite precision, the calculated gain would be exact,
+ * and the reverse conversion with gainCode() would produce the
+ * same gain code. In the real world, rounding errors may cause
+ * the calculated gain to be lower by an amount negligible for
+ * all purposes, except for the reverse conversion. Converting
+ * the gain to a gain code could then return the quantized value
+ * just lower than the original gain code. To avoid this, tests
+ * showed that adding the machine epsilon to the multiplier m is
+ * sufficient.
+ */
+ m += std::numeric_limits<decltype(m)>::epsilon();
+
+ return m * (1 << coarse) / (1.0 - (fine / d1) / d2);
+ }
+
+private:
+ static constexpr double kStep_ = 16;
+};
+REGISTER_CAMERA_SENSOR_HELPER("ar0144", CameraSensorHelperAr0144)
+
class CameraSensorHelperAr0521 : public CameraSensorHelper
{
public:
@@ -396,6 +524,8 @@ class CameraSensorHelperImx219 : public CameraSensorHelper
public:
CameraSensorHelperImx219()
{
+ /* From datasheet: 64 at 10bits. */
+ blackLevel_ = 4096;
gainType_ = AnalogueGainLinear;
gainConstants_.linear = { 0, 256, -1, 256 };
}
@@ -407,6 +537,8 @@ class CameraSensorHelperImx258 : public CameraSensorHelper
public:
CameraSensorHelperImx258()
{
+ /* From datasheet: 0x40 at 10bits. */
+ blackLevel_ = 4096;
gainType_ = AnalogueGainLinear;
gainConstants_.linear = { 0, 512, -1, 512 };
}
@@ -456,6 +588,8 @@ class CameraSensorHelperImx335 : public CameraSensorHelper
public:
CameraSensorHelperImx335()
{
+ /* From datasheet: 0x32 at 10bits. */
+ blackLevel_ = 3200;
gainType_ = AnalogueGainExponential;
gainConstants_.exp = { 1.0, expGainDb(0.3) };
}
@@ -515,6 +649,8 @@ class CameraSensorHelperOv4689 : public CameraSensorHelper
public:
CameraSensorHelperOv4689()
{
+ /* From datasheet: 0x40 at 12bits. */
+ blackLevel_ = 1024;
gainType_ = AnalogueGainLinear;
gainConstants_.linear = { 1, 0, 0, 128 };
}
@@ -526,6 +662,8 @@ class CameraSensorHelperOv5640 : public CameraSensorHelper
public:
CameraSensorHelperOv5640()
{
+ /* From datasheet: 0x10 at 10bits. */
+ blackLevel_ = 1024;
gainType_ = AnalogueGainLinear;
gainConstants_.linear = { 1, 0, 0, 16 };
}
@@ -559,6 +697,8 @@ class CameraSensorHelperOv5675 : public CameraSensorHelper
public:
CameraSensorHelperOv5675()
{
+ /* From Linux kernel driver: 0x40 at 10bits. */
+ blackLevel_ = 4096;
gainType_ = AnalogueGainLinear;
gainConstants_.linear = { 1, 0, 0, 128 };
}
diff --git a/src/ipa/libipa/camera_sensor_helper.h b/src/ipa/libipa/camera_sensor_helper.h
index 0d99073b..75868205 100644
--- a/src/ipa/libipa/camera_sensor_helper.h
+++ b/src/ipa/libipa/camera_sensor_helper.h
@@ -7,9 +7,9 @@
#pragma once
-#include <stdint.h>
-
#include <memory>
+#include <optional>
+#include <stdint.h>
#include <string>
#include <vector>
@@ -25,6 +25,7 @@ public:
CameraSensorHelper() = default;
virtual ~CameraSensorHelper() = default;
+ std::optional<int16_t> blackLevel() const { return blackLevel_; }
virtual uint32_t gainCode(double gain) const;
virtual double gain(uint32_t gainCode) const;
@@ -51,6 +52,7 @@ protected:
AnalogueGainExpConstants exp;
};
+ std::optional<int16_t> blackLevel_;
AnalogueGainType gainType_;
AnalogueGainConstants gainConstants_;
diff --git a/src/ipa/libipa/histogram.h b/src/ipa/libipa/histogram.h
index 032adca0..6fd64168 100644
--- a/src/ipa/libipa/histogram.h
+++ b/src/ipa/libipa/histogram.h
@@ -7,7 +7,6 @@
#pragma once
-#include <assert.h>
#include <limits.h>
#include <stdint.h>
#include <type_traits>
diff --git a/src/ipa/libipa/matrix.h b/src/ipa/libipa/matrix.h
index 8aa8f343..5471e697 100644
--- a/src/ipa/libipa/matrix.h
+++ b/src/ipa/libipa/matrix.h
@@ -7,7 +7,6 @@
#pragma once
#include <algorithm>
-#include <cmath>
#include <sstream>
#include <vector>
diff --git a/src/ipa/libipa/matrix_interpolator.cpp b/src/ipa/libipa/matrix_interpolator.cpp
index 04ca177f..d5188f8a 100644
--- a/src/ipa/libipa/matrix_interpolator.cpp
+++ b/src/ipa/libipa/matrix_interpolator.cpp
@@ -6,15 +6,8 @@
*/
#include "matrix_interpolator.h"
-#include <algorithm>
-#include <string>
-
#include <libcamera/base/log.h>
-#include "libcamera/internal/yaml_parser.h"
-
-#include "matrix.h"
-
/**
* \file matrix_interpolator.h
* \brief Helper class for interpolating maps of matrices
diff --git a/src/ipa/libipa/matrix_interpolator.h b/src/ipa/libipa/matrix_interpolator.h
index 087c4fd1..afbce538 100644
--- a/src/ipa/libipa/matrix_interpolator.h
+++ b/src/ipa/libipa/matrix_interpolator.h
@@ -7,10 +7,8 @@
#pragma once
-#include <algorithm>
#include <map>
#include <string>
-#include <tuple>
#include <libcamera/base/log.h>
diff --git a/src/ipa/libipa/pwl.cpp b/src/ipa/libipa/pwl.cpp
index 9b213754..88fe2022 100644
--- a/src/ipa/libipa/pwl.cpp
+++ b/src/ipa/libipa/pwl.cpp
@@ -8,10 +8,8 @@
#include "pwl.h"
-#include <assert.h>
#include <cmath>
#include <sstream>
-#include <stdexcept>
/**
* \file pwl.h
diff --git a/src/ipa/libipa/pwl.h b/src/ipa/libipa/pwl.h
index b6f93494..d4ec9f4f 100644
--- a/src/ipa/libipa/pwl.h
+++ b/src/ipa/libipa/pwl.h
@@ -7,14 +7,11 @@
#pragma once
#include <algorithm>
-#include <cmath>
#include <functional>
#include <string>
#include <utility>
#include <vector>
-#include "libcamera/internal/yaml_parser.h"
-
#include "vector.h"
namespace libcamera {
diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h
index 556e0967..8612a06a 100644
--- a/src/ipa/libipa/vector.h
+++ b/src/ipa/libipa/vector.h
@@ -6,10 +6,10 @@
*/
#pragma once
-#include <algorithm>
#include <array>
#include <cmath>
-#include <sstream>
+#include <optional>
+#include <ostream>
#include <libcamera/base/log.h>
#include <libcamera/base/span.h>
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index f12f8b60..17d074d9 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -281,7 +281,7 @@ void Agc::queueRequest(IPAContext &context,
* \copydoc libcamera::ipa::Algorithm::prepare
*/
void Agc::prepare(IPAContext &context, const uint32_t frame,
- IPAFrameContext &frameContext, rkisp1_params_cfg *params)
+ IPAFrameContext &frameContext, RkISP1Params *params)
{
if (frameContext.agc.autoEnabled) {
frameContext.agc.exposure = context.activeState.agc.automatic.exposure;
@@ -291,41 +291,39 @@ void Agc::prepare(IPAContext &context, const uint32_t frame,
if (frame > 0 && !frameContext.agc.updateMetering)
return;
- /* Configure the measurement window. */
- params->meas.aec_config.meas_window = context.configuration.agc.measureWindow;
- /* Use a continuous method for measure. */
- params->meas.aec_config.autostop = RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0;
- /* Estimate Y as (R + G + B) x (85/256). */
- params->meas.aec_config.mode = RKISP1_CIF_ISP_EXP_MEASURING_MODE_1;
+ /*
+ * Configure the AEC measurements. Set the window, measure
+ * continuously, and estimate Y as (R + G + B) x (85/256).
+ */
+ auto aecConfig = params->block<BlockType::Aec>();
+ aecConfig.setEnabled(true);
+
+ aecConfig->meas_window = context.configuration.agc.measureWindow;
+ aecConfig->autostop = RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0;
+ aecConfig->mode = RKISP1_CIF_ISP_EXP_MEASURING_MODE_1;
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AEC;
- params->module_ens |= RKISP1_CIF_ISP_MODULE_AEC;
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_AEC;
+ /*
+ * Configure the histogram measurement. Set the window, produce a
+ * luminance histogram, and set the weights and predivider.
+ */
+ auto hstConfig = params->block<BlockType::Hst>();
+ hstConfig.setEnabled(true);
- /* Configure histogram. */
- params->meas.hst_config.meas_window = context.configuration.agc.measureWindow;
- /* Produce the luminance histogram. */
- params->meas.hst_config.mode = RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM;
+ hstConfig->meas_window = context.configuration.agc.measureWindow;
+ hstConfig->mode = RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM;
- /* Set an average weighted histogram. */
Span<uint8_t> weights{
- params->meas.hst_config.hist_weight,
+ hstConfig->hist_weight,
context.hw->numHistogramWeights
};
std::vector<uint8_t> &modeWeights = meteringModes_.at(frameContext.agc.meteringMode);
std::copy(modeWeights.begin(), modeWeights.end(), weights.begin());
- struct rkisp1_cif_isp_window window = params->meas.hst_config.meas_window;
+ struct rkisp1_cif_isp_window window = hstConfig->meas_window;
Size windowSize = { window.h_size, window.v_size };
- params->meas.hst_config.histogram_predivider =
+ hstConfig->histogram_predivider =
computeHistogramPredivider(windowSize,
- static_cast<rkisp1_cif_isp_histogram_mode>(params->meas.hst_config.mode));
-
- /* Update the configuration for histogram. */
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_HST;
- /* Enable the histogram measure unit. */
- params->module_ens |= RKISP1_CIF_ISP_MODULE_HST;
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_HST;
+ static_cast<rkisp1_cif_isp_histogram_mode>(hstConfig->mode));
}
void Agc::fillMetadata(IPAContext &context, IPAFrameContext &frameContext,
diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h
index 9ceaa82b..aa86f2c5 100644
--- a/src/ipa/rkisp1/algorithms/agc.h
+++ b/src/ipa/rkisp1/algorithms/agc.h
@@ -15,7 +15,6 @@
#include <libcamera/geometry.h>
#include "libipa/agc_mean_luminance.h"
-#include "libipa/histogram.h"
#include "algorithm.h"
@@ -37,7 +36,7 @@ public:
const ControlList &controls) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ RkISP1Params *params) override;
void process(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
const rkisp1_stat_buffer *stats,
diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp
index a01fe5d9..955a9ff4 100644
--- a/src/ipa/rkisp1/algorithms/awb.cpp
+++ b/src/ipa/rkisp1/algorithms/awb.cpp
@@ -8,12 +8,12 @@
#include "awb.h"
#include <algorithm>
-#include <cmath>
-#include <iomanip>
+#include <ios>
#include <libcamera/base/log.h>
#include <libcamera/control_ids.h>
+
#include <libcamera/ipa/core_ipa_interface.h>
/**
@@ -108,7 +108,7 @@ void Awb::queueRequest(IPAContext &context,
* \copydoc libcamera::ipa::Algorithm::prepare
*/
void Awb::prepare(IPAContext &context, const uint32_t frame,
- IPAFrameContext &frameContext, rkisp1_params_cfg *params)
+ IPAFrameContext &frameContext, RkISP1Params *params)
{
/*
* This is the latest time we can read the active state. This is the
@@ -120,29 +120,30 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,
frameContext.awb.gains.blue = context.activeState.awb.gains.automatic.blue;
}
- params->others.awb_gain_config.gain_green_b = 256 * frameContext.awb.gains.green;
- params->others.awb_gain_config.gain_blue = 256 * frameContext.awb.gains.blue;
- params->others.awb_gain_config.gain_red = 256 * frameContext.awb.gains.red;
- params->others.awb_gain_config.gain_green_r = 256 * frameContext.awb.gains.green;
+ auto gainConfig = params->block<BlockType::AwbGain>();
+ gainConfig.setEnabled(true);
- /* Update the gains. */
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
+ gainConfig->gain_green_b = std::clamp<int>(256 * frameContext.awb.gains.green, 0, 0x3ff);
+ gainConfig->gain_blue = std::clamp<int>(256 * frameContext.awb.gains.blue, 0, 0x3ff);
+ gainConfig->gain_red = std::clamp<int>(256 * frameContext.awb.gains.red, 0, 0x3ff);
+ gainConfig->gain_green_r = std::clamp<int>(256 * frameContext.awb.gains.green, 0, 0x3ff);
/* If we have already set the AWB measurement parameters, return. */
if (frame > 0)
return;
- rkisp1_cif_isp_awb_meas_config &awb_config = params->meas.awb_meas_config;
+ auto awbConfig = params->block<BlockType::Awb>();
+ awbConfig.setEnabled(true);
/* Configure the measure window for AWB. */
- awb_config.awb_wnd = context.configuration.awb.measureWindow;
+ awbConfig->awb_wnd = context.configuration.awb.measureWindow;
/* Number of frames to use to estimate the means (0 means 1 frame). */
- awb_config.frames = 0;
+ awbConfig->frames = 0;
/* Select RGB or YCbCr means measurement. */
if (rgbMode_) {
- awb_config.awb_mode = RKISP1_CIF_ISP_AWB_MODE_RGB;
+ awbConfig->awb_mode = RKISP1_CIF_ISP_AWB_MODE_RGB;
/*
* For RGB-based measurements, pixels are selected with maximum
@@ -150,19 +151,19 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,
* awb_ref_cr, awb_min_y and awb_ref_cb respectively. The other
* values are not used, set them to 0.
*/
- awb_config.awb_ref_cr = 250;
- awb_config.min_y = 250;
- awb_config.awb_ref_cb = 250;
+ awbConfig->awb_ref_cr = 250;
+ awbConfig->min_y = 250;
+ awbConfig->awb_ref_cb = 250;
- awb_config.max_y = 0;
- awb_config.min_c = 0;
- awb_config.max_csum = 0;
+ awbConfig->max_y = 0;
+ awbConfig->min_c = 0;
+ awbConfig->max_csum = 0;
} else {
- awb_config.awb_mode = RKISP1_CIF_ISP_AWB_MODE_YCBCR;
+ awbConfig->awb_mode = RKISP1_CIF_ISP_AWB_MODE_YCBCR;
/* Set the reference Cr and Cb (AWB target) to white. */
- awb_config.awb_ref_cb = 128;
- awb_config.awb_ref_cr = 128;
+ awbConfig->awb_ref_cb = 128;
+ awbConfig->awb_ref_cr = 128;
/*
* Filter out pixels based on luminance and chrominance values.
@@ -170,20 +171,11 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,
* range, while the acceptable chroma values are specified with
* a minimum of 16 and a maximum Cb+Cr sum of 250.
*/
- awb_config.min_y = 16;
- awb_config.max_y = 250;
- awb_config.min_c = 16;
- awb_config.max_csum = 250;
+ awbConfig->min_y = 16;
+ awbConfig->max_y = 250;
+ awbConfig->min_c = 16;
+ awbConfig->max_csum = 250;
}
-
- /* Enable the AWB gains. */
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
- params->module_ens |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
-
- /* Update the AWB measurement parameters and enable the AWB module. */
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB;
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_AWB;
- params->module_ens |= RKISP1_CIF_ISP_MODULE_AWB;
}
uint32_t Awb::estimateCCT(double red, double green, double blue)
@@ -218,6 +210,12 @@ void Awb::process(IPAContext &context,
double redMean;
double blueMean;
+ metadata.set(controls::AwbEnable, frameContext.awb.autoEnabled);
+ metadata.set(controls::ColourGains, {
+ static_cast<float>(frameContext.awb.gains.red),
+ static_cast<float>(frameContext.awb.gains.blue)
+ });
+
if (rgbMode_) {
greenMean = awb->awb_mean[0].mean_y_or_g;
redMean = awb->awb_mean[0].mean_cr_or_r;
@@ -273,12 +271,15 @@ void Awb::process(IPAContext &context,
*/
if (redMean < kMeanMinThreshold && greenMean < kMeanMinThreshold &&
blueMean < kMeanMinThreshold) {
- frameContext.awb.temperatureK = activeState.awb.temperatureK;
+ metadata.set(controls::ColourTemperature, activeState.awb.temperatureK);
return;
}
activeState.awb.temperatureK = estimateCCT(redMean, greenMean, blueMean);
+ /* Metadata shall contain the up to date measurement */
+ metadata.set(controls::ColourTemperature, activeState.awb.temperatureK);
+
/*
* Estimate the red and blue gains to apply in a grey world. The green
* gain is hardcoded to 1.0. Avoid divisions by zero by clamping the
@@ -305,21 +306,13 @@ void Awb::process(IPAContext &context,
activeState.awb.gains.automatic.blue = blueGain;
activeState.awb.gains.automatic.green = 1.0;
- frameContext.awb.temperatureK = activeState.awb.temperatureK;
-
- metadata.set(controls::AwbEnable, frameContext.awb.autoEnabled);
- metadata.set(controls::ColourGains, {
- static_cast<float>(frameContext.awb.gains.red),
- static_cast<float>(frameContext.awb.gains.blue)
- });
- metadata.set(controls::ColourTemperature, frameContext.awb.temperatureK);
-
- LOG(RkISP1Awb, Debug) << std::showpoint
+ LOG(RkISP1Awb, Debug)
+ << std::showpoint
<< "Means [" << redMean << ", " << greenMean << ", " << blueMean
<< "], gains [" << activeState.awb.gains.automatic.red << ", "
<< activeState.awb.gains.automatic.green << ", "
<< activeState.awb.gains.automatic.blue << "], temp "
- << frameContext.awb.temperatureK << "K";
+ << activeState.awb.temperatureK << "K";
}
REGISTER_IPA_ALGORITHM(Awb, "Awb")
diff --git a/src/ipa/rkisp1/algorithms/awb.h b/src/ipa/rkisp1/algorithms/awb.h
index 06c92896..b3b2c0bb 100644
--- a/src/ipa/rkisp1/algorithms/awb.h
+++ b/src/ipa/rkisp1/algorithms/awb.h
@@ -25,7 +25,7 @@ public:
const ControlList &controls) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ RkISP1Params *params) override;
void process(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
const rkisp1_stat_buffer *stats,
diff --git a/src/ipa/rkisp1/algorithms/blc.cpp b/src/ipa/rkisp1/algorithms/blc.cpp
index d2e74354..98cb7145 100644
--- a/src/ipa/rkisp1/algorithms/blc.cpp
+++ b/src/ipa/rkisp1/algorithms/blc.cpp
@@ -7,8 +7,12 @@
#include "blc.h"
+#include <linux/videodev2.h>
+
#include <libcamera/base/log.h>
+#include <libcamera/control_ids.h>
+
#include "libcamera/internal/yaml_parser.h"
/**
@@ -36,22 +40,62 @@ namespace ipa::rkisp1::algorithms {
LOG_DEFINE_CATEGORY(RkISP1Blc)
BlackLevelCorrection::BlackLevelCorrection()
- : tuningParameters_(false)
{
+ /*
+ * This is a bit of a hack. In raw mode no black level correction
+ * happens. This flag is used to ensure the metadata gets populated with
+ * the black level which is needed to capture proper raw images for
+ * tuning.
+ */
+ supportsRaw_ = true;
}
/**
* \copydoc libcamera::ipa::Algorithm::init
*/
-int BlackLevelCorrection::init([[maybe_unused]] IPAContext &context,
- const YamlObject &tuningData)
+int BlackLevelCorrection::init(IPAContext &context, const YamlObject &tuningData)
{
- blackLevelRed_ = tuningData["R"].get<int16_t>(256);
- blackLevelGreenR_ = tuningData["Gr"].get<int16_t>(256);
- blackLevelGreenB_ = tuningData["Gb"].get<int16_t>(256);
- blackLevelBlue_ = tuningData["B"].get<int16_t>(256);
-
- tuningParameters_ = true;
+ std::optional<int16_t> levelRed = tuningData["R"].get<int16_t>();
+ std::optional<int16_t> levelGreenR = tuningData["Gr"].get<int16_t>();
+ std::optional<int16_t> levelGreenB = tuningData["Gb"].get<int16_t>();
+ std::optional<int16_t> levelBlue = tuningData["B"].get<int16_t>();
+ bool tuningHasLevels = levelRed && levelGreenR && levelGreenB && levelBlue;
+
+ auto blackLevel = context.camHelper->blackLevel();
+ if (!blackLevel) {
+ /*
+ * Not all camera sensor helpers have been updated with black
+ * levels. Print a warning and fall back to the levels from the
+ * tuning data to preserve backward compatibility. This should
+ * be removed once all helpers provide the data.
+ */
+ LOG(RkISP1Blc, Warning)
+ << "No black levels provided by camera sensor helper"
+ << ", please fix";
+
+ blackLevelRed_ = levelRed.value_or(4096);
+ blackLevelGreenR_ = levelGreenR.value_or(4096);
+ blackLevelGreenB_ = levelGreenB.value_or(4096);
+ blackLevelBlue_ = levelBlue.value_or(4096);
+ } else if (tuningHasLevels) {
+ /*
+ * If black levels are provided in the tuning file, use them to
+ * avoid breaking existing camera tuning. This is deprecated and
+ * will be removed.
+ */
+ LOG(RkISP1Blc, Warning)
+ << "Deprecated: black levels overwritten by tuning file";
+
+ blackLevelRed_ = *levelRed;
+ blackLevelGreenR_ = *levelGreenR;
+ blackLevelGreenB_ = *levelGreenB;
+ blackLevelBlue_ = *levelBlue;
+ } else {
+ blackLevelRed_ = *blackLevel;
+ blackLevelGreenR_ = *blackLevel;
+ blackLevelGreenB_ = *blackLevel;
+ blackLevelBlue_ = *blackLevel;
+ }
LOG(RkISP1Blc, Debug)
<< "Black levels: red " << blackLevelRed_
@@ -62,29 +106,80 @@ int BlackLevelCorrection::init([[maybe_unused]] IPAContext &context,
return 0;
}
+int BlackLevelCorrection::configure(IPAContext &context,
+ [[maybe_unused]] const IPACameraSensorInfo &configInfo)
+{
+ /*
+ * BLC on ISP versions that include the companding block requires usage
+ * of the extensible parameters format.
+ */
+ supported_ = context.configuration.paramFormat == V4L2_META_FMT_RK_ISP1_EXT_PARAMS ||
+ !context.hw->compand;
+
+ if (!supported_)
+ LOG(RkISP1Blc, Warning)
+ << "BLC in companding block requires extensible parameters";
+
+ return 0;
+}
+
/**
* \copydoc libcamera::ipa::Algorithm::prepare
*/
-void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,
+void BlackLevelCorrection::prepare(IPAContext &context,
const uint32_t frame,
[[maybe_unused]] IPAFrameContext &frameContext,
- rkisp1_params_cfg *params)
+ RkISP1Params *params)
{
+ if (context.configuration.raw)
+ return;
+
if (frame > 0)
return;
- if (!tuningParameters_)
+ if (!supported_)
return;
- params->others.bls_config.enable_auto = 0;
- params->others.bls_config.fixed_val.r = blackLevelRed_;
- params->others.bls_config.fixed_val.gr = blackLevelGreenR_;
- params->others.bls_config.fixed_val.gb = blackLevelGreenB_;
- params->others.bls_config.fixed_val.b = blackLevelBlue_;
+ if (context.hw->compand) {
+ auto config = params->block<BlockType::CompandBls>();
+ config.setEnabled(true);
+
+ /*
+ * Scale up to the 20-bit black levels used by the companding
+ * block.
+ */
+ config->r = blackLevelRed_ << 4;
+ config->gr = blackLevelGreenR_ << 4;
+ config->gb = blackLevelGreenB_ << 4;
+ config->b = blackLevelBlue_ << 4;
+ } else {
+ auto config = params->block<BlockType::Bls>();
+ config.setEnabled(true);
+
+ config->enable_auto = 0;
+
+ /* Scale down to the 12-bit black levels used by the BLS block. */
+ config->fixed_val.r = blackLevelRed_ >> 4;
+ config->fixed_val.gr = blackLevelGreenR_ >> 4;
+ config->fixed_val.gb = blackLevelGreenB_ >> 4;
+ config->fixed_val.b = blackLevelBlue_ >> 4;
+ }
+}
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_BLS;
- params->module_ens |= RKISP1_CIF_ISP_MODULE_BLS;
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_BLS;
+/**
+ * \copydoc libcamera::ipa::Algorithm::process
+ */
+void BlackLevelCorrection::process([[maybe_unused]] IPAContext &context,
+ [[maybe_unused]] const uint32_t frame,
+ [[maybe_unused]] IPAFrameContext &frameContext,
+ [[maybe_unused]] const rkisp1_stat_buffer *stats,
+ ControlList &metadata)
+{
+ metadata.set(controls::SensorBlackLevels,
+ { static_cast<int32_t>(blackLevelRed_),
+ static_cast<int32_t>(blackLevelGreenR_),
+ static_cast<int32_t>(blackLevelGreenB_),
+ static_cast<int32_t>(blackLevelBlue_) });
}
REGISTER_IPA_ALGORITHM(BlackLevelCorrection, "BlackLevelCorrection")
diff --git a/src/ipa/rkisp1/algorithms/blc.h b/src/ipa/rkisp1/algorithms/blc.h
index 460ebcc1..f797ae44 100644
--- a/src/ipa/rkisp1/algorithms/blc.h
+++ b/src/ipa/rkisp1/algorithms/blc.h
@@ -20,12 +20,19 @@ public:
~BlackLevelCorrection() = default;
int init(IPAContext &context, const YamlObject &tuningData) override;
+ int configure(IPAContext &context,
+ const IPACameraSensorInfo &configInfo) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ RkISP1Params *params) override;
+ void process(IPAContext &context, const uint32_t frame,
+ IPAFrameContext &frameContext,
+ const rkisp1_stat_buffer *stats,
+ ControlList &metadata) override;
private:
- bool tuningParameters_;
+ bool supported_;
+
int16_t blackLevelRed_;
int16_t blackLevelGreenR_;
int16_t blackLevelGreenB_;
diff --git a/src/ipa/rkisp1/algorithms/ccm.cpp b/src/ipa/rkisp1/algorithms/ccm.cpp
index c1f5403a..1ca0e73f 100644
--- a/src/ipa/rkisp1/algorithms/ccm.cpp
+++ b/src/ipa/rkisp1/algorithms/ccm.cpp
@@ -7,11 +7,7 @@
#include "ccm.h"
-#include <algorithm>
-#include <chrono>
-#include <cmath>
-#include <tuple>
-#include <vector>
+#include <map>
#include <libcamera/base/log.h>
#include <libcamera/base/utils.h>
@@ -71,12 +67,10 @@ int Ccm::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData
return 0;
}
-void Ccm::setParameters(rkisp1_params_cfg *params,
+void Ccm::setParameters(struct rkisp1_cif_isp_ctk_config &config,
const Matrix<float, 3, 3> &matrix,
const Matrix<int16_t, 3, 1> &offsets)
{
- struct rkisp1_cif_isp_ctk_config &config = params->others.ctk_config;
-
/*
* 4 bit integer and 7 bit fractional, ranging from -8 (0x400) to
* +7.992 (0x3ff)
@@ -92,18 +86,13 @@ void Ccm::setParameters(rkisp1_params_cfg *params,
LOG(RkISP1Ccm, Debug) << "Setting matrix " << matrix;
LOG(RkISP1Ccm, Debug) << "Setting offsets " << offsets;
-
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_CTK;
- params->module_ens |= RKISP1_CIF_ISP_MODULE_CTK;
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_CTK;
}
/**
* \copydoc libcamera::ipa::Algorithm::prepare
*/
void Ccm::prepare(IPAContext &context, const uint32_t frame,
- IPAFrameContext &frameContext,
- rkisp1_params_cfg *params)
+ IPAFrameContext &frameContext, RkISP1Params *params)
{
uint32_t ct = context.activeState.awb.temperatureK;
@@ -111,16 +100,21 @@ void Ccm::prepare(IPAContext &context, const uint32_t frame,
* \todo The colour temperature will likely be noisy, add filtering to
* avoid updating the CCM matrix all the time.
*/
- if (frame > 0 && ct == ct_)
+ if (frame > 0 && ct == ct_) {
+ frameContext.ccm.ccm = context.activeState.ccm.ccm;
return;
+ }
ct_ = ct;
Matrix<float, 3, 3> ccm = ccm_.get(ct);
Matrix<int16_t, 3, 1> offsets = offsets_.get(ct);
+ context.activeState.ccm.ccm = ccm;
frameContext.ccm.ccm = ccm;
- setParameters(params, ccm, offsets);
+ auto config = params->block<BlockType::Ctk>();
+ config.setEnabled(true);
+ setParameters(*config, ccm, offsets);
}
/**
@@ -135,7 +129,7 @@ void Ccm::process([[maybe_unused]] IPAContext &context,
float m[9];
for (unsigned int i = 0; i < 3; i++) {
for (unsigned int j = 0; j < 3; j++)
- m[i] = frameContext.ccm.ccm[i][j];
+ m[i * 3 + j] = frameContext.ccm.ccm[i][j];
}
metadata.set(controls::ColourCorrectionMatrix, m);
}
diff --git a/src/ipa/rkisp1/algorithms/ccm.h b/src/ipa/rkisp1/algorithms/ccm.h
index 30cb8821..9daadb68 100644
--- a/src/ipa/rkisp1/algorithms/ccm.h
+++ b/src/ipa/rkisp1/algorithms/ccm.h
@@ -27,7 +27,7 @@ public:
int init(IPAContext &context, const YamlObject &tuningData) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ RkISP1Params *params) override;
void process(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
const rkisp1_stat_buffer *stats,
@@ -35,7 +35,7 @@ public:
private:
void parseYaml(const YamlObject &tuningData);
- void setParameters(rkisp1_params_cfg *params,
+ void setParameters(struct rkisp1_cif_isp_ctk_config &config,
const Matrix<float, 3, 3> &matrix,
const Matrix<int16_t, 3, 1> &offsets);
diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp
index ef0931b2..d1fff699 100644
--- a/src/ipa/rkisp1/algorithms/cproc.cpp
+++ b/src/ipa/rkisp1/algorithms/cproc.cpp
@@ -140,19 +140,17 @@ void ColorProcessing::queueRequest(IPAContext &context,
void ColorProcessing::prepare([[maybe_unused]] IPAContext &context,
[[maybe_unused]] const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params)
+ RkISP1Params *params)
{
/* Check if the algorithm configuration has been updated. */
if (!frameContext.cproc.update)
return;
- params->others.cproc_config.brightness = frameContext.cproc.brightness;
- params->others.cproc_config.contrast = frameContext.cproc.contrast;
- params->others.cproc_config.sat = frameContext.cproc.saturation;
-
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_CPROC;
- params->module_ens |= RKISP1_CIF_ISP_MODULE_CPROC;
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_CPROC;
+ auto config = params->block<BlockType::Cproc>();
+ config.setEnabled(true);
+ config->brightness = frameContext.cproc.brightness;
+ config->contrast = frameContext.cproc.contrast;
+ config->sat = frameContext.cproc.saturation;
}
REGISTER_IPA_ALGORITHM(ColorProcessing, "ColorProcessing")
diff --git a/src/ipa/rkisp1/algorithms/cproc.h b/src/ipa/rkisp1/algorithms/cproc.h
index e50e7200..fd38fd17 100644
--- a/src/ipa/rkisp1/algorithms/cproc.h
+++ b/src/ipa/rkisp1/algorithms/cproc.h
@@ -29,7 +29,7 @@ public:
const ControlList &controls) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ RkISP1Params *params) override;
};
} /* namespace ipa::rkisp1::algorithms */
diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp
index b5a339e9..78946281 100644
--- a/src/ipa/rkisp1/algorithms/dpcc.cpp
+++ b/src/ipa/rkisp1/algorithms/dpcc.cpp
@@ -232,16 +232,14 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
void DefectPixelClusterCorrection::prepare([[maybe_unused]] IPAContext &context,
const uint32_t frame,
[[maybe_unused]] IPAFrameContext &frameContext,
- rkisp1_params_cfg *params)
+ RkISP1Params *params)
{
if (frame > 0)
return;
- params->others.dpcc_config = config_;
-
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_DPCC;
- params->module_ens |= RKISP1_CIF_ISP_MODULE_DPCC;
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_DPCC;
+ auto config = params->block<BlockType::Dpcc>();
+ config.setEnabled(true);
+ *config = config_;
}
REGISTER_IPA_ALGORITHM(DefectPixelClusterCorrection, "DefectPixelClusterCorrection")
diff --git a/src/ipa/rkisp1/algorithms/dpcc.h b/src/ipa/rkisp1/algorithms/dpcc.h
index d39b7bed..b77766c3 100644
--- a/src/ipa/rkisp1/algorithms/dpcc.h
+++ b/src/ipa/rkisp1/algorithms/dpcc.h
@@ -22,7 +22,7 @@ public:
int init(IPAContext &context, const YamlObject &tuningData) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ RkISP1Params *params) override;
private:
rkisp1_cif_isp_dpcc_config config_;
diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp
index abf95728..cb6095da 100644
--- a/src/ipa/rkisp1/algorithms/dpf.cpp
+++ b/src/ipa/rkisp1/algorithms/dpf.cpp
@@ -7,7 +7,9 @@
#include "dpf.h"
-#include <cmath>
+#include <algorithm>
+#include <string>
+#include <vector>
#include <libcamera/base/log.h>
@@ -215,15 +217,21 @@ void Dpf::queueRequest(IPAContext &context,
* \copydoc libcamera::ipa::Algorithm::prepare
*/
void Dpf::prepare(IPAContext &context, const uint32_t frame,
- IPAFrameContext &frameContext, rkisp1_params_cfg *params)
+ IPAFrameContext &frameContext, RkISP1Params *params)
{
- if (frame == 0) {
- params->others.dpf_config = config_;
- params->others.dpf_strength_config = strengthConfig_;
+ if (!frameContext.dpf.update && frame > 0)
+ return;
+
+ auto config = params->block<BlockType::Dpf>();
+ config.setEnabled(frameContext.dpf.denoise);
+
+ if (frameContext.dpf.denoise) {
+ *config = config_;
const auto &awb = context.configuration.awb;
const auto &lsc = context.configuration.lsc;
- auto &mode = params->others.dpf_config.gain.mode;
+
+ auto &mode = config->gain.mode;
/*
* The DPF needs to take into account the total amount of
@@ -241,15 +249,12 @@ void Dpf::prepare(IPAContext &context, const uint32_t frame,
mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS;
else
mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED;
-
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_DPF |
- RKISP1_CIF_ISP_MODULE_DPF_STRENGTH;
}
- if (frameContext.dpf.update) {
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_DPF;
- if (frameContext.dpf.denoise)
- params->module_ens |= RKISP1_CIF_ISP_MODULE_DPF;
+ if (frame == 0) {
+ auto strengthConfig = params->block<BlockType::DpfStrength>();
+ strengthConfig.setEnabled(true);
+ *strengthConfig = strengthConfig_;
}
}
diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h
index da0115ba..2dd8cd36 100644
--- a/src/ipa/rkisp1/algorithms/dpf.h
+++ b/src/ipa/rkisp1/algorithms/dpf.h
@@ -27,7 +27,7 @@ public:
const ControlList &controls) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ RkISP1Params *params) override;
private:
struct rkisp1_cif_isp_dpf_config config_;
diff --git a/src/ipa/rkisp1/algorithms/filter.cpp b/src/ipa/rkisp1/algorithms/filter.cpp
index 9752248a..7598ef8a 100644
--- a/src/ipa/rkisp1/algorithms/filter.cpp
+++ b/src/ipa/rkisp1/algorithms/filter.cpp
@@ -104,7 +104,7 @@ void Filter::queueRequest(IPAContext &context,
*/
void Filter::prepare([[maybe_unused]] IPAContext &context,
[[maybe_unused]] const uint32_t frame,
- IPAFrameContext &frameContext, rkisp1_params_cfg *params)
+ IPAFrameContext &frameContext, RkISP1Params *params)
{
/* Check if the algorithm configuration has been updated. */
if (!frameContext.filter.update)
@@ -160,23 +160,25 @@ void Filter::prepare([[maybe_unused]] IPAContext &context,
uint8_t denoise = frameContext.filter.denoise;
uint8_t sharpness = frameContext.filter.sharpness;
- auto &flt_config = params->others.flt_config;
-
- flt_config.fac_sh0 = filt_fac_sh0[sharpness];
- flt_config.fac_sh1 = filt_fac_sh1[sharpness];
- flt_config.fac_mid = filt_fac_mid[sharpness];
- flt_config.fac_bl0 = filt_fac_bl0[sharpness];
- flt_config.fac_bl1 = filt_fac_bl1[sharpness];
-
- flt_config.lum_weight = kFiltLumWeightDefault;
- flt_config.mode = kFiltModeDefault;
- flt_config.thresh_sh0 = filt_thresh_sh0[denoise];
- flt_config.thresh_sh1 = filt_thresh_sh1[denoise];
- flt_config.thresh_bl0 = filt_thresh_bl0[denoise];
- flt_config.thresh_bl1 = filt_thresh_bl1[denoise];
- flt_config.grn_stage1 = stage1_select[denoise];
- flt_config.chr_v_mode = filt_chr_v_mode[denoise];
- flt_config.chr_h_mode = filt_chr_h_mode[denoise];
+
+ auto config = params->block<BlockType::Flt>();
+ config.setEnabled(true);
+
+ config->fac_sh0 = filt_fac_sh0[sharpness];
+ config->fac_sh1 = filt_fac_sh1[sharpness];
+ config->fac_mid = filt_fac_mid[sharpness];
+ config->fac_bl0 = filt_fac_bl0[sharpness];
+ config->fac_bl1 = filt_fac_bl1[sharpness];
+
+ config->lum_weight = kFiltLumWeightDefault;
+ config->mode = kFiltModeDefault;
+ config->thresh_sh0 = filt_thresh_sh0[denoise];
+ config->thresh_sh1 = filt_thresh_sh1[denoise];
+ config->thresh_bl0 = filt_thresh_bl0[denoise];
+ config->thresh_bl1 = filt_thresh_bl1[denoise];
+ config->grn_stage1 = stage1_select[denoise];
+ config->chr_v_mode = filt_chr_v_mode[denoise];
+ config->chr_h_mode = filt_chr_h_mode[denoise];
/*
* Combined high denoising and high sharpening requires some
@@ -186,27 +188,23 @@ void Filter::prepare([[maybe_unused]] IPAContext &context,
*/
if (denoise == 9) {
if (sharpness > 3)
- flt_config.grn_stage1 = 2;
+ config->grn_stage1 = 2;
} else if (denoise == 10) {
if (sharpness > 5)
- flt_config.grn_stage1 = 2;
+ config->grn_stage1 = 2;
else if (sharpness > 3)
- flt_config.grn_stage1 = 1;
+ config->grn_stage1 = 1;
}
if (denoise > 7) {
if (sharpness > 7) {
- flt_config.fac_bl0 /= 2;
- flt_config.fac_bl1 /= 4;
+ config->fac_bl0 /= 2;
+ config->fac_bl1 /= 4;
} else if (sharpness > 4) {
- flt_config.fac_bl0 = flt_config.fac_bl0 * 3 / 4;
- flt_config.fac_bl1 /= 2;
+ config->fac_bl0 = config->fac_bl0 * 3 / 4;
+ config->fac_bl1 /= 2;
}
}
-
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_FLT;
- params->module_ens |= RKISP1_CIF_ISP_MODULE_FLT;
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_FLT;
}
REGISTER_IPA_ALGORITHM(Filter, "Filter")
diff --git a/src/ipa/rkisp1/algorithms/filter.h b/src/ipa/rkisp1/algorithms/filter.h
index d595811d..8f858e57 100644
--- a/src/ipa/rkisp1/algorithms/filter.h
+++ b/src/ipa/rkisp1/algorithms/filter.h
@@ -26,7 +26,7 @@ public:
const ControlList &controls) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ RkISP1Params *params) override;
};
} /* namespace ipa::rkisp1::algorithms */
diff --git a/src/ipa/rkisp1/algorithms/goc.cpp b/src/ipa/rkisp1/algorithms/goc.cpp
index a82cee3b..a9493678 100644
--- a/src/ipa/rkisp1/algorithms/goc.cpp
+++ b/src/ipa/rkisp1/algorithms/goc.cpp
@@ -99,11 +99,14 @@ void GammaOutCorrection::queueRequest(IPAContext &context, const uint32_t frame,
void GammaOutCorrection::prepare(IPAContext &context,
[[maybe_unused]] const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params)
+ RkISP1Params *params)
{
ASSERT(context.hw->numGammaOutSamples ==
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10);
+ if (!frameContext.goc.update)
+ return;
+
/*
* The logarithmic segments as specified in the reference.
* Plus an additional 0 to make the loop easier
@@ -112,10 +115,11 @@ void GammaOutCorrection::prepare(IPAContext &context,
64, 64, 64, 64, 128, 128, 128, 128, 256,
256, 256, 512, 512, 512, 512, 512, 0
};
- __u16 *gamma_y = params->others.goc_config.gamma_y;
- if (!frameContext.goc.update)
- return;
+ auto config = params->block<BlockType::Goc>();
+ config.setEnabled(true);
+
+ __u16 *gamma_y = config->gamma_y;
unsigned x = 0;
for (const auto [i, size] : utils::enumerate(segments)) {
@@ -123,10 +127,7 @@ void GammaOutCorrection::prepare(IPAContext &context,
x += size;
}
- params->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC;
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC;
- params->module_ens |= RKISP1_CIF_ISP_MODULE_GOC;
+ config->mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;
}
/**
diff --git a/src/ipa/rkisp1/algorithms/goc.h b/src/ipa/rkisp1/algorithms/goc.h
index 0e05d7ce..bb2ddfc9 100644
--- a/src/ipa/rkisp1/algorithms/goc.h
+++ b/src/ipa/rkisp1/algorithms/goc.h
@@ -28,7 +28,7 @@ public:
const ControlList &controls) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ RkISP1Params *params) override;
void process(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
const rkisp1_stat_buffer *stats,
diff --git a/src/ipa/rkisp1/algorithms/gsl.cpp b/src/ipa/rkisp1/algorithms/gsl.cpp
index 9b056c6e..9604c0ac 100644
--- a/src/ipa/rkisp1/algorithms/gsl.cpp
+++ b/src/ipa/rkisp1/algorithms/gsl.cpp
@@ -119,24 +119,20 @@ int GammaSensorLinearization::init([[maybe_unused]] IPAContext &context,
void GammaSensorLinearization::prepare([[maybe_unused]] IPAContext &context,
const uint32_t frame,
[[maybe_unused]] IPAFrameContext &frameContext,
- rkisp1_params_cfg *params)
+ RkISP1Params *params)
{
if (frame > 0)
return;
- params->others.sdg_config.xa_pnts.gamma_dx0 = gammaDx_[0];
- params->others.sdg_config.xa_pnts.gamma_dx1 = gammaDx_[1];
+ auto config = params->block<BlockType::Sdg>();
+ config.setEnabled(true);
- std::copy(curveYr_.begin(), curveYr_.end(),
- params->others.sdg_config.curve_r.gamma_y);
- std::copy(curveYg_.begin(), curveYg_.end(),
- params->others.sdg_config.curve_g.gamma_y);
- std::copy(curveYb_.begin(), curveYb_.end(),
- params->others.sdg_config.curve_b.gamma_y);
+ config->xa_pnts.gamma_dx0 = gammaDx_[0];
+ config->xa_pnts.gamma_dx1 = gammaDx_[1];
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_SDG;
- params->module_ens |= RKISP1_CIF_ISP_MODULE_SDG;
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_SDG;
+ std::copy(curveYr_.begin(), curveYr_.end(), config->curve_r.gamma_y);
+ std::copy(curveYg_.begin(), curveYg_.end(), config->curve_g.gamma_y);
+ std::copy(curveYb_.begin(), curveYb_.end(), config->curve_b.gamma_y);
}
REGISTER_IPA_ALGORITHM(GammaSensorLinearization, "GammaSensorLinearization")
diff --git a/src/ipa/rkisp1/algorithms/gsl.h b/src/ipa/rkisp1/algorithms/gsl.h
index c404105e..91cf6efa 100644
--- a/src/ipa/rkisp1/algorithms/gsl.h
+++ b/src/ipa/rkisp1/algorithms/gsl.h
@@ -22,7 +22,7 @@ public:
int init(IPAContext &context, const YamlObject &tuningData) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ RkISP1Params *params) override;
private:
uint32_t gammaDx_[2];
diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp
index 161183fc..5f3a0388 100644
--- a/src/ipa/rkisp1/algorithms/lsc.cpp
+++ b/src/ipa/rkisp1/algorithms/lsc.cpp
@@ -185,18 +185,12 @@ int LensShadingCorrection::configure(IPAContext &context,
return 0;
}
-void LensShadingCorrection::setParameters(rkisp1_params_cfg *params)
+void LensShadingCorrection::setParameters(rkisp1_cif_isp_lsc_config &config)
{
- struct rkisp1_cif_isp_lsc_config &config = params->others.lsc_config;
-
memcpy(config.x_grad_tbl, xGrad_, sizeof(config.x_grad_tbl));
memcpy(config.y_grad_tbl, yGrad_, sizeof(config.y_grad_tbl));
memcpy(config.x_size_tbl, xSizes_, sizeof(config.x_size_tbl));
memcpy(config.y_size_tbl, ySizes_, sizeof(config.y_size_tbl));
-
- params->module_en_update |= RKISP1_CIF_ISP_MODULE_LSC;
- params->module_ens |= RKISP1_CIF_ISP_MODULE_LSC;
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_LSC;
}
void LensShadingCorrection::copyTable(rkisp1_cif_isp_lsc_config &config,
@@ -248,10 +242,8 @@ void LensShadingCorrection::interpolateTable(rkisp1_cif_isp_lsc_config &config,
void LensShadingCorrection::prepare(IPAContext &context,
const uint32_t frame,
[[maybe_unused]] IPAFrameContext &frameContext,
- rkisp1_params_cfg *params)
+ RkISP1Params *params)
{
- struct rkisp1_cif_isp_lsc_config &config = params->others.lsc_config;
-
/*
* If there is only one set, the configuration has already been done
* for first frame.
@@ -264,8 +256,11 @@ void LensShadingCorrection::prepare(IPAContext &context,
* never be relevant.
*/
if (sets_.size() == 1) {
- setParameters(params);
- copyTable(config, sets_.cbegin()->second);
+ auto config = params->block<BlockType::Lsc>();
+ config.setEnabled(true);
+
+ setParameters(*config);
+ copyTable(*config, sets_.cbegin()->second);
return;
}
@@ -294,13 +289,15 @@ void LensShadingCorrection::prepare(IPAContext &context,
(lastCt_.adjusted <= ct && ct <= lastCt_.original))
return;
- setParameters(params);
+ auto config = params->block<BlockType::Lsc>();
+ config.setEnabled(true);
+ setParameters(*config);
/*
* The color temperature matches exactly one of the available LSC tables.
*/
if (sets_.count(ct)) {
- copyTable(config, sets_[ct]);
+ copyTable(*config, sets_[ct]);
lastCt_ = { ct, ct };
return;
}
@@ -319,7 +316,7 @@ void LensShadingCorrection::prepare(IPAContext &context,
if (diff0 < threshold || diff1 < threshold) {
const Components &set = diff0 < diff1 ? set0 : set1;
LOG(RkISP1Lsc, Debug) << "using LSC table for " << set.ct;
- copyTable(config, set);
+ copyTable(*config, set);
lastCt_ = { ct, set.ct };
return;
}
@@ -331,7 +328,7 @@ void LensShadingCorrection::prepare(IPAContext &context,
LOG(RkISP1Lsc, Debug)
<< "ct is " << ct << ", interpolating between "
<< ct0 << " and " << ct1;
- interpolateTable(config, set0, set1, ct);
+ interpolateTable(*config, set0, set1, ct);
lastCt_ = { ct, ct };
}
diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h
index 5baf5927..a9c7a230 100644
--- a/src/ipa/rkisp1/algorithms/lsc.h
+++ b/src/ipa/rkisp1/algorithms/lsc.h
@@ -25,7 +25,7 @@ public:
int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ RkISP1Params *params) override;
private:
struct Components {
@@ -36,7 +36,7 @@ private:
std::vector<uint16_t> b;
};
- void setParameters(rkisp1_params_cfg *params);
+ void setParameters(rkisp1_cif_isp_lsc_config &config);
void copyTable(rkisp1_cif_isp_lsc_config &config, const Components &set0);
void interpolateTable(rkisp1_cif_isp_lsc_config &config,
const Components &set0, const Components &set1,
diff --git a/src/ipa/rkisp1/data/imx219.yaml b/src/ipa/rkisp1/data/imx219.yaml
index cbcc43b8..0d99cb52 100644
--- a/src/ipa/rkisp1/data/imx219.yaml
+++ b/src/ipa/rkisp1/data/imx219.yaml
@@ -6,10 +6,6 @@ algorithms:
- Agc:
- Awb:
- BlackLevelCorrection:
- R: 256
- Gr: 256
- Gb: 256
- B: 256
- LensShadingCorrection:
x-size: [ 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625 ]
y-size: [ 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625 ]
diff --git a/src/ipa/rkisp1/data/imx258.yaml b/src/ipa/rkisp1/data/imx258.yaml
index 43dddf20..202af36a 100644
--- a/src/ipa/rkisp1/data/imx258.yaml
+++ b/src/ipa/rkisp1/data/imx258.yaml
@@ -5,6 +5,7 @@ version: 1
algorithms:
- Agc:
- Awb:
+ - BlackLevelCorrection:
- LensShadingCorrection:
x-size: [ 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625 ]
y-size: [ 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625, 0.0625 ]
diff --git a/src/ipa/rkisp1/data/meson.build b/src/ipa/rkisp1/data/meson.build
index 7150e155..1e3522b2 100644
--- a/src/ipa/rkisp1/data/meson.build
+++ b/src/ipa/rkisp1/data/meson.build
@@ -2,8 +2,12 @@
conf_files = files([
'imx219.yaml',
+ 'imx258.yaml',
+ 'ov2685.yaml',
'ov4689.yaml',
'ov5640.yaml',
+ 'ov5695.yaml',
+ 'ov8858.yaml',
'uncalibrated.yaml',
])
diff --git a/src/ipa/rkisp1/data/ov4689.yaml b/src/ipa/rkisp1/data/ov4689.yaml
index 2068684c..60901296 100644
--- a/src/ipa/rkisp1/data/ov4689.yaml
+++ b/src/ipa/rkisp1/data/ov4689.yaml
@@ -6,8 +6,4 @@ algorithms:
- Agc:
- Awb:
- BlackLevelCorrection:
- R: 66
- Gr: 66
- Gb: 66
- B: 66
...
diff --git a/src/ipa/rkisp1/data/ov5640.yaml b/src/ipa/rkisp1/data/ov5640.yaml
index 897b83cb..4b21d412 100644
--- a/src/ipa/rkisp1/data/ov5640.yaml
+++ b/src/ipa/rkisp1/data/ov5640.yaml
@@ -6,10 +6,6 @@ algorithms:
- Agc:
- Awb:
- BlackLevelCorrection:
- R: 256
- Gr: 256
- Gb: 256
- B: 256
- ColorProcessing:
- GammaSensorLinearization:
x-intervals: [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]
diff --git a/src/ipa/rkisp1/data/uncalibrated.yaml b/src/ipa/rkisp1/data/uncalibrated.yaml
index a7bbd8d8..60901296 100644
--- a/src/ipa/rkisp1/data/uncalibrated.yaml
+++ b/src/ipa/rkisp1/data/uncalibrated.yaml
@@ -5,4 +5,5 @@ version: 1
algorithms:
- Agc:
- Awb:
+ - BlackLevelCorrection:
...
diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp
index 9f3f576a..730a55b4 100644
--- a/src/ipa/rkisp1/ipa_context.cpp
+++ b/src/ipa/rkisp1/ipa_context.cpp
@@ -106,6 +106,11 @@ namespace libcamera::ipa::rkisp1 {
*/
/**
+ * \var IPASessionConfiguration::paramFormat
+ * \brief The fourcc of the parameters buffers format
+ */
+
+/**
* \struct IPAActiveState
* \brief Active state for algorithms
*
diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
index 8602b408..3af2774a 100644
--- a/src/ipa/rkisp1/ipa_context.h
+++ b/src/ipa/rkisp1/ipa_context.h
@@ -8,6 +8,8 @@
#pragma once
+#include <memory>
+
#include <linux/rkisp1-config.h>
#include <libcamera/base/utils.h>
@@ -16,6 +18,7 @@
#include <libcamera/controls.h>
#include <libcamera/geometry.h>
+#include <libipa/camera_sensor_helper.h>
#include <libipa/fc_queue.h>
#include <libipa/matrix.h>
@@ -28,6 +31,7 @@ struct IPAHwSettings {
unsigned int numHistogramBins;
unsigned int numHistogramWeights;
unsigned int numGammaOutSamples;
+ bool compand;
};
struct IPASessionConfiguration {
@@ -56,6 +60,7 @@ struct IPASessionConfiguration {
} sensor;
bool raw;
+ uint32_t paramFormat;
};
struct IPAActiveState {
@@ -95,6 +100,10 @@ struct IPAActiveState {
} awb;
struct {
+ Matrix<float, 3, 3> ccm;
+ } ccm;
+
+ struct {
int8_t brightness;
uint8_t contrast;
uint8_t saturation;
@@ -133,7 +142,6 @@ struct IPAFrameContext : public FrameContext {
double blue;
} gains;
- unsigned int temperatureK;
bool autoEnabled;
} awb;
@@ -178,6 +186,9 @@ struct IPAContext {
FCQueue<IPAFrameContext> frameContexts;
ControlInfoMap::Map ctrlMap;
+
+ /* Interface to the Camera Helper */
+ std::unique_ptr<CameraSensorHelper> camHelper;
};
} /* namespace ipa::rkisp1 */
diff --git a/src/ipa/rkisp1/meson.build b/src/ipa/rkisp1/meson.build
index e8b266f1..34844f14 100644
--- a/src/ipa/rkisp1/meson.build
+++ b/src/ipa/rkisp1/meson.build
@@ -7,14 +7,14 @@ ipa_name = 'ipa_rkisp1'
rkisp1_ipa_sources = files([
'ipa_context.cpp',
+ 'params.cpp',
'rkisp1.cpp',
'utils.cpp',
])
rkisp1_ipa_sources += rkisp1_ipa_algorithms
-mod = shared_module(ipa_name,
- [rkisp1_ipa_sources, libcamera_generated_ipa_headers],
+mod = shared_module(ipa_name, rkisp1_ipa_sources,
name_prefix : '',
include_directories : [ipa_includes],
dependencies : [libcamera_private, libipa_dep],
diff --git a/src/ipa/rkisp1/module.h b/src/ipa/rkisp1/module.h
index 16c3e43e..69e9bc82 100644
--- a/src/ipa/rkisp1/module.h
+++ b/src/ipa/rkisp1/module.h
@@ -14,13 +14,14 @@
#include <libipa/module.h>
#include "ipa_context.h"
+#include "params.h"
namespace libcamera {
namespace ipa::rkisp1 {
using Module = ipa::Module<IPAContext, IPAFrameContext, IPACameraSensorInfo,
- rkisp1_params_cfg, rkisp1_stat_buffer>;
+ RkISP1Params, rkisp1_stat_buffer>;
} /* namespace ipa::rkisp1 */
diff --git a/src/ipa/rkisp1/params.cpp b/src/ipa/rkisp1/params.cpp
new file mode 100644
index 00000000..4c0b051c
--- /dev/null
+++ b/src/ipa/rkisp1/params.cpp
@@ -0,0 +1,222 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2024, Ideas On Board
+ *
+ * RkISP1 ISP Parameters
+ */
+
+#include "params.h"
+
+#include <map>
+#include <stddef.h>
+#include <string.h>
+
+#include <linux/rkisp1-config.h>
+#include <linux/videodev2.h>
+
+#include <libcamera/base/log.h>
+#include <libcamera/base/utils.h>
+
+namespace libcamera {
+
+LOG_DEFINE_CATEGORY(RkISP1Params)
+
+namespace ipa::rkisp1 {
+
+namespace {
+
+struct BlockTypeInfo {
+ enum rkisp1_ext_params_block_type type;
+ size_t size;
+ size_t offset;
+ uint32_t enableBit;
+};
+
+#define RKISP1_BLOCK_TYPE_ENTRY(block, id, type, category, bit) \
+ { BlockType::block, { \
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_##id, \
+ sizeof(struct rkisp1_cif_isp_##type##_config), \
+ offsetof(struct rkisp1_params_cfg, category.type##_config), \
+ RKISP1_CIF_ISP_MODULE_##bit, \
+ } }
+
+#define RKISP1_BLOCK_TYPE_ENTRY_MEAS(block, id, type) \
+ RKISP1_BLOCK_TYPE_ENTRY(block, id##_MEAS, type, meas, id)
+
+#define RKISP1_BLOCK_TYPE_ENTRY_OTHERS(block, id, type) \
+ RKISP1_BLOCK_TYPE_ENTRY(block, id, type, others, id)
+
+#define RKISP1_BLOCK_TYPE_ENTRY_EXT(block, id, type) \
+ { BlockType::block, { \
+ RKISP1_EXT_PARAMS_BLOCK_TYPE_##id, \
+ sizeof(struct rkisp1_cif_isp_##type##_config), \
+ 0, 0, \
+ } }
+
+const std::map<BlockType, BlockTypeInfo> kBlockTypeInfo = {
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(Bls, BLS, bls),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(Dpcc, DPCC, dpcc),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(Sdg, SDG, sdg),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(AwbGain, AWB_GAIN, awb_gain),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(Flt, FLT, flt),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(Bdm, BDM, bdm),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(Ctk, CTK, ctk),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(Goc, GOC, goc),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(Dpf, DPF, dpf),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(DpfStrength, DPF_STRENGTH, dpf_strength),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(Cproc, CPROC, cproc),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(Ie, IE, ie),
+ RKISP1_BLOCK_TYPE_ENTRY_OTHERS(Lsc, LSC, lsc),
+ RKISP1_BLOCK_TYPE_ENTRY_MEAS(Awb, AWB, awb_meas),
+ RKISP1_BLOCK_TYPE_ENTRY_MEAS(Hst, HST, hst),
+ RKISP1_BLOCK_TYPE_ENTRY_MEAS(Aec, AEC, aec),
+ RKISP1_BLOCK_TYPE_ENTRY_MEAS(Afc, AFC, afc),
+ RKISP1_BLOCK_TYPE_ENTRY_EXT(CompandBls, COMPAND_BLS, compand_bls),
+ RKISP1_BLOCK_TYPE_ENTRY_EXT(CompandExpand, COMPAND_EXPAND, compand_curve),
+ RKISP1_BLOCK_TYPE_ENTRY_EXT(CompandCompress, COMPAND_COMPRESS, compand_curve),
+};
+
+} /* namespace */
+
+RkISP1ParamsBlockBase::RkISP1ParamsBlockBase(RkISP1Params *params, BlockType type,
+ const Span<uint8_t> &data)
+ : params_(params), type_(type)
+{
+ if (params_->format() == V4L2_META_FMT_RK_ISP1_EXT_PARAMS) {
+ header_ = data.subspan(0, sizeof(rkisp1_ext_params_block_header));
+ data_ = data.subspan(sizeof(rkisp1_ext_params_block_header));
+ } else {
+ data_ = data;
+ }
+}
+
+void RkISP1ParamsBlockBase::setEnabled(bool enabled)
+{
+ /*
+ * For the legacy fixed format, blocks are enabled in the top-level
+ * header. Delegate to the RkISP1Params class.
+ */
+ if (params_->format() == V4L2_META_FMT_RK_ISP1_PARAMS)
+ return params_->setBlockEnabled(type_, enabled);
+
+ /*
+ * For the extensible format, set the enable and disable flags in the
+ * block header directly.
+ */
+ struct rkisp1_ext_params_block_header *header =
+ reinterpret_cast<struct rkisp1_ext_params_block_header *>(header_.data());
+ header->flags &= ~(RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE |
+ RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE);
+ header->flags |= enabled ? RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE
+ : RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE;
+}
+
+RkISP1Params::RkISP1Params(uint32_t format, Span<uint8_t> data)
+ : format_(format), data_(data), used_(0)
+{
+ if (format_ == V4L2_META_FMT_RK_ISP1_EXT_PARAMS) {
+ struct rkisp1_ext_params_cfg *cfg =
+ reinterpret_cast<struct rkisp1_ext_params_cfg *>(data.data());
+
+ cfg->version = RKISP1_EXT_PARAM_BUFFER_V1;
+ cfg->data_size = 0;
+
+ used_ += offsetof(struct rkisp1_ext_params_cfg, data);
+ } else {
+ memset(data.data(), 0, data.size());
+ used_ = sizeof(struct rkisp1_params_cfg);
+ }
+}
+
+void RkISP1Params::setBlockEnabled(BlockType type, bool enabled)
+{
+ const BlockTypeInfo &info = kBlockTypeInfo.at(type);
+
+ struct rkisp1_params_cfg *cfg =
+ reinterpret_cast<struct rkisp1_params_cfg *>(data_.data());
+ if (enabled)
+ cfg->module_ens |= info.enableBit;
+ else
+ cfg->module_ens &= ~info.enableBit;
+}
+
+Span<uint8_t> RkISP1Params::block(BlockType type)
+{
+ auto infoIt = kBlockTypeInfo.find(type);
+ if (infoIt == kBlockTypeInfo.end()) {
+ LOG(RkISP1Params, Error)
+ << "Invalid parameters block type "
+ << utils::to_underlying(type);
+ return {};
+ }
+
+ const BlockTypeInfo &info = infoIt->second;
+
+ /*
+ * For the legacy format, return a block referencing the fixed location
+ * of the data.
+ */
+ if (format_ == V4L2_META_FMT_RK_ISP1_PARAMS) {
+ /*
+ * Blocks available only in extended parameters have an offset
+ * of 0. Return nullptr in that case.
+ */
+ if (info.offset == 0) {
+ LOG(RkISP1Params, Error)
+ << "Block type " << utils::to_underlying(type)
+ << " unavailable in fixed parameters format";
+ return {};
+ }
+
+ struct rkisp1_params_cfg *cfg =
+ reinterpret_cast<struct rkisp1_params_cfg *>(data_.data());
+
+ cfg->module_cfg_update |= info.enableBit;
+ cfg->module_en_update |= info.enableBit;
+
+ return data_.subspan(info.offset, info.size);
+ }
+
+ /*
+ * For the extensible format, allocate memory for the block, including
+ * the header. Look up the block in the cache first. If an algorithm
+ * requests the same block type twice, it should get the same block.
+ */
+ auto cacheIt = blocks_.find(type);
+ if (cacheIt != blocks_.end())
+ return cacheIt->second;
+
+ /* Make sure we don't run out of space. */
+ size_t size = sizeof(struct rkisp1_ext_params_block_header)
+ + ((info.size + 7) & ~7);
+ if (size > data_.size() - used_) {
+ LOG(RkISP1Params, Error)
+ << "Out of memory to allocate block type "
+ << utils::to_underlying(type);
+ return {};
+ }
+
+ /* Allocate a new block, clear its memory, and initialize its header. */
+ Span<uint8_t> block = data_.subspan(used_, size);
+ used_ += size;
+
+ struct rkisp1_ext_params_cfg *cfg =
+ reinterpret_cast<struct rkisp1_ext_params_cfg *>(data_.data());
+ cfg->data_size += size;
+
+ memset(block.data(), 0, block.size());
+
+ struct rkisp1_ext_params_block_header *header =
+ reinterpret_cast<struct rkisp1_ext_params_block_header *>(block.data());
+ header->type = info.type;
+ header->size = block.size();
+
+ /* Update the cache. */
+ blocks_[type] = block;
+
+ return block;
+}
+
+} /* namespace ipa::rkisp1 */
+
+} /* namespace libcamera */
diff --git a/src/ipa/rkisp1/params.h b/src/ipa/rkisp1/params.h
new file mode 100644
index 00000000..40450e34
--- /dev/null
+++ b/src/ipa/rkisp1/params.h
@@ -0,0 +1,163 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2024, Ideas On Board
+ *
+ * RkISP1 ISP Parameters
+ */
+
+#pragma once
+
+#include <map>
+#include <stdint.h>
+
+#include <linux/rkisp1-config.h>
+
+#include <libcamera/base/class.h>
+#include <libcamera/base/span.h>
+
+namespace libcamera {
+
+namespace ipa::rkisp1 {
+
+enum class BlockType {
+ Bls,
+ Dpcc,
+ Sdg,
+ AwbGain,
+ Flt,
+ Bdm,
+ Ctk,
+ Goc,
+ Dpf,
+ DpfStrength,
+ Cproc,
+ Ie,
+ Lsc,
+ Awb,
+ Hst,
+ Aec,
+ Afc,
+ CompandBls,
+ CompandExpand,
+ CompandCompress,
+};
+
+namespace details {
+
+template<BlockType B>
+struct block_type {
+};
+
+#define RKISP1_DEFINE_BLOCK_TYPE(blockType, blockStruct) \
+template<> \
+struct block_type<BlockType::blockType> { \
+ using type = struct rkisp1_cif_isp_##blockStruct##_config; \
+};
+
+RKISP1_DEFINE_BLOCK_TYPE(Bls, bls)
+RKISP1_DEFINE_BLOCK_TYPE(Dpcc, dpcc)
+RKISP1_DEFINE_BLOCK_TYPE(Sdg, sdg)
+RKISP1_DEFINE_BLOCK_TYPE(AwbGain, awb_gain)
+RKISP1_DEFINE_BLOCK_TYPE(Flt, flt)
+RKISP1_DEFINE_BLOCK_TYPE(Bdm, bdm)
+RKISP1_DEFINE_BLOCK_TYPE(Ctk, ctk)
+RKISP1_DEFINE_BLOCK_TYPE(Goc, goc)
+RKISP1_DEFINE_BLOCK_TYPE(Dpf, dpf)
+RKISP1_DEFINE_BLOCK_TYPE(DpfStrength, dpf_strength)
+RKISP1_DEFINE_BLOCK_TYPE(Cproc, cproc)
+RKISP1_DEFINE_BLOCK_TYPE(Ie, ie)
+RKISP1_DEFINE_BLOCK_TYPE(Lsc, lsc)
+RKISP1_DEFINE_BLOCK_TYPE(Awb, awb_meas)
+RKISP1_DEFINE_BLOCK_TYPE(Hst, hst)
+RKISP1_DEFINE_BLOCK_TYPE(Aec, aec)
+RKISP1_DEFINE_BLOCK_TYPE(Afc, afc)
+RKISP1_DEFINE_BLOCK_TYPE(CompandBls, compand_bls)
+RKISP1_DEFINE_BLOCK_TYPE(CompandExpand, compand_curve)
+RKISP1_DEFINE_BLOCK_TYPE(CompandCompress, compand_curve)
+
+} /* namespace details */
+
+class RkISP1Params;
+
+class RkISP1ParamsBlockBase
+{
+public:
+ RkISP1ParamsBlockBase(RkISP1Params *params, BlockType type,
+ const Span<uint8_t> &data);
+
+ Span<uint8_t> data() const { return data_; }
+
+ void setEnabled(bool enabled);
+
+private:
+ LIBCAMERA_DISABLE_COPY(RkISP1ParamsBlockBase)
+
+ RkISP1Params *params_;
+ BlockType type_;
+ Span<uint8_t> header_;
+ Span<uint8_t> data_;
+};
+
+template<BlockType B>
+class RkISP1ParamsBlock : public RkISP1ParamsBlockBase
+{
+public:
+ using Type = typename details::block_type<B>::type;
+
+ RkISP1ParamsBlock(RkISP1Params *params, const Span<uint8_t> &data)
+ : RkISP1ParamsBlockBase(params, B, data)
+ {
+ }
+
+ const Type *operator->() const
+ {
+ return reinterpret_cast<const Type *>(data().data());
+ }
+
+ Type *operator->()
+ {
+ return reinterpret_cast<Type *>(data().data());
+ }
+
+ const Type &operator*() const &
+ {
+ return *reinterpret_cast<const Type *>(data().data());
+ }
+
+ Type &operator*() &
+ {
+ return *reinterpret_cast<Type *>(data().data());
+ }
+};
+
+class RkISP1Params
+{
+public:
+ RkISP1Params(uint32_t format, Span<uint8_t> data);
+
+ template<BlockType B>
+ RkISP1ParamsBlock<B> block()
+ {
+ return RkISP1ParamsBlock<B>(this, block(B));
+ }
+
+ uint32_t format() const { return format_; }
+ size_t size() const { return used_; }
+
+private:
+ friend class RkISP1ParamsBlockBase;
+
+ Span<uint8_t> block(BlockType type);
+ void setBlockEnabled(BlockType type, bool enabled);
+
+ uint32_t format_;
+
+ Span<uint8_t> data_;
+ size_t used_;
+
+ std::map<BlockType, Span<uint8_t>> blocks_;
+};
+
+} /* namespace ipa::rkisp1 */
+
+} /* namespace libcamera*/
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index d31cdbab..78d2c375 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -6,8 +6,8 @@
*/
#include <algorithm>
-#include <math.h>
-#include <queue>
+#include <array>
+#include <chrono>
#include <stdint.h>
#include <string.h>
@@ -18,20 +18,22 @@
#include <libcamera/base/log.h>
#include <libcamera/control_ids.h>
+#include <libcamera/controls.h>
#include <libcamera/framebuffer.h>
+#include <libcamera/request.h>
+
#include <libcamera/ipa/ipa_interface.h>
#include <libcamera/ipa/ipa_module_info.h>
#include <libcamera/ipa/rkisp1_ipa_interface.h>
-#include <libcamera/request.h>
#include "libcamera/internal/formats.h"
#include "libcamera/internal/mapped_framebuffer.h"
#include "libcamera/internal/yaml_parser.h"
#include "algorithms/algorithm.h"
-#include "libipa/camera_sensor_helper.h"
#include "ipa_context.h"
+#include "params.h"
namespace libcamera {
@@ -81,9 +83,6 @@ private:
ControlInfoMap sensorControls_;
- /* Interface to the Camera Helper */
- std::unique_ptr<CameraSensorHelper> camHelper_;
-
/* Local parameter storage */
struct IPAContext context_;
};
@@ -95,6 +94,15 @@ const IPAHwSettings ipaHwSettingsV10{
RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10,
RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10,
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10,
+ false,
+};
+
+const IPAHwSettings ipaHwSettingsIMX8MP{
+ RKISP1_CIF_ISP_AE_MEAN_MAX_V10,
+ RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10,
+ RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10,
+ RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10,
+ true,
};
const IPAHwSettings ipaHwSettingsV12{
@@ -102,6 +110,7 @@ const IPAHwSettings ipaHwSettingsV12{
RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12,
RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12,
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12,
+ false,
};
/* List of controls handled by the RkISP1 IPA */
@@ -115,7 +124,7 @@ const ControlInfoMap::Map rkisp1Controls{
} /* namespace */
IPARkISP1::IPARkISP1()
- : context_({ {}, {}, {}, { kMaxFrameContexts }, {} })
+ : context_({ {}, {}, {}, { kMaxFrameContexts }, {}, {} })
{
}
@@ -132,9 +141,11 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
/* \todo Add support for other revisions */
switch (hwRevision) {
case RKISP1_V10:
- case RKISP1_V_IMX8MP:
context_.hw = &ipaHwSettingsV10;
break;
+ case RKISP1_V_IMX8MP:
+ context_.hw = &ipaHwSettingsIMX8MP;
+ break;
case RKISP1_V12:
context_.hw = &ipaHwSettingsV12;
break;
@@ -147,16 +158,16 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
LOG(IPARkISP1, Debug) << "Hardware revision is " << hwRevision;
- camHelper_ = CameraSensorHelperFactoryBase::create(settings.sensorModel);
- if (!camHelper_) {
+ context_.camHelper = CameraSensorHelperFactoryBase::create(settings.sensorModel);
+ if (!context_.camHelper) {
LOG(IPARkISP1, Error)
<< "Failed to create camera sensor helper for "
<< settings.sensorModel;
return -ENODEV;
}
- context_.configuration.sensor.lineDuration = sensorInfo.minLineLength
- * 1.0s / sensorInfo.pixelRate;
+ context_.configuration.sensor.lineDuration =
+ sensorInfo.minLineLength * 1.0s / sensorInfo.pixelRate;
/* Load the tuning data file. */
File file(settings.configurationFile);
@@ -230,6 +241,8 @@ int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
context_.activeState = {};
context_.frameContexts.clear();
+ context_.configuration.paramFormat = ipaConfig.paramFormat;
+
const IPACameraSensorInfo &info = ipaConfig.sensorInfo;
const ControlInfo vBlank = sensorControls_.find(V4L2_CID_VBLANK)->second;
context_.configuration.sensor.defVBlank = vBlank.def().get<int32_t>();
@@ -250,8 +263,10 @@ int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
minExposure * context_.configuration.sensor.lineDuration;
context_.configuration.sensor.maxShutterSpeed =
maxExposure * context_.configuration.sensor.lineDuration;
- context_.configuration.sensor.minAnalogueGain = camHelper_->gain(minGain);
- context_.configuration.sensor.maxAnalogueGain = camHelper_->gain(maxGain);
+ context_.configuration.sensor.minAnalogueGain =
+ context_.camHelper->gain(minGain);
+ context_.configuration.sensor.maxAnalogueGain =
+ context_.camHelper->gain(maxGain);
context_.configuration.raw = std::any_of(streamConfig.begin(), streamConfig.end(),
[](auto &cfg) -> bool {
@@ -322,17 +337,13 @@ void IPARkISP1::fillParamsBuffer(const uint32_t frame, const uint32_t bufferId)
{
IPAFrameContext &frameContext = context_.frameContexts.get(frame);
- rkisp1_params_cfg *params =
- reinterpret_cast<rkisp1_params_cfg *>(
- mappedBuffers_.at(bufferId).planes()[0].data());
-
- /* Prepare parameters buffer. */
- memset(params, 0, sizeof(*params));
+ RkISP1Params params(context_.configuration.paramFormat,
+ mappedBuffers_.at(bufferId).planes()[0]);
for (auto const &algo : algorithms())
- algo->prepare(context_, frame, frameContext, params);
+ algo->prepare(context_, frame, frameContext, &params);
- paramsBufferReady.emit(frame);
+ paramsBufferReady.emit(frame, params.size());
}
void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId,
@@ -352,7 +363,7 @@ void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId
frameContext.sensor.exposure =
sensorControls.get(V4L2_CID_EXPOSURE).get<int32_t>();
frameContext.sensor.gain =
- camHelper_->gain(sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>());
+ context_.camHelper->gain(sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>());
ControlList metadata(controls::controls);
@@ -389,9 +400,9 @@ void IPARkISP1::updateControls(const IPACameraSensorInfo &sensorInfo,
/* Compute the analogue gain limits. */
const ControlInfo &v4l2Gain = sensorControls.find(V4L2_CID_ANALOGUE_GAIN)->second;
- float minGain = camHelper_->gain(v4l2Gain.min().get<int32_t>());
- float maxGain = camHelper_->gain(v4l2Gain.max().get<int32_t>());
- float defGain = camHelper_->gain(v4l2Gain.def().get<int32_t>());
+ float minGain = context_.camHelper->gain(v4l2Gain.min().get<int32_t>());
+ float maxGain = context_.camHelper->gain(v4l2Gain.max().get<int32_t>());
+ float defGain = context_.camHelper->gain(v4l2Gain.def().get<int32_t>());
ctrlMap.emplace(std::piecewise_construct,
std::forward_as_tuple(&controls::AnalogueGain),
std::forward_as_tuple(minGain, maxGain, defGain));
@@ -436,7 +447,7 @@ void IPARkISP1::setControls(unsigned int frame)
IPAFrameContext &frameContext = context_.frameContexts.get(frame);
uint32_t exposure = frameContext.agc.exposure;
- uint32_t gain = camHelper_->gainCode(frameContext.agc.gain);
+ uint32_t gain = context_.camHelper->gainCode(frameContext.agc.gain);
ControlList ctrls(sensorControls_);
ctrls.set(V4L2_CID_EXPOSURE, static_cast<int32_t>(exposure));
diff --git a/src/ipa/rkisp1/utils.h b/src/ipa/rkisp1/utils.h
index 450f2244..5f38b50b 100644
--- a/src/ipa/rkisp1/utils.h
+++ b/src/ipa/rkisp1/utils.h
@@ -8,7 +8,6 @@
#pragma once
#include <cmath>
-#include <limits>
#include <type_traits>
namespace libcamera {
diff --git a/src/ipa/rpi/controller/rpi/alsc.cpp b/src/ipa/rpi/controller/rpi/alsc.cpp
index 67029fc3..161fd455 100644
--- a/src/ipa/rpi/controller/rpi/alsc.cpp
+++ b/src/ipa/rpi/controller/rpi/alsc.cpp
@@ -9,6 +9,7 @@
#include <functional>
#include <math.h>
#include <numeric>
+#include <vector>
#include <libcamera/base/log.h>
#include <libcamera/base/span.h>
@@ -496,8 +497,9 @@ void resampleCalTable(const Array2D<double> &calTableIn,
* Precalculate and cache the x sampling locations and phases to save
* recomputing them on every row.
*/
- int xLo[X], xHi[X];
- double xf[X];
+ std::vector<int> xLo(X);
+ std::vector<int> xHi(X);
+ std::vector<double> xf(X);
double scaleX = cameraMode.sensorWidth /
(cameraMode.width * cameraMode.scaleX);
double xOff = cameraMode.cropX / (double)cameraMode.sensorWidth;
diff --git a/src/ipa/rpi/vc4/meson.build b/src/ipa/rpi/vc4/meson.build
index 63fc5925..c10fa17e 100644
--- a/src/ipa/rpi/vc4/meson.build
+++ b/src/ipa/rpi/vc4/meson.build
@@ -23,8 +23,7 @@ vc4_ipa_sources = files([
vc4_ipa_includes += include_directories('..')
-mod = shared_module(ipa_name,
- [vc4_ipa_sources, libcamera_generated_ipa_headers],
+mod = shared_module(ipa_name, vc4_ipa_sources,
name_prefix : '',
include_directories : vc4_ipa_includes,
dependencies : [vc4_ipa_deps, libipa_dep],
diff --git a/src/ipa/simple/meson.build b/src/ipa/simple/meson.build
index 33d1c96a..b297e1d2 100644
--- a/src/ipa/simple/meson.build
+++ b/src/ipa/simple/meson.build
@@ -7,8 +7,7 @@ soft_simple_sources = files([
'black_level.cpp',
])
-mod = shared_module(ipa_name,
- [soft_simple_sources, libcamera_generated_ipa_headers],
+mod = shared_module(ipa_name, soft_simple_sources,
name_prefix : '',
include_directories : [ipa_includes],
dependencies : [libcamera_private, libipa_dep],
diff --git a/src/ipa/vimc/meson.build b/src/ipa/vimc/meson.build
index d0b63edd..2cc5f80b 100644
--- a/src/ipa/vimc/meson.build
+++ b/src/ipa/vimc/meson.build
@@ -2,8 +2,7 @@
ipa_name = 'ipa_vimc'
-mod = shared_module(ipa_name,
- ['vimc.cpp', libcamera_generated_ipa_headers],
+mod = shared_module(ipa_name, 'vimc.cpp',
name_prefix : '',
include_directories : [ipa_includes],
dependencies : [libcamera_private, libipa_dep],
diff --git a/src/ipa/vimc/vimc.cpp b/src/ipa/vimc/vimc.cpp
index ebd63fa6..5495401f 100644
--- a/src/ipa/vimc/vimc.cpp
+++ b/src/ipa/vimc/vimc.cpp
@@ -14,6 +14,7 @@
#include <iostream>
#include <libcamera/base/file.h>
+#include <libcamera/base/flags.h>
#include <libcamera/base/log.h>
#include <libcamera/ipa/ipa_interface.h>