ipa: rkisp1: Add support for manual gain and exposure
Add support for manual gain and exposure in the rkisp1 IPA. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
This commit is contained in:
parent
947b8627f9
commit
4cf3c96493
4 changed files with 96 additions and 9 deletions
|
@ -74,9 +74,14 @@ Agc::Agc()
|
||||||
int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
|
int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
|
||||||
{
|
{
|
||||||
/* Configure the default exposure and gain. */
|
/* Configure the default exposure and gain. */
|
||||||
context.activeState.agc.gain = std::max(context.configuration.sensor.minAnalogueGain,
|
context.activeState.agc.automatic.gain =
|
||||||
|
std::max(context.configuration.sensor.minAnalogueGain,
|
||||||
kMinAnalogueGain);
|
kMinAnalogueGain);
|
||||||
context.activeState.agc.exposure = 10ms / context.configuration.sensor.lineDuration;
|
context.activeState.agc.automatic.exposure =
|
||||||
|
10ms / context.configuration.sensor.lineDuration;
|
||||||
|
context.activeState.agc.manual.gain = context.activeState.agc.automatic.gain;
|
||||||
|
context.activeState.agc.manual.exposure = context.activeState.agc.automatic.exposure;
|
||||||
|
context.activeState.agc.autoEnabled = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* According to the RkISP1 documentation:
|
* According to the RkISP1 documentation:
|
||||||
|
@ -108,14 +113,58 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \copydoc libcamera::ipa::Algorithm::queueRequest
|
||||||
|
*/
|
||||||
|
void Agc::queueRequest(IPAContext &context,
|
||||||
|
[[maybe_unused]] const uint32_t frame,
|
||||||
|
IPAFrameContext &frameContext,
|
||||||
|
const ControlList &controls)
|
||||||
|
{
|
||||||
|
auto &agc = context.activeState.agc;
|
||||||
|
|
||||||
|
const auto &agcEnable = controls.get(controls::AeEnable);
|
||||||
|
if (agcEnable && *agcEnable != agc.autoEnabled) {
|
||||||
|
agc.autoEnabled = *agcEnable;
|
||||||
|
|
||||||
|
LOG(RkISP1Agc, Debug)
|
||||||
|
<< (agc.autoEnabled ? "Enabling" : "Disabling") << " AGC";
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &exposure = controls.get(controls::ExposureTime);
|
||||||
|
if (exposure && !agc.autoEnabled) {
|
||||||
|
agc.manual.exposure = *exposure * 1.0us
|
||||||
|
/ context.configuration.sensor.lineDuration;
|
||||||
|
|
||||||
|
LOG(RkISP1Agc, Debug)
|
||||||
|
<< "Set exposure to " << agc.manual.exposure;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &gain = controls.get(controls::AnalogueGain);
|
||||||
|
if (gain && !agc.autoEnabled) {
|
||||||
|
agc.manual.gain = *gain;
|
||||||
|
|
||||||
|
LOG(RkISP1Agc, Debug) << "Set gain to " << agc.manual.gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
frameContext.agc.autoEnabled = agc.autoEnabled;
|
||||||
|
|
||||||
|
if (!frameContext.agc.autoEnabled) {
|
||||||
|
frameContext.agc.exposure = agc.manual.exposure;
|
||||||
|
frameContext.agc.gain = agc.manual.gain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \copydoc libcamera::ipa::Algorithm::prepare
|
* \copydoc libcamera::ipa::Algorithm::prepare
|
||||||
*/
|
*/
|
||||||
void Agc::prepare(IPAContext &context, const uint32_t frame,
|
void Agc::prepare(IPAContext &context, const uint32_t frame,
|
||||||
IPAFrameContext &frameContext, rkisp1_params_cfg *params)
|
IPAFrameContext &frameContext, rkisp1_params_cfg *params)
|
||||||
{
|
{
|
||||||
frameContext.agc.exposure = context.activeState.agc.exposure;
|
if (frameContext.agc.autoEnabled) {
|
||||||
frameContext.agc.gain = context.activeState.agc.gain;
|
frameContext.agc.exposure = context.activeState.agc.automatic.exposure;
|
||||||
|
frameContext.agc.gain = context.activeState.agc.automatic.gain;
|
||||||
|
}
|
||||||
|
|
||||||
if (frame > 0)
|
if (frame > 0)
|
||||||
return;
|
return;
|
||||||
|
@ -263,8 +312,8 @@ void Agc::computeExposure(IPAContext &context, IPAFrameContext &frameContext,
|
||||||
<< stepGain;
|
<< stepGain;
|
||||||
|
|
||||||
/* Update the estimated exposure and gain. */
|
/* Update the estimated exposure and gain. */
|
||||||
activeState.agc.exposure = shutterTime / configuration.sensor.lineDuration;
|
activeState.agc.automatic.exposure = shutterTime / configuration.sensor.lineDuration;
|
||||||
activeState.agc.gain = stepGain;
|
activeState.agc.automatic.gain = stepGain;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -26,6 +26,10 @@ public:
|
||||||
~Agc() = default;
|
~Agc() = default;
|
||||||
|
|
||||||
int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;
|
int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;
|
||||||
|
void queueRequest(IPAContext &context,
|
||||||
|
const uint32_t frame,
|
||||||
|
IPAFrameContext &frameContext,
|
||||||
|
const ControlList &controls) override;
|
||||||
void prepare(IPAContext &context, const uint32_t frame,
|
void prepare(IPAContext &context, const uint32_t frame,
|
||||||
IPAFrameContext &frameContext,
|
IPAFrameContext &frameContext,
|
||||||
rkisp1_params_cfg *params) override;
|
rkisp1_params_cfg *params) override;
|
||||||
|
|
|
@ -53,9 +53,17 @@ struct IPASessionConfiguration {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IPAActiveState {
|
struct IPAActiveState {
|
||||||
|
struct {
|
||||||
struct {
|
struct {
|
||||||
uint32_t exposure;
|
uint32_t exposure;
|
||||||
double gain;
|
double gain;
|
||||||
|
} manual;
|
||||||
|
struct {
|
||||||
|
uint32_t exposure;
|
||||||
|
double gain;
|
||||||
|
} automatic;
|
||||||
|
|
||||||
|
bool autoEnabled;
|
||||||
} agc;
|
} agc;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -96,6 +104,7 @@ struct IPAFrameContext : public FrameContext {
|
||||||
struct {
|
struct {
|
||||||
uint32_t exposure;
|
uint32_t exposure;
|
||||||
double gain;
|
double gain;
|
||||||
|
bool autoEnabled;
|
||||||
} agc;
|
} agc;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -157,6 +157,9 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context_.configuration.sensor.lineDuration = sensorInfo.minLineLength
|
||||||
|
* 1.0s / sensorInfo.pixelRate;
|
||||||
|
|
||||||
/* Load the tuning data file. */
|
/* Load the tuning data file. */
|
||||||
File file(settings.configurationFile);
|
File file(settings.configurationFile);
|
||||||
if (!file.open(File::OpenModeFlag::ReadOnly)) {
|
if (!file.open(File::OpenModeFlag::ReadOnly)) {
|
||||||
|
@ -376,6 +379,28 @@ void IPARkISP1::updateControls(const IPACameraSensorInfo &sensorInfo,
|
||||||
{
|
{
|
||||||
ControlInfoMap::Map ctrlMap = rkisp1Controls;
|
ControlInfoMap::Map ctrlMap = rkisp1Controls;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute exposure time limits from the V4L2_CID_EXPOSURE control
|
||||||
|
* limits and the line duration.
|
||||||
|
*/
|
||||||
|
double lineDuration = context_.configuration.sensor.lineDuration.get<std::micro>();
|
||||||
|
const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;
|
||||||
|
int32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration;
|
||||||
|
int32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration;
|
||||||
|
int32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration;
|
||||||
|
ctrlMap.emplace(std::piecewise_construct,
|
||||||
|
std::forward_as_tuple(&controls::ExposureTime),
|
||||||
|
std::forward_as_tuple(minExposure, maxExposure, defExposure));
|
||||||
|
|
||||||
|
/* Compute the analogue gain limits. */
|
||||||
|
const ControlInfo &v4l2Gain = sensorControls.find(V4L2_CID_ANALOGUE_GAIN)->second;
|
||||||
|
float minGain = camHelper_->gain(v4l2Gain.min().get<int32_t>());
|
||||||
|
float maxGain = camHelper_->gain(v4l2Gain.max().get<int32_t>());
|
||||||
|
float defGain = camHelper_->gain(v4l2Gain.def().get<int32_t>());
|
||||||
|
ctrlMap.emplace(std::piecewise_construct,
|
||||||
|
std::forward_as_tuple(&controls::AnalogueGain),
|
||||||
|
std::forward_as_tuple(minGain, maxGain, defGain));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute the frame duration limits.
|
* Compute the frame duration limits.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue