mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-16 00:45:07 +03:00
libipa: camera_sensor_helper: Implement exponential gain model
The CameraSensorHelper specifies two gain models, linear and 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 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@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
This commit is contained in:
parent
a9d43c4710
commit
8ad9249fb0
2 changed files with 67 additions and 21 deletions
|
@ -7,6 +7,8 @@
|
||||||
*/
|
*/
|
||||||
#include "camera_sensor_helper.h"
|
#include "camera_sensor_helper.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include <libcamera/base/log.h>
|
#include <libcamera/base/log.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,20 +53,28 @@ namespace ipa {
|
||||||
* This function aims to abstract the calculation of the gain letting the IPA
|
* This function aims to abstract the calculation of the gain letting the IPA
|
||||||
* use the real gain for its estimations.
|
* 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
|
* \return The gain code to pass to V4L2
|
||||||
*/
|
*/
|
||||||
uint32_t CameraSensorHelper::gainCode(double gain) const
|
uint32_t CameraSensorHelper::gainCode(double gain) const
|
||||||
{
|
{
|
||||||
const AnalogueGainConstants &k = gainConstants_;
|
const AnalogueGainConstants &k = gainConstants_;
|
||||||
|
|
||||||
ASSERT(gainType_ == AnalogueGainLinear);
|
switch (gainType_) {
|
||||||
|
case AnalogueGainLinear:
|
||||||
ASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);
|
ASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);
|
||||||
|
|
||||||
return (k.linear.c0 - k.linear.c1 * gain) /
|
return (k.linear.c0 - k.linear.c1 * gain) /
|
||||||
(k.linear.m1 * gain - k.linear.m0);
|
(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
|
* use the real gain for its estimations. It is the counterpart of the function
|
||||||
* CameraSensorHelper::gainCode.
|
* CameraSensorHelper::gainCode.
|
||||||
*
|
*
|
||||||
* The parameters come from the MIPI Alliance Camera Specification for
|
|
||||||
* Camera Command Set (CCS).
|
|
||||||
*
|
|
||||||
* \return The real gain
|
* \return The real gain
|
||||||
*/
|
*/
|
||||||
double CameraSensorHelper::gain(uint32_t gainCode) const
|
double CameraSensorHelper::gain(uint32_t gainCode) const
|
||||||
{
|
{
|
||||||
const AnalogueGainConstants &k = gainConstants_;
|
const AnalogueGainConstants &k = gainConstants_;
|
||||||
|
double gain = static_cast<double>(gainCode);
|
||||||
|
|
||||||
ASSERT(gainType_ == AnalogueGainLinear);
|
switch (gainType_) {
|
||||||
|
case AnalogueGainLinear:
|
||||||
ASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);
|
ASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);
|
||||||
|
|
||||||
return (k.linear.m0 * static_cast<double>(gainCode) + k.linear.c0) /
|
return (k.linear.m0 * gain + k.linear.c0) /
|
||||||
(k.linear.m1 * static_cast<double>(gainCode) + k.linear.c1);
|
(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
|
* \var CameraSensorHelper::AnalogueGainExponential
|
||||||
* \brief Gain is computed using exponential gain estimation
|
* \brief Gain is expressed using an exponential model
|
||||||
* (introduced in CCS v1.1)
|
|
||||||
*
|
*
|
||||||
* Starting with CCS v1.1, Alternate Global Analogue Gain is also available.
|
* The relationship between the integer gain parameter and the resulting gain
|
||||||
* If the image sensor supports it, then the global analogue gain can be
|
* multiplier is given by the following equation:
|
||||||
* controlled by linear and exponential gain formula:
|
|
||||||
*
|
*
|
||||||
* \f$gain = analogLinearGainGlobal * 2^{analogExponentialGainGlobal}\f$
|
* \f$gain = a \cdot 2^{m \cdot x}\f$
|
||||||
* \todo not implemented in libipa
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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
|
* \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
|
* \struct CameraSensorHelper::AnalogueGainConstants
|
||||||
* \brief Analogue gain model constants
|
* \brief Analogue gain model constants
|
||||||
|
@ -161,6 +198,9 @@ double CameraSensorHelper::gain(uint32_t gainCode) const
|
||||||
*
|
*
|
||||||
* \var CameraSensorHelper::AnalogueGainConstants::linear
|
* \var CameraSensorHelper::AnalogueGainConstants::linear
|
||||||
* \brief Constants for the linear gain model
|
* \brief Constants for the linear gain model
|
||||||
|
*
|
||||||
|
* \var CameraSensorHelper::AnalogueGainConstants::exp
|
||||||
|
* \brief Constants for the exponential gain model
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -41,8 +41,14 @@ protected:
|
||||||
int16_t c1;
|
int16_t c1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AnalogueGainExpConstants {
|
||||||
|
double a;
|
||||||
|
double m;
|
||||||
|
};
|
||||||
|
|
||||||
union AnalogueGainConstants {
|
union AnalogueGainConstants {
|
||||||
AnalogueGainLinearConstants linear;
|
AnalogueGainLinearConstants linear;
|
||||||
|
AnalogueGainExpConstants exp;
|
||||||
};
|
};
|
||||||
|
|
||||||
AnalogueGainType gainType_;
|
AnalogueGainType gainType_;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue