@@ -22,6 +22,7 @@ protected:
~DenoiseBaseAlgorithm() = default;
virtual void setDevMode(bool dev) { devMode_ = dev; }
virtual bool isDevMode() const { return devMode_; }
+
virtual uint32_t computeExposureIndex(const IPAContext &context,
const IPAFrameContext &frameContext) const;
template<typename LevelContainer>
@@ -31,6 +32,9 @@ protected:
{
return true;
}
+ virtual void collectManualOverrides([[maybe_unused]] const ControlList &controls)
+ {
+ }
virtual void handleReductionModeControl([[maybe_unused]] const ControlList &controls,
[[maybe_unused]] IPAFrameContext &frameContext,
[[maybe_unused]] IPAContext &context,
@@ -39,7 +43,6 @@ protected:
}
virtual int32_t getRunningMode() const { return currentRunMode_; }
virtual void setRunningMode(int32_t mode) { currentRunMode_ = mode; }
-
private:
/**< Developer mode state for advanced controls */
bool devMode_ = false;
@@ -358,6 +358,72 @@ void Dpf::loadReductionModeConfig(IPAFrameContext &frameContext)
strengthConfig_ = it->strength;
frameContext.dpf.update = true;
}
+
+void Dpf::collectManualOverrides(const ControlList &controls)
+{
+ if (const auto &c = controls.get(controls::rkisp1::DpfChannelStrengths); c) {
+ if (c->size() == 3) {
+ overrides_.strength = DpfStrengthSettings{
+ static_cast<uint16_t>((*c)[0]),
+ static_cast<uint16_t>((*c)[1]),
+ static_cast<uint16_t>((*c)[2])
+ };
+ }
+ }
+ if (!isDevMode())
+ return;
+
+ if (const auto &c = controls.get(controls::rkisp1::DpfGreenSpatialCoefficients); c) {
+ if (c->size() == RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS) {
+ DpfSpatialGreenSettings green;
+ std::copy_n(c->begin(), RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS,
+ green.coeffs.begin());
+ overrides_.spatialGreen = green;
+ }
+ }
+ if (const auto &c =
+ controls.get(controls::rkisp1::DpfRedBlueSpatialCoefficients);
+ c) {
+ if (c->size() == RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS) {
+ DpfSpatialRbSettings rb;
+ std::copy_n(c->begin(), RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS,
+ rb.coeffs.begin());
+ rb.size = (config_.rb_flt.fltsize ==
+ RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_13x9)
+ ? 1
+ : 0;
+ overrides_.spatialRb = rb;
+ }
+ }
+ if (const auto &c = controls.get(controls::rkisp1::DpfRbFilterSize); c) {
+ overrides_.rbSize = *c ? 1 : 0;
+ }
+ if (const auto &c = controls.get(controls::rkisp1::DpfNoiseLevelLookupCoefficients); c) {
+ if (c->size() == RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS) {
+ DpfNllSettings nll;
+ std::copy_n(c->begin(), RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS,
+ nll.coeffs.begin());
+ nll.scaleMode = (config_.nll.scale_mode ==
+ RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC)
+ ? 1
+ : 0;
+ overrides_.nll = nll;
+ }
+ }
+ if (const auto &c = controls.get(controls::rkisp1::DpfNoiseLevelLookupScaleMode); c) {
+ if (overrides_.nll) {
+ overrides_.nll->scaleMode = *c ? 1 : 0;
+ } else {
+ DpfNllSettings nll;
+ std::copy_n(std::begin(config_.nll.coeff),
+ RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS,
+ nll.coeffs.begin());
+ nll.scaleMode = *c ? 1 : 0;
+ overrides_.nll = nll;
+ }
+ }
+}
+
/**
* \copydoc libcamera::ipa::Algorithm::queueRequest
*/
@@ -35,6 +35,20 @@ private:
struct rkisp1_cif_isp_dpf_strength_config strengthConfig_;
struct rkisp1_cif_isp_dpf_config baseConfig_;
struct rkisp1_cif_isp_dpf_strength_config baseStrengthConfig_;
+ struct DpfStrengthSettings {
+ uint16_t r, g, b;
+ };
+ struct DpfSpatialGreenSettings {
+ std::array<uint8_t, RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS> coeffs;
+ };
+ struct DpfSpatialRbSettings {
+ std::array<uint8_t, RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS> coeffs;
+ uint8_t size; /* 0=9x9, 1=13x9 */
+ };
+ struct DpfNllSettings {
+ std::array<uint16_t, RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS> coeffs;
+ uint8_t scaleMode; /* 0 linear, 1 log */
+ };
struct ExposureIndexLevelConfig {
uint32_t maxExposureIndex; /* inclusive upper bound */
struct rkisp1_cif_isp_dpf_config dpf;
@@ -45,6 +59,14 @@ private:
struct rkisp1_cif_isp_dpf_config dpf;
struct rkisp1_cif_isp_dpf_strength_config strength;
};
+ struct Overrides {
+ std::optional<DpfStrengthSettings> strength;
+ std::optional<DpfSpatialGreenSettings> spatialGreen;
+ std::optional<DpfSpatialRbSettings> spatialRb;
+ std::optional<uint8_t> rbSize;
+ std::optional<DpfNllSettings> nll;
+ void clear() { *this = Overrides{}; }
+ } overrides_;
std::vector<ExposureIndexLevelConfig> exposureIndexLevels_;
std::vector<ModeConfig> modes_;
@@ -56,6 +78,7 @@ private:
IPAContext &context,
uint32_t frame) override;
void loadReductionModeConfig(IPAFrameContext &frameContext);
+ void collectManualOverrides(const ControlList &controls) override;
bool parseConfig(const YamlObject &tuningData) override;
bool parseSingleConfig(const YamlObject &tuningData,
rkisp1_cif_isp_dpf_config &config,
@@ -70,4 +70,75 @@ controls:
value: 3
description: |
Reduction mode - uses predefined noise reduction settings from tuning data.
+
+ - DpfChannelStrengths:
+ type: int32_t
+ direction: inout
+ description: |
+ Override filter strength for R,G,B channels. Values map to hardware
+ strength registers (0..255 typical). Size must be exactly 3 when set.
+ Order: R,G,B. If unset the tuning / exposure index level derived strengths apply.
+ size: [3]
+
+ - DpfGreenSpatialCoefficients:
+ type: int32_t
+ direction: inout
+ description: |
+ Override 9x9 green spatial kernel coefficients (6 values). Order must
+ follow tuning file convention. Each value 0..63 typical. All 6 required
+ when provided; otherwise ignored.
+ size: [6]
+
+ - DpfRedBlueSpatialCoefficients:
+ type: int32_t
+ direction: inout
+ description: |
+ Override Red/Blue spatial kernel coefficients (6 values). Applies to
+ either 9x9 or 13x9 depending on DpfRbFilterSize. For 9x9 the last
+ column pair is dropped in hardware. Values 0..63 typical.
+ size: [6]
+
+ - DpfRbFilterSize:
+ type: int32_t
+ direction: inout
+ description: |
+ Override RB spatial filter size selection.
+ enum:
+ - name: DpfRbFilterSize9x9
+ value: 0
+ description: Use 9x9 RB domain filter.
+ - name: DpfRbFilterSize13x9
+ value: 1
+ description: Use 13x9 RB domain filter (if coefficients valid).
+
+ - DpfNoiseLevelLookupCoefficients:
+ type: int32_t
+ direction: inout
+ description: |
+ Override Noise Level Lookup (NLL) piecewise-linear coefficients
+ (17 values). Must supply full set when used or override is ignored.
+ size: [17]
+
+ - DpfNoiseLevelLookupScaleMode:
+ type: int32_t
+ direction: inout
+ description: |
+ Override NLL scale mode (0=linear,1=logarithmic). Matches hardware
+ RKISP1_CIF_ISP_NLL_SCALE_* constants.
+ enum:
+ - name: DpfNoiseLevelLookupScaleLinear
+ value: 0
+ description: Linear scale.
+ - name: DpfNoiseLevelLookupScaleLogarithmic
+ value: 1
+ description: Logarithmic scale.
+
+ - ExposureGainIndex:
+ type: int32_t
+ direction: out
+ description: |
+ Estimated scene exposure gain index used for Denoise tuning selection. Derived
+ from analogue gain (approx index = gain * 100). Provided each frame
+ for client awareness and debugging. Range 0..409600.
+
...
Implement collectManualOverrides() to capture strength and developer-mode override arrays from control requests. Extend queueRequest() to collect overrides in manual mode and mark frames dirty when strength values differ from the active configuration. Developer mode controls (spatial coefficients, filter size, NLL tables) are only collected when devmode is enabled. The function populates the overrides_ structure which will be applied during prepare(). Signed-off-by: Rui Wang <rui.wang@ideasonboard.com> --- src/ipa/rkisp1/algorithms/denoise.h | 5 +- src/ipa/rkisp1/algorithms/dpf.cpp | 66 +++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/dpf.h | 23 +++++++++ src/libcamera/control_ids_rkisp1.yaml | 71 +++++++++++++++++++++++++++ 4 files changed, 164 insertions(+), 1 deletion(-)