summaryrefslogtreecommitdiff
path: root/src/ipa
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipa')
-rw-r--r--src/ipa/raspberrypi/controller/agc_algorithm.hpp1
-rw-r--r--src/ipa/raspberrypi/controller/rpi/agc.cpp47
-rw-r--r--src/ipa/raspberrypi/controller/rpi/agc.hpp3
-rw-r--r--src/ipa/raspberrypi/raspberrypi.cpp12
4 files changed, 48 insertions, 15 deletions
diff --git a/src/ipa/raspberrypi/controller/agc_algorithm.hpp b/src/ipa/raspberrypi/controller/agc_algorithm.hpp
index 981f1de2..f97deb0f 100644
--- a/src/ipa/raspberrypi/controller/agc_algorithm.hpp
+++ b/src/ipa/raspberrypi/controller/agc_algorithm.hpp
@@ -19,6 +19,7 @@ public:
virtual void SetEv(double ev) = 0;
virtual void SetFlickerPeriod(double flicker_period) = 0;
virtual void SetFixedShutter(double fixed_shutter) = 0; // microseconds
+ virtual void SetMaxShutter(double max_shutter) = 0; // microseconds
virtual void SetFixedAnalogueGain(double fixed_analogue_gain) = 0;
virtual void SetMeteringMode(std::string const &metering_mode_name) = 0;
virtual void SetExposureMode(std::string const &exposure_mode_name) = 0;
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp
index eddd1684..f4cd5d26 100644
--- a/src/ipa/raspberrypi/controller/rpi/agc.cpp
+++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp
@@ -157,7 +157,7 @@ Agc::Agc(Controller *controller)
frame_count_(0), lock_count_(0),
last_target_exposure_(0.0),
ev_(1.0), flicker_period_(0.0),
- fixed_shutter_(0), fixed_analogue_gain_(0.0)
+ max_shutter_(0), fixed_shutter_(0), fixed_analogue_gain_(0.0)
{
memset(&awb_, 0, sizeof(awb_));
// Setting status_.total_exposure_value_ to zero initially tells us
@@ -227,11 +227,16 @@ void Agc::SetFlickerPeriod(double flicker_period)
flicker_period_ = flicker_period;
}
+void Agc::SetMaxShutter(double max_shutter)
+{
+ max_shutter_ = max_shutter;
+}
+
void Agc::SetFixedShutter(double fixed_shutter)
{
fixed_shutter_ = fixed_shutter;
// Set this in case someone calls Pause() straight after.
- status_.shutter_time = fixed_shutter;
+ status_.shutter_time = clipShutter(fixed_shutter_);
}
void Agc::SetFixedAnalogueGain(double fixed_analogue_gain)
@@ -261,7 +266,8 @@ void Agc::SwitchMode([[maybe_unused]] CameraMode const &camera_mode,
{
housekeepConfig();
- if (fixed_shutter_ != 0.0 && fixed_analogue_gain_ != 0.0) {
+ double fixed_shutter = clipShutter(fixed_shutter_);
+ if (fixed_shutter != 0.0 && fixed_analogue_gain_ != 0.0) {
// We're going to reset the algorithm here with these fixed values.
fetchAwbStatus(metadata);
@@ -269,14 +275,14 @@ void Agc::SwitchMode([[maybe_unused]] CameraMode const &camera_mode,
ASSERT(min_colour_gain != 0.0);
// This is the equivalent of computeTargetExposure and applyDigitalGain.
- target_.total_exposure_no_dg = fixed_shutter_ * fixed_analogue_gain_;
+ target_.total_exposure_no_dg = fixed_shutter * fixed_analogue_gain_;
target_.total_exposure = target_.total_exposure_no_dg / min_colour_gain;
// Equivalent of filterExposure. This resets any "history".
filtered_ = target_;
// Equivalent of divideUpExposure.
- filtered_.shutter = fixed_shutter_;
+ filtered_.shutter = fixed_shutter;
filtered_.analogue_gain = fixed_analogue_gain_;
} else if (status_.total_exposure_value) {
// On a mode switch, it's possible the exposure profile could change,
@@ -290,7 +296,7 @@ void Agc::SwitchMode([[maybe_unused]] CameraMode const &camera_mode,
// for any that weren't set.
// Equivalent of divideUpExposure.
- filtered_.shutter = fixed_shutter_ ? fixed_shutter_ : config_.default_exposure_time;
+ filtered_.shutter = fixed_shutter ? fixed_shutter : config_.default_exposure_time;
filtered_.analogue_gain = fixed_analogue_gain_ ? fixed_analogue_gain_ : config_.default_analogue_gain;
}
@@ -403,7 +409,7 @@ void Agc::housekeepConfig()
{
// First fetch all the up-to-date settings, so no one else has to do it.
status_.ev = ev_;
- status_.fixed_shutter = fixed_shutter_;
+ status_.fixed_shutter = clipShutter(fixed_shutter_);
status_.fixed_analogue_gain = fixed_analogue_gain_;
status_.flicker_period = flicker_period_;
LOG(RPiAgc, Debug) << "ev " << status_.ev << " fixed_shutter "
@@ -582,13 +588,15 @@ void Agc::computeTargetExposure(double gain)
target_.total_exposure = current_.total_exposure_no_dg * gain;
// The final target exposure is also limited to what the exposure
// mode allows.
+ double max_shutter = status_.fixed_shutter != 0.0
+ ? status_.fixed_shutter
+ : exposure_mode_->shutter.back();
+ max_shutter = clipShutter(max_shutter);
double max_total_exposure =
- (status_.fixed_shutter != 0.0
- ? status_.fixed_shutter
- : exposure_mode_->shutter.back()) *
+ max_shutter *
(status_.fixed_analogue_gain != 0.0
- ? status_.fixed_analogue_gain
- : exposure_mode_->gain.back());
+ ? status_.fixed_analogue_gain
+ : exposure_mode_->gain.back());
target_.total_exposure = std::min(target_.total_exposure,
max_total_exposure);
}
@@ -671,6 +679,7 @@ void Agc::divideUpExposure()
shutter_time = status_.fixed_shutter != 0.0
? status_.fixed_shutter
: exposure_mode_->shutter[0];
+ shutter_time = clipShutter(shutter_time);
analogue_gain = status_.fixed_analogue_gain != 0.0
? status_.fixed_analogue_gain
: exposure_mode_->gain[0];
@@ -678,14 +687,15 @@ void Agc::divideUpExposure()
for (unsigned int stage = 1;
stage < exposure_mode_->gain.size(); stage++) {
if (status_.fixed_shutter == 0.0) {
- if (exposure_mode_->shutter[stage] *
- analogue_gain >=
+ double stage_shutter =
+ clipShutter(exposure_mode_->shutter[stage]);
+ if (stage_shutter * analogue_gain >=
exposure_value) {
shutter_time =
exposure_value / analogue_gain;
break;
}
- shutter_time = exposure_mode_->shutter[stage];
+ shutter_time = stage_shutter;
}
if (status_.fixed_analogue_gain == 0.0) {
if (exposure_mode_->gain[stage] *
@@ -740,6 +750,13 @@ void Agc::writeAndFinish(Metadata *image_metadata, bool desaturate)
<< " analogue gain " << filtered_.analogue_gain;
}
+double Agc::clipShutter(double shutter)
+{
+ if (max_shutter_)
+ shutter = std::min(shutter, max_shutter_);
+ return shutter;
+}
+
// Register algorithm with the system.
static Algorithm *Create(Controller *controller)
{
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.hpp b/src/ipa/raspberrypi/controller/rpi/agc.hpp
index 05c334e4..0427fb59 100644
--- a/src/ipa/raspberrypi/controller/rpi/agc.hpp
+++ b/src/ipa/raspberrypi/controller/rpi/agc.hpp
@@ -78,6 +78,7 @@ public:
unsigned int GetConvergenceFrames() const override;
void SetEv(double ev) override;
void SetFlickerPeriod(double flicker_period) override;
+ void SetMaxShutter(double max_shutter) override; // microseconds
void SetFixedShutter(double fixed_shutter) override; // microseconds
void SetFixedAnalogueGain(double fixed_analogue_gain) override;
void SetMeteringMode(std::string const &metering_mode_name) override;
@@ -100,6 +101,7 @@ private:
void filterExposure(bool desaturate);
void divideUpExposure();
void writeAndFinish(Metadata *image_metadata, bool desaturate);
+ double clipShutter(double shutter);
AgcMeteringMode *metering_mode_;
AgcExposureMode *exposure_mode_;
AgcConstraintMode *constraint_mode_;
@@ -126,6 +128,7 @@ private:
std::string constraint_mode_name_;
double ev_;
double flicker_period_;
+ double max_shutter_;
double fixed_shutter_;
double fixed_analogue_gain_;
};
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
index 85aee6f7..ff14cfc4 100644
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ b/src/ipa/raspberrypi/raspberrypi.cpp
@@ -1065,6 +1065,18 @@ void IPARPi::applyFrameDurations(double minFrameDuration, double maxFrameDuratio
libcameraMetadata_.set(controls::FrameDurations,
{ static_cast<int64_t>(minFrameDuration_),
static_cast<int64_t>(maxFrameDuration_) });
+
+ /*
+ * Calculate the maximum exposure time possible for the AGC to use.
+ * GetVBlanking() will update maxShutter with the largest exposure
+ * value possible.
+ */
+ double maxShutter = std::numeric_limits<double>::max();
+ helper_->GetVBlanking(maxShutter, minFrameDuration_, maxFrameDuration_);
+
+ RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
+ controller_.GetAlgorithm("agc"));
+ agc->SetMaxShutter(maxShutter);
}
void IPARPi::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls)