[{"id":14129,"web_url":"https://patchwork.libcamera.org/comment/14129/","msgid":"<CAEmqJPpHOB3U+fNJr=e73oBia4kgH4e4BYcmv3Ak+ujMq1et+w@mail.gmail.com>","date":"2020-12-08T10:13:45","subject":"Re: [libcamera-devel] [PATCH v2 5/6] src: ipa: raspberrypi:\n\tEstimate the colour temerature if starting with fixed colour gains","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi David,\n\nThank you for your patch.\n\nOn Mon, 7 Dec 2020 at 18:02, David Plowman <david.plowman@raspberrypi.com>\nwrote:\n\n> When the AWB is started from \"cold\" with fixed colour gains, we try to\n> estimate the colour temperature this corresponds to (if a calibrated\n> CT curve was supplied). When fixed colour gains are set after the AWB\n> has been running, we leave the CT estimate alone, as the one we have\n> is probably sensible.\n>\n> This estimated colour is passed out in the metadata for other\n> algorithms - notably ALSC - to use.\n>\n> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> ---\n>  src/ipa/raspberrypi/controller/rpi/alsc.cpp |  6 +++++-\n>  src/ipa/raspberrypi/controller/rpi/awb.cpp  | 14 ++++++++++++++\n>  src/ipa/raspberrypi/controller/rpi/awb.hpp  |  1 +\n>  3 files changed, 20 insertions(+), 1 deletion(-)\n>\n> diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> b/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> index 183a0c95..c354c985 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> @@ -146,6 +146,7 @@ void Alsc::Read(boost::property_tree::ptree const\n> &params)\n>         config_.threshold = params.get<double>(\"threshold\", 1e-3);\n>  }\n>\n> +static double get_ct(Metadata *metadata, double default_ct);\n>  static void get_cal_table(double ct,\n>                           std::vector<AlscCalibration> const &calibrations,\n>                           double cal_table[XY]);\n> @@ -210,6 +211,9 @@ void Alsc::SwitchMode(CameraMode const &camera_mode,\n>         // change.\n>         bool reset_tables = first_time_ || compare_modes(camera_mode_,\n> camera_mode);\n>\n> +       // Believe the colour temperature from the AWB, if there is one.\n> +       ct_ = get_ct(metadata, ct_);\n> +\n>         // Ensure the other thread isn't running while we do this.\n>         waitForAysncThread();\n>\n> @@ -254,7 +258,7 @@ void Alsc::fetchAsyncResults()\n>         memcpy(sync_results_, async_results_, sizeof(sync_results_));\n>  }\n>\n> -static double get_ct(Metadata *metadata, double default_ct)\n> +double get_ct(Metadata *metadata, double default_ct)\n>  {\n>         AwbStatus awb_status;\n>         awb_status.temperature_K = default_ct; // in case nothing found\n> diff --git a/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> index 6b359ac5..2266c07b 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> @@ -19,6 +19,9 @@ using namespace RPiController;\n>\n>  const double Awb::RGB::INVALID = -1.0;\n>\n> +// todo - the locking in this algorithm needs some tidying up as has been\n> done\n> +// elsewhere (ALSC and AGC).\n> +\n>  void AwbMode::Read(boost::property_tree::ptree const &params)\n>  {\n>         ct_lo = params.get<double>(\"lo\");\n> @@ -121,6 +124,7 @@ Awb::Awb(Controller *controller)\n>         async_abort_ = async_start_ = async_started_ = async_finished_ =\n> false;\n>         mode_ = nullptr;\n>         manual_r_ = manual_b_ = 0.0;\n> +       first_switch_mode_ = true;\n>         async_thread_ = std::thread(std::bind(&Awb::asyncFunc, this));\n>  }\n>\n> @@ -201,9 +205,19 @@ void Awb::SwitchMode([[maybe_unused]] CameraMode\n> const &camera_mode,\n>                 prev_sync_results_.gain_r = manual_r_;\n>                 prev_sync_results_.gain_g = 1.0;\n>                 prev_sync_results_.gain_b = manual_b_;\n> +               // If we're starting up for the first time, try and\n> +               // \"dead reckon\" the corresponding colour temperature.\n> +               if (first_switch_mode_ && config_.bayes) {\n> +                       Pwl ct_r_inverse =\n> std::move(config_.ct_r.Inverse());\n> +                       Pwl ct_b_inverse =\n> std::move(config_.ct_b.Inverse());\n>\n\nNot a review comment just for my curiosity - will std::move do anything\nhere?  Would C++ Return Value Optimisation ensure that we don't make any\nextra copies without the std::move?\n\nReviewed-by: Naushir Patuck <naush@raspberrypi.com>\n\n\n> +                       double ct_r =\n> ct_r_inverse.Eval(ct_r_inverse.Domain().Clip(1 / manual_r_));\n> +                       double ct_b =\n> ct_b_inverse.Eval(ct_b_inverse.Domain().Clip(1 / manual_b_));\n> +                       prev_sync_results_.temperature_K = (ct_r + ct_b) /\n> 2;\n> +               }\n>                 sync_results_ = prev_sync_results_;\n>         }\n>         metadata->Set(\"awb.status\", prev_sync_results_);\n> +       first_switch_mode_ = false;\n>  }\n>\n>  void Awb::fetchAsyncResults()\n> diff --git a/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> b/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> index d86b9598..8525af32 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> @@ -159,6 +159,7 @@ private:\n>         double manual_r_;\n>         // manual b setting\n>         double manual_b_;\n> +       bool first_switch_mode_; // is this the first call to SwitchMode?\n>  };\n>\n>  static inline Awb::RGB operator+(Awb::RGB const &a, Awb::RGB const &b)\n> --\n> 2.20.1\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel\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 E0876BDB20\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  8 Dec 2020 10:14:06 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5C05A67E73;\n\tTue,  8 Dec 2020 11:14:06 +0100 (CET)","from mail-lj1-x229.google.com (mail-lj1-x229.google.com\n\t[IPv6:2a00:1450:4864:20::229])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C77E635F2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  8 Dec 2020 11:14:05 +0100 (CET)","by mail-lj1-x229.google.com with SMTP id f11so6586704ljn.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 08 Dec 2020 02:14:05 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"BcLhi4ct\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=musQiQNGv0d9jxc2bC+xiykWNyMWlp1bvCEFMolSo5o=;\n\tb=BcLhi4ct69rzwX2v4PgMZQAgfBo7gZDlcTOm4kGNZ9SBwEB+MRkxs0Td0JrvM+iWAW\n\tA2WiatcbsZCJnOOcxQ16JNx84wx0dV5XZnppo8JLJs2pISxPnDifhjNp/yEL7I2kkv+E\n\tLKQpbCvZr5I12092RqjbaagS/ceWrZvTSumIPHWDnn10hIt4XwoVm50BQvEj29vnRIKr\n\tRFIPwykFSLIxLJu27v/6FVogoayOLfsQbal94cFwqxi4eCPPH5jDsr+F9QR/TfoqA2+p\n\tlVkv86/s5IousN5M3DzI8xVHnUcnjbSAHuYZXfYmaHbPPjaQopOGgSKh594lnXl8BWVZ\n\tgxpg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=musQiQNGv0d9jxc2bC+xiykWNyMWlp1bvCEFMolSo5o=;\n\tb=ShXdbDlZTbHTcVKrlFhzNmZcW/a0OeeuOFPABrBlVCqpUWjYiU1maMYR+n2iTi1Q26\n\tAqU4Flu3NaBfOrEom0n7myf2vGuamCnhv1ubT8c5jonGmwkIBof7sUbURE87JexA+Qf2\n\tFaKIv6lKAMMlv/F8YqIignNg7p0kKkoG2yh6gHxP4GGQvAhbCVDPsNoEAjPhxDNA3rzk\n\tnL680b1p/T+mSyXeHRnLpvKC2mUsZ915z+olDi5NekubEohovQTibOkGni7+6B/Bt55O\n\t1ANI5MPy2NcmSlZwsKMdA1P9HIEa0XqauZPKDjWCqojyx87h/PHMJX68mr1QvFILycSZ\n\tbX/Q==","X-Gm-Message-State":"AOAM5301jX1KGrkrEfmz4ZvCG20y/mwm3wo+ChgVweOewyKGkshWhi48\n\tV04Tx7l3I8Jnfj/svprvapZDE/TSHIm48sJ1PJGMiA==","X-Google-Smtp-Source":"ABdhPJzx9zPkFV2bmU6egZ7XhY+Xpy3/oekHeJMXRTh1riUnqENXyi/eaijILFITUSfspe5XGDsJtzbqQQ01OpVx5Tw=","X-Received":"by 2002:a05:651c:503:: with SMTP id\n\to3mr10117727ljp.253.1607422444824; \n\tTue, 08 Dec 2020 02:14:04 -0800 (PST)","MIME-Version":"1.0","References":"<20201207180121.6374-1-david.plowman@raspberrypi.com>\n\t<20201207180121.6374-6-david.plowman@raspberrypi.com>","In-Reply-To":"<20201207180121.6374-6-david.plowman@raspberrypi.com>","From":"Naushir Patuck <naush@raspberrypi.com>","Date":"Tue, 8 Dec 2020 10:13:45 +0000","Message-ID":"<CAEmqJPpHOB3U+fNJr=e73oBia4kgH4e4BYcmv3Ak+ujMq1et+w@mail.gmail.com>","To":"David Plowman <david.plowman@raspberrypi.com>","Subject":"Re: [libcamera-devel] [PATCH v2 5/6] src: ipa: raspberrypi:\n\tEstimate the colour temerature if starting with fixed colour gains","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>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Content-Type":"multipart/mixed;\n\tboundary=\"===============3040885042267853902==\"","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":14142,"web_url":"https://patchwork.libcamera.org/comment/14142/","msgid":"<X89qlkGN2SrpX0jx@pendragon.ideasonboard.com>","date":"2020-12-08T11:59:18","subject":"Re: [libcamera-devel] [PATCH v2 5/6] src: ipa: raspberrypi:\n\tEstimate the colour temerature if starting with fixed colour gains","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi David,\n\nThank you for the patch.\n\nOn Mon, Dec 07, 2020 at 06:01:20PM +0000, David Plowman wrote:\n> When the AWB is started from \"cold\" with fixed colour gains, we try to\n> estimate the colour temperature this corresponds to (if a calibrated\n> CT curve was supplied). When fixed colour gains are set after the AWB\n> has been running, we leave the CT estimate alone, as the one we have\n> is probably sensible.\n> \n> This estimated colour is passed out in the metadata for other\n> algorithms - notably ALSC - to use.\n> \n> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> ---\n>  src/ipa/raspberrypi/controller/rpi/alsc.cpp |  6 +++++-\n>  src/ipa/raspberrypi/controller/rpi/awb.cpp  | 14 ++++++++++++++\n>  src/ipa/raspberrypi/controller/rpi/awb.hpp  |  1 +\n>  3 files changed, 20 insertions(+), 1 deletion(-)\n> \n> diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> index 183a0c95..c354c985 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> @@ -146,6 +146,7 @@ void Alsc::Read(boost::property_tree::ptree const &params)\n>  \tconfig_.threshold = params.get<double>(\"threshold\", 1e-3);\n>  }\n>  \n> +static double get_ct(Metadata *metadata, double default_ct);\n>  static void get_cal_table(double ct,\n>  \t\t\t  std::vector<AlscCalibration> const &calibrations,\n>  \t\t\t  double cal_table[XY]);\n> @@ -210,6 +211,9 @@ void Alsc::SwitchMode(CameraMode const &camera_mode,\n>  \t// change.\n>  \tbool reset_tables = first_time_ || compare_modes(camera_mode_, camera_mode);\n>  \n> +\t// Believe the colour temperature from the AWB, if there is one.\n> +\tct_ = get_ct(metadata, ct_);\n> +\n>  \t// Ensure the other thread isn't running while we do this.\n>  \twaitForAysncThread();\n>  \n> @@ -254,7 +258,7 @@ void Alsc::fetchAsyncResults()\n>  \tmemcpy(sync_results_, async_results_, sizeof(sync_results_));\n>  }\n>  \n> -static double get_ct(Metadata *metadata, double default_ct)\n> +double get_ct(Metadata *metadata, double default_ct)\n\nIs this needed, does the compiler complain otherwise ? And on a side\nnote, we could also move the function up to avoid forward declarations,\nbut that doesn't have to be part of this patch.\n\n>  {\n>  \tAwbStatus awb_status;\n>  \tawb_status.temperature_K = default_ct; // in case nothing found\n> diff --git a/src/ipa/raspberrypi/controller/rpi/awb.cpp b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> index 6b359ac5..2266c07b 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> @@ -19,6 +19,9 @@ using namespace RPiController;\n>  \n>  const double Awb::RGB::INVALID = -1.0;\n>  \n> +// todo - the locking in this algorithm needs some tidying up as has been done\n> +// elsewhere (ALSC and AGC).\n> +\n>  void AwbMode::Read(boost::property_tree::ptree const &params)\n>  {\n>  \tct_lo = params.get<double>(\"lo\");\n> @@ -121,6 +124,7 @@ Awb::Awb(Controller *controller)\n>  \tasync_abort_ = async_start_ = async_started_ = async_finished_ = false;\n>  \tmode_ = nullptr;\n>  \tmanual_r_ = manual_b_ = 0.0;\n> +\tfirst_switch_mode_ = true;\n>  \tasync_thread_ = std::thread(std::bind(&Awb::asyncFunc, this));\n>  }\n>  \n> @@ -201,9 +205,19 @@ void Awb::SwitchMode([[maybe_unused]] CameraMode const &camera_mode,\n>  \t\tprev_sync_results_.gain_r = manual_r_;\n>  \t\tprev_sync_results_.gain_g = 1.0;\n>  \t\tprev_sync_results_.gain_b = manual_b_;\n> +\t\t// If we're starting up for the first time, try and\n> +\t\t// \"dead reckon\" the corresponding colour temperature.\n> +\t\tif (first_switch_mode_ && config_.bayes) {\n> +\t\t\tPwl ct_r_inverse = std::move(config_.ct_r.Inverse());\n> +\t\t\tPwl ct_b_inverse = std::move(config_.ct_b.Inverse());\n\nI think you can drop std::move(), as Naush mentioned return value\noptimization will take care of this (and std::move() can actually\nprevent RVO in some cases).\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +\t\t\tdouble ct_r = ct_r_inverse.Eval(ct_r_inverse.Domain().Clip(1 / manual_r_));\n> +\t\t\tdouble ct_b = ct_b_inverse.Eval(ct_b_inverse.Domain().Clip(1 / manual_b_));\n> +\t\t\tprev_sync_results_.temperature_K = (ct_r + ct_b) / 2;\n> +\t\t}\n>  \t\tsync_results_ = prev_sync_results_;\n>  \t}\n>  \tmetadata->Set(\"awb.status\", prev_sync_results_);\n> +\tfirst_switch_mode_ = false;\n>  }\n>  \n>  void Awb::fetchAsyncResults()\n> diff --git a/src/ipa/raspberrypi/controller/rpi/awb.hpp b/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> index d86b9598..8525af32 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> @@ -159,6 +159,7 @@ private:\n>  \tdouble manual_r_;\n>  \t// manual b setting\n>  \tdouble manual_b_;\n> +\tbool first_switch_mode_; // is this the first call to SwitchMode?\n>  };\n>  \n>  static inline Awb::RGB operator+(Awb::RGB const &a, Awb::RGB const &b)","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 1C010BDB1F\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  8 Dec 2020 11:59:23 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7B40C67E71;\n\tTue,  8 Dec 2020 12:59:22 +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 94DD267E15\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  8 Dec 2020 12:59:21 +0100 (CET)","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 2055DDD;\n\tTue,  8 Dec 2020 12:59:21 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"ummGJlw/\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1607428761;\n\tbh=D/xExY9fR7mPgM7qNlzuNmj2U1JfIti26csAsQBzx4E=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=ummGJlw/KWYQoU5A4gU6Rnwykmmfu+gwuUp7BJJ2H1DTkzphCOtkwrnz9k4DOekV7\n\t656yacmnWcKW9Yd/Xcr3Aai4AXILZGAausN/LIhro/K++uCnT+oZb6Ah+QPDL4HCol\n\tySPx7XImThSGvBsYahMSjLfUZnr7de4vkDt9By6E=","Date":"Tue, 8 Dec 2020 13:59:18 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"David Plowman <david.plowman@raspberrypi.com>","Message-ID":"<X89qlkGN2SrpX0jx@pendragon.ideasonboard.com>","References":"<20201207180121.6374-1-david.plowman@raspberrypi.com>\n\t<20201207180121.6374-6-david.plowman@raspberrypi.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20201207180121.6374-6-david.plowman@raspberrypi.com>","Subject":"Re: [libcamera-devel] [PATCH v2 5/6] src: ipa: raspberrypi:\n\tEstimate the colour temerature if starting with fixed colour gains","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":14144,"web_url":"https://patchwork.libcamera.org/comment/14144/","msgid":"<X89txxeAk14xr4+A@pendragon.ideasonboard.com>","date":"2020-12-08T12:12:55","subject":"Re: [libcamera-devel] [PATCH v2 5/6] src: ipa: raspberrypi:\n\tEstimate the colour temerature if starting with fixed colour gains","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi David,\n\nOn Tue, Dec 08, 2020 at 01:59:18PM +0200, Laurent Pinchart wrote:\n> On Mon, Dec 07, 2020 at 06:01:20PM +0000, David Plowman wrote:\n> > When the AWB is started from \"cold\" with fixed colour gains, we try to\n> > estimate the colour temperature this corresponds to (if a calibrated\n> > CT curve was supplied). When fixed colour gains are set after the AWB\n> > has been running, we leave the CT estimate alone, as the one we have\n> > is probably sensible.\n> > \n> > This estimated colour is passed out in the metadata for other\n> > algorithms - notably ALSC - to use.\n> > \n> > Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> > ---\n> >  src/ipa/raspberrypi/controller/rpi/alsc.cpp |  6 +++++-\n> >  src/ipa/raspberrypi/controller/rpi/awb.cpp  | 14 ++++++++++++++\n> >  src/ipa/raspberrypi/controller/rpi/awb.hpp  |  1 +\n> >  3 files changed, 20 insertions(+), 1 deletion(-)\n> > \n> > diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> > index 183a0c95..c354c985 100644\n> > --- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> > +++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> > @@ -146,6 +146,7 @@ void Alsc::Read(boost::property_tree::ptree const &params)\n> >  \tconfig_.threshold = params.get<double>(\"threshold\", 1e-3);\n> >  }\n> >  \n> > +static double get_ct(Metadata *metadata, double default_ct);\n> >  static void get_cal_table(double ct,\n> >  \t\t\t  std::vector<AlscCalibration> const &calibrations,\n> >  \t\t\t  double cal_table[XY]);\n> > @@ -210,6 +211,9 @@ void Alsc::SwitchMode(CameraMode const &camera_mode,\n> >  \t// change.\n> >  \tbool reset_tables = first_time_ || compare_modes(camera_mode_, camera_mode);\n> >  \n> > +\t// Believe the colour temperature from the AWB, if there is one.\n> > +\tct_ = get_ct(metadata, ct_);\n> > +\n> >  \t// Ensure the other thread isn't running while we do this.\n> >  \twaitForAysncThread();\n> >  \n> > @@ -254,7 +258,7 @@ void Alsc::fetchAsyncResults()\n> >  \tmemcpy(sync_results_, async_results_, sizeof(sync_results_));\n> >  }\n> >  \n> > -static double get_ct(Metadata *metadata, double default_ct)\n> > +double get_ct(Metadata *metadata, double default_ct)\n> \n> Is this needed, does the compiler complain otherwise ? And on a side\n> note, we could also move the function up to avoid forward declarations,\n> but that doesn't have to be part of this patch.\n> \n> >  {\n> >  \tAwbStatus awb_status;\n> >  \tawb_status.temperature_K = default_ct; // in case nothing found\n> > diff --git a/src/ipa/raspberrypi/controller/rpi/awb.cpp b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> > index 6b359ac5..2266c07b 100644\n> > --- a/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> > +++ b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> > @@ -19,6 +19,9 @@ using namespace RPiController;\n> >  \n> >  const double Awb::RGB::INVALID = -1.0;\n> >  \n> > +// todo - the locking in this algorithm needs some tidying up as has been done\n> > +// elsewhere (ALSC and AGC).\n> > +\n> >  void AwbMode::Read(boost::property_tree::ptree const &params)\n> >  {\n> >  \tct_lo = params.get<double>(\"lo\");\n> > @@ -121,6 +124,7 @@ Awb::Awb(Controller *controller)\n> >  \tasync_abort_ = async_start_ = async_started_ = async_finished_ = false;\n> >  \tmode_ = nullptr;\n> >  \tmanual_r_ = manual_b_ = 0.0;\n> > +\tfirst_switch_mode_ = true;\n> >  \tasync_thread_ = std::thread(std::bind(&Awb::asyncFunc, this));\n> >  }\n> >  \n> > @@ -201,9 +205,19 @@ void Awb::SwitchMode([[maybe_unused]] CameraMode const &camera_mode,\n> >  \t\tprev_sync_results_.gain_r = manual_r_;\n> >  \t\tprev_sync_results_.gain_g = 1.0;\n> >  \t\tprev_sync_results_.gain_b = manual_b_;\n> > +\t\t// If we're starting up for the first time, try and\n> > +\t\t// \"dead reckon\" the corresponding colour temperature.\n> > +\t\tif (first_switch_mode_ && config_.bayes) {\n> > +\t\t\tPwl ct_r_inverse = std::move(config_.ct_r.Inverse());\n> > +\t\t\tPwl ct_b_inverse = std::move(config_.ct_b.Inverse());\n> \n> I think you can drop std::move(), as Naush mentioned return value\n> optimization will take care of this (and std::move() can actually\n> prevent RVO in some cases).\n\nclang even warns about this:\n\n../../src/ipa/raspberrypi/controller/rpi/awb.cpp:211:23: error: moving a temporary object prevents copy elision [-Werror,-Wpessimizing-move]\n                        Pwl ct_r_inverse = std::move(config_.ct_r.Inverse());\n\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n> > +\t\t\tdouble ct_r = ct_r_inverse.Eval(ct_r_inverse.Domain().Clip(1 / manual_r_));\n> > +\t\t\tdouble ct_b = ct_b_inverse.Eval(ct_b_inverse.Domain().Clip(1 / manual_b_));\n> > +\t\t\tprev_sync_results_.temperature_K = (ct_r + ct_b) / 2;\n> > +\t\t}\n> >  \t\tsync_results_ = prev_sync_results_;\n> >  \t}\n> >  \tmetadata->Set(\"awb.status\", prev_sync_results_);\n> > +\tfirst_switch_mode_ = false;\n> >  }\n> >  \n> >  void Awb::fetchAsyncResults()\n> > diff --git a/src/ipa/raspberrypi/controller/rpi/awb.hpp b/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> > index d86b9598..8525af32 100644\n> > --- a/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> > +++ b/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> > @@ -159,6 +159,7 @@ private:\n> >  \tdouble manual_r_;\n> >  \t// manual b setting\n> >  \tdouble manual_b_;\n> > +\tbool first_switch_mode_; // is this the first call to SwitchMode?\n> >  };\n> >  \n> >  static inline Awb::RGB operator+(Awb::RGB const &a, Awb::RGB const &b)","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 0212ABDB1F\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  8 Dec 2020 12:13:01 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 70EC767E72;\n\tTue,  8 Dec 2020 13:13:00 +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 488A967E6F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  8 Dec 2020 13:12:59 +0100 (CET)","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 B1271DD;\n\tTue,  8 Dec 2020 13:12:58 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"eajpgsGp\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1607429578;\n\tbh=jxHZlPTZjENfho7gZRt/3wKwgNoSBFbYRNFrV1nAWrk=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=eajpgsGpGoNj1KyYhF4YpYBvoVSfsujBZWm31mX7EAfAzkqKO+jRl543lBv+is6Sf\n\tmbd/9u+vPw3aqscCqUFoz86rkddtN5fH0r8hLaqb//LORs7257v6pPwyj6N/skkoTR\n\tGiASI3cIZfPYzV7nYqE9SgDmZrSYOAkueGPfFA94=","Date":"Tue, 8 Dec 2020 14:12:55 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"David Plowman <david.plowman@raspberrypi.com>","Message-ID":"<X89txxeAk14xr4+A@pendragon.ideasonboard.com>","References":"<20201207180121.6374-1-david.plowman@raspberrypi.com>\n\t<20201207180121.6374-6-david.plowman@raspberrypi.com>\n\t<X89qlkGN2SrpX0jx@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<X89qlkGN2SrpX0jx@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v2 5/6] src: ipa: raspberrypi:\n\tEstimate the colour temerature if starting with fixed colour gains","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]