[{"id":26392,"web_url":"https://patchwork.libcamera.org/comment/26392/","msgid":"<167517475558.42371.6132833722566979535@Monstersaurus>","date":"2023-01-31T14:19:15","subject":"Re: [libcamera-devel] [PATCH] ipa: raspberrypi: Normalise region\n\tsums to 16-bits","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Naushir Patuck (2023-01-31 13:46:46)\n> The VC4 ISP uses a pipeline bit-depth of 13-bits. The AGC algorithm needs to\n> know this bit-depth when computing the Y value for the image.\n> \n> Instead of hardcoding the VC4 bit-depth in the AGC source code, normalise all\n> region sums to 16-bits when filling the Statistics structure. AWB and ALSC are\n> agnostic about pipeline depth, so do not need changing.\n> \n> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>\n> Reviewed-by: David Plowman <david.plowman@raspberrypi.com>\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> ---\n>  src/ipa/raspberrypi/controller/rpi/agc.cpp | 11 +++++------\n>  src/ipa/raspberrypi/raspberrypi.cpp        | 18 ++++++++++++------\n>  src/ipa/raspberrypi/statistics.h           |  6 ++++++\n>  3 files changed, 23 insertions(+), 12 deletions(-)\n> \n> diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp\n> index 868c30f03d66..ea0c82b5c4c8 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/agc.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp\n> @@ -28,8 +28,6 @@ LOG_DEFINE_CATEGORY(RPiAgc)\n>  \n>  #define NAME \"rpi.agc\"\n>  \n> -static constexpr unsigned int PipelineBits = 13; /* seems to be a 13-bit pipeline */\n> -\n>  int AgcMeteringMode::read(const libcamera::YamlObject &params)\n>  {\n>         const YamlObject &yamlWeights = params[\"weights\"];\n> @@ -586,6 +584,7 @@ void Agc::fetchAwbStatus(Metadata *imageMetadata)\n>  static double computeInitialY(StatisticsPtr &stats, AwbStatus const &awb,\n>                               double weights[], double gain)\n>  {\n> +       constexpr unsigned int maxVal = 1 << Statistics::NormalisationFactorPow2;\n>         /*\n>          * Note how the calculation below means that equal weights give you\n>          * \"average\" metering (i.e. all pixels equally important).\n> @@ -593,9 +592,9 @@ static double computeInitialY(StatisticsPtr &stats, AwbStatus const &awb,\n>         double rSum = 0, gSum = 0, bSum = 0, pixelSum = 0;\n>         for (unsigned int i = 0; i < stats->agcRegions.numRegions(); i++) {\n>                 auto &region = stats->agcRegions.get(i);\n> -               double rAcc = std::min<double>(region.val.rSum * gain, ((1 << PipelineBits) - 1) * region.counted);\n> -               double gAcc = std::min<double>(region.val.gSum * gain, ((1 << PipelineBits) - 1) * region.counted);\n> -               double bAcc = std::min<double>(region.val.bSum * gain, ((1 << PipelineBits) - 1) * region.counted);\n> +               double rAcc = std::min<double>(region.val.rSum * gain, (maxVal - 1) * region.counted);\n> +               double gAcc = std::min<double>(region.val.gSum * gain, (maxVal - 1) * region.counted);\n> +               double bAcc = std::min<double>(region.val.bSum * gain, (maxVal - 1) * region.counted);\n>                 rSum += rAcc * weights[i];\n>                 gSum += gAcc * weights[i];\n>                 bSum += bAcc * weights[i];\n> @@ -608,7 +607,7 @@ static double computeInitialY(StatisticsPtr &stats, AwbStatus const &awb,\n>         double ySum = rSum * awb.gainR * .299 +\n>                       gSum * awb.gainG * .587 +\n>                       bSum * awb.gainB * .114;\n> -       return ySum / pixelSum / (1 << PipelineBits);\n> +       return ySum / pixelSum / maxVal;\n>  }\n>  \n>  /*\n> diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp\n> index cff079bbafb3..1cf7649c3303 100644\n> --- a/src/ipa/raspberrypi/raspberrypi.cpp\n> +++ b/src/ipa/raspberrypi/raspberrypi.cpp\n> @@ -1154,11 +1154,17 @@ RPiController::StatisticsPtr IPARPi::fillStatistics(bcm2835_isp_stats *stats) co\n>         /* RGB histograms are not used, so do not populate them. */\n>         statistics->yHist = std::move(RPiController::Histogram(stats->hist[0].g_hist, NUM_HISTOGRAM_BINS));\n>  \n> +       /*\n> +        * All region sums are based on a 13-bit pipeline bit-depth. Normalise\n> +        * this to 16-bits for the AGC/AWB/ALSC algorithms.\n> +        */\n> +       constexpr unsigned int scale = Statistics::NormalisationFactorPow2 - 13;\n> +\n>         statistics->awbRegions.init({ DEFAULT_AWB_REGIONS_X, DEFAULT_AWB_REGIONS_Y });\n>         for (i = 0; i < statistics->awbRegions.numRegions(); i++)\n> -               statistics->awbRegions.set(i, { { stats->awb_stats[i].r_sum,\n> -                                                 stats->awb_stats[i].g_sum,\n> -                                                 stats->awb_stats[i].b_sum },\n> +               statistics->awbRegions.set(i, { { stats->awb_stats[i].r_sum << scale,\n> +                                                 stats->awb_stats[i].g_sum << scale,\n> +                                                 stats->awb_stats[i].b_sum << scale },\n>                                                 stats->awb_stats[i].counted,\n>                                                 stats->awb_stats[i].notcounted });\n>  \n> @@ -1168,9 +1174,9 @@ RPiController::StatisticsPtr IPARPi::fillStatistics(bcm2835_isp_stats *stats) co\n>          */\n>         statistics->agcRegions.init(15);\n>         for (i = 0; i < statistics->agcRegions.numRegions(); i++)\n> -               statistics->agcRegions.set(i, { { stats->agc_stats[i].r_sum,\n> -                                                 stats->agc_stats[i].g_sum,\n> -                                                 stats->agc_stats[i].b_sum },\n> +               statistics->agcRegions.set(i, { { stats->agc_stats[i].r_sum << scale,\n> +                                                 stats->agc_stats[i].g_sum << scale,\n> +                                                 stats->agc_stats[i].b_sum << scale },\n>                                                 stats->agc_stats[i].counted,\n>                                                 stats->awb_stats[i].notcounted });\n>  \n> diff --git a/src/ipa/raspberrypi/statistics.h b/src/ipa/raspberrypi/statistics.h\n> index affb7272c963..22a72c94a90d 100644\n> --- a/src/ipa/raspberrypi/statistics.h\n> +++ b/src/ipa/raspberrypi/statistics.h\n> @@ -30,6 +30,12 @@ using RgbyRegions = RegionStats<RgbySums>;\n>  using FocusRegions = RegionStats<uint64_t>;\n>  \n>  struct Statistics {\n> +       /*\n> +        * All histogram and region based statistics are scaled to a maximum\n> +        * value given by (1 << NormalisationFactorPow2) - 1.\n> +        */\n> +       static constexpr unsigned int NormalisationFactorPow2 = 16;\n> +\n>         /*\n>          * Positioning of the AGC statistics gathering in the pipeline:\n>          * Pre-WB correction or post-WB correction.\n> -- \n> 2.25.1\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 222D0BEFBE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 31 Jan 2023 14:19:21 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 703A4625E4;\n\tTue, 31 Jan 2023 15:19:20 +0100 (CET)","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 102A6625D0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 31 Jan 2023 15:19:19 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 89E44D6;\n\tTue, 31 Jan 2023 15:19:18 +0100 (CET)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1675174760;\n\tbh=sYyuhirB96rpOAqBJuV42ngaxW3dEdnuhPwMYFv5fKQ=;\n\th=In-Reply-To:References:To:Date:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=28dktqCLCLbQhoez1SKetcY3bYxBPEh9HzpSpL/G8GwIhU4cw6YXp7LcSG8A/lRje\n\tAjqWRxI2+wLaPaUyEVrjrBwz5EFxkRH/cQbXogszTFWwgUuR5U/IWKUUpLRQVHDNwu\n\th9IwGqJhqVrEYDJerYcj4JsS7acdkyf+PfU4np0RR+PX2y6roZUAZAc+9ByXkZXAgO\n\tdDdFICcLHnh5OGotp1GN8U7RtgW/kVkr51qrrTFhwTOFxVVAt2OY1qYyE9QCzny3EV\n\tsK157Xs2mCTDkz8apQ8JE3rEccGMSZ+87PfhyKxblKK1s3Hne6Df0MIketJ2w+oDCW\n\t+34wjUvkGO9PQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1675174758;\n\tbh=sYyuhirB96rpOAqBJuV42ngaxW3dEdnuhPwMYFv5fKQ=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=FNSKFLtahNvXXIf+T0DCVsYrHxvsOGQMuXxJ1BsFLbXWv5XIsy9Bww6YhIm1lljWY\n\tufW4+h0OOa6KMuEyBLoEtapC0R+fdnWXjD0IhTOZKK+honXX27nVce51aE8xMI2Ybm\n\tFqfWvmyC0gSI47c1bx06eim8tuBMPLTLxP+AqjpI="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"FNSKFLta\"; dkim-atps=neutral","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20230131134646.9868-1-naush@raspberrypi.com>","References":"<20221213114836.15473-6-naush@raspberrypi.com>\n\t<20230131134646.9868-1-naush@raspberrypi.com>","To":"Naushir Patuck <naush@raspberrypi.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Tue, 31 Jan 2023 14:19:15 +0000","Message-ID":"<167517475558.42371.6132833722566979535@Monstersaurus>","User-Agent":"alot/0.10","Subject":"Re: [libcamera-devel] [PATCH] ipa: raspberrypi: Normalise region\n\tsums to 16-bits","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":"Kieran Bingham via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]