From patchwork Sat Jan 13 14:22:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 19398 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 5D664C32BC for ; Sat, 13 Jan 2024 14:22:54 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C0FA2628B7; Sat, 13 Jan 2024 15:22:53 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1705155773; bh=eFI/fdQvCKtqt5YP3BJh4G6bo9P8bDRFhACvmRW8uO0=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=xZ+3KrWF3ByvvBw9LP9J8i3uhvYcJJL97QIDAqfuSDm04N9MCX1BmZub7oqtHAdjh gkj8W/AGl5nsMmb0vah93xPAQu0OBO0zfqia9PgeXguTUCrM52MyQUlZ+gRzpDWxl1 OFWkuoohL9J3VK4hFzQ8drEqLFb78fCkIBxDDHew6oltTrIscy5gtuTRXYQ1dYSiKA fixJrO0fCm0rxI7DS3OupGJ+Ytq4A9wRzEwocqpMkefZfCQThyaAbz3P/JFM5/2lA5 yM/hJ8kGFaQnKIcrAv2ODQr+5BLTjZM+F83unPdyoVULH4JZ1YtbhSAyHPY9bf7ahX BFAvs54J69CNA== Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 79F90628B7 for ; Sat, 13 Jan 2024 15:22:51 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="KXuctxWs"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1705155770; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iHh0+quNqZweKageHVF3MNHrPbdzsoknlC/B33SLw6s=; b=KXuctxWsYbVtYUfOR4ontnXzGhwW4u+DEqWpSprcs12EdXzeQkSn9vEN92vyYWro1b842x PaUrCcZJAi/P4FvX4HrWhrvQJXsPNmj/Baio6Nv09YXNzIDmUnRlG1SdgGktD8ZGQjpVuL sMncH4YfnDz38yih4VHLpAztgrFTJ58= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-190-dHIwm4UUOnWbkEGIAVSmKA-1; Sat, 13 Jan 2024 09:22:47 -0500 X-MC-Unique: dHIwm4UUOnWbkEGIAVSmKA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 871DB3C11C8E; Sat, 13 Jan 2024 14:22:46 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.58]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4DCC13C25; Sat, 13 Jan 2024 14:22:43 +0000 (UTC) To: libcamera-devel@lists.libcamera.org, Andrey Konovalov 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 Subject: [libcamera-devel] [PATCH v2 08/18] libcamera: software_isp: Add SwStatsCpu 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: , X-Patchwork-Original-From: Hans de Goede via libcamera-devel From: Hans de Goede Reply-To: Hans de Goede Cc: Maxime Ripard , g.martti@gmail.com, t.langendam@gmail.com, srinivas.kandagatla@linaro.org, Pavel Machek , Bryan O'Donoghue , admin@dennisbonke.com Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add a CPU based SwStats implementation for SoftwareISP / SoftIPA use. Co-authored-by: Andrey Konovalov Signed-off-by: Andrey Konovalov Co-authored-by: Pavel Machek Signed-off-by: Pavel Machek Co-authored-by: Dennis Bonke Signed-off-by: Dennis Bonke Co-authored-by: Marttico Signed-off-by: Marttico Co-authored-by: Toon Langendam Signed-off-by: Toon Langendam Signed-off-by: Hans de Goede Tested-by: Bryan O'Donoghue # sc8280xp Lenovo x13s Tested-by: Pavel Machek --- .../internal/software_isp/meson.build | 1 + .../internal/software_isp/swstats_cpu.h | 44 +++++ src/libcamera/software_isp/meson.build | 1 + src/libcamera/software_isp/swstats_cpu.cpp | 164 ++++++++++++++++++ 4 files changed, 210 insertions(+) create mode 100644 include/libcamera/internal/software_isp/swstats_cpu.h create mode 100644 src/libcamera/software_isp/swstats_cpu.cpp diff --git a/include/libcamera/internal/software_isp/meson.build b/include/libcamera/internal/software_isp/meson.build index 1c43acc4..1d9e4018 100644 --- a/include/libcamera/internal/software_isp/meson.build +++ b/include/libcamera/internal/software_isp/meson.build @@ -3,4 +3,5 @@ libcamera_internal_headers += files([ 'swisp_stats.h', 'swstats.h', + 'swstats_cpu.h', ]) diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h new file mode 100644 index 00000000..8bb86e98 --- /dev/null +++ b/include/libcamera/internal/software_isp/swstats_cpu.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Linaro Ltd + * Copyright (C) 2023, Red Hat Inc. + * + * Authors: + * Hans de Goede + * + * swstats_cpu.h - CPU based software statistics implementation + */ + +#pragma once + +#include "libcamera/internal/shared_mem_object.h" +#include "libcamera/internal/software_isp/swisp_stats.h" +#include "libcamera/internal/software_isp/swstats.h" + +namespace libcamera { + +/** + * \class SwStatsCpu + * \brief Implementation for the Software statistics on the CPU. + */ +class SwStatsCpu : public SwStats +{ +public: + SwStatsCpu(); + ~SwStatsCpu() { } + + bool isValid() const { return sharedStats_.fd().isValid(); } + const SharedFD &getStatsFD() { return sharedStats_.fd(); } + int configure(const StreamConfiguration &inputCfg); +private: + void statsBGGR10PLine0(const uint8_t *src[]); + void statsGBRG10PLine0(const uint8_t *src[]); + void resetStats(void); + void finishStats(void); + + SharedMemObject sharedStats_; + SwIspStats stats_; + bool swap_lines_; +}; + +} /* namespace libcamera */ diff --git a/src/libcamera/software_isp/meson.build b/src/libcamera/software_isp/meson.build index 9359075d..d31c6217 100644 --- a/src/libcamera/software_isp/meson.build +++ b/src/libcamera/software_isp/meson.build @@ -2,4 +2,5 @@ libcamera_sources += files([ 'swstats.cpp', + 'swstats_cpu.cpp', ]) diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp new file mode 100644 index 00000000..59453d07 --- /dev/null +++ b/src/libcamera/software_isp/swstats_cpu.cpp @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Linaro Ltd + * Copyright (C) 2023, Red Hat Inc. + * + * Authors: + * Hans de Goede + * + * swstats_cpu.cpp - CPU based software statistics implementation + */ + +#include "libcamera/internal/software_isp/swstats_cpu.h" + +#include + +#include + +#include "libcamera/internal/bayer_format.h" + +namespace libcamera { + +SwStatsCpu::SwStatsCpu() + : SwStats() +{ + sharedStats_ = SharedMemObject("softIsp_stats"); + if (!sharedStats_.fd().isValid()) + LOG(SwStats, Error) + << "Failed to create shared memory for statistics"; +} + +/* for brightness values in the 0 to 255 range: */ +static const unsigned int BRIGHT_LVL = 200U << 8; +static const unsigned int TOO_BRIGHT_LVL = 240U << 8; + +static const unsigned int RED_Y_MUL = 77; /* 0.30 * 256 */ +static const unsigned int GREEN_Y_MUL = 150; /* 0.59 * 256 */ +static const unsigned int BLUE_Y_MUL = 29; /* 0.11 * 256 */ + +#define SWISP_LINARO_START_LINE_STATS(pixel_t) \ + pixel_t r, g, g2, b; \ + unsigned int y_val; \ + \ + unsigned int sumR = 0; \ + unsigned int sumG = 0; \ + unsigned int sumB = 0; + +#define SWISP_LINARO_ACCUMULATE_LINE_STATS(div) \ + sumR += r; \ + sumG += g; \ + sumB += b; \ + \ + y_val = r * RED_Y_MUL; \ + y_val += g * GREEN_Y_MUL; \ + y_val += b * BLUE_Y_MUL; \ + stats_.y_histogram[y_val / (256 * 16 * (div))]++; + +#define SWISP_LINARO_FINISH_LINE_STATS() \ + stats_.sumR_ += sumR; \ + stats_.sumG_ += sumG; \ + stats_.sumB_ += sumB; + +static inline __attribute__((always_inline)) void +statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bggr, SwIspStats &stats_) +{ + const int width_in_bytes = width * 5 / 4; + + SWISP_LINARO_START_LINE_STATS(uint8_t) + + for (int x = 0; x < width_in_bytes; x += 5) { + if (bggr) { + /* BGGR */ + b = src0[x]; + g = src0[x + 1]; + g2 = src1[x]; + r = src1[x + 1]; + } else { + /* GBRG */ + g = src0[x]; + b = src0[x + 1]; + r = src1[x]; + g2 = src1[x + 1]; + } + g = (g + g2) / 2; + + SWISP_LINARO_ACCUMULATE_LINE_STATS(1) + } + + SWISP_LINARO_FINISH_LINE_STATS() +} + +void SwStatsCpu::statsBGGR10PLine0(const uint8_t *src[]) +{ + const uint8_t *src0 = src[1] + window_.x * 5 / 4; + const uint8_t *src1 = src[2] + window_.x * 5 / 4; + + if (swap_lines_) + std::swap(src0, src1); + + statsBayer10P(window_.width, src0, src1, true, stats_); +} + +void SwStatsCpu::statsGBRG10PLine0(const uint8_t *src[]) +{ + const uint8_t *src0 = src[1] + window_.x * 5 / 4; + const uint8_t *src1 = src[2] + window_.x * 5 / 4; + + if (swap_lines_) + std::swap(src0, src1); + + statsBayer10P(window_.width, src0, src1, false, stats_); +} + +void SwStatsCpu::resetStats(void) +{ + stats_.sumR_ = 0; + stats_.sumB_ = 0; + stats_.sumG_ = 0; + std::fill_n(stats_.y_histogram, 16, 0); +} + +void SwStatsCpu::finishStats(void) +{ + *sharedStats_ = stats_; + statsReady.emit(0); +} + +int SwStatsCpu::configure(const StreamConfiguration &inputCfg) +{ + BayerFormat bayerFormat = + BayerFormat::fromPixelFormat(inputCfg.pixelFormat); + + startFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::resetStats; + finishFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::finishStats; + + if (bayerFormat.bitDepth == 10 && + bayerFormat.packing == BayerFormat::Packing::CSI2) { + bpp_ = 10; + patternSize_.height = 2; + patternSize_.width = 4; /* 5 bytes per *4* pixels */ + y_skip_mask_ = 0x02; /* Skip every 3th and 4th line */ + x_shift_ = 0; + + switch (bayerFormat.order) { + case BayerFormat::BGGR: + case BayerFormat::GRBG: + stats0_ = (SwStats::statsProcessFn)&SwStatsCpu::statsBGGR10PLine0; + swap_lines_ = bayerFormat.order == BayerFormat::GRBG; + return 0; + case BayerFormat::GBRG: + case BayerFormat::RGGB: + stats0_ = (SwStats::statsProcessFn)&SwStatsCpu::statsGBRG10PLine0; + swap_lines_ = bayerFormat.order == BayerFormat::RGGB; + return 0; + default: + break; + } + } + + LOG(SwStats, Info) + << "Unsupported input format " << inputCfg.pixelFormat.toString(); + return -EINVAL; +} + +} /* namespace libcamera */