summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Plowman <david.plowman@raspberrypi.com>2020-06-18 12:12:36 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-06-22 07:03:31 +0300
commit846e7d999a15ce0c3784a790cd5c249ba7aaa5c6 (patch)
tree16df4db955d1c121b0fb942cbe1d41b4cbc19437 /src
parentff291b3c15ba250fb05236a774771fdf54554ff7 (diff)
libcamera: ipa: raspberrypi: Recalculate camera exposure/gain when camera mode changes
This commit causes the AGC to recalculate its camera exposure/gain values when the camera mode changes. For example it's possible that the exposure profile could be changed by the application so the division between exposure time and analogue gain may be different. The other underlying reason (and which this commit accomplishes too) is that the sensor's line timing may change in a new mode, and because V4L2 drivers store a number of exposure _lines_, the resulting _time_ will "change under our feet". So we have to go through the process of recalculating the correct number of lines and writing this back to the sensor with every mode switch, regardless of anything else. Signed-off-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src')
-rw-r--r--src/ipa/raspberrypi/controller/rpi/agc.cpp12
-rw-r--r--src/ipa/raspberrypi/controller/rpi/agc.hpp1
-rw-r--r--src/ipa/raspberrypi/raspberrypi.cpp25
3 files changed, 26 insertions, 12 deletions
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp
index a4742872..c02b5ece 100644
--- a/src/ipa/raspberrypi/controller/rpi/agc.cpp
+++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp
@@ -221,6 +221,18 @@ void Agc::SetConstraintMode(std::string const &constraint_mode_name)
constraint_mode_name_ = constraint_mode_name;
}
+void Agc::SwitchMode(CameraMode const &camera_mode, Metadata *metadata)
+{
+ // On a mode switch, it's possible the exposure profile could change,
+ // so we run through the dividing up of exposure/gain again and
+ // write the results into the metadata we've been given.
+ if (status_.total_exposure_value) {
+ housekeepConfig();
+ divvyupExposure();
+ writeAndFinish(metadata, false);
+ }
+}
+
void Agc::Prepare(Metadata *image_metadata)
{
AgcStatus status;
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.hpp b/src/ipa/raspberrypi/controller/rpi/agc.hpp
index dbcefba6..9a7e89c1 100644
--- a/src/ipa/raspberrypi/controller/rpi/agc.hpp
+++ b/src/ipa/raspberrypi/controller/rpi/agc.hpp
@@ -75,6 +75,7 @@ public:
void SetMeteringMode(std::string const &metering_mode_name) override;
void SetExposureMode(std::string const &exposure_mode_name) override;
void SetConstraintMode(std::string const &contraint_mode_name) override;
+ void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override;
void Prepare(Metadata *image_metadata) override;
void Process(StatisticsPtr &stats, Metadata *image_metadata) override;
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
index d6fd3df3..42c84b16 100644
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ b/src/ipa/raspberrypi/raspberrypi.cpp
@@ -247,29 +247,30 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo,
mistrust_count_ = helper_->MistrustFramesStartup();
}
+ struct AgcStatus agcStatus;
+ /* These zero values mean not program anything (unless overwritten). */
+ agcStatus.shutter_time = 0.0;
+ agcStatus.analogue_gain = 0.0;
+
if (!controllerInit_) {
/* Load the tuning file for this sensor. */
controller_.Read(tuningFile_.c_str());
controller_.Initialise();
controllerInit_ = true;
- /* Calculate initial values for gain and exposure. */
- int32_t gain_code = helper_->GainCode(DEFAULT_ANALOGUE_GAIN);
- int32_t exposure_lines = helper_->ExposureLines(DEFAULT_EXPOSURE_TIME);
-
- ControlList ctrls(unicam_ctrls_);
- ctrls.set(V4L2_CID_ANALOGUE_GAIN, gain_code);
- ctrls.set(V4L2_CID_EXPOSURE, exposure_lines);
-
- IPAOperationData op;
- op.operation = RPI_IPA_ACTION_V4L2_SET_STAGGERED;
- op.controls.push_back(ctrls);
- queueFrameAction.emit(0, op);
+ /* Supply initial values for gain and exposure. */
+ agcStatus.shutter_time = DEFAULT_EXPOSURE_TIME;
+ agcStatus.analogue_gain = DEFAULT_ANALOGUE_GAIN;
}
RPi::Metadata metadata;
controller_.SwitchMode(mode_, &metadata);
+ /* SwitchMode may supply updated exposure/gain values to use. */
+ metadata.Get("agc.status", agcStatus);
+ if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0)
+ applyAGC(&agcStatus);
+
lastMode_ = mode_;
}