[PATCH/RFC] libcamera: Rename "shutter speed" to "exposure time"

Laurent Pinchart laurent.pinchart at ideasonboard.com
Mon Oct 28 02:34:28 CET 2024


The terms "shutter" and "shutter speed" are used through libcamera to
mean "exposure time". This is confusing, both due to "speed" being used
as "time" while it should be the inverse (i.e. a maximum speed should
correspond to the minimum time), and due to "shutter speed" and
"exposure time" being used in different places with the same meaning.

To improve clarity of the code base and the documentation, use "exposure
time" consistently to replace "shutter speed".

I'm sending this patch as an RFC to gather opinions before addressing a
few remaining issues, regarding which I'd appreciate feedback as well:

- The tuning data for the AgcMeanLuminance helper class still uses a
  "shutter" YAML element. I would ideally like to rename that too.

- The ExposureModeHelper::splitExposure() function used to document that
  it splits "exposure time into shutter time and gain". I have reworded
  that to "split exposure into exposure time and gain", but I'm not
  entirely happy with the result as "exposure" has a defined meaning in
  photography (see https://en.wikipedia.org/wiki/Exposure_(photography))
  that is not expressed as a duration. It seems we need a better term
  here.

- I haven't touched the Raspberry Pi IPA module. David, Naush, would you
  accept a rename there too ?

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/ipa/ipu3/algorithms/agc.cpp         |  26 ++--
 src/ipa/ipu3/algorithms/agc.h           |   4 +-
 src/ipa/ipu3/ipa_context.cpp            |   8 +-
 src/ipa/ipu3/ipa_context.h              |   4 +-
 src/ipa/ipu3/ipu3.cpp                   |  10 +-
 src/ipa/libipa/agc_mean_luminance.cpp   |  43 +++----
 src/ipa/libipa/agc_mean_luminance.h     |   2 +-
 src/ipa/libipa/exposure_mode_helper.cpp | 152 ++++++++++++------------
 src/ipa/libipa/exposure_mode_helper.h   |  14 +--
 src/ipa/rkisp1/algorithms/agc.cpp       |  27 +++--
 src/ipa/rkisp1/ipa_context.cpp          |   8 +-
 src/ipa/rkisp1/ipa_context.h            |   4 +-
 src/ipa/rkisp1/rkisp1.cpp               |  10 +-
 src/libcamera/control_ids_core.yaml     |  14 +--
 14 files changed, 163 insertions(+), 163 deletions(-)

diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp
index c5f3d8f0ccac..ff0f857d378c 100644
--- a/src/ipa/ipu3/algorithms/agc.cpp
+++ b/src/ipa/ipu3/algorithms/agc.cpp
@@ -33,7 +33,7 @@ namespace ipa::ipu3::algorithms {
  * \class Agc
  * \brief A mean-based auto-exposure algorithm
  *
- * This algorithm calculates a shutter time and an analogue gain so that the
+ * This algorithm calculates an exposure time and an analogue gain so that the
  * average value of the green channel of the brightest 2% of pixels approaches
  * 0.5. The AWB gains are not used here, and all cells in the grid have the same
  * weight, like an average-metering case. In this metering mode, the camera uses
@@ -51,13 +51,13 @@ LOG_DEFINE_CATEGORY(IPU3Agc)
 static constexpr double kMinAnalogueGain = 1.0;
 
 /* \todo Honour the FrameDurationLimits control instead of hardcoding a limit */
-static constexpr utils::Duration kMaxShutterSpeed = 60ms;
+static constexpr utils::Duration kMaxExposureTime = 60ms;
 
 /* Histogram constants */
 static constexpr uint32_t knumHistogramBins = 256;
 
 Agc::Agc()
-	: minShutterSpeed_(0s), maxShutterSpeed_(0s)
+	: minExposureTime_(0s), maxExposureTime_(0s)
 {
 }
 
@@ -100,9 +100,9 @@ int Agc::configure(IPAContext &context,
 	stride_ = configuration.grid.stride;
 	bdsGrid_ = configuration.grid.bdsGrid;
 
-	minShutterSpeed_ = configuration.agc.minShutterSpeed;
-	maxShutterSpeed_ = std::min(configuration.agc.maxShutterSpeed,
-				    kMaxShutterSpeed);
+	minExposureTime_ = configuration.agc.minExposureTime;
+	maxExposureTime_ = std::min(configuration.agc.maxExposureTime,
+				    kMaxExposureTime);
 
 	minAnalogueGain_ = std::max(configuration.agc.minAnalogueGain, kMinAnalogueGain);
 	maxAnalogueGain_ = configuration.agc.maxAnalogueGain;
@@ -115,7 +115,7 @@ int Agc::configure(IPAContext &context,
 	context.activeState.agc.exposureMode = exposureModeHelpers().begin()->first;
 
 	/* \todo Run this again when FrameDurationLimits is passed in */
-	setLimits(minShutterSpeed_, maxShutterSpeed_, minAnalogueGain_,
+	setLimits(minExposureTime_, maxExposureTime_, minAnalogueGain_,
 		  maxAnalogueGain_);
 	resetFrameCount();
 
@@ -222,20 +222,20 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
 	double analogueGain = frameContext.sensor.gain;
 	utils::Duration effectiveExposureValue = exposureTime * analogueGain;
 
-	utils::Duration shutterTime;
+	utils::Duration newExposureTime;
 	double aGain, dGain;
-	std::tie(shutterTime, aGain, dGain) =
+	std::tie(newExposureTime, aGain, dGain) =
 		calculateNewEv(context.activeState.agc.constraintMode,
 			       context.activeState.agc.exposureMode, hist,
 			       effectiveExposureValue);
 
 	LOG(IPU3Agc, Debug)
-		<< "Divided up shutter, analogue gain and digital gain are "
-		<< shutterTime << ", " << aGain << " and " << dGain;
+		<< "Divided up exposure time, analogue gain and digital gain are "
+		<< newExposureTime << ", " << aGain << " and " << dGain;
 
 	IPAActiveState &activeState = context.activeState;
-	/* Update the estimated exposure and gain. */
-	activeState.agc.exposure = shutterTime / context.configuration.sensor.lineDuration;
+	/* Update the estimated exposure time and gain. */
+	activeState.agc.exposure = newExposureTime / context.configuration.sensor.lineDuration;
 	activeState.agc.gain = aGain;
 
 	metadata.set(controls::AnalogueGain, frameContext.sensor.gain);
diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h
index 411f4da0704e..890c271b4462 100644
--- a/src/ipa/ipu3/algorithms/agc.h
+++ b/src/ipa/ipu3/algorithms/agc.h
@@ -42,8 +42,8 @@ private:
 	Histogram parseStatistics(const ipu3_uapi_stats_3a *stats,
 				  const ipu3_uapi_grid_config &grid);
 
-	utils::Duration minShutterSpeed_;
-	utils::Duration maxShutterSpeed_;
+	utils::Duration minExposureTime_;
+	utils::Duration maxExposureTime_;
 
 	double minAnalogueGain_;
 	double maxAnalogueGain_;
diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp
index 917d06541abe..fe455e0715c6 100644
--- a/src/ipa/ipu3/ipa_context.cpp
+++ b/src/ipa/ipu3/ipa_context.cpp
@@ -92,11 +92,11 @@ namespace libcamera::ipa::ipu3 {
  * \var IPASessionConfiguration::agc
  * \brief AGC parameters configuration of the IPA
  *
- * \var IPASessionConfiguration::agc.minShutterSpeed
- * \brief Minimum shutter speed supported with the configured sensor
+ * \var IPASessionConfiguration::agc.minExposureTime
+ * \brief Minimum exposure time supported with the configured sensor
  *
- * \var IPASessionConfiguration::agc.maxShutterSpeed
- * \brief Maximum shutter speed supported with the configured sensor
+ * \var IPASessionConfiguration::agc.maxExposureTime
+ * \brief Maximum exposure time supported with the configured sensor
  *
  * \var IPASessionConfiguration::agc.minAnalogueGain
  * \brief Minimum analogue gain supported with the configured sensor
diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h
index c85d1e34ea85..29f38b36a9a3 100644
--- a/src/ipa/ipu3/ipa_context.h
+++ b/src/ipa/ipu3/ipa_context.h
@@ -33,8 +33,8 @@ struct IPASessionConfiguration {
 	} af;
 
 	struct {
-		utils::Duration minShutterSpeed;
-		utils::Duration maxShutterSpeed;
+		utils::Duration minExposureTime;
+		utils::Duration maxExposureTime;
 		double minAnalogueGain;
 		double maxAnalogueGain;
 	} agc;
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 10a8c86d8e64..e82287631146 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -112,7 +112,7 @@ namespace ipa::ipu3 {
  * blue gains to apply to generate a neutral grey frame overall.
  *
  * AGC is handled by calculating a histogram of the green channel to estimate an
- * analogue gain and shutter time which will provide a well exposed frame. A
+ * analogue gain and exposure time which will provide a well exposed frame. A
  * low-pass IIR filter is used to smooth the changes to the sensor to reduce
  * perceivable steps.
  *
@@ -215,13 +215,13 @@ void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls)
 
 	/*
 	 * When the AGC computes the new exposure values for a frame, it needs
-	 * to know the limits for shutter speed and analogue gain.
+	 * to know the limits for exposure time and analogue gain.
 	 * As it depends on the sensor, update it with the controls.
 	 *
-	 * \todo take VBLANK into account for maximum shutter speed
+	 * \todo take VBLANK into account for maximum exposure time
 	 */
-	context_.configuration.agc.minShutterSpeed = minExposure * context_.configuration.sensor.lineDuration;
-	context_.configuration.agc.maxShutterSpeed = maxExposure * context_.configuration.sensor.lineDuration;
+	context_.configuration.agc.minExposureTime = minExposure * context_.configuration.sensor.lineDuration;
+	context_.configuration.agc.maxExposureTime = maxExposure * context_.configuration.sensor.lineDuration;
 	context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain);
 	context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain);
 }
diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp
index f97ef11771c4..d2d50001e51a 100644
--- a/src/ipa/libipa/agc_mean_luminance.cpp
+++ b/src/ipa/libipa/agc_mean_luminance.cpp
@@ -89,10 +89,10 @@ static constexpr double kDefaultRelativeLuminanceTarget = 0.16;
  * \class AgcMeanLuminance
  * \brief A mean-based auto-exposure algorithm
  *
- * This algorithm calculates a shutter time, analogue and digital gain such that
- * the normalised mean luminance value of an image is driven towards a target,
- * which itself is discovered from tuning data. The algorithm is a two-stage
- * process.
+ * This algorithm calculates an exposure time, analogue and digital gain such
+ * that the normalised mean luminance value of an image is driven towards a
+ * target, which itself is discovered from tuning data. The algorithm is a
+ * two-stage process.
  *
  * In the first stage, an initial gain value is derived by iteratively comparing
  * the gain-adjusted mean luminance across the entire image against a target,
@@ -109,7 +109,7 @@ static constexpr double kDefaultRelativeLuminanceTarget = 0.16;
  * stage is then clamped to the gain from this stage.
  *
  * The final gain is used to adjust the effective exposure value of the image,
- * and that new exposure value is divided into shutter time, analogue gain and
+ * and that new exposure value is divided into exposure time, analogue gain and
  * digital gain according to the selected AeExposureMode. This class uses the
  * \ref ExposureModeHelper class to assist in that division, and expects the
  * data needed to initialise that class to be present in tuning data in a
@@ -247,27 +247,27 @@ int AgcMeanLuminance::parseExposureModes(const YamlObject &tuningData)
 				return -EINVAL;
 			}
 
-			std::vector<uint32_t> shutters =
+			std::vector<uint32_t> exposureTimes =
 				modeValues["shutter"].getList<uint32_t>().value_or(std::vector<uint32_t>{});
 			std::vector<double> gains =
 				modeValues["gain"].getList<double>().value_or(std::vector<double>{});
 
-			if (shutters.size() != gains.size()) {
+			if (exposureTimes.size() != gains.size()) {
 				LOG(AgcMeanLuminance, Error)
 					<< "Shutter and gain array sizes unequal";
 				return -EINVAL;
 			}
 
-			if (shutters.empty()) {
+			if (exposureTimes.empty()) {
 				LOG(AgcMeanLuminance, Error)
 					<< "Shutter and gain arrays are empty";
 				return -EINVAL;
 			}
 
 			std::vector<std::pair<utils::Duration, double>> stages;
-			for (unsigned int i = 0; i < shutters.size(); i++) {
+			for (unsigned int i = 0; i < exposureTimes.size(); i++) {
 				stages.push_back({
-					std::chrono::microseconds(shutters[i]),
+					std::chrono::microseconds(exposureTimes[i]),
 					gains[i]
 				});
 			}
@@ -283,7 +283,7 @@ int AgcMeanLuminance::parseExposureModes(const YamlObject &tuningData)
 	/*
 	 * If we don't have any exposure modes in the tuning data we create an
 	 * ExposureModeHelper using an empty vector of stages. This will result
-	 * in the ExposureModeHelper simply driving the shutter as high as
+	 * in the ExposureModeHelper simply driving the exposure time as high as
 	 * possible before touching gain.
 	 */
 	if (availableExposureModes.empty()) {
@@ -338,8 +338,8 @@ int AgcMeanLuminance::parseExposureModes(const YamlObject &tuningData)
  * For the AeExposureMode control the data should contain a dictionary called
  * AeExposureMode containing per-mode setting dictionaries with the key being a
  * value from \ref controls::AeExposureModeNameValueMap. Each mode dict should
- * contain an array of shutter times with the key "shutter" and an array of gain
- * values with the key "gain", in this format:
+ * contain an array of exposure times with the key "shutter" and an array of
+ * gain values with the key "gain", in this format:
  *
  * \code{.unparsed}
  * algorithms:
@@ -371,20 +371,20 @@ int AgcMeanLuminance::parseTuningData(const YamlObject &tuningData)
 
 /**
  * \brief Set the ExposureModeHelper limits for this class
- * \param[in] minShutter Minimum shutter time to allow
- * \param[in] maxShutter Maximum shutter time to allow
+ * \param[in] minExposureTime Minimum exposure time to allow
+ * \param[in] maxExposureTime Maximum ewposure time to allow
  * \param[in] minGain Minimum gain to allow
  * \param[in] maxGain Maximum gain to allow
  *
  * This function calls \ref ExposureModeHelper::setLimits() for each
  * ExposureModeHelper that has been created for this class.
  */
-void AgcMeanLuminance::setLimits(utils::Duration minShutter,
-				 utils::Duration maxShutter,
+void AgcMeanLuminance::setLimits(utils::Duration minExposureTime,
+				 utils::Duration maxExposureTime,
 				 double minGain, double maxGain)
 {
 	for (auto &[id, helper] : exposureModeHelpers_)
-		helper->setLimits(minShutter, maxShutter, minGain, maxGain);
+		helper->setLimits(minExposureTime, maxExposureTime, minGain, maxGain);
 }
 
 /**
@@ -513,7 +513,8 @@ utils::Duration AgcMeanLuminance::filterExposure(utils::Duration exposureValue)
 }
 
 /**
- * \brief Calculate the new exposure value and splut it between shutter time and gain
+ * \brief Calculate the new exposure value and splut it between exposure time
+ * and gain
  * \param[in] constraintModeIndex The index of the current constraint mode
  * \param[in] exposureModeIndex The index of the current exposure mode
  * \param[in] yHist A Histogram from the ISP statistics to use in constraining
@@ -523,9 +524,9 @@ utils::Duration AgcMeanLuminance::filterExposure(utils::Duration exposureValue)
  *
  * Calculate a new exposure value to try to obtain the target. The calculated
  * exposure value is filtered to prevent rapid changes from frame to frame, and
- * divided into shutter time, analogue and digital gain.
+ * divided into exposure time, analogue and digital gain.
  *
- * \return Tuple of shutter time, analogue gain, and digital gain
+ * \return Tuple of exposure time, analogue gain, and digital gain
  */
 std::tuple<utils::Duration, double, double>
 AgcMeanLuminance::calculateNewEv(uint32_t constraintModeIndex,
diff --git a/src/ipa/libipa/agc_mean_luminance.h b/src/ipa/libipa/agc_mean_luminance.h
index 576d28be8eb0..c41391cb0b73 100644
--- a/src/ipa/libipa/agc_mean_luminance.h
+++ b/src/ipa/libipa/agc_mean_luminance.h
@@ -44,7 +44,7 @@ public:
 
 	int parseTuningData(const YamlObject &tuningData);
 
-	void setLimits(utils::Duration minShutter, utils::Duration maxShutter,
+	void setLimits(utils::Duration minExposureTime, utils::Duration maxExposureTime,
 		       double minGain, double maxGain);
 
 	std::map<int32_t, std::vector<AgcConstraint>> constraintModes()
diff --git a/src/ipa/libipa/exposure_mode_helper.cpp b/src/ipa/libipa/exposure_mode_helper.cpp
index 30da0c894044..f235316d3539 100644
--- a/src/ipa/libipa/exposure_mode_helper.cpp
+++ b/src/ipa/libipa/exposure_mode_helper.cpp
@@ -14,9 +14,9 @@
  * \file exposure_mode_helper.h
  * \brief Helper class that performs computations relating to exposure
  *
- * AEGC algorithms have a need to split exposure between shutter time, analogue
+ * AEGC algorithms have a need to split exposure between exposure time, analogue
  * and digital gain. Multiple implementations do so based on paired stages of
- * shutter time and gain limits; provide a helper to avoid duplicating the code.
+ * exposure time and gain limits; provide a helper to avoid duplicating the code.
  */
 
 namespace libcamera {
@@ -29,24 +29,24 @@ namespace ipa {
 
 /**
  * \class ExposureModeHelper
- * \brief Class for splitting exposure into shutter time and total gain
+ * \brief Class for splitting exposure into exposure time and total gain
  *
  * The ExposureModeHelper class provides a standard interface through which an
- * AEGC algorithm can divide exposure between shutter time and gain. It is
- * configured with a set of shutter time and gain pairs and works by initially
- * fixing gain at 1.0 and increasing shutter time up to the shutter time value
+ * AEGC algorithm can divide exposure between exposure time and gain. It is
+ * configured with a set of exposure time and gain pairs and works by initially
+ * fixing gain at 1.0 and increasing exposure time up to the exposure time value
  * from the first pair in the set in an attempt to meet the required exposure
  * value.
  *
- * If the required exposure is not achievable by the first shutter time value
+ * If the required exposure is not achievable by the first exposure time value
  * alone it ramps gain up to the value from the first pair in the set. If the
- * required exposure is still not met it then allows shutter time to ramp up to
- * the shutter time value from the second pair in the set, and continues in this
+ * required exposure is still not met it then allows exposure time to ramp up to
+ * the exposure time value from the second pair in the set, and continues in this
  * vein until either the required exposure time is met, or else the hardware's
- * shutter time or gain limits are reached.
+ * exposure time or gain limits are reached.
  *
  * This method allows users to strike a balance between a well-exposed image and
- * an acceptable frame-rate, as opposed to simply maximising shutter time
+ * an acceptable frame-rate, as opposed to simply maximising exposure time
  * followed by gain. The same helpers can be used to perform the latter
  * operation if needed by passing an empty set of pairs to the initialisation
  * function.
@@ -61,9 +61,9 @@ namespace ipa {
 
 /**
  * \brief Construct an ExposureModeHelper instance
- * \param[in] stages The vector of paired shutter time and gain limits
+ * \param[in] stages The vector of paired exposure time and gain limits
  *
- * The input stages are shutter time and _total_ gain pairs; the gain
+ * The input stages are exposure time and _total_ gain pairs; the gain
  * encompasses both analogue and digital gain.
  *
  * The vector of stages may be empty. In that case, the helper will simply use
@@ -71,46 +71,46 @@ namespace ipa {
  */
 ExposureModeHelper::ExposureModeHelper(const Span<std::pair<utils::Duration, double>> stages)
 {
-	minShutter_ = 0us;
-	maxShutter_ = 0us;
+	minExposureTime_ = 0us;
+	maxExposureTime_ = 0us;
 	minGain_ = 0;
 	maxGain_ = 0;
 
 	for (const auto &[s, g] : stages) {
-		shutters_.push_back(s);
+		exposureTimes_.push_back(s);
 		gains_.push_back(g);
 	}
 }
 
 /**
- * \brief Set the shutter time and gain limits
- * \param[in] minShutter The minimum shutter time supported
- * \param[in] maxShutter The maximum shutter time supported
+ * \brief Set the exposure time and gain limits
+ * \param[in] minExposureTime The minimum exposure time supported
+ * \param[in] maxExposureTime The maximum exposure time supported
  * \param[in] minGain The minimum analogue gain supported
  * \param[in] maxGain The maximum analogue gain supported
  *
- * This function configures the shutter time and analogue gain limits that need
+ * This function configures the exposure time and analogue gain limits that need
  * to be adhered to as the helper divides up exposure. Note that this function
  * *must* be called whenever those limits change and before splitExposure() is
  * used.
  *
- * If the algorithm using the helpers needs to indicate that either shutter time
+ * If the algorithm using the helpers needs to indicate that either exposure time
  * or analogue gain or both should be fixed it can do so by setting both the
  * minima and maxima to the same value.
  */
-void ExposureModeHelper::setLimits(utils::Duration minShutter,
-				   utils::Duration maxShutter,
+void ExposureModeHelper::setLimits(utils::Duration minExposureTime,
+				   utils::Duration maxExposureTime,
 				   double minGain, double maxGain)
 {
-	minShutter_ = minShutter;
-	maxShutter_ = maxShutter;
+	minExposureTime_ = minExposureTime;
+	maxExposureTime_ = maxExposureTime;
 	minGain_ = minGain;
 	maxGain_ = maxGain;
 }
 
-utils::Duration ExposureModeHelper::clampShutter(utils::Duration shutter) const
+utils::Duration ExposureModeHelper::clampExposureTime(utils::Duration exposureTime) const
 {
-	return std::clamp(shutter, minShutter_, maxShutter_);
+	return std::clamp(exposureTime, minExposureTime_, maxExposureTime_);
 }
 
 double ExposureModeHelper::clampGain(double gain) const
@@ -119,108 +119,108 @@ double ExposureModeHelper::clampGain(double gain) const
 }
 
 /**
- * \brief Split exposure time into shutter time and gain
- * \param[in] exposure Exposure time
+ * \brief Split exposure into exposure time and gain
+ * \param[in] exposure Exposure value
  *
- * This function divides a given exposure time into shutter time, analogue and
- * digital gain by iterating through stages of shutter time and gain limits. At
- * each stage the current stage's shutter time limit is multiplied by the
+ * This function divides a given exposure into exposure time, analogue and
+ * digital gain by iterating through stages of exposure time and gain limits.
+ * At each stage the current stage's exposure time limit is multiplied by the
  * previous stage's gain limit (or 1.0 initially) to see if the combination of
- * the two can meet the required exposure time. If they cannot then the current
- * stage's shutter time limit is multiplied by the same stage's gain limit to
+ * the two can meet the required exposure. If they cannot then the current
+ * stage's exposure time limit is multiplied by the same stage's gain limit to
  * see if that combination can meet the required exposure time. If they cannot
  * then the function moves to consider the next stage.
  *
- * When a combination of shutter time and gain _stage_ limits are found that are
- * sufficient to meet the required exposure time, the function attempts to
- * reduce shutter time as much as possible whilst fixing gain and still meeting
- * the exposure time. If a _runtime_ limit prevents shutter time from being
- * lowered enough to meet the exposure time with gain fixed at the stage limit,
- * gain is also lowered to compensate.
+ * When a combination of exposure time and gain _stage_ limits are found that
+ * are sufficient to meet the required exposure, the function attempts to reduce
+ * exposure time as much as possible whilst fixing gain and still meeting the
+ * exposure. If a _runtime_ limit prevents exposure time from being lowered
+ * enough to meet the exposure with gain fixed at the stage limit, gain is also
+ * lowered to compensate.
  *
- * Once the shutter time and gain values are ascertained, gain is assigned as
+ * Once the exposure time and gain values are ascertained, gain is assigned as
  * analogue gain as much as possible, with digital gain only in use if the
  * maximum analogue gain runtime limit is unable to accommodate the exposure
  * value.
  *
- * If no combination of shutter time and gain limits is found that meets the
- * required exposure time, the helper falls-back to simply maximising the
- * shutter time first, followed by analogue gain, followed by digital gain.
+ * If no combination of exposure time and gain limits is found that meets the
+ * required exposure, the helper falls-back to simply maximising the exposure
+ * time first, followed by analogue gain, followed by digital gain.
  *
- * \return Tuple of shutter time, analogue gain, and digital gain
+ * \return Tuple of exposure time, analogue gain, and digital gain
  */
 std::tuple<utils::Duration, double, double>
 ExposureModeHelper::splitExposure(utils::Duration exposure) const
 {
-	ASSERT(maxShutter_);
+	ASSERT(maxExposureTime_);
 	ASSERT(maxGain_);
 
 	bool gainFixed = minGain_ == maxGain_;
-	bool shutterFixed = minShutter_ == maxShutter_;
+	bool exposureTimeFixed = minExposureTime_ == maxExposureTime_;
 
 	/*
 	 * There's no point entering the loop if we cannot change either gain
-	 * nor shutter anyway.
+	 * nor exposure time anyway.
 	 */
-	if (shutterFixed && gainFixed)
-		return { minShutter_, minGain_, exposure / (minShutter_ * minGain_) };
+	if (exposureTimeFixed && gainFixed)
+		return { minExposureTime_, minGain_, exposure / (minExposureTime_ * minGain_) };
 
-	utils::Duration shutter;
+	utils::Duration exposureTime;
 	double stageGain = 1.0;
 	double gain;
 
 	for (unsigned int stage = 0; stage < gains_.size(); stage++) {
 		double lastStageGain = stage == 0 ? 1.0 : clampGain(gains_[stage - 1]);
-		utils::Duration stageShutter = clampShutter(shutters_[stage]);
+		utils::Duration stageExposureTime = clampExposureTime(exposureTimes_[stage]);
 		stageGain = clampGain(gains_[stage]);
 
 		/*
-		 * We perform the clamping on both shutter and gain in case the
-		 * helper has had limits set that prevent those values being
-		 * lowered beyond a certain minimum...this can happen at runtime
-		 * for various reasons and so would not be known when the stage
-		 * limits are initialised.
+		 * We perform the clamping on both exposure time and gain in
+		 * case the helper has had limits set that prevent those values
+		 * being lowered beyond a certain minimum...this can happen at
+		 * runtime for various reasons and so would not be known when
+		 * the stage limits are initialised.
 		 */
 
-		if (stageShutter * lastStageGain >= exposure) {
-			shutter = clampShutter(exposure / clampGain(lastStageGain));
-			gain = clampGain(exposure / shutter);
+		if (stageExposureTime * lastStageGain >= exposure) {
+			exposureTime = clampExposureTime(exposure / clampGain(lastStageGain));
+			gain = clampGain(exposure / exposureTime);
 
-			return { shutter, gain, exposure / (shutter * gain) };
+			return { exposureTime, gain, exposure / (exposureTime * gain) };
 		}
 
-		if (stageShutter * stageGain >= exposure) {
-			shutter = clampShutter(exposure / clampGain(stageGain));
-			gain = clampGain(exposure / shutter);
+		if (stageExposureTime * stageGain >= exposure) {
+			exposureTime = clampExposureTime(exposure / clampGain(stageGain));
+			gain = clampGain(exposure / exposureTime);
 
-			return { shutter, gain, exposure / (shutter * gain) };
+			return { exposureTime, gain, exposure / (exposureTime * gain) };
 		}
 	}
 
 	/*
-	 * From here on all we can do is max out the shutter time, followed by
+	 * From here on all we can do is max out the exposure time, followed by
 	 * the analogue gain. If we still haven't achieved the target we send
 	 * the rest of the exposure time to digital gain. If we were given no
 	 * stages to use then the default stageGain of 1.0 is used so that
-	 * shutter time is maxed before gain is touched at all.
+	 * exposure time is maxed before gain is touched at all.
 	 */
-	shutter = clampShutter(exposure / clampGain(stageGain));
-	gain = clampGain(exposure / shutter);
+	exposureTime = clampExposureTime(exposure / clampGain(stageGain));
+	gain = clampGain(exposure / exposureTime);
 
-	return { shutter, gain, exposure / (shutter * gain) };
+	return { exposureTime, gain, exposure / (exposureTime * gain) };
 }
 
 /**
- * \fn ExposureModeHelper::minShutter()
- * \brief Retrieve the configured minimum shutter time limit set through
+ * \fn ExposureModeHelper::minExposureTime()
+ * \brief Retrieve the configured minimum exposure time limit set through
  * setLimits()
- * \return The minShutter_ value
+ * \return The minExposureTime_ value
  */
 
 /**
- * \fn ExposureModeHelper::maxShutter()
- * \brief Retrieve the configured maximum shutter time set through setLimits()
- * \return The maxShutter_ value
+ * \fn ExposureModeHelper::maxExposureTime()
+ * \brief Retrieve the configured maximum exposure time set through setLimits()
+ * \return The maxExposureTime_ value
  */
 
 /**
diff --git a/src/ipa/libipa/exposure_mode_helper.h b/src/ipa/libipa/exposure_mode_helper.h
index 85c665d7d187..c5be1b6703a8 100644
--- a/src/ipa/libipa/exposure_mode_helper.h
+++ b/src/ipa/libipa/exposure_mode_helper.h
@@ -24,26 +24,26 @@ public:
 	ExposureModeHelper(const Span<std::pair<utils::Duration, double>> stages);
 	~ExposureModeHelper() = default;
 
-	void setLimits(utils::Duration minShutter, utils::Duration maxShutter,
+	void setLimits(utils::Duration minExposureTime, utils::Duration maxExposureTime,
 		       double minGain, double maxGain);
 
 	std::tuple<utils::Duration, double, double>
 	splitExposure(utils::Duration exposure) const;
 
-	utils::Duration minShutter() const { return minShutter_; }
-	utils::Duration maxShutter() const { return maxShutter_; }
+	utils::Duration minExposureTime() const { return minExposureTime_; }
+	utils::Duration maxExposureTime() const { return maxExposureTime_; }
 	double minGain() const { return minGain_; }
 	double maxGain() const { return maxGain_; }
 
 private:
-	utils::Duration clampShutter(utils::Duration shutter) const;
+	utils::Duration clampExposureTime(utils::Duration exposureTime) const;
 	double clampGain(double gain) const;
 
-	std::vector<utils::Duration> shutters_;
+	std::vector<utils::Duration> exposureTimes_;
 	std::vector<double> gains_;
 
-	utils::Duration minShutter_;
-	utils::Duration maxShutter_;
+	utils::Duration minExposureTime_;
+	utils::Duration maxExposureTime_;
 	double minGain_;
 	double maxGain_;
 };
diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp
index 301b7ec26508..40e5a8f481b2 100644
--- a/src/ipa/rkisp1/algorithms/agc.cpp
+++ b/src/ipa/rkisp1/algorithms/agc.cpp
@@ -183,7 +183,7 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
 	 * except it's computed in the IPA and not here so we'd have to
 	 * recompute it.
 	 */
-	context.activeState.agc.maxFrameDuration = context.configuration.sensor.maxShutterSpeed;
+	context.activeState.agc.maxFrameDuration = context.configuration.sensor.maxExposureTime;
 
 	/*
 	 * Define the measurement window for AGC as a centered rectangle
@@ -194,8 +194,8 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
 	context.configuration.agc.measureWindow.h_size = 3 * configInfo.outputSize.width / 4;
 	context.configuration.agc.measureWindow.v_size = 3 * configInfo.outputSize.height / 4;
 
-	setLimits(context.configuration.sensor.minShutterSpeed,
-		  context.configuration.sensor.maxShutterSpeed,
+	setLimits(context.configuration.sensor.minExposureTime,
+		  context.configuration.sensor.maxExposureTime,
 		  context.configuration.sensor.minAnalogueGain,
 		  context.configuration.sensor.maxAnalogueGain);
 
@@ -424,12 +424,12 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
 		       [](uint32_t x) { return x >> 4; });
 	expMeans_ = { params->ae.exp_mean, context.hw->numAeCells };
 
-	utils::Duration maxShutterSpeed =
+	utils::Duration maxExposureTime =
 		std::clamp(frameContext.agc.maxFrameDuration,
-			   context.configuration.sensor.minShutterSpeed,
-			   context.configuration.sensor.maxShutterSpeed);
-	setLimits(context.configuration.sensor.minShutterSpeed,
-		  maxShutterSpeed,
+			   context.configuration.sensor.minExposureTime,
+			   context.configuration.sensor.maxExposureTime);
+	setLimits(context.configuration.sensor.minExposureTime,
+		  maxExposureTime,
 		  context.configuration.sensor.minAnalogueGain,
 		  context.configuration.sensor.maxAnalogueGain);
 
@@ -442,20 +442,21 @@ void Agc::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
 	double analogueGain = frameContext.sensor.gain;
 	utils::Duration effectiveExposureValue = exposureTime * analogueGain;
 
-	utils::Duration shutterTime;
+	utils::Duration newExposureTime;
 	double aGain, dGain;
-	std::tie(shutterTime, aGain, dGain) =
+	std::tie(newExposureTime, aGain, dGain) =
 		calculateNewEv(frameContext.agc.constraintMode,
 			       frameContext.agc.exposureMode,
 			       hist, effectiveExposureValue);
 
 	LOG(RkISP1Agc, Debug)
-		<< "Divided up shutter, analogue gain and digital gain are "
-		<< shutterTime << ", " << aGain << " and " << dGain;
+		<< "Divided up exposure time, analogue gain and digital gain are "
+		<< newExposureTime << ", " << aGain << " and " << dGain;
 
 	IPAActiveState &activeState = context.activeState;
 	/* Update the estimated exposure and gain. */
-	activeState.agc.automatic.exposure = shutterTime / context.configuration.sensor.lineDuration;
+	activeState.agc.automatic.exposure = newExposureTime
+					   / context.configuration.sensor.lineDuration;
 	activeState.agc.automatic.gain = aGain;
 
 	fillMetadata(context, frameContext, metadata);
diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp
index 14d0c02a2b32..833e2cbb784f 100644
--- a/src/ipa/rkisp1/ipa_context.cpp
+++ b/src/ipa/rkisp1/ipa_context.cpp
@@ -78,11 +78,11 @@ namespace libcamera::ipa::rkisp1 {
  * \var IPASessionConfiguration::sensor
  * \brief Sensor-specific configuration of the IPA
  *
- * \var IPASessionConfiguration::sensor.minShutterSpeed
- * \brief Minimum shutter speed supported with the sensor
+ * \var IPASessionConfiguration::sensor.minExposureTime
+ * \brief Minimum exposure time supported with the sensor
  *
- * \var IPASessionConfiguration::sensor.maxShutterSpeed
- * \brief Maximum shutter speed supported with the sensor
+ * \var IPASessionConfiguration::sensor.maxExposureTime
+ * \brief Maximum exposure time supported with the sensor
  *
  * \var IPASessionConfiguration::sensor.minAnalogueGain
  * \brief Minimum analogue gain supported with the sensor
diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
index e274d9b01e1c..5fc53011d9b4 100644
--- a/src/ipa/rkisp1/ipa_context.h
+++ b/src/ipa/rkisp1/ipa_context.h
@@ -50,8 +50,8 @@ struct IPASessionConfiguration {
 	} lsc;
 
 	struct {
-		utils::Duration minShutterSpeed;
-		utils::Duration maxShutterSpeed;
+		utils::Duration minExposureTime;
+		utils::Duration maxExposureTime;
 		double minAnalogueGain;
 		double maxAnalogueGain;
 
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index 9e161cabdea4..69417b9ec6bf 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -256,14 +256,14 @@ int IPARkISP1::configure(const IPAConfigInfo &ipaConfig,
 
 	/*
 	 * When the AGC computes the new exposure values for a frame, it needs
-	 * to know the limits for shutter speed and analogue gain.
-	 * As it depends on the sensor, update it with the controls.
+	 * to know the limits for exposure time and analogue gain. As it depends
+	 * on the sensor, update it with the controls.
 	 *
-	 * \todo take VBLANK into account for maximum shutter speed
+	 * \todo take VBLANK into account for maximum exposure time
 	 */
-	context_.configuration.sensor.minShutterSpeed =
+	context_.configuration.sensor.minExposureTime =
 		minExposure * context_.configuration.sensor.lineDuration;
-	context_.configuration.sensor.maxShutterSpeed =
+	context_.configuration.sensor.maxExposureTime =
 		maxExposure * context_.configuration.sensor.lineDuration;
 	context_.configuration.sensor.minAnalogueGain =
 		context_.camHelper->gain(minGain);
diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml
index 1b1bd9507d25..438a5d003750 100644
--- a/src/libcamera/control_ids_core.yaml
+++ b/src/libcamera/control_ids_core.yaml
@@ -102,7 +102,7 @@ controls:
         Specify an exposure mode for the AE algorithm to use.
 
         The exposure modes specify how the desired total exposure is divided
-        between the shutter time and the sensor's analogue gain. They are
+        between the exposure time and the sensor's analogue gain. They are
         platform specific, and not all exposure modes may be supported.
       enum:
         - name: ExposureNormal
@@ -135,8 +135,7 @@ controls:
   - ExposureTime:
       type: int32_t
       description: |
-        Exposure time (shutter speed) for the frame applied in the sensor
-        device.
+        Exposure time for the frame applied in the sensor device.
 
         This value is specified in micro-seconds.
 
@@ -463,14 +462,13 @@ controls:
         values to be the same. Setting both values to 0 reverts to using the
         camera defaults.
 
-        The maximum frame duration provides the absolute limit to the shutter
-        speed computed by the AE algorithm and it overrides any exposure mode
+        The maximum frame duration provides the absolute limit to the exposure
+        time computed by the AE algorithm and it overrides any exposure mode
         setting specified with controls::AeExposureMode. Similarly, when a
         manual exposure time is set through controls::ExposureTime, it also
         gets clipped to the limits set by this control. When reported in
-        metadata, the control expresses the minimum and maximum frame
-        durations used after being clipped to the sensor provided frame
-        duration limits.
+        metadata, the control expresses the minimum and maximum frame durations
+        used after being clipped to the sensor provided frame duration limits.
 
         \sa AeExposureMode
         \sa ExposureTime

base-commit: 80a7ccd3add45eb56fda6f1fb445017ac01fea7a
prerequisite-patch-id: 19ba9a578d3e04662488c7189f88ffea94c769fe
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list