pipeline: rkisp1: Query kernel for available params blocks

Query the params device for RKISP1_CID_SUPPORTED_PARAMS_BLOCKS and
inject the information into the IPA hardware context for use by the
algorithms.

To be able to modify the hardware configuration at runtime, replace the
pointer with an instance and create a copy of the static hardware
specific data.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Stefan Klug
2025-09-19 11:40:29 +02:00
committed by Kieran Bingham
parent c8f323b7ae
commit c7cc1f7f0d
9 changed files with 49 additions and 21 deletions

View File

@@ -16,7 +16,7 @@ struct IPAConfigInfo {
interface IPARkISP1Interface {
init(libcamera.IPASettings settings,
uint32 hwRevision,
uint32 hwRevision, uint32 supportedBlocks,
libcamera.IPACameraSensorInfo sensorInfo,
libcamera.ControlInfoMap sensorControls)
=> (int32 ret, libcamera.ControlInfoMap ipaControls);

View File

@@ -56,7 +56,7 @@ int Agc::parseMeteringModes(IPAContext &context, const YamlObject &tuningData)
std::vector<uint8_t> weights =
value.getList<uint8_t>().value_or(std::vector<uint8_t>{});
if (weights.size() != context.hw->numHistogramWeights) {
if (weights.size() != context.hw.numHistogramWeights) {
LOG(RkISP1Agc, Warning)
<< "Failed to read metering mode'" << key << "'";
continue;
@@ -68,7 +68,7 @@ int Agc::parseMeteringModes(IPAContext &context, const YamlObject &tuningData)
if (meteringModes_.empty()) {
LOG(RkISP1Agc, Warning)
<< "No metering modes read from tuning file; defaulting to matrix";
std::vector<uint8_t> weights(context.hw->numHistogramWeights, 1);
std::vector<uint8_t> weights(context.hw.numHistogramWeights, 1);
meteringModes_[controls::MeteringMatrix] = weights;
}
@@ -418,7 +418,7 @@ void Agc::prepare(IPAContext &context, const uint32_t frame,
Span<uint8_t> weights{
hstConfig->hist_weight,
context.hw->numHistogramWeights
context.hw.numHistogramWeights
};
std::vector<uint8_t> &modeWeights = meteringModes_.at(frameContext.agc.meteringMode);
std::copy(modeWeights.begin(), modeWeights.end(), weights.begin());
@@ -556,9 +556,9 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
const rkisp1_cif_isp_stat *params = &stats->params;
/* The lower 4 bits are fractional and meant to be discarded. */
Histogram hist({ params->hist.hist_bins, context.hw->numHistogramBins },
Histogram hist({ params->hist.hist_bins, context.hw.numHistogramBins },
[](uint32_t x) { return x >> 4; });
expMeans_ = { params->ae.exp_mean, context.hw->numAeCells };
expMeans_ = { params->ae.exp_mean, context.hw.numAeCells };
std::vector<uint8_t> &modeWeights = meteringModes_.at(frameContext.agc.meteringMode);
weights_ = { modeWeights.data(), modeWeights.size() };

View File

@@ -114,7 +114,7 @@ int BlackLevelCorrection::configure(IPAContext &context,
* of the extensible parameters format.
*/
supported_ = context.configuration.paramFormat == V4L2_META_FMT_RK_ISP1_EXT_PARAMS ||
!context.hw->compand;
!context.hw.compand;
if (!supported_)
LOG(RkISP1Blc, Warning)
@@ -140,7 +140,7 @@ void BlackLevelCorrection::prepare(IPAContext &context,
if (!supported_)
return;
if (context.hw->compand) {
if (context.hw.compand) {
auto config = params->block<BlockType::CompandBls>();
config.setEnabled(true);

View File

@@ -51,7 +51,7 @@ int Compress::configure(IPAContext &context,
[[maybe_unused]] const IPACameraSensorInfo &configInfo)
{
if (context.configuration.paramFormat != V4L2_META_FMT_RK_ISP1_EXT_PARAMS ||
!context.hw->compand) {
!context.hw.compand) {
LOG(RkISP1Compress, Warning)
<< "Compression is not supported by the hardware or kernel.";
return 0;

View File

@@ -50,7 +50,7 @@ const float kDefaultGamma = 2.2f;
*/
int GammaOutCorrection::init(IPAContext &context, const YamlObject &tuningData)
{
if (context.hw->numGammaOutSamples !=
if (context.hw.numGammaOutSamples !=
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10) {
LOG(RkISP1Gamma, Error)
<< "Gamma is not implemented for RkISP1 V12";
@@ -101,7 +101,7 @@ void GammaOutCorrection::prepare(IPAContext &context,
IPAFrameContext &frameContext,
RkISP1Params *params)
{
ASSERT(context.hw->numGammaOutSamples ==
ASSERT(context.hw.numGammaOutSamples ==
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10);
if (!frameContext.goc.update)

View File

@@ -61,7 +61,7 @@ void Lux::process(IPAContext &context,
/* \todo Deduplicate the histogram calculation from AGC */
const rkisp1_cif_isp_stat *params = &stats->params;
Histogram yHist({ params->hist.hist_bins, context.hw->numHistogramBins },
Histogram yHist({ params->hist.hist_bins, context.hw.numHistogramBins },
[](uint32_t x) { return x >> 4; });
double lux = lux_.estimateLux(exposureTime, gain, 1.0, yHist);

View File

@@ -36,6 +36,7 @@ struct IPAHwSettings {
unsigned int numHistogramBins;
unsigned int numHistogramWeights;
unsigned int numGammaOutSamples;
uint32_t supportedBlocks;
bool compand;
};
@@ -201,11 +202,11 @@ struct IPAFrameContext : public FrameContext {
struct IPAContext {
IPAContext(unsigned int frameContextSize)
: hw(nullptr), frameContexts(frameContextSize)
: frameContexts(frameContextSize)
{
}
const IPAHwSettings *hw;
IPAHwSettings hw;
IPACameraSensorInfo sensorInfo;
IPASessionConfiguration configuration;
IPAActiveState activeState;

View File

@@ -52,6 +52,7 @@ public:
IPARkISP1();
int init(const IPASettings &settings, unsigned int hwRevision,
uint32_t supportedBlocks,
const IPACameraSensorInfo &sensorInfo,
const ControlInfoMap &sensorControls,
ControlInfoMap *ipaControls) override;
@@ -94,6 +95,7 @@ const IPAHwSettings ipaHwSettingsV10{
RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10,
RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10,
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10,
0,
false,
};
@@ -102,6 +104,7 @@ const IPAHwSettings ipaHwSettingsIMX8MP{
RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10,
RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10,
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10,
0,
true,
};
@@ -110,6 +113,7 @@ const IPAHwSettings ipaHwSettingsV12{
RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12,
RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12,
RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12,
0,
false,
};
@@ -132,6 +136,7 @@ std::string IPARkISP1::logPrefix() const
}
int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
uint32_t supportedBlocks,
const IPACameraSensorInfo &sensorInfo,
const ControlInfoMap &sensorControls,
ControlInfoMap *ipaControls)
@@ -139,13 +144,13 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
/* \todo Add support for other revisions */
switch (hwRevision) {
case RKISP1_V10:
context_.hw = &ipaHwSettingsV10;
context_.hw = ipaHwSettingsV10;
break;
case RKISP1_V_IMX8MP:
context_.hw = &ipaHwSettingsIMX8MP;
context_.hw = ipaHwSettingsIMX8MP;
break;
case RKISP1_V12:
context_.hw = &ipaHwSettingsV12;
context_.hw = ipaHwSettingsV12;
break;
default:
LOG(IPARkISP1, Error)
@@ -153,6 +158,7 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
<< " is currently not supported";
return -ENODEV;
}
context_.hw.supportedBlocks = supportedBlocks;
LOG(IPARkISP1, Debug) << "Hardware revision is " << hwRevision;

View File

@@ -100,7 +100,7 @@ public:
PipelineHandlerRkISP1 *pipe();
const PipelineHandlerRkISP1 *pipe() const;
int loadIPA(unsigned int hwRevision);
int loadIPA(unsigned int hwRevision, uint32_t supportedBlocks);
Stream mainPathStream_;
Stream selfPathStream_;
@@ -383,7 +383,7 @@ const PipelineHandlerRkISP1 *RkISP1CameraData::pipe() const
return static_cast<const PipelineHandlerRkISP1 *>(Camera::Private::pipe());
}
int RkISP1CameraData::loadIPA(unsigned int hwRevision)
int RkISP1CameraData::loadIPA(unsigned int hwRevision, uint32_t supportedBlocks)
{
ipa_ = IPAManager::createIPA<ipa::rkisp1::IPAProxyRkISP1>(pipe(), 1, 1);
if (!ipa_)
@@ -405,7 +405,8 @@ int RkISP1CameraData::loadIPA(unsigned int hwRevision)
}
ret = ipa_->init({ ipaTuningFile, sensor_->model() }, hwRevision,
sensorInfo, sensor_->controls(), &ipaControls_);
supportedBlocks, sensorInfo, sensor_->controls(),
&ipaControls_);
if (ret < 0) {
LOG(RkISP1, Error) << "IPA initialization failure";
return ret;
@@ -1313,6 +1314,12 @@ int PipelineHandlerRkISP1::updateControls(RkISP1CameraData *data)
return 0;
}
/*
* By default we assume all the blocks that were included in the first
* extensible parameters series are available. That is the lower 20bits.
*/
const uint32_t kDefaultExtParamsBlocks = 0xfffff;
int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
{
int ret;
@@ -1350,7 +1357,21 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
isp_->frameStart.connect(data->delayedCtrls_.get(),
&DelayedControls::applyControls);
ret = data->loadIPA(media_->hwRevision());
uint32_t supportedBlocks = kDefaultExtParamsBlocks;
auto &controls = param_->controls();
if (controls.find(RKISP1_CID_SUPPORTED_PARAMS_BLOCKS) != controls.end()) {
auto list = param_->getControls({ { RKISP1_CID_SUPPORTED_PARAMS_BLOCKS } });
if (!list.empty())
supportedBlocks = static_cast<uint32_t>(
list.get(RKISP1_CID_SUPPORTED_PARAMS_BLOCKS)
.get<int32_t>());
} else {
LOG(RkISP1, Error)
<< "Failed to query supported params blocks. Falling back to defaults.";
}
ret = data->loadIPA(media_->hwRevision(), supportedBlocks);
if (ret)
return ret;