From patchwork Tue Apr 22 21:58:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 23219 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 39C43C32A2 for ; Tue, 22 Apr 2025 21:59:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E23C068B2A; Tue, 22 Apr 2025 23:59:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="H1KuB6ez"; dkim-atps=neutral Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0FB7268AD9 for ; Tue, 22 Apr 2025 23:59:29 +0200 (CEST) Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-39efc1365e4so2059265f8f.1 for ; Tue, 22 Apr 2025 14:59:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1745359168; x=1745963968; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=NL86VTXgXgeQtJwMlBiBDgKApRvuNu2cPMHijbRU9yo=; b=H1KuB6ez99mh9tg/2hpuplddll0/zET3UfRPoveuTvHrIFPvjh2BDfhg6zOKE7HFWy L3D70/D/RCx4M1hm2jZV2JMkjyjzb0fwF/aWYPLpyfwTMqhiLxt1oSaKFwvQOoUvPin4 YvXr8YXwl/JQAaEMSZmdHhzTL6JXAN/PhMg7+8g6du+UZl9nURrKSxbQEXPiBQTbqupO 6O1yiJ0jKyLdltj1w9tyfNbr/Z605qdOw1wcW9dJV253d2mLogSLBe92ydvRTfyRlTuV 5T36wnVyN3jcpFp5SsAW1FfUmXzHq+tMZFDsPBH+w3uAjH5Qql5rzPPUtM66A9KLJwH1 wT6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1745359168; x=1745963968; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NL86VTXgXgeQtJwMlBiBDgKApRvuNu2cPMHijbRU9yo=; b=Q9/C5Qd/RxzAb2Qpk5bItla0dzp376SVZ9yA+kUssCzMujKkMTHv512C6oQOzOHW2a yUm9mS7k6ePh66cDkkGNIQ/O+2aRcJwFNeLXjnt1Bq5iUuAn3kaG6m/nIJhp/9/oy8U9 gSnn4u7yWUNRmRR8CfKTf2gSHSWWjZrD6+s3dWsez2hGb4g9lytZJjrQBTYYAjKMsnNJ KIclXJ4ZSu3dPudP704msyCJYotEEdhvILxWpDhoDdEuHhvEsSma5doFDFuPTK1DZvRA C/fY1knRw9DkPcAFg+qCpC6Xpspdd+fkjLxxrmlqQPrTBAaGQ9j3YBx6I8M6YR3ElO7C 8StA== X-Gm-Message-State: AOJu0YwyBY0UgRtud8XQ65U1cdYT5qFyBXshlmlFpGqXjQVn5XvnaGyW vY/1tMJGiM2K+r68Qs25Qb22266ZrCQXgwbHOjrgo89S2lAzPCKEggy2rwPSfZT7YpluLNTGV3H pGWY= X-Gm-Gg: ASbGncsXx55o7urIK2oKRNeYX+shDfWZCw+EHl5IJyQsV6lVku8mOmogXf0GK/BhVQj Ksp1CDVq5zO2nfv3M0WctpceLZ2/rkg0TQTPwFiyKjf+FQQkBtZ0QYcF0R8q4yrQt+8zyx7S22T wjBKJY+llVoYwBts/WjFYGtd0Z55T5YxV7sNXPWTnz0KaGiQzWUHaFqweP0tU/R9aXOuhKuBlxd hATCRW23URJiPtPQtnzwL/5wBj8SVcZP+1mQGLKMfDcJDW3f5zeJCq9tcoFuYVwGxG4nQ/1Mrgo p0UwlT5d7uRfURMSuxI3xUmA1voU/UmCA+TcOdy0MEOxH/vq71oUkufWw4h/ili//pZQgBatjXX 7CENxqOtABA/RuOl0ryHj X-Google-Smtp-Source: AGHT+IGiTgRjWIY/8L+Vth5Qai6xIQmdiAnk+4gf2Ep1fYEyxz6LqXb2MCYZWOX/09VAAa0CTASwJA== X-Received: by 2002:a05:6000:22c7:b0:391:3988:1c97 with SMTP id ffacd0b85a97d-39efba4af82mr14396217f8f.17.1745359168357; Tue, 22 Apr 2025 14:59:28 -0700 (PDT) Received: from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie. [188.141.3.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-44092d2eccesm2726615e9.20.2025.04.22.14.59.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Apr 2025 14:59:27 -0700 (PDT) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: hdegoede@redhat.com, mzamazal@redhat.com, bryan.odonoghue@linaro.org, bod.linux@nxsw.ie, Kieran Bingham Subject: [PATCH 06/27] libcamera: software_isp: Move benchmark code to its own class Date: Tue, 22 Apr 2025 22:58:59 +0100 Message-ID: <20250422215920.4297-7-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250422215920.4297-1-bryan.odonoghue@linaro.org> References: <20250422215920.4297-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Hans de Goede Move the code for the builtin benchmark to its own small Benchmark class. Reviewed-by: Kieran Bingham Reviewed-by: Milan Zamazal Signed-off-by: Hans de Goede --- Changes since the RFC: - Add doxygen documentation to for all the public methods Signed-off-by: Bryan O'Donoghue --- .../internal/software_isp/benchmark.h | 36 +++++++ .../internal/software_isp/meson.build | 1 + src/libcamera/software_isp/benchmark.cpp | 93 +++++++++++++++++++ src/libcamera/software_isp/debayer_cpu.cpp | 36 +------ src/libcamera/software_isp/debayer_cpu.h | 7 +- src/libcamera/software_isp/meson.build | 1 + 6 files changed, 135 insertions(+), 39 deletions(-) create mode 100644 include/libcamera/internal/software_isp/benchmark.h create mode 100644 src/libcamera/software_isp/benchmark.cpp diff --git a/include/libcamera/internal/software_isp/benchmark.h b/include/libcamera/internal/software_isp/benchmark.h new file mode 100644 index 00000000..8af25015 --- /dev/null +++ b/include/libcamera/internal/software_isp/benchmark.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Red Hat Inc. + * + * Authors: + * Hans de Goede + * + * Simple builtin benchmark to measure software ISP processing times + */ + +#pragma once + +#include +#include + +namespace libcamera { + +class Benchmark +{ +public: + Benchmark(); + ~Benchmark(); + + void startFrame(void); + void finishFrame(void); + +private: + unsigned int measuredFrames_; + int64_t frameProcessTime_; + timespec frameStartTime_; + /* Skip 30 frames for things to stabilize then measure 30 frames */ + static constexpr unsigned int kFramesToSkip = 30; + static constexpr unsigned int kLastFrameToMeasure = 60; +}; + +} /* namespace libcamera */ diff --git a/include/libcamera/internal/software_isp/meson.build b/include/libcamera/internal/software_isp/meson.build index 508ddddc..a7e606d2 100644 --- a/include/libcamera/internal/software_isp/meson.build +++ b/include/libcamera/internal/software_isp/meson.build @@ -1,6 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 libcamera_internal_headers += files([ + 'benchmark.h', 'debayer_params.h', 'software_isp.h', 'swisp_stats.h', diff --git a/src/libcamera/software_isp/benchmark.cpp b/src/libcamera/software_isp/benchmark.cpp new file mode 100644 index 00000000..b3da3c41 --- /dev/null +++ b/src/libcamera/software_isp/benchmark.cpp @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024, Red Hat Inc. + * + * Authors: + * Hans de Goede + * + * Simple builtin benchmark to measure software ISP processing times + */ + +#include "libcamera/internal/software_isp/benchmark.h" + +#include + +namespace libcamera { + +LOG_DEFINE_CATEGORY(Benchmark) + +/** + * \class Benchmark + * \brief Simple builtin benchmark + * + * Simple builtin benchmark to measure software ISP processing times. + */ + +/** + * \brief Constructs a Benchmark object + */ +Benchmark::Benchmark() + : measuredFrames_(0), frameProcessTime_(0) +{ +} + +Benchmark::~Benchmark() +{ +} + +static inline int64_t timeDiff(timespec &after, timespec &before) +{ + return (after.tv_sec - before.tv_sec) * 1000000000LL + + (int64_t)after.tv_nsec - (int64_t)before.tv_nsec; +} + +/** + * \brief Start measuring process time for a single frame + * + * Call this function before processing frame data to start measuring + * the process time for a frame. + */ +void Benchmark::startFrame(void) +{ + if (measuredFrames_ >= Benchmark::kLastFrameToMeasure) + return; + + frameStartTime_ = {}; + clock_gettime(CLOCK_MONOTONIC_RAW, &frameStartTime_); +} + +/** + * \brief Finish measuring process time for a single frame + * + * Call this function after processing frame data to finish measuring + * the process time for a frame. + * + * This function will log frame processing time information after + * Benchmark::kLastFrameToMeasure frames have been processed. + */ +void Benchmark::finishFrame(void) +{ + if (measuredFrames_ >= Benchmark::kLastFrameToMeasure) + return; + + measuredFrames_++; + + if (measuredFrames_ <= Benchmark::kFramesToSkip) + return; + + timespec frameEndTime = {}; + clock_gettime(CLOCK_MONOTONIC_RAW, &frameEndTime); + frameProcessTime_ += timeDiff(frameEndTime, frameStartTime_); + + if (measuredFrames_ == Benchmark::kLastFrameToMeasure) { + const unsigned int measuredFrames = Benchmark::kLastFrameToMeasure - + Benchmark::kFramesToSkip; + LOG(Benchmark, Info) + << "Processed " << measuredFrames + << " frames in " << frameProcessTime_ / 1000 << "us, " + << frameProcessTime_ / (1000 * measuredFrames) + << " us/frame"; + } +} + +} /* namespace libcamera */ diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index 66f6038c..8d30bf4a 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -554,9 +554,6 @@ int DebayerCpu::configure(const StreamConfiguration &inputCfg, lineBuffers_[i].resize(lineBufferLength_); } - measuredFrames_ = 0; - frameProcessTime_ = 0; - return 0; } @@ -746,24 +743,9 @@ void DebayerCpu::process4(const uint8_t *src, uint8_t *dst) } } -namespace { - -inline int64_t timeDiff(timespec &after, timespec &before) -{ - return (after.tv_sec - before.tv_sec) * 1000000000LL + - (int64_t)after.tv_nsec - (int64_t)before.tv_nsec; -} - -} /* namespace */ - void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params) { - timespec frameStartTime; - - if (measuredFrames_ < DebayerCpu::kLastFrameToMeasure) { - frameStartTime = {}; - clock_gettime(CLOCK_MONOTONIC_RAW, &frameStartTime); - } + bench_.startFrame(); std::vector dmaSyncers; for (const FrameBuffer::Plane &plane : input->planes()) @@ -817,21 +799,7 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output dmaSyncers.clear(); /* Measure before emitting signals */ - if (measuredFrames_ < DebayerCpu::kLastFrameToMeasure && - ++measuredFrames_ > DebayerCpu::kFramesToSkip) { - timespec frameEndTime = {}; - clock_gettime(CLOCK_MONOTONIC_RAW, &frameEndTime); - frameProcessTime_ += timeDiff(frameEndTime, frameStartTime); - if (measuredFrames_ == DebayerCpu::kLastFrameToMeasure) { - const unsigned int measuredFrames = DebayerCpu::kLastFrameToMeasure - - DebayerCpu::kFramesToSkip; - LOG(Debayer, Info) - << "Processed " << measuredFrames - << " frames in " << frameProcessTime_ / 1000 << "us, " - << frameProcessTime_ / (1000 * measuredFrames) - << " us/frame"; - } - } + bench_.finishFrame(); /* * Buffer ids are currently not used, so pass zeros as its parameter. diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 926195e9..d6820d5e 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -17,6 +17,7 @@ #include +#include "libcamera/internal/software_isp/benchmark.h" #include "libcamera/internal/bayer_format.h" #include "debayer.h" @@ -160,11 +161,7 @@ private: unsigned int xShift_; /* Offset of 0/1 applied to window_.x */ bool enableInputMemcpy_; bool swapRedBlueGains_; - unsigned int measuredFrames_; - int64_t frameProcessTime_; - /* Skip 30 frames for things to stabilize then measure 30 frames */ - static constexpr unsigned int kFramesToSkip = 30; - static constexpr unsigned int kLastFrameToMeasure = 60; + Benchmark bench_; }; } /* namespace libcamera */ diff --git a/src/libcamera/software_isp/meson.build b/src/libcamera/software_isp/meson.build index aac7eda7..59fa5f02 100644 --- a/src/libcamera/software_isp/meson.build +++ b/src/libcamera/software_isp/meson.build @@ -8,6 +8,7 @@ if not softisp_enabled endif libcamera_internal_sources += files([ + 'benchmark.cpp', 'debayer.cpp', 'debayer_cpu.cpp', 'software_isp.cpp',