@@ -8,6 +8,7 @@
#include "dpf.h"
#include <algorithm>
+#include <map>
#include <string>
#include <vector>
@@ -36,8 +37,32 @@ namespace ipa::rkisp1::algorithms {
LOG_DEFINE_CATEGORY(RkISP1Dpf)
+namespace {
+
+const std::map<std::string, int32_t> kModesMap = {
+ { "ReductionMinimal", controls::draft::NoiseReductionModeMinimal },
+ { "ReductionFast", controls::draft::NoiseReductionModeFast },
+ { "ReductionHighQuality", controls::draft::NoiseReductionModeHighQuality },
+ { "ReductionZSL", controls::draft::NoiseReductionModeZSL },
+ { "ReductionOff", controls::draft::NoiseReductionModeOff },
+};
+
+std::string modeName(int32_t mode)
+{
+ auto it = std::find_if(kModesMap.begin(), kModesMap.end(),
+ [mode](const auto &pair) {
+ return pair.second == mode;
+ });
+
+ if (it != kModesMap.end())
+ return it->first;
+
+ return "ReductionUnknown";
+}
+} /* namespace */
+
Dpf::Dpf()
- : config_({}), strengthConfig_({})
+ : noiseReductionModes_({}), activeMode_(noiseReductionModes_.end())
{
}
@@ -57,10 +82,57 @@ int Dpf::init([[maybe_unused]] IPAContext &context,
int Dpf::parseConfig(const YamlObject &tuningData)
{
- /* Parse base config. */
- int ret = parseSingleConfig(tuningData, config_, strengthConfig_);
- if (ret)
- return ret;
+ /* Parse noise reduction modes. */
+ if (!tuningData.contains("NoiseReductionModes")) {
+ LOG(RkISP1Dpf, Error) << "Missing modes in DPF tuning data";
+ return -EINVAL;
+ }
+
+ noiseReductionModes_.clear();
+ for (const auto &entry : tuningData["NoiseReductionModes"].asList()) {
+ std::optional<std::string> typeOpt =
+ entry["type"].get<std::string>();
+ if (!typeOpt) {
+ LOG(RkISP1Dpf, Error) << "Modes entry missing type";
+ return -EINVAL;
+ }
+
+ ModeConfig mode;
+ auto it = kModesMap.find(*typeOpt);
+ if (it == kModesMap.end()) {
+ LOG(RkISP1Dpf, Error) << "Unknown mode type: " << *typeOpt;
+ return -EINVAL;
+ }
+
+ mode.modeValue = it->second;
+ int ret = parseSingleConfig(entry, mode.dpf, mode.strength);
+ if (ret) {
+ LOG(RkISP1Dpf, Error) << "Failed to parse mode: " << *typeOpt;
+ return ret;
+ }
+
+ noiseReductionModes_.push_back(mode);
+ }
+
+ /*
+ * Parse the optional ActiveMode.
+ * If not present, default to "ReductionOff".
+ */
+ std::string activeMode = tuningData["ActiveMode"].get<std::string>().value_or("ReductionOff");
+ auto it = kModesMap.find(activeMode);
+ if (it == kModesMap.end()) {
+ LOG(RkISP1Dpf, Warning) << "Invalid ActiveMode: " << activeMode;
+ activeMode_ = noiseReductionModes_.end();
+ return 0;
+ }
+
+ if (!loadConfig(it->second)) {
+ /* If the default "ReductionOff" mode is requested but not configured, disable DPF. */
+ if (it->second == controls::draft::NoiseReductionModeOff)
+ activeMode_ = noiseReductionModes_.end();
+ else
+ return -EINVAL;
+ }
return 0;
}
@@ -193,6 +265,27 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData,
return 0;
}
+bool Dpf::loadConfig(int32_t mode)
+{
+ auto it = std::find_if(noiseReductionModes_.begin(), noiseReductionModes_.end(),
+ [mode](const ModeConfig &m) {
+ return m.modeValue == mode;
+ });
+ if (it == noiseReductionModes_.end()) {
+ LOG(RkISP1Dpf, Warning)
+ << "No DPF config for reduction mode: " << modeName(mode);
+ return false;
+ }
+
+ activeMode_ = it;
+
+ LOG(RkISP1Dpf, Debug)
+ << "DPF mode=Reduction (config loaded)"
+ << " mode= " << modeName(mode);
+
+ return true;
+}
+
/**
* \copydoc libcamera::ipa::Algorithm::queueRequest
*/
@@ -206,8 +299,6 @@ void Dpf::queueRequest(IPAContext &context,
const auto &denoise = controls.get(controls::draft::NoiseReductionMode);
if (denoise) {
- LOG(RkISP1Dpf, Debug) << "Set denoise to " << *denoise;
-
switch (*denoise) {
case controls::draft::NoiseReductionModeOff:
if (dpf.denoise) {
@@ -218,9 +309,10 @@ void Dpf::queueRequest(IPAContext &context,
case controls::draft::NoiseReductionModeMinimal:
case controls::draft::NoiseReductionModeHighQuality:
case controls::draft::NoiseReductionModeFast:
- if (!dpf.denoise) {
- dpf.denoise = true;
+ case controls::draft::NoiseReductionModeZSL:
+ if (loadConfig(*denoise)) {
update = true;
+ dpf.denoise = true;
}
break;
default:
@@ -229,6 +321,8 @@ void Dpf::queueRequest(IPAContext &context,
<< *denoise;
break;
}
+ if (update)
+ LOG(RkISP1Dpf, Debug) << "Set denoise to " << modeName(*denoise);
}
frameContext.dpf.denoise = dpf.denoise;
@@ -251,8 +345,10 @@ void Dpf::prepare(IPAContext &context, const uint32_t frame,
strengthConfig.setEnabled(frameContext.dpf.denoise);
if (frameContext.dpf.denoise) {
- *config = config_;
- *strengthConfig = strengthConfig_;
+ const ModeConfig &modeConfig = *activeMode_;
+
+ *config = modeConfig.dpf;
+ *strengthConfig = modeConfig.strength;
const auto &awb = context.configuration.awb;
const auto &lsc = context.configuration.lsc;
@@ -30,13 +30,21 @@ public:
RkISP1Params *params) override;
private:
+ struct ModeConfig {
+ int32_t modeValue;
+ rkisp1_cif_isp_dpf_config dpf;
+ rkisp1_cif_isp_dpf_strength_config strength;
+ };
+
int parseConfig(const YamlObject &tuningData);
int parseSingleConfig(const YamlObject &tuningData,
rkisp1_cif_isp_dpf_config &config,
rkisp1_cif_isp_dpf_strength_config &strengthConfig);
- struct rkisp1_cif_isp_dpf_config config_;
- struct rkisp1_cif_isp_dpf_strength_config strengthConfig_;
+ bool loadConfig(int32_t mode);
+
+ std::vector<ModeConfig> noiseReductionModes_;
+ std::vector<ModeConfig>::const_iterator activeMode_;
};
} /* namespace ipa::rkisp1::algorithms */
Implement support for switching between different noise reduction modes. This allows the DPF algorithm to be configured with different parameters based on the requested noise reduction level (e.g., minimal, fast, high quality). Mode configurations are stored in the tuning data as a list of modes, with each mode specifying its 'type' and corresponding DPF parameters. An optional 'ActiveMode' setting allows defining the default mode at startup, defaulting to "ReductionOff" if not specified. The Dpf class is refactored to store configurations in a vector and track the current mode using an iterator, which avoids data copying during runtime. Signed-off-by: Rui Wang <rui.wang@ideasonboard.com> --- changelog since v5: - Update log verbos from Info to Debug in loadReductionConfig - Update log mode value to string to in loadReductionConfig - improving the return value changed like : if (ret != 0) -> if (ret) Reviewed-by tags from v5 are carried over (no function changes). changelog since v6: - add { controls::draft::NoiseReductionModeOff, "off" }, to fix out_of_range issue changelog since v7: - Delete base config parse from parseConfig changelog since v8: - remove config_ strengthConfig_ by replacing activeMode_ iterator to avoiding data copy during config loading - Update kModesMap from std::map<int32_t, std:string> std::map<std::string, int32_t> for quick search improvement - add ActiveMode as Stefan and Jacopo's review comments - update type : auto -> int for ret value - name change loadRecuctionConfig -> loadConfig - delete parseMode --- src/ipa/rkisp1/algorithms/dpf.cpp | 118 +++++++++++++++++++++++++++--- src/ipa/rkisp1/algorithms/dpf.h | 12 ++- 2 files changed, 117 insertions(+), 13 deletions(-)