[{"id":29564,"web_url":"https://patchwork.libcamera.org/comment/29564/","msgid":"<c7117594-1e34-488b-90df-fe8dd5c0b4ac@ideasonboard.com>","date":"2024-05-20T10:53:15","subject":"Re: [PATCH 3/3] pipeline: rkisp1: Implement gamma control","submitter":{"id":156,"url":"https://patchwork.libcamera.org/api/people/156/","name":"Dan Scally","email":"dan.scally@ideasonboard.com"},"content":"Hi Stefan - thanks for the patch\n\nOn 16/05/2024 13:41, Stefan Klug wrote:\n> Add support for the gamma control on the rkisp1. This was tested on\n> an imx8mp.\n>\n> While at it, reorder the controls inside rkisp1.cpp alphabetically.\n>\n> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> ---\n>   src/ipa/rkisp1/algorithms/goc.cpp | 74 ++++++++++++++++++++++++++-----\n>   src/ipa/rkisp1/algorithms/goc.h   | 11 ++++-\n>   src/ipa/rkisp1/ipa_context.h      |  4 ++\n>   src/ipa/rkisp1/rkisp1.cpp         |  3 +-\n>   4 files changed, 80 insertions(+), 12 deletions(-)\n>\n> diff --git a/src/ipa/rkisp1/algorithms/goc.cpp b/src/ipa/rkisp1/algorithms/goc.cpp\n> index 1598d730..2c7cb8a8 100644\n> --- a/src/ipa/rkisp1/algorithms/goc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/goc.cpp\n> @@ -11,6 +11,8 @@\n>   #include <libcamera/base/log.h>\n>   #include <libcamera/base/utils.h>\n>   \n> +#include <libcamera/control_ids.h>\n> +\n>   #include \"libcamera/internal/yaml_parser.h\"\n>   \n>   #include \"linux/rkisp1-config.h\"\n> @@ -53,6 +55,41 @@ int Gamma::init([[maybe_unused]] IPAContext &context,\n>   \treturn 0;\n>   }\n>   \n> +/**\n> + * \\brief Configure the Gamma given a configInfo\n> + * \\param[in] context The shared IPA context\n> + * \\param[in] configInfo The IPA configuration data\n> + *\n> + * \\return 0\n> + */\n> +int Gamma::configure(IPAContext &context,\n> +\t\t     [[maybe_unused]] const IPACameraSensorInfo &configInfo)\n> +{\n> +\tcontext.activeState.gamma = 2.2;\n> +\treturn 0;\n> +}\nI think ::configure() is often called in stream start paths, so this would reset the gamma when the \ncamera is stopped and started - is that what we want to happen?\n> +\n> +/**\n> + * \\copydoc libcamera::ipa::Algorithm::queueRequest\n> + */\n> +void Gamma::queueRequest([[maybe_unused]] IPAContext &context,\n> +\t\t\t [[maybe_unused]] const uint32_t frame,\n> +\t\t\t IPAFrameContext &frameContext,\n> +\t\t\t const ControlList &controls)\n> +{\n> +\tconst auto &gamma = controls.get(controls::Gamma);\n> +\tif (gamma) {\n> +\t\t/* \\todo This is not correct as it updates the current state with a\n> +\t\t * future value. But it does no harm at the moment an allows us to\n> +\t\t * track the last active gamma\n> +\t\t */\n> +\t\tcontext.activeState.gamma = *gamma;\n> +\t\tLOG(RkISP1Gamma, Debug) << \"Set gamma to \" << *gamma;\n> +\t}\n> +\n> +\tframeContext.gamma = context.activeState.gamma;\n> +}\n> +\n>   /**\n>    * \\copydoc libcamera::ipa::Algorithm::prepare\n>    */\n> @@ -67,19 +104,36 @@ void Gamma::prepare([[maybe_unused]] IPAContext &context,\n>   \t\t\t   512, 512, 512, 512, 512, 0 };\n>   \tauto gamma_y = params->others.goc_config.gamma_y;\n>   \n> -\tif (frame > 0)\n> -\t\treturn;\n> +\tif (frame == 0 || std::fabs(frameContext.gamma - gamma_) > 0.001) {\n> +\t\tgamma_ = frameContext.gamma;\n> +\n> +\t\tint x = 0;\n> +\t\tfor (int i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10; i++) {\n> +\t\t\tgamma_y[i] = std::pow(x / 4096.0, 1.0 / gamma_) * 1023.0;\n> +\t\t\tx += segments[i];\n> +\t\t}\n>   \n> -\tint x = 0;\n> -\tfor (int i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10; i++) {\n> -\t\tgamma_y[i] = std::pow(x / 4096.0, 1.0 / gamma_) * 1023.0;\n> -\t\tx += segments[i];\n> +\t\tparams->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;\n> +\t\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> +\n> +\t\t/* It is unclear why these bits need to be set more than once.\n> +\t\t * Setting them only on frame 0 didn't apply gamma.\n> +\t\t */\n> +\t\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> +\t\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_GOC;\n>   \t}\n> +}\n>   \n> -\tparams->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;\n> -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_GOC;\n> -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> +/**\n> + * \\copydoc libcamera::ipa::Algorithm::process\n> + */\n> +void Gamma::process([[maybe_unused]] IPAContext &context,\n> +\t\t    [[maybe_unused]] const uint32_t frame,\n> +\t\t    IPAFrameContext &frameContext,\n> +\t\t    [[maybe_unused]] const rkisp1_stat_buffer *stats,\n> +\t\t    ControlList &metadata)\n> +{\n> +\tmetadata.set(controls::Gamma, frameContext.gamma);\n>   }\n>   \n>   REGISTER_IPA_ALGORITHM(Gamma, \"Gamma\")\n> diff --git a/src/ipa/rkisp1/algorithms/goc.h b/src/ipa/rkisp1/algorithms/goc.h\n> index 3c83655b..c6414040 100644\n> --- a/src/ipa/rkisp1/algorithms/goc.h\n> +++ b/src/ipa/rkisp1/algorithms/goc.h\n> @@ -20,12 +20,21 @@ public:\n>   \t~Gamma() = default;\n>   \n>   \tint init(IPAContext &context, const YamlObject &tuningData) override;\n> +\tint configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;\n> +\tvoid queueRequest(IPAContext &context,\n> +\t\t\t  const uint32_t frame,\n> +\t\t\t  IPAFrameContext &frameContext,\n> +\t\t\t  const ControlList &controls) override;\n>   \tvoid prepare(IPAContext &context, const uint32_t frame,\n>   \t\t     IPAFrameContext &frameContext,\n>   \t\t     rkisp1_params_cfg *params) override;\n> +\tvoid process(IPAContext &context, const uint32_t frame,\n> +\t\t     IPAFrameContext &frameContext,\n> +\t\t     const rkisp1_stat_buffer *stats,\n> +\t\t     ControlList &metadata) override;\n>   \n>   private:\n> -\tfloat gamma_ = 2.2;\n> +\tfloat gamma_;\n>   };\n>   \n>   } /* namespace ipa::rkisp1::algorithms */\n> diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h\n> index bd02a7a2..5252e222 100644\n> --- a/src/ipa/rkisp1/ipa_context.h\n> +++ b/src/ipa/rkisp1/ipa_context.h\n> @@ -104,6 +104,8 @@ struct IPAActiveState {\n>   \t\tuint8_t denoise;\n>   \t\tuint8_t sharpness;\n>   \t} filter;\n> +\n> +\tdouble gamma;\n>   };\n>   \n>   struct IPAFrameContext : public FrameContext {\n> @@ -146,6 +148,8 @@ struct IPAFrameContext : public FrameContext {\n>   \t\tuint32_t exposure;\n>   \t\tdouble gain;\n>   \t} sensor;\n> +\n> +\tdouble gamma;\n>   };\n>   \n>   struct IPAContext {\n> diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp\n> index 6687c91e..7364fd73 100644\n> --- a/src/ipa/rkisp1/rkisp1.cpp\n> +++ b/src/ipa/rkisp1/rkisp1.cpp\n> @@ -108,9 +108,10 @@ const IPAHwSettings ipaHwSettingsV12{\n>   const ControlInfoMap::Map rkisp1Controls{\n>   \t{ &controls::AeEnable, ControlInfo(false, true) },\n>   \t{ &controls::AwbEnable, ControlInfo(false, true) },\n> -\t{ &controls::ColourGains, ControlInfo(0.0f, 3.996f, 1.0f) },\n>   \t{ &controls::Brightness, ControlInfo(-1.0f, 0.993f, 0.0f) },\n> +\t{ &controls::ColourGains, ControlInfo(0.0f, 3.996f, 1.0f) },\n>   \t{ &controls::Contrast, ControlInfo(0.0f, 1.993f, 1.0f) },\n> +\t{ &controls::Gamma, ControlInfo(0.1f, 10.0f, 2.2f) },\n>   \t{ &controls::Saturation, ControlInfo(0.0f, 1.993f, 1.0f) },\n>   \t{ &controls::Sharpness, ControlInfo(0.0f, 10.0f, 1.0f) },\n>   \t{ &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) },\n\n\nI think that this should be registered by the algorithm during ::init() and merged into \ncontext.ctrlMap - otherwise in a case where the tuning file chooses not to instantiate the Gamma \nalgorithm we're going to advertise a control that we don't actually support.","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 10193BDE6B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 20 May 2024 10:53:23 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BAA516347F;\n\tMon, 20 May 2024 12:53:22 +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 A050561A58\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 20 May 2024 12:53:18 +0200 (CEST)","from [192.168.0.43]\n\t(cpc141996-chfd3-2-0-cust928.12-3.cable.virginm.net [86.13.91.161])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 7A983581\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 20 May 2024 12:53:07 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"k+BhHQdw\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1716202387;\n\tbh=SZTiaGoDuzTODLE6VRbNolcaUSMZ5v4rEE8Cqz8k09g=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=k+BhHQdwPLeACYxxQk3scDvr87nQFLcc7x8+/DQMP49rkV2pOzt1+zcec4tSxjuY9\n\tuf1Ycdm8gNPoc+Wr8kaItaqj42LKPFrqD20oYtAFZfCOpnxTLtqF3YRX3fmqp6hWE1\n\t/tNCFopi90VFLda4Y5YvIcf2MAg0MM5hftsGKCbg=","Message-ID":"<c7117594-1e34-488b-90df-fe8dd5c0b4ac@ideasonboard.com>","Date":"Mon, 20 May 2024 11:53:15 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH 3/3] pipeline: rkisp1: Implement gamma control","To":"libcamera-devel@lists.libcamera.org","References":"<20240516124150.219054-1-stefan.klug@ideasonboard.com>\n\t<20240516124150.219054-4-stefan.klug@ideasonboard.com>","Content-Language":"en-US","From":"Dan Scally <dan.scally@ideasonboard.com>","Autocrypt":"addr=dan.scally@ideasonboard.com; keydata=\n\t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","In-Reply-To":"<20240516124150.219054-4-stefan.klug@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":29590,"web_url":"https://patchwork.libcamera.org/comment/29590/","msgid":"<20240521144935.fcdlq7ktybryyrll@jasper>","date":"2024-05-21T14:49:35","subject":"Re: [PATCH 3/3] pipeline: rkisp1: Implement gamma control","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"content":"Hi Dan,\n\nthanks for the review.\n\nOn Mon, May 20, 2024 at 11:53:15AM +0100, Dan Scally wrote:\n> Hi Stefan - thanks for the patch\n> \n> On 16/05/2024 13:41, Stefan Klug wrote:\n> > Add support for the gamma control on the rkisp1. This was tested on\n> > an imx8mp.\n> > \n> > While at it, reorder the controls inside rkisp1.cpp alphabetically.\n> > \n> > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> > ---\n> >   src/ipa/rkisp1/algorithms/goc.cpp | 74 ++++++++++++++++++++++++++-----\n> >   src/ipa/rkisp1/algorithms/goc.h   | 11 ++++-\n> >   src/ipa/rkisp1/ipa_context.h      |  4 ++\n> >   src/ipa/rkisp1/rkisp1.cpp         |  3 +-\n> >   4 files changed, 80 insertions(+), 12 deletions(-)\n> > \n> > diff --git a/src/ipa/rkisp1/algorithms/goc.cpp b/src/ipa/rkisp1/algorithms/goc.cpp\n> > index 1598d730..2c7cb8a8 100644\n> > --- a/src/ipa/rkisp1/algorithms/goc.cpp\n> > +++ b/src/ipa/rkisp1/algorithms/goc.cpp\n> > @@ -11,6 +11,8 @@\n> >   #include <libcamera/base/log.h>\n> >   #include <libcamera/base/utils.h>\n> > +#include <libcamera/control_ids.h>\n> > +\n> >   #include \"libcamera/internal/yaml_parser.h\"\n> >   #include \"linux/rkisp1-config.h\"\n> > @@ -53,6 +55,41 @@ int Gamma::init([[maybe_unused]] IPAContext &context,\n> >   \treturn 0;\n> >   }\n> > +/**\n> > + * \\brief Configure the Gamma given a configInfo\n> > + * \\param[in] context The shared IPA context\n> > + * \\param[in] configInfo The IPA configuration data\n> > + *\n> > + * \\return 0\n> > + */\n> > +int Gamma::configure(IPAContext &context,\n> > +\t\t     [[maybe_unused]] const IPACameraSensorInfo &configInfo)\n> > +{\n> > +\tcontext.activeState.gamma = 2.2;\n> > +\treturn 0;\n> > +}\n> I think ::configure() is often called in stream start paths, so this would\n> reset the gamma when the camera is stopped and started - is that what we\n> want to happen?\n\nI think that's also what other algos do (agc/awb). I believe we said,\nthat state should not survive a restart of a camera. But I might be\nmistaken. \n\n> > +\n> > +/**\n> > + * \\copydoc libcamera::ipa::Algorithm::queueRequest\n> > + */\n> > +void Gamma::queueRequest([[maybe_unused]] IPAContext &context,\n> > +\t\t\t [[maybe_unused]] const uint32_t frame,\n> > +\t\t\t IPAFrameContext &frameContext,\n> > +\t\t\t const ControlList &controls)\n> > +{\n> > +\tconst auto &gamma = controls.get(controls::Gamma);\n> > +\tif (gamma) {\n> > +\t\t/* \\todo This is not correct as it updates the current state with a\n> > +\t\t * future value. But it does no harm at the moment an allows us to\n> > +\t\t * track the last active gamma\n> > +\t\t */\n> > +\t\tcontext.activeState.gamma = *gamma;\n> > +\t\tLOG(RkISP1Gamma, Debug) << \"Set gamma to \" << *gamma;\n> > +\t}\n> > +\n> > +\tframeContext.gamma = context.activeState.gamma;\n> > +}\n> > +\n> >   /**\n> >    * \\copydoc libcamera::ipa::Algorithm::prepare\n> >    */\n> > @@ -67,19 +104,36 @@ void Gamma::prepare([[maybe_unused]] IPAContext &context,\n> >   \t\t\t   512, 512, 512, 512, 512, 0 };\n> >   \tauto gamma_y = params->others.goc_config.gamma_y;\n> > -\tif (frame > 0)\n> > -\t\treturn;\n> > +\tif (frame == 0 || std::fabs(frameContext.gamma - gamma_) > 0.001) {\n> > +\t\tgamma_ = frameContext.gamma;\n> > +\n> > +\t\tint x = 0;\n> > +\t\tfor (int i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10; i++) {\n> > +\t\t\tgamma_y[i] = std::pow(x / 4096.0, 1.0 / gamma_) * 1023.0;\n> > +\t\t\tx += segments[i];\n> > +\t\t}\n> > -\tint x = 0;\n> > -\tfor (int i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10; i++) {\n> > -\t\tgamma_y[i] = std::pow(x / 4096.0, 1.0 / gamma_) * 1023.0;\n> > -\t\tx += segments[i];\n> > +\t\tparams->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;\n> > +\t\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> > +\n> > +\t\t/* It is unclear why these bits need to be set more than once.\n> > +\t\t * Setting them only on frame 0 didn't apply gamma.\n> > +\t\t */\n> > +\t\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> > +\t\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_GOC;\n> >   \t}\n> > +}\n> > -\tparams->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;\n> > -\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> > -\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_GOC;\n> > -\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC;\n> > +/**\n> > + * \\copydoc libcamera::ipa::Algorithm::process\n> > + */\n> > +void Gamma::process([[maybe_unused]] IPAContext &context,\n> > +\t\t    [[maybe_unused]] const uint32_t frame,\n> > +\t\t    IPAFrameContext &frameContext,\n> > +\t\t    [[maybe_unused]] const rkisp1_stat_buffer *stats,\n> > +\t\t    ControlList &metadata)\n> > +{\n> > +\tmetadata.set(controls::Gamma, frameContext.gamma);\n> >   }\n> >   REGISTER_IPA_ALGORITHM(Gamma, \"Gamma\")\n> > diff --git a/src/ipa/rkisp1/algorithms/goc.h b/src/ipa/rkisp1/algorithms/goc.h\n> > index 3c83655b..c6414040 100644\n> > --- a/src/ipa/rkisp1/algorithms/goc.h\n> > +++ b/src/ipa/rkisp1/algorithms/goc.h\n> > @@ -20,12 +20,21 @@ public:\n> >   \t~Gamma() = default;\n> >   \tint init(IPAContext &context, const YamlObject &tuningData) override;\n> > +\tint configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;\n> > +\tvoid queueRequest(IPAContext &context,\n> > +\t\t\t  const uint32_t frame,\n> > +\t\t\t  IPAFrameContext &frameContext,\n> > +\t\t\t  const ControlList &controls) override;\n> >   \tvoid prepare(IPAContext &context, const uint32_t frame,\n> >   \t\t     IPAFrameContext &frameContext,\n> >   \t\t     rkisp1_params_cfg *params) override;\n> > +\tvoid process(IPAContext &context, const uint32_t frame,\n> > +\t\t     IPAFrameContext &frameContext,\n> > +\t\t     const rkisp1_stat_buffer *stats,\n> > +\t\t     ControlList &metadata) override;\n> >   private:\n> > -\tfloat gamma_ = 2.2;\n> > +\tfloat gamma_;\n> >   };\n> >   } /* namespace ipa::rkisp1::algorithms */\n> > diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h\n> > index bd02a7a2..5252e222 100644\n> > --- a/src/ipa/rkisp1/ipa_context.h\n> > +++ b/src/ipa/rkisp1/ipa_context.h\n> > @@ -104,6 +104,8 @@ struct IPAActiveState {\n> >   \t\tuint8_t denoise;\n> >   \t\tuint8_t sharpness;\n> >   \t} filter;\n> > +\n> > +\tdouble gamma;\n> >   };\n> >   struct IPAFrameContext : public FrameContext {\n> > @@ -146,6 +148,8 @@ struct IPAFrameContext : public FrameContext {\n> >   \t\tuint32_t exposure;\n> >   \t\tdouble gain;\n> >   \t} sensor;\n> > +\n> > +\tdouble gamma;\n> >   };\n> >   struct IPAContext {\n> > diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp\n> > index 6687c91e..7364fd73 100644\n> > --- a/src/ipa/rkisp1/rkisp1.cpp\n> > +++ b/src/ipa/rkisp1/rkisp1.cpp\n> > @@ -108,9 +108,10 @@ const IPAHwSettings ipaHwSettingsV12{\n> >   const ControlInfoMap::Map rkisp1Controls{\n> >   \t{ &controls::AeEnable, ControlInfo(false, true) },\n> >   \t{ &controls::AwbEnable, ControlInfo(false, true) },\n> > -\t{ &controls::ColourGains, ControlInfo(0.0f, 3.996f, 1.0f) },\n> >   \t{ &controls::Brightness, ControlInfo(-1.0f, 0.993f, 0.0f) },\n> > +\t{ &controls::ColourGains, ControlInfo(0.0f, 3.996f, 1.0f) },\n> >   \t{ &controls::Contrast, ControlInfo(0.0f, 1.993f, 1.0f) },\n> > +\t{ &controls::Gamma, ControlInfo(0.1f, 10.0f, 2.2f) },\n> >   \t{ &controls::Saturation, ControlInfo(0.0f, 1.993f, 1.0f) },\n> >   \t{ &controls::Sharpness, ControlInfo(0.0f, 10.0f, 1.0f) },\n> >   \t{ &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) },\n> \n> \n> I think that this should be registered by the algorithm during ::init() and\n> merged into context.ctrlMap - otherwise in a case where the tuning file\n> chooses not to instantiate the Gamma algorithm we're going to advertise a\n> control that we don't actually support.\n\nYes that's definitely better. I'll fix it in the next version.\n\nCheers,\nStefan","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 7ED2ABD78E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 21 May 2024 14:49:41 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A0EC963487;\n\tTue, 21 May 2024 16:49:40 +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 D388961A55\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 21 May 2024 16:49:38 +0200 (CEST)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:7426:1738:6d7b:2532])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id A35CBFD6;\n\tTue, 21 May 2024 16:49:26 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"hbe8vnkk\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1716302966;\n\tbh=5tU7Fnx+9ZbsSeXkMaerRLw3qGHwwnggnhJlD88dHzM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=hbe8vnkkXxK3IWzSFMvEfDo9PxKps5GX9YI8Bu/z2A3VvIP75FNvOPSMrvHttES0J\n\tOSJKybG0BWQZQG3TD0M3cReg3loeRonqQFDdS7bIRAC2yZZMXOYWALyTloXkojjz59\n\tnH4/pO0ysIw4m6Gg+U0KlJyOJI3YLYy/dgHfSYzY=","Date":"Tue, 21 May 2024 16:49:35 +0200","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"Dan Scally <dan.scally@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH 3/3] pipeline: rkisp1: Implement gamma control","Message-ID":"<20240521144935.fcdlq7ktybryyrll@jasper>","References":"<20240516124150.219054-1-stefan.klug@ideasonboard.com>\n\t<20240516124150.219054-4-stefan.klug@ideasonboard.com>\n\t<c7117594-1e34-488b-90df-fe8dd5c0b4ac@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<c7117594-1e34-488b-90df-fe8dd5c0b4ac@ideasonboard.com>","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]