diff options
Diffstat (limited to 'src/ipa/rkisp1/algorithms')
-rw-r--r-- | src/ipa/rkisp1/algorithms/awb.cpp | 34 | ||||
-rw-r--r-- | src/ipa/rkisp1/algorithms/blc.cpp | 85 | ||||
-rw-r--r-- | src/ipa/rkisp1/algorithms/blc.h | 5 | ||||
-rw-r--r-- | src/ipa/rkisp1/algorithms/ccm.cpp | 7 |
4 files changed, 103 insertions, 28 deletions
diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp index a01fe5d9..4ccafd48 100644 --- a/src/ipa/rkisp1/algorithms/awb.cpp +++ b/src/ipa/rkisp1/algorithms/awb.cpp @@ -120,10 +120,14 @@ 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; + params->others.awb_gain_config.gain_green_b = + std::clamp<int>(256 * frameContext.awb.gains.green, 0, 0x3ff); + params->others.awb_gain_config.gain_blue = + std::clamp<int>(256 * frameContext.awb.gains.blue, 0, 0x3ff); + params->others.awb_gain_config.gain_red = + std::clamp<int>(256 * frameContext.awb.gains.red, 0, 0x3ff); + params->others.awb_gain_config.gain_green_r = + std::clamp<int>(256 * frameContext.awb.gains.green, 0, 0x3ff); /* Update the gains. */ params->module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN; @@ -218,6 +222,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 +283,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 +318,12 @@ 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 << "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/blc.cpp b/src/ipa/rkisp1/algorithms/blc.cpp index d2e74354..871dd204 100644 --- a/src/ipa/rkisp1/algorithms/blc.cpp +++ b/src/ipa/rkisp1/algorithms/blc.cpp @@ -9,6 +9,8 @@ #include <libcamera/base/log.h> +#include <libcamera/control_ids.h> + #include "libcamera/internal/yaml_parser.h" /** @@ -38,18 +40,61 @@ 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); + 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; + } tuningParameters_ = true; @@ -70,6 +115,9 @@ void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context, [[maybe_unused]] IPAFrameContext &frameContext, rkisp1_params_cfg *params) { + if (context.configuration.raw) + return; + if (frame > 0) return; @@ -77,16 +125,33 @@ void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context, 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_; + /* The rkisp1 uses 12bit based black levels. Scale down accordingly. */ + params->others.bls_config.fixed_val.r = blackLevelRed_ >> 4; + params->others.bls_config.fixed_val.gr = blackLevelGreenR_ >> 4; + params->others.bls_config.fixed_val.gb = blackLevelGreenB_ >> 4; + params->others.bls_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") } /* namespace ipa::rkisp1::algorithms */ diff --git a/src/ipa/rkisp1/algorithms/blc.h b/src/ipa/rkisp1/algorithms/blc.h index 460ebcc1..4ecac233 100644 --- a/src/ipa/rkisp1/algorithms/blc.h +++ b/src/ipa/rkisp1/algorithms/blc.h @@ -23,7 +23,10 @@ public: void prepare(IPAContext &context, const uint32_t frame, IPAFrameContext &frameContext, rkisp1_params_cfg *params) override; - + void process(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const rkisp1_stat_buffer *stats, + ControlList &metadata) override; private: bool tuningParameters_; int16_t blackLevelRed_; diff --git a/src/ipa/rkisp1/algorithms/ccm.cpp b/src/ipa/rkisp1/algorithms/ccm.cpp index c1f5403a..fe7246f8 100644 --- a/src/ipa/rkisp1/algorithms/ccm.cpp +++ b/src/ipa/rkisp1/algorithms/ccm.cpp @@ -111,13 +111,16 @@ 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); @@ -135,7 +138,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); } |