Patch Detail
Show a patch.
GET /api/patches/13331/?format=api
{ "id": 13331, "url": "https://patchwork.libcamera.org/api/patches/13331/?format=api", "web_url": "https://patchwork.libcamera.org/patch/13331/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20210812165243.276977-4-jeanmichel.hautbois@ideasonboard.com>", "date": "2021-08-12T16:52:36", "name": "[libcamera-devel,v2,03/10] ipa: ipu3: Introduce modular grid algorithm", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "d52ba2ea5044cf5406c64dff23d906768e1df697", "submitter": { "id": 75, "url": "https://patchwork.libcamera.org/api/people/75/?format=api", "name": "Jean-Michel Hautbois", "email": "jeanmichel.hautbois@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/13331/mbox/", "series": [ { "id": 2347, "url": "https://patchwork.libcamera.org/api/series/2347/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2347", "date": "2021-08-12T16:52:33", "name": "IPU3: Introduce modularity for algorithms", "version": 2, "mbox": "https://patchwork.libcamera.org/series/2347/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/13331/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/13331/checks/", "tags": {}, "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 56007BD87D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 12 Aug 2021 16:52:52 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 95A7568890;\n\tThu, 12 Aug 2021 18:52:51 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 57A1568888\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 12 Aug 2021 18:52:47 +0200 (CEST)", "from tatooine.ideasonboard.com (unknown\n\t[IPv6:2a01:e0a:169:7140:3d6d:7284:3c48:5edc])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 19F0E49A;\n\tThu, 12 Aug 2021 18:52:47 +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=\"No52B3Vs\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628787167;\n\tbh=PsmbVu6HPI2MuJ7eVEQfYQkvNAXoYqIFs8qZthpJ4lk=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=No52B3VsclcVZuIkRwQ0ZY0SNA8cdzxPHCcCsoNUxktOPXJ5dAj/ciBDwtnp7bUEY\n\tuaT/gw+1gnDVNaoqU3Fk6msNuSI4JXdEesWX7LXHyuuQa5SxlSPvWsnKsytisAeVtv\n\tAIVk+AgGOLoUDTXcEE/u60iQftS1Ouw0uAsdNa30=", "From": "Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Thu, 12 Aug 2021 18:52:36 +0200", "Message-Id": "<20210812165243.276977-4-jeanmichel.hautbois@ideasonboard.com>", "X-Mailer": "git-send-email 2.30.2", "In-Reply-To": "<20210812165243.276977-1-jeanmichel.hautbois@ideasonboard.com>", "References": "<20210812165243.276977-1-jeanmichel.hautbois@ideasonboard.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v2 03/10] ipa: ipu3: Introduce modular\n\tgrid algorithm", "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>" }, "content": "Implement a new modular framework for algorithms with a common context\nstructure that is passed to each algorithm through a common API.\n\nThe initial algorithm is chosen to configure the Bayer Down Scaler grid\nwhich is moved from the IPAIPU3 class.\n\nThis patch:\n- adds a configure() function to the Algorithm interface\n- creates a new Grid class implementing the computation at configure\n call\n- removes all the local references from IPAIPU3\n- implements the list of pointers and the loop at configure call on each\n algorithm (right now, only Grid is in the list)\n- removes the imguCssAwbDefaults structure as it is now configured\n properly\n\nSigned-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n---\n src/ipa/ipu3/algorithms/algorithm.h | 11 ++++\n src/ipa/ipu3/algorithms/grid.cpp | 83 +++++++++++++++++++++++++++++\n src/ipa/ipu3/algorithms/grid.h | 29 ++++++++++\n src/ipa/ipu3/algorithms/meson.build | 1 +\n src/ipa/ipu3/ipa_context.h | 8 +++\n src/ipa/ipu3/ipu3.cpp | 75 ++++++--------------------\n src/ipa/ipu3/ipu3_awb.cpp | 27 ++--------\n 7 files changed, 154 insertions(+), 80 deletions(-)\n create mode 100644 src/ipa/ipu3/algorithms/grid.cpp\n create mode 100644 src/ipa/ipu3/algorithms/grid.h", "diff": "diff --git a/src/ipa/ipu3/algorithms/algorithm.h b/src/ipa/ipu3/algorithms/algorithm.h\nindex 072f01c4..c1b37276 100644\n--- a/src/ipa/ipu3/algorithms/algorithm.h\n+++ b/src/ipa/ipu3/algorithms/algorithm.h\n@@ -7,6 +7,12 @@\n #ifndef __LIBCAMERA_IPA_IPU3_ALGORITHM_H__\n #define __LIBCAMERA_IPA_IPU3_ALGORITHM_H__\n \n+#include <iostream>\n+\n+#include <libcamera/ipa/ipu3_ipa_interface.h>\n+\n+#include \"ipa_context.h\"\n+\n namespace libcamera {\n \n namespace ipa::ipu3 {\n@@ -15,6 +21,11 @@ class Algorithm\n {\n public:\n \tvirtual ~Algorithm() {}\n+\n+\tvirtual int configure([[maybe_unused]] IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo)\n+\t{\n+\t\treturn 0;\n+\t}\n };\n \n } /* namespace ipa::ipu3 */\ndiff --git a/src/ipa/ipu3/algorithms/grid.cpp b/src/ipa/ipu3/algorithms/grid.cpp\nnew file mode 100644\nindex 00000000..3578f41b\n--- /dev/null\n+++ b/src/ipa/ipu3/algorithms/grid.cpp\n@@ -0,0 +1,83 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2021, Ideas On Board\n+ *\n+ * grid.cpp - IPU3 grid configuration\n+ */\n+\n+#include \"grid.h\"\n+\n+#include <libcamera/base/log.h>\n+\n+namespace libcamera {\n+\n+namespace ipa::ipu3::algorithms {\n+\n+LOG_DEFINE_CATEGORY(IPU3Grid)\n+\n+/* Maximum number of cells on a row */\n+static constexpr uint32_t kMaxCellWidthPerSet = 160;\n+/* Maximum number of cells on a column */\n+static constexpr uint32_t kMaxCellHeightPerSet = 56;\n+\n+/**\n+ * This function calculates a grid for the AWB algorithm in the IPU3 firmware.\n+ * Its input is the BDS output size calculated in the ImgU.\n+ * It is limited for now to the simplest method: find the lesser error\n+ * with the width/height and respective log2 width/height of the cells.\n+ *\n+ * \\todo The frame is divided into cells which can be 8x8 => 128x128.\n+ * As a smaller cell improves the algorithm precision, adapting the\n+ * x_start and y_start parameters of the grid would provoke a loss of\n+ * some pixels but would also result in more accurate algorithms.\n+ */\n+int Grid::configure(IPAContext &context, const IPAConfigInfo &configInfo)\n+{\n+\tuint32_t minError = std::numeric_limits<uint32_t>::max();\n+\tSize best;\n+\tSize bestLog2;\n+\tipu3_uapi_grid_config &bdsGrid = context.configuration.grid.bdsGrid;\n+\n+\tcontext.configuration.grid.bdsOutputSize = configInfo.bdsOutputSize;\n+\tSize &bdsOutputSize = context.configuration.grid.bdsOutputSize;\n+\n+\tbdsGrid.x_start = 0;\n+\tbdsGrid.y_start = 0;\n+\n+\tfor (uint32_t widthShift = 3; widthShift <= 7; ++widthShift) {\n+\t\tuint32_t width = std::min(kMaxCellWidthPerSet,\n+\t\t\t\t\t bdsOutputSize.width >> widthShift);\n+\t\twidth = width << widthShift;\n+\t\tfor (uint32_t heightShift = 3; heightShift <= 7; ++heightShift) {\n+\t\t\tint32_t height = std::min(kMaxCellHeightPerSet,\n+\t\t\t\t\t\t bdsOutputSize.height >> heightShift);\n+\t\t\theight = height << heightShift;\n+\t\t\tuint32_t error = std::abs(static_cast<int>(width - bdsOutputSize.width))\n+\t\t\t\t + std::abs(static_cast<int>(height - bdsOutputSize.height));\n+\n+\t\t\tif (error > minError)\n+\t\t\t\tcontinue;\n+\n+\t\t\tminError = error;\n+\t\t\tbest.width = width;\n+\t\t\tbest.height = height;\n+\t\t\tbestLog2.width = widthShift;\n+\t\t\tbestLog2.height = heightShift;\n+\t\t}\n+\t}\n+\n+\tbdsGrid.width = best.width >> bestLog2.width;\n+\tbdsGrid.block_width_log2 = bestLog2.width;\n+\tbdsGrid.height = best.height >> bestLog2.height;\n+\tbdsGrid.block_height_log2 = bestLog2.height;\n+\n+\tLOG(IPU3Grid, Debug) << \"Best grid found is: (\"\n+\t\t\t << (int)bdsGrid.width << \" << \" << (int)bdsGrid.block_width_log2 << \") x (\"\n+\t\t\t << (int)bdsGrid.height << \" << \" << (int)bdsGrid.block_height_log2 << \")\";\n+\n+\treturn 0;\n+}\n+\n+} /* namespace ipa::ipu3::algorithms */\n+\n+} /* namespace libcamera */\ndiff --git a/src/ipa/ipu3/algorithms/grid.h b/src/ipa/ipu3/algorithms/grid.h\nnew file mode 100644\nindex 00000000..b4a51b42\n--- /dev/null\n+++ b/src/ipa/ipu3/algorithms/grid.h\n@@ -0,0 +1,29 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2021, Google\n+ *\n+ * grid.h - IPU3 grid configuration\n+ */\n+#ifndef __LIBCAMERA_IPU3_ALGORITHMS_GRID_H__\n+#define __LIBCAMERA_IPU3_ALGORITHMS_GRID_H__\n+\n+#include \"algorithm.h\"\n+\n+namespace libcamera {\n+\n+namespace ipa::ipu3::algorithms {\n+\n+class Grid : public Algorithm\n+{\n+public:\n+\t~Grid() = default;\n+\n+\tint configure(IPAContext &context, const IPAConfigInfo &configInfo) override;\n+};\n+\n+} /* namespace ipa::ipu3::algorithms */\n+\n+} /* namespace libcamera */\n+\n+#endif /* __LIBCAMERA_IPU3_ALGORITHMS_CONTRAST_H__ */\n+\ndiff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build\nindex 67148333..3fb3ce56 100644\n--- a/src/ipa/ipu3/algorithms/meson.build\n+++ b/src/ipa/ipu3/algorithms/meson.build\n@@ -1,4 +1,5 @@\n # SPDX-License-Identifier: CC0-1.0\n \n ipu3_ipa_algorithms = files([\n+ 'grid.cpp',\n ])\ndiff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h\nindex 0a197a41..90b2f2c2 100644\n--- a/src/ipa/ipu3/ipa_context.h\n+++ b/src/ipa/ipu3/ipa_context.h\n@@ -11,12 +11,20 @@\n \n #include <linux/intel-ipu3.h>\n \n+#include <libcamera/geometry.h>\n+\n namespace libcamera {\n \n namespace ipa::ipu3 {\n \n /* Fixed configuration of the IPA */\n struct IPAConfiguration {\n+\tstruct Grid {\n+\t\t/* Bayer Down Scaler grid plane config used by the kernel */\n+\t\tipu3_uapi_grid_config bdsGrid;\n+\t\t/* BDS output size configured by the pipeline handler */\n+\t\tSize bdsOutputSize;\n+\t} grid;\n };\n \n /*\ndiff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp\nindex c34fa460..ef7fec86 100644\n--- a/src/ipa/ipu3/ipu3.cpp\n+++ b/src/ipa/ipu3/ipu3.cpp\n@@ -29,13 +29,12 @@\n \n #include \"libcamera/internal/mapped_framebuffer.h\"\n \n+#include \"algorithms/algorithm.h\"\n+#include \"algorithms/grid.h\"\n #include \"ipu3_agc.h\"\n #include \"ipu3_awb.h\"\n #include \"libipa/camera_sensor_helper.h\"\n \n-static constexpr uint32_t kMaxCellWidthPerSet = 160;\n-static constexpr uint32_t kMaxCellHeightPerSet = 56;\n-\n namespace libcamera {\n \n LOG_DEFINE_CATEGORY(IPAIPU3)\n@@ -91,10 +90,12 @@ private:\n \t/* Interface to the Camera Helper */\n \tstd::unique_ptr<CameraSensorHelper> camHelper_;\n \n+\t/* Maintain the algorithms used by the IPA */\n+\tstd::list<std::unique_ptr<ipa::ipu3::Algorithm>> algorithms_;\n+\n \t/* Local parameter storage */\n+\tstruct IPAContext context_;\n \tstruct ipu3_uapi_params params_;\n-\n-\tstruct ipu3_uapi_grid_config bdsGrid_;\n };\n \n /**\n@@ -164,6 +165,8 @@ int IPAIPU3::init(const IPASettings &settings,\n \t\t\t\t\t\t\t frameDurations[2]);\n \n \t*ipaControls = ControlInfoMap(std::move(controls), controls::controls);\n+\t/* Construct our Algorithms */\n+\talgorithms_.emplace_back(new algorithms::Grid());\n \n \treturn 0;\n }\n@@ -175,56 +178,6 @@ int IPAIPU3::start()\n \treturn 0;\n }\n \n-/**\n- * This function calculates a grid for the AWB algorithm in the IPU3 firmware.\n- * Its input is the BDS output size calculated in the ImgU.\n- * It is limited for now to the simplest method: find the lesser error\n- * with the width/height and respective log2 width/height of the cells.\n- *\n- * \\todo The frame is divided into cells which can be 8x8 => 128x128.\n- * As a smaller cell improves the algorithm precision, adapting the\n- * x_start and y_start parameters of the grid would provoke a loss of\n- * some pixels but would also result in more accurate algorithms.\n- */\n-void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)\n-{\n-\tuint32_t minError = std::numeric_limits<uint32_t>::max();\n-\tSize best;\n-\tSize bestLog2;\n-\tbdsGrid_ = {};\n-\n-\tfor (uint32_t widthShift = 3; widthShift <= 7; ++widthShift) {\n-\t\tuint32_t width = std::min(kMaxCellWidthPerSet,\n-\t\t\t\t\t bdsOutputSize.width >> widthShift);\n-\t\twidth = width << widthShift;\n-\t\tfor (uint32_t heightShift = 3; heightShift <= 7; ++heightShift) {\n-\t\t\tint32_t height = std::min(kMaxCellHeightPerSet,\n-\t\t\t\t\t\t bdsOutputSize.height >> heightShift);\n-\t\t\theight = height << heightShift;\n-\t\t\tuint32_t error = std::abs(static_cast<int>(width - bdsOutputSize.width))\n-\t\t\t\t\t\t\t+ std::abs(static_cast<int>(height - bdsOutputSize.height));\n-\n-\t\t\tif (error > minError)\n-\t\t\t\tcontinue;\n-\n-\t\t\tminError = error;\n-\t\t\tbest.width = width;\n-\t\t\tbest.height = height;\n-\t\t\tbestLog2.width = widthShift;\n-\t\t\tbestLog2.height = heightShift;\n-\t\t}\n-\t}\n-\n-\tbdsGrid_.width = best.width >> bestLog2.width;\n-\tbdsGrid_.block_width_log2 = bestLog2.width;\n-\tbdsGrid_.height = best.height >> bestLog2.height;\n-\tbdsGrid_.block_height_log2 = bestLog2.height;\n-\n-\tLOG(IPAIPU3, Debug) << \"Best grid found is: (\"\n-\t\t\t << (int)bdsGrid_.width << \" << \" << (int)bdsGrid_.block_width_log2 << \") x (\"\n-\t\t\t << (int)bdsGrid_.height << \" << \" << (int)bdsGrid_.block_height_log2 << \")\";\n-}\n-\n int IPAIPU3::configure(const IPAConfigInfo &configInfo)\n {\n \tif (configInfo.entityControls.empty()) {\n@@ -264,15 +217,21 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo)\n \n \tdefVBlank_ = itVBlank->second.def().get<int32_t>();\n \n+\t/* Clean context and IPU3 parameters at configuration */\n \tparams_ = {};\n+\tcontext_ = {};\n \n-\tcalculateBdsGrid(configInfo.bdsOutputSize);\n+\tfor (auto const &algo : algorithms_) {\n+\t\tint ret = algo->configure(context_, configInfo);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n \n \tawbAlgo_ = std::make_unique<IPU3Awb>();\n-\tawbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);\n+\tawbAlgo_->initialise(params_, context_.configuration.grid.bdsOutputSize, context_.configuration.grid.bdsGrid);\n \n \tagcAlgo_ = std::make_unique<IPU3Agc>();\n-\tagcAlgo_->initialise(bdsGrid_, sensorInfo_);\n+\tagcAlgo_->initialise(context_.configuration.grid.bdsGrid, sensorInfo_);\n \n \treturn 0;\n }\ndiff --git a/src/ipa/ipu3/ipu3_awb.cpp b/src/ipa/ipu3/ipu3_awb.cpp\nindex 4bb321b3..4ee5ee6f 100644\n--- a/src/ipa/ipu3/ipu3_awb.cpp\n+++ b/src/ipa/ipu3/ipu3_awb.cpp\n@@ -107,25 +107,6 @@ static const struct ipu3_uapi_bnr_static_config imguCssBnrDefaults = {\n \t.opt_center_sqr = { 419904, 133956 },\n };\n \n-/* Default settings for Auto White Balance replicated from the Kernel*/\n-static const struct ipu3_uapi_awb_config_s imguCssAwbDefaults = {\n-\t.rgbs_thr_gr = 8191,\n-\t.rgbs_thr_r = 8191,\n-\t.rgbs_thr_gb = 8191,\n-\t.rgbs_thr_b = 8191 | IPU3_UAPI_AWB_RGBS_THR_B_EN | IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT,\n-\t.grid = {\n-\t\t.width = 160,\n-\t\t.height = 36,\n-\t\t.block_width_log2 = 3,\n-\t\t.block_height_log2 = 4,\n-\t\t.height_per_slice = 1, /* Overridden by kernel. */\n-\t\t.x_start = 0,\n-\t\t.y_start = 0,\n-\t\t.x_end = 0,\n-\t\t.y_end = 0,\n-\t},\n-};\n-\n /* Default color correction matrix defined as an identity matrix */\n static const struct ipu3_uapi_ccm_mat_config imguCssCcmDefault = {\n \t8191, 0, 0, 0,\n@@ -174,10 +155,12 @@ IPU3Awb::~IPU3Awb()\n void IPU3Awb::initialise(ipu3_uapi_params ¶ms, const Size &bdsOutputSize, struct ipu3_uapi_grid_config &bdsGrid)\n {\n \tparams.use.acc_awb = 1;\n-\tparams.acc_param.awb.config = imguCssAwbDefaults;\n-\n+\tparams.acc_param.awb.config.rgbs_thr_gr = 8191;\n+\tparams.acc_param.awb.config.rgbs_thr_r = 8191;\n+\tparams.acc_param.awb.config.rgbs_thr_gb = 8191;\n+\tparams.acc_param.awb.config.rgbs_thr_b = 8191 | IPU3_UAPI_AWB_RGBS_THR_B_EN | IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT;\n+\tparams.acc_param.awb.config.grid = bdsGrid;\n \tawbGrid_ = bdsGrid;\n-\tparams.acc_param.awb.config.grid = awbGrid_;\n \n \tparams.use.acc_bnr = 1;\n \tparams.acc_param.bnr = imguCssBnrDefaults;\n", "prefixes": [ "libcamera-devel", "v2", "03/10" ] }