summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo.mondi@ideasonboard.com>2024-05-31 12:20:34 +0200
committerJacopo Mondi <jacopo.mondi@ideasonboard.com>2024-06-20 18:22:17 +0200
commit4acc8e35cff7548eba9fb1e4be4052d5340a9254 (patch)
tree91a9ca3ee7c882b710c4bbc2bbb0d1db22709ddb
parente689b2f0c9fef525364ba518054297558086a051 (diff)
ipa: rkisp1: Use the extensible parameters formatimx8mp/extensible-format
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
-rw-r--r--src/ipa/rkisp1/algorithms/agc.cpp73
-rw-r--r--src/ipa/rkisp1/algorithms/agc.h7
-rw-r--r--src/ipa/rkisp1/algorithms/awb.cpp116
-rw-r--r--src/ipa/rkisp1/algorithms/awb.h6
-rw-r--r--src/ipa/rkisp1/algorithms/blc.cpp21
-rw-r--r--src/ipa/rkisp1/algorithms/blc.h2
-rw-r--r--src/ipa/rkisp1/algorithms/cproc.cpp17
-rw-r--r--src/ipa/rkisp1/algorithms/cproc.h2
-rw-r--r--src/ipa/rkisp1/algorithms/dpcc.cpp13
-rw-r--r--src/ipa/rkisp1/algorithms/dpcc.h2
-rw-r--r--src/ipa/rkisp1/algorithms/dpf.cpp98
-rw-r--r--src/ipa/rkisp1/algorithms/dpf.h4
-rw-r--r--src/ipa/rkisp1/algorithms/filter.cpp15
-rw-r--r--src/ipa/rkisp1/algorithms/filter.h2
-rw-r--r--src/ipa/rkisp1/algorithms/gsl.cpp25
-rw-r--r--src/ipa/rkisp1/algorithms/gsl.h2
-rw-r--r--src/ipa/rkisp1/algorithms/lsc.cpp39
-rw-r--r--src/ipa/rkisp1/algorithms/lsc.h4
-rw-r--r--src/ipa/rkisp1/module.h2
-rw-r--r--src/ipa/rkisp1/rkisp1.cpp34
-rw-r--r--src/libcamera/pipeline/rkisp1/rkisp1.cpp2
21 files changed, 302 insertions, 184 deletions
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index 50e0690f..e2e47453 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -149,11 +149,49 @@ void Agc::queueRequest(IPAContext &context,
}
}
+void Agc::prepareAecMeas(IPAContext &context,
+ rkisp1_ext_params_aec_config *aec)
+{
+ aec->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS;
+ aec->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
+ aec->header.size = sizeof(rkisp1_ext_params_aec_config);
+
+ /* Configure the measurement window. */
+ aec->aec_config.meas_window = context.configuration.agc.measureWindow;
+ /* Use a continuous method for measure. */
+ aec->aec_config.autostop = RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0;
+ /* Estimate Y as (R + G + B) x (85/256). */
+ aec->aec_config.mode = RKISP1_CIF_ISP_EXP_MEASURING_MODE_1;
+}
+
+void Agc::prepareHistMeas(IPAContext &context,
+ rkisp1_ext_params_hst_config *hst)
+{
+ hst->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS;
+ hst->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
+ hst->header.size = sizeof(rkisp1_ext_params_hst_config);
+
+ hst->hst_config.meas_window = context.configuration.agc.measureWindow;
+
+ /* Produce the luminance histogram. */
+ hst->hst_config.mode = RKISP1_CIF_ISP_HISTOGRAM_MODE_Y_HISTOGRAM;
+
+ /* Set an average weighted histogram. */
+ Span<uint8_t> weights{
+ hst->hst_config.hist_weight,
+ context.hw->numHistogramWeights
+ };
+ std::fill(weights.begin(), weights.end(), 1);
+
+ /* Step size can't be less than 3. */
+ hst->hst_config.histogram_predivider = 4;
+}
+
/**
* \copydoc libcamera::ipa::Algorithm::prepare
*/
void Agc::prepare(IPAContext &context, const uint32_t frame,
- IPAFrameContext &frameContext, rkisp1_params_cfg *params)
+ IPAFrameContext &frameContext, rkisp1_ext_params_block_header *hdr)
{
if (frameContext.agc.autoEnabled) {
frameContext.agc.exposure = context.activeState.agc.automatic.exposure;
@@ -163,35 +201,18 @@ void Agc::prepare(IPAContext &context, const uint32_t frame,
if (frame > 0)
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;
+ struct rkisp1_ext_params_aec_config *aec =
+ reinterpret_cast<rkisp1_ext_params_aec_config *>(hdr);
- 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;
+ prepareAecMeas(context, aec);
/* 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;
- /* Set an average weighted histogram. */
- Span<uint8_t> weights{
- params->meas.hst_config.hist_weight,
- context.hw->numHistogramWeights
- };
- std::fill(weights.begin(), weights.end(), 1);
- /* Step size can't be less than 3. */
- params->meas.hst_config.histogram_predivider = 4;
+ char *hst_hdr = reinterpret_cast<char *>(hdr);
+ struct rkisp1_ext_params_hst_config *hst =
+ reinterpret_cast<rkisp1_ext_params_hst_config *>
+ (hst_hdr + sizeof(rkisp1_ext_params_aec_config));
- /* 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;
+ prepareHistMeas(context, hst);
}
void Agc::fillMetadata(IPAContext &context, IPAFrameContext &frameContext,
diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h
index 04b3247e..7e994206 100644
--- a/src/ipa/rkisp1/algorithms/agc.h
+++ b/src/ipa/rkisp1/algorithms/agc.h
@@ -37,7 +37,7 @@ public:
const ControlList &controls) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ rkisp1_ext_params_block_header *hdr) override;
void process(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
const rkisp1_stat_buffer *stats,
@@ -48,6 +48,11 @@ private:
ControlList &metadata);
double estimateLuminance(double gain) const override;
+ void prepareAecMeas(IPAContext &context,
+ rkisp1_ext_params_aec_config *aec);
+ void prepareHistMeas(IPAContext &context,
+ rkisp1_ext_params_hst_config *hst);
+
Span<const uint8_t> expMeans_;
};
diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp
index a01fe5d9..b6ca27ba 100644
--- a/src/ipa/rkisp1/algorithms/awb.cpp
+++ b/src/ipa/rkisp1/algorithms/awb.cpp
@@ -104,45 +104,34 @@ 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)
+void Awb::prepareAwbGains(IPAFrameContext &frameContext,
+ rkisp1_ext_params_awb_gain_config *awbg)
{
- /*
- * This is the latest time we can read the active state. This is the
- * most up-to-date automatic values we can read.
- */
- if (frameContext.awb.autoEnabled) {
- frameContext.awb.gains.red = context.activeState.awb.gains.automatic.red;
- frameContext.awb.gains.green = context.activeState.awb.gains.automatic.green;
- 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;
-
- /* Update the gains. */
- params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
-
- /* If we have already set the AWB measurement parameters, return. */
- if (frame > 0)
- return;
+ awbg->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAINS;
+ awbg->header.size = sizeof(rkisp1_ext_params_awb_gain_config);
+ awbg->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
+
+ awbg->awb_config.gain_green_b = 256 * frameContext.awb.gains.green;
+ awbg->awb_config.gain_blue = 256 * frameContext.awb.gains.blue;
+ awbg->awb_config.gain_red = 256 * frameContext.awb.gains.red;
+ awbg->awb_config.gain_green_r = 256 * frameContext.awb.gains.green;
+}
- rkisp1_cif_isp_awb_meas_config &awb_config = params->meas.awb_meas_config;
+void Awb::prepareAwbMeas(IPAContext &context,
+ rkisp1_ext_params_awb_meas_config *awbm)
+{
+ awbm->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS;
+ awbm->header.size = sizeof(rkisp1_ext_params_awb_meas_config);
+ awbm->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
- /* Configure the measure window for AWB. */
- awb_config.awb_wnd = context.configuration.awb.measureWindow;
+ awbm->awb_meas_config.awb_wnd = context.configuration.awb.measureWindow;
/* Number of frames to use to estimate the means (0 means 1 frame). */
- awb_config.frames = 0;
+ awbm->awb_meas_config.frames = 0;
/* Select RGB or YCbCr means measurement. */
if (rgbMode_) {
- awb_config.awb_mode = RKISP1_CIF_ISP_AWB_MODE_RGB;
+ awbm->awb_meas_config.awb_mode = RKISP1_CIF_ISP_AWB_MODE_RGB;
/*
* For RGB-based measurements, pixels are selected with maximum
@@ -150,19 +139,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;
+ awbm->awb_meas_config.awb_ref_cr = 250;
+ awbm->awb_meas_config.min_y = 250;
+ awbm->awb_meas_config.awb_ref_cb = 250;
- awb_config.max_y = 0;
- awb_config.min_c = 0;
- awb_config.max_csum = 0;
+ awbm->awb_meas_config.max_y = 0;
+ awbm->awb_meas_config.min_c = 0;
+ awbm->awb_meas_config.max_csum = 0;
} else {
- awb_config.awb_mode = RKISP1_CIF_ISP_AWB_MODE_YCBCR;
+ awbm->awb_meas_config.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;
+ awbm->awb_meas_config.awb_ref_cb = 128;
+ awbm->awb_meas_config.awb_ref_cr = 128;
/*
* Filter out pixels based on luminance and chrominance values.
@@ -170,20 +159,45 @@ 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;
+ awbm->awb_meas_config.min_y = 16;
+ awbm->awb_meas_config.max_y = 250;
+ awbm->awb_meas_config.min_c = 16;
+ awbm->awb_meas_config.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;
+/**
+ * \copydoc libcamera::ipa::Algorithm::prepare
+ */
+void Awb::prepare(IPAContext &context, const uint32_t frame,
+ IPAFrameContext &frameContext, rkisp1_ext_params_block_header *hdr)
+{
+ /*
+ * This is the latest time we can read the active state. This is the
+ * most up-to-date automatic values we can read.
+ */
+ if (frameContext.awb.autoEnabled) {
+ frameContext.awb.gains.red = context.activeState.awb.gains.automatic.red;
+ frameContext.awb.gains.green = context.activeState.awb.gains.automatic.green;
+ frameContext.awb.gains.blue = context.activeState.awb.gains.automatic.blue;
+ }
+
+ struct rkisp1_ext_params_awb_gain_config *awbg =
+ reinterpret_cast<rkisp1_ext_params_awb_gain_config *>(hdr);
+
+ prepareAwbGains(frameContext, awbg);
+
+ /* If we have already set the AWB measurement parameters, return. */
+ if (frame > 0)
+ return;
+
+ /* Configure the measure window for AWB. */
+ char *awb_hdr = reinterpret_cast<char *>(hdr);
+ struct rkisp1_ext_params_awb_meas_config *awbm =
+ reinterpret_cast<rkisp1_ext_params_awb_meas_config *>
+ (awb_hdr + sizeof(rkisp1_ext_params_awb_gain_config));
- /* 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;
+ prepareAwbMeas(context, awbm);
}
uint32_t Awb::estimateCCT(double red, double green, double blue)
diff --git a/src/ipa/rkisp1/algorithms/awb.h b/src/ipa/rkisp1/algorithms/awb.h
index 06c92896..acc1940e 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;
+ rkisp1_ext_params_block_header *hdr) override;
void process(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
const rkisp1_stat_buffer *stats,
@@ -33,6 +33,10 @@ public:
private:
uint32_t estimateCCT(double red, double green, double blue);
+ void prepareAwbGains(IPAFrameContext &frameContext,
+ rkisp1_ext_params_awb_gain_config *awbg);
+ void prepareAwbMeas(IPAContext &context,
+ rkisp1_ext_params_awb_meas_config *awbm);
bool rgbMode_;
};
diff --git a/src/ipa/rkisp1/algorithms/blc.cpp b/src/ipa/rkisp1/algorithms/blc.cpp
index d2e74354..def3bb80 100644
--- a/src/ipa/rkisp1/algorithms/blc.cpp
+++ b/src/ipa/rkisp1/algorithms/blc.cpp
@@ -68,7 +68,7 @@ int BlackLevelCorrection::init([[maybe_unused]] IPAContext &context,
void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,
const uint32_t frame,
[[maybe_unused]] IPAFrameContext &frameContext,
- rkisp1_params_cfg *params)
+ rkisp1_ext_params_block_header *hdr)
{
if (frame > 0)
return;
@@ -76,15 +76,18 @@ void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,
if (!tuningParameters_)
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_;
+ struct rkisp1_ext_params_bls_config *bls =
+ reinterpret_cast<rkisp1_ext_params_bls_config *>(hdr);
- 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;
+ bls->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS;
+ bls->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
+ bls->header.size = sizeof(rkisp1_ext_params_bls_config);
+
+ bls->bls_config.enable_auto = 0;
+ bls->bls_config.fixed_val.r = blackLevelRed_;
+ bls->bls_config.fixed_val.gr = blackLevelGreenR_;
+ bls->bls_config.fixed_val.gb = blackLevelGreenB_;
+ bls->bls_config.fixed_val.b = blackLevelBlue_;
}
REGISTER_IPA_ALGORITHM(BlackLevelCorrection, "BlackLevelCorrection")
diff --git a/src/ipa/rkisp1/algorithms/blc.h b/src/ipa/rkisp1/algorithms/blc.h
index 460ebcc1..73348807 100644
--- a/src/ipa/rkisp1/algorithms/blc.h
+++ b/src/ipa/rkisp1/algorithms/blc.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;
+ rkisp1_ext_params_block_header *hdr) override;
private:
bool tuningParameters_;
diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp
index 68bb8180..a994302d 100644
--- a/src/ipa/rkisp1/algorithms/cproc.cpp
+++ b/src/ipa/rkisp1/algorithms/cproc.cpp
@@ -89,19 +89,22 @@ void ColorProcessing::queueRequest(IPAContext &context,
void ColorProcessing::prepare([[maybe_unused]] IPAContext &context,
[[maybe_unused]] const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params)
+ rkisp1_ext_params_block_header *hdr)
{
/* 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;
+ struct rkisp1_ext_params_cproc_config *cproc =
+ reinterpret_cast<rkisp1_ext_params_cproc_config *>(hdr);
- 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;
+ cproc->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC;
+ cproc->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
+ cproc->header.size = sizeof(rkisp1_ext_params_cproc_config);
+
+ cproc->cproc_config.brightness = frameContext.cproc.brightness;
+ cproc->cproc_config.contrast = frameContext.cproc.contrast;
+ cproc->cproc_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 bafba5cc..1355a02e 100644
--- a/src/ipa/rkisp1/algorithms/cproc.h
+++ b/src/ipa/rkisp1/algorithms/cproc.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;
+ rkisp1_ext_params_block_header *hdr) override;
};
} /* namespace ipa::rkisp1::algorithms */
diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp
index b5a339e9..4223b3e2 100644
--- a/src/ipa/rkisp1/algorithms/dpcc.cpp
+++ b/src/ipa/rkisp1/algorithms/dpcc.cpp
@@ -232,16 +232,19 @@ 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)
+ rkisp1_ext_params_block_header *hdr)
{
if (frame > 0)
return;
- params->others.dpcc_config = config_;
+ struct rkisp1_ext_params_dpcc_config *dpcc =
+ reinterpret_cast<rkisp1_ext_params_dpcc_config *>(hdr);
- 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;
+ dpcc->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC;
+ dpcc->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
+ dpcc->header.size = sizeof(rkisp1_ext_params_dpcc_config);
+
+ dpcc->dpcc_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..ba9fff7c 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;
+ rkisp1_ext_params_block_header *hdr) 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..9f24b13b 100644
--- a/src/ipa/rkisp1/algorithms/dpf.cpp
+++ b/src/ipa/rkisp1/algorithms/dpf.cpp
@@ -211,46 +211,82 @@ void Dpf::queueRequest(IPAContext &context,
frameContext.dpf.update = update;
}
+void Dpf::prepareDpf(IPAContext &context, rkisp1_ext_params_dpf_config *dpf)
+{
+ dpf->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF;
+ dpf->header.size = sizeof(rkisp1_ext_params_dpf_config);
+ dpf->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
+
+ dpf->dpf_config = config_;
+
+ /*
+ * The DPF needs to take into account the total amount of
+ * digital gain, which comes from the AWB and LSC modules. The
+ * DPF hardware can be programmed with a digital gain value
+ * manually, but can also use the gains supplied by the AWB and
+ * LSC modules automatically when they are enabled. Use that
+ * mode of operation as it simplifies control of the DPF.
+ */
+ const auto &awb = context.configuration.awb;
+ const auto &lsc = context.configuration.lsc;
+ auto &mode = dpf->dpf_config.gain.mode;
+ if (awb.enabled && lsc.enabled)
+ mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS;
+ else if (awb.enabled)
+ mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS;
+ else if (lsc.enabled)
+ mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS;
+ else
+ mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED;
+}
+
+void Dpf::prepareDpfStrength(rkisp1_ext_params_dpf_strength_config *dpfs)
+{
+ dpfs->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH;
+ dpfs->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
+ dpfs->header.size = sizeof(rkisp1_ext_params_dpf_strength_config);
+
+ dpfs->dpf_strength_config = strengthConfig_;
+}
+
/**
* \copydoc libcamera::ipa::Algorithm::prepare
*/
void Dpf::prepare(IPAContext &context, const uint32_t frame,
- IPAFrameContext &frameContext, rkisp1_params_cfg *params)
+ IPAFrameContext &frameContext, rkisp1_ext_params_block_header *hdr)
{
+ struct rkisp1_ext_params_dpf_config *dpf =
+ reinterpret_cast<rkisp1_ext_params_dpf_config *>(hdr);
+
+ /* On first frame program both DPF and strenghts. */
if (frame == 0) {
- params->others.dpf_config = config_;
- params->others.dpf_strength_config = strengthConfig_;
-
- const auto &awb = context.configuration.awb;
- const auto &lsc = context.configuration.lsc;
- auto &mode = params->others.dpf_config.gain.mode;
-
- /*
- * The DPF needs to take into account the total amount of
- * digital gain, which comes from the AWB and LSC modules. The
- * DPF hardware can be programmed with a digital gain value
- * manually, but can also use the gains supplied by the AWB and
- * LSC modules automatically when they are enabled. Use that
- * mode of operation as it simplifies control of the DPF.
- */
- if (awb.enabled && lsc.enabled)
- mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS;
- else if (awb.enabled)
- mode = RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS;
- else if (lsc.enabled)
- 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;
+
+ prepareDpf(context, dpf);
+
+ char *dpf_hdr = reinterpret_cast<char *>(hdr);
+ struct rkisp1_ext_params_dpf_strength_config *dpfs =
+ reinterpret_cast<rkisp1_ext_params_dpf_strength_config *>
+ (dpf_hdr + sizeof(rkisp1_ext_params_dpf_config));
+
+ prepareDpfStrength(dpfs);
+
+ return;
}
- 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 no updates, skip the DPF block completely. */
+ if (!frameContext.dpf.update)
+ return;
+
+ /* Re-enable DPF by re-programming it, or disable it. */
+ if (frameContext.dpf.denoise) {
+ prepareDpf(context, dpf);
+
+ return;
}
+
+ dpf->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF;
+ dpf->header.size = sizeof(rkisp1_ext_params_dpf_config);
+ dpf->header.enable = RKISP1_EXT_PARAMS_BLOCK_DISABLE;
}
REGISTER_IPA_ALGORITHM(Dpf, "Dpf")
diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h
index da0115ba..5b8e060d 100644
--- a/src/ipa/rkisp1/algorithms/dpf.h
+++ b/src/ipa/rkisp1/algorithms/dpf.h
@@ -27,9 +27,11 @@ public:
const ControlList &controls) override;
void prepare(IPAContext &context, const uint32_t frame,
IPAFrameContext &frameContext,
- rkisp1_params_cfg *params) override;
+ rkisp1_ext_params_block_header *hdr) override;
private:
+ void prepareDpf(IPAContext &context, rkisp1_ext_params_dpf_config *dpf);
+ void prepareDpfStrength(rkisp1_ext_params_dpf_strength_config *dpfs);
struct rkisp1_cif_isp_dpf_config config_;
struct rkisp1_cif_isp_dpf_strength_config strengthConfig_;
};
diff --git a/src/ipa/rkisp1/algorithms/filter.cpp b/src/ipa/rkisp1/algorithms/filter.cpp
index 9752248a..6e278a9a 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, rkisp1_ext_params_block_header *hdr)
{
/* Check if the algorithm configuration has been updated. */
if (!frameContext.filter.update)
@@ -160,7 +160,14 @@ 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;
+
+ struct rkisp1_ext_params_flt_config *flt =
+ reinterpret_cast<rkisp1_ext_params_flt_config *>(hdr);
+ auto &flt_config = flt->flt_config;
+
+ flt->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT;
+ flt->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
+ flt->header.size = sizeof(rkisp1_ext_params_flt_config);
flt_config.fac_sh0 = filt_fac_sh0[sharpness];
flt_config.fac_sh1 = filt_fac_sh1[sharpness];
@@ -203,10 +210,6 @@ void Filter::prepare([[maybe_unused]] IPAContext &context,
flt_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..8d9a9ce1 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;
+ rkisp1_ext_params_block_header *hdr) override;
};
} /* namespace ipa::rkisp1::algorithms */
diff --git a/src/ipa/rkisp1/algorithms/gsl.cpp b/src/ipa/rkisp1/algorithms/gsl.cpp
index 9b056c6e..169fada2 100644
--- a/src/ipa/rkisp1/algorithms/gsl.cpp
+++ b/src/ipa/rkisp1/algorithms/gsl.cpp
@@ -119,24 +119,25 @@ 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)
+ rkisp1_ext_params_block_header *hdr)
{
if (frame > 0)
return;
- params->others.sdg_config.xa_pnts.gamma_dx0 = gammaDx_[0];
- params->others.sdg_config.xa_pnts.gamma_dx1 = gammaDx_[1];
+ struct rkisp1_ext_params_sdg_config *sdg =
+ reinterpret_cast<rkisp1_ext_params_sdg_config *>(hdr);
- 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);
+ sdg->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG;
+ sdg->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
+ sdg->header.size = sizeof(rkisp1_ext_params_sdg_config);
- 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;
+ struct rkisp1_cif_isp_sdg_config &sdg_config = sdg->sdg_config;
+ sdg_config.xa_pnts.gamma_dx0 = gammaDx_[0];
+ sdg_config.xa_pnts.gamma_dx1 = gammaDx_[1];
+
+ std::copy(curveYr_.begin(), curveYr_.end(), sdg_config.curve_r.gamma_y);
+ std::copy(curveYg_.begin(), curveYg_.end(), sdg_config.curve_g.gamma_y);
+ std::copy(curveYb_.begin(), curveYb_.end(), sdg_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..f71add58 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;
+ rkisp1_ext_params_block_header *hdr) override;
private:
uint32_t gammaDx_[2];
diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp
index 161183fc..3f00707b 100644
--- a/src/ipa/rkisp1/algorithms/lsc.cpp
+++ b/src/ipa/rkisp1/algorithms/lsc.cpp
@@ -185,18 +185,16 @@ int LensShadingCorrection::configure(IPAContext &context,
return 0;
}
-void LensShadingCorrection::setParameters(rkisp1_params_cfg *params)
+void LensShadingCorrection::setParameters(rkisp1_ext_params_lsc_config *lsc)
{
- 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;
+ memcpy(lsc->lsc_config.x_grad_tbl, xGrad_, sizeof(lsc->lsc_config.x_grad_tbl));
+ memcpy(lsc->lsc_config.y_grad_tbl, yGrad_, sizeof(lsc->lsc_config.y_grad_tbl));
+ memcpy(lsc->lsc_config.x_size_tbl, xSizes_, sizeof(lsc->lsc_config.x_size_tbl));
+ memcpy(lsc->lsc_config.y_size_tbl, ySizes_, sizeof(lsc->lsc_config.y_size_tbl));
+
+ lsc->header.type = RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC;
+ lsc->header.enable = RKISP1_EXT_PARAMS_BLOCK_ENABLE;
+ lsc->header.size = sizeof(rkisp1_ext_params_lsc_config);
}
void LensShadingCorrection::copyTable(rkisp1_cif_isp_lsc_config &config,
@@ -248,10 +246,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)
+ rkisp1_ext_params_block_header *hdr)
{
- 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.
@@ -259,13 +255,16 @@ void LensShadingCorrection::prepare(IPAContext &context,
if (sets_.size() == 1 && frame > 0)
return;
+ struct rkisp1_ext_params_lsc_config *lsc =
+ reinterpret_cast<rkisp1_ext_params_lsc_config *>(hdr);
+
/*
* If there is only one set, pick it. We can ignore lastCt_, as it will
* never be relevant.
*/
if (sets_.size() == 1) {
- setParameters(params);
- copyTable(config, sets_.cbegin()->second);
+ setParameters(lsc);
+ copyTable(lsc->lsc_config, sets_.cbegin()->second);
return;
}
@@ -294,13 +293,13 @@ void LensShadingCorrection::prepare(IPAContext &context,
(lastCt_.adjusted <= ct && ct <= lastCt_.original))
return;
- setParameters(params);
+ setParameters(lsc);
/*
* The color temperature matches exactly one of the available LSC tables.
*/
if (sets_.count(ct)) {
- copyTable(config, sets_[ct]);
+ copyTable(lsc->lsc_config, sets_[ct]);
lastCt_ = { ct, ct };
return;
}
@@ -319,7 +318,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(lsc->lsc_config, set);
lastCt_ = { ct, set.ct };
return;
}
@@ -331,7 +330,7 @@ void LensShadingCorrection::prepare(IPAContext &context,
LOG(RkISP1Lsc, Debug)
<< "ct is " << ct << ", interpolating between "
<< ct0 << " and " << ct1;
- interpolateTable(config, set0, set1, ct);
+ interpolateTable(lsc->lsc_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..690bf267 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;
+ rkisp1_ext_params_block_header *hdr) override;
private:
struct Components {
@@ -36,7 +36,7 @@ private:
std::vector<uint16_t> b;
};
- void setParameters(rkisp1_params_cfg *params);
+ void setParameters(rkisp1_ext_params_lsc_config *lsc);
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/module.h b/src/ipa/rkisp1/module.h
index 16c3e43e..89d5338b 100644
--- a/src/ipa/rkisp1/module.h
+++ b/src/ipa/rkisp1/module.h
@@ -20,7 +20,7 @@ namespace libcamera {
namespace ipa::rkisp1 {
using Module = ipa::Module<IPAContext, IPAFrameContext, IPACameraSensorInfo,
- rkisp1_params_cfg, rkisp1_stat_buffer>;
+ rkisp1_ext_params_block_header, rkisp1_stat_buffer>;
} /* namespace ipa::rkisp1 */
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index 6687c91e..05e5ed26 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -325,16 +325,40 @@ void IPARkISP1::queueRequest(const uint32_t frame, const ControlList &controls)
void IPARkISP1::fillParamsBuffer(const uint32_t frame, const uint32_t bufferId)
{
IPAFrameContext &frameContext = context_.frameContexts.get(frame);
+ rkisp1_ext_params_block_header *block;
+ size_t totalSize = 0;
- rkisp1_params_cfg *params =
- reinterpret_cast<rkisp1_params_cfg *>(
- mappedBuffers_.at(bufferId).planes()[0].data());
+ rkisp1_ext_params_cfg *params =
+ reinterpret_cast<rkisp1_ext_params_cfg *>(
+ mappedBuffers_.at(bufferId).planes()[0].data());
/* Prepare parameters buffer. */
memset(params, 0, sizeof(*params));
- for (auto const &algo : algorithms())
- algo->prepare(context_, frame, frameContext, params);
+ params->version = RKISP1_EXT_PARAM_BUFFER_V1;
+
+ block = reinterpret_cast<rkisp1_ext_params_block_header *>(params->data);
+ for (auto const &algo : algorithms()) {
+
+ algo->prepare(context_, frame, frameContext, block);
+
+ /*
+ * Each algorithm could add multiple parameter blocks, each of
+ * which will have its own embedded header struct with the size
+ * of that block. We need to iterate through them, sum all of
+ * the block sizes and advance the 'block' pointer to the next
+ * empty one.
+ */
+ while (totalSize < RKISP1_EXT_PARAMS_MAX_SIZE && block->size) {
+ totalSize += block->size;
+ block = reinterpret_cast<rkisp1_ext_params_block_header *>
+ (params->data + totalSize);
+ }
+
+ ASSERT(totalSize <= RKISP1_EXT_PARAMS_MAX_SIZE);
+ }
+
+ params->total_size = totalSize;
paramsBufferReady.emit(frame);
}
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 4cbf105d..1ec210e4 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -800,7 +800,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
}
V4L2DeviceFormat paramFormat;
- paramFormat.fourcc = V4L2PixelFormat(V4L2_META_FMT_RK_ISP1_PARAMS);
+ paramFormat.fourcc = V4L2PixelFormat(V4L2_META_FMT_RK_ISP1_EXT_PARAMS);
ret = param_->setFormat(&paramFormat);
if (ret)
return ret;