Patch Detail
Show a patch.
GET /api/patches/20208/?format=api
{ "id": 20208, "url": "https://patchwork.libcamera.org/api/patches/20208/?format=api", "web_url": "https://patchwork.libcamera.org/patch/20208/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20240605095417.157703-4-stefan.klug@ideasonboard.com>", "date": "2024-06-05T09:53:51", "name": "[v4,3/3] ipa: rkisp1: Add GammaOutCorrection algorithm", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "72ce472b96892f6e21cfed08be082978a6805100", "submitter": { "id": 184, "url": "https://patchwork.libcamera.org/api/people/184/?format=api", "name": "Stefan Klug", "email": "stefan.klug@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/20208/mbox/", "series": [ { "id": 4363, "url": "https://patchwork.libcamera.org/api/series/4363/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4363", "date": "2024-06-05T09:53:48", "name": "libcamera: Add gamma control for rkisp1", "version": 4, "mbox": "https://patchwork.libcamera.org/series/4363/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/20208/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/20208/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id EEB99BDE6B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 5 Jun 2024 09:54:34 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A2FD465443;\n\tWed, 5 Jun 2024 11:54:34 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 09DA265445\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 5 Jun 2024 11:54:32 +0200 (CEST)", "from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:dcc4:f2dc:93ce:ff8f])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AF9C614B0;\n\tWed, 5 Jun 2024 11:54:23 +0200 (CEST)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"SARCiVdu\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1717581263;\n\tbh=qKxgbKMZ1FO1tyf5cBYxHEBbBz4b5IC6T96rmOyMbe8=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=SARCiVduuX5upNR97u0/wE2D6Dhi96Sk8T0xl73jFPe5LCDNGwrE7VDyzREUfPz2Q\n\tfLvIC8E19Jq6cRr2b2Ntl23E62+OVeIs0yFNVXPYWsFsZjFPlxxLQ9Pv3pNEdmFxOX\n\t0i2Z44AueJMAzVJsqYwFjwqyEQlSCw9cIsf8eAds=", "From": "Stefan Klug <stefan.klug@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Stefan Klug <stefan.klug@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>", "Subject": "[PATCH v4 3/3] ipa: rkisp1: Add GammaOutCorrection algorithm", "Date": "Wed, 5 Jun 2024 11:53:51 +0200", "Message-ID": "<20240605095417.157703-4-stefan.klug@ideasonboard.com>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<20240605095417.157703-1-stefan.klug@ideasonboard.com>", "References": "<20240605095417.157703-1-stefan.klug@ideasonboard.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "Add a gamma algorithm for the rkisp1. It defaults to a gamma of 2.2 which\nclosely resembles sRGB. No seperate sRGB mode was implemented because the pwl\nthat models the gamma curve is so coarse that there is basically no difference\nbetween srgb and gamma=2.2. The default can be overridden within the tuning\nfile or set at runtime using the gamma control.\n\nThe gamma algorithm is not enabled by default. This will be done in future\ntuning file updates.\n\nSigned-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n---\n src/ipa/rkisp1/algorithms/goc.cpp | 153 ++++++++++++++++++++++++++\n src/ipa/rkisp1/algorithms/goc.h | 42 +++++++\n src/ipa/rkisp1/algorithms/meson.build | 1 +\n src/ipa/rkisp1/ipa_context.h | 9 ++\n 4 files changed, 205 insertions(+)\n create mode 100644 src/ipa/rkisp1/algorithms/goc.cpp\n create mode 100644 src/ipa/rkisp1/algorithms/goc.h", "diff": "diff --git a/src/ipa/rkisp1/algorithms/goc.cpp b/src/ipa/rkisp1/algorithms/goc.cpp\nnew file mode 100644\nindex 000000000000..ab634c1c9709\n--- /dev/null\n+++ b/src/ipa/rkisp1/algorithms/goc.cpp\n@@ -0,0 +1,153 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2024, Ideas On Board\n+ *\n+ * RkISP1 Gamma out control\n+ */\n+#include \"goc.h\"\n+\n+#include <cmath>\n+\n+#include <libcamera/base/log.h>\n+#include <libcamera/base/utils.h>\n+\n+#include <libcamera/control_ids.h>\n+\n+#include \"libcamera/internal/yaml_parser.h\"\n+\n+#include \"linux/rkisp1-config.h\"\n+\n+/**\n+ * \\file goc.h\n+ */\n+\n+namespace libcamera {\n+\n+namespace ipa::rkisp1::algorithms {\n+\n+/**\n+ * \\class GammaOutCorrection\n+ * \\brief RkISP1 Gamma out correction\n+ *\n+ * This algorithm implements the gamma out curve for the RkISP1.\n+ * It defaults to a gamma value of 2.2\n+ * As gamma is internally represented as a piecewise linear function with only\n+ * 17 knots, the difference between gamma=2.2 and sRGB gamma is minimal.\n+ * Therefore sRGB gamma was not implemented as special case.\n+ *\n+ * Useful links:\n+ * https://www.cambridgeincolour.com/tutorials/gamma-correction.htm\n+ * https://en.wikipedia.org/wiki/SRGB\n+ */\n+\n+LOG_DEFINE_CATEGORY(RkISP1Gamma)\n+\n+const float kDefaultGamma = 2.2f;\n+\n+/**\n+ * \\copydoc libcamera::ipa::Algorithm::init\n+ */\n+int GammaOutCorrection::init([[maybe_unused]] IPAContext &context,\n+\t\t\t [[maybe_unused]] const YamlObject &tuningData)\n+{\n+\tif (context.hw->numGammaOutSamples !=\n+\t RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10) {\n+\t\tLOG(RkISP1Gamma, Error)\n+\t\t\t<< \"Gamma is not implemented for RkISP1 V12\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tcontext.ctrlMap[&controls::Gamma] = ControlInfo(0.1f, 10.0f, kDefaultGamma);\n+\tdefaultGamma_ = tuningData[\"gamma\"].get<double>(kDefaultGamma);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * \\brief Configure the Gamma given a configInfo\n+ * \\param[in] context The shared IPA context\n+ * \\param[in] configInfo The IPA configuration data\n+ *\n+ * \\return 0\n+ */\n+int GammaOutCorrection::configure(IPAContext &context,\n+\t\t\t\t [[maybe_unused]] const IPACameraSensorInfo &configInfo)\n+{\n+\tcontext.activeState.goc.gamma = defaultGamma_;\n+\treturn 0;\n+}\n+\n+/**\n+ * \\copydoc libcamera::ipa::Algorithm::queueRequest\n+ */\n+void GammaOutCorrection::queueRequest([[maybe_unused]] IPAContext &context,\n+\t\t\t\t [[maybe_unused]] const uint32_t frame,\n+\t\t\t\t IPAFrameContext &frameContext,\n+\t\t\t\t const ControlList &controls)\n+{\n+\tif (frame == 0)\n+\t\tframeContext.goc.update = true;\n+\n+\tconst auto &gamma = controls.get(controls::Gamma);\n+\tif (gamma) {\n+\t\tcontext.activeState.goc.gamma = *gamma;\n+\t\tframeContext.goc.update = true;\n+\t\tLOG(RkISP1Gamma, Debug) << \"Set gamma to \" << *gamma;\n+\t}\n+\n+\tframeContext.goc.gamma = context.activeState.goc.gamma;\n+}\n+\n+/**\n+ * \\copydoc libcamera::ipa::Algorithm::prepare\n+ */\n+void GammaOutCorrection::prepare([[maybe_unused]] IPAContext &context,\n+\t\t\t\t [[maybe_unused]] const uint32_t frame,\n+\t\t\t\t [[maybe_unused]] IPAFrameContext &frameContext,\n+\t\t\t\t rkisp1_params_cfg *params)\n+{\n+\tASSERT(context.hw->numGammaOutSamples ==\n+\t RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10);\n+\n+\t/*\n+\t * The logarithmic segments as specified in the reference.\n+\t * Plus an additional 0 to make the loop easier\n+\t */\n+\tstd::array<unsigned, RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES_V10> segments = {\n+\t\t64, 64, 64, 64, 128, 128, 128, 128, 256,\n+\t\t256, 256, 512, 512, 512, 512, 512, 0\n+\t};\n+\tauto gamma_y = params->others.goc_config.gamma_y;\n+\n+\tif (!frameContext.goc.update)\n+\t\treturn;\n+\n+\tunsigned x = 0;\n+\tfor (const auto [i, size] : utils::enumerate(segments)) {\n+\t\tgamma_y[i] = std::pow(x / 4096.0, 1.0 / frameContext.goc.gamma) * 1023.0;\n+\t\tx += size;\n+\t}\n+\n+\tparams->others.goc_config.mode = RKISP1_CIF_ISP_GOC_MODE_LOGARITHMIC;\n+\tparams->module_cfg_update |= RKISP1_CIF_ISP_MODULE_GOC;\n+\tparams->module_en_update |= RKISP1_CIF_ISP_MODULE_GOC;\n+\tparams->module_ens |= RKISP1_CIF_ISP_MODULE_GOC;\n+}\n+\n+/**\n+ * \\copydoc libcamera::ipa::Algorithm::process\n+ */\n+void GammaOutCorrection::process([[maybe_unused]] IPAContext &context,\n+\t\t\t\t [[maybe_unused]] const uint32_t frame,\n+\t\t\t\t IPAFrameContext &frameContext,\n+\t\t\t\t [[maybe_unused]] const rkisp1_stat_buffer *stats,\n+\t\t\t\t ControlList &metadata)\n+{\n+\tmetadata.set(controls::Gamma, frameContext.goc.gamma);\n+}\n+\n+REGISTER_IPA_ALGORITHM(GammaOutCorrection, \"GammaOutCorrection\")\n+\n+} /* namespace ipa::rkisp1::algorithms */\n+\n+} /* namespace libcamera */\ndiff --git a/src/ipa/rkisp1/algorithms/goc.h b/src/ipa/rkisp1/algorithms/goc.h\nnew file mode 100644\nindex 000000000000..3be8e500be67\n--- /dev/null\n+++ b/src/ipa/rkisp1/algorithms/goc.h\n@@ -0,0 +1,42 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2024, Ideas On Board\n+ *\n+ * RkISP1 Gamma out control\n+ */\n+\n+#pragma once\n+\n+#include \"algorithm.h\"\n+\n+namespace libcamera {\n+\n+namespace ipa::rkisp1::algorithms {\n+\n+class GammaOutCorrection : public Algorithm\n+{\n+public:\n+\tGammaOutCorrection() = default;\n+\t~GammaOutCorrection() = default;\n+\n+\tint init(IPAContext &context, const YamlObject &tuningData) override;\n+\tint configure(IPAContext &context,\n+\t\t const IPACameraSensorInfo &configInfo) override;\n+\tvoid queueRequest(IPAContext &context,\n+\t\t\t const uint32_t frame,\n+\t\t\t IPAFrameContext &frameContext,\n+\t\t\t const ControlList &controls) override;\n+\tvoid prepare(IPAContext &context, const uint32_t frame,\n+\t\t IPAFrameContext &frameContext,\n+\t\t rkisp1_params_cfg *params) override;\n+\tvoid process(IPAContext &context, const uint32_t frame,\n+\t\t IPAFrameContext &frameContext,\n+\t\t const rkisp1_stat_buffer *stats,\n+\t\t ControlList &metadata) override;\n+\n+private:\n+\tdouble defaultGamma_;\n+};\n+\n+} /* namespace ipa::rkisp1::algorithms */\n+} /* namespace libcamera */\ndiff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build\nindex 93a483292753..6ee71a9b5da3 100644\n--- a/src/ipa/rkisp1/algorithms/meson.build\n+++ b/src/ipa/rkisp1/algorithms/meson.build\n@@ -8,6 +8,7 @@ rkisp1_ipa_algorithms = files([\n 'dpcc.cpp',\n 'dpf.cpp',\n 'filter.cpp',\n+ 'goc.cpp',\n 'gsl.cpp',\n 'lsc.cpp',\n ])\ndiff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h\nindex bd02a7a24fdd..f261e42fc2fd 100644\n--- a/src/ipa/rkisp1/ipa_context.h\n+++ b/src/ipa/rkisp1/ipa_context.h\n@@ -104,6 +104,10 @@ struct IPAActiveState {\n \t\tuint8_t denoise;\n \t\tuint8_t sharpness;\n \t} filter;\n+\n+\tstruct {\n+\t\tdouble gamma;\n+\t} goc;\n };\n \n struct IPAFrameContext : public FrameContext {\n@@ -146,6 +150,11 @@ struct IPAFrameContext : public FrameContext {\n \t\tuint32_t exposure;\n \t\tdouble gain;\n \t} sensor;\n+\n+\tstruct {\n+\t\tdouble gamma;\n+\t\tbool update;\n+\t} goc;\n };\n \n struct IPAContext {\n", "prefixes": [ "v4", "3/3" ] }