[{"id":37870,"web_url":"https://patchwork.libcamera.org/comment/37870/","msgid":"<176908629744.1693075.12877698854137743540@ping.linuxembedded.co.uk>","date":"2026-01-22T12:51:37","subject":"Re: [PATCH v2] ipa: rkisp1: cproc: Fix brightness and contrast value\n\thandling","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Stefan Klug (2026-01-21 13:39:07)\n> By reverse engineering it was discovered that the transfer curve applied\n> by the CPROC module is\n> \n> Yout = Yin * contrast + brightness/2.\n> \n> However the most common expectation on contrast is to not change the\n> middle gray of an image. So the expected curve is:\n> \n> Yout = (Yin - 0.5) * contrast + 0.5 + brightness\n> \n> Map the user expectation to the hardware by changing the brightness\n> value written to the hardware. This also includes multiplying the\n> requested brightness value by two.\n> \n> Note: The limits of the brightness control are left as is even though\n> they can not be reached without changing the contrast. But limiting them\n> to [0.5, 0.5] would cut off parts of the combined control space of\n\ndid you mean [-0.5, 0.5] ? \n\nMeasuring the limits on my board with camshark metadata results:\n\n | Contrast | Brightness-min | Brightness-max |\n |----------|----------------|----------------|\n |   1.99   |     -0.0039    |    0.98828     |\n |   1.00   |     -0.5       |    0.49609     |\n |   0.00   |     -1.0       |   -0.00390     |\n\nBut I think that's correct from my understanding so far, just some\nfloating point variance which I'm not concerned about so:\n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n   \n\n> contrast + brightness.\n> \n> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> \n> ---\n> \n> This patch needs to be applied on top of the quantization series:\n> https://patchwork.libcamera.org/project/libcamera/list/?series=5708\n> \n> Changes in v2:\n> - Moved calculation of brightness into helper function, to be able to\n>   reuse it inside configure()\n> - Moved calculation of actualBrightness from process() to the helper\n>   function\n> - Added documentation for the new context variables\n> - Removed unnecessary curly braces\n> - Improved comment\n> ---\n>  src/ipa/rkisp1/algorithms/cproc.cpp | 58 ++++++++++++++++++++++-------\n>  src/ipa/rkisp1/ipa_context.cpp      | 17 +++++++--\n>  src/ipa/rkisp1/ipa_context.h        |  3 ++\n>  3 files changed, 61 insertions(+), 17 deletions(-)\n> \n> diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp\n> index 7484e4780094..e0f6ac9816f7 100644\n> --- a/src/ipa/rkisp1/algorithms/cproc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/cproc.cpp\n> @@ -46,6 +46,33 @@ constexpr float kDefaultSaturation = 1.0f;\n>   */\n>  constexpr float kHueScale = -90.0f;\n>  \n> +void applyRequestedBrightness(IPAActiveState &activeState)\n> +{\n> +       auto &cproc = activeState.cproc;\n> +\n> +       /*\n> +        * The CPROC module applies the transfer function\n> +        *\n> +        * Yout = Yin * contrast + brightness/2\n> +        *\n> +        * The calculations are done one bit wider than the input data to\n> +        * account for the maximum contrast of 2x without clamping. Brightness\n> +        * is applied after and therefore affects the output only with half the\n> +        * value.\n> +        *\n> +        * Most users expect that changing contrast doesn't change the middle\n> +        * gray and that the brightness value is normalized to one. So they\n> +        * expect a transfer function of\n> +        *\n> +        * Yout = (Yin - 0.5) * contrast + 0.5 + brightness\n> +        *\n> +        * To implement above formula with the given hardware we need adjust the\n> +        * hardware brightness value depending on the contrast.\n> +        */\n> +       cproc.brightness = (1 - cproc.contrast.value()) + 2 * cproc.requestedBrightness;\n> +       cproc.actualBrightness = (cproc.brightness.value() - (1 - cproc.contrast.value())) / 2;\n> +}\n> +\n>  } /* namespace */\n>  \n>  /**\n> @@ -76,8 +103,10 @@ int ColorProcessing::configure(IPAContext &context,\n>  {\n>         auto &cproc = context.activeState.cproc;\n>  \n> -       cproc.brightness = BrightnessQ(kDefaultBrightness);\n> +       cproc.requestedBrightness = kDefaultBrightness;\n>         cproc.contrast = ContrastQ(kDefaultContrast);\n> +       applyRequestedBrightness(context.activeState);\n> +\n>         cproc.hue = HueQ(kDefaultHue);\n>         cproc.saturation = SaturationQ(kDefaultSaturation);\n>  \n> @@ -98,17 +127,6 @@ void ColorProcessing::queueRequest(IPAContext &context,\n>         if (frame == 0)\n>                 update = true;\n>  \n> -       const auto &brightness = controls.get(controls::Brightness);\n> -       if (brightness) {\n> -               BrightnessQ value = *brightness;\n> -               if (cproc.brightness != value) {\n> -                       cproc.brightness = value;\n> -                       update = true;\n> -               }\n> -\n> -               LOG(RkISP1CProc, Debug) << \"Set brightness to \" << value;\n> -       }\n> -\n>         const auto &contrast = controls.get(controls::Contrast);\n>         if (contrast) {\n>                 ContrastQ value = *contrast;\n> @@ -120,6 +138,19 @@ void ColorProcessing::queueRequest(IPAContext &context,\n>                 LOG(RkISP1CProc, Debug) << \"Set contrast to \" << value;\n>         }\n>  \n> +       const auto &brightness = controls.get(controls::Brightness);\n> +       if (brightness)\n> +               cproc.requestedBrightness = *brightness;\n> +\n> +       if (update || brightness) {\n> +               BrightnessQ old = cproc.brightness;\n> +               applyRequestedBrightness(context.activeState);\n> +               if (cproc.brightness != old)\n> +                       update = true;\n> +\n> +               LOG(RkISP1CProc, Debug) << \"Set brightness to \" << cproc.actualBrightness;\n> +       }\n> +\n>         const auto &hue = controls.get(controls::Hue);\n>         if (hue) {\n>                 /* Scale the Hue from ]-90, +90] */\n> @@ -144,6 +175,7 @@ void ColorProcessing::queueRequest(IPAContext &context,\n>         }\n>  \n>         frameContext.cproc.brightness = cproc.brightness;\n> +       frameContext.cproc.actualBrightness = cproc.actualBrightness;\n>         frameContext.cproc.contrast = cproc.contrast;\n>         frameContext.cproc.hue = cproc.hue;\n>         frameContext.cproc.saturation = cproc.saturation;\n> @@ -179,7 +211,7 @@ void ColorProcessing::process([[maybe_unused]] IPAContext &context,\n>                               [[maybe_unused]] const rkisp1_stat_buffer *stats,\n>                               ControlList &metadata)\n>  {\n> -       metadata.set(controls::Brightness, frameContext.cproc.brightness.value());\n> +       metadata.set(controls::Brightness, frameContext.cproc.actualBrightness);\n>         metadata.set(controls::Contrast, frameContext.cproc.contrast.value());\n>         metadata.set(controls::Hue, frameContext.cproc.hue.value() * kHueScale);\n>         metadata.set(controls::Saturation, frameContext.cproc.saturation.value());\n> diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp\n> index 15cb0afe9fe8..f9d0aff058bc 100644\n> --- a/src/ipa/rkisp1/ipa_context.cpp\n> +++ b/src/ipa/rkisp1/ipa_context.cpp\n> @@ -232,9 +232,15 @@ namespace libcamera::ipa::rkisp1 {\n>  /**\n>   * \\var IPAActiveState::cproc\n>   * \\brief State for the Color Processing algorithm\n> +  *\n> + * \\var IPAActiveState::cproc.requestedBrightness\n> + * \\brief Brightness level requested by the user\n> +  *\n> + * \\var IPAActiveState::cproc.actualBrightness\n> + * \\brief Brightness level after contrast compensation\n>   *\n> - * \\struct IPAActiveState::cproc.brightness\n> - * \\brief Brightness level\n> + * \\var IPAActiveState::cproc.brightness\n> + * \\brief Hardware brightness level\n>   *\n>   * \\var IPAActiveState::cproc.contrast\n>   * \\brief Contrast level\n> @@ -400,8 +406,11 @@ namespace libcamera::ipa::rkisp1 {\n>   * \\var IPAFrameContext::cproc\n>   * \\brief Color Processing parameters for this frame\n>   *\n> - * \\struct IPAFrameContext::cproc.brightness\n> - * \\brief Brightness level\n> + * \\var IPAFrameContext::cproc.actualBrightness\n> + * \\brief Brightness level after contrast compensation\n> + *\n> + * \\var IPAFrameContext::cproc.brightness\n> + * \\brief Hardware brightness level\n>   *\n>   * \\var IPAFrameContext::cproc.contrast\n>   * \\brief Contrast level\n> diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h\n> index 80b035044cda..72ec64532dd8 100644\n> --- a/src/ipa/rkisp1/ipa_context.h\n> +++ b/src/ipa/rkisp1/ipa_context.h\n> @@ -122,6 +122,8 @@ struct IPAActiveState {\n>         } ccm;\n>  \n>         struct {\n> +               float requestedBrightness;\n> +               float actualBrightness;\n>                 BrightnessQ brightness;\n>                 ContrastQ contrast;\n>                 HueQ hue;\n> @@ -181,6 +183,7 @@ struct IPAFrameContext : public FrameContext {\n>         } awb;\n>  \n>         struct {\n> +               float actualBrightness;\n>                 BrightnessQ brightness;\n>                 ContrastQ contrast;\n>                 HueQ hue;\n> -- \n> 2.51.0\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 6E15CC3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 22 Jan 2026 12:51:43 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B703E61F84;\n\tThu, 22 Jan 2026 13:51:42 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 5B8F261F84\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 22 Jan 2026 13:51:40 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 84DE6324;\n\tThu, 22 Jan 2026 13:51:07 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"ZvgHrXuw\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1769086267;\n\tbh=edeFSQzhQ3wIYGq4kjHUuX0/S5YnsEndy0dzhoS5CCs=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=ZvgHrXuwJUXuVt0Xcl9rXhNoXHXL3C55obyAVTiIoxJEEmGxeMP73iGBXvf/rRNc6\n\tu/x8AQAsepxDD1QfEd+MnihEkcXUIXpSvd5GchzhnLHd/VTYH1VczCarFeRHHMzQ/3\n\tc+ONj51O1lCyBdR+1bWASnmJ5dHQQ/i7HsDdlBc0=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260121133910.34925-1-stefan.klug@ideasonboard.com>","References":"<20260121133910.34925-1-stefan.klug@ideasonboard.com>","Subject":"Re: [PATCH v2] ipa: rkisp1: cproc: Fix brightness and contrast value\n\thandling","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Thu, 22 Jan 2026 12:51:37 +0000","Message-ID":"<176908629744.1693075.12877698854137743540@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","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":39029,"web_url":"https://patchwork.libcamera.org/comment/39029/","msgid":"<20260611010324.GA1126460@killaraus.ideasonboard.com>","date":"2026-06-11T01:03:24","subject":"Re: [PATCH v2] ipa: rkisp1: cproc: Fix brightness and contrast value\n\thandling","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Thu, Jan 22, 2026 at 12:51:37PM +0000, Kieran Bingham wrote:\n> Quoting Stefan Klug (2026-01-21 13:39:07)\n> > By reverse engineering it was discovered that the transfer curve applied\n> > by the CPROC module is\n> > \n> > Yout = Yin * contrast + brightness/2.\n> > \n> > However the most common expectation on contrast is to not change the\n> > middle gray of an image. So the expected curve is:\n> > \n> > Yout = (Yin - 0.5) * contrast + 0.5 + brightness\n> > \n> > Map the user expectation to the hardware by changing the brightness\n> > value written to the hardware. This also includes multiplying the\n> > requested brightness value by two.\n> > \n> > Note: The limits of the brightness control are left as is even though\n> > they can not be reached without changing the contrast. But limiting them\n> > to [0.5, 0.5] would cut off parts of the combined control space of\n> \n> did you mean [-0.5, 0.5] ? \n> \n> Measuring the limits on my board with camshark metadata results:\n> \n>  | Contrast | Brightness-min | Brightness-max |\n>  |----------|----------------|----------------|\n>  |   1.99   |     -0.0039    |    0.98828     |\n>  |   1.00   |     -0.5       |    0.49609     |\n>  |   0.00   |     -1.0       |   -0.00390     |\n> \n> But I think that's correct from my understanding so far, just some\n> floating point variance which I'm not concerned about so:\n> \n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>    \n> > contrast + brightness.\n> > \n> > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n> > \n> > ---\n> > \n> > This patch needs to be applied on top of the quantization series:\n> > https://patchwork.libcamera.org/project/libcamera/list/?series=5708\n> > \n> > Changes in v2:\n> > - Moved calculation of brightness into helper function, to be able to\n> >   reuse it inside configure()\n> > - Moved calculation of actualBrightness from process() to the helper\n> >   function\n> > - Added documentation for the new context variables\n> > - Removed unnecessary curly braces\n> > - Improved comment\n> > ---\n> >  src/ipa/rkisp1/algorithms/cproc.cpp | 58 ++++++++++++++++++++++-------\n> >  src/ipa/rkisp1/ipa_context.cpp      | 17 +++++++--\n> >  src/ipa/rkisp1/ipa_context.h        |  3 ++\n> >  3 files changed, 61 insertions(+), 17 deletions(-)\n> > \n> > diff --git a/src/ipa/rkisp1/algorithms/cproc.cpp b/src/ipa/rkisp1/algorithms/cproc.cpp\n> > index 7484e4780094..e0f6ac9816f7 100644\n> > --- a/src/ipa/rkisp1/algorithms/cproc.cpp\n> > +++ b/src/ipa/rkisp1/algorithms/cproc.cpp\n> > @@ -46,6 +46,33 @@ constexpr float kDefaultSaturation = 1.0f;\n> >   */\n> >  constexpr float kHueScale = -90.0f;\n> >  \n> > +void applyRequestedBrightness(IPAActiveState &activeState)\n> > +{\n> > +       auto &cproc = activeState.cproc;\n> > +\n> > +       /*\n> > +        * The CPROC module applies the transfer function\n> > +        *\n> > +        * Yout = Yin * contrast + brightness/2\n> > +        *\n> > +        * The calculations are done one bit wider than the input data to\n> > +        * account for the maximum contrast of 2x without clamping. Brightness\n> > +        * is applied after and therefore affects the output only with half the\n> > +        * value.\n> > +        *\n> > +        * Most users expect that changing contrast doesn't change the middle\n> > +        * gray and that the brightness value is normalized to one. So they\n> > +        * expect a transfer function of\n> > +        *\n> > +        * Yout = (Yin - 0.5) * contrast + 0.5 + brightness\n\nYout = Yin * contrast - 0.5 * contrast + 0.5 + brightness\n\nb = - contrast + 1.0 + 2 * brightness\n\n> > +        *\n> > +        * To implement above formula with the given hardware we need adjust the\n\ns/above formula/the above formula/ (or just \"the formula\")\n\n> > +        * hardware brightness value depending on the contrast.\n> > +        */\n> > +       cproc.brightness = (1 - cproc.contrast.value()) + 2 * cproc.requestedBrightness;\n\nYou can drop the parentheses.\n\n> > +       cproc.actualBrightness = (cproc.brightness.value() - (1 - cproc.contrast.value())) / 2;\n\nAnd here too ?\n\n\tcproc.actualBrightness = (cproc.brightness.value() - 1 + cproc.contrast.value()) / 2;\n\nWhat's not immediately apparent from the code is that the last line is\nthere to clamp the requested value. Explaining that in the comment would\nbe nice. Maybe something like this:\n\n\t * Most users expect that changing contrast doesn't change the middle\n\t * gray and that the brightness value is normalized to one. So they\n\t * expect a transfer function of\n\t *\n\t * Yout = (Yin - 0.5) * contrast + 0.5 + user brightness\n\t *\n\t * This can be achieved by computing the hardware brightness value from\n\t * the user brightness and contrast:\n\t *\n\t * Yout = Yin * contract + 0.5 - 0.5 * contrast + user brightness\n\t *      = Yin * contract + (1.0 - contrast + 2 * user brightness) / 2\n\t */\n\tcproc.brightness = 1.0 - cproc.contrast.value()\n\t\t\t + 2 * cproc.requestedBrightness;\n\n\t/*\n\t * The cproc.brightness value is clamped to the hardware limits by the\n\t * Quantized class. This effectively clamps the user brightness to\n\t * limits that now depend on the contrast. Calculate the actual user\n\t * brightness to report in metadata by inverting the formula.\n\t */\n\tcproc.actualBrightness = (cproc.brightness.value() - 1.0 + cproc.contrast.value()) / 2;\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> > +}\n> > +\n> >  } /* namespace */\n> >  \n> >  /**\n> > @@ -76,8 +103,10 @@ int ColorProcessing::configure(IPAContext &context,\n> >  {\n> >         auto &cproc = context.activeState.cproc;\n> >  \n> > -       cproc.brightness = BrightnessQ(kDefaultBrightness);\n> > +       cproc.requestedBrightness = kDefaultBrightness;\n> >         cproc.contrast = ContrastQ(kDefaultContrast);\n> > +       applyRequestedBrightness(context.activeState);\n> > +\n> >         cproc.hue = HueQ(kDefaultHue);\n> >         cproc.saturation = SaturationQ(kDefaultSaturation);\n> >  \n> > @@ -98,17 +127,6 @@ void ColorProcessing::queueRequest(IPAContext &context,\n> >         if (frame == 0)\n> >                 update = true;\n> >  \n> > -       const auto &brightness = controls.get(controls::Brightness);\n> > -       if (brightness) {\n> > -               BrightnessQ value = *brightness;\n> > -               if (cproc.brightness != value) {\n> > -                       cproc.brightness = value;\n> > -                       update = true;\n> > -               }\n> > -\n> > -               LOG(RkISP1CProc, Debug) << \"Set brightness to \" << value;\n> > -       }\n> > -\n> >         const auto &contrast = controls.get(controls::Contrast);\n> >         if (contrast) {\n> >                 ContrastQ value = *contrast;\n> > @@ -120,6 +138,19 @@ void ColorProcessing::queueRequest(IPAContext &context,\n> >                 LOG(RkISP1CProc, Debug) << \"Set contrast to \" << value;\n> >         }\n> >  \n> > +       const auto &brightness = controls.get(controls::Brightness);\n> > +       if (brightness)\n> > +               cproc.requestedBrightness = *brightness;\n> > +\n> > +       if (update || brightness) {\n> > +               BrightnessQ old = cproc.brightness;\n> > +               applyRequestedBrightness(context.activeState);\n> > +               if (cproc.brightness != old)\n> > +                       update = true;\n> > +\n> > +               LOG(RkISP1CProc, Debug) << \"Set brightness to \" << cproc.actualBrightness;\n> > +       }\n> > +\n> >         const auto &hue = controls.get(controls::Hue);\n> >         if (hue) {\n> >                 /* Scale the Hue from ]-90, +90] */\n> > @@ -144,6 +175,7 @@ void ColorProcessing::queueRequest(IPAContext &context,\n> >         }\n> >  \n> >         frameContext.cproc.brightness = cproc.brightness;\n> > +       frameContext.cproc.actualBrightness = cproc.actualBrightness;\n> >         frameContext.cproc.contrast = cproc.contrast;\n> >         frameContext.cproc.hue = cproc.hue;\n> >         frameContext.cproc.saturation = cproc.saturation;\n> > @@ -179,7 +211,7 @@ void ColorProcessing::process([[maybe_unused]] IPAContext &context,\n> >                               [[maybe_unused]] const rkisp1_stat_buffer *stats,\n> >                               ControlList &metadata)\n> >  {\n> > -       metadata.set(controls::Brightness, frameContext.cproc.brightness.value());\n> > +       metadata.set(controls::Brightness, frameContext.cproc.actualBrightness);\n> >         metadata.set(controls::Contrast, frameContext.cproc.contrast.value());\n> >         metadata.set(controls::Hue, frameContext.cproc.hue.value() * kHueScale);\n> >         metadata.set(controls::Saturation, frameContext.cproc.saturation.value());\n> > diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp\n> > index 15cb0afe9fe8..f9d0aff058bc 100644\n> > --- a/src/ipa/rkisp1/ipa_context.cpp\n> > +++ b/src/ipa/rkisp1/ipa_context.cpp\n> > @@ -232,9 +232,15 @@ namespace libcamera::ipa::rkisp1 {\n> >  /**\n> >   * \\var IPAActiveState::cproc\n> >   * \\brief State for the Color Processing algorithm\n> > +  *\n> > + * \\var IPAActiveState::cproc.requestedBrightness\n> > + * \\brief Brightness level requested by the user\n> > +  *\n> > + * \\var IPAActiveState::cproc.actualBrightness\n> > + * \\brief Brightness level after contrast compensation\n> >   *\n> > - * \\struct IPAActiveState::cproc.brightness\n> > - * \\brief Brightness level\n> > + * \\var IPAActiveState::cproc.brightness\n> > + * \\brief Hardware brightness level\n> >   *\n> >   * \\var IPAActiveState::cproc.contrast\n> >   * \\brief Contrast level\n> > @@ -400,8 +406,11 @@ namespace libcamera::ipa::rkisp1 {\n> >   * \\var IPAFrameContext::cproc\n> >   * \\brief Color Processing parameters for this frame\n> >   *\n> > - * \\struct IPAFrameContext::cproc.brightness\n> > - * \\brief Brightness level\n> > + * \\var IPAFrameContext::cproc.actualBrightness\n> > + * \\brief Brightness level after contrast compensation\n> > + *\n> > + * \\var IPAFrameContext::cproc.brightness\n> > + * \\brief Hardware brightness level\n> >   *\n> >   * \\var IPAFrameContext::cproc.contrast\n> >   * \\brief Contrast level\n> > diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h\n> > index 80b035044cda..72ec64532dd8 100644\n> > --- a/src/ipa/rkisp1/ipa_context.h\n> > +++ b/src/ipa/rkisp1/ipa_context.h\n> > @@ -122,6 +122,8 @@ struct IPAActiveState {\n> >         } ccm;\n> >  \n> >         struct {\n> > +               float requestedBrightness;\n> > +               float actualBrightness;\n> >                 BrightnessQ brightness;\n> >                 ContrastQ contrast;\n> >                 HueQ hue;\n> > @@ -181,6 +183,7 @@ struct IPAFrameContext : public FrameContext {\n> >         } awb;\n> >  \n> >         struct {\n> > +               float actualBrightness;\n> >                 BrightnessQ brightness;\n> >                 ContrastQ contrast;\n> >                 HueQ hue;","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 CE590C324C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 11 Jun 2026 01:03:29 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B9EC161F15;\n\tThu, 11 Jun 2026 03:03:28 +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 02D406139A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 11 Jun 2026 03:03:26 +0200 (CEST)","from killaraus.ideasonboard.com\n\t(2001-14ba-70f3-e800--a06.rev.dnainternet.fi\n\t[IPv6:2001:14ba:70f3:e800::a06])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 20ABD228;\n\tThu, 11 Jun 2026 03:02:57 +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=\"JAd0RKaJ\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1781139777;\n\tbh=8yGN/i4i9yBr/iZMsg3Qx/1kXuw6pT7yk60yJ0cq1Rw=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=JAd0RKaJKP9CgY95WYQA1eT+T/0k5dWxF7oE/0rnAHBY+BQHysIaaZMnQqd4cvAzM\n\tUuE/URc2PUVfJ26WvyOiM6IZiwm1t50kqvwmgY4RQKtVqcpij20SZ5A+MOK1qPETR3\n\tVtNlu3WVday8rG1+R8+5ub2IeRU56/KXxlzSZrZI=","Date":"Thu, 11 Jun 2026 04:03:24 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v2] ipa: rkisp1: cproc: Fix brightness and contrast value\n\thandling","Message-ID":"<20260611010324.GA1126460@killaraus.ideasonboard.com>","References":"<20260121133910.34925-1-stefan.klug@ideasonboard.com>\n\t<176908629744.1693075.12877698854137743540@ping.linuxembedded.co.uk>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<176908629744.1693075.12877698854137743540@ping.linuxembedded.co.uk>","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>"}}]