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

Laurent Pinchart laurent.pinchart at ideasonboard.com
Mon Nov 25 13:33:26 CET 2024


Naush, David, could you give me an ack (or nack) for the Raspberry
Pi-specific parts when you get a chance ?

On Wed, Nov 20, 2024 at 12:38:02PM +0200, Laurent Pinchart wrote:
> 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".
> 
> This rename highlighted another vocabulary issue in libcamera. The
> ExposureModeHelper::splitExposure() function used to document that it
> splits "exposure time into shutter time and gain". It has been reworded
> to "split exposure into exposure time and gain". That is not entirely
> satisfactory, as "exposure" has a defined meaning in photography (see
> https://en.wikipedia.org/wiki/Exposure_(photography)) that is not
> expressed as a duration. This issue if left to be addressed separately.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> Changes since v1:
> 
> - Rename occurrences in the Raspberry Pi IPA module
> - Rename occurrences in rkisp1 tuning data format
> ---
>  include/libcamera/ipa/raspberrypi.mojom      |   2 +-
>  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        |  53 ++---
>  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/ipa/rpi/cam_helper/cam_helper.cpp        |   2 +-
>  src/ipa/rpi/cam_helper/cam_helper_imx219.cpp |   2 +-
>  src/ipa/rpi/cam_helper/cam_helper_imx477.cpp |   4 +-
>  src/ipa/rpi/cam_helper/cam_helper_imx519.cpp |   4 +-
>  src/ipa/rpi/cam_helper/cam_helper_imx708.cpp |   4 +-
>  src/ipa/rpi/common/ipa_base.cpp              |  46 +++--
>  src/ipa/rpi/controller/agc_algorithm.h       |   6 +-
>  src/ipa/rpi/controller/agc_status.h          |   4 +-
>  src/ipa/rpi/controller/camera_mode.h         |   6 +-
>  src/ipa/rpi/controller/device_status.cpp     |   2 +-
>  src/ipa/rpi/controller/device_status.h       |   8 +-
>  src/ipa/rpi/controller/rpi/agc.cpp           |  10 +-
>  src/ipa/rpi/controller/rpi/agc.h             |   6 +-
>  src/ipa/rpi/controller/rpi/agc_channel.cpp   | 191 ++++++++++---------
>  src/ipa/rpi/controller/rpi/agc_channel.h     |  14 +-
>  src/ipa/rpi/controller/rpi/lux.cpp           |   8 +-
>  src/ipa/rpi/controller/rpi/lux.h             |   2 +-
>  src/libcamera/control_ids_core.yaml          |  14 +-
>  utils/tuning/libtuning/modules/agc/rkisp1.py |   4 +-
>  33 files changed, 334 insertions(+), 327 deletions(-)
> 
> diff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom
> index 5986c4366c15..0b92587de1be 100644
> --- a/include/libcamera/ipa/raspberrypi.mojom
> +++ b/include/libcamera/ipa/raspberrypi.mojom
> @@ -272,7 +272,7 @@ interface IPARPiEventInterface {
>  	 * \param[in] delayContext IPA context index used for this request
>  	 *
>  	 * This asynchronous event is signalled to the pipeline handler when
> -	 * the IPA requires sensor specific controls (e.g. shutter speed, gain,
> +	 * the IPA requires sensor specific controls (e.g. exposure time, gain,
>  	 * blanking) to be applied.
>  	 */
>  	setDelayedControls(libcamera.ControlList controls, uint32 delayContext);
> diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp
> index 466b3fb31a6c..466692036824 100644
> --- a/src/ipa/ipu3/algorithms/agc.cpp
> +++ b/src/ipa/ipu3/algorithms/agc.cpp
> @@ -34,7 +34,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
> @@ -52,13 +52,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)
>  {
>  }
>  
> @@ -101,9 +101,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;
> @@ -116,7 +116,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();
>  
> @@ -223,20 +223,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 89c3192c6295..44c98cbf6e89 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..cd17570861e9 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 =
> -				modeValues["shutter"].getList<uint32_t>().value_or(std::vector<uint32_t>{});
> +			std::vector<uint32_t> exposureTimes =
> +				modeValues["exposure-time"].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";
> +					<< "Exposure time and gain array sizes unequal";
>  				return -EINVAL;
>  			}
>  
> -			if (shutters.empty()) {
> +			if (exposureTimes.empty()) {
>  				LOG(AgcMeanLuminance, Error)
> -					<< "Shutter and gain arrays are empty";
> +					<< "Exposure time 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,18 +338,18 @@ 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 "exposure-time" and an array
> + * of gain values with the key "gain", in this format:
>   *
>   * \code{.unparsed}
>   * algorithms:
>   *   - Agc:
>   *       AeExposureMode:
>   *         ExposureNormal:
> - *           shutter: [ 100, 10000, 30000, 60000, 120000 ]
> + *           exposure-time: [ 100, 10000, 30000, 60000, 120000 ]
>   *           gain: [ 2.0, 4.0, 6.0, 8.0, 10.0 ]
>   *         ExposureShort:
> - *           shutter: [ 100, 10000, 30000, 60000, 120000 ]
> + *           exposure-time: [ 100, 10000, 30000, 60000, 120000 ]
>   *           gain: [ 2.0, 4.0, 6.0, 8.0, 10.0 ]
>   *
>   * \endcode
> @@ -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 7b93a9e9461d..0a165c1366f6 100644
> --- a/src/ipa/rkisp1/ipa_context.h
> +++ b/src/ipa/rkisp1/ipa_context.h
> @@ -53,8 +53,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 a29dab3403ef..2ffdd99b158a 100644
> --- a/src/ipa/rkisp1/rkisp1.cpp
> +++ b/src/ipa/rkisp1/rkisp1.cpp
> @@ -257,14 +257,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/ipa/rpi/cam_helper/cam_helper.cpp b/src/ipa/rpi/cam_helper/cam_helper.cpp
> index ee5d011f1279..6493e88232a4 100644
> --- a/src/ipa/rpi/cam_helper/cam_helper.cpp
> +++ b/src/ipa/rpi/cam_helper/cam_helper.cpp
> @@ -241,7 +241,7 @@ void CamHelper::parseEmbeddedData(Span<const uint8_t> buffer,
>  		return;
>  	}
>  
> -	deviceStatus.shutterSpeed = parsedDeviceStatus.shutterSpeed;
> +	deviceStatus.exposureTime = parsedDeviceStatus.exposureTime;
>  	deviceStatus.analogueGain = parsedDeviceStatus.analogueGain;
>  	deviceStatus.frameLength = parsedDeviceStatus.frameLength;
>  	deviceStatus.lineLength = parsedDeviceStatus.lineLength;
> diff --git a/src/ipa/rpi/cam_helper/cam_helper_imx219.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx219.cpp
> index 91461f7af7b6..ba01153ebecf 100644
> --- a/src/ipa/rpi/cam_helper/cam_helper_imx219.cpp
> +++ b/src/ipa/rpi/cam_helper/cam_helper_imx219.cpp
> @@ -99,7 +99,7 @@ void CamHelperImx219::populateMetadata(const MdParser::RegisterMap &registers,
>  
>  	deviceStatus.lineLength = lineLengthPckToDuration(registers.at(lineLengthHiReg) * 256 +
>  							  registers.at(lineLengthLoReg));
> -	deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
> +	deviceStatus.exposureTime = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
>  					     deviceStatus.lineLength);
>  	deviceStatus.analogueGain = gain(registers.at(gainReg));
>  	deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
> diff --git a/src/ipa/rpi/cam_helper/cam_helper_imx477.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx477.cpp
> index 6bd89334bf50..a53c40cdf843 100644
> --- a/src/ipa/rpi/cam_helper/cam_helper_imx477.cpp
> +++ b/src/ipa/rpi/cam_helper/cam_helper_imx477.cpp
> @@ -112,7 +112,7 @@ void CamHelperImx477::prepare(libcamera::Span<const uint8_t> buffer, Metadata &m
>  		DeviceStatus parsedDeviceStatus;
>  
>  		metadata.get("device.status", parsedDeviceStatus);
> -		parsedDeviceStatus.shutterSpeed = deviceStatus.shutterSpeed;
> +		parsedDeviceStatus.exposureTime = deviceStatus.exposureTime;
>  		parsedDeviceStatus.frameLength = deviceStatus.frameLength;
>  		metadata.set("device.status", parsedDeviceStatus);
>  
> @@ -180,7 +180,7 @@ void CamHelperImx477::populateMetadata(const MdParser::RegisterMap &registers,
>  
>  	deviceStatus.lineLength = lineLengthPckToDuration(registers.at(lineLengthHiReg) * 256 +
>  							  registers.at(lineLengthLoReg));
> -	deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
> +	deviceStatus.exposureTime = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
>  					     deviceStatus.lineLength);
>  	deviceStatus.analogueGain = gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg));
>  	deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
> diff --git a/src/ipa/rpi/cam_helper/cam_helper_imx519.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx519.cpp
> index c2de3d407d18..2ff086531053 100644
> --- a/src/ipa/rpi/cam_helper/cam_helper_imx519.cpp
> +++ b/src/ipa/rpi/cam_helper/cam_helper_imx519.cpp
> @@ -112,7 +112,7 @@ void CamHelperImx519::prepare(libcamera::Span<const uint8_t> buffer, Metadata &m
>  		DeviceStatus parsedDeviceStatus;
>  
>  		metadata.get("device.status", parsedDeviceStatus);
> -		parsedDeviceStatus.shutterSpeed = deviceStatus.shutterSpeed;
> +		parsedDeviceStatus.exposureTime = deviceStatus.exposureTime;
>  		parsedDeviceStatus.frameLength = deviceStatus.frameLength;
>  		metadata.set("device.status", parsedDeviceStatus);
>  
> @@ -180,7 +180,7 @@ void CamHelperImx519::populateMetadata(const MdParser::RegisterMap &registers,
>  
>  	deviceStatus.lineLength = lineLengthPckToDuration(registers.at(lineLengthHiReg) * 256 +
>  							  registers.at(lineLengthLoReg));
> -	deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
> +	deviceStatus.exposureTime = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
>  					     deviceStatus.lineLength);
>  	deviceStatus.analogueGain = gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg));
>  	deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
> diff --git a/src/ipa/rpi/cam_helper/cam_helper_imx708.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx708.cpp
> index 63ddb55e6674..ec83d9fdaaf2 100644
> --- a/src/ipa/rpi/cam_helper/cam_helper_imx708.cpp
> +++ b/src/ipa/rpi/cam_helper/cam_helper_imx708.cpp
> @@ -155,7 +155,7 @@ void CamHelperImx708::prepare(libcamera::Span<const uint8_t> buffer, Metadata &m
>  		DeviceStatus parsedDeviceStatus;
>  
>  		metadata.get("device.status", parsedDeviceStatus);
> -		parsedDeviceStatus.shutterSpeed = deviceStatus.shutterSpeed;
> +		parsedDeviceStatus.exposureTime = deviceStatus.exposureTime;
>  		parsedDeviceStatus.frameLength = deviceStatus.frameLength;
>  		metadata.set("device.status", parsedDeviceStatus);
>  
> @@ -255,7 +255,7 @@ void CamHelperImx708::populateMetadata(const MdParser::RegisterMap &registers,
>  
>  	deviceStatus.lineLength = lineLengthPckToDuration(registers.at(lineLengthHiReg) * 256 +
>  							  registers.at(lineLengthLoReg));
> -	deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
> +	deviceStatus.exposureTime = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg),
>  					     deviceStatus.lineLength);
>  	deviceStatus.analogueGain = gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg));
>  	deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg);
> diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp
> index 468f36a82ab2..5fce17e67bd6 100644
> --- a/src/ipa/rpi/common/ipa_base.cpp
> +++ b/src/ipa/rpi/common/ipa_base.cpp
> @@ -224,7 +224,7 @@ int32_t IpaBase::configure(const IPACameraSensorInfo &sensorInfo, const ConfigPa
>  
>  		/* Supply initial values for gain and exposure. */
>  		AgcStatus agcStatus;
> -		agcStatus.shutterTime = defaultExposureTime;
> +		agcStatus.exposureTime = defaultExposureTime;
>  		agcStatus.analogueGain = defaultAnalogueGain;
>  		applyAGC(&agcStatus, ctrls);
>  
> @@ -265,8 +265,8 @@ int32_t IpaBase::configure(const IPACameraSensorInfo &sensorInfo, const ConfigPa
>  			    static_cast<float>(mode_.maxAnalogueGain));
>  
>  	ctrlMap[&controls::ExposureTime] =
> -		ControlInfo(static_cast<int32_t>(mode_.minShutter.get<std::micro>()),
> -			    static_cast<int32_t>(mode_.maxShutter.get<std::micro>()));
> +		ControlInfo(static_cast<int32_t>(mode_.minExposureTime.get<std::micro>()),
> +			    static_cast<int32_t>(mode_.maxExposureTime.get<std::micro>()));
>  
>  	/* Declare colour processing related controls for non-mono sensors. */
>  	if (!monoSensor_)
> @@ -299,11 +299,11 @@ void IpaBase::start(const ControlList &controls, StartResult *result)
>  
>  	/* SwitchMode may supply updated exposure/gain values to use. */
>  	AgcStatus agcStatus;
> -	agcStatus.shutterTime = 0.0s;
> +	agcStatus.exposureTime = 0.0s;
>  	agcStatus.analogueGain = 0.0;
>  
>  	metadata.get("agc.status", agcStatus);
> -	if (agcStatus.shutterTime && agcStatus.analogueGain) {
> +	if (agcStatus.exposureTime && agcStatus.analogueGain) {
>  		ControlList ctrls(sensorCtrls_);
>  		applyAGC(&agcStatus, ctrls);
>  		result->controls = std::move(ctrls);
> @@ -599,7 +599,7 @@ void IpaBase::setMode(const IPACameraSensorInfo &sensorInfo)
>  	mode_.sensitivity = helper_->getModeSensitivity(mode_);
>  
>  	const ControlInfo &gainCtrl = sensorCtrls_.at(V4L2_CID_ANALOGUE_GAIN);
> -	const ControlInfo &shutterCtrl = sensorCtrls_.at(V4L2_CID_EXPOSURE);
> +	const ControlInfo &exposureTimeCtrl = sensorCtrls_.at(V4L2_CID_EXPOSURE);
>  
>  	mode_.minAnalogueGain = helper_->gain(gainCtrl.min().get<int32_t>());
>  	mode_.maxAnalogueGain = helper_->gain(gainCtrl.max().get<int32_t>());
> @@ -610,11 +610,15 @@ void IpaBase::setMode(const IPACameraSensorInfo &sensorInfo)
>  	 */
>  	helper_->setCameraMode(mode_);
>  
> -	/* Shutter speed is calculated based on the limits of the frame durations. */
> -	mode_.minShutter = helper_->exposure(shutterCtrl.min().get<int32_t>(), mode_.minLineLength);
> -	mode_.maxShutter = Duration::max();
> -	helper_->getBlanking(mode_.maxShutter,
> -			     mode_.minFrameDuration, mode_.maxFrameDuration);
> +	/*
> +	 * Exposure time is calculated based on the limits of the frame
> +	 * durations.
> +	 */
> +	mode_.minExposureTime = helper_->exposure(exposureTimeCtrl.min().get<int32_t>(),
> +						  mode_.minLineLength);
> +	mode_.maxExposureTime = Duration::max();
> +	helper_->getBlanking(mode_.maxExposureTime, mode_.minFrameDuration,
> +			     mode_.maxFrameDuration);
>  }
>  
>  void IpaBase::setCameraTimeoutValue()
> @@ -788,7 +792,7 @@ void IpaBase::applyControls(const ControlList &controls)
>  			}
>  
>  			/* The control provides units of microseconds. */
> -			agc->setFixedShutter(0, ctrl.second.get<int32_t>() * 1.0us);
> +			agc->setFixedExposureTime(0, ctrl.second.get<int32_t>() * 1.0us);
>  
>  			libcameraMetadata_.set(controls::ExposureTime, ctrl.second.get<int32_t>());
>  			break;
> @@ -1281,7 +1285,7 @@ void IpaBase::fillDeviceStatus(const ControlList &sensorControls, unsigned int i
>  	int32_t hblank = sensorControls.get(V4L2_CID_HBLANK).get<int32_t>();
>  
>  	deviceStatus.lineLength = helper_->hblankToLineLength(hblank);
> -	deviceStatus.shutterSpeed = helper_->exposure(exposureLines, deviceStatus.lineLength);
> +	deviceStatus.exposureTime = helper_->exposure(exposureLines, deviceStatus.lineLength);
>  	deviceStatus.analogueGain = helper_->gain(gainCode);
>  	deviceStatus.frameLength = mode_.height + vblank;
>  
> @@ -1308,7 +1312,7 @@ void IpaBase::reportMetadata(unsigned int ipaContext)
>  	DeviceStatus *deviceStatus = rpiMetadata.getLocked<DeviceStatus>("device.status");
>  	if (deviceStatus) {
>  		libcameraMetadata_.set(controls::ExposureTime,
> -				       deviceStatus->shutterSpeed.get<std::micro>());
> +				       deviceStatus->exposureTime.get<std::micro>());
>  		libcameraMetadata_.set(controls::AnalogueGain, deviceStatus->analogueGain);
>  		libcameraMetadata_.set(controls::FrameDuration,
>  				       helper_->exposure(deviceStatus->frameLength, deviceStatus->lineLength).get<std::micro>());
> @@ -1459,15 +1463,15 @@ void IpaBase::applyFrameDurations(Duration minFrameDuration, Duration maxFrameDu
>  
>  	/*
>  	 * Calculate the maximum exposure time possible for the AGC to use.
> -	 * getBlanking() will update maxShutter with the largest exposure
> +	 * getBlanking() will update maxExposureTime with the largest exposure
>  	 * value possible.
>  	 */
> -	Duration maxShutter = Duration::max();
> -	helper_->getBlanking(maxShutter, minFrameDuration_, maxFrameDuration_);
> +	Duration maxExposureTime = Duration::max();
> +	helper_->getBlanking(maxExposureTime, minFrameDuration_, maxFrameDuration_);
>  
>  	RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
>  		controller_.getAlgorithm("agc"));
> -	agc->setMaxShutter(maxShutter);
> +	agc->setMaxExposureTime(maxExposureTime);
>  }
>  
>  void IpaBase::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls)
> @@ -1484,14 +1488,14 @@ void IpaBase::applyAGC(const struct AgcStatus *agcStatus, ControlList &ctrls)
>  	gainCode = std::clamp<int32_t>(gainCode, minGainCode, maxGainCode);
>  
>  	/* getBlanking might clip exposure time to the fps limits. */
> -	Duration exposure = agcStatus->shutterTime;
> +	Duration exposure = agcStatus->exposureTime;
>  	auto [vblank, hblank] = helper_->getBlanking(exposure, minFrameDuration_, maxFrameDuration_);
>  	int32_t exposureLines = helper_->exposureLines(exposure,
>  						       helper_->hblankToLineLength(hblank));
>  
>  	LOG(IPARPI, Debug) << "Applying AGC Exposure: " << exposure
> -			   << " (Shutter lines: " << exposureLines << ", AGC requested "
> -			   << agcStatus->shutterTime << ") Gain: "
> +			   << " (Exposure lines: " << exposureLines << ", AGC requested "
> +			   << agcStatus->exposureTime << ") Gain: "
>  			   << agcStatus->analogueGain << " (Gain Code: "
>  			   << gainCode << ")";
>  
> diff --git a/src/ipa/rpi/controller/agc_algorithm.h b/src/ipa/rpi/controller/agc_algorithm.h
> index 1132de7e050e..c97828577602 100644
> --- a/src/ipa/rpi/controller/agc_algorithm.h
> +++ b/src/ipa/rpi/controller/agc_algorithm.h
> @@ -23,9 +23,9 @@ public:
>  	virtual std::vector<double> const &getWeights() const = 0;
>  	virtual void setEv(unsigned int channel, double ev) = 0;
>  	virtual void setFlickerPeriod(libcamera::utils::Duration flickerPeriod) = 0;
> -	virtual void setFixedShutter(unsigned int channel,
> -				     libcamera::utils::Duration fixedShutter) = 0;
> -	virtual void setMaxShutter(libcamera::utils::Duration maxShutter) = 0;
> +	virtual void setFixedExposureTime(unsigned int channel,
> +					  libcamera::utils::Duration fixedExposureTime) = 0;
> +	virtual void setMaxExposureTime(libcamera::utils::Duration maxExposureTime) = 0;
>  	virtual void setFixedAnalogueGain(unsigned int channel, double fixedAnalogueGain) = 0;
>  	virtual void setMeteringMode(std::string const &meteringModeName) = 0;
>  	virtual void setExposureMode(std::string const &exposureModeName) = 0;
> diff --git a/src/ipa/rpi/controller/agc_status.h b/src/ipa/rpi/controller/agc_status.h
> index c7c87b83a196..9308b156051c 100644
> --- a/src/ipa/rpi/controller/agc_status.h
> +++ b/src/ipa/rpi/controller/agc_status.h
> @@ -28,7 +28,7 @@
>  struct AgcStatus {
>  	libcamera::utils::Duration totalExposureValue; /* value for all exposure and gain for this image */
>  	libcamera::utils::Duration targetExposureValue; /* (unfiltered) target total exposure AGC is aiming for */
> -	libcamera::utils::Duration shutterTime;
> +	libcamera::utils::Duration exposureTime;
>  	double analogueGain;
>  	std::string exposureMode;
>  	std::string constraintMode;
> @@ -36,7 +36,7 @@ struct AgcStatus {
>  	double ev;
>  	libcamera::utils::Duration flickerPeriod;
>  	int floatingRegionEnable;
> -	libcamera::utils::Duration fixedShutter;
> +	libcamera::utils::Duration fixedExposureTime;
>  	double fixedAnalogueGain;
>  	unsigned int channel;
>  	HdrStatus hdr;
> diff --git a/src/ipa/rpi/controller/camera_mode.h b/src/ipa/rpi/controller/camera_mode.h
> index 4fdb5b85b299..61162b3276d6 100644
> --- a/src/ipa/rpi/controller/camera_mode.h
> +++ b/src/ipa/rpi/controller/camera_mode.h
> @@ -50,9 +50,9 @@ struct CameraMode {
>  	double sensitivity;
>  	/* pixel clock rate */
>  	uint64_t pixelRate;
> -	/* Mode specific shutter speed limits */
> -	libcamera::utils::Duration minShutter;
> -	libcamera::utils::Duration maxShutter;
> +	/* Mode specific exposure time limits */
> +	libcamera::utils::Duration minExposureTime;
> +	libcamera::utils::Duration maxExposureTime;
>  	/* Mode specific analogue gain limits */
>  	double minAnalogueGain;
>  	double maxAnalogueGain;
> diff --git a/src/ipa/rpi/controller/device_status.cpp b/src/ipa/rpi/controller/device_status.cpp
> index 68100137323a..1695764d2fa1 100644
> --- a/src/ipa/rpi/controller/device_status.cpp
> +++ b/src/ipa/rpi/controller/device_status.cpp
> @@ -10,7 +10,7 @@ using namespace libcamera; /* for the Duration operator<< overload */
>  
>  std::ostream &operator<<(std::ostream &out, const DeviceStatus &d)
>  {
> -	out << "Exposure: " << d.shutterSpeed
> +	out << "Exposure time: " << d.exposureTime
>  	    << " Frame length: " << d.frameLength
>  	    << " Line length: " << d.lineLength
>  	    << " Gain: " << d.analogueGain;
> diff --git a/src/ipa/rpi/controller/device_status.h b/src/ipa/rpi/controller/device_status.h
> index 518f15b5a5a6..b1792035c55e 100644
> --- a/src/ipa/rpi/controller/device_status.h
> +++ b/src/ipa/rpi/controller/device_status.h
> @@ -12,21 +12,21 @@
>  #include <libcamera/base/utils.h>
>  
>  /*
> - * Definition of "device metadata" which stores things like shutter time and
> + * Definition of "device metadata" which stores things like exposure time and
>   * analogue gain that downstream control algorithms will want to know.
>   */
>  
>  struct DeviceStatus {
>  	DeviceStatus()
> -		: shutterSpeed(std::chrono::seconds(0)), frameLength(0),
> +		: exposureTime(std::chrono::seconds(0)), frameLength(0),
>  		  lineLength(std::chrono::seconds(0)), analogueGain(0.0)
>  	{
>  	}
>  
>  	friend std::ostream &operator<<(std::ostream &out, const DeviceStatus &d);
>  
> -	/* time shutter is open */
> -	libcamera::utils::Duration shutterSpeed;
> +	/* time the image is exposed */
> +	libcamera::utils::Duration exposureTime;
>  	/* frame length given in number of lines */
>  	uint32_t frameLength;
>  	/* line length for the current frame */
> diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp
> index fcf7aec99375..c48fdf156591 100644
> --- a/src/ipa/rpi/controller/rpi/agc.cpp
> +++ b/src/ipa/rpi/controller/rpi/agc.cpp
> @@ -127,21 +127,21 @@ void Agc::setFlickerPeriod(Duration flickerPeriod)
>  		data.channel.setFlickerPeriod(flickerPeriod);
>  }
>  
> -void Agc::setMaxShutter(Duration maxShutter)
> +void Agc::setMaxExposureTime(Duration maxExposureTime)
>  {
>  	/* Frame durations will be the same across all channels too. */
>  	for (auto &data : channelData_)
> -		data.channel.setMaxShutter(maxShutter);
> +		data.channel.setMaxExposureTime(maxExposureTime);
>  }
>  
> -void Agc::setFixedShutter(unsigned int channelIndex, Duration fixedShutter)
> +void Agc::setFixedExposureTime(unsigned int channelIndex, Duration fixedExposureTime)
>  {
>  	if (checkChannel(channelIndex))
>  		return;
>  
> -	LOG(RPiAgc, Debug) << "setFixedShutter " << fixedShutter
> +	LOG(RPiAgc, Debug) << "setFixedExposureTime " << fixedExposureTime
>  			   << " for channel " << channelIndex;
> -	channelData_[channelIndex].channel.setFixedShutter(fixedShutter);
> +	channelData_[channelIndex].channel.setFixedExposureTime(fixedExposureTime);
>  }
>  
>  void Agc::setFixedAnalogueGain(unsigned int channelIndex, double fixedAnalogueGain)
> diff --git a/src/ipa/rpi/controller/rpi/agc.h b/src/ipa/rpi/controller/rpi/agc.h
> index 5d056f02e2ac..3aca000bb4c2 100644
> --- a/src/ipa/rpi/controller/rpi/agc.h
> +++ b/src/ipa/rpi/controller/rpi/agc.h
> @@ -32,9 +32,9 @@ public:
>  	std::vector<double> const &getWeights() const override;
>  	void setEv(unsigned int channel, double ev) override;
>  	void setFlickerPeriod(libcamera::utils::Duration flickerPeriod) override;
> -	void setMaxShutter(libcamera::utils::Duration maxShutter) override;
> -	void setFixedShutter(unsigned int channelIndex,
> -			     libcamera::utils::Duration fixedShutter) override;
> +	void setMaxExposureTime(libcamera::utils::Duration maxExposureTime) override;
> +	void setFixedExposureTime(unsigned int channelIndex,
> +				  libcamera::utils::Duration fixedExposureTime) override;
>  	void setFixedAnalogueGain(unsigned int channelIndex,
>  				  double fixedAnalogueGain) override;
>  	void setMeteringMode(std::string const &meteringModeName) override;
> diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp
> index 8583f4f31907..143359437f3a 100644
> --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp
> +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp
> @@ -67,7 +67,7 @@ int AgcExposureMode::read(const libcamera::YamlObject &params)
>  	auto value = params["shutter"].getList<double>();
>  	if (!value)
>  		return -EINVAL;
> -	std::transform(value->begin(), value->end(), std::back_inserter(shutter),
> +	std::transform(value->begin(), value->end(), std::back_inserter(exposureTime),
>  		       [](double v) { return v * 1us; });
>  
>  	value = params["gain"].getList<double>();
> @@ -75,13 +75,13 @@ int AgcExposureMode::read(const libcamera::YamlObject &params)
>  		return -EINVAL;
>  	gain = std::move(*value);
>  
> -	if (shutter.size() < 2 || gain.size() < 2) {
> +	if (exposureTime.size() < 2 || gain.size() < 2) {
>  		LOG(RPiAgc, Error)
>  			<< "AgcExposureMode: must have at least two entries in exposure profile";
>  		return -EINVAL;
>  	}
>  
> -	if (shutter.size() != gain.size()) {
> +	if (exposureTime.size() != gain.size()) {
>  		LOG(RPiAgc, Error)
>  			<< "AgcExposureMode: expect same number of exposure and gain entries in exposure profile";
>  		return -EINVAL;
> @@ -262,7 +262,7 @@ int AgcConfig::read(const libcamera::YamlObject &params)
>  }
>  
>  AgcChannel::ExposureValues::ExposureValues()
> -	: shutter(0s), analogueGain(0),
> +	: exposureTime(0s), analogueGain(0),
>  	  totalExposure(0s), totalExposureNoDG(0s)
>  {
>  }
> @@ -271,7 +271,7 @@ AgcChannel::AgcChannel()
>  	: meteringMode_(nullptr), exposureMode_(nullptr), constraintMode_(nullptr),
>  	  frameCount_(0), lockCount_(0),
>  	  lastTargetExposure_(0s), ev_(1.0), flickerPeriod_(0s),
> -	  maxShutter_(0s), fixedShutter_(0s), fixedAnalogueGain_(0.0)
> +	  maxExposureTime_(0s), fixedExposureTime_(0s), fixedAnalogueGain_(0.0)
>  {
>  	/* Set AWB default values in case early frames have no updates in metadata. */
>  	awb_.gainR = 1.0;
> @@ -312,31 +312,31 @@ int AgcChannel::read(const libcamera::YamlObject &params,
>  	exposureMode_ = &config_.exposureModes[exposureModeName_];
>  	constraintModeName_ = config_.defaultConstraintMode;
>  	constraintMode_ = &config_.constraintModes[constraintModeName_];
> -	/* Set up the "last shutter/gain" values, in case AGC starts "disabled". */
> -	status_.shutterTime = config_.defaultExposureTime;
> +	/* Set up the "last exposure time/gain" values, in case AGC starts "disabled". */
> +	status_.exposureTime = config_.defaultExposureTime;
>  	status_.analogueGain = config_.defaultAnalogueGain;
>  	return 0;
>  }
>  
>  void AgcChannel::disableAuto()
>  {
> -	fixedShutter_ = status_.shutterTime;
> +	fixedExposureTime_ = status_.exposureTime;
>  	fixedAnalogueGain_ = status_.analogueGain;
>  }
>  
>  void AgcChannel::enableAuto()
>  {
> -	fixedShutter_ = 0s;
> +	fixedExposureTime_ = 0s;
>  	fixedAnalogueGain_ = 0;
>  }
>  
>  unsigned int AgcChannel::getConvergenceFrames() const
>  {
>  	/*
> -	 * If shutter and gain have been explicitly set, there is no
> +	 * If exposure time and gain have been explicitly set, there is no
>  	 * convergence to happen, so no need to drop any frames - return zero.
>  	 */
> -	if (fixedShutter_ && fixedAnalogueGain_)
> +	if (fixedExposureTime_ && fixedAnalogueGain_)
>  		return 0;
>  	else
>  		return config_.convergenceFrames;
> @@ -364,16 +364,16 @@ void AgcChannel::setFlickerPeriod(Duration flickerPeriod)
>  	flickerPeriod_ = flickerPeriod;
>  }
>  
> -void AgcChannel::setMaxShutter(Duration maxShutter)
> +void AgcChannel::setMaxExposureTime(Duration maxExposureTime)
>  {
> -	maxShutter_ = maxShutter;
> +	maxExposureTime_ = maxExposureTime;
>  }
>  
> -void AgcChannel::setFixedShutter(Duration fixedShutter)
> +void AgcChannel::setFixedExposureTime(Duration fixedExposureTime)
>  {
> -	fixedShutter_ = fixedShutter;
> +	fixedExposureTime_ = fixedExposureTime;
>  	/* Set this in case someone calls disableAuto() straight after. */
> -	status_.shutterTime = limitShutter(fixedShutter_);
> +	status_.exposureTime = limitExposureTime(fixedExposureTime_);
>  }
>  
>  void AgcChannel::setFixedAnalogueGain(double fixedAnalogueGain)
> @@ -413,22 +413,22 @@ void AgcChannel::switchMode(CameraMode const &cameraMode,
>  	double lastSensitivity = mode_.sensitivity;
>  	mode_ = cameraMode;
>  
> -	Duration fixedShutter = limitShutter(fixedShutter_);
> -	if (fixedShutter && fixedAnalogueGain_) {
> +	Duration fixedExposureTime = limitExposureTime(fixedExposureTime_);
> +	if (fixedExposureTime && fixedAnalogueGain_) {
>  		/* We're going to reset the algorithm here with these fixed values. */
>  		fetchAwbStatus(metadata);
>  		double minColourGain = std::min({ awb_.gainR, awb_.gainG, awb_.gainB, 1.0 });
>  		ASSERT(minColourGain != 0.0);
>  
>  		/* This is the equivalent of computeTargetExposure and applyDigitalGain. */
> -		target_.totalExposureNoDG = fixedShutter_ * fixedAnalogueGain_;
> +		target_.totalExposureNoDG = fixedExposureTime_ * fixedAnalogueGain_;
>  		target_.totalExposure = target_.totalExposureNoDG / minColourGain;
>  
>  		/* Equivalent of filterExposure. This resets any "history". */
>  		filtered_ = target_;
>  
>  		/* Equivalent of divideUpExposure. */
> -		filtered_.shutter = fixedShutter;
> +		filtered_.exposureTime = fixedExposureTime;
>  		filtered_.analogueGain = fixedAnalogueGain_;
>  	} else if (status_.totalExposureValue) {
>  		/*
> @@ -450,14 +450,15 @@ void AgcChannel::switchMode(CameraMode const &cameraMode,
>  		divideUpExposure();
>  	} else {
>  		/*
> -		 * We come through here on startup, when at least one of the shutter
> -		 * or gain has not been fixed. We must still write those values out so
> -		 * that they will be applied immediately. We supply some arbitrary defaults
> -		 * for any that weren't set.
> +		 * We come through here on startup, when at least one of the
> +		 * exposure time or gain has not been fixed. We must still
> +		 * write those values out so that they will be applied
> +		 * immediately. We supply some arbitrary defaults for any that
> +		 * weren't set.
>  		 */
>  
>  		/* Equivalent of divideUpExposure. */
> -		filtered_.shutter = fixedShutter ? fixedShutter : config_.defaultExposureTime;
> +		filtered_.exposureTime = fixedExposureTime ? fixedExposureTime : config_.defaultExposureTime;
>  		filtered_.analogueGain = fixedAnalogueGain_ ? fixedAnalogueGain_ : config_.defaultAnalogueGain;
>  	}
>  
> @@ -483,7 +484,7 @@ void AgcChannel::prepare(Metadata *imageMetadata)
>  		/* Process has run, so we have meaningful values. */
>  		DeviceStatus deviceStatus;
>  		if (imageMetadata->get("device.status", deviceStatus) == 0) {
> -			Duration actualExposure = deviceStatus.shutterSpeed *
> +			Duration actualExposure = deviceStatus.exposureTime *
>  						  deviceStatus.analogueGain;
>  			if (actualExposure) {
>  				double digitalGain = totalExposureValue / actualExposure;
> @@ -537,7 +538,7 @@ void AgcChannel::process(StatisticsPtr &stats, DeviceStatus const &deviceStatus,
>  	 */
>  	bool desaturate = applyDigitalGain(gain, targetY, channelBound);
>  	/*
> -	 * The last thing is to divide up the exposure value into a shutter time
> +	 * The last thing is to divide up the exposure value into a exposure time
>  	 * and analogue gain, according to the current exposure mode.
>  	 */
>  	divideUpExposure();
> @@ -553,7 +554,7 @@ bool AgcChannel::updateLockStatus(DeviceStatus const &deviceStatus)
>  	const double resetMargin = 1.5;
>  
>  	/* Add 200us to the exposure time error to allow for line quantisation. */
> -	Duration exposureError = lastDeviceStatus_.shutterSpeed * errorFactor + 200us;
> +	Duration exposureError = lastDeviceStatus_.exposureTime * errorFactor + 200us;
>  	double gainError = lastDeviceStatus_.analogueGain * errorFactor;
>  	Duration targetError = lastTargetExposure_ * errorFactor;
>  
> @@ -562,15 +563,15 @@ bool AgcChannel::updateLockStatus(DeviceStatus const &deviceStatus)
>  	 * the values we keep requesting may be unachievable. For this reason
>  	 * we only insist that we're close to values in the past few frames.
>  	 */
> -	if (deviceStatus.shutterSpeed > lastDeviceStatus_.shutterSpeed - exposureError &&
> -	    deviceStatus.shutterSpeed < lastDeviceStatus_.shutterSpeed + exposureError &&
> +	if (deviceStatus.exposureTime > lastDeviceStatus_.exposureTime - exposureError &&
> +	    deviceStatus.exposureTime < lastDeviceStatus_.exposureTime + exposureError &&
>  	    deviceStatus.analogueGain > lastDeviceStatus_.analogueGain - gainError &&
>  	    deviceStatus.analogueGain < lastDeviceStatus_.analogueGain + gainError &&
>  	    status_.targetExposureValue > lastTargetExposure_ - targetError &&
>  	    status_.targetExposureValue < lastTargetExposure_ + targetError)
>  		lockCount_ = std::min(lockCount_ + 1, maxLockCount);
> -	else if (deviceStatus.shutterSpeed < lastDeviceStatus_.shutterSpeed - resetMargin * exposureError ||
> -		 deviceStatus.shutterSpeed > lastDeviceStatus_.shutterSpeed + resetMargin * exposureError ||
> +	else if (deviceStatus.exposureTime < lastDeviceStatus_.exposureTime - resetMargin * exposureError ||
> +		 deviceStatus.exposureTime > lastDeviceStatus_.exposureTime + resetMargin * exposureError ||
>  		 deviceStatus.analogueGain < lastDeviceStatus_.analogueGain - resetMargin * gainError ||
>  		 deviceStatus.analogueGain > lastDeviceStatus_.analogueGain + resetMargin * gainError ||
>  		 status_.targetExposureValue < lastTargetExposure_ - resetMargin * targetError ||
> @@ -588,11 +589,11 @@ void AgcChannel::housekeepConfig()
>  {
>  	/* First fetch all the up-to-date settings, so no one else has to do it. */
>  	status_.ev = ev_;
> -	status_.fixedShutter = limitShutter(fixedShutter_);
> +	status_.fixedExposureTime = limitExposureTime(fixedExposureTime_);
>  	status_.fixedAnalogueGain = fixedAnalogueGain_;
>  	status_.flickerPeriod = flickerPeriod_;
> -	LOG(RPiAgc, Debug) << "ev " << status_.ev << " fixedShutter "
> -			   << status_.fixedShutter << " fixedAnalogueGain "
> +	LOG(RPiAgc, Debug) << "ev " << status_.ev << " fixedExposureTime "
> +			   << status_.fixedExposureTime << " fixedAnalogueGain "
>  			   << status_.fixedAnalogueGain;
>  	/*
>  	 * Make sure the "mode" pointers point to the up-to-date things, if
> @@ -636,10 +637,10 @@ void AgcChannel::housekeepConfig()
>  
>  void AgcChannel::fetchCurrentExposure(DeviceStatus const &deviceStatus)
>  {
> -	current_.shutter = deviceStatus.shutterSpeed;
> +	current_.exposureTime = deviceStatus.exposureTime;
>  	current_.analogueGain = deviceStatus.analogueGain;
>  	current_.totalExposure = 0s; /* this value is unused */
> -	current_.totalExposureNoDG = current_.shutter * current_.analogueGain;
> +	current_.totalExposureNoDG = current_.exposureTime * current_.analogueGain;
>  }
>  
>  void AgcChannel::fetchAwbStatus(Metadata *imageMetadata)
> @@ -777,17 +778,17 @@ void AgcChannel::computeGain(StatisticsPtr &statistics, Metadata *imageMetadata,
>  
>  void AgcChannel::computeTargetExposure(double gain)
>  {
> -	if (status_.fixedShutter && status_.fixedAnalogueGain) {
> +	if (status_.fixedExposureTime && status_.fixedAnalogueGain) {
>  		/*
> -		 * When ag and shutter are both fixed, we need to drive the
> -		 * total exposure so that we end up with a digital gain of at least
> -		 * 1/minColourGain. Otherwise we'd desaturate channels causing
> -		 * white to go cyan or magenta.
> +		 * When analogue gain and exposure time are both fixed, we need
> +		 * to drive the total exposure so that we end up with a digital
> +		 * gain of at least 1/minColourGain. Otherwise we'd desaturate
> +		 * channels causing white to go cyan or magenta.
>  		 */
>  		double minColourGain = std::min({ awb_.gainR, awb_.gainG, awb_.gainB, 1.0 });
>  		ASSERT(minColourGain != 0.0);
>  		target_.totalExposure =
> -			status_.fixedShutter * status_.fixedAnalogueGain / minColourGain;
> +			status_.fixedExposureTime * status_.fixedAnalogueGain / minColourGain;
>  	} else {
>  		/*
>  		 * The statistics reflect the image without digital gain, so the final
> @@ -795,12 +796,12 @@ void AgcChannel::computeTargetExposure(double gain)
>  		 */
>  		target_.totalExposure = current_.totalExposureNoDG * gain;
>  		/* The final target exposure is also limited to what the exposure mode allows. */
> -		Duration maxShutter = status_.fixedShutter
> -					      ? status_.fixedShutter
> -					      : exposureMode_->shutter.back();
> -		maxShutter = limitShutter(maxShutter);
> +		Duration maxExposureTime = status_.fixedExposureTime
> +					 ? status_.fixedExposureTime
> +					 : exposureMode_->exposureTime.back();
> +		maxExposureTime = limitExposureTime(maxExposureTime);
>  		Duration maxTotalExposure =
> -			maxShutter *
> +			maxExposureTime *
>  			(status_.fixedAnalogueGain != 0.0
>  				 ? status_.fixedAnalogueGain
>  				 : exposureMode_->gain.back());
> @@ -884,11 +885,12 @@ void AgcChannel::filterExposure()
>  	double stableRegion = config_.stableRegion;
>  
>  	/*
> -	 * AGC adapts instantly if both shutter and gain are directly specified
> -	 * or we're in the startup phase. Also disable the stable region, because we want
> -	 * to reflect any user exposure/gain updates, however small.
> +	 * AGC adapts instantly if both exposure time and gain are directly
> +	 * specified or we're in the startup phase. Also disable the stable
> +	 * region, because we want to reflect any user exposure/gain updates,
> +	 * however small.
>  	 */
> -	if ((status_.fixedShutter && status_.fixedAnalogueGain) ||
> +	if ((status_.fixedExposureTime && status_.fixedAnalogueGain) ||
>  	    frameCount_ <= config_.startupFrames) {
>  		speed = 1.0;
>  		stableRegion = 0.0;
> @@ -916,34 +918,34 @@ void AgcChannel::filterExposure()
>  void AgcChannel::divideUpExposure()
>  {
>  	/*
> -	 * Sending the fixed shutter/gain cases through the same code may seem
> -	 * unnecessary, but it will make more sense when extend this to cover
> -	 * variable aperture.
> +	 * Sending the fixed exposure time/gain cases through the same code may
> +	 * seem unnecessary, but it will make more sense when extend this to
> +	 * cover variable aperture.
>  	 */
>  	Duration exposureValue = filtered_.totalExposureNoDG;
> -	Duration shutterTime;
> +	Duration exposureTime;
>  	double analogueGain;
> -	shutterTime = status_.fixedShutter ? status_.fixedShutter
> -					   : exposureMode_->shutter[0];
> -	shutterTime = limitShutter(shutterTime);
> +	exposureTime = status_.fixedExposureTime ? status_.fixedExposureTime
> +						 : exposureMode_->exposureTime[0];
> +	exposureTime = limitExposureTime(exposureTime);
>  	analogueGain = status_.fixedAnalogueGain != 0.0 ? status_.fixedAnalogueGain
>  							: exposureMode_->gain[0];
>  	analogueGain = limitGain(analogueGain);
> -	if (shutterTime * analogueGain < exposureValue) {
> +	if (exposureTime * analogueGain < exposureValue) {
>  		for (unsigned int stage = 1;
>  		     stage < exposureMode_->gain.size(); stage++) {
> -			if (!status_.fixedShutter) {
> -				Duration stageShutter =
> -					limitShutter(exposureMode_->shutter[stage]);
> -				if (stageShutter * analogueGain >= exposureValue) {
> -					shutterTime = exposureValue / analogueGain;
> +			if (!status_.fixedExposureTime) {
> +				Duration stageExposureTime =
> +					limitExposureTime(exposureMode_->exposureTime[stage]);
> +				if (stageExposureTime * analogueGain >= exposureValue) {
> +					exposureTime = exposureValue / analogueGain;
>  					break;
>  				}
> -				shutterTime = stageShutter;
> +				exposureTime = stageExposureTime;
>  			}
>  			if (status_.fixedAnalogueGain == 0.0) {
> -				if (exposureMode_->gain[stage] * shutterTime >= exposureValue) {
> -					analogueGain = exposureValue / shutterTime;
> +				if (exposureMode_->gain[stage] * exposureTime >= exposureValue) {
> +					analogueGain = exposureValue / exposureTime;
>  					break;
>  				}
>  				analogueGain = exposureMode_->gain[stage];
> @@ -951,18 +953,19 @@ void AgcChannel::divideUpExposure()
>  			}
>  		}
>  	}
> -	LOG(RPiAgc, Debug) << "Divided up shutter and gain are " << shutterTime << " and "
> -			   << analogueGain;
> +	LOG(RPiAgc, Debug)
> +		<< "Divided up exposure time and gain are " << exposureTime
> +		<< " and " << analogueGain;
>  	/*
> -	 * Finally adjust shutter time for flicker avoidance (require both
> -	 * shutter and gain not to be fixed).
> +	 * Finally adjust exposure time for flicker avoidance (require both
> +	 * exposure time and gain not to be fixed).
>  	 */
> -	if (!status_.fixedShutter && !status_.fixedAnalogueGain &&
> +	if (!status_.fixedExposureTime && !status_.fixedAnalogueGain &&
>  	    status_.flickerPeriod) {
> -		int flickerPeriods = shutterTime / status_.flickerPeriod;
> +		int flickerPeriods = exposureTime / status_.flickerPeriod;
>  		if (flickerPeriods) {
> -			Duration newShutterTime = flickerPeriods * status_.flickerPeriod;
> -			analogueGain *= shutterTime / newShutterTime;
> +			Duration newExposureTime = flickerPeriods * status_.flickerPeriod;
> +			analogueGain *= exposureTime / newExposureTime;
>  			/*
>  			 * We should still not allow the ag to go over the
>  			 * largest value in the exposure mode. Note that this
> @@ -971,12 +974,12 @@ void AgcChannel::divideUpExposure()
>  			 */
>  			analogueGain = std::min(analogueGain, exposureMode_->gain.back());
>  			analogueGain = limitGain(analogueGain);
> -			shutterTime = newShutterTime;
> +			exposureTime = newExposureTime;
>  		}
> -		LOG(RPiAgc, Debug) << "After flicker avoidance, shutter "
> -				   << shutterTime << " gain " << analogueGain;
> +		LOG(RPiAgc, Debug) << "After flicker avoidance, exposure time "
> +				   << exposureTime << " gain " << analogueGain;
>  	}
> -	filtered_.shutter = shutterTime;
> +	filtered_.exposureTime = exposureTime;
>  	filtered_.analogueGain = analogueGain;
>  }
>  
> @@ -984,7 +987,7 @@ void AgcChannel::writeAndFinish(Metadata *imageMetadata, bool desaturate)
>  {
>  	status_.totalExposureValue = filtered_.totalExposure;
>  	status_.targetExposureValue = desaturate ? 0s : target_.totalExposure;
> -	status_.shutterTime = filtered_.shutter;
> +	status_.exposureTime = filtered_.exposureTime;
>  	status_.analogueGain = filtered_.analogueGain;
>  	/*
>  	 * Write to metadata as well, in case anyone wants to update the camera
> @@ -993,32 +996,32 @@ void AgcChannel::writeAndFinish(Metadata *imageMetadata, bool desaturate)
>  	imageMetadata->set("agc.status", status_);
>  	LOG(RPiAgc, Debug) << "Output written, total exposure requested is "
>  			   << filtered_.totalExposure;
> -	LOG(RPiAgc, Debug) << "Camera exposure update: shutter time " << filtered_.shutter
> +	LOG(RPiAgc, Debug) << "Camera exposure update: exposure time " << filtered_.exposureTime
>  			   << " analogue gain " << filtered_.analogueGain;
>  }
>  
> -Duration AgcChannel::limitShutter(Duration shutter)
> +Duration AgcChannel::limitExposureTime(Duration exposureTime)
>  {
>  	/*
> -	 * shutter == 0 is a special case for fixed shutter values, and must pass
> -	 * through unchanged
> +	 * exposureTime == 0 is a special case for fixed exposure time values,
> +	 * and must pass through unchanged.
>  	 */
> -	if (!shutter)
> -		return shutter;
> +	if (!exposureTime)
> +		return exposureTime;
>  
> -	shutter = std::clamp(shutter, mode_.minShutter, maxShutter_);
> -	return shutter;
> +	exposureTime = std::clamp(exposureTime, mode_.minExposureTime, maxExposureTime_);
> +	return exposureTime;
>  }
>  
>  double AgcChannel::limitGain(double gain) const
>  {
>  	/*
> -	 * Only limit the lower bounds of the gain value to what the sensor limits.
> -	 * The upper bound on analogue gain will be made up with additional digital
> -	 * gain applied by the ISP.
> +	 * Only limit the lower bounds of the gain value to what the sensor
> +	 * limits. The upper bound on analogue gain will be made up with
> +	 * additional digital gain applied by the ISP.
>  	 *
> -	 * gain == 0.0 is a special case for fixed shutter values, and must pass
> -	 * through unchanged
> +	 * gain == 0.0 is a special case for fixed exposure time values, and
> +	 * must pass through unchanged.
>  	 */
>  	if (!gain)
>  		return gain;
> diff --git a/src/ipa/rpi/controller/rpi/agc_channel.h b/src/ipa/rpi/controller/rpi/agc_channel.h
> index 58368889e6a2..734e5efd3266 100644
> --- a/src/ipa/rpi/controller/rpi/agc_channel.h
> +++ b/src/ipa/rpi/controller/rpi/agc_channel.h
> @@ -30,7 +30,7 @@ struct AgcMeteringMode {
>  };
>  
>  struct AgcExposureMode {
> -	std::vector<libcamera::utils::Duration> shutter;
> +	std::vector<libcamera::utils::Duration> exposureTime;
>  	std::vector<double> gain;
>  	int read(const libcamera::YamlObject &params);
>  };
> @@ -90,8 +90,8 @@ public:
>  	std::vector<double> const &getWeights() const;
>  	void setEv(double ev);
>  	void setFlickerPeriod(libcamera::utils::Duration flickerPeriod);
> -	void setMaxShutter(libcamera::utils::Duration maxShutter);
> -	void setFixedShutter(libcamera::utils::Duration fixedShutter);
> +	void setMaxExposureTime(libcamera::utils::Duration maxExposureTime);
> +	void setFixedExposureTime(libcamera::utils::Duration fixedExposureTime);
>  	void setFixedAnalogueGain(double fixedAnalogueGain);
>  	void setMeteringMode(std::string const &meteringModeName);
>  	void setExposureMode(std::string const &exposureModeName);
> @@ -117,7 +117,7 @@ private:
>  	bool applyDigitalGain(double gain, double targetY, bool channelBound);
>  	void divideUpExposure();
>  	void writeAndFinish(Metadata *imageMetadata, bool desaturate);
> -	libcamera::utils::Duration limitShutter(libcamera::utils::Duration shutter);
> +	libcamera::utils::Duration limitExposureTime(libcamera::utils::Duration exposureTime);
>  	double limitGain(double gain) const;
>  	AgcMeteringMode *meteringMode_;
>  	AgcExposureMode *exposureMode_;
> @@ -128,7 +128,7 @@ private:
>  	struct ExposureValues {
>  		ExposureValues();
>  
> -		libcamera::utils::Duration shutter;
> +		libcamera::utils::Duration exposureTime;
>  		double analogueGain;
>  		libcamera::utils::Duration totalExposure;
>  		libcamera::utils::Duration totalExposureNoDG; /* without digital gain */
> @@ -146,8 +146,8 @@ private:
>  	std::string constraintModeName_;
>  	double ev_;
>  	libcamera::utils::Duration flickerPeriod_;
> -	libcamera::utils::Duration maxShutter_;
> -	libcamera::utils::Duration fixedShutter_;
> +	libcamera::utils::Duration maxExposureTime_;
> +	libcamera::utils::Duration fixedExposureTime_;
>  	double fixedAnalogueGain_;
>  };
>  
> diff --git a/src/ipa/rpi/controller/rpi/lux.cpp b/src/ipa/rpi/controller/rpi/lux.cpp
> index 652d85d7e22f..27b89a8f6658 100644
> --- a/src/ipa/rpi/controller/rpi/lux.cpp
> +++ b/src/ipa/rpi/controller/rpi/lux.cpp
> @@ -40,7 +40,7 @@ int Lux::read(const libcamera::YamlObject &params)
>  	auto value = params["reference_shutter_speed"].get<double>();
>  	if (!value)
>  		return -EINVAL;
> -	referenceShutterSpeed_ = *value * 1.0us;
> +	referenceExposureTime_ = *value * 1.0us;
>  
>  	value = params["reference_gain"].get<double>();
>  	if (!value)
> @@ -82,11 +82,11 @@ void Lux::process(StatisticsPtr &stats, Metadata *imageMetadata)
>  		double currentAperture = deviceStatus.aperture.value_or(currentAperture_);
>  		double currentY = stats->yHist.interQuantileMean(0, 1);
>  		double gainRatio = referenceGain_ / currentGain;
> -		double shutterSpeedRatio =
> -			referenceShutterSpeed_ / deviceStatus.shutterSpeed;
> +		double exposureTimeRatio =
> +			referenceExposureTime_ / deviceStatus.exposureTime;
>  		double apertureRatio = referenceAperture_ / currentAperture;
>  		double yRatio = currentY * (65536 / stats->yHist.bins()) / referenceY_;
> -		double estimatedLux = shutterSpeedRatio * gainRatio *
> +		double estimatedLux = exposureTimeRatio * gainRatio *
>  				      apertureRatio * apertureRatio *
>  				      yRatio * referenceLux_;
>  		LuxStatus status;
> diff --git a/src/ipa/rpi/controller/rpi/lux.h b/src/ipa/rpi/controller/rpi/lux.h
> index 89f441fc4f6e..da007fe9ac7d 100644
> --- a/src/ipa/rpi/controller/rpi/lux.h
> +++ b/src/ipa/rpi/controller/rpi/lux.h
> @@ -32,7 +32,7 @@ private:
>  	 * These values define the conditions of the reference image, against
>  	 * which we compare the new image.
>  	 */
> -	libcamera::utils::Duration referenceShutterSpeed_;
> +	libcamera::utils::Duration referenceExposureTime_;
>  	double referenceGain_;
>  	double referenceAperture_; /* units of 1/f */
>  	double referenceY_; /* out of 65536 */
> diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml
> index d34a2d068b60..d45cf8e56187 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
> diff --git a/utils/tuning/libtuning/modules/agc/rkisp1.py b/utils/tuning/libtuning/modules/agc/rkisp1.py
> index 7147028a774a..1a4dbe7b416a 100644
> --- a/utils/tuning/libtuning/modules/agc/rkisp1.py
> +++ b/utils/tuning/libtuning/modules/agc/rkisp1.py
> @@ -47,9 +47,9 @@ class AGCRkISP1(AGC):
>          }
>  
>      def _generate_exposure_modes(self) -> dict:
> -        normal = {'shutter': [100, 10000, 30000, 60000, 120000],
> +        normal = {'exposure-time': [100, 10000, 30000, 60000, 120000],
>                    'gain': [2.0, 4.0, 6.0, 6.0, 6.0]}
> -        short = {'shutter': [100, 5000, 10000, 20000, 120000],
> +        short = {'exposure-time': [100, 5000, 10000, 20000, 120000],
>                   'gain': [2.0, 4.0, 6.0, 6.0, 6.0]}
>  
>          return {'ExposureNormal': normal, 'ExposureShort': short}
> 
> base-commit: d5217b16020c659145f9d6dbf5849129b8500967

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list