From patchwork Wed Sep 25 09:58:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 21368 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 0A229C0F1B for ; Wed, 25 Sep 2024 09:59:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7548663521; Wed, 25 Sep 2024 11:59:49 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="UwU39VMw"; dkim-atps=neutral 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 D784463522 for ; Wed, 25 Sep 2024 11:59:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1727258378; 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=wJG1tQ87SSdqXY6pv8AF2ifHmKXXdruKG1yI76SHP9Y=; b=UwU39VMwDqxxMbe2hh6njT/CrCyr2hlBmCAQOKpXcD9mZSAwvRDQEc+g8Aat+5+N/r3Rno Vcz2Xl5KW2+ofm/IArke7PpRk7HrHkI2BscUXscXgSmAj3Us81R49fHuN2pjQd9hD4dxB1 NMcFI8CWVuEmuQ6ZzE4LnflrxwDWlnM= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-614-qXe_p2iZN9KEYGyn96CqyA-1; Wed, 25 Sep 2024 05:59:35 -0400 X-MC-Unique: qXe_p2iZN9KEYGyn96CqyA-1 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (unknown [10.30.177.12]) (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 mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B2DF21955D59; Wed, 25 Sep 2024 09:59:34 +0000 (UTC) Received: from nuthatch.redhat.com (unknown [10.45.225.29]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EDD7119560AA; Wed, 25 Sep 2024 09:59:32 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Kieran Bingham , Naushir Patuck Subject: [PATCH v4 15/15] libcamera: software_isp: Make measurement configurable Date: Wed, 25 Sep 2024 11:58:47 +0200 Message-ID: <20240925095850.348259-16-mzamazal@redhat.com> In-Reply-To: <20240925095850.348259-1-mzamazal@redhat.com> References: <20240925095850.348259-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com 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" Software ISP performs performance measurement on certain part of initial frames. Let's make this range configurable. For this purpose, this patch introduces new configuration options pipelines.simple.measure.skip and pipelines.simple.measure.number. Setting the latter one to 0 disables the measurement. Instead of the last frame, the class member and its configuration specify the number of frames to measure. This is easier to use for users and doesn't require to adjust two configuration parameters when the number of the initially skipped frames is changed. The patch also changes the names of the class members to make them more accurate. Completes software ISP TODO #7. Signed-off-by: Milan Zamazal --- Documentation/runtime_configuration.rst | 6 ++++++ src/libcamera/software_isp/TODO | 25 ---------------------- src/libcamera/software_isp/debayer_cpu.cpp | 25 ++++++++++++++-------- src/libcamera/software_isp/debayer_cpu.h | 7 +++--- 4 files changed, 25 insertions(+), 38 deletions(-) diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst index 4babce1ab..c51d1927a 100644 --- a/Documentation/runtime_configuration.rst +++ b/Documentation/runtime_configuration.rst @@ -56,6 +56,9 @@ file structure: tuning-file: # full path simple: copy_input_buffer: # true/false + measure: + skip: # non-negative integer, frames to skip initially + number: # non-negative integer, frames to measure supported_devices: - driver: # driver name, e.g. `mxc-isi` software_isp: # true/false @@ -89,6 +92,9 @@ Configuration file example config_file: /usr/local/share/libcamera/pipeline/rpi/vc4/minimal_mem.yaml simple: copy_input_buffer: false + measure: + skip: 50 + number: 30 supported_devices: - driver: mxc-isi software_isp: true diff --git a/src/libcamera/software_isp/TODO b/src/libcamera/software_isp/TODO index dfb1e9772..6de063512 100644 --- a/src/libcamera/software_isp/TODO +++ b/src/libcamera/software_isp/TODO @@ -71,31 +71,6 @@ per-frame buffers like we do for hardware ISPs. --- -7. Performance measurement configuration - -> void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams params) -> /* 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"; -> } -> } - -I wonder if there would be a way to control at runtime when/how to -perform those measurements. Maybe that's a bit overkill. - ---- - 8. DebayerCpu cleanups > >> class DebayerCpu : public Debayer, public Object diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index 12859062e..9a11adefc 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -52,6 +52,13 @@ DebayerCpu::DebayerCpu(std::unique_ptr stats) "pipelines.simple.copy_input_buffer") .value_or(true); + skipBeforeMeasure_ = GlobalConfiguration::option( + "pipelines.simple.measure.skip") + .value_or(skipBeforeMeasure_); + framesToMeasure_ = GlobalConfiguration::option( + "pipelines.simple.measure.number") + .value_or(framesToMeasure_); + /* Initialize color lookup tables */ for (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) red_[i] = green_[i] = blue_[i] = i; @@ -531,7 +538,7 @@ int DebayerCpu::configure(const StreamConfiguration &inputCfg, lineBuffers_[i].resize(lineBufferLength_); } - measuredFrames_ = 0; + encounteredFrames_ = 0; frameProcessTime_ = 0; return 0; @@ -755,7 +762,10 @@ void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams { timespec frameStartTime; - if (measuredFrames_ < DebayerCpu::kLastFrameToMeasure) { + bool measure = framesToMeasure_ > 0 && + encounteredFrames_ < skipBeforeMeasure_ + framesToMeasure_ && + ++encounteredFrames_ > skipBeforeMeasure_; + if (measure) { frameStartTime = {}; clock_gettime(CLOCK_MONOTONIC_RAW, &frameStartTime); } @@ -794,18 +804,15 @@ void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams syncBufferForCPU(input, DMA_BUF_SYNC_END | DMA_BUF_SYNC_READ); /* Measure before emitting signals */ - if (measuredFrames_ < DebayerCpu::kLastFrameToMeasure && - ++measuredFrames_ > DebayerCpu::kFramesToSkip) { + if (measure) { timespec frameEndTime = {}; clock_gettime(CLOCK_MONOTONIC_RAW, &frameEndTime); frameProcessTime_ += timeDiff(frameEndTime, frameStartTime); - if (measuredFrames_ == DebayerCpu::kLastFrameToMeasure) { - const unsigned int measuredFrames = DebayerCpu::kLastFrameToMeasure - - DebayerCpu::kFramesToSkip; + if (encounteredFrames_ == skipBeforeMeasure_ + framesToMeasure_) { LOG(Debayer, Info) - << "Processed " << measuredFrames + << "Processed " << framesToMeasure_ << " frames in " << frameProcessTime_ / 1000 << "us, " - << frameProcessTime_ / (1000 * measuredFrames) + << frameProcessTime_ / (1000 * framesToMeasure_) << " us/frame"; } } diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 8237a64be..30d8e256d 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -153,11 +153,10 @@ private: unsigned int xShift_; /* Offset of 0/1 applied to window_.x */ bool enableInputMemcpy_; bool swapRedBlueGains_; - unsigned int measuredFrames_; + unsigned int encounteredFrames_; 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; + unsigned int skipBeforeMeasure_ = 30; + unsigned int framesToMeasure_ = 30; }; } /* namespace libcamera */