Patch Detail
Show a patch.
GET /api/1.1/patches/19577/?format=api
{ "id": 19577, "url": "https://patchwork.libcamera.org/api/1.1/patches/19577/?format=api", "web_url": "https://patchwork.libcamera.org/patch/19577/", "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": "<20240229183654.7206-7-hdegoede@redhat.com>", "date": "2024-02-29T18:36:17", "name": "[v4,06/18] libcamera: software_isp: Add SwStatsCpu class", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "c6d37501259e0e865b642330963daa93d3f593c9", "submitter": { "id": 102, "url": "https://patchwork.libcamera.org/api/1.1/people/102/?format=api", "name": "Hans de Goede", "email": "hdegoede@redhat.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/19577/mbox/", "series": [ { "id": 4195, "url": "https://patchwork.libcamera.org/api/1.1/series/4195/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4195", "date": "2024-02-29T18:36:11", "name": "libcamera: introduce Software ISP and Software IPA", "version": 4, "mbox": "https://patchwork.libcamera.org/series/4195/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/19577/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/19577/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 D168BBD160\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 29 Feb 2024 18:37:15 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7697D62868;\n\tThu, 29 Feb 2024 19:37:15 +0100 (CET)", "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 506E962868\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 29 Feb 2024 19:37:13 +0100 (CET)", "from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73])\n\tby relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n\tcipher=TLS_AES_256_GCM_SHA384) id us-mta-408-fQHAZfKoOMSrZpbUrmO1Uw-1;\n\tThu, 29 Feb 2024 13:37:08 -0500", "from smtp.corp.redhat.com\n\t(int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7])\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 mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5D5B93C5CF23;\n\tThu, 29 Feb 2024 18:37:06 +0000 (UTC)", "from shalem.redhat.com (unknown [10.39.192.10])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id EF6491C060B1;\n\tThu, 29 Feb 2024 18:37:04 +0000 (UTC)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"HTolGNmb\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1709231832;\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=G6UPJKoTHTivwEjPrQmzRvX/gXaEW6vG+cGpIhqyd8M=;\n\tb=HTolGNmbexAeo+LSgKi4ZTDlXcXf/pNcrY2QMgFVK0WG95aFGOi8+FO7GCfZoaSVKl3df1\n\tEDX5dHXvLXvMi9WMlzASLrDosuUrlbd6hqRyQZxS4rrQNFZQU+fOGsqKCLB2kCtLNZ6BUG\n\tOPSus5PJ0fHGLz2Jxe3T8Ehvi0T59FI=", "X-MC-Unique": "fQHAZfKoOMSrZpbUrmO1Uw-1", "From": "Hans de Goede <hdegoede@redhat.com>", "To": "libcamera-devel@lists.libcamera.org", "Subject": "[PATCH v4 06/18] libcamera: software_isp: Add SwStatsCpu class", "Date": "Thu, 29 Feb 2024 19:36:17 +0100", "Message-ID": "<20240229183654.7206-7-hdegoede@redhat.com>", "In-Reply-To": "<20240229183654.7206-1-hdegoede@redhat.com>", "References": "<20240229183654.7206-1-hdegoede@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.4.1 on 10.11.54.7", "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>", "Cc": "Maxime Ripard <mripard@redhat.com>, Marttico <g.martti@gmail.com>,\n\tToon Langendam <t.langendam@gmail.com>, Pavel Machek <pavel@ucw.cz>, \n\tBryan O'Donoghue <bryan.odonoghue@linaro.org>,\n\tDennis Bonke <admin@dennisbonke.com>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "Add a CPU based SwStats implementation for SoftwareISP / SoftIPA use.\n\nThis implementation offers a configure function + functions to gather\nstatistics on a line by line basis. This allows CPU based software\ndebayering to call into interlace debayering and statistics gathering\non a line by line bases while the input data is still hot in the cache.\n\nThis implementation also allows specifying a window over which to gather\nstatistics instead of processing the whole frame.\n\nDoxygen documentation by Dennis Bonke.\n\nTested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s\nTested-by: Pavel Machek <pavel@ucw.cz>\nReviewed-by: Pavel Machek <pavel@ucw.cz>\nCo-developed-by: Andrey Konovalov <andrey.konovalov@linaro.org>\nSigned-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>\nCo-developed-by: Pavel Machek <pavel@ucw.cz>\nSigned-off-by: Pavel Machek <pavel@ucw.cz>\nCo-developed-by: Dennis Bonke <admin@dennisbonke.com>\nSigned-off-by: Dennis Bonke <admin@dennisbonke.com>\nCo-developed-by: Marttico <g.martti@gmail.com>\nSigned-off-by: Marttico <g.martti@gmail.com>\nCo-developed-by: Toon Langendam <t.langendam@gmail.com>\nSigned-off-by: Toon Langendam <t.langendam@gmail.com>\nSigned-off-by: Hans de Goede <hdegoede@redhat.com>\n---\nChanges in v3:\n- Merge SwStats base-class into SwStatsCpu\n- Move swstats_cpu.h to src/libcamera/software_isp/\n- Move documentation to .cpp file and extend it\n- Rename a bunch of foo_bar symbols to fooBar\n- Change a couple of defines and hardcoded values to constexpr\n- Remove statsBayer10P in swstats_cpu.cpp, instead move the loop to\n statsBGGR10PLine0 / statsGBRG10PLine0\n- Make startFrame() and finishFrame() normal methods instead of\n using function pointers for these\n---\n include/libcamera/internal/meson.build | 1 +\n .../internal/software_isp/meson.build | 5 +\n .../internal/software_isp/swisp_stats.h | 38 ++++\n src/libcamera/meson.build | 1 +\n src/libcamera/software_isp/meson.build | 5 +\n src/libcamera/software_isp/swstats_cpu.cpp | 208 ++++++++++++++++++\n src/libcamera/software_isp/swstats_cpu.h | 159 +++++++++++++\n 7 files changed, 417 insertions(+)\n create mode 100644 include/libcamera/internal/software_isp/meson.build\n create mode 100644 include/libcamera/internal/software_isp/swisp_stats.h\n create mode 100644 src/libcamera/software_isp/meson.build\n create mode 100644 src/libcamera/software_isp/swstats_cpu.cpp\n create mode 100644 src/libcamera/software_isp/swstats_cpu.h", "diff": "diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build\nindex 5807dfd9..160fdc37 100644\n--- a/include/libcamera/internal/meson.build\n+++ b/include/libcamera/internal/meson.build\n@@ -50,3 +50,4 @@ libcamera_internal_headers = files([\n ])\n \n subdir('converter')\n+subdir('software_isp')\ndiff --git a/include/libcamera/internal/software_isp/meson.build b/include/libcamera/internal/software_isp/meson.build\nnew file mode 100644\nindex 00000000..66c9c3fb\n--- /dev/null\n+++ b/include/libcamera/internal/software_isp/meson.build\n@@ -0,0 +1,5 @@\n+# SPDX-License-Identifier: CC0-1.0\n+\n+libcamera_internal_headers += files([\n+ 'swisp_stats.h',\n+])\ndiff --git a/include/libcamera/internal/software_isp/swisp_stats.h b/include/libcamera/internal/software_isp/swisp_stats.h\nnew file mode 100644\nindex 00000000..afe42c9a\n--- /dev/null\n+++ b/include/libcamera/internal/software_isp/swisp_stats.h\n@@ -0,0 +1,38 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2023, Linaro Ltd\n+ *\n+ * swisp_stats.h - Statistics data format used by the software ISP and software IPA\n+ */\n+\n+#pragma once\n+\n+namespace libcamera {\n+\n+/**\n+ * \\brief Struct that holds the statistics for the Software ISP.\n+ */\n+struct SwIspStats {\n+\t/**\n+\t * \\brief Holds the sum of all sampled red pixels.\n+\t */\n+\tunsigned long sumR_;\n+\t/**\n+\t * \\brief Holds the sum of all sampled green pixels.\n+\t */\n+\tunsigned long sumG_;\n+\t/**\n+\t * \\brief Holds the sum of all sampled blue pixels.\n+\t */\n+\tunsigned long sumB_;\n+\t/**\n+\t * \\brief Number of bins in the yHistogram.\n+\t */\n+\tstatic constexpr unsigned int kYHistogramSize = 16;\n+\t/**\n+\t * \\brief A histogram of luminance values.\n+\t */\n+\tstd::array<unsigned int, kYHistogramSize> yHistogram;\n+};\n+\n+} /* namespace libcamera */\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex 94a95ae3..91e4cc60 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -71,6 +71,7 @@ subdir('converter')\n subdir('ipa')\n subdir('pipeline')\n subdir('proxy')\n+subdir('software_isp')\n \n null_dep = dependency('', required : false)\n \ndiff --git a/src/libcamera/software_isp/meson.build b/src/libcamera/software_isp/meson.build\nnew file mode 100644\nindex 00000000..e1fb8ccc\n--- /dev/null\n+++ b/src/libcamera/software_isp/meson.build\n@@ -0,0 +1,5 @@\n+# SPDX-License-Identifier: CC0-1.0\n+\n+libcamera_sources += files([\n+ 'swstats_cpu.cpp',\n+])\ndiff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\nnew file mode 100644\nindex 00000000..448d0e4c\n--- /dev/null\n+++ b/src/libcamera/software_isp/swstats_cpu.cpp\n@@ -0,0 +1,208 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2023, Linaro Ltd\n+ * Copyright (C) 2023, Red Hat Inc.\n+ *\n+ * Authors:\n+ * Hans de Goede <hdegoede@redhat.com>\n+ *\n+ * swstats_cpu.cpp - CPU based software statistics implementation\n+ */\n+\n+#include \"swstats_cpu.h\"\n+\n+#include <libcamera/base/log.h>\n+\n+#include <libcamera/stream.h>\n+\n+#include \"libcamera/internal/bayer_format.h\"\n+\n+namespace libcamera {\n+\n+/**\n+ * \\class SwStatsCpu\n+ * \\brief Class for gathering statistics on the CPU\n+ *\n+ * CPU based software ISP statistics implementation.\n+ *\n+ * This class offers a configure function + functions to gather statistics\n+ * on a line by line basis. This allows CPU based software debayering to\n+ * interlace debayering and statistics gathering on a line by line basis\n+ * while the input data is still hot in the cache.\n+ *\n+ * It is also possible to specify a window over which to gather\n+ * statistics instead of processing the whole frame.\n+ */\n+\n+LOG_DEFINE_CATEGORY(SwStatsCpu)\n+\n+SwStatsCpu::SwStatsCpu()\n+{\n+\tsharedStats_ = SharedMemObject<SwIspStats>(\"softIsp_stats\");\n+\tif (!sharedStats_.fd().isValid())\n+\t\tLOG(SwStatsCpu, Error)\n+\t\t\t<< \"Failed to create shared memory for statistics\";\n+}\n+\n+static const unsigned int kRedYMul = 77; /* 0.299 * 256 */\n+static const unsigned int kGreenYMul = 150; /* 0.587 * 256 */\n+static const unsigned int kBlueYMul = 29; /* 0.114 * 256 */\n+\n+#define SWSTATS_START_LINE_STATS(pixel_t) \\\n+\tpixel_t r, g, g2, b; \\\n+\tunsigned int yVal; \\\n+ \\\n+\tunsigned int sumR = 0; \\\n+\tunsigned int sumG = 0; \\\n+\tunsigned int sumB = 0;\n+\n+#define SWSTATS_ACCUMULATE_LINE_STATS(div) \\\n+\tsumR += r; \\\n+\tsumG += g; \\\n+\tsumB += b; \\\n+ \\\n+\tyVal = r * kRedYMul; \\\n+\tyVal += g * kGreenYMul; \\\n+\tyVal += b * kBlueYMul; \\\n+\tstats_.yHistogram[yVal * SwIspStats::kYHistogramSize / (256 * 256 * (div))]++;\n+\n+#define SWSTATS_FINISH_LINE_STATS() \\\n+\tstats_.sumR_ += sumR; \\\n+\tstats_.sumG_ += sumG; \\\n+\tstats_.sumB_ += sumB;\n+\n+void SwStatsCpu::statsBGGR10PLine0(const uint8_t *src[])\n+{\n+\tconst uint8_t *src0 = src[1] + window_.x * 5 / 4;\n+\tconst uint8_t *src1 = src[2] + window_.x * 5 / 4;\n+\tconst int widthInBytes = window_.width * 5 / 4;\n+\n+\tif (swapLines_)\n+\t\tstd::swap(src0, src1);\n+\n+\tSWSTATS_START_LINE_STATS(uint8_t)\n+\n+\t/* x += 5 sample every other 2x2 block */\n+\tfor (int x = 0; x < widthInBytes; x += 5) {\n+\t\t/* BGGR */\n+\t\tb = src0[x];\n+\t\tg = src0[x + 1];\n+\t\tg2 = src1[x];\n+\t\tr = src1[x + 1];\n+\t\tg = (g + g2) / 2;\n+\t\t/* Data is already 8 bits, divide by 1 */\n+\t\tSWSTATS_ACCUMULATE_LINE_STATS(1)\n+\t}\n+\n+\tSWSTATS_FINISH_LINE_STATS()\n+}\n+\n+void SwStatsCpu::statsGBRG10PLine0(const uint8_t *src[])\n+{\n+\tconst uint8_t *src0 = src[1] + window_.x * 5 / 4;\n+\tconst uint8_t *src1 = src[2] + window_.x * 5 / 4;\n+\tconst int widthInBytes = window_.width * 5 / 4;\n+\n+\tif (swapLines_)\n+\t\tstd::swap(src0, src1);\n+\n+\tSWSTATS_START_LINE_STATS(uint8_t)\n+\n+\t/* x += 5 sample every other 2x2 block */\n+\tfor (int x = 0; x < widthInBytes; x += 5) {\n+\t\t/* GBRG */\n+\t\tg = src0[x];\n+\t\tb = src0[x + 1];\n+\t\tr = src1[x];\n+\t\tg2 = src1[x + 1];\n+\t\tg = (g + g2) / 2;\n+\t\t/* Data is already 8 bits, divide by 1 */\n+\t\tSWSTATS_ACCUMULATE_LINE_STATS(1)\n+\t}\n+\n+\tSWSTATS_FINISH_LINE_STATS()\n+}\n+\n+/**\n+ * \\brief Reset state to start statistics gathering for a new frame.\n+ *\n+ * This may only be called after a successful setWindow() call.\n+ */\n+void SwStatsCpu::startFrame(void)\n+{\n+\tstats_.sumR_ = 0;\n+\tstats_.sumB_ = 0;\n+\tstats_.sumG_ = 0;\n+\tstats_.yHistogram.fill(0);\n+}\n+\n+/**\n+ * \\brief Finish statistics calculation for the current frame.\n+ *\n+ * This may only be called after a successful setWindow() call.\n+ */\n+void SwStatsCpu::finishFrame(void)\n+{\n+\t*sharedStats_ = stats_;\n+\tstatsReady.emit(0);\n+}\n+\n+/**\n+ * \\brief Configure the statistics object for the passed in input format.\n+ * \\param[in] inputCfg The input format\n+ *\n+ * \\return 0 on success, a negative errno value on failure\n+ */\n+int SwStatsCpu::configure(const StreamConfiguration &inputCfg)\n+{\n+\tBayerFormat bayerFormat =\n+\t\tBayerFormat::fromPixelFormat(inputCfg.pixelFormat);\n+\n+\tif (bayerFormat.bitDepth == 10 &&\n+\t bayerFormat.packing == BayerFormat::Packing::CSI2) {\n+\t\tpatternSize_.height = 2;\n+\t\tpatternSize_.width = 4; /* 5 bytes per *4* pixels */\n+\t\t/* Skip every 3th and 4th line, sample every other 2x2 block */\n+\t\tySkipMask_ = 0x02;\n+\t\txShift_ = 0;\n+\n+\t\tswitch (bayerFormat.order) {\n+\t\tcase BayerFormat::BGGR:\n+\t\tcase BayerFormat::GRBG:\n+\t\t\tstats0_ = &SwStatsCpu::statsBGGR10PLine0;\n+\t\t\tswapLines_ = bayerFormat.order == BayerFormat::GRBG;\n+\t\t\treturn 0;\n+\t\tcase BayerFormat::GBRG:\n+\t\tcase BayerFormat::RGGB:\n+\t\t\tstats0_ = &SwStatsCpu::statsGBRG10PLine0;\n+\t\t\tswapLines_ = bayerFormat.order == BayerFormat::RGGB;\n+\t\t\treturn 0;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tLOG(SwStatsCpu, Info)\n+\t\t<< \"Unsupported input format \" << inputCfg.pixelFormat.toString();\n+\treturn -EINVAL;\n+}\n+\n+/**\n+ * \\brief Specify window coordinates over which to gather statistics.\n+ * \\param[in] window The window object.\n+ */\n+void SwStatsCpu::setWindow(Rectangle window)\n+{\n+\twindow_ = window;\n+\n+\twindow_.x &= ~(patternSize_.width - 1);\n+\twindow_.x += xShift_;\n+\twindow_.y &= ~(patternSize_.height - 1);\n+\n+\t/* width_ - xShift_ to make sure the window fits */\n+\twindow_.width -= xShift_;\n+\twindow_.width &= ~(patternSize_.width - 1);\n+\twindow_.height &= ~(patternSize_.height - 1);\n+}\n+\n+} /* namespace libcamera */\ndiff --git a/src/libcamera/software_isp/swstats_cpu.h b/src/libcamera/software_isp/swstats_cpu.h\nnew file mode 100644\nindex 00000000..df13263b\n--- /dev/null\n+++ b/src/libcamera/software_isp/swstats_cpu.h\n@@ -0,0 +1,159 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2023, Linaro Ltd\n+ * Copyright (C) 2023, Red Hat Inc.\n+ *\n+ * Authors:\n+ * Hans de Goede <hdegoede@redhat.com>\n+ *\n+ * swstats_cpu.h - CPU based software statistics implementation\n+ */\n+\n+#pragma once\n+\n+#include <stdint.h>\n+\n+#include <libcamera/base/signal.h>\n+\n+#include <libcamera/geometry.h>\n+\n+#include \"libcamera/internal/shared_mem_object.h\"\n+#include \"libcamera/internal/software_isp/swisp_stats.h\"\n+\n+namespace libcamera {\n+\n+class PixelFormat;\n+struct StreamConfiguration;\n+\n+class SwStatsCpu\n+{\n+public:\n+\tSwStatsCpu();\n+\t~SwStatsCpu() = default;\n+\n+\t/**\n+\t * \\brief Gets wether the statistics object is valid.\n+\t *\n+\t * \\return true if it's valid, false otherwise\n+\t */\n+\tbool isValid() const { return sharedStats_.fd().isValid(); }\n+\n+\t/**\n+\t * \\brief Get the file descriptor for the statistics.\n+\t *\n+\t * \\return the file descriptor\n+\t */\n+\tconst SharedFD &getStatsFD() { return sharedStats_.fd(); }\n+\n+\t/**\n+\t * \\brief Get the pattern size.\n+\t *\n+\t * For some input-formats, e.g. Bayer data, processing is done multiple lines\n+\t * and/or columns at a time. Get width and height at which the (bayer) pattern\n+\t * repeats. Window values are rounded down to a multiple of this and the height\n+\t * also indicates if processLine2() should be called or not.\n+\t * This may only be called after a successful configure() call.\n+\t *\n+\t * \\return the pattern size\n+\t */\n+\tconst Size &patternSize() { return patternSize_; }\n+\n+\tint configure(const StreamConfiguration &inputCfg);\n+\tvoid setWindow(Rectangle window);\n+\tvoid startFrame();\n+\tvoid finishFrame();\n+\n+\t/**\n+\t * \\brief Process line 0.\n+\t * \\param[in] y The y coordinate.\n+\t * \\param[in] src The input data.\n+\t *\n+\t * This function processes line 0 for input formats with patternSize height == 1.\n+\t * It'll process line 0 and 1 for input formats with patternSize height >= 2.\n+\t * This function may only be called after a successful setWindow() call.\n+\t */\n+\tvoid processLine0(unsigned int y, const uint8_t *src[])\n+\t{\n+\t\tif ((y & ySkipMask_) || y < (unsigned int)window_.y ||\n+\t\t y >= (window_.y + window_.height))\n+\t\t\treturn;\n+\n+\t\t(this->*stats0_)(src);\n+\t}\n+\n+\t/**\n+\t * \\brief Process line 2 and 3.\n+\t * \\param[in] y The y coordinate.\n+\t * \\param[in] src The input data.\n+\t *\n+\t * This function processes line 2 and 3 for input formats with patternSize height == 4.\n+\t * This function may only be called after a successful setWindow() call.\n+\t */\n+\tvoid processLine2(unsigned int y, const uint8_t *src[])\n+\t{\n+\t\tif ((y & ySkipMask_) || y < (unsigned int)window_.y ||\n+\t\t y >= (window_.y + window_.height))\n+\t\t\treturn;\n+\n+\t\t(this->*stats2_)(src);\n+\t}\n+\n+\t/**\n+\t * \\brief Signals that the statistics are ready.\n+\t *\n+\t * The int parameter isn't actually used.\n+\t */\n+\tSignal<int> statsReady;\n+\n+private:\n+\t/**\n+\t * \\brief Called when there is data to get statistics from.\n+\t * \\param[in] src The input data\n+\t *\n+\t * These functions take an array of (patternSize_.height + 1) src\n+\t * pointers each pointing to a line in the source image. The middle\n+\t * element of the array will point to the actual line being processed.\n+\t * Earlier element(s) will point to the previous line(s) and later\n+\t * element(s) to the next line(s).\n+\t *\n+\t * See the documentation of DebayerCpu::debayerFn for more details.\n+\t */\n+\tusing statsProcessFn = void (SwStatsCpu::*)(const uint8_t *src[]);\n+\n+\tvoid statsBGGR10PLine0(const uint8_t *src[]);\n+\tvoid statsGBRG10PLine0(const uint8_t *src[]);\n+\n+\t/* Variables set by configure(), used every line */\n+\tstatsProcessFn stats0_;\n+\tstatsProcessFn stats2_;\n+\tbool swapLines_;\n+\n+\t/**\n+\t * \\brief Skip lines where this bitmask is set in y.\n+\t */\n+\tunsigned int ySkipMask_;\n+\n+\t/**\n+\t * \\brief Statistics window, set by setWindow(), used ever line.\n+\t */\n+\tRectangle window_;\n+\n+\t/**\n+\t * \\brief The size of the bayer pattern.\n+\t *\n+\t * Valid sizes are: 2x2, 4x2 or 4x4.\n+\t */\n+\tSize patternSize_;\n+\n+\t/**\n+\t * \\brief The offset of x, applied to window_.x for bayer variants.\n+\t *\n+\t * This can either be 0 or 1.\n+\t */\n+\tunsigned int xShift_;\n+\n+\tSharedMemObject<SwIspStats> sharedStats_;\n+\tSwIspStats stats_;\n+};\n+\n+} /* namespace libcamera */\n", "prefixes": [ "v4", "06/18" ] }