Patch Detail
Show a patch.
GET /api/1.1/patches/21186/?format=api
{ "id": 21186, "url": "https://patchwork.libcamera.org/api/1.1/patches/21186/?format=api", "web_url": "https://patchwork.libcamera.org/patch/21186/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/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": "<20240906120927.4071508-14-mzamazal@redhat.com>", "date": "2024-09-06T12:09:22", "name": "[v6,13/18] libcamera: software_isp: Move black level to an algorithm module", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "453cbbd2b6c9d19d81a498fb9275efbc0a613709", "submitter": { "id": 177, "url": "https://patchwork.libcamera.org/api/1.1/people/177/?format=api", "name": "Milan Zamazal", "email": "mzamazal@redhat.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/21186/mbox/", "series": [ { "id": 4566, "url": "https://patchwork.libcamera.org/api/1.1/series/4566/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4566", "date": "2024-09-06T12:09:09", "name": "Software ISP refactoring", "version": 6, "mbox": "https://patchwork.libcamera.org/series/4566/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/21186/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/21186/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 7B8E2BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 6 Sep 2024 12:10:44 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EA394634FD;\n\tFri, 6 Sep 2024 14:10:43 +0200 (CEST)", "from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9EE2D634F1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 6 Sep 2024 14:10:27 +0200 (CEST)", "from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com\n\t(ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63])\n\tby relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n\tcipher=TLS_AES_256_GCM_SHA384) id us-mta-678-d4ae-EcZMSC0cFKbCkkbSg-1;\n\tFri, 06 Sep 2024 08:10:21 -0400", "from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com\n\t[10.30.177.15])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (2048 bits)\n\tserver-digest SHA256) (No client certificate requested)\n\tby mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTPS id 903F41955DDC; Fri, 6 Sep 2024 12:10:20 +0000 (UTC)", "from nuthatch.redhat.com (unknown [10.45.224.65])\n\tby mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id 451D11956086; Fri, 6 Sep 2024 12:10:17 +0000 (UTC)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"NDuPuRBm\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1725624626;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tcontent-transfer-encoding:content-transfer-encoding:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=v3hbskSj10Sebk+q4Ui2FQh35wFYE0OLZnvkVpq2zc8=;\n\tb=NDuPuRBmkBdWHL/Zq7UHw4c3wAaYKy+tVIQSJVN57ItLQPXvZXJzVjGDFCZShxA+OZNkRT\n\tmpiuwX6r4kgr71FIaOJG26UnJ51KmbhUINKWXLmYApBHRUg+BrJnUtxgcBjaHW05mEvWx6\n\tA5Dn73jsVNBPzfC0s4SbeE0lPVq8odM=", "X-MC-Unique": "d4ae-EcZMSC0cFKbCkkbSg-1", "From": "Milan Zamazal <mzamazal@redhat.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Milan Zamazal <mzamazal@redhat.com>,\n\tUmang Jain <umang.jain@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tDaniel Scally <dan.scally@ideasonboard.com>", "Subject": "[PATCH v6 13/18] libcamera: software_isp: Move black level to an\n\talgorithm module", "Date": "Fri, 6 Sep 2024 14:09:22 +0200", "Message-ID": "<20240906120927.4071508-14-mzamazal@redhat.com>", "In-Reply-To": "<20240906120927.4071508-1-mzamazal@redhat.com>", "References": "<20240906120927.4071508-1-mzamazal@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.15", "X-Mimecast-Spam-Score": "0", "X-Mimecast-Originator": "redhat.com", "Content-Transfer-Encoding": "8bit", "Content-Type": "text/plain; charset=\"US-ASCII\"; x-default=true", "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": "The black level determination, already present as a separate class, can\nbe moved to the prepared Algorithm processing structure. It is the\nfirst of the current software ISP algorithms that is called in the stats\nprocessing sequence, which means it is also the first one that should be\nmoved to the new structure. Stats processing starts with calling\nAlgorithm-based processing so the call order of the algorithms is\nretained.\n\nMovement of this algorithm is relatively straightforward because all it\ndoes is processing stats.\n\nThe comment about getting black level from the tuning files is dropped.\nThe black level will be taken from CameraSensorHelper if available and\nthat will be implemented in one of the followup patches.\n\nBlack level is now recomputed on each stats processing. In a future\npatch, after DelayedControls are used, this will be changed to recompute\nthe black level only after exposure/gain changes.\n\nThe black level depends on the sensor used, the computed value can be\nreused in a followup capture sessions with the same sensor. Thus it is\nsufficient to (re)set the initial value in BlackLevel::init.\n\nSigned-off-by: Milan Zamazal <mzamazal@redhat.com>\nReviewed-by: Umang Jain <umang.jain@ideasonboard.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n src/ipa/simple/algorithms/blc.cpp | 71 ++++++++++++++++++++\n src/ipa/simple/algorithms/blc.h | 32 +++++++++\n src/ipa/simple/algorithms/meson.build | 1 +\n src/ipa/simple/black_level.cpp | 93 ---------------------------\n src/ipa/simple/black_level.h | 33 ----------\n src/ipa/simple/data/uncalibrated.yaml | 1 +\n src/ipa/simple/ipa_context.cpp | 8 +++\n src/ipa/simple/ipa_context.h | 5 ++\n src/ipa/simple/meson.build | 1 -\n src/ipa/simple/soft_simple.cpp | 8 +--\n 10 files changed, 120 insertions(+), 133 deletions(-)\n create mode 100644 src/ipa/simple/algorithms/blc.cpp\n create mode 100644 src/ipa/simple/algorithms/blc.h\n delete mode 100644 src/ipa/simple/black_level.cpp\n delete mode 100644 src/ipa/simple/black_level.h", "diff": "diff --git a/src/ipa/simple/algorithms/blc.cpp b/src/ipa/simple/algorithms/blc.cpp\nnew file mode 100644\nindex 00000000..08f4345e\n--- /dev/null\n+++ b/src/ipa/simple/algorithms/blc.cpp\n@@ -0,0 +1,71 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2024, Red Hat Inc.\n+ *\n+ * Black level handling\n+ */\n+\n+#include \"blc.h\"\n+\n+#include <numeric>\n+\n+#include <libcamera/base/log.h>\n+\n+namespace libcamera {\n+\n+namespace ipa::soft::algorithms {\n+\n+LOG_DEFINE_CATEGORY(IPASoftBL)\n+\n+BlackLevel::BlackLevel()\n+{\n+}\n+\n+int BlackLevel::init(IPAContext &context,\n+\t\t [[maybe_unused]] const YamlObject &tuningData)\n+{\n+\tcontext.activeState.blc.level = 255;\n+\treturn 0;\n+}\n+\n+void BlackLevel::process(IPAContext &context,\n+\t\t\t [[maybe_unused]] const uint32_t frame,\n+\t\t\t [[maybe_unused]] IPAFrameContext &frameContext,\n+\t\t\t const SwIspStats *stats,\n+\t\t\t [[maybe_unused]] ControlList &metadata)\n+{\n+\tconst SwIspStats::Histogram &histogram = stats->yHistogram;\n+\n+\t/*\n+\t * The constant is selected to be \"good enough\", not overly\n+\t * conservative or aggressive. There is no magic about the given value.\n+\t */\n+\tconstexpr float ignoredPercentage = 0.02;\n+\tconst unsigned int total =\n+\t\tstd::accumulate(begin(histogram), end(histogram), 0);\n+\tconst unsigned int pixelThreshold = ignoredPercentage * total;\n+\tconst unsigned int histogramRatio = 256 / SwIspStats::kYHistogramSize;\n+\tconst unsigned int currentBlackIdx =\n+\t\tcontext.activeState.blc.level / histogramRatio;\n+\n+\tfor (unsigned int i = 0, seen = 0;\n+\t i < currentBlackIdx && i < SwIspStats::kYHistogramSize;\n+\t i++) {\n+\t\tseen += histogram[i];\n+\t\tif (seen >= pixelThreshold) {\n+\t\t\tcontext.activeState.blc.level = i * histogramRatio;\n+\t\t\tLOG(IPASoftBL, Debug)\n+\t\t\t\t<< \"Auto-set black level: \"\n+\t\t\t\t<< i << \"/\" << SwIspStats::kYHistogramSize\n+\t\t\t\t<< \" (\" << 100 * (seen - histogram[i]) / total << \"% below, \"\n+\t\t\t\t<< 100 * seen / total << \"% at or below)\";\n+\t\t\tbreak;\n+\t\t}\n+\t};\n+}\n+\n+REGISTER_IPA_ALGORITHM(BlackLevel, \"BlackLevel\")\n+\n+} /* namespace ipa::soft::algorithms */\n+\n+} /* namespace libcamera */\ndiff --git a/src/ipa/simple/algorithms/blc.h b/src/ipa/simple/algorithms/blc.h\nnew file mode 100644\nindex 00000000..c2140b4b\n--- /dev/null\n+++ b/src/ipa/simple/algorithms/blc.h\n@@ -0,0 +1,32 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2024, Red Hat Inc.\n+ *\n+ * Black level handling\n+ */\n+\n+#pragma once\n+\n+#include \"algorithm.h\"\n+\n+namespace libcamera {\n+\n+namespace ipa::soft::algorithms {\n+\n+class BlackLevel : public Algorithm\n+{\n+public:\n+\tBlackLevel();\n+\t~BlackLevel() = default;\n+\n+\tint init(IPAContext &context, const YamlObject &tuningData)\n+\t\toverride;\n+\tvoid process(IPAContext &context, const uint32_t frame,\n+\t\t IPAFrameContext &frameContext,\n+\t\t const SwIspStats *stats,\n+\t\t ControlList &metadata) override;\n+};\n+\n+} /* namespace ipa::soft::algorithms */\n+\n+} /* namespace libcamera */\ndiff --git a/src/ipa/simple/algorithms/meson.build b/src/ipa/simple/algorithms/meson.build\nindex 31d26e43..1f63c220 100644\n--- a/src/ipa/simple/algorithms/meson.build\n+++ b/src/ipa/simple/algorithms/meson.build\n@@ -1,4 +1,5 @@\n # SPDX-License-Identifier: CC0-1.0\n \n soft_simple_ipa_algorithms = files([\n+ 'blc.cpp',\n ])\ndiff --git a/src/ipa/simple/black_level.cpp b/src/ipa/simple/black_level.cpp\ndeleted file mode 100644\nindex 37e0109c..00000000\n--- a/src/ipa/simple/black_level.cpp\n+++ /dev/null\n@@ -1,93 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2024, Red Hat Inc.\n- *\n- * black level handling\n- */\n-\n-#include \"black_level.h\"\n-\n-#include <numeric>\n-\n-#include <libcamera/base/log.h>\n-\n-namespace libcamera {\n-\n-LOG_DEFINE_CATEGORY(IPASoftBL)\n-\n-namespace ipa::soft {\n-\n-/**\n- * \\class BlackLevel\n- * \\brief Object providing black point level for software ISP\n- *\n- * Black level can be provided in hardware tuning files or, if no tuning file is\n- * available for the given hardware, guessed automatically, with less accuracy.\n- * As tuning files are not yet implemented for software ISP, BlackLevel\n- * currently provides only guessed black levels.\n- *\n- * This class serves for tracking black level as a property of the underlying\n- * hardware, not as means of enhancing a particular scene or image.\n- *\n- * The class is supposed to be instantiated for the given camera stream.\n- * The black level can be retrieved using BlackLevel::get() method. It is\n- * initially 0 and may change when updated using BlackLevel::update() method.\n- */\n-\n-BlackLevel::BlackLevel()\n-\t: blackLevel_(255), blackLevelSet_(false)\n-{\n-}\n-\n-/**\n- * \\brief Return the current black level\n- *\n- * \\return The black level, in the range from 0 (minimum) to 255 (maximum).\n- * If the black level couldn't be determined yet, return 0.\n- */\n-uint8_t BlackLevel::get() const\n-{\n-\treturn blackLevelSet_ ? blackLevel_ : 0;\n-}\n-\n-/**\n- * \\brief Update black level from the provided histogram\n- * \\param[in] yHistogram The histogram to be used for updating black level\n- *\n- * The black level is property of the given hardware, not image. It is updated\n- * only if it has not been yet set or if it is lower than the lowest value seen\n- * so far.\n- */\n-void BlackLevel::update(SwIspStats::Histogram &yHistogram)\n-{\n-\t/*\n-\t * The constant is selected to be \"good enough\", not overly conservative or\n-\t * aggressive. There is no magic about the given value.\n-\t */\n-\tconstexpr float ignoredPercentage_ = 0.02;\n-\tconst unsigned int total =\n-\t\tstd::accumulate(begin(yHistogram), end(yHistogram), 0);\n-\tconst unsigned int pixelThreshold = ignoredPercentage_ * total;\n-\tconst unsigned int histogramRatio = 256 / SwIspStats::kYHistogramSize;\n-\tconst unsigned int currentBlackIdx = blackLevel_ / histogramRatio;\n-\n-\tfor (unsigned int i = 0, seen = 0;\n-\t i < currentBlackIdx && i < SwIspStats::kYHistogramSize;\n-\t i++) {\n-\t\tseen += yHistogram[i];\n-\t\tif (seen >= pixelThreshold) {\n-\t\t\tblackLevel_ = i * histogramRatio;\n-\t\t\tblackLevelSet_ = true;\n-\t\t\tLOG(IPASoftBL, Debug)\n-\t\t\t\t<< \"Auto-set black level: \"\n-\t\t\t\t<< i << \"/\" << SwIspStats::kYHistogramSize\n-\t\t\t\t<< \" (\" << 100 * (seen - yHistogram[i]) / total << \"% below, \"\n-\t\t\t\t<< 100 * seen / total << \"% at or below)\";\n-\t\t\tbreak;\n-\t\t}\n-\t};\n-}\n-\n-} /* namespace ipa::soft */\n-\n-} /* namespace libcamera */\ndiff --git a/src/ipa/simple/black_level.h b/src/ipa/simple/black_level.h\ndeleted file mode 100644\nindex a04230c9..00000000\n--- a/src/ipa/simple/black_level.h\n+++ /dev/null\n@@ -1,33 +0,0 @@\n-/* SPDX-License-Identifier: LGPL-2.1-or-later */\n-/*\n- * Copyright (C) 2024, Red Hat Inc.\n- *\n- * black level handling\n- */\n-\n-#pragma once\n-\n-#include <array>\n-#include <stdint.h>\n-\n-#include \"libcamera/internal/software_isp/swisp_stats.h\"\n-\n-namespace libcamera {\n-\n-namespace ipa::soft {\n-\n-class BlackLevel\n-{\n-public:\n-\tBlackLevel();\n-\tuint8_t get() const;\n-\tvoid update(SwIspStats::Histogram &yHistogram);\n-\n-private:\n-\tuint8_t blackLevel_;\n-\tbool blackLevelSet_;\n-};\n-\n-} /* namespace ipa::soft */\n-\n-} /* namespace libcamera */\ndiff --git a/src/ipa/simple/data/uncalibrated.yaml b/src/ipa/simple/data/uncalibrated.yaml\nindex 2cdc39a8..e0d03d96 100644\n--- a/src/ipa/simple/data/uncalibrated.yaml\n+++ b/src/ipa/simple/data/uncalibrated.yaml\n@@ -3,4 +3,5 @@\n ---\n version: 1\n algorithms:\n+ - BlackLevel:\n ...\ndiff --git a/src/ipa/simple/ipa_context.cpp b/src/ipa/simple/ipa_context.cpp\nindex 3c1c7262..268cff32 100644\n--- a/src/ipa/simple/ipa_context.cpp\n+++ b/src/ipa/simple/ipa_context.cpp\n@@ -50,4 +50,12 @@ namespace libcamera::ipa::soft {\n * \\brief The current state of IPA algorithms\n */\n \n+/**\n+ * \\var IPAActiveState::black\n+ * \\brief Context for the Black Level algorithm\n+ *\n+ * \\var IPAActiveState::black.level\n+ * \\brief Current determined black level\n+ */\n+\n } /* namespace libcamera::ipa::soft */\ndiff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\nindex e7d8b8df..ac2a59d7 100644\n--- a/src/ipa/simple/ipa_context.h\n+++ b/src/ipa/simple/ipa_context.h\n@@ -7,6 +7,8 @@\n \n #pragma once\n \n+#include <stdint.h>\n+\n #include <libipa/fc_queue.h>\n \n namespace libcamera {\n@@ -17,6 +19,9 @@ struct IPASessionConfiguration {\n };\n \n struct IPAActiveState {\n+\tstruct {\n+\t\tuint8_t level;\n+\t} blc;\n };\n \n struct IPAFrameContext : public FrameContext {\ndiff --git a/src/ipa/simple/meson.build b/src/ipa/simple/meson.build\nindex dcd7c70a..2f9f15f4 100644\n--- a/src/ipa/simple/meson.build\n+++ b/src/ipa/simple/meson.build\n@@ -8,7 +8,6 @@ ipa_name = 'ipa_soft_simple'\n soft_simple_sources = files([\n 'ipa_context.cpp',\n 'soft_simple.cpp',\n- 'black_level.cpp',\n ])\n \n soft_simple_sources += soft_simple_ipa_algorithms\ndiff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp\nindex 5beec45a..3332e2b1 100644\n--- a/src/ipa/simple/soft_simple.cpp\n+++ b/src/ipa/simple/soft_simple.cpp\n@@ -29,7 +29,6 @@\n \n #include \"libipa/camera_sensor_helper.h\"\n \n-#include \"black_level.h\"\n #include \"module.h\"\n \n namespace libcamera {\n@@ -61,7 +60,7 @@ class IPASoftSimple : public ipa::soft::IPASoftInterface, public Module\n {\n public:\n \tIPASoftSimple()\n-\t\t: params_(nullptr), stats_(nullptr), blackLevel_(BlackLevel()),\n+\t\t: params_(nullptr), stats_(nullptr),\n \t\t context_({ {}, {}, { kMaxFrameContexts } }),\n \t\t ignoreUpdates_(0)\n \t{\n@@ -93,7 +92,6 @@ private:\n \tSwIspStats *stats_;\n \tstd::unique_ptr<CameraSensorHelper> camHelper_;\n \tControlInfoMap sensorInfoMap_;\n-\tBlackLevel blackLevel_;\n \n \tstatic constexpr unsigned int kGammaLookupSize = 1024;\n \tstd::array<uint8_t, kGammaLookupSize> gammaTable_;\n@@ -303,9 +301,7 @@ void IPASoftSimple::processStats(const uint32_t frame,\n \t\talgo->process(context_, frame, frameContext, stats_, metadata);\n \n \tSwIspStats::Histogram histogram = stats_->yHistogram;\n-\tif (ignoreUpdates_ > 0)\n-\t\tblackLevel_.update(histogram);\n-\tconst uint8_t blackLevel = blackLevel_.get();\n+\tconst uint8_t blackLevel = context_.activeState.blc.level;\n \n \t/*\n \t * Black level must be subtracted to get the correct AWB ratios, they\n", "prefixes": [ "v6", "13/18" ] }