Skip to content

Commit 4cf3c96

Browse files
Rahi374pinchartl
authored andcommitted
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 <[email protected]> Reviewed-by: Laurent Pinchart <[email protected]> Reviewed-by: Jacopo Mondi <[email protected]> Signed-off-by: Laurent Pinchart <[email protected]> Reviewed-by: Paul Elder <[email protected]>
1 parent 947b862 commit 4cf3c96

File tree

4 files changed

+96
-9
lines changed

4 files changed

+96
-9
lines changed

src/ipa/rkisp1/algorithms/agc.cpp

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,14 @@ Agc::Agc()
7474
int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
7575
{
7676
/* Configure the default exposure and gain. */
77-
context.activeState.agc.gain = std::max(context.configuration.sensor.minAnalogueGain,
78-
kMinAnalogueGain);
79-
context.activeState.agc.exposure = 10ms / context.configuration.sensor.lineDuration;
77+
context.activeState.agc.automatic.gain =
78+
std::max(context.configuration.sensor.minAnalogueGain,
79+
kMinAnalogueGain);
80+
context.activeState.agc.automatic.exposure =
81+
10ms / context.configuration.sensor.lineDuration;
82+
context.activeState.agc.manual.gain = context.activeState.agc.automatic.gain;
83+
context.activeState.agc.manual.exposure = context.activeState.agc.automatic.exposure;
84+
context.activeState.agc.autoEnabled = true;
8085

8186
/*
8287
* According to the RkISP1 documentation:
@@ -108,14 +113,58 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
108113
return 0;
109114
}
110115

116+
/**
117+
* \copydoc libcamera::ipa::Algorithm::queueRequest
118+
*/
119+
void Agc::queueRequest(IPAContext &context,
120+
[[maybe_unused]] const uint32_t frame,
121+
IPAFrameContext &frameContext,
122+
const ControlList &controls)
123+
{
124+
auto &agc = context.activeState.agc;
125+
126+
const auto &agcEnable = controls.get(controls::AeEnable);
127+
if (agcEnable && *agcEnable != agc.autoEnabled) {
128+
agc.autoEnabled = *agcEnable;
129+
130+
LOG(RkISP1Agc, Debug)
131+
<< (agc.autoEnabled ? "Enabling" : "Disabling") << " AGC";
132+
}
133+
134+
const auto &exposure = controls.get(controls::ExposureTime);
135+
if (exposure && !agc.autoEnabled) {
136+
agc.manual.exposure = *exposure * 1.0us
137+
/ context.configuration.sensor.lineDuration;
138+
139+
LOG(RkISP1Agc, Debug)
140+
<< "Set exposure to " << agc.manual.exposure;
141+
}
142+
143+
const auto &gain = controls.get(controls::AnalogueGain);
144+
if (gain && !agc.autoEnabled) {
145+
agc.manual.gain = *gain;
146+
147+
LOG(RkISP1Agc, Debug) << "Set gain to " << agc.manual.gain;
148+
}
149+
150+
frameContext.agc.autoEnabled = agc.autoEnabled;
151+
152+
if (!frameContext.agc.autoEnabled) {
153+
frameContext.agc.exposure = agc.manual.exposure;
154+
frameContext.agc.gain = agc.manual.gain;
155+
}
156+
}
157+
111158
/**
112159
* \copydoc libcamera::ipa::Algorithm::prepare
113160
*/
114161
void Agc::prepare(IPAContext &context, const uint32_t frame,
115162
IPAFrameContext &frameContext, rkisp1_params_cfg *params)
116163
{
117-
frameContext.agc.exposure = context.activeState.agc.exposure;
118-
frameContext.agc.gain = context.activeState.agc.gain;
164+
if (frameContext.agc.autoEnabled) {
165+
frameContext.agc.exposure = context.activeState.agc.automatic.exposure;
166+
frameContext.agc.gain = context.activeState.agc.automatic.gain;
167+
}
119168

120169
if (frame > 0)
121170
return;
@@ -263,8 +312,8 @@ void Agc::computeExposure(IPAContext &context, IPAFrameContext &frameContext,
263312
<< stepGain;
264313

265314
/* Update the estimated exposure and gain. */
266-
activeState.agc.exposure = shutterTime / configuration.sensor.lineDuration;
267-
activeState.agc.gain = stepGain;
315+
activeState.agc.automatic.exposure = shutterTime / configuration.sensor.lineDuration;
316+
activeState.agc.automatic.gain = stepGain;
268317
}
269318

270319
/**

src/ipa/rkisp1/algorithms/agc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ class Agc : public Algorithm
2626
~Agc() = default;
2727

2828
int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;
29+
void queueRequest(IPAContext &context,
30+
const uint32_t frame,
31+
IPAFrameContext &frameContext,
32+
const ControlList &controls) override;
2933
void prepare(IPAContext &context, const uint32_t frame,
3034
IPAFrameContext &frameContext,
3135
rkisp1_params_cfg *params) override;

src/ipa/rkisp1/ipa_context.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,16 @@ struct IPASessionConfiguration {
5454

5555
struct IPAActiveState {
5656
struct {
57-
uint32_t exposure;
58-
double gain;
57+
struct {
58+
uint32_t exposure;
59+
double gain;
60+
} manual;
61+
struct {
62+
uint32_t exposure;
63+
double gain;
64+
} automatic;
65+
66+
bool autoEnabled;
5967
} agc;
6068

6169
struct {
@@ -96,6 +104,7 @@ struct IPAFrameContext : public FrameContext {
96104
struct {
97105
uint32_t exposure;
98106
double gain;
107+
bool autoEnabled;
99108
} agc;
100109

101110
struct {

src/ipa/rkisp1/rkisp1.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
157157
return -ENODEV;
158158
}
159159

160+
context_.configuration.sensor.lineDuration = sensorInfo.minLineLength
161+
* 1.0s / sensorInfo.pixelRate;
162+
160163
/* Load the tuning data file. */
161164
File file(settings.configurationFile);
162165
if (!file.open(File::OpenModeFlag::ReadOnly)) {
@@ -376,6 +379,28 @@ void IPARkISP1::updateControls(const IPACameraSensorInfo &sensorInfo,
376379
{
377380
ControlInfoMap::Map ctrlMap = rkisp1Controls;
378381

382+
/*
383+
* Compute exposure time limits from the V4L2_CID_EXPOSURE control
384+
* limits and the line duration.
385+
*/
386+
double lineDuration = context_.configuration.sensor.lineDuration.get<std::micro>();
387+
const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;
388+
int32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration;
389+
int32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration;
390+
int32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration;
391+
ctrlMap.emplace(std::piecewise_construct,
392+
std::forward_as_tuple(&controls::ExposureTime),
393+
std::forward_as_tuple(minExposure, maxExposure, defExposure));
394+
395+
/* Compute the analogue gain limits. */
396+
const ControlInfo &v4l2Gain = sensorControls.find(V4L2_CID_ANALOGUE_GAIN)->second;
397+
float minGain = camHelper_->gain(v4l2Gain.min().get<int32_t>());
398+
float maxGain = camHelper_->gain(v4l2Gain.max().get<int32_t>());
399+
float defGain = camHelper_->gain(v4l2Gain.def().get<int32_t>());
400+
ctrlMap.emplace(std::piecewise_construct,
401+
std::forward_as_tuple(&controls::AnalogueGain),
402+
std::forward_as_tuple(minGain, maxGain, defGain));
403+
379404
/*
380405
* Compute the frame duration limits.
381406
*

0 commit comments

Comments
 (0)