{"id":19398,"url":"https://patchwork.libcamera.org/api/patches/19398/?format=json","web_url":"https://patchwork.libcamera.org/patch/19398/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20240113142218.28063-9-hdegoede@redhat.com>","date":"2024-01-13T14:22:08","name":"[libcamera-devel,v2,08/18] libcamera: software_isp: Add SwStatsCpu class","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"334af723c2cea6aea66fd08234be90d881451fea","submitter":{"id":102,"url":"https://patchwork.libcamera.org/api/people/102/?format=json","name":"Hans de Goede","email":"hdegoede@redhat.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/19398/mbox/","series":[{"id":4142,"url":"https://patchwork.libcamera.org/api/series/4142/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=4142","date":"2024-01-13T14:22:00","name":"[libcamera-devel,v2,01/18] libcamera: pipeline: simple: fix size adjustment in validate()","version":2,"mbox":"https://patchwork.libcamera.org/series/4142/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/19398/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/19398/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 5D664C32BC\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat, 13 Jan 2024 14:22:54 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C0FA2628B7;\n\tSat, 13 Jan 2024 15:22:53 +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 79F90628B7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 13 Jan 2024 15:22:51 +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-190-dHIwm4UUOnWbkEGIAVSmKA-1;\n\tSat, 13 Jan 2024 09:22:47 -0500","from smtp.corp.redhat.com\n\t(int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1])\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 871DB3C11C8E;\n\tSat, 13 Jan 2024 14:22:46 +0000 (UTC)","from localhost.localdomain (unknown [10.39.192.58])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id 4DCC13C25;\n\tSat, 13 Jan 2024 14:22:43 +0000 (UTC)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1705155773;\n\tbh=eFI/fdQvCKtqt5YP3BJh4G6bo9P8bDRFhACvmRW8uO0=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=xZ+3KrWF3ByvvBw9LP9J8i3uhvYcJJL97QIDAqfuSDm04N9MCX1BmZub7oqtHAdjh\n\tgkj8W/AGl5nsMmb0vah93xPAQu0OBO0zfqia9PgeXguTUCrM52MyQUlZ+gRzpDWxl1\n\tOFWkuoohL9J3VK4hFzQ8drEqLFb78fCkIBxDDHew6oltTrIscy5gtuTRXYQ1dYSiKA\n\tfixJrO0fCm0rxI7DS3OupGJ+Ytq4A9wRzEwocqpMkefZfCQThyaAbz3P/JFM5/2lA5\n\tyM/hJ8kGFaQnKIcrAv2ODQr+5BLTjZM+F83unPdyoVULH4JZ1YtbhSAyHPY9bf7ahX\n\tBFAvs54J69CNA==","v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1705155770;\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=iHh0+quNqZweKageHVF3MNHrPbdzsoknlC/B33SLw6s=;\n\tb=KXuctxWsYbVtYUfOR4ontnXzGhwW4u+DEqWpSprcs12EdXzeQkSn9vEN92vyYWro1b842x\n\tPaUrCcZJAi/P4FvX4HrWhrvQJXsPNmj/Baio6Nv09YXNzIDmUnRlG1SdgGktD8ZGQjpVuL\n\tsMncH4YfnDz38yih4VHLpAztgrFTJ58="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=redhat.com\n\theader.i=@redhat.com header.b=\"KXuctxWs\"; \n\tdkim-atps=neutral","X-MC-Unique":"dHIwm4UUOnWbkEGIAVSmKA-1","To":"libcamera-devel@lists.libcamera.org,\n\tAndrey Konovalov <andrey.konovalov.ynk@gmail.com>","Date":"Sat, 13 Jan 2024 15:22:08 +0100","Message-ID":"<20240113142218.28063-9-hdegoede@redhat.com>","In-Reply-To":"<20240113142218.28063-1-hdegoede@redhat.com>","References":"<20240113142218.28063-1-hdegoede@redhat.com>","MIME-Version":"1.0","X-Scanned-By":"MIMEDefang 3.4.1 on 10.11.54.1","X-Mimecast-Spam-Score":"0","X-Mimecast-Originator":"redhat.com","Content-Transfer-Encoding":"8bit","Content-Type":"text/plain; charset=\"US-ASCII\"; x-default=true","Subject":"[libcamera-devel] [PATCH v2 08/18] libcamera: software_isp: Add\n\tSwStatsCpu class","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>","From":"Hans de Goede via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"Hans de Goede <hdegoede@redhat.com>","Cc":"Maxime Ripard <mripard@redhat.com>, g.martti@gmail.com,\n\tt.langendam@gmail.com, srinivas.kandagatla@linaro.org,\n\tPavel Machek <pavel@ucw.cz>,\n\tBryan O'Donoghue <bryan.odonoghue@linaro.org>, 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\nCo-authored-by: Andrey Konovalov <andrey.konovalov@linaro.org>\nSigned-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>\nCo-authored-by: Pavel Machek <pavel@ucw.cz>\nSigned-off-by: Pavel Machek <pavel@ucw.cz>\nCo-authored-by: Dennis Bonke <admin@dennisbonke.com>\nSigned-off-by: Dennis Bonke <admin@dennisbonke.com>\nCo-authored-by: Marttico <g.martti@gmail.com>\nSigned-off-by: Marttico <g.martti@gmail.com>\nCo-authored-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>\nTested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s\nTested-by: Pavel Machek <pavel@ucw.cz>\n---\n .../internal/software_isp/meson.build         |   1 +\n .../internal/software_isp/swstats_cpu.h       |  44 +++++\n src/libcamera/software_isp/meson.build        |   1 +\n src/libcamera/software_isp/swstats_cpu.cpp    | 164 ++++++++++++++++++\n 4 files changed, 210 insertions(+)\n create mode 100644 include/libcamera/internal/software_isp/swstats_cpu.h\n create mode 100644 src/libcamera/software_isp/swstats_cpu.cpp","diff":"diff --git a/include/libcamera/internal/software_isp/meson.build b/include/libcamera/internal/software_isp/meson.build\nindex 1c43acc4..1d9e4018 100644\n--- a/include/libcamera/internal/software_isp/meson.build\n+++ b/include/libcamera/internal/software_isp/meson.build\n@@ -3,4 +3,5 @@\n libcamera_internal_headers += files([\n     'swisp_stats.h',\n     'swstats.h',\n+    'swstats_cpu.h',\n ])\ndiff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h\nnew file mode 100644\nindex 00000000..8bb86e98\n--- /dev/null\n+++ b/include/libcamera/internal/software_isp/swstats_cpu.h\n@@ -0,0 +1,44 @@\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 \"libcamera/internal/shared_mem_object.h\"\n+#include \"libcamera/internal/software_isp/swisp_stats.h\"\n+#include \"libcamera/internal/software_isp/swstats.h\"\n+\n+namespace libcamera {\n+\n+/**\n+ * \\class SwStatsCpu\n+ * \\brief Implementation for the Software statistics on the CPU.\n+ */\n+class SwStatsCpu : public SwStats\n+{\n+public:\n+\tSwStatsCpu();\n+\t~SwStatsCpu() { }\n+\n+\tbool isValid() const { return sharedStats_.fd().isValid(); }\n+\tconst SharedFD &getStatsFD() { return sharedStats_.fd(); }\n+\tint configure(const StreamConfiguration &inputCfg);\n+private:\n+\tvoid statsBGGR10PLine0(const uint8_t *src[]);\n+\tvoid statsGBRG10PLine0(const uint8_t *src[]);\n+\tvoid resetStats(void);\n+\tvoid finishStats(void);\n+\n+\tSharedMemObject<SwIspStats> sharedStats_;\n+\tSwIspStats stats_;\n+\tbool swap_lines_;\n+};\n+\n+} /* namespace libcamera */\ndiff --git a/src/libcamera/software_isp/meson.build b/src/libcamera/software_isp/meson.build\nindex 9359075d..d31c6217 100644\n--- a/src/libcamera/software_isp/meson.build\n+++ b/src/libcamera/software_isp/meson.build\n@@ -2,4 +2,5 @@\n \n libcamera_sources += files([\n \t'swstats.cpp',\n+\t'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..59453d07\n--- /dev/null\n+++ b/src/libcamera/software_isp/swstats_cpu.cpp\n@@ -0,0 +1,164 @@\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 \"libcamera/internal/software_isp/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+SwStatsCpu::SwStatsCpu()\n+\t: SwStats()\n+{\n+\tsharedStats_ = SharedMemObject<SwIspStats>(\"softIsp_stats\");\n+\tif (!sharedStats_.fd().isValid())\n+\t\tLOG(SwStats, Error)\n+\t\t\t<< \"Failed to create shared memory for statistics\";\n+}\n+\n+/* for brightness values in the 0 to 255 range: */\n+static const unsigned int BRIGHT_LVL = 200U << 8;\n+static const unsigned int TOO_BRIGHT_LVL = 240U << 8;\n+\n+static const unsigned int RED_Y_MUL = 77; /* 0.30 * 256 */\n+static const unsigned int GREEN_Y_MUL = 150; /* 0.59 * 256 */\n+static const unsigned int BLUE_Y_MUL = 29; /* 0.11 * 256 */\n+\n+#define SWISP_LINARO_START_LINE_STATS(pixel_t) \\\n+\tpixel_t r, g, g2, b;                   \\\n+\tunsigned int y_val;                    \\\n+                                               \\\n+\tunsigned int sumR = 0;                 \\\n+\tunsigned int sumG = 0;                 \\\n+\tunsigned int sumB = 0;\n+\n+#define SWISP_LINARO_ACCUMULATE_LINE_STATS(div) \\\n+\tsumR += r;                              \\\n+\tsumG += g;                              \\\n+\tsumB += b;                              \\\n+                                                \\\n+\ty_val = r * RED_Y_MUL;                  \\\n+\ty_val += g * GREEN_Y_MUL;               \\\n+\ty_val += b * BLUE_Y_MUL;                \\\n+\tstats_.y_histogram[y_val / (256 * 16 * (div))]++;\n+\n+#define SWISP_LINARO_FINISH_LINE_STATS() \\\n+\tstats_.sumR_ += sumR;            \\\n+\tstats_.sumG_ += sumG;            \\\n+\tstats_.sumB_ += sumB;\n+\n+static inline __attribute__((always_inline)) void\n+statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bggr, SwIspStats &stats_)\n+{\n+\tconst int width_in_bytes = width * 5 / 4;\n+\n+\tSWISP_LINARO_START_LINE_STATS(uint8_t)\n+\n+\tfor (int x = 0; x < width_in_bytes; x += 5) {\n+\t\tif (bggr) {\n+\t\t\t/* BGGR */\n+\t\t\tb = src0[x];\n+\t\t\tg = src0[x + 1];\n+\t\t\tg2 = src1[x];\n+\t\t\tr = src1[x + 1];\n+\t\t} else {\n+\t\t\t/* GBRG */\n+\t\t\tg = src0[x];\n+\t\t\tb = src0[x + 1];\n+\t\t\tr = src1[x];\n+\t\t\tg2 = src1[x + 1];\n+\t\t}\n+\t\tg = (g + g2) / 2;\n+\n+\t\tSWISP_LINARO_ACCUMULATE_LINE_STATS(1)\n+\t}\n+\n+\tSWISP_LINARO_FINISH_LINE_STATS()\n+}\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+\n+\tif (swap_lines_)\n+\t\tstd::swap(src0, src1);\n+\n+\tstatsBayer10P(window_.width, src0, src1, true, 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+\n+\tif (swap_lines_)\n+\t\tstd::swap(src0, src1);\n+\n+\tstatsBayer10P(window_.width, src0, src1, false, stats_);\n+}\n+\n+void SwStatsCpu::resetStats(void)\n+{\n+\tstats_.sumR_ = 0;\n+\tstats_.sumB_ = 0;\n+\tstats_.sumG_ = 0;\n+\tstd::fill_n(stats_.y_histogram, 16, 0);\n+}\n+\n+void SwStatsCpu::finishStats(void)\n+{\n+\t*sharedStats_ = stats_;\n+\tstatsReady.emit(0);\n+}\n+\n+int SwStatsCpu::configure(const StreamConfiguration &inputCfg)\n+{\n+\tBayerFormat bayerFormat =\n+\t\tBayerFormat::fromPixelFormat(inputCfg.pixelFormat);\n+\n+\tstartFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::resetStats;\n+\tfinishFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::finishStats;\n+\n+\tif (bayerFormat.bitDepth == 10 &&\n+\t    bayerFormat.packing == BayerFormat::Packing::CSI2) {\n+\t\tbpp_ = 10;\n+\t\tpatternSize_.height = 2;\n+\t\tpatternSize_.width = 4; /* 5 bytes per *4* pixels */\n+\t\ty_skip_mask_ = 0x02; /* Skip every 3th and 4th line */\n+\t\tx_shift_ = 0;\n+\n+\t\tswitch (bayerFormat.order) {\n+\t\tcase BayerFormat::BGGR:\n+\t\tcase BayerFormat::GRBG:\n+\t\t\tstats0_ = (SwStats::statsProcessFn)&SwStatsCpu::statsBGGR10PLine0;\n+\t\t\tswap_lines_ = bayerFormat.order == BayerFormat::GRBG;\n+\t\t\treturn 0;\n+\t\tcase BayerFormat::GBRG:\n+\t\tcase BayerFormat::RGGB:\n+\t\t\tstats0_ = (SwStats::statsProcessFn)&SwStatsCpu::statsGBRG10PLine0;\n+\t\t\tswap_lines_ = bayerFormat.order == BayerFormat::RGGB;\n+\t\t\treturn 0;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tLOG(SwStats, Info)\n+\t\t<< \"Unsupported input format \" << inputCfg.pixelFormat.toString();\n+\treturn -EINVAL;\n+}\n+\n+} /* namespace libcamera */\n","prefixes":["libcamera-devel","v2","08/18"]}