| Message ID | 20260115163318.1339354-3-rui.wang@ideasonboard.com |
|---|---|
| State | Superseded |
| Headers | show |
| Series |
|
| Related | show |
Hi Rui On Thu, Jan 15, 2026 at 11:33:13AM -0500, Rui Wang wrote: > Add support for switching between different noise reduction modes. > > Introduce `noiseReductionModes_` to store mode-specific configs. > > LoadReductionConfig() select specific config from configs. > > Signed-off-by: Rui Wang <rui.wang@ideasonboard.com> > Reviewed-by: Jacopo Mondi <jacopo.mondi@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 > --- > src/ipa/rkisp1/algorithms/dpf.cpp | 90 +++++++++++++++++++++++++++---- > src/ipa/rkisp1/algorithms/dpf.h | 11 ++++ > 2 files changed, 92 insertions(+), 9 deletions(-) > > diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp > index dd3effa1..9b663831 100644 > --- a/src/ipa/rkisp1/algorithms/dpf.cpp > +++ b/src/ipa/rkisp1/algorithms/dpf.cpp > @@ -8,6 +8,7 @@ > #include "dpf.h" > > #include <algorithm> > +#include <map> > #include <string> > #include <vector> > > @@ -36,8 +37,21 @@ namespace ipa::rkisp1::algorithms { > > LOG_DEFINE_CATEGORY(RkISP1Dpf) > > +namespace { > + > +const std::map<int32_t, std::string> kModesMap = { > + { controls::draft::NoiseReductionModeMinimal, "minimal" }, > + { controls::draft::NoiseReductionModeFast, "fast" }, > + { controls::draft::NoiseReductionModeHighQuality, "highquality" }, > + { controls::draft::NoiseReductionModeZSL, "zsl" }, > + { controls::draft::NoiseReductionModeOff, "off" }, > +}; > + > +} /* namespace */ > + > Dpf::Dpf() > - : config_({}), strengthConfig_({}) > + : config_({}), strengthConfig_({}), noiseReductionModes_({}), > + runningMode_(controls::draft::NoiseReductionModeOff) > { > } > > @@ -57,10 +71,43 @@ 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 modes. */ > + return parseModes(tuningData); This should be called by init() removing the need for parseConfig() as suggested in the review of the previous patch > +} > + > +int Dpf::parseModes(const YamlObject &tuningData) > +{ > + /* Parse noise reduction modes. */ > + if (!tuningData.contains("modes")) Should we LOG(Error) now that modes are mandatory ? > + return -EINVAL; > + > + noiseReductionModes_.clear(); > + for (const auto &entry : tuningData["modes"].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 = std::find_if(kModesMap.begin(), kModesMap.end(), > + [&typeOpt](const auto &pair) { > + return pair.second == *typeOpt; > + }); > + > + if (it == kModesMap.end()) { > + LOG(RkISP1Dpf, Error) << "Unknown mode type: " << *typeOpt; > + return -EINVAL; > + } > + > + mode.modeValue = it->first; > + auto ret = parseSingleConfig(entry, mode.dpf, mode.strength); int ret; auto gives you nothing here > + if (ret) > + return ret; > + > + noiseReductionModes_.push_back(mode); I think it was pointed out already in the previous versions: you should populate context.ctrlMap[controls::draft::NoiseReductionMode] with one entry for each supported mode. See https://git.libcamera.org/libcamera/libcamera.git/tree/src/ipa/rkisp1/algorithms/agc.cpp#n76 Will it happen later on in the series and I've missed it ? > + } > > return 0; > } > @@ -193,6 +240,28 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData, > return 0; > } > > +bool Dpf::loadReductionConfig(int32_t mode) loadModeConfig(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: " << kModesMap.at(mode); << "No DPF config for mode: " << kModesMap.at(mode); > + return false; > + } > + > + config_ = it->dpf; > + strengthConfig_ = it->strength; So now the config_ and strengthConfig_ member variables point to the 'active' mode configuration. Why are you copying them instead of just keeping a pointer to the active mode in noiseReductionModes_ ? > + > + LOG(RkISP1Dpf, Debug) > + << "DPF mode=Reduction (config loaded)" > + << " mode=" << kModesMap.at(mode); " mode = " > + > + return true; > +} > + > /** > * \copydoc libcamera::ipa::Algorithm::queueRequest > */ > @@ -206,8 +275,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 +285,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 (loadReductionConfig(*denoise)) { > update = true; > + dpf.denoise = true; > } > break; > default: > @@ -229,6 +297,10 @@ void Dpf::queueRequest(IPAContext &context, > << *denoise; > break; > } > + if (update) { > + runningMode_ = *denoise; So the member variable runningMode_ simply keeps track of the index of the enabled mode, right ? And I see it only used in logConfig() introduced in the next patch. If you accept the above suggestion about keeping a pointer/refernce/iterator to the active mode on the noiseReductionModes_ vector instead of copying its content to config_ and strengthConfig_ you can use the 'modeValue' index instead of duplicating the information in runnigMode_ > + LOG(RkISP1Dpf, Debug) << "Set denoise to " << kModesMap.at(runningMode_); > + } > } > > frameContext.dpf.denoise = dpf.denoise; > diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h > index 39186c55..2a2c7052 100644 > --- a/src/ipa/rkisp1/algorithms/dpf.h > +++ b/src/ipa/rkisp1/algorithms/dpf.h > @@ -30,13 +30,24 @@ 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 parseModes(const YamlObject &tuningData); > int parseSingleConfig(const YamlObject &tuningData, > rkisp1_cif_isp_dpf_config &config, > rkisp1_cif_isp_dpf_strength_config &strengthConfig); > > + bool loadReductionConfig(int32_t mode); > + > struct rkisp1_cif_isp_dpf_config config_; > struct rkisp1_cif_isp_dpf_strength_config strengthConfig_; > + std::vector<ModeConfig> noiseReductionModes_; > + int32_t runningMode_; > }; > > } /* namespace ipa::rkisp1::algorithms */ > -- > 2.43.0 >
On 2026-01-16 04:21, Jacopo Mondi wrote: > Hi Rui > > On Thu, Jan 15, 2026 at 11:33:13AM -0500, Rui Wang wrote: >> Add support for switching between different noise reduction modes. >> >> Introduce `noiseReductionModes_` to store mode-specific configs. >> >> LoadReductionConfig() select specific config from configs. >> >> Signed-off-by: Rui Wang <rui.wang@ideasonboard.com> >> Reviewed-by: Jacopo Mondi <jacopo.mondi@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 >> --- >> src/ipa/rkisp1/algorithms/dpf.cpp | 90 +++++++++++++++++++++++++++---- >> src/ipa/rkisp1/algorithms/dpf.h | 11 ++++ >> 2 files changed, 92 insertions(+), 9 deletions(-) >> >> diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp >> index dd3effa1..9b663831 100644 >> --- a/src/ipa/rkisp1/algorithms/dpf.cpp >> +++ b/src/ipa/rkisp1/algorithms/dpf.cpp >> @@ -8,6 +8,7 @@ >> #include "dpf.h" >> >> #include <algorithm> >> +#include <map> >> #include <string> >> #include <vector> >> >> @@ -36,8 +37,21 @@ namespace ipa::rkisp1::algorithms { >> >> LOG_DEFINE_CATEGORY(RkISP1Dpf) >> >> +namespace { >> + >> +const std::map<int32_t, std::string> kModesMap = { >> + { controls::draft::NoiseReductionModeMinimal, "minimal" }, >> + { controls::draft::NoiseReductionModeFast, "fast" }, >> + { controls::draft::NoiseReductionModeHighQuality, "highquality" }, >> + { controls::draft::NoiseReductionModeZSL, "zsl" }, >> + { controls::draft::NoiseReductionModeOff, "off" }, >> +}; >> + >> +} /* namespace */ >> + >> Dpf::Dpf() >> - : config_({}), strengthConfig_({}) >> + : config_({}), strengthConfig_({}), noiseReductionModes_({}), >> + runningMode_(controls::draft::NoiseReductionModeOff) >> { >> } >> >> @@ -57,10 +71,43 @@ 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 modes. */ >> + return parseModes(tuningData); > This should be called by init() removing the need for parseConfig() as > suggested in the review of the previous patch I am thinking about add parseActiveMode into parseConfig , and all YAML parsing into this function in future. currently it has only parseModes inside parseConfig. - enableMode: '' > >> +} >> + >> +int Dpf::parseModes(const YamlObject &tuningData) >> +{ >> + /* Parse noise reduction modes. */ >> + if (!tuningData.contains("modes")) > Should we LOG(Error) now that modes are mandatory ? > >> + return -EINVAL; >> + >> + noiseReductionModes_.clear(); >> + for (const auto &entry : tuningData["modes"].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 = std::find_if(kModesMap.begin(), kModesMap.end(), >> + [&typeOpt](const auto &pair) { >> + return pair.second == *typeOpt; >> + }); >> + >> + if (it == kModesMap.end()) { >> + LOG(RkISP1Dpf, Error) << "Unknown mode type: " << *typeOpt; >> + return -EINVAL; >> + } >> + >> + mode.modeValue = it->first; >> + auto ret = parseSingleConfig(entry, mode.dpf, mode.strength); > int ret; > > auto gives you nothing here > >> + if (ret) >> + return ret; >> + >> + noiseReductionModes_.push_back(mode); > I think it was pointed out already in the previous versions: you > should populate context.ctrlMap[controls::draft::NoiseReductionMode] > with one entry for each supported mode. > > See https://git.libcamera.org/libcamera/libcamera.git/tree/src/ipa/rkisp1/algorithms/agc.cpp#n76 > > Will it happen later on in the series and I've missed it ? > auto it = std::find_if(kModesMap.begin(), kModesMap.end(), [&typeOpt](const auto &pair) { return pair.second == *typeOpt; }); kModesMap contains all NoiseReductionMode value . so I can traverse each mode in YAML and then add into noiseReductionModes_. >> + } >> >> return 0; >> } >> @@ -193,6 +240,28 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData, >> return 0; >> } >> >> +bool Dpf::loadReductionConfig(int32_t mode) > loadModeConfig(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: " << kModesMap.at(mode); > << "No DPF config for mode: " << kModesMap.at(mode); > > will remove this 'reduction' in v9. >> + return false; >> + } >> + >> + config_ = it->dpf; >> + strengthConfig_ = it->strength; > So now the config_ and strengthConfig_ member variables point to the > 'active' mode configuration. Why are you copying them instead of just > keeping a pointer to the active mode in noiseReductionModes_ ? good idea, Introduce a const interator to point active mode in noiseReductionModes_ it can save strengthConfig_,config_, runningMode. will implement in v9. > >> + >> + LOG(RkISP1Dpf, Debug) >> + << "DPF mode=Reduction (config loaded)" >> + << " mode=" << kModesMap.at(mode); > " mode = " will update in v9. >> + >> + return true; >> +} >> + >> /** >> * \copydoc libcamera::ipa::Algorithm::queueRequest >> */ >> @@ -206,8 +275,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 +285,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 (loadReductionConfig(*denoise)) { >> update = true; >> + dpf.denoise = true; >> } >> break; >> default: >> @@ -229,6 +297,10 @@ void Dpf::queueRequest(IPAContext &context, >> << *denoise; >> break; >> } >> + if (update) { >> + runningMode_ = *denoise; > So the member variable runningMode_ simply keeps track of the index of > the enabled mode, right ? And I see it only used in logConfig() > introduced in the next patch. > > If you accept the above suggestion about keeping a > pointer/refernce/iterator to the active mode on the > noiseReductionModes_ vector instead of copying its content to config_ > and strengthConfig_ you can use the 'modeValue' index instead of > duplicating the information in runnigMode_ yes will add const_iterator activeMode_ to point noiseReductionModes_ > >> + LOG(RkISP1Dpf, Debug) << "Set denoise to " << kModesMap.at(runningMode_); >> + } >> } >> >> frameContext.dpf.denoise = dpf.denoise; >> diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h >> index 39186c55..2a2c7052 100644 >> --- a/src/ipa/rkisp1/algorithms/dpf.h >> +++ b/src/ipa/rkisp1/algorithms/dpf.h >> @@ -30,13 +30,24 @@ 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 parseModes(const YamlObject &tuningData); >> int parseSingleConfig(const YamlObject &tuningData, >> rkisp1_cif_isp_dpf_config &config, >> rkisp1_cif_isp_dpf_strength_config &strengthConfig); >> >> + bool loadReductionConfig(int32_t mode); >> + >> struct rkisp1_cif_isp_dpf_config config_; >> struct rkisp1_cif_isp_dpf_strength_config strengthConfig_; >> + std::vector<ModeConfig> noiseReductionModes_; >> + int32_t runningMode_; >> }; >> >> } /* namespace ipa::rkisp1::algorithms */ >> -- >> 2.43.0 >>
Hi Rui On Fri, Jan 16, 2026 at 10:13:35PM -0500, rui wang wrote: > > On 2026-01-16 04:21, Jacopo Mondi wrote: > > Hi Rui > > > > On Thu, Jan 15, 2026 at 11:33:13AM -0500, Rui Wang wrote: > > > Add support for switching between different noise reduction modes. > > > > > > Introduce `noiseReductionModes_` to store mode-specific configs. > > > > > > LoadReductionConfig() select specific config from configs. > > > > > > Signed-off-by: Rui Wang <rui.wang@ideasonboard.com> > > > Reviewed-by: Jacopo Mondi <jacopo.mondi@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 > > > --- > > > src/ipa/rkisp1/algorithms/dpf.cpp | 90 +++++++++++++++++++++++++++---- > > > src/ipa/rkisp1/algorithms/dpf.h | 11 ++++ > > > 2 files changed, 92 insertions(+), 9 deletions(-) > > > > > > diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp > > > index dd3effa1..9b663831 100644 > > > --- a/src/ipa/rkisp1/algorithms/dpf.cpp > > > +++ b/src/ipa/rkisp1/algorithms/dpf.cpp > > > @@ -8,6 +8,7 @@ > > > #include "dpf.h" > > > > > > #include <algorithm> > > > +#include <map> > > > #include <string> > > > #include <vector> > > > > > > @@ -36,8 +37,21 @@ namespace ipa::rkisp1::algorithms { > > > > > > LOG_DEFINE_CATEGORY(RkISP1Dpf) > > > > > > +namespace { > > > + > > > +const std::map<int32_t, std::string> kModesMap = { > > > + { controls::draft::NoiseReductionModeMinimal, "minimal" }, > > > + { controls::draft::NoiseReductionModeFast, "fast" }, > > > + { controls::draft::NoiseReductionModeHighQuality, "highquality" }, > > > + { controls::draft::NoiseReductionModeZSL, "zsl" }, > > > + { controls::draft::NoiseReductionModeOff, "off" }, > > > +}; > > > + > > > +} /* namespace */ > > > + > > > Dpf::Dpf() > > > - : config_({}), strengthConfig_({}) > > > + : config_({}), strengthConfig_({}), noiseReductionModes_({}), > > > + runningMode_(controls::draft::NoiseReductionModeOff) > > > { > > > } > > > > > > @@ -57,10 +71,43 @@ 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 modes. */ > > > + return parseModes(tuningData); > > This should be called by init() removing the need for parseConfig() as > > suggested in the review of the previous patch > > I am thinking about add parseActiveMode into parseConfig , and all YAML > parsing into this function in future. > > currently it has only parseModes inside parseConfig. > > - enableMode: '' > > > > > > +} > > > + > > > +int Dpf::parseModes(const YamlObject &tuningData) > > > +{ > > > + /* Parse noise reduction modes. */ > > > + if (!tuningData.contains("modes")) > > Should we LOG(Error) now that modes are mandatory ? > > > > > + return -EINVAL; > > > + > > > + noiseReductionModes_.clear(); > > > + for (const auto &entry : tuningData["modes"].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 = std::find_if(kModesMap.begin(), kModesMap.end(), > > > + [&typeOpt](const auto &pair) { > > > + return pair.second == *typeOpt; > > > + }); > > > + > > > + if (it == kModesMap.end()) { > > > + LOG(RkISP1Dpf, Error) << "Unknown mode type: " << *typeOpt; > > > + return -EINVAL; > > > + } > > > + > > > + mode.modeValue = it->first; > > > + auto ret = parseSingleConfig(entry, mode.dpf, mode.strength); > > int ret; > > > > auto gives you nothing here > > > > > + if (ret) > > > + return ret; > > > + > > > + noiseReductionModes_.push_back(mode); > > I think it was pointed out already in the previous versions: you > > should populate context.ctrlMap[controls::draft::NoiseReductionMode] > > with one entry for each supported mode. > > > > See https://git.libcamera.org/libcamera/libcamera.git/tree/src/ipa/rkisp1/algorithms/agc.cpp#n76 > > > > Will it happen later on in the series and I've missed it ? > > > auto it = std::find_if(kModesMap.begin(), kModesMap.end(), > > [&typeOpt](const auto &pair) { > > return pair.second == *typeOpt; > > }); > > > kModesMap contains all NoiseReductionMode value . so I can traverse each mode in YAML > and then add into noiseReductionModes_. I'm sorry but maybe we're not getting each other. Could you please read the link I provided above where the AGC algorithm populates context.ctrlMap[] ? You should populate that map as well with only the modes enabled in config file. Please apply the following patch to your series: ------------------------------------------------------------------------------ --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -58,30 +58,33 @@ Dpf::Dpf() /** * \copydoc libcamera::ipa::Algorithm::init */ -int Dpf::init([[maybe_unused]] IPAContext &context, - const YamlObject &tuningData) +int Dpf::init(IPAContext &context, const YamlObject &tuningData) { /* Parse tuning block. */ - int ret = parseConfig(tuningData); + int ret = parseConfig(context, tuningData); if (ret) return ret; return 0; } -int Dpf::parseConfig(const YamlObject &tuningData) +int Dpf::parseConfig(IPAContext &context, const YamlObject &tuningData) { /* Parse modes. */ - return parseModes(tuningData); + return parseModes(context, tuningData); } -int Dpf::parseModes(const YamlObject &tuningData) +int Dpf::parseModes(IPAContext &context, const YamlObject &tuningData) { /* Parse noise reduction modes. */ if (!tuningData.contains("modes")) return -EINVAL; + std::vector<ControlValue> enabledModes{ + ControlValue(controls::draft::NoiseReductionModeOff), + }; noiseReductionModes_.clear(); + for (const auto &entry : tuningData["modes"].asList()) { std::optional<std::string> typeOpt = entry["type"].get<std::string>(); @@ -107,8 +110,12 @@ int Dpf::parseModes(const YamlObject &tuningData) return ret; noiseReductionModes_.push_back(mode); + enabledModes.push_back(ControlValue(mode.modeValue)); } + context.ctrlMap[&controls::draft::NoiseReductionMode] = + ControlInfo(enabledModes); + return 0; } diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h index 1821da396cd7..4deedb838d4d 100644 --- a/src/ipa/rkisp1/algorithms/dpf.h +++ b/src/ipa/rkisp1/algorithms/dpf.h @@ -36,8 +36,8 @@ private: rkisp1_cif_isp_dpf_strength_config strength; }; - int parseConfig(const YamlObject &tuningData); - int parseModes(const YamlObject &tuningData); + int parseConfig(IPAContext &context, const YamlObject &tuningData); + int parseModes(IPAContext &context, const YamlObject &tuningData); int parseSingleConfig(const YamlObject &tuningData, rkisp1_cif_isp_dpf_config &config, rkisp1_cif_isp_dpf_strength_config &strengthConfig); diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index fbcc39103d4b..402ed62ceaa9 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -120,7 +120,6 @@ const IPAHwSettings ipaHwSettingsV12{ /* List of controls handled by the RkISP1 IPA */ const ControlInfoMap::Map rkisp1Controls{ { &controls::DebugMetadataEnable, ControlInfo(false, true, false) }, - { &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) }, }; } /* namespace */ ------------------------------------------------------------------------------ So that only modes enabled in the tuning file are reported in Camera::controls(). Without the patch: # cam -c1 --list-controls Control: [inout] draft::NoiseReductionMode: - NoiseReductionModeOff (0) [default] - NoiseReductionModeFast (1) - NoiseReductionModeHighQuality (2) - NoiseReductionModeMinimal (3) - NoiseReductionModeZSL (4) With the patch and modes "minimal" and "highquality" in the tuning file as per this series on imx219 # cam -c1 --list-controls Control: [inout] draft::NoiseReductionMode: - NoiseReductionModeOff (0) [default] - NoiseReductionModeMinimal (3) - NoiseReductionModeHighQuality (2) With the patch and mode "highquality" removed from the tuning file # cam -c1 --list-controls Control: [inout] draft::NoiseReductionMode: - NoiseReductionModeOff (0) [default] - NoiseReductionModeMinimal (3) > > > > > + } > > > > > > return 0; > > > } > > > @@ -193,6 +240,28 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData, > > > return 0; > > > } > > > > > > +bool Dpf::loadReductionConfig(int32_t mode) > > loadModeConfig(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: " << kModesMap.at(mode); > > << "No DPF config for mode: " << kModesMap.at(mode); > > > > will remove this 'reduction' in v9. > > > + return false; > > > + } > > > + > > > + config_ = it->dpf; > > > + strengthConfig_ = it->strength; > > So now the config_ and strengthConfig_ member variables point to the > > 'active' mode configuration. Why are you copying them instead of just > > keeping a pointer to the active mode in noiseReductionModes_ ? > good idea, Introduce a const interator to point active mode in > > noiseReductionModes_ it can save strengthConfig_,config_, runningMode. > will implement in v9. > > > > > > + > > > + LOG(RkISP1Dpf, Debug) > > > + << "DPF mode=Reduction (config loaded)" > > > + << " mode=" << kModesMap.at(mode); > > " mode = " > will update in v9. > > > + > > > + return true; > > > +} > > > + > > > /** > > > * \copydoc libcamera::ipa::Algorithm::queueRequest > > > */ > > > @@ -206,8 +275,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 +285,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 (loadReductionConfig(*denoise)) { > > > update = true; > > > + dpf.denoise = true; > > > } > > > break; > > > default: > > > @@ -229,6 +297,10 @@ void Dpf::queueRequest(IPAContext &context, > > > << *denoise; > > > break; > > > } > > > + if (update) { > > > + runningMode_ = *denoise; > > So the member variable runningMode_ simply keeps track of the index of > > the enabled mode, right ? And I see it only used in logConfig() > > introduced in the next patch. > > > > If you accept the above suggestion about keeping a > > pointer/refernce/iterator to the active mode on the > > noiseReductionModes_ vector instead of copying its content to config_ > > and strengthConfig_ you can use the 'modeValue' index instead of > > duplicating the information in runnigMode_ > > yes will add const_iterator activeMode_ to point noiseReductionModes_ > > > > > > > + LOG(RkISP1Dpf, Debug) << "Set denoise to " << kModesMap.at(runningMode_); > > > + } > > > } > > > > > > frameContext.dpf.denoise = dpf.denoise; > > > diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h > > > index 39186c55..2a2c7052 100644 > > > --- a/src/ipa/rkisp1/algorithms/dpf.h > > > +++ b/src/ipa/rkisp1/algorithms/dpf.h > > > @@ -30,13 +30,24 @@ 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 parseModes(const YamlObject &tuningData); > > > int parseSingleConfig(const YamlObject &tuningData, > > > rkisp1_cif_isp_dpf_config &config, > > > rkisp1_cif_isp_dpf_strength_config &strengthConfig); > > > > > > + bool loadReductionConfig(int32_t mode); > > > + > > > struct rkisp1_cif_isp_dpf_config config_; > > > struct rkisp1_cif_isp_dpf_strength_config strengthConfig_; > > > + std::vector<ModeConfig> noiseReductionModes_; > > > + int32_t runningMode_; > > > }; > > > > > > } /* namespace ipa::rkisp1::algorithms */ > > > -- > > > 2.43.0 > > >
diff --git a/src/ipa/rkisp1/algorithms/dpf.cpp b/src/ipa/rkisp1/algorithms/dpf.cpp index dd3effa1..9b663831 100644 --- a/src/ipa/rkisp1/algorithms/dpf.cpp +++ b/src/ipa/rkisp1/algorithms/dpf.cpp @@ -8,6 +8,7 @@ #include "dpf.h" #include <algorithm> +#include <map> #include <string> #include <vector> @@ -36,8 +37,21 @@ namespace ipa::rkisp1::algorithms { LOG_DEFINE_CATEGORY(RkISP1Dpf) +namespace { + +const std::map<int32_t, std::string> kModesMap = { + { controls::draft::NoiseReductionModeMinimal, "minimal" }, + { controls::draft::NoiseReductionModeFast, "fast" }, + { controls::draft::NoiseReductionModeHighQuality, "highquality" }, + { controls::draft::NoiseReductionModeZSL, "zsl" }, + { controls::draft::NoiseReductionModeOff, "off" }, +}; + +} /* namespace */ + Dpf::Dpf() - : config_({}), strengthConfig_({}) + : config_({}), strengthConfig_({}), noiseReductionModes_({}), + runningMode_(controls::draft::NoiseReductionModeOff) { } @@ -57,10 +71,43 @@ 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 modes. */ + return parseModes(tuningData); +} + +int Dpf::parseModes(const YamlObject &tuningData) +{ + /* Parse noise reduction modes. */ + if (!tuningData.contains("modes")) + return -EINVAL; + + noiseReductionModes_.clear(); + for (const auto &entry : tuningData["modes"].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 = std::find_if(kModesMap.begin(), kModesMap.end(), + [&typeOpt](const auto &pair) { + return pair.second == *typeOpt; + }); + + if (it == kModesMap.end()) { + LOG(RkISP1Dpf, Error) << "Unknown mode type: " << *typeOpt; + return -EINVAL; + } + + mode.modeValue = it->first; + auto ret = parseSingleConfig(entry, mode.dpf, mode.strength); + if (ret) + return ret; + + noiseReductionModes_.push_back(mode); + } return 0; } @@ -193,6 +240,28 @@ int Dpf::parseSingleConfig(const YamlObject &tuningData, return 0; } +bool Dpf::loadReductionConfig(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: " << kModesMap.at(mode); + return false; + } + + config_ = it->dpf; + strengthConfig_ = it->strength; + + LOG(RkISP1Dpf, Debug) + << "DPF mode=Reduction (config loaded)" + << " mode=" << kModesMap.at(mode); + + return true; +} + /** * \copydoc libcamera::ipa::Algorithm::queueRequest */ @@ -206,8 +275,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 +285,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 (loadReductionConfig(*denoise)) { update = true; + dpf.denoise = true; } break; default: @@ -229,6 +297,10 @@ void Dpf::queueRequest(IPAContext &context, << *denoise; break; } + if (update) { + runningMode_ = *denoise; + LOG(RkISP1Dpf, Debug) << "Set denoise to " << kModesMap.at(runningMode_); + } } frameContext.dpf.denoise = dpf.denoise; diff --git a/src/ipa/rkisp1/algorithms/dpf.h b/src/ipa/rkisp1/algorithms/dpf.h index 39186c55..2a2c7052 100644 --- a/src/ipa/rkisp1/algorithms/dpf.h +++ b/src/ipa/rkisp1/algorithms/dpf.h @@ -30,13 +30,24 @@ 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 parseModes(const YamlObject &tuningData); int parseSingleConfig(const YamlObject &tuningData, rkisp1_cif_isp_dpf_config &config, rkisp1_cif_isp_dpf_strength_config &strengthConfig); + bool loadReductionConfig(int32_t mode); + struct rkisp1_cif_isp_dpf_config config_; struct rkisp1_cif_isp_dpf_strength_config strengthConfig_; + std::vector<ModeConfig> noiseReductionModes_; + int32_t runningMode_; }; } /* namespace ipa::rkisp1::algorithms */