Files
external_libcamera/src/ipa/rkisp1/algorithms/dpcc.cpp
T
Laurent Pinchart 9861678f23 ipa: rkisp1: Use the new ISP parameters abstraction
Use the new ISP parameters abstraction class RkISP1Params to access the
ISP parameters in the IPA algorithms. The class replaces the pointer to
the rkisp1_params_cfg structure passed to the algorithms' prepare()
function, and is used to access individual parameters blocks.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-08-27 12:28:57 +03:00

250 lines
6.6 KiB
C++

/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2021-2022, Ideas On Board
*
* RkISP1 Defect Pixel Cluster Correction control
*/
#include "dpcc.h"
#include <libcamera/base/log.h>
#include "libcamera/internal/yaml_parser.h"
#include "linux/rkisp1-config.h"
/**
* \file dpcc.h
*/
namespace libcamera {
namespace ipa::rkisp1::algorithms {
/**
* \class DefectPixelClusterCorrection
* \brief RkISP1 Defect Pixel Cluster Correction control
*
* Depending of the sensor quality, some pixels can be defective and then
* appear significantly brighter or darker than the other pixels.
*
* The Defect Pixel Cluster Correction algorithms is responsible to minimize
* the impact of the pixels. This can be done with algorithms applied at run
* time (on-the-fly method) or with a table of defective pixels. Only the first
* method is supported for the moment.
*/
LOG_DEFINE_CATEGORY(RkISP1Dpcc)
DefectPixelClusterCorrection::DefectPixelClusterCorrection()
: config_({})
{
}
/**
* \copydoc libcamera::ipa::Algorithm::init
*/
int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
const YamlObject &tuningData)
{
config_.mode = RKISP1_CIF_ISP_DPCC_MODE_STAGE1_ENABLE;
config_.output_mode = RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_STAGE1_INCL_G_CENTER
| RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_STAGE1_INCL_RB_CENTER;
config_.set_use = tuningData["fixed-set"].get<bool>(false)
? RKISP1_CIF_ISP_DPCC_SET_USE_STAGE1_USE_FIX_SET : 0;
/* Get all defined sets to apply (up to 3). */
const YamlObject &setsObject = tuningData["sets"];
if (!setsObject.isList()) {
LOG(RkISP1Dpcc, Error)
<< "'sets' parameter not found in tuning file";
return -EINVAL;
}
if (setsObject.size() > RKISP1_CIF_ISP_DPCC_METHODS_MAX) {
LOG(RkISP1Dpcc, Error)
<< "'sets' size in tuning file (" << setsObject.size()
<< ") exceeds the maximum hardware capacity (3)";
return -EINVAL;
}
for (std::size_t i = 0; i < setsObject.size(); ++i) {
struct rkisp1_cif_isp_dpcc_methods_config &method = config_.methods[i];
const YamlObject &set = setsObject[i];
uint16_t value;
/* Enable set if described in YAML tuning file. */
config_.set_use |= 1 << i;
/* PG Method */
const YamlObject &pgObject = set["pg-factor"];
if (pgObject.contains("green")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_GREEN_ENABLE;
value = pgObject["green"].get<uint16_t>(0);
method.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_G(value);
}
if (pgObject.contains("red-blue")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_RED_BLUE_ENABLE;
value = pgObject["red-blue"].get<uint16_t>(0);
method.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_RB(value);
}
/* RO Method */
const YamlObject &roObject = set["ro-limits"];
if (roObject.contains("green")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_GREEN_ENABLE;
value = roObject["green"].get<uint16_t>(0);
config_.ro_limits |=
RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_G(i, value);
}
if (roObject.contains("red-blue")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_RED_BLUE_ENABLE;
value = roObject["red-blue"].get<uint16_t>(0);
config_.ro_limits |=
RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_RB(i, value);
}
/* RG Method */
const YamlObject &rgObject = set["rg-factor"];
method.rg_fac = 0;
if (rgObject.contains("green")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_GREEN_ENABLE;
value = rgObject["green"].get<uint16_t>(0);
method.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_G(value);
}
if (rgObject.contains("red-blue")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_RED_BLUE_ENABLE;
value = rgObject["red-blue"].get<uint16_t>(0);
method.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_RB(value);
}
/* RND Method */
const YamlObject &rndOffsetsObject = set["rnd-offsets"];
if (rndOffsetsObject.contains("green")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
value = rndOffsetsObject["green"].get<uint16_t>(0);
config_.rnd_offs |=
RKISP1_CIF_ISP_DPCC_RND_OFFS_n_G(i, value);
}
if (rndOffsetsObject.contains("red-blue")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
value = rndOffsetsObject["red-blue"].get<uint16_t>(0);
config_.rnd_offs |=
RKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(i, value);
}
const YamlObject &rndThresholdObject = set["rnd-threshold"];
method.rnd_thresh = 0;
if (rndThresholdObject.contains("green")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
value = rndThresholdObject["green"].get<uint16_t>(0);
method.rnd_thresh |=
RKISP1_CIF_ISP_DPCC_RND_THRESH_G(value);
}
if (rndThresholdObject.contains("red-blue")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
value = rndThresholdObject["red-blue"].get<uint16_t>(0);
method.rnd_thresh |=
RKISP1_CIF_ISP_DPCC_RND_THRESH_RB(value);
}
/* LC Method */
const YamlObject &lcThresholdObject = set["line-threshold"];
method.line_thresh = 0;
if (lcThresholdObject.contains("green")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
value = lcThresholdObject["green"].get<uint16_t>(0);
method.line_thresh |=
RKISP1_CIF_ISP_DPCC_LINE_THRESH_G(value);
}
if (lcThresholdObject.contains("red-blue")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
value = lcThresholdObject["red-blue"].get<uint16_t>(0);
method.line_thresh |=
RKISP1_CIF_ISP_DPCC_LINE_THRESH_RB(value);
}
const YamlObject &lcTMadFactorObject = set["line-mad-factor"];
method.line_mad_fac = 0;
if (lcTMadFactorObject.contains("green")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
value = lcTMadFactorObject["green"].get<uint16_t>(0);
method.line_mad_fac |=
RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_G(value);
}
if (lcTMadFactorObject.contains("red-blue")) {
method.method |=
RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
value = lcTMadFactorObject["red-blue"].get<uint16_t>(0);
method.line_mad_fac |=
RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RB(value);
}
}
return 0;
}
/**
* \copydoc libcamera::ipa::Algorithm::prepare
*/
void DefectPixelClusterCorrection::prepare([[maybe_unused]] IPAContext &context,
const uint32_t frame,
[[maybe_unused]] IPAFrameContext &frameContext,
RkISP1Params *params)
{
if (frame > 0)
return;
auto config = params->block<BlockType::Dpcc>();
config.setEnabled(true);
*config = config_;
}
REGISTER_IPA_ALGORITHM(DefectPixelClusterCorrection, "DefectPixelClusterCorrection")
} /* namespace ipa::rkisp1::algorithms */
} /* namespace libcamera */