From patchwork Thu Aug 12 16:52:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13329 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id CF9E0BD87D for ; Thu, 12 Aug 2021 16:52:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 525BB68895; Thu, 12 Aug 2021 18:52:50 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Fl2SLGi1"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0AD2068864 for ; Thu, 12 Aug 2021 18:52:47 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:3d6d:7284:3c48:5edc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B1A7C8AF; Thu, 12 Aug 2021 18:52:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628787166; bh=sm1EjPl+Zv8p29ut3Vxwz46WKyBblz+42Osld8w3hCM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Fl2SLGi1d1+c9VGPEk1Kfgtb6fjA2CzqabvFcgcCyOBgMJZUz/vHP/6Idowk1e4lR k4GZs83r/l9V1E4y7WsiEc8Zh8FFejuK6LeMrN9CSHRDkPeZ1pUJSceUy0UaQ8K7OD /9J5V1Fq/Igk4NM8Ckp0gALp7Y/tetsZ+LxS/20o= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 12 Aug 2021 18:52:34 +0200 Message-Id: <20210812165243.276977-2-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 Subject: [libcamera-devel] [PATCH v2 01/10] ipa: move libipa::Algorithm to ipa/ipu3/algorithms X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The abstract Algorithm class was originally placed in libipa as an attempt to define a generic algorithm container. This was a little optimistic and pushed a bit far too early. Move the Algorithm class into the IPU3 which is the only user of the class, as we adapt it to support modular algorithm components for the IPU3. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham kieran.bingham@ideasonboard.com --- src/ipa/ipu3/algorithms/algorithm.h | 24 ++++++++++++++++++ src/ipa/ipu3/algorithms/meson.build | 4 +++ src/ipa/ipu3/ipu3_agc.h | 2 +- src/ipa/ipu3/ipu3_awb.h | 2 +- src/ipa/ipu3/meson.build | 4 +++ src/ipa/libipa/algorithm.cpp | 39 ----------------------------- src/ipa/libipa/algorithm.h | 24 ------------------ src/ipa/libipa/meson.build | 2 -- 8 files changed, 34 insertions(+), 67 deletions(-) create mode 100644 src/ipa/ipu3/algorithms/algorithm.h create mode 100644 src/ipa/ipu3/algorithms/meson.build delete mode 100644 src/ipa/libipa/algorithm.cpp delete mode 100644 src/ipa/libipa/algorithm.h diff --git a/src/ipa/ipu3/algorithms/algorithm.h b/src/ipa/ipu3/algorithms/algorithm.h new file mode 100644 index 00000000..072f01c4 --- /dev/null +++ b/src/ipa/ipu3/algorithms/algorithm.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Ideas On Board + * + * algorithm.h - IPU3 control algorithm interface + */ +#ifndef __LIBCAMERA_IPA_IPU3_ALGORITHM_H__ +#define __LIBCAMERA_IPA_IPU3_ALGORITHM_H__ + +namespace libcamera { + +namespace ipa::ipu3 { + +class Algorithm +{ +public: + virtual ~Algorithm() {} +}; + +} /* namespace ipa::ipu3 */ + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_IPA_IPU3_ALGORITHM_H__ */ diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build new file mode 100644 index 00000000..67148333 --- /dev/null +++ b/src/ipa/ipu3/algorithms/meson.build @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: CC0-1.0 + +ipu3_ipa_algorithms = files([ +]) diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h index 9f3d4257..f00b98d6 100644 --- a/src/ipa/ipu3/ipu3_agc.h +++ b/src/ipa/ipu3/ipu3_agc.h @@ -13,7 +13,7 @@ #include -#include "libipa/algorithm.h" +#include "algorithms/algorithm.h" namespace libcamera { diff --git a/src/ipa/ipu3/ipu3_awb.h b/src/ipa/ipu3/ipu3_awb.h index 122cf68c..ea2d4320 100644 --- a/src/ipa/ipu3/ipu3_awb.h +++ b/src/ipa/ipu3/ipu3_awb.h @@ -13,7 +13,7 @@ #include -#include "libipa/algorithm.h" +#include "algorithms/algorithm.h" namespace libcamera { diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build index b6364190..fcb27d68 100644 --- a/src/ipa/ipu3/meson.build +++ b/src/ipa/ipu3/meson.build @@ -1,5 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 +subdir('algorithms') + ipa_name = 'ipa_ipu3' ipu3_ipa_sources = files([ @@ -8,6 +10,8 @@ ipu3_ipa_sources = files([ 'ipu3_awb.cpp', ]) +ipu3_ipa_sources += ipu3_ipa_algorithms + mod = shared_module(ipa_name, [ipu3_ipa_sources, libcamera_generated_ipa_headers], name_prefix : '', diff --git a/src/ipa/libipa/algorithm.cpp b/src/ipa/libipa/algorithm.cpp deleted file mode 100644 index 930f9353..00000000 --- a/src/ipa/libipa/algorithm.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2021, Ideas On Board - * - * algorithm.cpp - ISP control algorithms - */ - -#include "algorithm.h" - -/** - * \file algorithm.h - * \brief Algorithm common interface - */ - -namespace libcamera { - -/** - * \brief The IPA namespace - * - * The IPA namespace groups all types specific to IPA modules. It serves as the - * top-level namespace for the IPA library libipa, and also contains - * module-specific namespaces for IPA modules. - */ -namespace ipa { - -/** - * \class Algorithm - * \brief The base class for all IPA algorithms - * - * The Algorithm class defines a standard interface for IPA algorithms. By - * abstracting algorithms, it makes possible the implementation of generic code - * to manage algorithms regardless of their specific type. - */ - -Algorithm::~Algorithm() = default; - -} /* namespace ipa */ - -} /* namespace libcamera */ diff --git a/src/ipa/libipa/algorithm.h b/src/ipa/libipa/algorithm.h deleted file mode 100644 index 89cee4c4..00000000 --- a/src/ipa/libipa/algorithm.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2021, Ideas On Board - * - * algorithm.h - ISP control algorithm interface - */ -#ifndef __LIBCAMERA_IPA_LIBIPA_ALGORITHM_H__ -#define __LIBCAMERA_IPA_LIBIPA_ALGORITHM_H__ - -namespace libcamera { - -namespace ipa { - -class Algorithm -{ -public: - virtual ~Algorithm(); -}; - -} /* namespace ipa */ - -} /* namespace libcamera */ - -#endif /* __LIBCAMERA_IPA_LIBIPA_ALGORITHM_H__ */ diff --git a/src/ipa/libipa/meson.build b/src/ipa/libipa/meson.build index 3fda7c00..2a694b1e 100644 --- a/src/ipa/libipa/meson.build +++ b/src/ipa/libipa/meson.build @@ -1,13 +1,11 @@ # SPDX-License-Identifier: CC0-1.0 libipa_headers = files([ - 'algorithm.h', 'camera_sensor_helper.h', 'histogram.h' ]) libipa_sources = files([ - 'algorithm.cpp', 'camera_sensor_helper.cpp', 'histogram.cpp' ]) From patchwork Thu Aug 12 16:52:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13330 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id A19A0C3241 for ; Thu, 12 Aug 2021 16:52:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B8FA7688D2; Thu, 12 Aug 2021 18:52:50 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="osEFlxUv"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3F08268886 for ; Thu, 12 Aug 2021 18:52:47 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:3d6d:7284:3c48:5edc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DD338F49; Thu, 12 Aug 2021 18:52:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628787167; bh=IbwUJCWjDBTZ9PmeeYyA/cYLrH0famVDqDWbUtCIzBE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=osEFlxUv/8cxEoaxebEblSDQFsg+eCwHNCTKnlykfdZnoKAXXRTp84yqiJRkiVQGo jI2nOiVCCzf50SgwEjr37nJ6Mu/buMY5GM5eDuPu0Ns0xhXbUkTNbHqhDmsWC3R/Dd wrVMW+d/1NBEGz2zviTdWfdPrTdJ/La893VFZcmE= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 12 Aug 2021 18:52:35 +0200 Message-Id: <20210812165243.276977-3-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 Subject: [libcamera-devel] [PATCH v2 02/10] ipa: ipu3: Introduce a Context structure X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" An increasing amount of data and information needs to be shared between the components that build up to implement image processing algorithms. Create a context structure which will allow us to work towards calling algorithms in a modular way, and sharing information between the modules. The IPA context is a global context set at configure time (IPAConfiguration) and a per-frame context (IPAFrameContext) used while streaming. Signed-off-by: Kieran Bingham Signed-off-by: Jean-Michel Hautbois --- src/ipa/ipu3/ipa_context.h | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/ipa/ipu3/ipa_context.h diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h new file mode 100644 index 00000000..0a197a41 --- /dev/null +++ b/src/ipa/ipu3/ipa_context.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * ipu3_ipa_context.h - IPU3 IPA Context + * + * Context information shared between the algorithms + */ +#ifndef __LIBCAMERA_IPU3_IPA_CONTEXT_H__ +#define __LIBCAMERA_IPU3_IPA_CONTEXT_H__ + +#include + +namespace libcamera { + +namespace ipa::ipu3 { + +/* Fixed configuration of the IPA */ +struct IPAConfiguration { +}; + +/* + * Context of a frame for each algorithms + * This may be stored in a way that is associated with a given request + * lifetime, though for now a single instance is used. + */ +struct IPAFrameContext { +}; + +/* Global context of the IPA */ +struct IPAContext { + IPAConfiguration configuration; + IPAFrameContext frameContext; +}; + +} /* namespace ipa::ipu3 */ + +} /* namespace libcamera*/ + +#endif /* __LIBCAMERA_IPU3_IPA_CONTEXT_H__ */ From patchwork Thu Aug 12 16:52:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13331 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 56007BD87D for ; Thu, 12 Aug 2021 16:52:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 95A7568890; Thu, 12 Aug 2021 18:52:51 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="No52B3Vs"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 57A1568888 for ; Thu, 12 Aug 2021 18:52:47 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:3d6d:7284:3c48:5edc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 19F0E49A; Thu, 12 Aug 2021 18:52:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628787167; bh=PsmbVu6HPI2MuJ7eVEQfYQkvNAXoYqIFs8qZthpJ4lk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=No52B3VsclcVZuIkRwQ0ZY0SNA8cdzxPHCcCsoNUxktOPXJ5dAj/ciBDwtnp7bUEY uaT/gw+1gnDVNaoqU3Fk6msNuSI4JXdEesWX7LXHyuuQa5SxlSPvWsnKsytisAeVtv AIVk+AgGOLoUDTXcEE/u60iQftS1Ouw0uAsdNa30= From: Jean-Michel Hautbois 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 Subject: [libcamera-devel] [PATCH v2 03/10] ipa: ipu3: Introduce modular grid algorithm X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Implement a new modular framework for algorithms with a common context structure that is passed to each algorithm through a common API. The initial algorithm is chosen to configure the Bayer Down Scaler grid which is moved from the IPAIPU3 class. This patch: - adds a configure() function to the Algorithm interface - creates a new Grid class implementing the computation at configure call - removes all the local references from IPAIPU3 - implements the list of pointers and the loop at configure call on each algorithm (right now, only Grid is in the list) - removes the imguCssAwbDefaults structure as it is now configured properly Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- src/ipa/ipu3/algorithms/algorithm.h | 11 ++++ src/ipa/ipu3/algorithms/grid.cpp | 83 +++++++++++++++++++++++++++++ src/ipa/ipu3/algorithms/grid.h | 29 ++++++++++ src/ipa/ipu3/algorithms/meson.build | 1 + src/ipa/ipu3/ipa_context.h | 8 +++ src/ipa/ipu3/ipu3.cpp | 75 ++++++-------------------- src/ipa/ipu3/ipu3_awb.cpp | 27 ++-------- 7 files changed, 154 insertions(+), 80 deletions(-) create mode 100644 src/ipa/ipu3/algorithms/grid.cpp create mode 100644 src/ipa/ipu3/algorithms/grid.h diff --git a/src/ipa/ipu3/algorithms/algorithm.h b/src/ipa/ipu3/algorithms/algorithm.h index 072f01c4..c1b37276 100644 --- a/src/ipa/ipu3/algorithms/algorithm.h +++ b/src/ipa/ipu3/algorithms/algorithm.h @@ -7,6 +7,12 @@ #ifndef __LIBCAMERA_IPA_IPU3_ALGORITHM_H__ #define __LIBCAMERA_IPA_IPU3_ALGORITHM_H__ +#include + +#include + +#include "ipa_context.h" + namespace libcamera { namespace ipa::ipu3 { @@ -15,6 +21,11 @@ class Algorithm { public: virtual ~Algorithm() {} + + virtual int configure([[maybe_unused]] IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo) + { + return 0; + } }; } /* namespace ipa::ipu3 */ diff --git a/src/ipa/ipu3/algorithms/grid.cpp b/src/ipa/ipu3/algorithms/grid.cpp new file mode 100644 index 00000000..3578f41b --- /dev/null +++ b/src/ipa/ipu3/algorithms/grid.cpp @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Ideas On Board + * + * grid.cpp - IPU3 grid configuration + */ + +#include "grid.h" + +#include + +namespace libcamera { + +namespace ipa::ipu3::algorithms { + +LOG_DEFINE_CATEGORY(IPU3Grid) + +/* Maximum number of cells on a row */ +static constexpr uint32_t kMaxCellWidthPerSet = 160; +/* Maximum number of cells on a column */ +static constexpr uint32_t kMaxCellHeightPerSet = 56; + +/** + * This function calculates a grid for the AWB algorithm in the IPU3 firmware. + * Its input is the BDS output size calculated in the ImgU. + * It is limited for now to the simplest method: find the lesser error + * with the width/height and respective log2 width/height of the cells. + * + * \todo The frame is divided into cells which can be 8x8 => 128x128. + * As a smaller cell improves the algorithm precision, adapting the + * x_start and y_start parameters of the grid would provoke a loss of + * some pixels but would also result in more accurate algorithms. + */ +int Grid::configure(IPAContext &context, const IPAConfigInfo &configInfo) +{ + uint32_t minError = std::numeric_limits::max(); + Size best; + Size bestLog2; + ipu3_uapi_grid_config &bdsGrid = context.configuration.grid.bdsGrid; + + context.configuration.grid.bdsOutputSize = configInfo.bdsOutputSize; + Size &bdsOutputSize = context.configuration.grid.bdsOutputSize; + + bdsGrid.x_start = 0; + bdsGrid.y_start = 0; + + for (uint32_t widthShift = 3; widthShift <= 7; ++widthShift) { + uint32_t width = std::min(kMaxCellWidthPerSet, + bdsOutputSize.width >> widthShift); + width = width << widthShift; + for (uint32_t heightShift = 3; heightShift <= 7; ++heightShift) { + int32_t height = std::min(kMaxCellHeightPerSet, + bdsOutputSize.height >> heightShift); + height = height << heightShift; + uint32_t error = std::abs(static_cast(width - bdsOutputSize.width)) + + std::abs(static_cast(height - bdsOutputSize.height)); + + if (error > minError) + continue; + + minError = error; + best.width = width; + best.height = height; + bestLog2.width = widthShift; + bestLog2.height = heightShift; + } + } + + bdsGrid.width = best.width >> bestLog2.width; + bdsGrid.block_width_log2 = bestLog2.width; + bdsGrid.height = best.height >> bestLog2.height; + bdsGrid.block_height_log2 = bestLog2.height; + + LOG(IPU3Grid, Debug) << "Best grid found is: (" + << (int)bdsGrid.width << " << " << (int)bdsGrid.block_width_log2 << ") x (" + << (int)bdsGrid.height << " << " << (int)bdsGrid.block_height_log2 << ")"; + + return 0; +} + +} /* namespace ipa::ipu3::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/ipu3/algorithms/grid.h b/src/ipa/ipu3/algorithms/grid.h new file mode 100644 index 00000000..b4a51b42 --- /dev/null +++ b/src/ipa/ipu3/algorithms/grid.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google + * + * grid.h - IPU3 grid configuration + */ +#ifndef __LIBCAMERA_IPU3_ALGORITHMS_GRID_H__ +#define __LIBCAMERA_IPU3_ALGORITHMS_GRID_H__ + +#include "algorithm.h" + +namespace libcamera { + +namespace ipa::ipu3::algorithms { + +class Grid : public Algorithm +{ +public: + ~Grid() = default; + + int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; +}; + +} /* namespace ipa::ipu3::algorithms */ + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_IPU3_ALGORITHMS_CONTRAST_H__ */ + diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build index 67148333..3fb3ce56 100644 --- a/src/ipa/ipu3/algorithms/meson.build +++ b/src/ipa/ipu3/algorithms/meson.build @@ -1,4 +1,5 @@ # SPDX-License-Identifier: CC0-1.0 ipu3_ipa_algorithms = files([ + 'grid.cpp', ]) diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index 0a197a41..90b2f2c2 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -11,12 +11,20 @@ #include +#include + namespace libcamera { namespace ipa::ipu3 { /* Fixed configuration of the IPA */ struct IPAConfiguration { + struct Grid { + /* Bayer Down Scaler grid plane config used by the kernel */ + ipu3_uapi_grid_config bdsGrid; + /* BDS output size configured by the pipeline handler */ + Size bdsOutputSize; + } grid; }; /* diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index c34fa460..ef7fec86 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -29,13 +29,12 @@ #include "libcamera/internal/mapped_framebuffer.h" +#include "algorithms/algorithm.h" +#include "algorithms/grid.h" #include "ipu3_agc.h" #include "ipu3_awb.h" #include "libipa/camera_sensor_helper.h" -static constexpr uint32_t kMaxCellWidthPerSet = 160; -static constexpr uint32_t kMaxCellHeightPerSet = 56; - namespace libcamera { LOG_DEFINE_CATEGORY(IPAIPU3) @@ -91,10 +90,12 @@ private: /* Interface to the Camera Helper */ std::unique_ptr camHelper_; + /* Maintain the algorithms used by the IPA */ + std::list> algorithms_; + /* Local parameter storage */ + struct IPAContext context_; struct ipu3_uapi_params params_; - - struct ipu3_uapi_grid_config bdsGrid_; }; /** @@ -164,6 +165,8 @@ int IPAIPU3::init(const IPASettings &settings, frameDurations[2]); *ipaControls = ControlInfoMap(std::move(controls), controls::controls); + /* Construct our Algorithms */ + algorithms_.emplace_back(new algorithms::Grid()); return 0; } @@ -175,56 +178,6 @@ int IPAIPU3::start() return 0; } -/** - * This function calculates a grid for the AWB algorithm in the IPU3 firmware. - * Its input is the BDS output size calculated in the ImgU. - * It is limited for now to the simplest method: find the lesser error - * with the width/height and respective log2 width/height of the cells. - * - * \todo The frame is divided into cells which can be 8x8 => 128x128. - * As a smaller cell improves the algorithm precision, adapting the - * x_start and y_start parameters of the grid would provoke a loss of - * some pixels but would also result in more accurate algorithms. - */ -void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize) -{ - uint32_t minError = std::numeric_limits::max(); - Size best; - Size bestLog2; - bdsGrid_ = {}; - - for (uint32_t widthShift = 3; widthShift <= 7; ++widthShift) { - uint32_t width = std::min(kMaxCellWidthPerSet, - bdsOutputSize.width >> widthShift); - width = width << widthShift; - for (uint32_t heightShift = 3; heightShift <= 7; ++heightShift) { - int32_t height = std::min(kMaxCellHeightPerSet, - bdsOutputSize.height >> heightShift); - height = height << heightShift; - uint32_t error = std::abs(static_cast(width - bdsOutputSize.width)) - + std::abs(static_cast(height - bdsOutputSize.height)); - - if (error > minError) - continue; - - minError = error; - best.width = width; - best.height = height; - bestLog2.width = widthShift; - bestLog2.height = heightShift; - } - } - - bdsGrid_.width = best.width >> bestLog2.width; - bdsGrid_.block_width_log2 = bestLog2.width; - bdsGrid_.height = best.height >> bestLog2.height; - bdsGrid_.block_height_log2 = bestLog2.height; - - LOG(IPAIPU3, Debug) << "Best grid found is: (" - << (int)bdsGrid_.width << " << " << (int)bdsGrid_.block_width_log2 << ") x (" - << (int)bdsGrid_.height << " << " << (int)bdsGrid_.block_height_log2 << ")"; -} - int IPAIPU3::configure(const IPAConfigInfo &configInfo) { if (configInfo.entityControls.empty()) { @@ -264,15 +217,21 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) defVBlank_ = itVBlank->second.def().get(); + /* Clean context and IPU3 parameters at configuration */ params_ = {}; + context_ = {}; - calculateBdsGrid(configInfo.bdsOutputSize); + for (auto const &algo : algorithms_) { + int ret = algo->configure(context_, configInfo); + if (ret) + return ret; + } awbAlgo_ = std::make_unique(); - awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_); + awbAlgo_->initialise(params_, context_.configuration.grid.bdsOutputSize, context_.configuration.grid.bdsGrid); agcAlgo_ = std::make_unique(); - agcAlgo_->initialise(bdsGrid_, sensorInfo_); + agcAlgo_->initialise(context_.configuration.grid.bdsGrid, sensorInfo_); return 0; } diff --git a/src/ipa/ipu3/ipu3_awb.cpp b/src/ipa/ipu3/ipu3_awb.cpp index 4bb321b3..4ee5ee6f 100644 --- a/src/ipa/ipu3/ipu3_awb.cpp +++ b/src/ipa/ipu3/ipu3_awb.cpp @@ -107,25 +107,6 @@ static const struct ipu3_uapi_bnr_static_config imguCssBnrDefaults = { .opt_center_sqr = { 419904, 133956 }, }; -/* Default settings for Auto White Balance replicated from the Kernel*/ -static const struct ipu3_uapi_awb_config_s imguCssAwbDefaults = { - .rgbs_thr_gr = 8191, - .rgbs_thr_r = 8191, - .rgbs_thr_gb = 8191, - .rgbs_thr_b = 8191 | IPU3_UAPI_AWB_RGBS_THR_B_EN | IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT, - .grid = { - .width = 160, - .height = 36, - .block_width_log2 = 3, - .block_height_log2 = 4, - .height_per_slice = 1, /* Overridden by kernel. */ - .x_start = 0, - .y_start = 0, - .x_end = 0, - .y_end = 0, - }, -}; - /* Default color correction matrix defined as an identity matrix */ static const struct ipu3_uapi_ccm_mat_config imguCssCcmDefault = { 8191, 0, 0, 0, @@ -174,10 +155,12 @@ IPU3Awb::~IPU3Awb() void IPU3Awb::initialise(ipu3_uapi_params ¶ms, const Size &bdsOutputSize, struct ipu3_uapi_grid_config &bdsGrid) { params.use.acc_awb = 1; - params.acc_param.awb.config = imguCssAwbDefaults; - + params.acc_param.awb.config.rgbs_thr_gr = 8191; + params.acc_param.awb.config.rgbs_thr_r = 8191; + params.acc_param.awb.config.rgbs_thr_gb = 8191; + params.acc_param.awb.config.rgbs_thr_b = 8191 | IPU3_UAPI_AWB_RGBS_THR_B_EN | IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT; + params.acc_param.awb.config.grid = bdsGrid; awbGrid_ = bdsGrid; - params.acc_param.awb.config.grid = awbGrid_; params.use.acc_bnr = 1; params.acc_param.bnr = imguCssBnrDefaults; From patchwork Thu Aug 12 16:52:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13332 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id D768EC3242 for ; Thu, 12 Aug 2021 16:52:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 53901688A2; Thu, 12 Aug 2021 18:52:52 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="v5Qh6ZVJ"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8C5376888D for ; Thu, 12 Aug 2021 18:52:47 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:3d6d:7284:3c48:5edc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 45C0C8AF; Thu, 12 Aug 2021 18:52:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628787167; bh=ldM25BW6pc6QgpkW3YWFgxB8a+1jnLuUKpXxZWRqAfc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=v5Qh6ZVJ93eHRSn+eoAnt8Xbv77rMy5ZCn8R7h0x79taX7T5DyhCb2zNnuTi1WGZj F/Yqh45Ub759Npc9yRwZe6fPP53FGeSIzryzq95w6MDiMFewPz0UVAdxMT34RcHBfk UlUwvbvZQoQ/JBUar+FfnWzfXs5kZ2SuHt4U4obA= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 12 Aug 2021 18:52:37 +0200 Message-Id: <20210812165243.276977-5-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 Subject: [libcamera-devel] [PATCH v2 04/10] ipa: ipu3: Introduce a prepare() call to Algorithm X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When a new ipu3_uapi_params buffer is ready, IPAIPU3 receives a EventFillParams. When this is called, the algorithms should fill every field in the parameter structure they need to update. Demonstrate it by adding a loop on the prepare() call in IPAIPU3 and let the Grid algorithm update the grid field. This leads to removing this same update from the Awb algorithm. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- src/ipa/ipu3/algorithms/algorithm.h | 2 ++ src/ipa/ipu3/algorithms/grid.cpp | 6 ++++++ src/ipa/ipu3/algorithms/grid.h | 1 + src/ipa/ipu3/ipu3.cpp | 3 +++ src/ipa/ipu3/ipu3_awb.cpp | 1 - 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ipa/ipu3/algorithms/algorithm.h b/src/ipa/ipu3/algorithms/algorithm.h index c1b37276..b571f55a 100644 --- a/src/ipa/ipu3/algorithms/algorithm.h +++ b/src/ipa/ipu3/algorithms/algorithm.h @@ -26,6 +26,8 @@ public: { return 0; } + + virtual void prepare([[maybe_unused]] IPAContext &context, [[maybe_unused]] ipu3_uapi_params ¶ms) {} }; } /* namespace ipa::ipu3 */ diff --git a/src/ipa/ipu3/algorithms/grid.cpp b/src/ipa/ipu3/algorithms/grid.cpp index 3578f41b..e42a760d 100644 --- a/src/ipa/ipu3/algorithms/grid.cpp +++ b/src/ipa/ipu3/algorithms/grid.cpp @@ -78,6 +78,12 @@ int Grid::configure(IPAContext &context, const IPAConfigInfo &configInfo) return 0; } +void Grid::prepare(IPAContext &context, ipu3_uapi_params ¶ms) +{ + /* Update the IPU3 parameters with new calculated grid */ + params.acc_param.awb.config.grid = context.configuration.grid.bdsGrid; +} + } /* namespace ipa::ipu3::algorithms */ } /* namespace libcamera */ diff --git a/src/ipa/ipu3/algorithms/grid.h b/src/ipa/ipu3/algorithms/grid.h index b4a51b42..89399bd2 100644 --- a/src/ipa/ipu3/algorithms/grid.h +++ b/src/ipa/ipu3/algorithms/grid.h @@ -19,6 +19,7 @@ public: ~Grid() = default; int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; + void prepare(IPAContext &context, ipu3_uapi_params ¶ms) override; }; } /* namespace ipa::ipu3::algorithms */ diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index ef7fec86..394a7a45 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -305,6 +305,9 @@ void IPAIPU3::processControls([[maybe_unused]] unsigned int frame, void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params) { + for (auto const &algo : algorithms_) + algo->prepare(context_, params_); + if (agcAlgo_->updateControls()) awbAlgo_->updateWbParameters(params_, agcAlgo_->gamma()); diff --git a/src/ipa/ipu3/ipu3_awb.cpp b/src/ipa/ipu3/ipu3_awb.cpp index 4ee5ee6f..911760b3 100644 --- a/src/ipa/ipu3/ipu3_awb.cpp +++ b/src/ipa/ipu3/ipu3_awb.cpp @@ -159,7 +159,6 @@ void IPU3Awb::initialise(ipu3_uapi_params ¶ms, const Size &bdsOutputSize, st params.acc_param.awb.config.rgbs_thr_r = 8191; params.acc_param.awb.config.rgbs_thr_gb = 8191; params.acc_param.awb.config.rgbs_thr_b = 8191 | IPU3_UAPI_AWB_RGBS_THR_B_EN | IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT; - params.acc_param.awb.config.grid = bdsGrid; awbGrid_ = bdsGrid; params.use.acc_bnr = 1; From patchwork Thu Aug 12 16:52:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13333 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id A31CABD87D for ; Thu, 12 Aug 2021 16:52:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6D542688D2; Thu, 12 Aug 2021 18:52:54 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="De0rCV2V"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BC33268864 for ; Thu, 12 Aug 2021 18:52:47 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:3d6d:7284:3c48:5edc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7294F49A; Thu, 12 Aug 2021 18:52:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628787167; bh=Ma+KxMqwSLTIzxe5tm03n4LkUT0lfkzLgc5Q0BtVa4o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=De0rCV2VnDCtylOmEoPvRIt6wxB0clfbYBcBaP3Chpf1d+ksnYpFHrp/aazHK0Yhj 3tbUWtgME66cFPYGEpLEg+H2UF9lJTRKA1TKmHOP95biPAham8BGu9NghDYlnB5U9U D4qwRa598b57h7mRIvLaJDAJwLbxBIZ8eNaRR83U= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 12 Aug 2021 18:52:38 +0200 Message-Id: <20210812165243.276977-6-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 Subject: [libcamera-devel] [PATCH v2 05/10] ipa: ipu3: Introduce a modular contrast algorithm X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Introduce a new algorithm to manage the contrast handling of the IPU3. The initial algorithm is chosen to configure the gamma contrast curve which moves the implementation out of AWB for simplicity. As it is initialised with a default gamma value of 1.1, there is no need to use the default table at init time anymore. This demonstrates the way to use process() call when the EventStatReady comes in. The function calculates the LUT in the context of a frame, and when prepare() is called, the parameters are filled with the updated values. AGC needs to be modified to take the new process interface into account. Signed-off-by: Kieran Bingham Signed-off-by: Jean-Michel Hautbois --- src/ipa/ipu3/algorithms/algorithm.h | 2 ++ src/ipa/ipu3/algorithms/contrast.cpp | 51 ++++++++++++++++++++++++++++ src/ipa/ipu3/algorithms/contrast.h | 33 ++++++++++++++++++ src/ipa/ipu3/algorithms/meson.build | 3 +- src/ipa/ipu3/ipa_context.h | 8 +++++ src/ipa/ipu3/ipu3.cpp | 12 +++++-- src/ipa/ipu3/ipu3_agc.cpp | 9 +++-- src/ipa/ipu3/ipu3_agc.h | 5 +-- src/ipa/ipu3/ipu3_awb.cpp | 41 ++-------------------- src/ipa/ipu3/ipu3_awb.h | 2 +- 10 files changed, 114 insertions(+), 52 deletions(-) create mode 100644 src/ipa/ipu3/algorithms/contrast.cpp create mode 100644 src/ipa/ipu3/algorithms/contrast.h diff --git a/src/ipa/ipu3/algorithms/algorithm.h b/src/ipa/ipu3/algorithms/algorithm.h index b571f55a..13e5f2d4 100644 --- a/src/ipa/ipu3/algorithms/algorithm.h +++ b/src/ipa/ipu3/algorithms/algorithm.h @@ -28,6 +28,8 @@ public: } virtual void prepare([[maybe_unused]] IPAContext &context, [[maybe_unused]] ipu3_uapi_params ¶ms) {} + + virtual void process([[maybe_unused]] IPAContext &context, [[maybe_unused]] const ipu3_uapi_stats_3a *stats) {} }; } /* namespace ipa::ipu3 */ diff --git a/src/ipa/ipu3/algorithms/contrast.cpp b/src/ipa/ipu3/algorithms/contrast.cpp new file mode 100644 index 00000000..bc00490f --- /dev/null +++ b/src/ipa/ipu3/algorithms/contrast.cpp @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Ideas On Board + * + * constrast.cpp - IPU3 Contrast and Gamma control + */ + +#include "contrast.h" + +#include + +#include + +namespace libcamera { + +namespace ipa::ipu3::algorithms { + +LOG_DEFINE_CATEGORY(IPU3Contrast) + +Contrast::Contrast() + : gamma_(1.0) +{ +} + +void Contrast::prepare([[maybe_unused]] IPAContext &context, ipu3_uapi_params ¶ms) +{ + params.use.acc_gamma = 1; + params.acc_param.gamma.gc_ctrl.enable = 1; + + for (uint32_t i = 0; i < IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES; i++) + params.acc_param.gamma.gc_lut.lut[i] = context.frameContext.contrast.lut[i]; +} + +void Contrast::process([[maybe_unused]] IPAContext &context, [[maybe_unused]] const ipu3_uapi_stats_3a *stats) +{ + /* Limit the gamma effect for now */ + gamma_ = 1.1; + + /* Plot the gamma curve into the look up table */ + for (uint32_t i = 0; i < IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES; i++) { + double j = i / 255.0; + double gamma = std::pow(j, 1.0 / gamma_); + + /* The maximum value 255 is represented on 13 bits in the IPU3 */ + context.frameContext.contrast.lut[i] = gamma * 8191; + } +} + +} /* namespace ipa::ipu3::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/ipu3/algorithms/contrast.h b/src/ipa/ipu3/algorithms/contrast.h new file mode 100644 index 00000000..50cb626f --- /dev/null +++ b/src/ipa/ipu3/algorithms/contrast.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google + * + * constrast.h - IPU3 Contrast and Gamma control + */ +#ifndef __LIBCAMERA_IPU3_ALGORITHMS_CONTRAST_H__ +#define __LIBCAMERA_IPU3_ALGORITHMS_CONTRAST_H__ + +#include "algorithm.h" + +namespace libcamera { + +namespace ipa::ipu3::algorithms { + +class Contrast : public Algorithm +{ +public: + Contrast(); + ~Contrast() = default; + + void prepare(IPAContext &context, ipu3_uapi_params ¶ms) override; + void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override; + +private: + double gamma_; +}; + +} /* namespace ipa::ipu3::algorithms */ + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_IPU3_ALGORITHMS_CONTRAST_H__ */ diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build index 3fb3ce56..69a59096 100644 --- a/src/ipa/ipu3/algorithms/meson.build +++ b/src/ipa/ipu3/algorithms/meson.build @@ -1,5 +1,6 @@ # SPDX-License-Identifier: CC0-1.0 ipu3_ipa_algorithms = files([ - 'grid.cpp', + 'contrast.cpp', + 'grid.cpp', ]) diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index 90b2f2c2..e995c663 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -33,6 +33,14 @@ struct IPAConfiguration { * lifetime, though for now a single instance is used. */ struct IPAFrameContext { + struct Agc { + uint32_t exposure; + double gain; + } agc; + + struct Contrast { + uint16_t lut[IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES]; + } contrast; }; /* Global context of the IPA */ diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 394a7a45..e09adfc3 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -30,6 +30,7 @@ #include "libcamera/internal/mapped_framebuffer.h" #include "algorithms/algorithm.h" +#include "algorithms/contrast.h" #include "algorithms/grid.h" #include "ipu3_agc.h" #include "ipu3_awb.h" @@ -167,6 +168,7 @@ int IPAIPU3::init(const IPASettings &settings, *ipaControls = ControlInfoMap(std::move(controls), controls::controls); /* Construct our Algorithms */ algorithms_.emplace_back(new algorithms::Grid()); + algorithms_.emplace_back(new algorithms::Contrast()); return 0; } @@ -309,7 +311,7 @@ void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params) algo->prepare(context_, params_); if (agcAlgo_->updateControls()) - awbAlgo_->updateWbParameters(params_, agcAlgo_->gamma()); + awbAlgo_->updateWbParameters(params_); *params = params_; @@ -324,9 +326,15 @@ void IPAIPU3::parseStatistics(unsigned int frame, [[maybe_unused]] const ipu3_uapi_stats_3a *stats) { ControlList ctrls(controls::controls); + for (auto const &algo : algorithms_) + algo->process(context_, stats); double gain = camHelper_->gain(gain_); - agcAlgo_->process(stats, exposure_, gain); + context_.frameContext.agc.exposure = exposure_; + context_.frameContext.agc.gain = gain; + agcAlgo_->process(context_, stats); + exposure_ = context_.frameContext.agc.exposure; + gain = context_.frameContext.agc.gain; gain_ = camHelper_->gainCode(gain); awbAlgo_->calculateWBGains(stats); diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/ipu3_agc.cpp index 408eb849..c6782ff4 100644 --- a/src/ipa/ipu3/ipu3_agc.cpp +++ b/src/ipa/ipu3/ipu3_agc.cpp @@ -52,7 +52,7 @@ static constexpr uint8_t kCellSize = 8; IPU3Agc::IPU3Agc() : frameCount_(0), lastFrame_(0), converged_(false), - updateControls_(false), iqMean_(0.0), gamma_(1.0), + updateControls_(false), iqMean_(0.0), lineDuration_(0s), maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s), currentExposure_(0s), currentExposureNoDg_(0s) @@ -104,9 +104,6 @@ void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) } } - /* Limit the gamma effect for now */ - gamma_ = 1.1; - /* Estimate the quantile mean of the top 2% of the histogram */ iqMean_ = Histogram(Span(hist)).interQuantileMean(0.98, 1.0); } @@ -193,8 +190,10 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) lastFrame_ = frameCount_; } -void IPU3Agc::process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, double &gain) +void IPU3Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) { + uint32_t &exposure = context.frameContext.agc.exposure; + double &gain = context.frameContext.agc.gain; processBrightness(stats); lockExposureGain(exposure, gain); frameCount_++; diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h index f00b98d6..8b32e52f 100644 --- a/src/ipa/ipu3/ipu3_agc.h +++ b/src/ipa/ipu3/ipu3_agc.h @@ -30,11 +30,9 @@ public: ~IPU3Agc() = default; void initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo); - void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, double &gain); + void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override; bool converged() { return converged_; } bool updateControls() { return updateControls_; } - /* \todo Use a metadata exchange between IPAs */ - double gamma() { return gamma_; } private: void processBrightness(const ipu3_uapi_stats_3a *stats); @@ -50,7 +48,6 @@ private: bool updateControls_; double iqMean_; - double gamma_; Duration lineDuration_; Duration maxExposureTime_; diff --git a/src/ipa/ipu3/ipu3_awb.cpp b/src/ipa/ipu3/ipu3_awb.cpp index 911760b3..0f3bcdc9 100644 --- a/src/ipa/ipu3/ipu3_awb.cpp +++ b/src/ipa/ipu3/ipu3_awb.cpp @@ -114,31 +114,6 @@ static const struct ipu3_uapi_ccm_mat_config imguCssCcmDefault = { 0, 0, 8191, 0 }; -/* Default settings for Gamma correction */ -const struct ipu3_uapi_gamma_corr_lut imguCssGammaLut = { { - 63, 79, 95, 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, - 303, 319, 335, 351, 367, 383, 399, 415, 431, 447, 463, 479, 495, 511, - 527, 543, 559, 575, 591, 607, 623, 639, 655, 671, 687, 703, 719, 735, - 751, 767, 783, 799, 815, 831, 847, 863, 879, 895, 911, 927, 943, 959, - 975, 991, 1007, 1023, 1039, 1055, 1071, 1087, 1103, 1119, 1135, 1151, - 1167, 1183, 1199, 1215, 1231, 1247, 1263, 1279, 1295, 1311, 1327, 1343, - 1359, 1375, 1391, 1407, 1423, 1439, 1455, 1471, 1487, 1503, 1519, 1535, - 1551, 1567, 1583, 1599, 1615, 1631, 1647, 1663, 1679, 1695, 1711, 1727, - 1743, 1759, 1775, 1791, 1807, 1823, 1839, 1855, 1871, 1887, 1903, 1919, - 1935, 1951, 1967, 1983, 1999, 2015, 2031, 2047, 2063, 2079, 2095, 2111, - 2143, 2175, 2207, 2239, 2271, 2303, 2335, 2367, 2399, 2431, 2463, 2495, - 2527, 2559, 2591, 2623, 2655, 2687, 2719, 2751, 2783, 2815, 2847, 2879, - 2911, 2943, 2975, 3007, 3039, 3071, 3103, 3135, 3167, 3199, 3231, 3263, - 3295, 3327, 3359, 3391, 3423, 3455, 3487, 3519, 3551, 3583, 3615, 3647, - 3679, 3711, 3743, 3775, 3807, 3839, 3871, 3903, 3935, 3967, 3999, 4031, - 4063, 4095, 4127, 4159, 4223, 4287, 4351, 4415, 4479, 4543, 4607, 4671, - 4735, 4799, 4863, 4927, 4991, 5055, 5119, 5183, 5247, 5311, 5375, 5439, - 5503, 5567, 5631, 5695, 5759, 5823, 5887, 5951, 6015, 6079, 6143, 6207, - 6271, 6335, 6399, 6463, 6527, 6591, 6655, 6719, 6783, 6847, 6911, 6975, - 7039, 7103, 7167, 7231, 7295, 7359, 7423, 7487, 7551, 7615, 7679, 7743, - 7807, 7871, 7935, 7999, 8063, 8127, 8191 -} }; - IPU3Awb::IPU3Awb() : Algorithm() { @@ -179,10 +154,6 @@ void IPU3Awb::initialise(ipu3_uapi_params ¶ms, const Size &bdsOutputSize, st params.use.acc_ccm = 1; params.acc_param.ccm = imguCssCcmDefault; - params.use.acc_gamma = 1; - params.acc_param.gamma.gc_lut = imguCssGammaLut; - params.acc_param.gamma.gc_ctrl.enable = 1; - zones_.reserve(kAwbStatsSizeX * kAwbStatsSizeY); } @@ -332,7 +303,7 @@ void IPU3Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats) } } -void IPU3Awb::updateWbParameters(ipu3_uapi_params ¶ms, double agcGamma) +void IPU3Awb::updateWbParameters(ipu3_uapi_params ¶ms) { /* * Green gains should not be touched and considered 1. @@ -344,18 +315,10 @@ void IPU3Awb::updateWbParameters(ipu3_uapi_params ¶ms, double agcGamma) params.acc_param.bnr.wb_gains.b = 4096 * asyncResults_.blueGain; params.acc_param.bnr.wb_gains.gb = 16; - LOG(IPU3Awb, Debug) << "Color temperature estimated: " << asyncResults_.temperatureK - << " and gamma calculated: " << agcGamma; + LOG(IPU3Awb, Debug) << "Color temperature estimated: " << asyncResults_.temperatureK; /* The CCM matrix may change when color temperature will be used */ params.acc_param.ccm = imguCssCcmDefault; - - for (uint32_t i = 0; i < 256; i++) { - double j = i / 255.0; - double gamma = std::pow(j, 1.0 / agcGamma); - /* The maximum value 255 is represented on 13 bits in the IPU3 */ - params.acc_param.gamma.gc_lut.lut[i] = gamma * 8191; - } } } /* namespace ipa::ipu3 */ diff --git a/src/ipa/ipu3/ipu3_awb.h b/src/ipa/ipu3/ipu3_awb.h index ea2d4320..eeb2920b 100644 --- a/src/ipa/ipu3/ipu3_awb.h +++ b/src/ipa/ipu3/ipu3_awb.h @@ -31,7 +31,7 @@ public: void initialise(ipu3_uapi_params ¶ms, const Size &bdsOutputSize, struct ipu3_uapi_grid_config &bdsGrid); void calculateWBGains(const ipu3_uapi_stats_3a *stats); - void updateWbParameters(ipu3_uapi_params ¶ms, double agcGamma); + void updateWbParameters(ipu3_uapi_params ¶ms); struct Ipu3AwbCell { unsigned char greenRedAvg; From patchwork Thu Aug 12 16:52:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13334 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 2BAA9C3241 for ; Thu, 12 Aug 2021 16:52:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E8BE4688C4; Thu, 12 Aug 2021 18:52:54 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Poa9ICk6"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EDFD868891 for ; Thu, 12 Aug 2021 18:52:47 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:3d6d:7284:3c48:5edc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A3CFF8AF; Thu, 12 Aug 2021 18:52:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628787167; bh=KLJ7ueKcUdsxv2t3EztSUTwOHoGSxLt+SGRVnzaeI1w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Poa9ICk6cHQp/Unffdaq6yofNr40DXo71Sg4Q0O6jsvFaA8GziQN4uMFvSY/Te5qg WqP0nqFxBze1EW5pZK6NYySq21B4Gb8wnsoN/xLI861Q27B4PhEts23ocb0r3ZTH2o 4BICBZ8epOs+y0pIaoYQ05oq9hF8LbjBGiXhV4ps= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 12 Aug 2021 18:52:39 +0200 Message-Id: <20210812165243.276977-7-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 Subject: [libcamera-devel] [PATCH v2 06/10] ipa: ipu3: convert AWB to the new algorithm interface X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When the stats are received, pass it with the context to the existing AWB algorithm. IPAFrameContext now has a new structure to store the gains calculated byt the AWB algorithm. When a EventFillParams event is received, call prepare() and set the new gains accordingly in the params structure. There is no more a need for the IPU3Awb::initialise() function, as the params are always set in prepare(). Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- src/ipa/ipu3/ipa_context.h | 8 ++++ src/ipa/ipu3/ipu3.cpp | 5 +-- src/ipa/ipu3/ipu3_awb.cpp | 76 ++++++++++++++++++++------------------ src/ipa/ipu3/ipu3_awb.h | 6 +-- 4 files changed, 54 insertions(+), 41 deletions(-) diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h index e995c663..7bb4f598 100644 --- a/src/ipa/ipu3/ipa_context.h +++ b/src/ipa/ipu3/ipa_context.h @@ -38,6 +38,14 @@ struct IPAFrameContext { double gain; } agc; + struct Awb { + struct Gains { + double redGain; + double greenGain; + double blueGain; + } gains; + } awb; + struct Contrast { uint16_t lut[IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES]; } contrast; diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index e09adfc3..dba5554d 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -230,7 +230,6 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) } awbAlgo_ = std::make_unique(); - awbAlgo_->initialise(params_, context_.configuration.grid.bdsOutputSize, context_.configuration.grid.bdsGrid); agcAlgo_ = std::make_unique(); agcAlgo_->initialise(context_.configuration.grid.bdsGrid, sensorInfo_); @@ -311,7 +310,7 @@ void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params) algo->prepare(context_, params_); if (agcAlgo_->updateControls()) - awbAlgo_->updateWbParameters(params_); + awbAlgo_->prepare(context_, params_); *params = params_; @@ -337,7 +336,7 @@ void IPAIPU3::parseStatistics(unsigned int frame, gain = context_.frameContext.agc.gain; gain_ = camHelper_->gainCode(gain); - awbAlgo_->calculateWBGains(stats); + awbAlgo_->process(context_, stats); if (agcAlgo_->updateControls()) setControls(frame); diff --git a/src/ipa/ipu3/ipu3_awb.cpp b/src/ipa/ipu3/ipu3_awb.cpp index 0f3bcdc9..b422b095 100644 --- a/src/ipa/ipu3/ipu3_awb.cpp +++ b/src/ipa/ipu3/ipu3_awb.cpp @@ -121,42 +121,14 @@ IPU3Awb::IPU3Awb() asyncResults_.greenGain = 1.0; asyncResults_.redGain = 1.0; asyncResults_.temperatureK = 4500; + + zones_.reserve(kAwbStatsSizeX * kAwbStatsSizeY); } IPU3Awb::~IPU3Awb() { } -void IPU3Awb::initialise(ipu3_uapi_params ¶ms, const Size &bdsOutputSize, struct ipu3_uapi_grid_config &bdsGrid) -{ - params.use.acc_awb = 1; - params.acc_param.awb.config.rgbs_thr_gr = 8191; - params.acc_param.awb.config.rgbs_thr_r = 8191; - params.acc_param.awb.config.rgbs_thr_gb = 8191; - params.acc_param.awb.config.rgbs_thr_b = 8191 | IPU3_UAPI_AWB_RGBS_THR_B_EN | IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT; - awbGrid_ = bdsGrid; - - params.use.acc_bnr = 1; - params.acc_param.bnr = imguCssBnrDefaults; - /** - * Optical center is column (respectively row) startminus X (respectively Y) center. - * For the moment use BDS as a first approximation, but it should - * be calculated based on Shading (SHD) parameters. - */ - params.acc_param.bnr.column_size = bdsOutputSize.width; - params.acc_param.bnr.opt_center.x_reset = awbGrid_.x_start - (bdsOutputSize.width / 2); - params.acc_param.bnr.opt_center.y_reset = awbGrid_.y_start - (bdsOutputSize.height / 2); - params.acc_param.bnr.opt_center_sqr.x_sqr_reset = params.acc_param.bnr.opt_center.x_reset - * params.acc_param.bnr.opt_center.x_reset; - params.acc_param.bnr.opt_center_sqr.y_sqr_reset = params.acc_param.bnr.opt_center.y_reset - * params.acc_param.bnr.opt_center.y_reset; - - params.use.acc_ccm = 1; - params.acc_param.ccm = imguCssCcmDefault; - - zones_.reserve(kAwbStatsSizeX * kAwbStatsSizeY); -} - /** * The function estimates the correlated color temperature using * from RGB color space input. @@ -303,17 +275,51 @@ void IPU3Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats) } } -void IPU3Awb::updateWbParameters(ipu3_uapi_params ¶ms) +void IPU3Awb::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) +{ + calculateWBGains(stats); + context.frameContext.awb.gains.blueGain = asyncResults_.blueGain; + context.frameContext.awb.gains.greenGain = asyncResults_.greenGain; + context.frameContext.awb.gains.redGain = asyncResults_.redGain; +} + +void IPU3Awb::prepare(IPAContext &context, ipu3_uapi_params ¶ms) { + params.use.acc_awb = 1; + params.acc_param.awb.config.rgbs_thr_gr = 8191; + params.acc_param.awb.config.rgbs_thr_r = 8191; + params.acc_param.awb.config.rgbs_thr_gb = 8191; + params.acc_param.awb.config.rgbs_thr_b = 8191 | IPU3_UAPI_AWB_RGBS_THR_B_EN | IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT; + awbGrid_ = context.configuration.grid.bdsGrid; + + params.use.acc_bnr = 1; + params.acc_param.bnr = imguCssBnrDefaults; + /** + * Optical center is column (respectively row) startminus X (respectively Y) center. + * For the moment use BDS as a first approximation, but it should + * be calculated based on Shading (SHD) parameters. + */ + Size &bdsOutputSize = context.configuration.grid.bdsOutputSize; + params.acc_param.bnr.column_size = bdsOutputSize.width; + params.acc_param.bnr.opt_center.x_reset = awbGrid_.x_start - (bdsOutputSize.width / 2); + params.acc_param.bnr.opt_center.y_reset = awbGrid_.y_start - (bdsOutputSize.height / 2); + params.acc_param.bnr.opt_center_sqr.x_sqr_reset = params.acc_param.bnr.opt_center.x_reset + * params.acc_param.bnr.opt_center.x_reset; + params.acc_param.bnr.opt_center_sqr.y_sqr_reset = params.acc_param.bnr.opt_center.y_reset + * params.acc_param.bnr.opt_center.y_reset; + + params.use.acc_ccm = 1; + params.acc_param.ccm = imguCssCcmDefault; + /* * Green gains should not be touched and considered 1. * Default is 16, so do not change it at all. * 4096 is the value for a gain of 1.0 */ - params.acc_param.bnr.wb_gains.gr = 16; - params.acc_param.bnr.wb_gains.r = 4096 * asyncResults_.redGain; - params.acc_param.bnr.wb_gains.b = 4096 * asyncResults_.blueGain; - params.acc_param.bnr.wb_gains.gb = 16; + params.acc_param.bnr.wb_gains.gr = 16 * context.frameContext.awb.gains.greenGain; + params.acc_param.bnr.wb_gains.r = 4096 * context.frameContext.awb.gains.redGain; + params.acc_param.bnr.wb_gains.b = 4096 * context.frameContext.awb.gains.blueGain; + params.acc_param.bnr.wb_gains.gb = 16 * context.frameContext.awb.gains.greenGain; LOG(IPU3Awb, Debug) << "Color temperature estimated: " << asyncResults_.temperatureK; diff --git a/src/ipa/ipu3/ipu3_awb.h b/src/ipa/ipu3/ipu3_awb.h index eeb2920b..4de3fae2 100644 --- a/src/ipa/ipu3/ipu3_awb.h +++ b/src/ipa/ipu3/ipu3_awb.h @@ -29,9 +29,8 @@ public: IPU3Awb(); ~IPU3Awb(); - void initialise(ipu3_uapi_params ¶ms, const Size &bdsOutputSize, struct ipu3_uapi_grid_config &bdsGrid); - void calculateWBGains(const ipu3_uapi_stats_3a *stats); - void updateWbParameters(ipu3_uapi_params ¶ms); + void prepare(IPAContext &context, ipu3_uapi_params ¶ms) override; + void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override; struct Ipu3AwbCell { unsigned char greenRedAvg; @@ -72,6 +71,7 @@ public: }; private: + void calculateWBGains(const ipu3_uapi_stats_3a *stats); void generateZones(std::vector &zones); void generateAwbStats(const ipu3_uapi_stats_3a *stats); void clearAwbStats(); From patchwork Thu Aug 12 16:52:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13335 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 12D46C3242 for ; Thu, 12 Aug 2021 16:52:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9E9CD68886; Thu, 12 Aug 2021 18:52:55 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="GfW/FEHi"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1E20768893 for ; Thu, 12 Aug 2021 18:52:48 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:3d6d:7284:3c48:5edc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D09A3F49; Thu, 12 Aug 2021 18:52:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628787167; bh=tkuhE9jzm9r7eXnQj67EBvKN4thsCmh0T0knUSicSQM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GfW/FEHiB83KPdqddOKr8TRYnKibKsgChDxnxwPqPca5JWYmbHC2a4EXCiQ5s4UQm K5QpHD4QWMnJMZ2VSAx2gJgPqfraX1nxsKO3iCLO3ZlhYhxxkSfVA8pF9Ufyo+R+gQ MrjtER/GKXp5MN/MNwC1DVXcMpGXJtjU4o5/+dNY= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 12 Aug 2021 18:52:40 +0200 Message-Id: <20210812165243.276977-8-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 Subject: [libcamera-devel] [PATCH v2 07/10] ipa: ipu3: convert AGC to the new algorithm interface X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- src/ipa/ipu3/ipu3.cpp | 2 +- src/ipa/ipu3/ipu3_agc.cpp | 8 +++++--- src/ipa/ipu3/ipu3_agc.h | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index dba5554d..2a8225a0 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -232,7 +232,7 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) awbAlgo_ = std::make_unique(); agcAlgo_ = std::make_unique(); - agcAlgo_->initialise(context_.configuration.grid.bdsGrid, sensorInfo_); + agcAlgo_->configure(context_, configInfo); return 0; } diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/ipu3_agc.cpp index c6782ff4..0cc35b9f 100644 --- a/src/ipa/ipu3/ipu3_agc.cpp +++ b/src/ipa/ipu3/ipu3_agc.cpp @@ -59,12 +59,14 @@ IPU3Agc::IPU3Agc() { } -void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo) +int IPU3Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) { - aeGrid_ = bdsGrid; + aeGrid_ = context.configuration.grid.bdsGrid; - lineDuration_ = sensorInfo.lineLength * 1.0s / sensorInfo.pixelRate; + lineDuration_ = configInfo.sensorInfo.lineLength * 1.0s / configInfo.sensorInfo.pixelRate; maxExposureTime_ = kMaxExposure * lineDuration_; + + return 0; } void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h index 8b32e52f..e096648b 100644 --- a/src/ipa/ipu3/ipu3_agc.h +++ b/src/ipa/ipu3/ipu3_agc.h @@ -29,7 +29,7 @@ public: IPU3Agc(); ~IPU3Agc() = default; - void initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo); + int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override; bool converged() { return converged_; } bool updateControls() { return updateControls_; } From patchwork Thu Aug 12 16:52:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13336 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 951F8BD87D for ; Thu, 12 Aug 2021 16:52:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4699F6888F; Thu, 12 Aug 2021 18:52:56 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="kFoiCMJy"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4F8AE68894 for ; Thu, 12 Aug 2021 18:52:48 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:3d6d:7284:3c48:5edc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0884149A; Thu, 12 Aug 2021 18:52:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628787168; bh=55jw/y2mhxYMAJL6uHbuv9dgarSKY+SQjqqYtIFCRxs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kFoiCMJyMuiI2ctq6IC6hppfYOzeG88HwNRo/KEUszHT4bdQJUVhaqXX00cEpyvEb I72B0zbHhkEzLQyBbrv5nD2d9FB/n9RvoBaIVem3nfOyBWYCZoJdjnVQ+873oXhciV iBHzVRP87ivlAwS46pgfL5kCpPSZuak1zF+lYEyU= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 12 Aug 2021 18:52:41 +0200 Message-Id: <20210812165243.276977-9-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 Subject: [libcamera-devel] [PATCH v2 08/10] ipa: ipu3: Remove unneeded function calls in AGC X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" We never use converged_ so remove its declaration. The controls may not need to be updated at each call, but it should be decided on the context side and not by a specific call. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- src/ipa/ipu3/ipu3.cpp | 6 ++---- src/ipa/ipu3/ipu3_agc.cpp | 10 ++-------- src/ipa/ipu3/ipu3_agc.h | 5 ----- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 2a8225a0..27765aa6 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -309,8 +309,7 @@ void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params) for (auto const &algo : algorithms_) algo->prepare(context_, params_); - if (agcAlgo_->updateControls()) - awbAlgo_->prepare(context_, params_); + awbAlgo_->prepare(context_, params_); *params = params_; @@ -338,8 +337,7 @@ void IPAIPU3::parseStatistics(unsigned int frame, awbAlgo_->process(context_, stats); - if (agcAlgo_->updateControls()) - setControls(frame); + setControls(frame); /* \todo Use VBlank value calculated from each frame exposure. */ int64_t frameDuration = sensorInfo_.lineLength * (defVBlank_ + sensorInfo_.outputSize.height) / diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/ipu3_agc.cpp index 0cc35b9f..0d0584a8 100644 --- a/src/ipa/ipu3/ipu3_agc.cpp +++ b/src/ipa/ipu3/ipu3_agc.cpp @@ -51,9 +51,8 @@ static constexpr double kEvGainTarget = 0.5; static constexpr uint8_t kCellSize = 8; IPU3Agc::IPU3Agc() - : frameCount_(0), lastFrame_(0), converged_(false), - updateControls_(false), iqMean_(0.0), - lineDuration_(0s), maxExposureTime_(0s), + : frameCount_(0), lastFrame_(0), + iqMean_(0.0), lineDuration_(0s), maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s), currentExposure_(0s), currentExposureNoDg_(0s) { @@ -146,8 +145,6 @@ void IPU3Agc::filterExposure() void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) { - updateControls_ = false; - /* Algorithm initialization should wait for first valid frames */ /* \todo - have a number of frames given by DelayedControls ? * - implement a function for IIR */ @@ -157,7 +154,6 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) /* Are we correctly exposed ? */ if (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1) { LOG(IPU3Agc, Debug) << "!!! Good exposure with iqMean = " << iqMean_; - converged_ = true; } else { double newGain = kEvGainTarget * knumHistogramBins / iqMean_; @@ -180,12 +176,10 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) exposure = std::clamp(static_cast(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure); newExposure = currentExposure_ / exposure; gain = std::clamp(static_cast(gain * currentExposure_ / newExposure), kMinGain, kMaxGain); - updateControls_ = true; } else if (currentShutter >= maxExposureTime_) { gain = std::clamp(static_cast(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain); newExposure = currentExposure_ / gain; exposure = std::clamp(static_cast(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure); - updateControls_ = true; } LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain; } diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h index e096648b..0e922664 100644 --- a/src/ipa/ipu3/ipu3_agc.h +++ b/src/ipa/ipu3/ipu3_agc.h @@ -31,8 +31,6 @@ public: int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override; - bool converged() { return converged_; } - bool updateControls() { return updateControls_; } private: void processBrightness(const ipu3_uapi_stats_3a *stats); @@ -44,9 +42,6 @@ private: uint64_t frameCount_; uint64_t lastFrame_; - bool converged_; - bool updateControls_; - double iqMean_; Duration lineDuration_; From patchwork Thu Aug 12 16:52:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13337 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 0D71EC3241 for ; Thu, 12 Aug 2021 16:52:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B905E68893; Thu, 12 Aug 2021 18:52:56 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="iIb1wkbK"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7C7B968895 for ; Thu, 12 Aug 2021 18:52:48 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:3d6d:7284:3c48:5edc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 349268AF; Thu, 12 Aug 2021 18:52:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628787168; bh=oTYrAdFvDG9G2sxyLw1UwJCWc33uGxq2cjwwCgRAZSQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iIb1wkbKqk8iAouB1J0QD9360ubMbqmlUOd/Bz7IjekAIEyAco2kGHx3sPZk2LMUR 5Axmhag2T0eISe3zegva3hhK1us8+gl0tFl0Y9B4YrVi0K2jzYSGsMKzC78MN71ALK qViThGtWiKJ3GkCYzkJ2B1RD1JKyq1WLOgyzdhRE= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 12 Aug 2021 18:52:42 +0200 Message-Id: <20210812165243.276977-10-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 Subject: [libcamera-devel] [PATCH v2 09/10] ipa: ipu3: Move IPU3 awb into algorithms X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that the interface is properly used by the AWB class, move it into ipa::ipu3::algorithms and let the loops do the calls. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- .../ipu3/{ipu3_awb.cpp => algorithms/awb.cpp} | 28 +++++++++---------- src/ipa/ipu3/{ipu3_awb.h => algorithms/awb.h} | 20 ++++++------- src/ipa/ipu3/algorithms/meson.build | 1 + src/ipa/ipu3/ipu3.cpp | 12 ++------ src/ipa/ipu3/meson.build | 1 - 5 files changed, 28 insertions(+), 34 deletions(-) rename src/ipa/ipu3/{ipu3_awb.cpp => algorithms/awb.cpp} (94%) rename src/ipa/ipu3/{ipu3_awb.h => algorithms/awb.h} (84%) diff --git a/src/ipa/ipu3/ipu3_awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp similarity index 94% rename from src/ipa/ipu3/ipu3_awb.cpp rename to src/ipa/ipu3/algorithms/awb.cpp index b422b095..0f401d6d 100644 --- a/src/ipa/ipu3/ipu3_awb.cpp +++ b/src/ipa/ipu3/algorithms/awb.cpp @@ -2,9 +2,9 @@ /* * Copyright (C) 2021, Ideas On Board * - * ipu3_awb.cpp - AWB control algorithm + * awb.cpp - AWB control algorithm */ -#include "ipu3_awb.h" +#include "awb.h" #include #include @@ -13,7 +13,7 @@ namespace libcamera { -namespace ipa::ipu3 { +namespace ipa::ipu3::algorithms { LOG_DEFINE_CATEGORY(IPU3Awb) @@ -114,7 +114,7 @@ static const struct ipu3_uapi_ccm_mat_config imguCssCcmDefault = { 0, 0, 8191, 0 }; -IPU3Awb::IPU3Awb() +Awb::Awb() : Algorithm() { asyncResults_.blueGain = 1.0; @@ -125,7 +125,7 @@ IPU3Awb::IPU3Awb() zones_.reserve(kAwbStatsSizeX * kAwbStatsSizeY); } -IPU3Awb::~IPU3Awb() +Awb::~Awb() { } @@ -143,7 +143,7 @@ IPU3Awb::~IPU3Awb() * More detailed information can be found in: * https://en.wikipedia.org/wiki/Color_temperature#Approximation */ -uint32_t IPU3Awb::estimateCCT(double red, double green, double blue) +uint32_t Awb::estimateCCT(double red, double green, double blue) { /* Convert the RGB values to CIE tristimulus values (XYZ) */ double X = (-0.14282) * (red) + (1.54924) * (green) + (-0.95641) * (blue); @@ -160,7 +160,7 @@ uint32_t IPU3Awb::estimateCCT(double red, double green, double blue) } /* Generate an RGB vector with the average values for each region */ -void IPU3Awb::generateZones(std::vector &zones) +void Awb::generateZones(std::vector &zones) { for (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) { RGB zone; @@ -177,7 +177,7 @@ void IPU3Awb::generateZones(std::vector &zones) } /* Translate the IPU3 statistics into the default statistics region array */ -void IPU3Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats) +void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats) { uint32_t regionWidth = round(awbGrid_.width / static_cast(kAwbStatsSizeX)); uint32_t regionHeight = round(awbGrid_.height / static_cast(kAwbStatsSizeY)); @@ -209,7 +209,7 @@ void IPU3Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats) } } -void IPU3Awb::clearAwbStats() +void Awb::clearAwbStats() { for (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) { awbStats_[i].bSum = 0; @@ -220,7 +220,7 @@ void IPU3Awb::clearAwbStats() } } -void IPU3Awb::awbGreyWorld() +void Awb::awbGreyWorld() { LOG(IPU3Awb, Debug) << "Grey world AWB"; /* @@ -260,7 +260,7 @@ void IPU3Awb::awbGreyWorld() asyncResults_.blueGain = blueGain; } -void IPU3Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats) +void Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats) { ASSERT(stats->stats_3a_status.awb_en); zones_.clear(); @@ -275,7 +275,7 @@ void IPU3Awb::calculateWBGains(const ipu3_uapi_stats_3a *stats) } } -void IPU3Awb::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) +void Awb::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) { calculateWBGains(stats); context.frameContext.awb.gains.blueGain = asyncResults_.blueGain; @@ -283,7 +283,7 @@ void IPU3Awb::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) context.frameContext.awb.gains.redGain = asyncResults_.redGain; } -void IPU3Awb::prepare(IPAContext &context, ipu3_uapi_params ¶ms) +void Awb::prepare(IPAContext &context, ipu3_uapi_params ¶ms) { params.use.acc_awb = 1; params.acc_param.awb.config.rgbs_thr_gr = 8191; @@ -327,6 +327,6 @@ void IPU3Awb::prepare(IPAContext &context, ipu3_uapi_params ¶ms) params.acc_param.ccm = imguCssCcmDefault; } -} /* namespace ipa::ipu3 */ +} /* namespace ipa::ipu3::algorithms */ } /* namespace libcamera */ diff --git a/src/ipa/ipu3/ipu3_awb.h b/src/ipa/ipu3/algorithms/awb.h similarity index 84% rename from src/ipa/ipu3/ipu3_awb.h rename to src/ipa/ipu3/algorithms/awb.h index 4de3fae2..ad640521 100644 --- a/src/ipa/ipu3/ipu3_awb.h +++ b/src/ipa/ipu3/algorithms/awb.h @@ -2,10 +2,10 @@ /* * Copyright (C) 2021, Ideas On Board * - * ipu3_awb.h - IPU3 AWB control algorithm + * awb.h - IPU3 AWB control algorithm */ -#ifndef __LIBCAMERA_IPU3_AWB_H__ -#define __LIBCAMERA_IPU3_AWB_H__ +#ifndef __LIBCAMERA_IPU3_ALGORITHMS_AWB_H__ +#define __LIBCAMERA_IPU3_ALGORITHMS_AWB_H__ #include @@ -13,21 +13,21 @@ #include -#include "algorithms/algorithm.h" +#include "algorithm.h" namespace libcamera { -namespace ipa::ipu3 { +namespace ipa::ipu3::algorithms { /* Region size for the statistics generation algorithm */ static constexpr uint32_t kAwbStatsSizeX = 16; static constexpr uint32_t kAwbStatsSizeY = 12; -class IPU3Awb : public Algorithm +class Awb : public Algorithm { public: - IPU3Awb(); - ~IPU3Awb(); + Awb(); + ~Awb(); void prepare(IPAContext &context, ipu3_uapi_params ¶ms) override; void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override; @@ -85,7 +85,7 @@ private: AwbStatus asyncResults_; }; -} /* namespace ipa::ipu3 */ +} /* namespace ipa::ipu3::algorithms */ } /* namespace libcamera*/ -#endif /* __LIBCAMERA_IPU3_AWB_H__ */ +#endif /* __LIBCAMERA_IPU3_ALGORITHMS_AWB_H__ */ diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build index 69a59096..9ef2dd41 100644 --- a/src/ipa/ipu3/algorithms/meson.build +++ b/src/ipa/ipu3/algorithms/meson.build @@ -1,6 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 ipu3_ipa_algorithms = files([ + 'awb.cpp', 'contrast.cpp', 'grid.cpp', ]) diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 27765aa6..bea2a372 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -30,10 +30,10 @@ #include "libcamera/internal/mapped_framebuffer.h" #include "algorithms/algorithm.h" +#include "algorithms/awb.h" #include "algorithms/contrast.h" #include "algorithms/grid.h" #include "ipu3_agc.h" -#include "ipu3_awb.h" #include "libipa/camera_sensor_helper.h" namespace libcamera { @@ -84,8 +84,6 @@ private: uint32_t minGain_; uint32_t maxGain_; - /* Interface to the AWB algorithm */ - std::unique_ptr awbAlgo_; /* Interface to the AEC/AGC algorithm */ std::unique_ptr agcAlgo_; /* Interface to the Camera Helper */ @@ -168,6 +166,8 @@ int IPAIPU3::init(const IPASettings &settings, *ipaControls = ControlInfoMap(std::move(controls), controls::controls); /* Construct our Algorithms */ algorithms_.emplace_back(new algorithms::Grid()); + /* Grid needs to be prepared before AWB */ + algorithms_.emplace_back(new algorithms::Awb()); algorithms_.emplace_back(new algorithms::Contrast()); return 0; @@ -229,8 +229,6 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) return ret; } - awbAlgo_ = std::make_unique(); - agcAlgo_ = std::make_unique(); agcAlgo_->configure(context_, configInfo); @@ -309,8 +307,6 @@ void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params) for (auto const &algo : algorithms_) algo->prepare(context_, params_); - awbAlgo_->prepare(context_, params_); - *params = params_; IPU3Action op; @@ -335,8 +331,6 @@ void IPAIPU3::parseStatistics(unsigned int frame, gain = context_.frameContext.agc.gain; gain_ = camHelper_->gainCode(gain); - awbAlgo_->process(context_, stats); - setControls(frame); /* \todo Use VBlank value calculated from each frame exposure. */ diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build index fcb27d68..d1126947 100644 --- a/src/ipa/ipu3/meson.build +++ b/src/ipa/ipu3/meson.build @@ -7,7 +7,6 @@ ipa_name = 'ipa_ipu3' ipu3_ipa_sources = files([ 'ipu3.cpp', 'ipu3_agc.cpp', - 'ipu3_awb.cpp', ]) ipu3_ipa_sources += ipu3_ipa_algorithms From patchwork Thu Aug 12 16:52:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Michel Hautbois X-Patchwork-Id: 13338 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 51F76C3243 for ; Thu, 12 Aug 2021 16:52:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1BD2C688E5; Thu, 12 Aug 2021 18:52:57 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="BzxGvtL0"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AE6D568888 for ; Thu, 12 Aug 2021 18:52:48 +0200 (CEST) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:3d6d:7284:3c48:5edc]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 606A3F49; Thu, 12 Aug 2021 18:52:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628787168; bh=sAhwgxc/CJEHwOiAylZPRmpj1nbil3YQro0CQZzQ0h0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BzxGvtL0ETo7sCByiwHGJflbJOe2XAa+LGcOCFPHX7LfLbdHzONqs8D7ihJmjjfdy W4JKNGnfCjmTXdCgtc7gAUKS6UeiMmjZ3NTg6/95RxfWC5RFhwMfk0Pz41ugS4Z5HD z0dhhydjQ91yqCmTE71WFeVuuahjTlKEr4Yy7Cvc= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Thu, 12 Aug 2021 18:52:43 +0200 Message-Id: <20210812165243.276977-11-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 Subject: [libcamera-devel] [PATCH v2 10/10] ipa: ipu3: Move IPU3 agc into algorithms X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that the interface is properly used by the AGC class, move it into ipa::ipu3::algorithms and let the loops do the calls. As we need to exchange the exposure_ and gain_ by passing them through the FrameContext, use the calculated values in setControls() function to ease the reading. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- .../ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} | 18 +++++++-------- src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} | 20 ++++++++--------- src/ipa/ipu3/algorithms/meson.build | 1 + src/ipa/ipu3/ipu3.cpp | 22 +++++++------------ src/ipa/ipu3/meson.build | 1 - 5 files changed, 28 insertions(+), 34 deletions(-) rename src/ipa/ipu3/{ipu3_agc.cpp => algorithms/agc.cpp} (94%) rename src/ipa/ipu3/{ipu3_agc.h => algorithms/agc.h} (73%) diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp similarity index 94% rename from src/ipa/ipu3/ipu3_agc.cpp rename to src/ipa/ipu3/algorithms/agc.cpp index 0d0584a8..ee3d3bc2 100644 --- a/src/ipa/ipu3/ipu3_agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -5,7 +5,7 @@ * ipu3_agc.cpp - AGC/AEC control algorithm */ -#include "ipu3_agc.h" +#include "agc.h" #include #include @@ -21,7 +21,7 @@ namespace libcamera { using namespace std::literals::chrono_literals; -namespace ipa::ipu3 { +namespace ipa::ipu3::algorithms { LOG_DEFINE_CATEGORY(IPU3Agc) @@ -50,7 +50,7 @@ static constexpr double kEvGainTarget = 0.5; /* A cell is 8 bytes and contains averages for RGB values and saturation ratio */ static constexpr uint8_t kCellSize = 8; -IPU3Agc::IPU3Agc() +Agc::Agc() : frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s), maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s), @@ -58,7 +58,7 @@ IPU3Agc::IPU3Agc() { } -int IPU3Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) +int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) { aeGrid_ = context.configuration.grid.bdsGrid; @@ -68,7 +68,7 @@ int IPU3Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) return 0; } -void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) +void Agc::processBrightness(const ipu3_uapi_stats_3a *stats) { const struct ipu3_uapi_grid_config statsAeGrid = stats->stats_4a_config.awb_config.grid; Rectangle aeRegion = { statsAeGrid.x_start, @@ -109,7 +109,7 @@ void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) iqMean_ = Histogram(Span(hist)).interQuantileMean(0.98, 1.0); } -void IPU3Agc::filterExposure() +void Agc::filterExposure() { double speed = 0.2; if (prevExposure_ == 0s) { @@ -143,7 +143,7 @@ void IPU3Agc::filterExposure() LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << prevExposure_; } -void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) +void Agc::lockExposureGain(uint32_t &exposure, double &gain) { /* Algorithm initialization should wait for first valid frames */ /* \todo - have a number of frames given by DelayedControls ? @@ -186,7 +186,7 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain) lastFrame_ = frameCount_; } -void IPU3Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) +void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) { uint32_t &exposure = context.frameContext.agc.exposure; double &gain = context.frameContext.agc.gain; @@ -195,6 +195,6 @@ void IPU3Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) frameCount_++; } -} /* namespace ipa::ipu3 */ +} /* namespace ipa::ipu3::algorithms */ } /* namespace libcamera */ diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/algorithms/agc.h similarity index 73% rename from src/ipa/ipu3/ipu3_agc.h rename to src/ipa/ipu3/algorithms/agc.h index 0e922664..1739d2fd 100644 --- a/src/ipa/ipu3/ipu3_agc.h +++ b/src/ipa/ipu3/algorithms/agc.h @@ -2,10 +2,10 @@ /* * Copyright (C) 2021, Ideas On Board * - * ipu3_agc.h - IPU3 AGC/AEC control algorithm + * agc.h - IPU3 AGC/AEC control algorithm */ -#ifndef __LIBCAMERA_IPU3_AGC_H__ -#define __LIBCAMERA_IPU3_AGC_H__ +#ifndef __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ +#define __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ #include @@ -13,21 +13,21 @@ #include -#include "algorithms/algorithm.h" +#include "algorithm.h" namespace libcamera { struct IPACameraSensorInfo; -namespace ipa::ipu3 { +namespace ipa::ipu3::algorithms { using utils::Duration; -class IPU3Agc : public Algorithm +class Agc : public Algorithm { public: - IPU3Agc(); - ~IPU3Agc() = default; + Agc(); + ~Agc() = default; int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override; @@ -53,8 +53,8 @@ private: Duration currentExposureNoDg_; }; -} /* namespace ipa::ipu3 */ +} /* namespace ipa::ipu3::algorithms */ } /* namespace libcamera */ -#endif /* __LIBCAMERA_IPU3_AGC_H__ */ +#endif /* __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ */ diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build index 9ef2dd41..e75d92e0 100644 --- a/src/ipa/ipu3/algorithms/meson.build +++ b/src/ipa/ipu3/algorithms/meson.build @@ -1,6 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 ipu3_ipa_algorithms = files([ + 'agc.cpp', 'awb.cpp', 'contrast.cpp', 'grid.cpp', diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index bea2a372..a99fbcac 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -30,10 +30,10 @@ #include "libcamera/internal/mapped_framebuffer.h" #include "algorithms/algorithm.h" +#include "algorithms/agc.h" #include "algorithms/awb.h" #include "algorithms/contrast.h" #include "algorithms/grid.h" -#include "ipu3_agc.h" #include "libipa/camera_sensor_helper.h" namespace libcamera { @@ -84,8 +84,6 @@ private: uint32_t minGain_; uint32_t maxGain_; - /* Interface to the AEC/AGC algorithm */ - std::unique_ptr agcAlgo_; /* Interface to the Camera Helper */ std::unique_ptr camHelper_; @@ -167,6 +165,7 @@ int IPAIPU3::init(const IPASettings &settings, /* Construct our Algorithms */ algorithms_.emplace_back(new algorithms::Grid()); /* Grid needs to be prepared before AWB */ + algorithms_.emplace_back(new algorithms::Agc()); algorithms_.emplace_back(new algorithms::Awb()); algorithms_.emplace_back(new algorithms::Contrast()); @@ -229,9 +228,6 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) return ret; } - agcAlgo_ = std::make_unique(); - agcAlgo_->configure(context_, configInfo); - return 0; } @@ -320,17 +316,12 @@ void IPAIPU3::parseStatistics(unsigned int frame, [[maybe_unused]] const ipu3_uapi_stats_3a *stats) { ControlList ctrls(controls::controls); + context_.frameContext.agc.gain = camHelper_->gain(gain_); + context_.frameContext.agc.exposure = exposure_; + for (auto const &algo : algorithms_) algo->process(context_, stats); - double gain = camHelper_->gain(gain_); - context_.frameContext.agc.exposure = exposure_; - context_.frameContext.agc.gain = gain; - agcAlgo_->process(context_, stats); - exposure_ = context_.frameContext.agc.exposure; - gain = context_.frameContext.agc.gain; - gain_ = camHelper_->gainCode(gain); - setControls(frame); /* \todo Use VBlank value calculated from each frame exposure. */ @@ -350,6 +341,9 @@ void IPAIPU3::setControls(unsigned int frame) IPU3Action op; op.op = ActionSetSensorControls; + exposure_ = context_.frameContext.agc.exposure; + gain_ = camHelper_->gainCode(context_.frameContext.agc.gain); + ControlList ctrls(ctrls_); ctrls.set(V4L2_CID_EXPOSURE, static_cast(exposure_)); ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast(gain_)); diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build index d1126947..39320980 100644 --- a/src/ipa/ipu3/meson.build +++ b/src/ipa/ipu3/meson.build @@ -6,7 +6,6 @@ ipa_name = 'ipa_ipu3' ipu3_ipa_sources = files([ 'ipu3.cpp', - 'ipu3_agc.cpp', ]) ipu3_ipa_sources += ipu3_ipa_algorithms