@@ -38,6 +38,7 @@ protected:
int selectIsoBand(unsigned iso, const LevelContainer &levels) const;
virtual bool parseConfig(const YamlObject &tuningData) = 0;
virtual void handleEnableControl(const ControlList &controls, IPAFrameContext &frameContext, IPAContext &context) = 0;
+ virtual void collectManualOverrides(const ControlList &controls) = 0;
private:
bool manualMode_ = false; /**< Current manual/auto mode state */
@@ -243,6 +243,53 @@ void Dpf::handleEnableControl(const ControlList &controls, IPAFrameContext &fram
frameContext.dpf.denoise = enableDpf_;
}
+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()) {
+ 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
*/
@@ -253,6 +300,17 @@ void Dpf::queueRequest(IPAContext &context,
{
frameContext.dpf.update = false;
handleEnableControl(controls, frameContext, context);
+
+ if (isManualMode()) {
+ collectManualOverrides(controls);
+ // Check if manual overrides have changed and trigger update
+ if (overrides_.strength &&
+ (overrides_.strength->r != strengthConfig_.r ||
+ overrides_.strength->g != strengthConfig_.g ||
+ overrides_.strength->b != strengthConfig_.b)) {
+ frameContext.dpf.update = true;
+ }
+ }
}
/**
@@ -34,23 +34,53 @@ public:
private:
struct rkisp1_cif_isp_dpf_config config_ {
};
+
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 IsoLevelConfig {
unsigned int maxIso; /* inclusive upper bound */
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<IsoLevelConfig> isoLevels_;
bool useIsoLevels_ = false;
bool enableDpf_ = true; /* YAML master enable */
void handleEnableControl(const ControlList &controls, IPAFrameContext &frameContext, IPAContext &context) override;
+ void collectManualOverrides(const ControlList &controls) override;
bool parseConfig(const YamlObject &tuningData) override;
bool parseSingleConfig(const YamlObject &config,
rkisp1_cif_isp_dpf_config &cfg,
@@ -21,4 +21,66 @@ controls:
Reported in metadata as a boolean.
+ - 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 / ISO 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.
+
...
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 | 1 + src/ipa/rkisp1/algorithms/dpf.cpp | 58 +++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/dpf.h | 30 +++++++++++++ src/libcamera/control_ids_rkisp1.yaml | 62 +++++++++++++++++++++++++++ 4 files changed, 151 insertions(+)