[libcamera-devel] [PATCH 2/4] libipa: camera_sensor_helper: Implement exponential gain model

Laurent Pinchart laurent.pinchart at ideasonboard.com
Mon Mar 28 18:10:12 CEST 2022


Hi Jacopo,

On Mon, Mar 28, 2022 at 03:37:49PM +0200, Jacopo Mondi wrote:
> On Mon, Mar 28, 2022 at 03:03:34PM +0300, Laurent Pinchart via libcamera-devel wrote:
> > The CameraSensorHelper specifies two gain models, linear and an
> 
> s/an //
> 
> > exponential. They are modelled after the MIPI CCS specification. Only
> > the linear model has been implemented, the exponential model was left
> > for later.
> >
> > We now need to support sensors that configure their gain in a hardware
> > register with a value expressed in dB. This has similarities with the
> > MIPI CCS exponential gain model, but is only has an exponential factor,
> > while CCS also allows sensors to support a configurable linear factor.
> >
> > The full CCS exponential model needs two values (for the linear and
> > exponential factors) to express a gain, while IPAs use a single linear
> > gain value internally. However, the exponential gain model example in
> > the CCS specification has a fixed linear factor, which may indicate that
> > it could be common for sensors that implement the exponential gain model
> > to only use the exponential factor. For this reason, implement the
> > exponential gain model with a fixed linear factor, but with a
> 
> Isn't the linear factor k.exp.a not fixed ?
> 
>         return k.exp.a * std::exp2(k.exp.m * gain);
> 
> Reading this I would have expected k.exp.a to be fixed to 1

By fixed, I meant that it doesn't vary at runtime, but it can be
sensor-specific. The CCS exponential model has two parameters than can
vary at runtime:

gain = gain_{lin} * 2^{gain_{exp}}

with both gain_{lin} and gain_{exp} being programmable in two different
sensor registers.

