[{"id":20043,"web_url":"https://patchwork.libcamera.org/comment/20043/","msgid":"<YVurWMBb98E7IQNa@pendragon.ideasonboard.com>","date":"2021-10-05T01:33:12","subject":"Re: [libcamera-devel] [PATCH v2 12/12] ipa: ipu3: Replace\n\tipa::ipu3::algorithms::Ipu3AwbCell","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jean-Michel,\n\nThank you for the patch.\n\nOn Thu, Sep 30, 2021 at 11:37:15AM +0200, Jean-Michel Hautbois wrote:\n> The intel-ipu3.h public interface from the kernel does not define how to\n> parse the statistics for a cell. This had to be identified by a process\n> of reverse engineering, and later identifying the structures from [0]\n> leading to our custom definition of struct Ipu3AwbCell.\n> \n> [0]\n> https://chromium.googlesource.com/chromiumos/platform/arc-camera/+/refs/heads/master/hal/intel/include/ia_imaging/awb_public.h\n> \n> To improve the kernel interface, a proposal has been made to the\n> linux-kernel [1] to incorporate the memory layout for each cell into the\n> intel-ipu3 header directly.\n> \n> [1]\n> https://lore.kernel.org/linux-media/20210930092021.65741-1-jeanmichel.hautbois@ideasonboard.com/\n> \n> Update our local copy of the intel-ipu3.h to match the proposal and\n> change the AGC and AWB algorithms to reference that structure directly,\n> allowing us to remove the deprecated custom Ipu3AwbCell definition.\n> \n> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  include/linux/intel-ipu3.h      | 31 +++++++++++++++++++++----\n>  src/ipa/ipu3/algorithms/agc.cpp | 14 +++++------\n>  src/ipa/ipu3/algorithms/awb.cpp | 41 ++++++---------------------------\n>  src/ipa/ipu3/algorithms/awb.h   | 10 --------\n>  4 files changed, 40 insertions(+), 56 deletions(-)\n> \n> diff --git a/include/linux/intel-ipu3.h b/include/linux/intel-ipu3.h\n> index ee0e6d0e..a5a71ca8 100644\n> --- a/include/linux/intel-ipu3.h\n> +++ b/include/linux/intel-ipu3.h\n> @@ -59,6 +59,29 @@ struct ipu3_uapi_grid_config {\n>  \t__u16 y_end;\n>  } __attribute__((packed));\n>  \n> +/**\n> + * struct ipu3_uapi_awb_set_item - Memory layout for each cell in AWB\n> + *\n> + * @Gr_avg:\tGreen average for red lines in the cell.\n> + * @R_avg:\tRed average in the cell.\n> + * @B_avg:\tBlue average in the cell.\n> + * @Gb_avg:\tGreen average for blue lines in the cell.\n> + * @sat_ratio:  Saturation ratio in the cell.\n> + * @padding0:   Unused byte for padding.\n> + * @padding1:   Unused byte for padding.\n> + * @padding2:   Unused byte for padding.\n> + */\n> +struct ipu3_uapi_awb_set_item {\n> +\tunsigned char Gr_avg;\n> +\tunsigned char R_avg;\n> +\tunsigned char B_avg;\n> +\tunsigned char Gb_avg;\n> +\tunsigned char sat_ratio;\n> +\tunsigned char padding0;\n> +\tunsigned char padding1;\n> +\tunsigned char padding2;\n> +} __attribute__((packed));\n> +\n>  /*\n>   * The grid based data is divided into \"slices\" called set, each slice of setX\n>   * refers to ipu3_uapi_grid_config width * height_per_slice.\n> @@ -71,9 +94,9 @@ struct ipu3_uapi_grid_config {\n>  \t(IPU3_UAPI_MAX_BUBBLE_SIZE * IPU3_UAPI_MAX_STRIPES * \\\n>  \t IPU3_UAPI_AWB_MD_ITEM_SIZE)\n>  #define IPU3_UAPI_AWB_MAX_BUFFER_SIZE \\\n> -\t(IPU3_UAPI_AWB_MAX_SETS * \\\n> -\t (IPU3_UAPI_AWB_SET_SIZE + IPU3_UAPI_AWB_SPARE_FOR_BUBBLES))\n> -\n> +\t((IPU3_UAPI_AWB_MAX_SETS * \\\n> +\t (IPU3_UAPI_AWB_SET_SIZE + IPU3_UAPI_AWB_SPARE_FOR_BUBBLES)) / \\\n> +\t sizeof(struct ipu3_uapi_awb_set_item))\n\nI've reviewed the corresponding kernel patch, copying the comment here\nas libcamera-devel wasn't CC'ed:\n\nWe'll really have to figure out what the bubbles are... Not in this\npatch though.\n\nGiven that IPU3_UAPI_AWB_MD_ITEM_SIZE is equal to the size of one item,\nhow about this ?\n\ndiff --git a/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h b/drivers/staging/media/ipu3/include/uapi/intel-ipu3.h\nindex ee0e6d0e4b2c..a18e9228ed07 100644\n--- a/include/linux/intel-ipu3.h\n+++ b/include/linux/intel-ipu3.h\n@@ -65,11 +65,9 @@ struct ipu3_uapi_grid_config {\n  */\n #define IPU3_UAPI_AWB_MAX_SETS\t\t\t\t60\n /* Based on grid size 80 * 60 and cell size 16 x 16 */\n-#define IPU3_UAPI_AWB_SET_SIZE\t\t\t\t1280\n-#define IPU3_UAPI_AWB_MD_ITEM_SIZE\t\t\t8\n+#define IPU3_UAPI_AWB_SET_SIZE\t\t\t\t160\n #define IPU3_UAPI_AWB_SPARE_FOR_BUBBLES \\\n-\t(IPU3_UAPI_MAX_BUBBLE_SIZE * IPU3_UAPI_MAX_STRIPES * \\\n-\t IPU3_UAPI_AWB_MD_ITEM_SIZE)\n+\t(IPU3_UAPI_MAX_BUBBLE_SIZE * IPU3_UAPI_MAX_STRIPES)\n #define IPU3_UAPI_AWB_MAX_BUFFER_SIZE \\\n \t(IPU3_UAPI_AWB_MAX_SETS * \\\n \t (IPU3_UAPI_AWB_SET_SIZE + IPU3_UAPI_AWB_SPARE_FOR_BUBBLES))\n\n>  /**\n>   * struct ipu3_uapi_awb_raw_buffer - AWB raw buffer\n> @@ -82,7 +105,7 @@ struct ipu3_uapi_grid_config {\n>   *\t\tthe average values for each color channel.\n>   */\n>  struct ipu3_uapi_awb_raw_buffer {\n> -\t__u8 meta_data[IPU3_UAPI_AWB_MAX_BUFFER_SIZE]\n> +\tstruct ipu3_uapi_awb_set_item meta_data[IPU3_UAPI_AWB_MAX_BUFFER_SIZE]\n>  \t\t__attribute__((aligned(32)));\n>  } __attribute__((packed));\n>  \n> diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp\n> index 46e01fc4..44008632 100644\n> --- a/src/ipa/ipu3/algorithms/agc.cpp\n> +++ b/src/ipa/ipu3/algorithms/agc.cpp\n> @@ -6,7 +6,6 @@\n>   */\n>  \n>  #include \"agc.h\"\n> -#include \"awb.h\"\n>  \n>  #include <algorithm>\n>  #include <chrono>\n> @@ -73,18 +72,17 @@ void Agc::processBrightness(const ipu3_uapi_stats_3a *stats,\n>  \n>  \tfor (unsigned int cellY = 0; cellY < grid.height; cellY++) {\n>  \t\tfor (unsigned int cellX = 0; cellX < grid.width; cellX++) {\n> -\t\t\tuint32_t cellPosition = cellY * stride_ + cellX\n> -\t\t\t\t\t      * sizeof(Ipu3AwbCell);\n> +\t\t\tuint32_t cellPosition = cellY * stride_ + cellX;\n>  \n>  \t\t\t/* Cast the initial IPU3 structure to simplify the reading */\n> -\t\t\tconst Ipu3AwbCell *cell =\n> -\t\t\t\treinterpret_cast<const Ipu3AwbCell *>(\n> +\t\t\tconst ipu3_uapi_awb_set_item *cell =\n> +\t\t\t\treinterpret_cast<const ipu3_uapi_awb_set_item *>(\n>  \t\t\t\t\t&stats->awb_raw_buffer.meta_data[cellPosition]\n>  \t\t\t\t);\n>  \n> -\t\t\tif (cell->satRatio == 0) {\n> -\t\t\t\tuint8_t gr = cell->greenRedAvg;\n> -\t\t\t\tuint8_t gb = cell->greenBlueAvg;\n> +\t\t\tif (cell->sat_ratio == 0) {\n> +\t\t\t\tuint8_t gr = cell->Gr_avg;\n> +\t\t\t\tuint8_t gb = cell->Gb_avg;\n>  \t\t\t\thist[(gr + gb) / 2]++;\n>  \t\t\t}\n>  \t\t}\n> diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp\n> index fcd1469f..4558f85a 100644\n> --- a/src/ipa/ipu3/algorithms/awb.cpp\n> +++ b/src/ipa/ipu3/algorithms/awb.cpp\n> @@ -104,32 +104,6 @@ static constexpr uint32_t kMinGreenLevelInZone = 32;\n>   * \\brief Gain calculated for the blue channel\n>   */\n>  \n> -/**\n> - * \\struct Ipu3AwbCell\n> - * \\brief Memory layout for each cell in AWB metadata\n> - *\n> - * The Ipu3AwbCell structure is used to get individual values\n> - * such as red average or saturation ratio in a particular cell.\n> - *\n> - * \\var Ipu3AwbCell::greenRedAvg\n> - * \\brief Green average for red lines in the cell\n> - *\n> - * \\var Ipu3AwbCell::redAvg\n> - * \\brief Red average in the cell\n> - *\n> - * \\var Ipu3AwbCell::blueAvg\n> - * \\brief blue average in the cell\n> - *\n> - * \\var Ipu3AwbCell::greenBlueAvg\n> - * \\brief Green average for blue lines\n> - *\n> - * \\var Ipu3AwbCell::satRatio\n> - * \\brief Saturation ratio in the cell\n> - *\n> - * \\var Ipu3AwbCell::padding\n> - * \\brief array of unused bytes for padding\n> - */\n> -\n>  /* Default settings for Bayer noise reduction replicated from the Kernel */\n>  static const struct ipu3_uapi_bnr_static_config imguCssBnrDefaults = {\n>  \t.wb_gains = { 16, 16, 16, 16 },\n> @@ -243,25 +217,24 @@ void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats)\n>  \t */\n>  \tfor (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY_; cellY++) {\n>  \t\tfor (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX_; cellX++) {\n> -\t\t\tuint32_t cellPosition = (cellY * stride_ + cellX)\n> -\t\t\t\t\t      * sizeof(Ipu3AwbCell);\n> +\t\t\tuint32_t cellPosition = cellY * stride_ + cellX;\n>  \t\t\tuint32_t zoneX = cellX / cellsPerZoneX_;\n>  \t\t\tuint32_t zoneY = cellY / cellsPerZoneY_;\n>  \n>  \t\t\tuint32_t awbZonePosition = zoneY * kAwbStatsSizeX + zoneX;\n>  \n>  \t\t\t/* Cast the initial IPU3 structure to simplify the reading */\n> -\t\t\tconst Ipu3AwbCell *currentCell =\n> -\t\t\t\treinterpret_cast<const Ipu3AwbCell *>(\n> +\t\t\tconst ipu3_uapi_awb_set_item *currentCell =\n> +\t\t\t\treinterpret_cast<const ipu3_uapi_awb_set_item *>(\n>  \t\t\t\t\t&stats->awb_raw_buffer.meta_data[cellPosition]\n>  \t\t\t\t);\n> -\t\t\tif (currentCell->satRatio == 0) {\n> +\t\t\tif (currentCell->sat_ratio == 0) {\n>  \t\t\t\t/* The cell is not saturated, use the current cell */\n>  \t\t\t\tawbStats_[awbZonePosition].counted++;\n> -\t\t\t\tuint32_t greenValue = currentCell->greenRedAvg + currentCell->greenBlueAvg;\n> +\t\t\t\tuint32_t greenValue = currentCell->Gr_avg + currentCell->Gb_avg;\n>  \t\t\t\tawbStats_[awbZonePosition].sum.green += greenValue / 2;\n> -\t\t\t\tawbStats_[awbZonePosition].sum.red += currentCell->redAvg;\n> -\t\t\t\tawbStats_[awbZonePosition].sum.blue += currentCell->blueAvg;\n> +\t\t\t\tawbStats_[awbZonePosition].sum.red += currentCell->R_avg;\n> +\t\t\t\tawbStats_[awbZonePosition].sum.blue += currentCell->B_avg;\n>  \t\t\t}\n>  \t\t}\n>  \t}\n> diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h\n> index b3e0ad82..677384ed 100644\n> --- a/src/ipa/ipu3/algorithms/awb.h\n> +++ b/src/ipa/ipu3/algorithms/awb.h\n> @@ -23,16 +23,6 @@ namespace ipa::ipu3::algorithms {\n>  static constexpr uint32_t kAwbStatsSizeX = 16;\n>  static constexpr uint32_t kAwbStatsSizeY = 12;\n>  \n> -/* \\todo Move the cell layout into intel-ipu3.h kernel header */\n> -struct Ipu3AwbCell {\n> -\tunsigned char greenRedAvg;\n> -\tunsigned char redAvg;\n> -\tunsigned char blueAvg;\n> -\tunsigned char greenBlueAvg;\n> -\tunsigned char satRatio;\n> -\tunsigned char padding[3];\n> -} __attribute__((packed));\n> -\n>  struct Accumulator {\n>  \tunsigned int counted;\n>  \tstruct {","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 2DE7CC3243\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  5 Oct 2021 01:33:21 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A95AB6919D;\n\tTue,  5 Oct 2021 03:33:20 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4CA0E69189\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  5 Oct 2021 03:33:19 +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 C0FB5A2A;\n\tTue,  5 Oct 2021 03:33:18 +0200 (CEST)"],"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=\"SkOgW28M\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1633397599;\n\tbh=ILmcN8KRmrYxWTqCuotJMGifeDfBH3DYeai6w6M7DKs=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=SkOgW28M0LvKof6Max+jfDoPw1L5mwoPH+JEYGJTKYA8b9d10QP+GU8h2DmZQ4/n4\n\tfsM3bRq2I52q+auR2Yo3baNdkf2WVaxn6GhHmoGsy9IuXhtvuITQA7RT9KuuQaq7xc\n\thcLRll8zqmtAbYrICjrjhS7sINtxvj/8VQ5e254Q=","Date":"Tue, 5 Oct 2021 04:33:12 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Message-ID":"<YVurWMBb98E7IQNa@pendragon.ideasonboard.com>","References":"<20210930093715.73293-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20210930093715.73293-13-jeanmichel.hautbois@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210930093715.73293-13-jeanmichel.hautbois@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v2 12/12] ipa: ipu3: Replace\n\tipa::ipu3::algorithms::Ipu3AwbCell","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","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]