From patchwork Fri Nov 19 11:16:47 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: 14650 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 26D84C324F for ; Fri, 19 Nov 2021 11:17:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F2C6B603C2; Fri, 19 Nov 2021 12:17:02 +0100 (CET) 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="q6ll+eDI"; 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 9F4C560233 for ; Fri, 19 Nov 2021 12:16:59 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:db30:8e54:a96:9838]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4C3581C19; Fri, 19 Nov 2021 12:16:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1637320619; bh=brE+Bfy873jsRdIG1pEdUtihwUkm/680lVM2HL+3/Jg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q6ll+eDIcEMaQuPqmOUk/pEt+orsMKcf01IuKeEJDUkp9LUZWy7HmMVT8o7y/dN3b 5554yRyxr5gVFNmUQaaynUXlclWJk8dmbgc3ik1ceTVd0AW1dnodMcoyDs13+YD0Rg EblcSkJ9Gztc3mTV2CGkElsr/erP+WZDPl3I5YhQ= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 19 Nov 2021 12:16:47 +0100 Message-Id: <20211119111654.68445-2-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> References: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 1/8] ipa: rkisp1: Pass IPASettings at init call 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 IPA will be initialized, it will need to know the sensor model used in order to properly call CameraSensorHelper for the analogue gain. Modify the init definition in the pipeline handler and in the IPA as well as the mojo interface to pass a IPASettings. Signed-off-by: Jean-Michel Hautbois --- include/libcamera/ipa/rkisp1.mojom | 4 +++- src/ipa/rkisp1/rkisp1.cpp | 5 +++-- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 9 +++++---- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom index cae757ea..a6991d4f 100644 --- a/include/libcamera/ipa/rkisp1.mojom +++ b/include/libcamera/ipa/rkisp1.mojom @@ -29,7 +29,9 @@ struct RkISP1Action { }; interface IPARkISP1Interface { - init(uint32 hwRevision) => (int32 ret); + init(libcamera.IPASettings settings, + uint32 hwRevision) + => (int32 ret); start() => (int32 ret); stop(); diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index bf2c13b6..7ecbf8ae 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -34,7 +34,7 @@ namespace ipa::rkisp1 { class IPARkISP1 : public IPARkISP1Interface { public: - int init(unsigned int hwRevision) override; + int init(const IPASettings &settings, unsigned int hwRevision) override; int start() override; void stop() override {} @@ -75,7 +75,8 @@ private: unsigned int hwHistogramWeightGridsSize_; }; -int IPARkISP1::init(unsigned int hwRevision) +int IPARkISP1::init([[maybe_unused]] const IPASettings &settings, + unsigned int hwRevision) { /* \todo Add support for other revisions */ switch (hwRevision) { diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 98008862..db8856d3 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -88,7 +88,7 @@ public: } PipelineHandlerRkISP1 *pipe(); - int loadIPA(unsigned int hwRevision); + int loadIPA(const IPASettings &settings, unsigned int hwRevision); Stream mainPathStream_; Stream selfPathStream_; @@ -310,7 +310,7 @@ PipelineHandlerRkISP1 *RkISP1CameraData::pipe() return static_cast(Camera::Private::pipe()); } -int RkISP1CameraData::loadIPA(unsigned int hwRevision) +int RkISP1CameraData::loadIPA(const IPASettings &settings, unsigned int hwRevision) { ipa_ = IPAManager::createIPA(pipe(), 1, 1); if (!ipa_) @@ -319,7 +319,7 @@ int RkISP1CameraData::loadIPA(unsigned int hwRevision) ipa_->queueFrameAction.connect(this, &RkISP1CameraData::queueFrameAction); - int ret = ipa_->init(hwRevision); + int ret = ipa_->init(settings, hwRevision); if (ret < 0) { LOG(RkISP1, Error) << "IPA initialization failure"; return ret; @@ -965,7 +965,8 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) isp_->frameStart.connect(data->delayedCtrls_.get(), &DelayedControls::applyControls); - ret = data->loadIPA(media_->hwRevision()); + ret = data->loadIPA(IPASettings{ "", data->sensor_->model() }, + media_->hwRevision()); if (ret) return ret; From patchwork Fri Nov 19 11:16:48 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: 14651 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 41F0DBF415 for ; Fri, 19 Nov 2021 11:17:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6DC506042B; Fri, 19 Nov 2021 12:17:04 +0100 (CET) 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="Tk39Bf9a"; 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 C04D36033C for ; Fri, 19 Nov 2021 12:16:59 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:db30:8e54:a96:9838]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 760251C5D; Fri, 19 Nov 2021 12:16:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1637320619; bh=gtNs8mXGgWJs0AE3VGTZyudvUHjkt3KI+nRXiGGn8I8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Tk39Bf9a1ftOSGxXTn9Ij5qaO/bYAz7IxT5L8RpCeDcFnKVeNJKkj2yYZ5wAFyMRD mmnK3PH+b+cycC6d6fygdpLQysRD7VdxHp7EAsyjsCABjgAwMai3rH/q7EpbKLjimv Iylgt4ueL6D5+b2iooA1Fe6vXNOtb2Z1aOsJErnc= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 19 Nov 2021 12:16:48 +0100 Message-Id: <20211119111654.68445-3-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> References: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 2/8] ipa: rkisp1: Instantiate CameraSensorHelper 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 AGC will run, it will use analogue gains as double values. We will need those values to be converted to apply the control. Introduce CameraSensorHelper and call it at init(). Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/rkisp1/rkisp1.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 7ecbf8ae..ff8d8712 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -25,6 +25,8 @@ #include +#include "libipa/camera_sensor_helper.h" + namespace libcamera { LOG_DEFINE_CATEGORY(IPARkISP1) @@ -73,6 +75,9 @@ private: unsigned int hwHistBinNMax_; unsigned int hwGammaOutMaxSamples_; unsigned int hwHistogramWeightGridsSize_; + + /* Interface to the Camera Helper */ + std::unique_ptr camHelper_; }; int IPARkISP1::init([[maybe_unused]] const IPASettings &settings, @@ -100,6 +105,15 @@ int IPARkISP1::init([[maybe_unused]] const IPASettings &settings, } LOG(IPARkISP1, Debug) << "Hardware revision is " << hwRevision; + + camHelper_ = CameraSensorHelperFactory::create(settings.sensorModel); + if (camHelper_ == nullptr) { + LOG(IPARkISP1, Error) + << "Failed to create camera sensor helper for " + << settings.sensorModel; + return -ENODEV; + } + return 0; } From patchwork Fri Nov 19 11:16:49 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: 14652 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 E7E88C324F for ; Fri, 19 Nov 2021 11:17:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5993F60441; Fri, 19 Nov 2021 12:17:05 +0100 (CET) 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="wIMTyzcv"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DE07360371 for ; Fri, 19 Nov 2021 12:16:59 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:db30:8e54:a96:9838]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9FE221974; Fri, 19 Nov 2021 12:16:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1637320619; bh=RxDxDuTUzrl37A0VJHu1u4Vh5IazJhWRlLtxgx8HDGM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=wIMTyzcv9Gl7m1y5ORsyjkioje4TWaomCRLei2E0ljUGB5p6yLFaaPers3eyR2tWk 4cfm6/TxDQBp+istLO13nUvRNB9z5a1VJCRhYEbTTS+OlCj8w6nIgzeSWszkbrGYZJ FMkJfptu/oALFSsdSXFfDCoZKWwGP0K/RhXU/QN4= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 19 Nov 2021 12:16:49 +0100 Message-Id: <20211119111654.68445-4-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> References: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 3/8] ipa: rkisp1: Introduce IPAContext 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" Before using any algorithm, we want the IPAContext to be ready for those. Introduce the IPAContext as in IPA::IPU3 but empty. Each algorithm will then introduce the needed fields. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- src/ipa/rkisp1/ipa_context.cpp | 58 ++++++++++++++++++++++++++++++++++ src/ipa/rkisp1/ipa_context.h | 36 +++++++++++++++++++++ src/ipa/rkisp1/meson.build | 7 +++- src/ipa/rkisp1/rkisp1.cpp | 7 ++++ 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/ipa/rkisp1/ipa_context.cpp create mode 100644 src/ipa/rkisp1/ipa_context.h diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp new file mode 100644 index 00000000..819b2c73 --- /dev/null +++ b/src/ipa/rkisp1/ipa_context.cpp @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Ideas On Board + * + * ipa_context.cpp - RkISP1 IPA Context + */ + +#include "ipa_context.h" + +/** + * \file ipa_context.h + * \brief Context and state information shared between the algorithms + */ + +namespace libcamera::ipa::rkisp1 { + +/** + * \struct IPASessionConfiguration + * \brief Session configuration for the IPA module + * + * The session configuration contains all IPA configuration parameters that + * remain constant during the capture session, from IPA module start to stop. + * It is typically set during the configure() operation of the IPA module, but + * may also be updated in the start() operation. + */ + +/** + * \struct IPAFrameContext + * \brief Per-frame context for algorithms + * + * The frame context stores data specific to a single frame processed by the + * IPA. Each frame processed by the IPA has a context associated with it, + * accessible through the IPAContext structure. + * + * \todo Detail how to access contexts for a particular frame + * + * Each of the fields in the frame context belongs to either a specific + * algorithm, or to the top-level IPA module. A field may be read by any + * algorithm, but should only be written by its owner. + */ + +/** + * \struct IPAContext + * \brief Global IPA context data shared between all algorithms + * + * \var IPAContext::configuration + * \brief The IPA session configuration, immutable during the session + * + * \var IPAContext::frameContext + * \brief The frame context for the frame being processed + * + * \todo While the frame context is supposed to be per-frame, this + * single frame context stores data related to both the current frame + * and the previous frames, with fields being updated as the algorithms + * are run. This needs to be turned into real per-frame data storage. + */ + +} /* namespace libcamera::ipa::rkisp1 */ diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h new file mode 100644 index 00000000..a1dc39fe --- /dev/null +++ b/src/ipa/rkisp1/ipa_context.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Ideas On Board + * + * ipa_context.h - RkISP1 IPA Context + * + */ +#ifndef __LIBCAMERA_RKISP1_IPA_CONTEXT_H__ +#define __LIBCAMERA_RKISP1_IPA_CONTEXT_H__ + +#include + +#include + +#include + +namespace libcamera { + +namespace ipa::rkisp1 { + +struct IPASessionConfiguration { +}; + +struct IPAFrameContext { +}; + +struct IPAContext { + IPASessionConfiguration configuration; + IPAFrameContext frameContext; +}; + +} /* namespace ipa::rkisp1 */ + +} /* namespace libcamera*/ + +#endif /* __LIBCAMERA_RKISP1_IPA_CONTEXT_H__ */ diff --git a/src/ipa/rkisp1/meson.build b/src/ipa/rkisp1/meson.build index f76b37f5..3683c922 100644 --- a/src/ipa/rkisp1/meson.build +++ b/src/ipa/rkisp1/meson.build @@ -2,8 +2,13 @@ ipa_name = 'ipa_rkisp1' +rkisp1_ipa_sources = files([ + 'ipa_context.cpp', + 'rkisp1.cpp', +]) + mod = shared_module(ipa_name, - ['rkisp1.cpp', libcamera_generated_ipa_headers], + [rkisp1_ipa_sources, libcamera_generated_ipa_headers], name_prefix : '', include_directories : [ipa_includes, libipa_includes], dependencies : libcamera_private, diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index ff8d8712..e0933e22 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -25,6 +25,7 @@ #include +#include "ipa_context.h" #include "libipa/camera_sensor_helper.h" namespace libcamera { @@ -78,6 +79,9 @@ private: /* Interface to the Camera Helper */ std::unique_ptr camHelper_; + + /* Local parameter storage */ + struct IPAContext context_; }; int IPARkISP1::init([[maybe_unused]] const IPASettings &settings, @@ -165,6 +169,9 @@ int IPARkISP1::configure([[maybe_unused]] const IPACameraSensorInfo &info, << "Exposure: " << minExposure_ << "-" << maxExposure_ << " Gain: " << minGain_ << "-" << maxGain_; + /* Clean context at configuration */ + context_ = {}; + return 0; } From patchwork Fri Nov 19 11:16:50 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: 14653 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 9CC9AC3250 for ; Fri, 19 Nov 2021 11:17:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 32DE960398; Fri, 19 Nov 2021 12:17:06 +0100 (CET) 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="NKluxxcX"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0F66760376 for ; Fri, 19 Nov 2021 12:17:00 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:db30:8e54:a96:9838]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C8FCA1C19; Fri, 19 Nov 2021 12:16:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1637320619; bh=yNkIRJjs4v/QIzrtbu+rfR1PqWvSXqCB6KGEhxbNeGs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NKluxxcX4vG4JJL/ehDTnbex87VLBFfZQ5nomWhTA1Mu1KLNCEmb+ScsVbFlqtxEs ltlshwtPLsl+E1L/M7VQAHIB3vspGVFvPjDIclP5ZUjM3wJwsRrdQLBRKWofBWGlrm ip03voOisQCHbzkycZYwthfeZxtXjarUwUAHbqv8= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 19 Nov 2021 12:16:50 +0100 Message-Id: <20211119111654.68445-5-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> References: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 4/8] ipa: ipu3: Introduce the Algorithm class 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 everything is in place, introduce the Algorithm class and declare it in IPA::RkISP1. There is no functional change yet. Signed-off-by: Jean-Michel Hautbois --- src/ipa/rkisp1/algorithms/algorithm.cpp | 101 ++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/algorithm.h | 32 ++++++++ src/ipa/rkisp1/algorithms/meson.build | 5 ++ src/ipa/rkisp1/meson.build | 3 + src/ipa/rkisp1/rkisp1.cpp | 5 +- 5 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 src/ipa/rkisp1/algorithms/algorithm.cpp create mode 100644 src/ipa/rkisp1/algorithms/algorithm.h create mode 100644 src/ipa/rkisp1/algorithms/meson.build diff --git a/src/ipa/rkisp1/algorithms/algorithm.cpp b/src/ipa/rkisp1/algorithms/algorithm.cpp new file mode 100644 index 00000000..be3cd9f6 --- /dev/null +++ b/src/ipa/rkisp1/algorithms/algorithm.cpp @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Ideas On Board + * + * algorithm.cpp - RkISP1 control algorithm interface + */ + +#include "algorithm.h" + +/** + * \file algorithm.h + * \brief Algorithm common interface + */ + +namespace libcamera { + +namespace ipa::rkisp1 { + +/** + * \class Algorithm + * \brief The base class for all RkISP1 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. + */ + +/** + * \brief Configure the Algorithm given an IPAConfigInfo + * \param[in] context The shared IPA context + * \param[in] IPACameraSensorInfo The IPA configuration data, received from the + * pipeline handler + * + * Algorithms may implement a configure operation to pre-calculate + * parameters prior to commencing streaming. + * + * Configuration state may be stored in the IPASessionConfiguration structure of + * the IPAContext. + * + * \return 0 if successful, an error code otherwise + */ +int Algorithm::configure([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const IPACameraSensorInfo &configInfo) +{ + return 0; +} + +/** + * \brief Fill the \a params buffer with ISP processing parameters for a frame + * \param[in] context The shared IPA context + * \param[out] params The RkISP1 specific parameters. + * + * This function is called for every frame when the camera is running before it + * is processed by the ImgU to prepare the ImgU processing parameters for that + * frame. + * + * Algorithms shall fill in the parameter structure fields appropriately to + * configure the ImgU processing blocks that they are responsible for. This + * includes setting fields and flags that enable those processing blocks. + */ +void Algorithm::prepare([[maybe_unused]] IPAContext &context, + [[maybe_unused]] rkisp1_params_cfg *params) +{ +} + +/** + * \brief Process ISP statistics, and run algorithm operations + * \param[in] context The shared IPA context + * \param[in] stats The RkISP1 statistics and ISP results + * + * This function is called while camera is running for every frame processed by + * the ImgU, to process statistics generated from that frame by the ImgU. + * Algorithms shall use this data to run calculations and update their state + * accordingly. + * + * Processing shall not take an undue amount of time, and any extended or + * computationally expensive calculations or operations must be handled + * asynchronously in a separate thread. + * + * Algorithms can store state in their respective IPAFrameContext structures, + * and reference state from the IPAFrameContext of other algorithms. + * + * \todo Historical data may be required as part of the processing. + * Either the previous frame, or the IPAFrameContext state of the frame + * that generated the statistics for this operation may be required for + * some advanced algorithms to prevent oscillations or support control + * loops correctly. Only a single IPAFrameContext is available currently, + * and so any data stored may represent the results of the previously + * completed operations. + * + * Care shall be taken to ensure the ordering of access to the information + * such that the algorithms use up to date state as required. + */ +void Algorithm::process([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const rkisp1_stat_buffer *stats) +{ +} + +} /* namespace ipa::rkisp1 */ + +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/algorithm.h b/src/ipa/rkisp1/algorithms/algorithm.h new file mode 100644 index 00000000..5365a860 --- /dev/null +++ b/src/ipa/rkisp1/algorithms/algorithm.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Ideas On Board + * + * algorithm.h - RkISP1 control algorithm interface + */ +#ifndef __LIBCAMERA_IPA_RKISP1_ALGORITHM_H__ +#define __LIBCAMERA_IPA_RKISP1_ALGORITHM_H__ + +#include + +#include "ipa_context.h" + +namespace libcamera { + +namespace ipa::rkisp1 { + +class Algorithm +{ +public: + virtual ~Algorithm() {} + + virtual int configure(IPAContext &context, const IPACameraSensorInfo &configInfo); + virtual void prepare(IPAContext &context, rkisp1_params_cfg *params); + virtual void process(IPAContext &context, const rkisp1_stat_buffer *stats); +}; + +} /* namespace ipa::rkisp1 */ + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_IPA_RKISP1_ALGORITHM_H__ */ diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build new file mode 100644 index 00000000..d98f77e2 --- /dev/null +++ b/src/ipa/rkisp1/algorithms/meson.build @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: CC0-1.0 + +rkisp1_ipa_algorithms = files([ + 'algorithm.cpp', +]) diff --git a/src/ipa/rkisp1/meson.build b/src/ipa/rkisp1/meson.build index 3683c922..a6a4856e 100644 --- a/src/ipa/rkisp1/meson.build +++ b/src/ipa/rkisp1/meson.build @@ -1,4 +1,5 @@ # SPDX-License-Identifier: CC0-1.0 +subdir('algorithms') ipa_name = 'ipa_rkisp1' @@ -7,6 +8,8 @@ rkisp1_ipa_sources = files([ 'rkisp1.cpp', ]) +rkisp1_ipa_sources += rkisp1_ipa_algorithms + mod = shared_module(ipa_name, [rkisp1_ipa_sources, libcamera_generated_ipa_headers], name_prefix : '', diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index e0933e22..ddddd52d 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -25,7 +25,7 @@ #include -#include "ipa_context.h" +#include "algorithms/algorithm.h" #include "libipa/camera_sensor_helper.h" namespace libcamera { @@ -82,6 +82,9 @@ private: /* Local parameter storage */ struct IPAContext context_; + + /* Maintain the algorithms used by the IPA */ + std::list> algorithms_; }; int IPARkISP1::init([[maybe_unused]] const IPASettings &settings, From patchwork Fri Nov 19 11:16:51 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: 14654 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 39F74BF415 for ; Fri, 19 Nov 2021 11:17:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DEC9C6038C; Fri, 19 Nov 2021 12:17:06 +0100 (CET) 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="owIVwMwp"; 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 3C79160378 for ; Fri, 19 Nov 2021 12:17:00 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:db30:8e54:a96:9838]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F2EB71974; Fri, 19 Nov 2021 12:16:59 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1637320620; bh=1POXK+u/mwoOEr4kIx++HUgXWgdL4MWzdGGudHRC1IM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=owIVwMwpaB4DuWr/FlzrFfPq7BNNgAXVbQ2OY+Krt9auA+Vg0lK7s6tPgKwkDkHjG GvaAHaLOOEClfIR6/as7dWjWsxuX+6qsm0FbgNqXzoOEb/FBxBtOsat2EeooaNAwEb sSBJiUdhQalgBcK3ooJBqiVCpgP6c/eNcQwt+YQQ= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 19 Nov 2021 12:16:51 +0100 Message-Id: <20211119111654.68445-6-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> References: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 5/8] ipa: rkisp1: Report and use sensor controls 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 pipeline handler populates a new sensorControls ControlList, to have the effective exposure and gain values for the current frame. This is done when a statistics buffer is received. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- include/libcamera/ipa/rkisp1.mojom | 2 ++ src/ipa/rkisp1/rkisp1.cpp | 2 +- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/libcamera/ipa/rkisp1.mojom b/include/libcamera/ipa/rkisp1.mojom index a6991d4f..c3a6d8e1 100644 --- a/include/libcamera/ipa/rkisp1.mojom +++ b/include/libcamera/ipa/rkisp1.mojom @@ -21,11 +21,13 @@ struct RkISP1Event { uint32 frame; uint32 bufferId; libcamera.ControlList controls; + libcamera.ControlList sensorControls; }; struct RkISP1Action { RkISP1Operations op; libcamera.ControlList controls; + libcamera.ControlList sensorControls; }; interface IPARkISP1Interface { diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index ddddd52d..d2f4380a 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -313,7 +313,7 @@ void IPARkISP1::setControls(unsigned int frame) ControlList ctrls(ctrls_); ctrls.set(V4L2_CID_EXPOSURE, static_cast(exposure_)); ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast(gain_)); - op.controls = ctrls; + op.sensorControls = ctrls; queueFrameAction.emit(frame, op); } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index db8856d3..6e9f1dad 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -333,7 +333,7 @@ void RkISP1CameraData::queueFrameAction(unsigned int frame, { switch (action.op) { case ipa::rkisp1::ActionV4L2Set: { - const ControlList &controls = action.controls; + const ControlList &controls = action.sensorControls; delayedCtrls_->push(controls); break; } @@ -1125,6 +1125,7 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer) ev.op = ipa::rkisp1::EventSignalStatBuffer; ev.frame = info->frame; ev.bufferId = info->statBuffer->cookie(); + ev.sensorControls = data->delayedCtrls_->get(buffer->metadata().sequence); data->ipa_->processEvent(ev); } From patchwork Fri Nov 19 11:16:52 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: 14655 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 D0BEEC3251 for ; Fri, 19 Nov 2021 11:17:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8298860371; Fri, 19 Nov 2021 12:17:07 +0100 (CET) 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="GBWQXqXx"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 628616037A for ; Fri, 19 Nov 2021 12:17:00 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:db30:8e54:a96:9838]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2901C1C19; Fri, 19 Nov 2021 12:17:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1637320620; bh=ZWG9gX474vUUOgKnjwrRR35c6icXmt+2acx/eE8WtAo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GBWQXqXxXHIsqw9sCooHnbYVOF/ryr759JPvNkdbo7RIjBQ3Y5IVHVWle2CwYcwZS k6Qbu5KVGvtCJXvQC+DfxabwdeP3eSnGOgRR8HOIMI8NuhNCcHzAHiIqkDkCyO9Cnq 5Z6rYTczfxMxuxfuvA0M5B5osJsohwjQNoDW7Bm4= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 19 Nov 2021 12:16:52 +0100 Message-Id: <20211119111654.68445-7-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> References: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 6/8] ipa: rkisp1: Introduce 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" Now that we have IPAContext and Algorithm, we can implement a simple AGC based on the IPU3 one. It is very similar, except that there is no histogram used for an inter quantile mean. The RkISP1 is returning a 5x5 array (for V10) of luminance means. Estimating the relative luminance is thus a simple mean of all the blocks already calculated by the ISP. Signed-off-by: Jean-Michel Hautbois --- src/ipa/rkisp1/algorithms/agc.cpp | 249 ++++++++++++++++++++++++++ src/ipa/rkisp1/algorithms/agc.h | 55 ++++++ src/ipa/rkisp1/algorithms/meson.build | 1 + src/ipa/rkisp1/ipa_context.cpp | 44 +++++ src/ipa/rkisp1/ipa_context.h | 15 ++ src/ipa/rkisp1/rkisp1.cpp | 72 ++++---- 6 files changed, 401 insertions(+), 35 deletions(-) create mode 100644 src/ipa/rkisp1/algorithms/agc.cpp create mode 100644 src/ipa/rkisp1/algorithms/agc.h diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp new file mode 100644 index 00000000..3d4a17ff --- /dev/null +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -0,0 +1,249 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Ideas On Board + * + * agc.cpp - AGC/AEC mean-based control algorithm + */ + +#include "agc.h" + +#include +#include +#include + +#include + +#include + +/** + * \file agc.h + */ + +namespace libcamera { + +using namespace std::literals::chrono_literals; + +namespace ipa::rkisp1::algorithms { + +/** + * \class Agc + * \brief A mean-based auto-exposure algorithm + */ + +LOG_DEFINE_CATEGORY(RkISP1Agc) + +/* Limits for analogue gain values */ +static constexpr double kMinAnalogueGain = 1.0; +static constexpr double kMaxAnalogueGain = 8.0; + +/* \todo Honour the FrameDurationLimits control instead of hardcoding a limit */ +static constexpr utils::Duration kMaxShutterSpeed = 60ms; + +/* Number of frames to wait before calculating stats on minimum exposure */ +static constexpr uint32_t kNumStartupFrames = 10; + +/* Maximum luminance used for brightness normalization */ +static constexpr double kMaxLuminance = 255.0; + +/* + * Normalized luma value target. + * + * It's a number that's chosen so that, when the camera points at a grey + * target, the resulting image brightness is considered right. + */ +static constexpr double kNormalizedLumaTarget = 0.4; + +Agc::Agc() + : frameCount_(0), lineDuration_(0s), minShutterSpeed_(0s), + maxShutterSpeed_(0s), filteredExposure_(0s), currentExposure_(0s) +{ +} + +/** + * \brief Configure the AGC given a configInfo + * \param[in] context The shared IPA context + * \param[in] configInfo The IPA configuration data + * + * \return 0 + */ +int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) +{ + /* \todo use the IPAContext to provide the limits */ + lineDuration_ = configInfo.lineLength * 1.0s / configInfo.pixelRate; + + minShutterSpeed_ = context.configuration.agc.minShutterSpeed; + maxShutterSpeed_ = std::min(context.configuration.agc.maxShutterSpeed, + kMaxShutterSpeed); + + minAnalogueGain_ = std::max(context.configuration.agc.minAnalogueGain, kMinAnalogueGain); + maxAnalogueGain_ = std::min(context.configuration.agc.maxAnalogueGain, kMaxAnalogueGain); + + /* Configure the default exposure and gain. */ + context.frameContext.agc.gain = minAnalogueGain_; + context.frameContext.agc.exposure = 10ms / lineDuration_; + + return 0; +} + +/** + * \brief Apply a filter on the exposure value to limit the speed of changes + */ +void Agc::filterExposure() +{ + double speed = 0.2; + + /* Adapt instantly if we are in startup phase */ + if (frameCount_ < kNumStartupFrames) + speed = 1.0; + + if (filteredExposure_ == 0s) { + /* DG stands for digital gain.*/ + filteredExposure_ = currentExposure_; + } else { + /* + * If we are close to the desired result, go faster to avoid making + * multiple micro-adjustments. + * \todo Make this customisable? + */ + if (filteredExposure_ < 1.2 * currentExposure_ && + filteredExposure_ > 0.8 * currentExposure_) + speed = sqrt(speed); + + filteredExposure_ = speed * currentExposure_ + + filteredExposure_ * (1.0 - speed); + } + + LOG(RkISP1Agc, Debug) << "After filtering, total_exposure " << filteredExposure_; +} + +/** + * \brief Estimate the new exposure and gain values + * \param[inout] frameContext The shared IPA frame Context + * \param[in] currentYGain The gain calculated on the current brightness level + */ +void Agc::computeExposure(IPAFrameContext &frameContext, double currentYGain) +{ + /* Get the effective exposure and gain applied on the sensor. */ + uint32_t exposure = frameContext.sensor.exposure; + double analogueGain = frameContext.sensor.gain; + + /* Consider within 1% of the target as correctly exposed */ + if (std::abs(currentYGain - 1.0) < 0.01) + LOG(RkISP1Agc, Debug) << "We are well exposed (iqMean = " + << currentYGain << ")"; + + /* extracted from Rpi::Agc::computeTargetExposure */ + + /* Calculate the shutter time in seconds */ + utils::Duration currentShutter = exposure * lineDuration_; + + /* + * Update the exposure value for the next computation using the values + * of exposure and gain really used by the sensor. + */ + utils::Duration effectiveExposureValue = currentShutter * analogueGain; + + LOG(RkISP1Agc, Debug) << "Actual total exposure " << currentShutter * analogueGain + << " Shutter speed " << currentShutter + << " Gain " << analogueGain + << " Needed ev gain " << currentYGain; + + /* + * Calculate the current exposure value for the scene as the latest + * exposure value applied multiplied by the new estimated gain. + */ + currentExposure_ = effectiveExposureValue * currentYGain; + + /* Clamp the exposure value to the min and max authorized */ + utils::Duration maxTotalExposure = maxShutterSpeed_ * maxAnalogueGain_; + currentExposure_ = std::min(currentExposure_, maxTotalExposure); + LOG(RkISP1Agc, Debug) << "Target total exposure " << currentExposure_ + << ", maximum is " << maxTotalExposure; + + /* \todo: estimate if we need to desaturate */ + filterExposure(); + + /* Divide the exposure value as new exposure and gain values */ + utils::Duration exposureValue = filteredExposure_; + utils::Duration shutterTime; + + /* + * Push the shutter time up to the maximum first, and only then + * increase the gain. + */ + shutterTime = std::clamp(exposureValue / minAnalogueGain_, + minShutterSpeed_, maxShutterSpeed_); + double stepGain = std::clamp(exposureValue / shutterTime, + minAnalogueGain_, maxAnalogueGain_); + LOG(RkISP1Agc, Debug) << "Divided up shutter and gain are " + << shutterTime << " and " + << stepGain; + + /* Update the estimated exposure and gain. */ + frameContext.agc.exposure = shutterTime / lineDuration_; + frameContext.agc.gain = stepGain; +} + +/** + * \brief Estimate the average brightness of the frame + * \param[in] ae The RkISP1 statistics and ISP results + * \param[in] currentYGain The gain calculated on the current brightness level + * \return The normalized luma + */ +double Agc::computeInitialY(const rkisp1_cif_isp_ae_stat *ae, double currentYGain) +{ + double ySum = 0.0; + unsigned int num = 0; + + for (unsigned int aeCell = 0; aeCell < RKISP1_CIF_ISP_AE_MEAN_MAX_V10; aeCell++) { + ySum += ae->exp_mean[aeCell] * currentYGain; + num++; + } + + /* \todo Weight with the AWB gains */ + + /* Return the normalized relative luminance. */ + return ySum / num / kMaxLuminance; +} + +/** + * \brief Process RkISP1 statistics, and run AGC operations + * \param[in] context The shared IPA context + * \param[in] stats The RKIsp1 statistics and ISP results + * + * Identify the current image brightness, and use that to estimate the optimal + * new exposure and gain for the scene. + */ +void Agc::process(IPAContext &context, const rkisp1_stat_buffer *stats) +{ + const rkisp1_cif_isp_stat *params = &stats->params; + ASSERT(stats->meas_type & RKISP1_CIF_ISP_STAT_AUTOEXP); + + const rkisp1_cif_isp_ae_stat *ae = ¶ms->ae; + + double currentYGain = 1.0; + double targetY = kNormalizedLumaTarget; + + /* + * Do this calculation a few times as brightness increase can be + * non-linear when there are saturated regions. + */ + for (int i = 0; i < 8; i++) { + double initialY = computeInitialY(ae, currentYGain); + double extra_gain = std::min(10.0, targetY / (initialY + .001)); + + currentYGain *= extra_gain; + LOG(RkISP1Agc, Debug) << "Initial Y " << initialY + << " target " << targetY + << " gives gain " << currentYGain; + if (extra_gain < 1.01) + break; + } + + computeExposure(context.frameContext, currentYGain); + frameCount_++; +} + +} /* namespace ipa::rkisp1::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h new file mode 100644 index 00000000..fbb8ea98 --- /dev/null +++ b/src/ipa/rkisp1/algorithms/agc.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Ideas On Board + * + * agc.h - RkISP1 AGC/AEC mean-based control algorithm + */ +#ifndef __LIBCAMERA_RKISP1_ALGORITHMS_AGC_H__ +#define __LIBCAMERA_RKISP1_ALGORITHMS_AGC_H__ + +#include + +#include + +#include + +#include "algorithm.h" + +namespace libcamera { + +struct IPACameraSensorInfo; + +namespace ipa::rkisp1::algorithms { + +class Agc : public Algorithm +{ +public: + Agc(); + ~Agc() = default; + + int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override; + void process(IPAContext &context, const rkisp1_stat_buffer *stats) override; + +private: + void filterExposure(); + void computeExposure(IPAFrameContext &frameContext, double currentYGain); + double computeInitialY(const rkisp1_cif_isp_ae_stat *ae, double currentYGain); + + uint64_t frameCount_; + + utils::Duration lineDuration_; + utils::Duration minShutterSpeed_; + utils::Duration maxShutterSpeed_; + + double minAnalogueGain_; + double maxAnalogueGain_; + + utils::Duration filteredExposure_; + utils::Duration currentExposure_; +}; + +} /* namespace ipa::rkisp1::algorithms */ + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_RKISP1_ALGORITHMS_AGC_H__ */ diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build index d98f77e2..05195d99 100644 --- a/src/ipa/rkisp1/algorithms/meson.build +++ b/src/ipa/rkisp1/algorithms/meson.build @@ -1,5 +1,6 @@ # SPDX-License-Identifier: CC0-1.0 rkisp1_ipa_algorithms = files([ + 'agc.cpp', 'algorithm.cpp', ]) diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp index 819b2c73..16fc248f 100644 --- a/src/ipa/rkisp1/ipa_context.cpp +++ b/src/ipa/rkisp1/ipa_context.cpp @@ -55,4 +55,48 @@ namespace libcamera::ipa::rkisp1 { * are run. This needs to be turned into real per-frame data storage. */ +/** + * \var IPASessionConfiguration::agc + * \brief AGC parameters configuration of the IPA + * + * \var IPASessionConfiguration::agc.minShutterSpeed + * \brief Minimum shutter speed supported with the configured sensor + * + * \var IPASessionConfiguration::agc.maxShutterSpeed + * \brief Maximum shutter speed supported with the configured sensor + * + * \var IPASessionConfiguration::agc.minAnalogueGain + * \brief Minimum analogue gain supported with the configured sensor + * + * \var IPASessionConfiguration::agc.maxAnalogueGain + * \brief Maximum analogue gain supported with the configured sensor + */ + +/** + * \var IPAFrameContext::agc + * \brief Context for the Automatic Gain Control algorithm + * + * The exposure and gain determined are expected to be applied to the sensor + * at the earliest opportunity. + * + * \var IPAFrameContext::agc.exposure + * \brief Exposure time expressed as a number of lines + * + * \var IPAFrameContext::agc.gain + * \brief Analogue gain multiplier + * + * The gain should be adapted to the sensor specific gain code before applying. + */ + +/** + * \var IPAFrameContext::sensor + * \brief Effective sensor values + * + * \var IPAFrameContext::sensor.exposure + * \brief Exposure time expressed as a number of lines + * + * \var IPAFrameContext::sensor.gain + * \brief Analogue gain multiplier + */ + } /* namespace libcamera::ipa::rkisp1 */ diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index a1dc39fe..ca48ffc5 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -19,9 +19,24 @@ namespace libcamera { namespace ipa::rkisp1 { struct IPASessionConfiguration { + struct { + utils::Duration minShutterSpeed; + utils::Duration maxShutterSpeed; + double minAnalogueGain; + double maxAnalogueGain; + } agc; }; struct IPAFrameContext { + struct { + uint32_t exposure; + double gain; + } agc; + + struct { + uint32_t exposure; + double gain; + } sensor; }; struct IPAContext { diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index d2f4380a..1783f91f 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -25,6 +25,7 @@ #include +#include "algorithms/agc.h" #include "algorithms/algorithm.h" #include "libipa/camera_sensor_helper.h" @@ -32,6 +33,8 @@ namespace libcamera { LOG_DEFINE_CATEGORY(IPARkISP1) +using namespace std::literals::chrono_literals; + namespace ipa::rkisp1 { class IPARkISP1 : public IPARkISP1Interface @@ -77,6 +80,8 @@ private: unsigned int hwGammaOutMaxSamples_; unsigned int hwHistogramWeightGridsSize_; + utils::Duration lineDuration_; + /* Interface to the Camera Helper */ std::unique_ptr camHelper_; @@ -121,6 +126,9 @@ int IPARkISP1::init([[maybe_unused]] const IPASettings &settings, return -ENODEV; } + /* Construct our Algorithms */ + algorithms_.push_back(std::make_unique()); + return 0; } @@ -172,9 +180,29 @@ int IPARkISP1::configure([[maybe_unused]] const IPACameraSensorInfo &info, << "Exposure: " << minExposure_ << "-" << maxExposure_ << " Gain: " << minGain_ << "-" << maxGain_; + lineDuration_ = info.lineLength * 1.0s / info.pixelRate; + /* Clean context at configuration */ context_ = {}; + /* + * When the AGC computes the new exposure values for a frame, it needs + * to know the limits for shutter speed and analogue gain. + * As it depends on the sensor, update it with the controls. + * + * \todo take VBLANK into account for maximum shutter speed + */ + context_.configuration.agc.minShutterSpeed = minExposure_ * lineDuration_; + context_.configuration.agc.maxShutterSpeed = maxExposure_ * lineDuration_; + context_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain_); + context_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain_); + + for (auto const &algo : algorithms_) { + int ret = algo->configure(context_, info); + if (ret) + return ret; + } + return 0; } @@ -219,6 +247,9 @@ void IPARkISP1::processEvent(const RkISP1Event &event) reinterpret_cast( mappedBuffers_.at(bufferId).planes()[0].data()); + context_.frameContext.sensor.exposure = event.sensorControls.get(V4L2_CID_EXPOSURE).get(); + context_.frameContext.sensor.gain = camHelper_->gain(event.sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get()); + updateStatistics(frame, stats); break; } @@ -263,44 +294,12 @@ void IPARkISP1::queueRequest(unsigned int frame, rkisp1_params_cfg *params, void IPARkISP1::updateStatistics(unsigned int frame, const rkisp1_stat_buffer *stats) { - const rkisp1_cif_isp_stat *params = &stats->params; unsigned int aeState = 0; - if (stats->meas_type & RKISP1_CIF_ISP_STAT_AUTOEXP) { - const rkisp1_cif_isp_ae_stat *ae = ¶ms->ae; - - const unsigned int target = 60; + for (auto const &algo : algorithms_) + algo->process(context_, stats); - unsigned int value = 0; - unsigned int num = 0; - for (unsigned int i = 0; i < hwAeMeanMax_; i++) { - if (ae->exp_mean[i] <= 15) - continue; - - value += ae->exp_mean[i]; - num++; - } - value /= num; - - double factor = (double)target / value; - - if (frame % 3 == 0) { - double exposure; - - exposure = factor * exposure_ * gain_ / minGain_; - exposure_ = std::clamp((uint64_t)exposure, - minExposure_, - maxExposure_); - - exposure = exposure / exposure_ * minGain_; - gain_ = std::clamp((uint64_t)exposure, - minGain_, maxGain_); - - setControls(frame + 1); - } - - aeState = fabs(factor - 1.0f) < 0.05f ? 2 : 1; - } + setControls(frame + 1); metadataReady(frame, aeState); } @@ -310,6 +309,9 @@ void IPARkISP1::setControls(unsigned int frame) RkISP1Action op; op.op = ActionV4L2Set; + 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_)); From patchwork Fri Nov 19 11:16:53 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: 14656 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 801DEC324F for ; Fri, 19 Nov 2021 11:17:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 230B16037A; Fri, 19 Nov 2021 12:17:08 +0100 (CET) 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="jK32frfR"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9594A600B5 for ; Fri, 19 Nov 2021 12:17:00 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:db30:8e54:a96:9838]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 533911974; Fri, 19 Nov 2021 12:17:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1637320620; bh=IT0X6OYjckw+dbZKNhOIYk6zw8e46PKivGEmPAgA3eo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jK32frfReALCDzoiTpDIOZXbYaRayJY//b/2MkUrQc39fzD312VesN4GLEQSGGtqj E1jGEwKa3RaadYV6cXYaV7KxMT/oSvGrFbj05OjfGKp0fPsNYCqXkCrcHM+tf0f0es iby6FyyK5M0LzjPO9CER/+TSV2bYcGFbV+B68zoE= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 19 Nov 2021 12:16:53 +0100 Message-Id: <20211119111654.68445-8-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> References: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 7/8] ipa: rkisp1: agc: Introduce prepare call 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 parameter buffer needs to be queued, we need to specify which algorithm is activated or not in the ISP. Add a simple prepare function in AGC for that, which may later evolve to take the exposure locking into account. For that function to be called, we also need to add the loop on the algorithms in IPARkISP1::queueRequest. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Laurent Pinchart --- src/ipa/rkisp1/algorithms/agc.cpp | 7 +++++++ src/ipa/rkisp1/algorithms/agc.h | 1 + src/ipa/rkisp1/rkisp1.cpp | 12 +++--------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index 3d4a17ff..2b7c6fda 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -244,6 +244,13 @@ void Agc::process(IPAContext &context, const rkisp1_stat_buffer *stats) frameCount_++; } +void Agc::prepare([[maybe_unused]] IPAContext &context, + rkisp1_params_cfg *params) +{ + params->module_ens |= RKISP1_CIF_ISP_MODULE_AEC; + params->module_en_update |= RKISP1_CIF_ISP_MODULE_AEC; +} + } /* namespace ipa::rkisp1::algorithms */ } /* namespace libcamera */ diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h index fbb8ea98..934a455e 100644 --- a/src/ipa/rkisp1/algorithms/agc.h +++ b/src/ipa/rkisp1/algorithms/agc.h @@ -28,6 +28,7 @@ public: ~Agc() = default; int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override; + void prepare(IPAContext &context, rkisp1_params_cfg *params) override; void process(IPAContext &context, const rkisp1_stat_buffer *stats) override; private: diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 1783f91f..b1bfb8b6 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -271,19 +271,13 @@ void IPARkISP1::processEvent(const RkISP1Event &event) } void IPARkISP1::queueRequest(unsigned int frame, rkisp1_params_cfg *params, - const ControlList &controls) + [[maybe_unused]] const ControlList &controls) { /* Prepare parameters buffer. */ memset(params, 0, sizeof(*params)); - /* Auto Exposure on/off. */ - if (controls.contains(controls::AeEnable)) { - autoExposure_ = controls.get(controls::AeEnable); - if (autoExposure_) - params->module_ens = RKISP1_CIF_ISP_MODULE_AEC; - - params->module_en_update = RKISP1_CIF_ISP_MODULE_AEC; - } + for (auto const &algo : algorithms_) + algo->prepare(context_, params); RkISP1Action op; op.op = ActionParamFilled; From patchwork Fri Nov 19 11:16:54 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: 14657 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 29821C3252 for ; Fri, 19 Nov 2021 11:17:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B6202603EE; Fri, 19 Nov 2021 12:17:08 +0100 (CET) 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="Q27WfM9D"; 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 B5AB96038B for ; Fri, 19 Nov 2021 12:17:00 +0100 (CET) Received: from tatooine.ideasonboard.com (unknown [IPv6:2a01:e0a:169:7140:db30:8e54:a96:9838]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7C8E51C19; Fri, 19 Nov 2021 12:17:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1637320620; bh=IGZf8az6dw0g/aYVeYmxTWydcvz5Ff40gQQ8ccZ6U7Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Q27WfM9Dc+VDqO3NyyQ3ppkR6YsjmqBp5SlEJDzGHa3YuH5s0hRclWc1MjEzDfQV5 omKdJ+BRtearPBAU3DU8i3y8C7pm5rrSWMb58dNqLSZbl+t6ct4PvsOmbABAtmaUHB zdHItKJBbe2nliLTqxrxpCx6b8TxG8lTKsmeSvoM= From: Jean-Michel Hautbois To: libcamera-devel@lists.libcamera.org Date: Fri, 19 Nov 2021 12:16:54 +0100 Message-Id: <20211119111654.68445-9-jeanmichel.hautbois@ideasonboard.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> References: <20211119111654.68445-1-jeanmichel.hautbois@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 8/8] ipa: rkisp1: agc: Configure the number of cells used by HW 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 ISP can use 25 or 81 cells depending on its revision. Remove the cached value in IPARkISP1 and use IPASessionConfiguration to store it and pass it to AGC. Signed-off-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- src/ipa/ipu3/ipa_context.cpp | 3 +++ src/ipa/rkisp1/algorithms/agc.cpp | 4 +++- src/ipa/rkisp1/algorithms/agc.h | 2 ++ src/ipa/rkisp1/ipa_context.h | 1 + src/ipa/rkisp1/rkisp1.cpp | 5 ++--- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp index 99caf9ad..71a8619b 100644 --- a/src/ipa/ipu3/ipa_context.cpp +++ b/src/ipa/ipu3/ipa_context.cpp @@ -84,6 +84,9 @@ namespace libcamera::ipa::ipu3 { * * \var IPASessionConfiguration::grid.maxAnalogueGain * \brief Maximum analogue gain supported with the configured sensor + * + * \var IPASessionConfiguration::agc.numCells + * \brief Number of cells used by the ISP to store the Y means */ /** diff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp index 2b7c6fda..471cf584 100644 --- a/src/ipa/rkisp1/algorithms/agc.cpp +++ b/src/ipa/rkisp1/algorithms/agc.cpp @@ -82,6 +82,8 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo) context.frameContext.agc.gain = minAnalogueGain_; context.frameContext.agc.exposure = 10ms / lineDuration_; + numCells_ = context.configuration.agc.numCells; + return 0; } @@ -195,7 +197,7 @@ double Agc::computeInitialY(const rkisp1_cif_isp_ae_stat *ae, double currentYGai double ySum = 0.0; unsigned int num = 0; - for (unsigned int aeCell = 0; aeCell < RKISP1_CIF_ISP_AE_MEAN_MAX_V10; aeCell++) { + for (unsigned int aeCell = 0; aeCell < numCells_; aeCell++) { ySum += ae->exp_mean[aeCell] * currentYGain; num++; } diff --git a/src/ipa/rkisp1/algorithms/agc.h b/src/ipa/rkisp1/algorithms/agc.h index 934a455e..f4293035 100644 --- a/src/ipa/rkisp1/algorithms/agc.h +++ b/src/ipa/rkisp1/algorithms/agc.h @@ -45,6 +45,8 @@ private: double minAnalogueGain_; double maxAnalogueGain_; + uint32_t numCells_; + utils::Duration filteredExposure_; utils::Duration currentExposure_; }; diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index ca48ffc5..e8e1dc47 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -24,6 +24,7 @@ struct IPASessionConfiguration { utils::Duration maxShutterSpeed; double minAnalogueGain; double maxAnalogueGain; + uint32_t numCells; } agc; }; diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index b1bfb8b6..cebf2c65 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -75,7 +75,6 @@ private: uint32_t maxGain_; /* revision-specific data */ - unsigned int hwAeMeanMax_; unsigned int hwHistBinNMax_; unsigned int hwGammaOutMaxSamples_; unsigned int hwHistogramWeightGridsSize_; @@ -98,13 +97,13 @@ int IPARkISP1::init([[maybe_unused]] const IPASettings &settings, /* \todo Add support for other revisions */ switch (hwRevision) { case RKISP1_V10: - hwAeMeanMax_ = RKISP1_CIF_ISP_AE_MEAN_MAX_V10; + context_.configuration.agc.numCells = RKISP1_CIF_ISP_AE_MEAN_MAX_V10; hwHistBinNMax_ = RKISP1_CIF_ISP_HIST_BIN_N_MAX_V10; hwGammaOutMaxSamples_ = RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10; hwHistogramWeightGridsSize_ = RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V10; break; case RKISP1_V12: - hwAeMeanMax_ = RKISP1_CIF_ISP_AE_MEAN_MAX_V12; + context_.configuration.agc.numCells = RKISP1_CIF_ISP_AE_MEAN_MAX_V12; hwHistBinNMax_ = RKISP1_CIF_ISP_HIST_BIN_N_MAX_V12; hwGammaOutMaxSamples_ = RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V12; hwHistogramWeightGridsSize_ = RKISP1_CIF_ISP_HISTOGRAM_WEIGHT_GRIDS_SIZE_V12;