> > sensor-specific coefficient for the exponential factor that allows
> > expressing the gain in dB (or other logarithmical units) instead of
> > limiting it to powers of 2 as in the MIPI CCS specification.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > ---
> >  src/ipa/libipa/camera_sensor_helper.cpp | 82 ++++++++++++++++++-------
> >  src/ipa/libipa/camera_sensor_helper.h   |  6 ++
> >  2 files changed, 67 insertions(+), 21 deletions(-)
> >
> > diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp
> > index 714cd86f039f..7bb999e19102 100644
> > --- a/src/ipa/libipa/camera_sensor_helper.cpp
> > +++ b/src/ipa/libipa/camera_sensor_helper.cpp
> > @@ -7,6 +7,8 @@
> >   */
> >  #include "camera_sensor_helper.h"
> >
> > +#include <cmath>
> > +
> >  #include <libcamera/base/log.h>
> >
> >  /**
> > @@ -51,20 +53,28 @@ namespace ipa {
> >   * This function aims to abstract the calculation of the gain letting the IPA
> >   * use the real gain for its estimations.
> >   *
> > - * The parameters come from the MIPI Alliance Camera Specification for
> > - * Camera Command Set (CCS).
> > - *
> >   * \return The gain code to pass to V4L2
> >   */
> >  uint32_t CameraSensorHelper::gainCode(double gain) const
> >  {
> >  	const AnalogueGainConstants &k = gainConstants_;
> >
> > -	ASSERT(gainType_ == AnalogueGainLinear);
> > -	ASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);
> > +	switch (gainType_) {
> > +	case AnalogueGainLinear:
> > +		ASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);
> >
> > -	return (k.linear.c0 - k.linear.c1 * gain) /
> > -	       (k.linear.m1 * gain - k.linear.m0);
> > +		return (k.linear.c0 - k.linear.c1 * gain) /
> > +		       (k.linear.m1 * gain - k.linear.m0);
> > +
> > +	case AnalogueGainExponential:
> > +		ASSERT(k.exp.a != 0 && k.exp.m != 0);
> > +
> > +		return std::log2(gain / k.exp.a) / k.exp.m;
> > +
> > +	default:
> > +		ASSERT(false);
> > +		return 0;
> > +	}
> >  }
> >
> >  /**
> > @@ -75,20 +85,29 @@ uint32_t CameraSensorHelper::gainCode(double gain) const
> >   * use the real gain for its estimations. It is the counterpart of the function
> >   * CameraSensorHelper::gainCode.
> >   *
> > - * The parameters come from the MIPI Alliance Camera Specification for
> > - * Camera Command Set (CCS).
> > - *
> >   * \return The real gain
> >   */
> >  double CameraSensorHelper::gain(uint32_t gainCode) const
> >  {
> >  	const AnalogueGainConstants &k = gainConstants_;
> > +	double gain = static_cast<double>(gainCode);
> >
> > -	ASSERT(gainType_ == AnalogueGainLinear);
> > -	ASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);
> > +	switch (gainType_) {
> > +	case AnalogueGainLinear:
> > +		ASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);
> >
> > -	return (k.linear.m0 * static_cast<double>(gainCode) + k.linear.c0) /
> > -	       (k.linear.m1 * static_cast<double>(gainCode) + k.linear.c1);
> > +		return (k.linear.m0 * gain + k.linear.c0) /
> > +		       (k.linear.m1 * gain + k.linear.c1);
> > +
> > +	case AnalogueGainExponential:
> > +		ASSERT(k.exp.a != 0 && k.exp.m != 0);
> > +
> > +		return k.exp.a * std::exp2(k.exp.m * gain);
> > +
> > +	default:
> > +		ASSERT(false);
> > +		return 0.0;
> > +	}
> >  }
> >
> >  /**
> > @@ -120,15 +139,22 @@ double CameraSensorHelper::gain(uint32_t gainCode) const
> >
> >  /**
> >   * \var CameraSensorHelper::AnalogueGainExponential
> > - * \brief Gain is computed using exponential gain estimation
> > - * (introduced in CCS v1.1)
> > + * \brief Gain is expressed using an exponential model
> >   *
> > - * Starting with CCS v1.1, Alternate Global Analogue Gain is also available.
> > - * If the image sensor supports it, then the global analogue gain can be
> > - * controlled by linear and exponential gain formula:
> > + * The relationship between the integer gain parameter and the resulting gain
> > + * multiplier is given by the following equation:
> >   *
> > - * \f$gain = analogLinearGainGlobal * 2^{analogExponentialGainGlobal}\f$
> > - * \todo not implemented in libipa
> > + * \f$gain = a \cdot 2^{m \cdot x}\f$
> > + *
> > + * Where 'x' is the gain control parameter, and 'a' and 'm' are image
> > + * sensor-specific constants.
> > + *
> > + * This is a subset of the MIPI CCS exponential gain model with the linear
> > + * factor 'a' being a constant, but with the exponent being configurable
> > + * through the 'm' coefficient.
> 
> So I don't really get what 'constant' means, as this seems to match
> the CCS spec (apart from the 'm' paramter)
> 
> > + *
> > + * When the gain is expressed in dB, 'a' is equal to 1 and 'm' to
> > + * \f$log_{2}{10^{frac{1}{20}}}\f$.
> >   */
> >
> >  /**
> > @@ -152,6 +178,17 @@ double CameraSensorHelper::gain(uint32_t gainCode) const
> >   * \brief Constant used in the linear gain coding/decoding
> >   */
> >
> > +/**
> > + * \struct CameraSensorHelper::AnalogueGainExpConstants
> > + * \brief Analogue gain constants for the exponential gain model
> > + *
> > + * \var CameraSensorHelper::AnalogueGainExpConstants::a
> > + * \brief Constant used in the exponential gain coding/decoding
> > + *
> > + * \var CameraSensorHelper::AnalogueGainExpConstants::m
> > + * \brief Constant used in the exponential gain coding/decoding
> > + */
> > +
> >  /**
> >   * \struct CameraSensorHelper::AnalogueGainConstants
> >   * \brief Analogue gain model constants
> > @@ -161,6 +198,9 @@ double CameraSensorHelper::gain(uint32_t gainCode) const
> >   *
> >   * \var CameraSensorHelper::AnalogueGainConstants::linear
> >   * \brief Constants for the linear gain model
> > + *
> > + * \var CameraSensorHelper::AnalogueGainConstants::exp
> > + * \brief Constants for the exponential gain model
> >   */
> >
> >  /**
> > diff --git a/src/ipa/libipa/camera_sensor_helper.h b/src/ipa/libipa/camera_sensor_helper.h
> > index 6b96520ba601..7351fc7c2928 100644
> > --- a/src/ipa/libipa/camera_sensor_helper.h
> > +++ b/src/ipa/libipa/camera_sensor_helper.h
> > @@ -41,8 +41,14 @@ protected:
> >  		int16_t c1;
> >  	};
> >
> > +	struct AnalogueGainExpConstants {
> > +		double a;
> > +		double m;
> > +	};
> > +
> >  	union AnalogueGainConstants {
> >  		AnalogueGainLinearConstants linear;
> > +		AnalogueGainExpConstants exp;
> >  	};
> 
> With my confusion about what 'constant' means clarified:
> 
> Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
> 
> >
> >  	AnalogueGainType gainType_;

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list