ipa: mali-c55: Add BLC Algorithm
Add a Black Level Correction algorithm. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Acked-by: Nayden Kanchev <nayden.kanchev@arm.com> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
This commit is contained in:
parent
e8cae247e8
commit
fbea6a4c02
5 changed files with 194 additions and 0 deletions
140
src/ipa/mali-c55/algorithms/blc.cpp
Normal file
140
src/ipa/mali-c55/algorithms/blc.cpp
Normal file
|
@ -0,0 +1,140 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2024, Ideas On Board
|
||||
*
|
||||
* Mali-C55 sensor offset (black level) correction
|
||||
*/
|
||||
|
||||
#include "blc.h"
|
||||
|
||||
#include <libcamera/base/log.h>
|
||||
#include <libcamera/control_ids.h>
|
||||
|
||||
#include "libcamera/internal/yaml_parser.h"
|
||||
|
||||
/**
|
||||
* \file blc.h
|
||||
*/
|
||||
|
||||
namespace libcamera {
|
||||
|
||||
namespace ipa::mali_c55::algorithms {
|
||||
|
||||
/**
|
||||
* \class BlackLevelCorrection
|
||||
* \brief MaliC55 Black Level Correction control
|
||||
*/
|
||||
|
||||
LOG_DEFINE_CATEGORY(MaliC55Blc)
|
||||
|
||||
BlackLevelCorrection::BlackLevelCorrection()
|
||||
: tuningParameters_(false)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* \copydoc libcamera::ipa::Algorithm::init
|
||||
*/
|
||||
int BlackLevelCorrection::init([[maybe_unused]] IPAContext &context,
|
||||
const YamlObject &tuningData)
|
||||
{
|
||||
offset00 = tuningData["offset00"].get<uint32_t>(0);
|
||||
offset01 = tuningData["offset01"].get<uint32_t>(0);
|
||||
offset10 = tuningData["offset10"].get<uint32_t>(0);
|
||||
offset11 = tuningData["offset11"].get<uint32_t>(0);
|
||||
|
||||
if (offset00 > kMaxOffset || offset01 > kMaxOffset ||
|
||||
offset10 > kMaxOffset || offset11 > kMaxOffset) {
|
||||
LOG(MaliC55Blc, Error) << "Invalid black level offsets";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tuningParameters_ = true;
|
||||
|
||||
LOG(MaliC55Blc, Debug)
|
||||
<< "Black levels: 00 " << offset00 << ", 01 " << offset01
|
||||
<< ", 10 " << offset10 << ", 11 " << offset11;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \copydoc libcamera::ipa::Algorithm::configure
|
||||
*/
|
||||
int BlackLevelCorrection::configure(IPAContext &context,
|
||||
[[maybe_unused]] const IPACameraSensorInfo &configInfo)
|
||||
{
|
||||
/*
|
||||
* If no Black Levels were passed in through tuning data then we could
|
||||
* use the value from the CameraSensorHelper if one is available.
|
||||
*/
|
||||
if (context.configuration.sensor.blackLevel &&
|
||||
!(offset00 + offset01 + offset10 + offset11)) {
|
||||
offset00 = context.configuration.sensor.blackLevel;
|
||||
offset01 = context.configuration.sensor.blackLevel;
|
||||
offset10 = context.configuration.sensor.blackLevel;
|
||||
offset11 = context.configuration.sensor.blackLevel;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \copydoc libcamera::ipa::Algorithm::prepare
|
||||
*/
|
||||
void BlackLevelCorrection::prepare([[maybe_unused]] IPAContext &context,
|
||||
const uint32_t frame,
|
||||
[[maybe_unused]] IPAFrameContext &frameContext,
|
||||
mali_c55_params_buffer *params)
|
||||
{
|
||||
mali_c55_params_block block;
|
||||
block.data = ¶ms->data[params->total_size];
|
||||
|
||||
if (frame > 0)
|
||||
return;
|
||||
|
||||
if (!tuningParameters_)
|
||||
return;
|
||||
|
||||
block.header->type = MALI_C55_PARAM_BLOCK_SENSOR_OFFS;
|
||||
block.header->flags = MALI_C55_PARAM_BLOCK_FL_NONE;
|
||||
block.header->size = sizeof(mali_c55_params_sensor_off_preshading);
|
||||
|
||||
block.sensor_offs->chan00 = offset00;
|
||||
block.sensor_offs->chan01 = offset01;
|
||||
block.sensor_offs->chan10 = offset10;
|
||||
block.sensor_offs->chan11 = offset11;
|
||||
|
||||
params->total_size += block.header->size;
|
||||
}
|
||||
|
||||
void BlackLevelCorrection::process([[maybe_unused]] IPAContext &context,
|
||||
[[maybe_unused]] const uint32_t frame,
|
||||
[[maybe_unused]] IPAFrameContext &frameContext,
|
||||
[[maybe_unused]] const mali_c55_stats_buffer *stats,
|
||||
ControlList &metadata)
|
||||
{
|
||||
/*
|
||||
* Black Level Offsets in tuning data need to be 20-bit, whereas the
|
||||
* metadata expects values from a 16-bit range. Right-shift to remove
|
||||
* the 4 least significant bits.
|
||||
*
|
||||
* The black levels should be reported in the order R, Gr, Gb, B. We
|
||||
* ignore that here given we're using matching values so far, but it
|
||||
* would be safer to check the sensor's bayer order.
|
||||
*
|
||||
* \todo Account for bayer order.
|
||||
*/
|
||||
metadata.set(controls::SensorBlackLevels, {
|
||||
static_cast<int32_t>(offset00 >> 4),
|
||||
static_cast<int32_t>(offset01 >> 4),
|
||||
static_cast<int32_t>(offset10 >> 4),
|
||||
static_cast<int32_t>(offset11 >> 4),
|
||||
});
|
||||
}
|
||||
|
||||
REGISTER_IPA_ALGORITHM(BlackLevelCorrection, "BlackLevelCorrection")
|
||||
|
||||
} /* namespace ipa::mali_c55::algorithms */
|
||||
|
||||
} /* namespace libcamera */
|
42
src/ipa/mali-c55/algorithms/blc.h
Normal file
42
src/ipa/mali-c55/algorithms/blc.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2024, Ideas On Board
|
||||
*
|
||||
* Mali-C55 sensor offset (black level) correction
|
||||
*/
|
||||
|
||||
#include "algorithm.h"
|
||||
|
||||
namespace libcamera {
|
||||
|
||||
namespace ipa::mali_c55::algorithms {
|
||||
|
||||
class BlackLevelCorrection : public Algorithm
|
||||
{
|
||||
public:
|
||||
BlackLevelCorrection();
|
||||
~BlackLevelCorrection() = default;
|
||||
|
||||
int init(IPAContext &context, const YamlObject &tuningData) override;
|
||||
int configure(IPAContext &context,
|
||||
const IPACameraSensorInfo &configInfo) override;
|
||||
void prepare(IPAContext &context, const uint32_t frame,
|
||||
IPAFrameContext &frameContext,
|
||||
mali_c55_params_buffer *params) override;
|
||||
void process(IPAContext &context, const uint32_t frame,
|
||||
IPAFrameContext &frameContext,
|
||||
const mali_c55_stats_buffer *stats,
|
||||
ControlList &metadata) override;
|
||||
|
||||
private:
|
||||
static constexpr uint32_t kMaxOffset = 0xfffff;
|
||||
|
||||
bool tuningParameters_;
|
||||
uint32_t offset00;
|
||||
uint32_t offset01;
|
||||
uint32_t offset10;
|
||||
uint32_t offset11;
|
||||
};
|
||||
|
||||
} /* namespace ipa::mali_c55::algorithms */
|
||||
} /* namespace libcamera */
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
mali_c55_ipa_algorithms = files([
|
||||
'agc.cpp',
|
||||
'blc.cpp',
|
||||
])
|
||||
|
|
|
@ -30,6 +30,7 @@ struct IPASessionConfiguration {
|
|||
struct {
|
||||
BayerFormat::Order bayerOrder;
|
||||
utils::Duration lineDuration;
|
||||
uint32_t blackLevel;
|
||||
} sensor;
|
||||
};
|
||||
|
||||
|
|
|
@ -193,6 +193,16 @@ void IPAMaliC55::updateSessionConfiguration(const IPACameraSensorInfo &info,
|
|||
context_.configuration.agc.defaultExposure = defExposure;
|
||||
context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain);
|
||||
context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain);
|
||||
|
||||
if (camHelper_->blackLevel().has_value()) {
|
||||
/*
|
||||
* The black level from CameraSensorHelper is a 16-bit value.
|
||||
* The Mali-C55 ISP expects 20-bit settings, so we shift it to
|
||||
* the appropriate width
|
||||
*/
|
||||
context_.configuration.sensor.blackLevel =
|
||||
camHelper_->blackLevel().value() << 4;
|
||||
}
|
||||
}
|
||||
|
||||
void IPAMaliC55::updateControls(const IPACameraSensorInfo &sensorInfo,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue