[{"id":22485,"web_url":"https://patchwork.libcamera.org/comment/22485/","msgid":"<20220328133749.kdsmntscxdahv4px@uno.localdomain>","date":"2022-03-28T13:37:49","subject":"Re: [libcamera-devel] [PATCH 2/4] libipa: camera_sensor_helper:\n\tImplement exponential gain model","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent,\n\nOn Mon, Mar 28, 2022 at 03:03:34PM +0300, Laurent Pinchart via libcamera-devel wrote:\n> The CameraSensorHelper specifies two gain models, linear and an\n\ns/an //\n\n> exponential. They are modelled after the MIPI CCS specification. Only\n> the linear model has been implemented, the exponential model was left\n> for later.\n>\n> We now need to support sensors that configure their gain in a hardware\n> register with a value expressed in dB. This has similarities with the\n> MIPI CCS exponential gain model, but is only has an exponential factor,\n> while CCS also allows sensors to support a configurable linear factor.\n>\n> The full CCS exponential model needs two values (for the linear and\n> exponential factors) to express a gain, while IPAs use a single linear\n> gain value internally. However, the exponential gain model example in\n> the CCS specification has a fixed linear factor, which may indicate that\n> it could be common for sensors that implement the exponential gain model\n> to only use the exponential factor. For this reason, implement the\n> exponential gain model with a fixed linear factor, but with a\n\nIsn't the linear factor k.exp.a not fixed ?\n\n        return k.exp.a * std::exp2(k.exp.m * gain);\n\nReading this I would have expected k.exp.a to be fixed to 1\n\n> sensor-specific coefficient for the exponential factor that allows\n> expressing the gain in dB (or other logarithmical units) instead of\n> limiting it to powers of 2 as in the MIPI CCS specification.\n>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  src/ipa/libipa/camera_sensor_helper.cpp | 82 ++++++++++++++++++-------\n>  src/ipa/libipa/camera_sensor_helper.h   |  6 ++\n>  2 files changed, 67 insertions(+), 21 deletions(-)\n>\n> diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp\n> index 714cd86f039f..7bb999e19102 100644\n> --- a/src/ipa/libipa/camera_sensor_helper.cpp\n> +++ b/src/ipa/libipa/camera_sensor_helper.cpp\n> @@ -7,6 +7,8 @@\n>   */\n>  #include \"camera_sensor_helper.h\"\n>\n> +#include <cmath>\n> +\n>  #include <libcamera/base/log.h>\n>\n>  /**\n> @@ -51,20 +53,28 @@ namespace ipa {\n>   * This function aims to abstract the calculation of the gain letting the IPA\n>   * use the real gain for its estimations.\n>   *\n> - * The parameters come from the MIPI Alliance Camera Specification for\n> - * Camera Command Set (CCS).\n> - *\n>   * \\return The gain code to pass to V4L2\n>   */\n>  uint32_t CameraSensorHelper::gainCode(double gain) const\n>  {\n>  \tconst AnalogueGainConstants &k = gainConstants_;\n>\n> -\tASSERT(gainType_ == AnalogueGainLinear);\n> -\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n> +\tswitch (gainType_) {\n> +\tcase AnalogueGainLinear:\n> +\t\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n>\n> -\treturn (k.linear.c0 - k.linear.c1 * gain) /\n> -\t       (k.linear.m1 * gain - k.linear.m0);\n> +\t\treturn (k.linear.c0 - k.linear.c1 * gain) /\n> +\t\t       (k.linear.m1 * gain - k.linear.m0);\n> +\n> +\tcase AnalogueGainExponential:\n> +\t\tASSERT(k.exp.a != 0 && k.exp.m != 0);\n> +\n> +\t\treturn std::log2(gain / k.exp.a) / k.exp.m;\n> +\n> +\tdefault:\n> +\t\tASSERT(false);\n> +\t\treturn 0;\n> +\t}\n>  }\n>\n>  /**\n> @@ -75,20 +85,29 @@ uint32_t CameraSensorHelper::gainCode(double gain) const\n>   * use the real gain for its estimations. It is the counterpart of the function\n>   * CameraSensorHelper::gainCode.\n>   *\n> - * The parameters come from the MIPI Alliance Camera Specification for\n> - * Camera Command Set (CCS).\n> - *\n>   * \\return The real gain\n>   */\n>  double CameraSensorHelper::gain(uint32_t gainCode) const\n>  {\n>  \tconst AnalogueGainConstants &k = gainConstants_;\n> +\tdouble gain = static_cast<double>(gainCode);\n>\n> -\tASSERT(gainType_ == AnalogueGainLinear);\n> -\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n> +\tswitch (gainType_) {\n> +\tcase AnalogueGainLinear:\n> +\t\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n>\n> -\treturn (k.linear.m0 * static_cast<double>(gainCode) + k.linear.c0) /\n> -\t       (k.linear.m1 * static_cast<double>(gainCode) + k.linear.c1);\n> +\t\treturn (k.linear.m0 * gain + k.linear.c0) /\n> +\t\t       (k.linear.m1 * gain + k.linear.c1);\n> +\n> +\tcase AnalogueGainExponential:\n> +\t\tASSERT(k.exp.a != 0 && k.exp.m != 0);\n> +\n> +\t\treturn k.exp.a * std::exp2(k.exp.m * gain);\n> +\n> +\tdefault:\n> +\t\tASSERT(false);\n> +\t\treturn 0.0;\n> +\t}\n>  }\n>\n>  /**\n> @@ -120,15 +139,22 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n>\n>  /**\n>   * \\var CameraSensorHelper::AnalogueGainExponential\n> - * \\brief Gain is computed using exponential gain estimation\n> - * (introduced in CCS v1.1)\n> + * \\brief Gain is expressed using an exponential model\n>   *\n> - * Starting with CCS v1.1, Alternate Global Analogue Gain is also available.\n> - * If the image sensor supports it, then the global analogue gain can be\n> - * controlled by linear and exponential gain formula:\n> + * The relationship between the integer gain parameter and the resulting gain\n> + * multiplier is given by the following equation:\n>   *\n> - * \\f$gain = analogLinearGainGlobal * 2^{analogExponentialGainGlobal}\\f$\n> - * \\todo not implemented in libipa\n> + * \\f$gain = a \\cdot 2^{m \\cdot x}\\f$\n> + *\n> + * Where 'x' is the gain control parameter, and 'a' and 'm' are image\n> + * sensor-specific constants.\n> + *\n> + * This is a subset of the MIPI CCS exponential gain model with the linear\n> + * factor 'a' being a constant, but with the exponent being configurable\n> + * through the 'm' coefficient.\n\nSo I don't really get what 'constant' means, as this seems to match\nthe CCS spec (apart from the 'm' paramter)\n\n> + *\n> + * When the gain is expressed in dB, 'a' is equal to 1 and 'm' to\n> + * \\f$log_{2}{10^{frac{1}{20}}}\\f$.\n>   */\n>\n>  /**\n> @@ -152,6 +178,17 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n>   * \\brief Constant used in the linear gain coding/decoding\n>   */\n>\n> +/**\n> + * \\struct CameraSensorHelper::AnalogueGainExpConstants\n> + * \\brief Analogue gain constants for the exponential gain model\n> + *\n> + * \\var CameraSensorHelper::AnalogueGainExpConstants::a\n> + * \\brief Constant used in the exponential gain coding/decoding\n> + *\n> + * \\var CameraSensorHelper::AnalogueGainExpConstants::m\n> + * \\brief Constant used in the exponential gain coding/decoding\n> + */\n> +\n>  /**\n>   * \\struct CameraSensorHelper::AnalogueGainConstants\n>   * \\brief Analogue gain model constants\n> @@ -161,6 +198,9 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n>   *\n>   * \\var CameraSensorHelper::AnalogueGainConstants::linear\n>   * \\brief Constants for the linear gain model\n> + *\n> + * \\var CameraSensorHelper::AnalogueGainConstants::exp\n> + * \\brief Constants for the exponential gain model\n>   */\n>\n>  /**\n> diff --git a/src/ipa/libipa/camera_sensor_helper.h b/src/ipa/libipa/camera_sensor_helper.h\n> index 6b96520ba601..7351fc7c2928 100644\n> --- a/src/ipa/libipa/camera_sensor_helper.h\n> +++ b/src/ipa/libipa/camera_sensor_helper.h\n> @@ -41,8 +41,14 @@ protected:\n>  \t\tint16_t c1;\n>  \t};\n>\n> +\tstruct AnalogueGainExpConstants {\n> +\t\tdouble a;\n> +\t\tdouble m;\n> +\t};\n> +\n>  \tunion AnalogueGainConstants {\n>  \t\tAnalogueGainLinearConstants linear;\n> +\t\tAnalogueGainExpConstants exp;\n>  \t};\n\nWith my confusion about what 'constant' means clarified:\n\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\n\n>\n>  \tAnalogueGainType gainType_;\n> --\n> Regards,\n>\n> Laurent Pinchart\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id F03F6C3256\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 28 Mar 2022 13:37:53 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4977B65631;\n\tMon, 28 Mar 2022 15:37:53 +0200 (CEST)","from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net\n\t[217.70.183.197])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9EB2560135\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 28 Mar 2022 15:37:51 +0200 (CEST)","(Authenticated sender: jacopo@jmondi.org)\n\tby mail.gandi.net (Postfix) with ESMTPSA id 1AEF61C000B;\n\tMon, 28 Mar 2022 13:37:50 +0000 (UTC)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1648474673;\n\tbh=EwCQ2+IwgD9UiJhoZj1AtpzFINeDmv+tsp4Eo+bJK1A=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=bdoVowBJTs2wN5UbvhEKxct01HhjsS0Yxygg0pO87gLa15g/goLP/ckHR7hSoizp4\n\tgMhF7xSTzhpjm7uVqiPF9lAQnDFOIcig65ORHBdU7/4N449GcpQ8mWRXa8/T2vQHA4\n\t0sR10H/Xciu655OosmxNDkIXO+j6+njWcLaJzwHATeQdUTbdUjLi9Fr5wJc3F6VnOE\n\tPTPrzxjySrMCmy7uRd8ZeYHXqksPGYLmZyCo17tm9ZvR9kUXnYbNst3rywTVPKqbwF\n\ti2VaFjHitIArV3/ozU5qBdt2/VFsQ+J3EnRg/1km4eaXk+Fu7IiM4eaF3sRqYRnQPa\n\tZRJEtT/4AEroQ==","Date":"Mon, 28 Mar 2022 15:37:49 +0200","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20220328133749.kdsmntscxdahv4px@uno.localdomain>","References":"<20220328120336.10834-1-laurent.pinchart@ideasonboard.com>\n\t<20220328120336.10834-3-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20220328120336.10834-3-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 2/4] libipa: camera_sensor_helper:\n\tImplement exponential gain model","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Jacopo Mondi via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"Jacopo Mondi <jacopo@jmondi.org>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":22489,"web_url":"https://patchwork.libcamera.org/comment/22489/","msgid":"<YkHd5KsPZSec/T6B@pendragon.ideasonboard.com>","date":"2022-03-28T16:10:12","subject":"Re: [libcamera-devel] [PATCH 2/4] libipa: camera_sensor_helper:\n\tImplement exponential gain model","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nOn Mon, Mar 28, 2022 at 03:37:49PM +0200, Jacopo Mondi wrote:\n> On Mon, Mar 28, 2022 at 03:03:34PM +0300, Laurent Pinchart via libcamera-devel wrote:\n> > The CameraSensorHelper specifies two gain models, linear and an\n> \n> s/an //\n> \n> > exponential. They are modelled after the MIPI CCS specification. Only\n> > the linear model has been implemented, the exponential model was left\n> > for later.\n> >\n> > We now need to support sensors that configure their gain in a hardware\n> > register with a value expressed in dB. This has similarities with the\n> > MIPI CCS exponential gain model, but is only has an exponential factor,\n> > while CCS also allows sensors to support a configurable linear factor.\n> >\n> > The full CCS exponential model needs two values (for the linear and\n> > exponential factors) to express a gain, while IPAs use a single linear\n> > gain value internally. However, the exponential gain model example in\n> > the CCS specification has a fixed linear factor, which may indicate that\n> > it could be common for sensors that implement the exponential gain model\n> > to only use the exponential factor. For this reason, implement the\n> > exponential gain model with a fixed linear factor, but with a\n> \n> Isn't the linear factor k.exp.a not fixed ?\n> \n>         return k.exp.a * std::exp2(k.exp.m * gain);\n> \n> Reading this I would have expected k.exp.a to be fixed to 1\n\nBy fixed, I meant that it doesn't vary at runtime, but it can be\nsensor-specific. The CCS exponential model has two parameters than can\nvary at runtime:\n\ngain = gain_{lin} * 2^{gain_{exp}}\n\nwith both gain_{lin} and gain_{exp} being programmable in two different\nsensor registers.\n\n> > sensor-specific coefficient for the exponential factor that allows\n> > expressing the gain in dB (or other logarithmical units) instead of\n> > limiting it to powers of 2 as in the MIPI CCS specification.\n> >\n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >  src/ipa/libipa/camera_sensor_helper.cpp | 82 ++++++++++++++++++-------\n> >  src/ipa/libipa/camera_sensor_helper.h   |  6 ++\n> >  2 files changed, 67 insertions(+), 21 deletions(-)\n> >\n> > diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp\n> > index 714cd86f039f..7bb999e19102 100644\n> > --- a/src/ipa/libipa/camera_sensor_helper.cpp\n> > +++ b/src/ipa/libipa/camera_sensor_helper.cpp\n> > @@ -7,6 +7,8 @@\n> >   */\n> >  #include \"camera_sensor_helper.h\"\n> >\n> > +#include <cmath>\n> > +\n> >  #include <libcamera/base/log.h>\n> >\n> >  /**\n> > @@ -51,20 +53,28 @@ namespace ipa {\n> >   * This function aims to abstract the calculation of the gain letting the IPA\n> >   * use the real gain for its estimations.\n> >   *\n> > - * The parameters come from the MIPI Alliance Camera Specification for\n> > - * Camera Command Set (CCS).\n> > - *\n> >   * \\return The gain code to pass to V4L2\n> >   */\n> >  uint32_t CameraSensorHelper::gainCode(double gain) const\n> >  {\n> >  \tconst AnalogueGainConstants &k = gainConstants_;\n> >\n> > -\tASSERT(gainType_ == AnalogueGainLinear);\n> > -\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n> > +\tswitch (gainType_) {\n> > +\tcase AnalogueGainLinear:\n> > +\t\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n> >\n> > -\treturn (k.linear.c0 - k.linear.c1 * gain) /\n> > -\t       (k.linear.m1 * gain - k.linear.m0);\n> > +\t\treturn (k.linear.c0 - k.linear.c1 * gain) /\n> > +\t\t       (k.linear.m1 * gain - k.linear.m0);\n> > +\n> > +\tcase AnalogueGainExponential:\n> > +\t\tASSERT(k.exp.a != 0 && k.exp.m != 0);\n> > +\n> > +\t\treturn std::log2(gain / k.exp.a) / k.exp.m;\n> > +\n> > +\tdefault:\n> > +\t\tASSERT(false);\n> > +\t\treturn 0;\n> > +\t}\n> >  }\n> >\n> >  /**\n> > @@ -75,20 +85,29 @@ uint32_t CameraSensorHelper::gainCode(double gain) const\n> >   * use the real gain for its estimations. It is the counterpart of the function\n> >   * CameraSensorHelper::gainCode.\n> >   *\n> > - * The parameters come from the MIPI Alliance Camera Specification for\n> > - * Camera Command Set (CCS).\n> > - *\n> >   * \\return The real gain\n> >   */\n> >  double CameraSensorHelper::gain(uint32_t gainCode) const\n> >  {\n> >  \tconst AnalogueGainConstants &k = gainConstants_;\n> > +\tdouble gain = static_cast<double>(gainCode);\n> >\n> > -\tASSERT(gainType_ == AnalogueGainLinear);\n> > -\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n> > +\tswitch (gainType_) {\n> > +\tcase AnalogueGainLinear:\n> > +\t\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n> >\n> > -\treturn (k.linear.m0 * static_cast<double>(gainCode) + k.linear.c0) /\n> > -\t       (k.linear.m1 * static_cast<double>(gainCode) + k.linear.c1);\n> > +\t\treturn (k.linear.m0 * gain + k.linear.c0) /\n> > +\t\t       (k.linear.m1 * gain + k.linear.c1);\n> > +\n> > +\tcase AnalogueGainExponential:\n> > +\t\tASSERT(k.exp.a != 0 && k.exp.m != 0);\n> > +\n> > +\t\treturn k.exp.a * std::exp2(k.exp.m * gain);\n> > +\n> > +\tdefault:\n> > +\t\tASSERT(false);\n> > +\t\treturn 0.0;\n> > +\t}\n> >  }\n> >\n> >  /**\n> > @@ -120,15 +139,22 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n> >\n> >  /**\n> >   * \\var CameraSensorHelper::AnalogueGainExponential\n> > - * \\brief Gain is computed using exponential gain estimation\n> > - * (introduced in CCS v1.1)\n> > + * \\brief Gain is expressed using an exponential model\n> >   *\n> > - * Starting with CCS v1.1, Alternate Global Analogue Gain is also available.\n> > - * If the image sensor supports it, then the global analogue gain can be\n> > - * controlled by linear and exponential gain formula:\n> > + * The relationship between the integer gain parameter and the resulting gain\n> > + * multiplier is given by the following equation:\n> >   *\n> > - * \\f$gain = analogLinearGainGlobal * 2^{analogExponentialGainGlobal}\\f$\n> > - * \\todo not implemented in libipa\n> > + * \\f$gain = a \\cdot 2^{m \\cdot x}\\f$\n> > + *\n> > + * Where 'x' is the gain control parameter, and 'a' and 'm' are image\n> > + * sensor-specific constants.\n> > + *\n> > + * This is a subset of the MIPI CCS exponential gain model with the linear\n> > + * factor 'a' being a constant, but with the exponent being configurable\n> > + * through the 'm' coefficient.\n> \n> So I don't really get what 'constant' means, as this seems to match\n> the CCS spec (apart from the 'm' paramter)\n> \n> > + *\n> > + * When the gain is expressed in dB, 'a' is equal to 1 and 'm' to\n> > + * \\f$log_{2}{10^{frac{1}{20}}}\\f$.\n> >   */\n> >\n> >  /**\n> > @@ -152,6 +178,17 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n> >   * \\brief Constant used in the linear gain coding/decoding\n> >   */\n> >\n> > +/**\n> > + * \\struct CameraSensorHelper::AnalogueGainExpConstants\n> > + * \\brief Analogue gain constants for the exponential gain model\n> > + *\n> > + * \\var CameraSensorHelper::AnalogueGainExpConstants::a\n> > + * \\brief Constant used in the exponential gain coding/decoding\n> > + *\n> > + * \\var CameraSensorHelper::AnalogueGainExpConstants::m\n> > + * \\brief Constant used in the exponential gain coding/decoding\n> > + */\n> > +\n> >  /**\n> >   * \\struct CameraSensorHelper::AnalogueGainConstants\n> >   * \\brief Analogue gain model constants\n> > @@ -161,6 +198,9 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n> >   *\n> >   * \\var CameraSensorHelper::AnalogueGainConstants::linear\n> >   * \\brief Constants for the linear gain model\n> > + *\n> > + * \\var CameraSensorHelper::AnalogueGainConstants::exp\n> > + * \\brief Constants for the exponential gain model\n> >   */\n> >\n> >  /**\n> > diff --git a/src/ipa/libipa/camera_sensor_helper.h b/src/ipa/libipa/camera_sensor_helper.h\n> > index 6b96520ba601..7351fc7c2928 100644\n> > --- a/src/ipa/libipa/camera_sensor_helper.h\n> > +++ b/src/ipa/libipa/camera_sensor_helper.h\n> > @@ -41,8 +41,14 @@ protected:\n> >  \t\tint16_t c1;\n> >  \t};\n> >\n> > +\tstruct AnalogueGainExpConstants {\n> > +\t\tdouble a;\n> > +\t\tdouble m;\n> > +\t};\n> > +\n> >  \tunion AnalogueGainConstants {\n> >  \t\tAnalogueGainLinearConstants linear;\n> > +\t\tAnalogueGainExpConstants exp;\n> >  \t};\n> \n> With my confusion about what 'constant' means clarified:\n> \n> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n> \n> >\n> >  \tAnalogueGainType gainType_;","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B6745C3256\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 28 Mar 2022 16:10:17 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0BC7065633;\n\tMon, 28 Mar 2022 18:10:17 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6B35460135\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 28 Mar 2022 18:10:15 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 88BC3E27;\n\tMon, 28 Mar 2022 18:10:14 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1648483817;\n\tbh=OfAnws8l8bcxAj6bK0sXJa4eC+F3v9KVhgqzo1F8Ud4=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=RIywKVWkOCq2sKjzwq5iwOH/jYyn58T/PvLwLQB6FS+KTVAcdgQwxF3bRxOdETfB8\n\teS8q5Fj94spIHHXjXNNZdVYkz8gH241geSdLcS5yeOemv42hl59n+xuLZEUaRIbK/0\n\trF1q6rC3DMA4dViYfNSajJ2XSu6/zWWlMiACyNXXm6oQszFHsdKejJRpSx16iQmPNQ\n\t95pd+oB4MXK+5EnQ9+G3VLC+nSOPZ/SV+565yO3coq2z54BHwb7sofWxvWiSg4YroO\n\twnhXYj1DvLRXo16fk7iJ7ArYZMz9LjXKsWgtZMvlpZRwTVaRfKzbpcu06X5M6iZva6\n\tOJ8lr5TH+UflQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1648483814;\n\tbh=OfAnws8l8bcxAj6bK0sXJa4eC+F3v9KVhgqzo1F8Ud4=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Ac14zOEk/VKj4xs3l2utLgnbi3oURdwI4lV5BhHe1unrp11CHSW959N68I0LqjlTc\n\t+60w0KN7K5K+6d7UTJvWgtZrhoI/2r3K7QecMLAQL3lhrWPOyW+gn7wAcOBLd181td\n\tKca7k3l7r19cUwlx6K+gmMmPdIMBomR8b55RSS9s="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"Ac14zOEk\"; dkim-atps=neutral","Date":"Mon, 28 Mar 2022 19:10:12 +0300","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<YkHd5KsPZSec/T6B@pendragon.ideasonboard.com>","References":"<20220328120336.10834-1-laurent.pinchart@ideasonboard.com>\n\t<20220328120336.10834-3-laurent.pinchart@ideasonboard.com>\n\t<20220328133749.kdsmntscxdahv4px@uno.localdomain>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20220328133749.kdsmntscxdahv4px@uno.localdomain>","Subject":"Re: [libcamera-devel] [PATCH 2/4] libipa: camera_sensor_helper:\n\tImplement exponential gain model","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":22523,"web_url":"https://patchwork.libcamera.org/comment/22523/","msgid":"<034070d1-25ce-ea1c-37aa-702b376d5b2c@ideasonboard.com>","date":"2022-03-30T08:41:55","subject":"Re: [libcamera-devel] [PATCH 2/4] libipa: camera_sensor_helper:\n\tImplement exponential gain model","submitter":{"id":86,"url":"https://patchwork.libcamera.org/api/people/86/","name":"Umang Jain","email":"umang.jain@ideasonboard.com"},"content":"Hi Laurent,\n\nThank you for the patch.\n\nOn 3/28/22 17:33, Laurent Pinchart via libcamera-devel wrote:\n> The CameraSensorHelper specifies two gain models, linear and an\n> exponential. They are modelled after the MIPI CCS specification. Only\n> the linear model has been implemented, the exponential model was left\n> for later.\n>\n> We now need to support sensors that configure their gain in a hardware\n> register with a value expressed in dB. This has similarities with the\n> MIPI CCS exponential gain model, but is only has an exponential factor,\n> while CCS also allows sensors to support a configurable linear factor.\n>\n> The full CCS exponential model needs two values (for the linear and\n> exponential factors) to express a gain, while IPAs use a single linear\n> gain value internally. However, the exponential gain model example in\n> the CCS specification has a fixed linear factor, which may indicate that\n> it could be common for sensors that implement the exponential gain model\n> to only use the exponential factor. For this reason, implement the\n> exponential gain model with a fixed linear factor, but with a\n> sensor-specific coefficient for the exponential factor that allows\n> expressing the gain in dB (or other logarithmical units) instead of\n> limiting it to powers of 2 as in the MIPI CCS specification.\n>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n\nReviewed-by: Umang Jain <umang.jain@ideasonboard.com>\n> ---\n>   src/ipa/libipa/camera_sensor_helper.cpp | 82 ++++++++++++++++++-------\n>   src/ipa/libipa/camera_sensor_helper.h   |  6 ++\n>   2 files changed, 67 insertions(+), 21 deletions(-)\n>\n> diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp\n> index 714cd86f039f..7bb999e19102 100644\n> --- a/src/ipa/libipa/camera_sensor_helper.cpp\n> +++ b/src/ipa/libipa/camera_sensor_helper.cpp\n> @@ -7,6 +7,8 @@\n>    */\n>   #include \"camera_sensor_helper.h\"\n>   \n> +#include <cmath>\n> +\n>   #include <libcamera/base/log.h>\n>   \n>   /**\n> @@ -51,20 +53,28 @@ namespace ipa {\n>    * This function aims to abstract the calculation of the gain letting the IPA\n>    * use the real gain for its estimations.\n>    *\n> - * The parameters come from the MIPI Alliance Camera Specification for\n> - * Camera Command Set (CCS).\n> - *\n>    * \\return The gain code to pass to V4L2\n>    */\n>   uint32_t CameraSensorHelper::gainCode(double gain) const\n>   {\n>   \tconst AnalogueGainConstants &k = gainConstants_;\n>   \n> -\tASSERT(gainType_ == AnalogueGainLinear);\n> -\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n> +\tswitch (gainType_) {\n> +\tcase AnalogueGainLinear:\n> +\t\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n>   \n> -\treturn (k.linear.c0 - k.linear.c1 * gain) /\n> -\t       (k.linear.m1 * gain - k.linear.m0);\n> +\t\treturn (k.linear.c0 - k.linear.c1 * gain) /\n> +\t\t       (k.linear.m1 * gain - k.linear.m0);\n> +\n> +\tcase AnalogueGainExponential:\n> +\t\tASSERT(k.exp.a != 0 && k.exp.m != 0);\n> +\n> +\t\treturn std::log2(gain / k.exp.a) / k.exp.m;\n> +\n> +\tdefault:\n> +\t\tASSERT(false);\n> +\t\treturn 0;\n> +\t}\n>   }\n>   \n>   /**\n> @@ -75,20 +85,29 @@ uint32_t CameraSensorHelper::gainCode(double gain) const\n>    * use the real gain for its estimations. It is the counterpart of the function\n>    * CameraSensorHelper::gainCode.\n>    *\n> - * The parameters come from the MIPI Alliance Camera Specification for\n> - * Camera Command Set (CCS).\n> - *\n>    * \\return The real gain\n>    */\n>   double CameraSensorHelper::gain(uint32_t gainCode) const\n>   {\n>   \tconst AnalogueGainConstants &k = gainConstants_;\n> +\tdouble gain = static_cast<double>(gainCode);\n>   \n> -\tASSERT(gainType_ == AnalogueGainLinear);\n> -\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n> +\tswitch (gainType_) {\n> +\tcase AnalogueGainLinear:\n> +\t\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n>   \n> -\treturn (k.linear.m0 * static_cast<double>(gainCode) + k.linear.c0) /\n> -\t       (k.linear.m1 * static_cast<double>(gainCode) + k.linear.c1);\n> +\t\treturn (k.linear.m0 * gain + k.linear.c0) /\n> +\t\t       (k.linear.m1 * gain + k.linear.c1);\n> +\n> +\tcase AnalogueGainExponential:\n> +\t\tASSERT(k.exp.a != 0 && k.exp.m != 0);\n> +\n> +\t\treturn k.exp.a * std::exp2(k.exp.m * gain);\n> +\n> +\tdefault:\n> +\t\tASSERT(false);\n> +\t\treturn 0.0;\n> +\t}\n>   }\n>   \n>   /**\n> @@ -120,15 +139,22 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n>   \n>   /**\n>    * \\var CameraSensorHelper::AnalogueGainExponential\n> - * \\brief Gain is computed using exponential gain estimation\n> - * (introduced in CCS v1.1)\n> + * \\brief Gain is expressed using an exponential model\n>    *\n> - * Starting with CCS v1.1, Alternate Global Analogue Gain is also available.\n> - * If the image sensor supports it, then the global analogue gain can be\n> - * controlled by linear and exponential gain formula:\n> + * The relationship between the integer gain parameter and the resulting gain\n> + * multiplier is given by the following equation:\n>    *\n> - * \\f$gain = analogLinearGainGlobal * 2^{analogExponentialGainGlobal}\\f$\n> - * \\todo not implemented in libipa\n> + * \\f$gain = a \\cdot 2^{m \\cdot x}\\f$\n> + *\n> + * Where 'x' is the gain control parameter, and 'a' and 'm' are image\n> + * sensor-specific constants.\n> + *\n> + * This is a subset of the MIPI CCS exponential gain model with the linear\n> + * factor 'a' being a constant, but with the exponent being configurable\n> + * through the 'm' coefficient.\n> + *\n> + * When the gain is expressed in dB, 'a' is equal to 1 and 'm' to\n> + * \\f$log_{2}{10^{frac{1}{20}}}\\f$.\n>    */\n>   \n>   /**\n> @@ -152,6 +178,17 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n>    * \\brief Constant used in the linear gain coding/decoding\n>    */\n>   \n> +/**\n> + * \\struct CameraSensorHelper::AnalogueGainExpConstants\n> + * \\brief Analogue gain constants for the exponential gain model\n> + *\n> + * \\var CameraSensorHelper::AnalogueGainExpConstants::a\n> + * \\brief Constant used in the exponential gain coding/decoding\n> + *\n> + * \\var CameraSensorHelper::AnalogueGainExpConstants::m\n> + * \\brief Constant used in the exponential gain coding/decoding\n> + */\n> +\n>   /**\n>    * \\struct CameraSensorHelper::AnalogueGainConstants\n>    * \\brief Analogue gain model constants\n> @@ -161,6 +198,9 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n>    *\n>    * \\var CameraSensorHelper::AnalogueGainConstants::linear\n>    * \\brief Constants for the linear gain model\n> + *\n> + * \\var CameraSensorHelper::AnalogueGainConstants::exp\n> + * \\brief Constants for the exponential gain model\n>    */\n>   \n>   /**\n> diff --git a/src/ipa/libipa/camera_sensor_helper.h b/src/ipa/libipa/camera_sensor_helper.h\n> index 6b96520ba601..7351fc7c2928 100644\n> --- a/src/ipa/libipa/camera_sensor_helper.h\n> +++ b/src/ipa/libipa/camera_sensor_helper.h\n> @@ -41,8 +41,14 @@ protected:\n>   \t\tint16_t c1;\n>   \t};\n>   \n> +\tstruct AnalogueGainExpConstants {\n> +\t\tdouble a;\n> +\t\tdouble m;\n> +\t};\n> +\n>   \tunion AnalogueGainConstants {\n>   \t\tAnalogueGainLinearConstants linear;\n> +\t\tAnalogueGainExpConstants exp;\n>   \t};\n>   \n>   \tAnalogueGainType gainType_;","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 060C3C3256\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 30 Mar 2022 08:42:08 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5E09F65634;\n\tWed, 30 Mar 2022 10:42:07 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4196960397\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 30 Mar 2022 10:42:05 +0200 (CEST)","from [192.168.1.105] (unknown [103.74.73.208])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AA89459D;\n\tWed, 30 Mar 2022 10:42:03 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1648629727;\n\tbh=cvLAAxO20EVFof+B5o/B3yGHggRvuarJzF1YbfYcwXU=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=cNmpY1joNPRlN/E3VObgcUPOzRU0XCWKN4rKODxGEBB0qHkS/LluWMt/CWp3RftpH\n\t7UYal9Eo0TG0TaPnHxwkNWVwwDN+BQkwLps9IwPBqs218jygpoaxEbC7o3aPwUbcp7\n\t2KgfKKHh1H0/DFrNozdDIlnUx2oZUzBLg28Q2MIQEiXMqFkLv0whVPUvY4vzGYkmQm\n\thyPn3EcvH2eLbVKNeZM+xOb820/6/1zsT8P4yBvTbS/sIhaMDLKeavGhtWBhqsuaKW\n\tqW2+Nvi2jC2s3btclx15rrOhP7mYrte+M1TEGQQD1texd2NS4BwvaqrbVdYCK7BCpH\n\t1H/YNK/q0138g==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1648629724;\n\tbh=cvLAAxO20EVFof+B5o/B3yGHggRvuarJzF1YbfYcwXU=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=YTpm53/EyQOaEuWbXw6UOOWdcHbI1d8Ywolhr8juIuKAMgPG103vk1pH16ikJFEfs\n\thOvfevfu4wEPvNdxIoOIyvtbRf6umWadKVK1760gb4YkCk1IFO8E/rT0wB15bIbeLl\n\tLHVOdS6WNugXZ5qgrYKjzu5uNazs6jlOz1QNO+wc="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"YTpm53/E\"; dkim-atps=neutral","Message-ID":"<034070d1-25ce-ea1c-37aa-702b376d5b2c@ideasonboard.com>","Date":"Wed, 30 Mar 2022 14:11:55 +0530","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.4.1","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20220328120336.10834-1-laurent.pinchart@ideasonboard.com>\n\t<20220328120336.10834-3-laurent.pinchart@ideasonboard.com>","In-Reply-To":"<20220328120336.10834-3-laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH 2/4] libipa: camera_sensor_helper:\n\tImplement exponential gain model","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Umang Jain via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"Umang Jain <umang.jain@ideasonboard.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":22525,"web_url":"https://patchwork.libcamera.org/comment/22525/","msgid":"<20220330084511.GB3237525@pyrite.rasen.tech>","date":"2022-03-30T08:45:11","subject":"Re: [libcamera-devel] [PATCH 2/4] libipa: camera_sensor_helper:\n\tImplement exponential gain model","submitter":{"id":97,"url":"https://patchwork.libcamera.org/api/people/97/","name":"Nicolas Dufresne via libcamera-devel","email":"libcamera-devel@lists.libcamera.org"},"content":"Hi Laurent,\n\nOn Mon, Mar 28, 2022 at 03:03:34PM +0300, Laurent Pinchart via libcamera-devel wrote:\n> The CameraSensorHelper specifies two gain models, linear and an\n\ns/an//\n\n> exponential. They are modelled after the MIPI CCS specification. Only\n> the linear model has been implemented, the exponential model was left\n> for later.\n> \n> We now need to support sensors that configure their gain in a hardware\n> register with a value expressed in dB. This has similarities with the\n> MIPI CCS exponential gain model, but is only has an exponential factor,\n> while CCS also allows sensors to support a configurable linear factor.\n> \n> The full CCS exponential model needs two values (for the linear and\n> exponential factors) to express a gain, while IPAs use a single linear\n> gain value internally. However, the exponential gain model example in\n> the CCS specification has a fixed linear factor, which may indicate that\n> it could be common for sensors that implement the exponential gain model\n> to only use the exponential factor. For this reason, implement the\n> exponential gain model with a fixed linear factor, but with a\n> sensor-specific coefficient for the exponential factor that allows\n> expressing the gain in dB (or other logarithmical units) instead of\n> limiting it to powers of 2 as in the MIPI CCS specification.\n\nMakes sense to me.\n\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n> ---\n>  src/ipa/libipa/camera_sensor_helper.cpp | 82 ++++++++++++++++++-------\n>  src/ipa/libipa/camera_sensor_helper.h   |  6 ++\n>  2 files changed, 67 insertions(+), 21 deletions(-)\n> \n> diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp\n> index 714cd86f039f..7bb999e19102 100644\n> --- a/src/ipa/libipa/camera_sensor_helper.cpp\n> +++ b/src/ipa/libipa/camera_sensor_helper.cpp\n> @@ -7,6 +7,8 @@\n>   */\n>  #include \"camera_sensor_helper.h\"\n>  \n> +#include <cmath>\n> +\n>  #include <libcamera/base/log.h>\n>  \n>  /**\n> @@ -51,20 +53,28 @@ namespace ipa {\n>   * This function aims to abstract the calculation of the gain letting the IPA\n>   * use the real gain for its estimations.\n>   *\n> - * The parameters come from the MIPI Alliance Camera Specification for\n> - * Camera Command Set (CCS).\n> - *\n>   * \\return The gain code to pass to V4L2\n>   */\n>  uint32_t CameraSensorHelper::gainCode(double gain) const\n>  {\n>  \tconst AnalogueGainConstants &k = gainConstants_;\n>  \n> -\tASSERT(gainType_ == AnalogueGainLinear);\n> -\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n> +\tswitch (gainType_) {\n> +\tcase AnalogueGainLinear:\n> +\t\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n>  \n> -\treturn (k.linear.c0 - k.linear.c1 * gain) /\n> -\t       (k.linear.m1 * gain - k.linear.m0);\n> +\t\treturn (k.linear.c0 - k.linear.c1 * gain) /\n> +\t\t       (k.linear.m1 * gain - k.linear.m0);\n> +\n> +\tcase AnalogueGainExponential:\n> +\t\tASSERT(k.exp.a != 0 && k.exp.m != 0);\n> +\n> +\t\treturn std::log2(gain / k.exp.a) / k.exp.m;\n> +\n> +\tdefault:\n> +\t\tASSERT(false);\n> +\t\treturn 0;\n> +\t}\n>  }\n>  \n>  /**\n> @@ -75,20 +85,29 @@ uint32_t CameraSensorHelper::gainCode(double gain) const\n>   * use the real gain for its estimations. It is the counterpart of the function\n>   * CameraSensorHelper::gainCode.\n>   *\n> - * The parameters come from the MIPI Alliance Camera Specification for\n> - * Camera Command Set (CCS).\n> - *\n>   * \\return The real gain\n>   */\n>  double CameraSensorHelper::gain(uint32_t gainCode) const\n>  {\n>  \tconst AnalogueGainConstants &k = gainConstants_;\n> +\tdouble gain = static_cast<double>(gainCode);\n>  \n> -\tASSERT(gainType_ == AnalogueGainLinear);\n> -\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n> +\tswitch (gainType_) {\n> +\tcase AnalogueGainLinear:\n> +\t\tASSERT(k.linear.m0 == 0 || k.linear.m1 == 0);\n>  \n> -\treturn (k.linear.m0 * static_cast<double>(gainCode) + k.linear.c0) /\n> -\t       (k.linear.m1 * static_cast<double>(gainCode) + k.linear.c1);\n> +\t\treturn (k.linear.m0 * gain + k.linear.c0) /\n> +\t\t       (k.linear.m1 * gain + k.linear.c1);\n> +\n> +\tcase AnalogueGainExponential:\n> +\t\tASSERT(k.exp.a != 0 && k.exp.m != 0);\n> +\n> +\t\treturn k.exp.a * std::exp2(k.exp.m * gain);\n> +\n> +\tdefault:\n> +\t\tASSERT(false);\n> +\t\treturn 0.0;\n> +\t}\n>  }\n>  \n>  /**\n> @@ -120,15 +139,22 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n>  \n>  /**\n>   * \\var CameraSensorHelper::AnalogueGainExponential\n> - * \\brief Gain is computed using exponential gain estimation\n> - * (introduced in CCS v1.1)\n> + * \\brief Gain is expressed using an exponential model\n>   *\n> - * Starting with CCS v1.1, Alternate Global Analogue Gain is also available.\n> - * If the image sensor supports it, then the global analogue gain can be\n> - * controlled by linear and exponential gain formula:\n> + * The relationship between the integer gain parameter and the resulting gain\n> + * multiplier is given by the following equation:\n>   *\n> - * \\f$gain = analogLinearGainGlobal * 2^{analogExponentialGainGlobal}\\f$\n> - * \\todo not implemented in libipa\n> + * \\f$gain = a \\cdot 2^{m \\cdot x}\\f$\n> + *\n> + * Where 'x' is the gain control parameter, and 'a' and 'm' are image\n> + * sensor-specific constants.\n> + *\n> + * This is a subset of the MIPI CCS exponential gain model with the linear\n> + * factor 'a' being a constant, but with the exponent being configurable\n> + * through the 'm' coefficient.\n> + *\n> + * When the gain is expressed in dB, 'a' is equal to 1 and 'm' to\n> + * \\f$log_{2}{10^{frac{1}{20}}}\\f$.\n>   */\n>  \n>  /**\n> @@ -152,6 +178,17 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n>   * \\brief Constant used in the linear gain coding/decoding\n>   */\n>  \n> +/**\n> + * \\struct CameraSensorHelper::AnalogueGainExpConstants\n> + * \\brief Analogue gain constants for the exponential gain model\n> + *\n> + * \\var CameraSensorHelper::AnalogueGainExpConstants::a\n> + * \\brief Constant used in the exponential gain coding/decoding\n> + *\n> + * \\var CameraSensorHelper::AnalogueGainExpConstants::m\n> + * \\brief Constant used in the exponential gain coding/decoding\n> + */\n> +\n>  /**\n>   * \\struct CameraSensorHelper::AnalogueGainConstants\n>   * \\brief Analogue gain model constants\n> @@ -161,6 +198,9 @@ double CameraSensorHelper::gain(uint32_t gainCode) const\n>   *\n>   * \\var CameraSensorHelper::AnalogueGainConstants::linear\n>   * \\brief Constants for the linear gain model\n> + *\n> + * \\var CameraSensorHelper::AnalogueGainConstants::exp\n> + * \\brief Constants for the exponential gain model\n>   */\n>  \n>  /**\n> diff --git a/src/ipa/libipa/camera_sensor_helper.h b/src/ipa/libipa/camera_sensor_helper.h\n> index 6b96520ba601..7351fc7c2928 100644\n> --- a/src/ipa/libipa/camera_sensor_helper.h\n> +++ b/src/ipa/libipa/camera_sensor_helper.h\n> @@ -41,8 +41,14 @@ protected:\n>  \t\tint16_t c1;\n>  \t};\n>  \n> +\tstruct AnalogueGainExpConstants {\n> +\t\tdouble a;\n> +\t\tdouble m;\n> +\t};\n> +\n>  \tunion AnalogueGainConstants {\n>  \t\tAnalogueGainLinearConstants linear;\n> +\t\tAnalogueGainExpConstants exp;\n>  \t};\n>  \n>  \tAnalogueGainType gainType_;","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id C4315C0F1B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 30 Mar 2022 08:45:19 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 29CDE65635;\n\tWed, 30 Mar 2022 10:45:19 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 392F560397\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 30 Mar 2022 10:45:18 +0200 (CEST)","from pyrite.rasen.tech (h175-177-042-148.catv02.itscom.jp\n\t[175.177.42.148])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id F36C859D;\n\tWed, 30 Mar 2022 10:45:16 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1648629919;\n\tbh=S1mDnOnTGbUCMLl6xDCcYOBvnF5jVbVEbgdZ+c/Vyjk=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=OoubpKlDnc73h7llPXVUXehpo5xDKHYQ6SyMvZJTxOOb9IlW8r5yl6keCnpyT377s\n\tmzX1qieyCEostAPNtYS3fr7J3WvtODkRk15ra5uFlo5nUioxB/13OCB0e8enruJxGI\n\tKfiuYeqmrnEzCUlsZ1zV9kCGmZ/Fkh3qDr7bbJlshMC3TzTmlVM6JEwFZe/RbmOaNC\n\tYK7nNIUCiQYYsGDIBCGogWpehJfx1j0vNbwstxWD53jXBqT6rSDK1fdzo8XyPFZyCN\n\tXIpBKBocCYn+0mXOA0Xi8MGev+xlBrAmWaacGeyzaxWYrvD5CcqzzJvYgHQsAiGatY\n\tV8BD9Rgq0EU6w==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1648629918;\n\tbh=S1mDnOnTGbUCMLl6xDCcYOBvnF5jVbVEbgdZ+c/Vyjk=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=fYzsAuv0Jz7zUCmhD5PPaF4inSzYu2/joYrJptmGobHRIFavEYUAnfQH4/4svWJ0w\n\tO+MAUUrEEkvL6jwMUPxmmFXuIP7SWYY/NduuKoPkQLU8XKf+hAdW/hQ7TzsHoUmJYc\n\tkBOIR1mwNggAEGHXzk58lBIt/wib9+7AU97Smifs="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"fYzsAuv0\"; dkim-atps=neutral","Date":"Wed, 30 Mar 2022 17:45:11 +0900","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20220330084511.GB3237525@pyrite.rasen.tech>","References":"<20220328120336.10834-1-laurent.pinchart@ideasonboard.com>\n\t<20220328120336.10834-3-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20220328120336.10834-3-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 2/4] libipa: camera_sensor_helper:\n\tImplement exponential gain model","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","From":"Paul Elder via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"paul.elder@ideasonboard.com","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]