@@ -10,6 +10,8 @@
#include <cmath>
#include <string.h>
+#include <libcamera/base/span.h>
+
/**
* \file tone_mapping.h
*/
@@ -27,10 +29,17 @@ namespace ipa::ipu3::algorithms {
*/
ToneMapping::ToneMapping()
- : gamma_(1.0)
{
}
+/**
+ * \copydoc libcamera::ipa::Algorithm::init
+ */
+int ToneMapping::init(IPAContext &context, const ValueNode &tuningData)
+{
+ return gammaAlgo_.init(context.ctrlMap, tuningData);
+}
+
/**
* \brief Configure the tone mapping given a configInfo
* \param[in] context The shared IPA context
@@ -41,12 +50,21 @@ ToneMapping::ToneMapping()
int ToneMapping::configure(IPAContext &context,
[[maybe_unused]] const IPAConfigInfo &configInfo)
{
- /* Initialise tone mapping gamma value. */
- context.activeState.toneMapping.gamma = 0.0;
-
+ gammaAlgo_.configure(context.activeState.gamma);
return 0;
}
+/**
+ * \copydoc libcamera::ipa::Algorithm::queueRequest
+ */
+void ToneMapping::queueRequest(IPAContext &context, const uint32_t frame,
+ IPAFrameContext &frameContext,
+ const ControlList &controls)
+{
+ gammaAlgo_.queueRequest(context.activeState.gamma, frame,
+ frameContext.gamma, controls);
+}
+
/**
* \brief Fill in the parameter structure, and enable gamma control
* \param[in] context The shared IPA context
@@ -59,14 +77,21 @@ int ToneMapping::configure(IPAContext &context,
*/
void ToneMapping::prepare([[maybe_unused]] IPAContext &context,
[[maybe_unused]] const uint32_t frame,
- [[maybe_unused]] IPAFrameContext &frameContext,
+ IPAFrameContext &frameContext,
ipu3_uapi_params *params)
{
- /* Copy the calculated LUT into the parameters buffer. */
- memcpy(params->acc_param.gamma.gc_lut.lut,
- context.activeState.toneMapping.gammaCorrection.lut,
- IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES *
- sizeof(params->acc_param.gamma.gc_lut.lut[0]));
+ if (!frameContext.gamma.update)
+ return;
+
+ /*
+ * Unfortunately necessary given the IPU3's gamma uAPI struct has the
+ * __packed attribute.
+ */
+ uint16_t *lutData = reinterpret_cast<uint16_t *>(
+ __builtin_assume_aligned(params->acc_param.gamma.gc_lut.lut, 16));
+ Span<uint16_t> lut {lutData, kNumLutNodes};
+
+ gammaAlgo_.prepare(frameContext.gamma, lut);
/* Enable the custom gamma table. */
params->use.acc_gamma = 1;
@@ -84,33 +109,13 @@ void ToneMapping::prepare([[maybe_unused]] IPAContext &context,
* The tone mapping look up table is generated as an inverse power curve from
* our gamma setting.
*/
-void ToneMapping::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
- [[maybe_unused]] IPAFrameContext &frameContext,
+void ToneMapping::process([[maybe_unused]] IPAContext &context,
+ [[maybe_unused]] const uint32_t frame,
+ IPAFrameContext &frameContext,
[[maybe_unused]] const ipu3_uapi_stats_3a *stats,
[[maybe_unused]] ControlList &metadata)
{
- /*
- * Hardcode gamma to 1.1 as a default for now.
- *
- * \todo Expose gamma control setting through the libcamera control API
- */
- gamma_ = 1.1;
-
- if (context.activeState.toneMapping.gamma == gamma_)
- return;
-
- struct ipu3_uapi_gamma_corr_lut &lut =
- context.activeState.toneMapping.gammaCorrection;
-
- for (uint32_t i = 0; i < std::size(lut.lut); i++) {
- double j = static_cast<double>(i) / (std::size(lut.lut) - 1);
- double gamma = std::pow(j, 1.0 / gamma_);
-
- /* The output value is expressed on 13 bits. */
- lut.lut[i] = gamma * 8191;
- }
-
- context.activeState.toneMapping.gamma = gamma_;
+ gammaAlgo_.process(frameContext.gamma, metadata);
}
REGISTER_IPA_ALGORITHM(ToneMapping, "ToneMapping")
@@ -7,6 +7,8 @@
#pragma once
+#include <libipa/gamma.h>
+
#include "algorithm.h"
namespace libcamera {
@@ -18,7 +20,11 @@ class ToneMapping : public Algorithm
public:
ToneMapping();
+ int init(IPAContext &context, const ValueNode &tuningData) override;
int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
+ void queueRequest(IPAContext &context, const uint32_t frame,
+ IPAFrameContext &frameContext,
+ const ControlList &controls) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext, ipu3_uapi_params *params) override;
void process(IPAContext &context, const uint32_t frame,
@@ -27,7 +33,8 @@ public:
ControlList &metadata) override;
private:
- double gamma_;
+ static constexpr unsigned int kNumLutNodes = IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES;
+ GammaAlgorithm<kNumLutNodes, UQ<0, 13>> gammaAlgo_;
};
} /* namespace ipa::ipu3::algorithms */
@@ -119,6 +119,11 @@ namespace libcamera::ipa::ipu3 {
* \brief Active colour Correction Matrix parameters for the IPA
*/
+/**
+ * \var IPAActiveState::gamma
+ * \brief Active gamma correction parameters for the IPA
+ */
+
/**
* \var IPASessionConfiguration::sensor
* \brief Sensor-specific configuration of the IPA
@@ -154,20 +159,6 @@ namespace libcamera::ipa::ipu3 {
* The gain should be adapted to the sensor specific gain code before applying.
*/
-/**
- * \var IPAActiveState::toneMapping
- * \brief Context for ToneMapping and Gamma control
- *
- * \var IPAActiveState::toneMapping.gamma
- * \brief Gamma value for the LUT
- *
- * \var IPAActiveState::toneMapping.gammaCorrection
- * \brief Per-pixel tone mapping implemented as a LUT
- *
- * The LUT structure is defined by the IPU3 kernel interface. See
- * <linux/intel-ipu3.h> struct ipu3_uapi_gamma_corr_lut for further details.
- */
-
/**
* \struct IPAFrameContext
* \brief IPU3-specific FrameContext
@@ -192,4 +183,9 @@ namespace libcamera::ipa::ipu3 {
* \brief Per-frame colour Correction Matrix parameters for the IPA
*/
+/**
+ * \var IPAFrameContext::gamma
+ * \brief Per-frame gamma correction parameters for the IPA
+ */
+
} /* namespace libcamera::ipa::ipu3 */
@@ -18,6 +18,7 @@
#include <libipa/awb.h>
#include <libipa/ccm.h>
#include <libipa/fc_queue.h>
+#include <libipa/gamma.h>
namespace libcamera {
@@ -66,11 +67,7 @@ struct IPAActiveState {
ipa::awb::ActiveState awb;
ipa::ccm::ActiveState ccm;
-
- struct {
- double gamma;
- struct ipu3_uapi_gamma_corr_lut gammaCorrection;
- } toneMapping;
+ ipa::gamma::ActiveState gamma;
};
struct IPAFrameContext : public FrameContext {
@@ -81,6 +78,7 @@ struct IPAFrameContext : public FrameContext {
ipa::awb::FrameContext awb;
ipa::ccm::FrameContext ccm;
+ ipa::gamma::FrameContext gamma;
};
struct IPAContext {
Convert the IPU3 ToneMapping algorithm to use the new GammaAlgorithm base class. This gives us configurable gamma via the tuning files and at runtime using the Gamma control. Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> --- src/ipa/ipu3/algorithms/tone_mapping.cpp | 73 +++++++++++++++++--------------- src/ipa/ipu3/algorithms/tone_mapping.h | 9 +++- src/ipa/ipu3/ipa_context.cpp | 24 +++++------ src/ipa/ipu3/ipa_context.h | 8 ++-- 4 files changed, 60 insertions(+), 54 deletions(-)