From patchwork Tue Mar 10 12:01:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 26271 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 71A06BE086 for ; Tue, 10 Mar 2026 12:01:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1318062657; Tue, 10 Mar 2026 13:01:20 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.b="ZmR+DHXZ"; dkim=pass (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="L0d9fckY"; dkim-atps=neutral Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7B0C0622F1 for ; Tue, 10 Mar 2026 13:01:18 +0100 (CET) Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 62ABc4gI2021657 for ; Tue, 10 Mar 2026 12:01:17 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=pf95oxuDZJ2 Gr6M9VS6ydxNzYiU2Skcmi0Q2u9BrCxo=; b=ZmR+DHXZrlDiSovhoxafo2qlmRw KgGB9bcXfsMhWANw+p0Qb/4RGGTsUTBERhrV9jGr9vWCkTEZpdzjqRGhZcqFp9DS 9dgkeBwNQ8JQpQqg2JJRBosAoxqNlGtJB+Xl8JD+fPj8AGqrabAx3ZnMVfspemNq l5JNtD0e2IFo63HNOgErGQHTCQt8pwqEdRgl8aTTl7xFF/ZQ1rhxjdKTUk0uztiP PE5yzVSf3XQiIOspS/ZpPCSRkBYxhMW7ASRadW/8g3eySM/Vvy/vv5y7b6Arihrn g1sG+5WBQK5+ke1XYQTe+JbqXrs8nLuufIWRmeOizmaayVrZtMtXH7R558g== Received: from mail-ua1-f69.google.com (mail-ua1-f69.google.com [209.85.222.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4cte3w977v-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Tue, 10 Mar 2026 12:01:16 +0000 (GMT) Received: by mail-ua1-f69.google.com with SMTP id a1e0cc1a2514c-94ea8c27188so11702729241.1 for ; Tue, 10 Mar 2026 05:01:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1773144075; x=1773748875; 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=pf95oxuDZJ2Gr6M9VS6ydxNzYiU2Skcmi0Q2u9BrCxo=; b=L0d9fckYKr+rC5sKlux2J+tdkrC4fVZ5s9+XhUnjmsONqRzoccbqRKAT+JBnilCdng uUXePVVGa4djbTMIhiCSJsNStVc9I2Kx7aLbWhjfkteWNyVmOv7zC2hIk8NGNcnZeB99 i4BdFJSjzI82LH3A1ZwCkr07V3vS9/sB0ql25jfN5Md5ecTLL7TKNUk1zNMl9insa4Sc J2UIBmaNqd5ppKP7iVry1K77ox1XFMxkAQoxwhUE8JkQaJzuurIbVZlajXUWXpuL/kVa sTfIwHcy+N25U3qMeSwnxqkQeDGRBqMndkuCq4UyyLo0DcsjPj667Br8QTdZXMTg8yaY SMTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773144075; x=1773748875; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=pf95oxuDZJ2Gr6M9VS6ydxNzYiU2Skcmi0Q2u9BrCxo=; b=ljfO4i3jmrLigIpYv1IlQcfokYiZj6viZo7Mdjp5VJRFSrIGbsDV7YUqmfcZYWWJtZ ONxr7hHRyqVqbXlMR7QDsP2c08kJedTjFsUGjMvegWSYELKnmRzCqj4+MWc8jjXvuBes 6d1qvRo64MJpXZNjQ/k6XvS34TIQPUyhzGpb2qowRf2vy+XVl4G97Ef4/kIPTRw+fp2y /TTS69HMB1GgjlfXTXeZ3mtoMoEVXUrMRDb6JYh3H2MCsBKB+D9lxGgzlalWRuRLmzNy Mi7xlRgypjenRDhS0RdNd+wXt5zwuzQSPtAM2qMVO2WTkHm5PVt/rRB2eWf3zin5ON2F CHmA== X-Gm-Message-State: AOJu0YySmjytw5GIijTHnsa8i//hPPq3K6UstfPuhL1LDlOiOvw/bGY5 XzOb8kxWGmqgdlkXy2dbR/3kPCAZNFV2jwAYD4c5moKLEQs2dJi8Z0sMlh/GMC8rmaAwixyQedf t7ooTSOk611nLM6h21nvdG83nQrSJKMQbvcnH8wXu3Je9MDcjvFUr3IH7yIV/vcDkbB+NKKWbrM htGY3twDn/ X-Gm-Gg: ATEYQzyYNn5YtJw/R06EBJLa0x6wpYQ2fFmXny35loqTfVdJpAxEg+XBww1b6V/9ZBU 8gVx4HLNbaKy/zDDfk4eU8yVkLmY/bgyuWWiAoNrova8f4h0UJBJwne2fb2dDQ/j0aFu4SzCJB9 qyRMWs0kBdAZeRaD/NT+W9OiPGfGd8hhkerq9mHAlwnBXnBmTa8ZaFsRIWRduzSisAl5H+RFCR+ +EWDvSVfEfAjNq/SdNMfvzKfkLj/C3yoWAZNYPu5rrBF1OTuTcqSciNTAqXP5kKQ6LoODe9G5jQ OXoe2gRuIwXs03Z1z7dITmjPuMjN3QlUzvGLJunNQketAjZZbZS1Z7FEQm110ej5h1KwVi1pmZt c9cFYuyJLtM6FnnxgDOOv6bGAcE+CbmT67mhQ9V/dhH6e+tDHmWWjdzkevM+I1B4lcK+URbenbt EHayvRhqUkcSdDcW/qmcIHmsD17aIPRxqn1Q== X-Received: by 2002:a05:6102:292a:b0:5f5:2e63:f574 with SMTP id ada2fe7eead31-5ffe61e56f1mr5982796137.29.1773144073684; Tue, 10 Mar 2026 05:01:13 -0700 (PDT) X-Received: by 2002:a05:6102:292a:b0:5f5:2e63:f574 with SMTP id ada2fe7eead31-5ffe61e56f1mr5982644137.29.1773144071586; Tue, 10 Mar 2026 05:01:11 -0700 (PDT) Received: from t14s (2001-1c00-0c32-7800-beb3-9058-f5fe-3f2e.cable.dynamic.v6.ziggo.nl. [2001:1c00:c32:7800:beb3:9058:f5fe:3f2e]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48541aa7aacsm87843405e9.13.2026.03.10.05.01.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2026 05:01:10 -0700 (PDT) From: Hans de Goede To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Hans de Goede Subject: [PATCH v7 1/5] software_isp: swstats_cpu: Prepare for multi-threading support Date: Tue, 10 Mar 2026 13:01:02 +0100 Message-ID: <20260310120106.79922-2-johannes.goede@oss.qualcomm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310120106.79922-1-johannes.goede@oss.qualcomm.com> References: <20260310120106.79922-1-johannes.goede@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzEwMDEwNCBTYWx0ZWRfX5HIBTM3/0TIu tVtvqIAJSfUB58Z5FVD/dSlbTD8+0JAgsn5FXsrwpkm7FxSWf6LQ0LQ7BGIDlzJF9WxgE/jXWpM ewTfX2Y/nho8eWRMhMnPlNHduUSaYrC9noQRuj/C2ewOlL8h9a7W8v/Ukoea5KzfGV0PJC6bCKg Fg6CS5GrE/MtMtxchxfAESdpHA3VW52MSjOaKjmfS9djEUi2bUfkA7q4/ph9JdlKQAbXlfzcS8x JsMkRXq5+7R0c9DEgXXC7KNatCFlVnSq5A4kQ5pNFRyG/EhDuNBI1roFbfs7FoGzUJVyOseWvvY rguLffFWe0Bw88W1NVMVrOC5Z+MlI+ppwN4RFKcBCZsKYFwqnkhUgINMIWvWMllK21xNZ6r7YFU MJaVJae9ruYUPn1n7xE0fAHyOYCOA5FPyJ2rpz04EZNOaSMnwveXprDrImYkwZ0LMPm+eOp1DwG FhMYPD9oU+F6viekkvQ== X-Authority-Analysis: v=2.4 cv=GtFPO01C c=1 sm=1 tr=0 ts=69b0080c cx=c_pps a=UbhLPJ621ZpgOD2l3yZY1w==:117 a=xqWC_Br6kY4A:10 a=Yq5XynenixoA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=20KFwNOVAAAA:8 a=EUspDBNiAAAA:8 a=VvikW9XIONpR7lsxkDIA:9 a=TOPH6uDL9cOC6tEoww4z:22 X-Proofpoint-ORIG-GUID: 66G8xABiWie1LNNBnPyj6IjKjo6AE9-9 X-Proofpoint-GUID: 66G8xABiWie1LNNBnPyj6IjKjo6AE9-9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293, Aquarius:18.0.1143, Hydra:6.1.51, FMLib:17.12.100.49 definitions=2026-03-10_02,2026-03-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 phishscore=0 malwarescore=0 clxscore=1015 lowpriorityscore=0 spamscore=0 suspectscore=0 priorityscore=1501 impostorscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603100104 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" Make the storage used to accumulate the RGB sums and the Y histogram value a vector of SwIspStats objects instead of a single object so that when using multi-threading every thread can use its own storage to collect intermediate stats to avoid cache-line bouncing. Benchmarking with the GPU-ISP which does separate swstats benchmarking, on the Arduino Uno-Q which has a weak CPU which is good for performance testing, shows 20ms to generate stats for a 3272x2464 frame both before and after this change. Reviewed-by: Milan Zamazal Signed-off-by: Hans de Goede --- Changes in v4: - Use const in for (const auto &s : stats_) {} in SwStatsCpu::finishFrame() - Add Milan's Reviewed-by Changes in v3: - Use for (auto &s : stats_) {} Changes in v2: - Move the allocation of the vector of SwIspStats objects to inside the SwStatsCpu class, controlled by a configure() arguments instead of making the caller allocate the objects --- .../internal/software_isp/swstats_cpu.h | 25 ++++----- src/libcamera/software_isp/swstats_cpu.cpp | 54 +++++++++++++------ 2 files changed, 50 insertions(+), 29 deletions(-) diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h index 64b3e23f5..feee92f99 100644 --- a/include/libcamera/internal/software_isp/swstats_cpu.h +++ b/include/libcamera/internal/software_isp/swstats_cpu.h @@ -12,6 +12,7 @@ #pragma once #include +#include #include @@ -51,13 +52,13 @@ public: const Size &patternSize() { return patternSize_; } - int configure(const StreamConfiguration &inputCfg); + int configure(const StreamConfiguration &inputCfg, unsigned int statsBufferCount = 1); void setWindow(const Rectangle &window); void startFrame(uint32_t frame); void finishFrame(uint32_t frame, uint32_t bufferId); void processFrame(uint32_t frame, uint32_t bufferId, FrameBuffer *input); - void processLine0(uint32_t frame, unsigned int y, const uint8_t *src[]) + void processLine0(uint32_t frame, unsigned int y, const uint8_t *src[], unsigned int statsBufferIndex = 0) { if (frame % kStatPerNumFrames) return; @@ -66,10 +67,10 @@ public: y >= (window_.y + window_.height)) return; - (this->*stats0_)(src); + (this->*stats0_)(src, stats_[statsBufferIndex]); } - void processLine2(uint32_t frame, unsigned int y, const uint8_t *src[]) + void processLine2(uint32_t frame, unsigned int y, const uint8_t *src[], unsigned int statsBufferIndex = 0) { if (frame % kStatPerNumFrames) return; @@ -78,25 +79,25 @@ public: y >= (window_.y + window_.height)) return; - (this->*stats2_)(src); + (this->*stats2_)(src, stats_[statsBufferIndex]); } Signal statsReady; private: - using statsProcessFn = void (SwStatsCpu::*)(const uint8_t *src[]); + using statsProcessFn = void (SwStatsCpu::*)(const uint8_t *src[], SwIspStats &stats); using processFrameFn = void (SwStatsCpu::*)(MappedFrameBuffer &in); int setupStandardBayerOrder(BayerFormat::Order order); /* Bayer 8 bpp unpacked */ - void statsBGGR8Line0(const uint8_t *src[]); + void statsBGGR8Line0(const uint8_t *src[], SwIspStats &stats); /* Bayer 10 bpp unpacked */ - void statsBGGR10Line0(const uint8_t *src[]); + void statsBGGR10Line0(const uint8_t *src[], SwIspStats &stats); /* Bayer 12 bpp unpacked */ - void statsBGGR12Line0(const uint8_t *src[]); + void statsBGGR12Line0(const uint8_t *src[], SwIspStats &stats); /* Bayer 10 bpp packed */ - void statsBGGR10PLine0(const uint8_t *src[]); - void statsGBRG10PLine0(const uint8_t *src[]); + void statsBGGR10PLine0(const uint8_t *src[], SwIspStats &stats); + void statsGBRG10PLine0(const uint8_t *src[], SwIspStats &stats); void processBayerFrame2(MappedFrameBuffer &in); @@ -116,8 +117,8 @@ private: unsigned int xShift_; unsigned int stride_; + std::vector stats_; SharedMemObject sharedStats_; - SwIspStats stats_; Benchmark bench_; }; diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp index 1cedcfbc1..ded0dcf1a 100644 --- a/src/libcamera/software_isp/swstats_cpu.cpp +++ b/src/libcamera/software_isp/swstats_cpu.cpp @@ -74,11 +74,12 @@ namespace libcamera { */ /** - * \fn void SwStatsCpu::processLine0(uint32_t frame, unsigned int y, const uint8_t *src[]) + * \fn void SwStatsCpu::processLine0(uint32_t frame, unsigned int y, const uint8_t *src[], unsigned int statsBufferIndex = 0) * \brief Process line 0 * \param[in] frame The frame number * \param[in] y The y coordinate. * \param[in] src The input data. + * \param[in] statsBufferIndex Index of stats buffer to use for multi-threading. * * This function processes line 0 for input formats with * patternSize height == 1. @@ -97,14 +98,18 @@ namespace libcamera { * to the line in plane 0, etc. * * For non Bayer single plane input data only a single src pointer is required. + * + * The statsBufferIndex value must be less than the statsBufferCount value passed + * to configure(). */ /** - * \fn void SwStatsCpu::processLine2(uint32_t frame, unsigned int y, const uint8_t *src[]) + * \fn void SwStatsCpu::processLine2(uint32_t frame, unsigned int y, const uint8_t *src[], unsigned int statsBufferIndex = 0) * \brief Process line 2 and 3 * \param[in] frame The frame number * \param[in] y The y coordinate. * \param[in] src The input data. + * \param[in] statsBufferIndex Index of stats buffer to use for multi-threading. * * This function processes line 2 and 3 for input formats with * patternSize height == 4. @@ -182,14 +187,14 @@ static constexpr unsigned int kBlueYMul = 29; /* 0.114 * 256 */ yVal = r * kRedYMul; \ yVal += g * kGreenYMul; \ yVal += b * kBlueYMul; \ - stats_.yHistogram[yVal * SwIspStats::kYHistogramSize / (256 * 256 * (div))]++; + stats.yHistogram[yVal * SwIspStats::kYHistogramSize / (256 * 256 * (div))]++; #define SWSTATS_FINISH_LINE_STATS() \ - stats_.sum_.r() += sumR; \ - stats_.sum_.g() += sumG; \ - stats_.sum_.b() += sumB; + stats.sum_.r() += sumR; \ + stats.sum_.g() += sumG; \ + stats.sum_.b() += sumB; -void SwStatsCpu::statsBGGR8Line0(const uint8_t *src[]) +void SwStatsCpu::statsBGGR8Line0(const uint8_t *src[], SwIspStats &stats) { const uint8_t *src0 = src[1] + window_.x; const uint8_t *src1 = src[2] + window_.x; @@ -214,7 +219,7 @@ void SwStatsCpu::statsBGGR8Line0(const uint8_t *src[]) SWSTATS_FINISH_LINE_STATS() } -void SwStatsCpu::statsBGGR10Line0(const uint8_t *src[]) +void SwStatsCpu::statsBGGR10Line0(const uint8_t *src[], SwIspStats &stats) { const uint16_t *src0 = (const uint16_t *)src[1] + window_.x; const uint16_t *src1 = (const uint16_t *)src[2] + window_.x; @@ -240,7 +245,7 @@ void SwStatsCpu::statsBGGR10Line0(const uint8_t *src[]) SWSTATS_FINISH_LINE_STATS() } -void SwStatsCpu::statsBGGR12Line0(const uint8_t *src[]) +void SwStatsCpu::statsBGGR12Line0(const uint8_t *src[], SwIspStats &stats) { const uint16_t *src0 = (const uint16_t *)src[1] + window_.x; const uint16_t *src1 = (const uint16_t *)src[2] + window_.x; @@ -266,7 +271,7 @@ void SwStatsCpu::statsBGGR12Line0(const uint8_t *src[]) SWSTATS_FINISH_LINE_STATS() } -void SwStatsCpu::statsBGGR10PLine0(const uint8_t *src[]) +void SwStatsCpu::statsBGGR10PLine0(const uint8_t *src[], SwIspStats &stats) { const uint8_t *src0 = src[1] + window_.x * 5 / 4; const uint8_t *src1 = src[2] + window_.x * 5 / 4; @@ -292,7 +297,7 @@ void SwStatsCpu::statsBGGR10PLine0(const uint8_t *src[]) SWSTATS_FINISH_LINE_STATS() } -void SwStatsCpu::statsGBRG10PLine0(const uint8_t *src[]) +void SwStatsCpu::statsGBRG10PLine0(const uint8_t *src[], SwIspStats &stats) { const uint8_t *src0 = src[1] + window_.x * 5 / 4; const uint8_t *src1 = src[2] + window_.x * 5 / 4; @@ -332,8 +337,10 @@ void SwStatsCpu::startFrame(uint32_t frame) if (window_.width == 0) LOG(SwStatsCpu, Error) << "Calling startFrame() without setWindow()"; - stats_.sum_ = RGB({ 0, 0, 0 }); - stats_.yHistogram.fill(0); + for (auto &s : stats_) { + s.sum_ = RGB({ 0, 0, 0 }); + s.yHistogram.fill(0); + } } /** @@ -345,8 +352,19 @@ void SwStatsCpu::startFrame(uint32_t frame) */ void SwStatsCpu::finishFrame(uint32_t frame, uint32_t bufferId) { - stats_.valid = frame % kStatPerNumFrames == 0; - *sharedStats_ = stats_; + bool valid = frame % kStatPerNumFrames == 0; + + if (valid) { + sharedStats_->sum_ = RGB({ 0, 0, 0 }); + sharedStats_->yHistogram.fill(0); + for (const auto &s : stats_) { + sharedStats_->sum_ += s.sum_; + for (unsigned int j = 0; j < SwIspStats::kYHistogramSize; j++) + sharedStats_->yHistogram[j] += s.yHistogram[j]; + } + } + + sharedStats_->valid = valid; statsReady.emit(frame, bufferId); } @@ -389,12 +407,14 @@ int SwStatsCpu::setupStandardBayerOrder(BayerFormat::Order order) /** * \brief Configure the statistics object for the passed in input format * \param[in] inputCfg The input format + * \param[in] statsBufferCount number of internal stats buffers to use for multi-threading * * \return 0 on success, a negative errno value on failure */ -int SwStatsCpu::configure(const StreamConfiguration &inputCfg) +int SwStatsCpu::configure(const StreamConfiguration &inputCfg, unsigned int statsBufferCount) { stride_ = inputCfg.stride; + stats_.resize(statsBufferCount); BayerFormat bayerFormat = BayerFormat::fromPixelFormat(inputCfg.pixelFormat); @@ -504,7 +524,7 @@ void SwStatsCpu::processBayerFrame2(MappedFrameBuffer &in) /* linePointers[0] is not used by any stats0_ functions */ linePointers[1] = src; linePointers[2] = src + stride_; - (this->*stats0_)(linePointers); + (this->*stats0_)(linePointers, stats_[0]); src += stride_ * 2; } } From patchwork Tue Mar 10 12:01:03 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 26273 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 ED606BE086 for ; Tue, 10 Mar 2026 12:01:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A01FB6267D; Tue, 10 Mar 2026 13:01:23 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.b="mgEZZKtM"; dkim=pass (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="jEyYffwT"; dkim-atps=neutral Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2B8426265B for ; Tue, 10 Mar 2026 13:01:19 +0100 (CET) Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 62AARLod4188954 for ; Tue, 10 Mar 2026 12:01:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 849Ig9hDrdaC3xtXbjJ4ercO1l4j8X7pEhIvB+RBz3Q=; b=mgEZZKtMB3Xr+jhf fLLvOrDYTjd2n+kN9J/vO7fE1Qcz4VBoJOegh2fn1wvwo8Ifmua3WRC2OUmKmcnS OxsC9O4eAJ2DkioRCDzxhfWvH4E611OKQ40v65H+Auo2KDKWpOP0zXwS4GEpRhiN sBslAbTDDqn2oybxOPmSV4+Suuy2vD90S6TpWxhk6iyQKCdttA2dYqImAF0cbFry DNleScnxKYs1OPMilKhDq/sDRDmtDKKYuKH08MvjZs40C6vzdpUBZV7Q43AoJaAX wO4mZglE8yVXiO35JAXD+kfg4fre9F8ism9Prq23tBjxI2GspqeWLyR8ry43Ow/8 8MlkNw== Received: from mail-vs1-f69.google.com (mail-vs1-f69.google.com [209.85.217.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4cthjf0c0m-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Tue, 10 Mar 2026 12:01:17 +0000 (GMT) Received: by mail-vs1-f69.google.com with SMTP id ada2fe7eead31-5fff50a4ac4so24034644137.2 for ; Tue, 10 Mar 2026 05:01:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1773144076; x=1773748876; 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=849Ig9hDrdaC3xtXbjJ4ercO1l4j8X7pEhIvB+RBz3Q=; b=jEyYffwTnYCbit+bnVpFbq87KjsQPsfUIA09ylwNfLJmlYl2Svit2bJ2Wg6EUIcYHQ y1bUAhSTyVxKwP/ThskRF2i8x/MmpKdL3z1I977gJS4pSJVHOrLNMZxrGulKoOMT4pD9 ckQ2kqeHbpdBxd77gGMi8PNOxChzRZHBerJswTo8xpxdfq0Eoop9nGRVrTnFI9D7rtll FnFzokfq57mZ+j1EX1PtG0a8R3PKOvHjD6oe0ECaXFB0f1FMFoxJIRzZutUM07BDRfV+ OuM4Qf+Wh8zTTG5PISidlJd0Jwt6W3CYNT0NzOGX+rfq0qATcS2iMqVZ1ttISevtI86u HqhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773144076; x=1773748876; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=849Ig9hDrdaC3xtXbjJ4ercO1l4j8X7pEhIvB+RBz3Q=; b=Bl0jXMolZZvrmvQQ7aGFct4BW2lEDQi036UMJFUvk66ZKdfO1wcdYcsY0P1ghV+A2p aVAFDcGdm9Ne/MePwujNK3PjVOS46/ZILuvSSgYEtqhvu4Cz+KC+q1cqw0DRh+Gtl/ui Rac4IVCS8b30ZuMfAJOnu7l0VmrIjgkgj4c/zIO7U4+9YzyXuWiNu8zREXzvXmStzoSt JQwx1wkbPhY/EnY0XyHf3Bpdc/xCQv1os1QzPI4vbq3Ur7ioQYgvWjVtk20PqtmJYWki MwOEu2o56vDVEEvo9f8Q3TNNLWzvSCvNFO9Q2+CE1QcZkKa8VbaKSelKwHgSX4msKBg/ eIaw== X-Gm-Message-State: AOJu0YyCPli/QD4VDlnO8JdwASXGR5blNgy53d/1R7FQMa6zBdx05zXs 8TyZ4aAbw7LlrXMQB635+VTD6zc/qJKse88L860RGJ5/rS/yIT7oER70fHyr+teVUDOaG4219zv QtCn16LvowiAiqbz/yU++1zZcbd6xMhl+BGF/4t4Ogn4b+6gS3WPX/zpGGrJyejIV4JlaDALrL8 n6b3Nf/2Jp X-Gm-Gg: ATEYQzx/tpHSDP57291Ny3aVn/sL20vmPrF74oLAZH4iG+n4624rZKKt9MSm3gTHNNn UyQ1S6YcmlhpypxvdTF/Bu8Ji66almupXkdOnsYruQ7ARKgv0OOiGrDZG4zv1RpsstuEJt1wvk/ 7GYF4IQWPaNFbzrgWOqp4uXKEvxzNdO7/fMaOvuEVOGC1vwRK8CIWpVVs0K5dFRlQbcQuIy2iQG SrjE251Fxt7k5kzOv6uigHkIeVcHMvfTBmuj47d5CAmPfuemVd+ecqQ9dEqtTtJ2eQmtaXZ/a81 PSMiYfhlG5R/o9cwNoF+BUwmy7gxTHp6oLsQgeoEjCnBr2/vHXx5U3LolkZS/U9TsyDKu2FB2pZ nZfNDjSjQo2YgFWHLchPCV0vRZKgnB/O9SeiblDOIPj1h/V/16qB8xldJeF2qeGzl3gmH31+T8o h3IsN03tzWjwFWS1o7GzS2zNKxp2ijPalb9g== X-Received: by 2002:a05:6102:a54:b0:5f5:5c2e:59ba with SMTP id ada2fe7eead31-5ffe61fde73mr6965576137.33.1773144075307; Tue, 10 Mar 2026 05:01:15 -0700 (PDT) X-Received: by 2002:a05:6102:a54:b0:5f5:5c2e:59ba with SMTP id ada2fe7eead31-5ffe61fde73mr6965359137.33.1773144073165; Tue, 10 Mar 2026 05:01:13 -0700 (PDT) Received: from t14s (2001-1c00-0c32-7800-beb3-9058-f5fe-3f2e.cable.dynamic.v6.ziggo.nl. [2001:1c00:c32:7800:beb3:9058:f5fe:3f2e]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48541aa7aacsm87843405e9.13.2026.03.10.05.01.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2026 05:01:12 -0700 (PDT) From: Hans de Goede To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Hans de Goede , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [PATCH v7 2/5] software_isp: debayer_cpu: Add DebayerCpuThread class Date: Tue, 10 Mar 2026 13:01:03 +0100 Message-ID: <20260310120106.79922-3-johannes.goede@oss.qualcomm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310120106.79922-1-johannes.goede@oss.qualcomm.com> References: <20260310120106.79922-1-johannes.goede@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-GUID: ftTIau3v28n4gbdfqqaKyCVTHdbLcB-O X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzEwMDEwNCBTYWx0ZWRfX/sYxQM9I38n2 zUBMB2x+NnpsTlnwMPKes/GgSNotb/g8GRR5Kas4jQfwy8Gi9I9FTeOLK1zjGmaMkBIv9p+7IJ8 WpzrzGHOwbs0CHIiMLFqcdc7js8NvEeWUi9bbust2rAN3zzDTLtR07O3knbonfZbek0eeW+PkbV wexHuTh/6EuWVt1PLNaUEOIyNHyIzDNcrZ6bp96oMU9QZr1ZD7DNhLWU0H0X7DuPLDhw0YDfNax 2tigZ4HKUnHVECeeT9xaHW22DakRGYMWOPfe/PEapn1Honr53Ra/WTg7l/DYn1BxrBZIE60W/4h xaZl2Iupm3KU711oOOhWZyiAW/yJsRmAOTcqURZezsLSSSe+e6A+JjzFzxDDT4bgaG4ytolfkMe vSyOqZcvvGBVqb2EaN+WfdmYA8Ng/wUIl0ZswlpPZhdeJRqY71PNyo/joAcUP9tMEc9aRGoja/I H+dL7A2goVPxIQt5zeg== X-Authority-Analysis: v=2.4 cv=A71h/qWG c=1 sm=1 tr=0 ts=69b0080d cx=c_pps a=5HAIKLe1ejAbszaTRHs9Ug==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=Yq5XynenixoA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=P1BnusSwAAAA:8 a=20KFwNOVAAAA:8 a=EUspDBNiAAAA:8 a=Ba8D0n3WaO7QZ3tp1_0A:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=gYDTvv6II1OnSo0itH1n:22 a=D0XLA9XvdZm18NrgonBM:22 X-Proofpoint-ORIG-GUID: ftTIau3v28n4gbdfqqaKyCVTHdbLcB-O X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293, Aquarius:18.0.1143, Hydra:6.1.51, FMLib:17.12.100.49 definitions=2026-03-10_02,2026-03-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 phishscore=0 clxscore=1015 suspectscore=0 bulkscore=0 adultscore=0 spamscore=0 lowpriorityscore=0 priorityscore=1501 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603100104 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" Add a DebayerCpuThreadclass and use this in the inner render loop. This contains data which needs to be separate per thread. This is a preparation patch for making DebayerCpu support multi-threading. Benchmarking on the Arduino Uno-Q with a weak CPU which is good for performance testing, shows 146-147ms per 3272x2464 frame both before and after this change, with things maybe being 0.5 ms slower after this change. Tested-by: Barnabás Pőcze # ThinkPad X1 Yoga Gen 7 + ov2740 Reviewed-by: Milan Zamazal Signed-off-by: Hans de Goede --- Changes in v7: - Small update to DebayerCpuThread::configure() doc - Add missing space between type and name for threads_ declaration Changes in v4: - Move kMaxLineBuffers constant to DebayerCpuThread class - Add Milan's Reviewed-by Changes in v3: - Use std::unique_ptr for the DebayerCpuThread pointers - Document new DebayerCpuThread class - Make DebayerCpuThread inherit from both Thread and Object Changes in v2: - Replace the DebayerCpuThreadData struct from v1 with a DebayerCpuThread class, derived from Object to allow calling invokeMethod for thread re-use in followup patches - As part of this also move a bunch of methods which primarily deal with per thread data: setupInputMemcpy(), shiftLinePointers(), memcpyNextLine(), process*() to the new DebayerCpuThread class --- src/libcamera/software_isp/debayer_cpu.cpp | 247 +++++++++++++++------ src/libcamera/software_isp/debayer_cpu.h | 23 +- 2 files changed, 191 insertions(+), 79 deletions(-) diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index e7b012105..fc3305d2e 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -18,6 +18,8 @@ #include +#include + #include #include "libcamera/internal/bayer_format.h" @@ -27,6 +29,55 @@ namespace libcamera { +/** + * \brief Class representing one CPU debayering thread + * + * Implementation for CPU based debayering threads. + */ +class DebayerCpuThread : public Thread, public Object +{ +public: + DebayerCpuThread(DebayerCpu *debayer, unsigned int threadIndex, + bool enableInputMemcpy); + + void configure(unsigned int yStart, unsigned int yEnd); + void process(uint32_t frame, const uint8_t *src, uint8_t *dst); + +private: + void setupInputMemcpy(const uint8_t *linePointers[]); + void shiftLinePointers(const uint8_t *linePointers[], const uint8_t *src); + void memcpyNextLine(const uint8_t *linePointers[]); + void process2(uint32_t frame, const uint8_t *src, uint8_t *dst); + void process4(uint32_t frame, const uint8_t *src, uint8_t *dst); + + /* Max. supported Bayer pattern height is 4, debayering this requires 5 lines */ + static constexpr unsigned int kMaxLineBuffers = 5; + + DebayerCpu *debayer_; + unsigned int threadIndex_; + unsigned int yStart_; + unsigned int yEnd_; + unsigned int lineBufferLength_; + unsigned int lineBufferPadding_; + unsigned int lineBufferIndex_; + std::vector lineBuffers_[kMaxLineBuffers]; + bool enableInputMemcpy_; +}; + +/** + * \brief Construct a DebayerCpuThread object + * \param[in] debayer pointer back to the DebayerCpuObject this thread belongs to + * \param[in] threadIndex 0 .. n thread-index value for the thread + * \param[in] enableInputMemcpy when set copy input data to a heap buffer before use + */ +DebayerCpuThread::DebayerCpuThread(DebayerCpu *debayer, unsigned int threadIndex, + bool enableInputMemcpy) + : Thread("DebayerCpu:" + std::to_string(threadIndex)), + debayer_(debayer), threadIndex_(threadIndex), + enableInputMemcpy_(enableInputMemcpy) +{ +} + /** * \class DebayerCpu * \brief Class for debayering on the CPU @@ -53,8 +104,14 @@ DebayerCpu::DebayerCpu(std::unique_ptr stats, const GlobalConfigurat * \todo Make memcpy automatic based on runtime detection of platform * capabilities. */ - enableInputMemcpy_ = + bool enableInputMemcpy = configuration.option({ "software_isp", "copy_input_buffer" }).value_or(true); + + /* Just one thread object for now, which will be called inline rather than async */ + threads_.resize(1); + + for (unsigned int i = 0; i < threads_.size(); i++) + threads_[i] = std::make_unique(this, i, enableInputMemcpy); } DebayerCpu::~DebayerCpu() = default; @@ -484,7 +541,7 @@ int DebayerCpu::configure(const StreamConfiguration &inputCfg, if (getInputConfig(inputCfg.pixelFormat, inputConfig_) != 0) return -EINVAL; - if (stats_->configure(inputCfg) != 0) + if (stats_->configure(inputCfg, threads_.size()) != 0) return -EINVAL; const Size &statsPatternSize = stats_->patternSize(); @@ -548,17 +605,43 @@ int DebayerCpu::configure(const StreamConfiguration &inputCfg, */ stats_->setWindow(Rectangle(window_.size())); + unsigned int yStart = 0; + unsigned int linesPerThread = (window_.height / threads_.size()) & + ~(inputConfig_.patternSize.height - 1); + unsigned int i; + + for (i = 0; i < (threads_.size() - 1); i++) { + threads_[i]->configure(yStart, yStart + linesPerThread); + yStart += linesPerThread; + } + threads_[i]->configure(yStart, window_.height); + + return 0; +} + +/** + * \brief Configure thread to process a specific part of the image + * \param[in] yStart y coordinate of first line to process + * \param[in] yEnd y coordinate of the line at which to stop processing + * + * Configure the thread to process lines from yStart to yEnd - 1. + */ +void DebayerCpuThread::configure(unsigned int yStart, unsigned int yEnd) +{ + Debayer::DebayerInputConfig &inputConfig = debayer_->inputConfig_; + + yStart_ = yStart; + yEnd_ = yEnd; + /* pad with patternSize.Width on both left and right side */ - lineBufferPadding_ = inputConfig_.patternSize.width * inputConfig_.bpp / 8; - lineBufferLength_ = window_.width * inputConfig_.bpp / 8 + + lineBufferPadding_ = inputConfig.patternSize.width * inputConfig.bpp / 8; + lineBufferLength_ = debayer_->window_.width * inputConfig.bpp / 8 + 2 * lineBufferPadding_; if (enableInputMemcpy_) { - for (unsigned int i = 0; i <= inputConfig_.patternSize.height; i++) + for (unsigned int i = 0; i <= inputConfig.patternSize.height; i++) lineBuffers_[i].resize(lineBufferLength_); } - - return 0; } /* @@ -599,9 +682,9 @@ DebayerCpu::strideAndFrameSize(const PixelFormat &outputFormat, const Size &size return std::make_tuple(stride, stride * size.height); } -void DebayerCpu::setupInputMemcpy(const uint8_t *linePointers[]) +void DebayerCpuThread::setupInputMemcpy(const uint8_t *linePointers[]) { - const unsigned int patternHeight = inputConfig_.patternSize.height; + const unsigned int patternHeight = debayer_->inputConfig_.patternSize.height; if (!enableInputMemcpy_) return; @@ -617,20 +700,20 @@ void DebayerCpu::setupInputMemcpy(const uint8_t *linePointers[]) lineBufferIndex_ = patternHeight; } -void DebayerCpu::shiftLinePointers(const uint8_t *linePointers[], const uint8_t *src) +void DebayerCpuThread::shiftLinePointers(const uint8_t *linePointers[], const uint8_t *src) { - const unsigned int patternHeight = inputConfig_.patternSize.height; + const unsigned int patternHeight = debayer_->inputConfig_.patternSize.height; for (unsigned int i = 0; i < patternHeight; i++) linePointers[i] = linePointers[i + 1]; - linePointers[patternHeight] = src + - (patternHeight / 2) * (int)inputConfig_.stride; + linePointers[patternHeight] = + src + (patternHeight / 2) * (int)debayer_->inputConfig_.stride; } -void DebayerCpu::memcpyNextLine(const uint8_t *linePointers[]) +void DebayerCpuThread::memcpyNextLine(const uint8_t *linePointers[]) { - const unsigned int patternHeight = inputConfig_.patternSize.height; + const unsigned int patternHeight = debayer_->inputConfig_.patternSize.height; if (!enableInputMemcpy_) return; @@ -643,23 +726,48 @@ void DebayerCpu::memcpyNextLine(const uint8_t *linePointers[]) lineBufferIndex_ = (lineBufferIndex_ + 1) % (patternHeight + 1); } -void DebayerCpu::process2(uint32_t frame, const uint8_t *src, uint8_t *dst) +/** + * \brief Process part of the image assigned to this debayer thread + * \param[in] frame The frame number + * \param[in] src The source buffer + * \param[in] dst The destination buffer + */ +void DebayerCpuThread::process(uint32_t frame, const uint8_t *src, uint8_t *dst) { - unsigned int yEnd = window_.height; + Rectangle &window = debayer_->window_; + + /* Adjust src to top left corner of the window */ + src += (window.y + yStart_) * debayer_->inputConfig_.stride + + window.x * debayer_->inputConfig_.bpp / 8; + /* Adjust dst for yStart_ */ + dst += yStart_ * debayer_->outputConfig_.stride; + + if (debayer_->inputConfig_.patternSize.height == 2) + process2(frame, src, dst); + else + process4(frame, src, dst); +} + +void DebayerCpuThread::process2(uint32_t frame, const uint8_t *src, uint8_t *dst) +{ + unsigned int outputStride = debayer_->outputConfig_.stride; + unsigned int inputStride = debayer_->inputConfig_.stride; + Rectangle &window = debayer_->window_; + unsigned int yEnd = yEnd_; /* Holds [0] previous- [1] current- [2] next-line */ const uint8_t *linePointers[3]; - /* Adjust src to top left corner of the window */ - src += window_.y * inputConfig_.stride + window_.x * inputConfig_.bpp / 8; - /* [x] becomes [x - 1] after initial shiftLinePointers() call */ - if (window_.y) { - linePointers[1] = src - inputConfig_.stride; /* previous-line */ + if (window.y + yStart_) { + linePointers[1] = src - inputStride; /* previous-line */ linePointers[2] = src; } else { - /* window_.y == 0, use the next line as prev line */ - linePointers[1] = src + inputConfig_.stride; + /* Top line, use the next line as prev line */ + linePointers[1] = src + inputStride; linePointers[2] = src; + } + + if (window.y == 0 && yEnd_ == window.height) { /* * Last 2 lines also need special handling. * (And configure() ensures that yEnd >= 2.) @@ -669,83 +777,93 @@ void DebayerCpu::process2(uint32_t frame, const uint8_t *src, uint8_t *dst) setupInputMemcpy(linePointers); - for (unsigned int y = 0; y < yEnd; y += 2) { + /* + * Note y is the line-number *inside* the window, since stats_' window + * is the stats window inside/relative to the debayer window. IOW for + * single thread rendering y goes from 0 to window.height. + */ + for (unsigned int y = yStart_; y < yEnd; y += 2) { shiftLinePointers(linePointers, src); memcpyNextLine(linePointers); - stats_->processLine0(frame, y, linePointers); - (this->*debayer0_)(dst, linePointers); - src += inputConfig_.stride; - dst += outputConfig_.stride; + debayer_->stats_->processLine0(frame, y, linePointers, threadIndex_); + debayer_->debayer0(dst, linePointers); + src += inputStride; + dst += outputStride; shiftLinePointers(linePointers, src); memcpyNextLine(linePointers); - (this->*debayer1_)(dst, linePointers); - src += inputConfig_.stride; - dst += outputConfig_.stride; + debayer_->debayer1(dst, linePointers); + src += inputStride; + dst += outputStride; } - if (window_.y == 0) { + if (window.y == 0 && yEnd_ == window.height) { shiftLinePointers(linePointers, src); memcpyNextLine(linePointers); - stats_->processLine0(frame, yEnd, linePointers); - (this->*debayer0_)(dst, linePointers); - src += inputConfig_.stride; - dst += outputConfig_.stride; + debayer_->stats_->processLine0(frame, yEnd, linePointers, threadIndex_); + debayer_->debayer0(dst, linePointers); + src += inputStride; + dst += outputStride; shiftLinePointers(linePointers, src); /* next line may point outside of src, use prev. */ linePointers[2] = linePointers[0]; - (this->*debayer1_)(dst, linePointers); - src += inputConfig_.stride; - dst += outputConfig_.stride; + debayer_->debayer1(dst, linePointers); + src += inputStride; + dst += outputStride; } } -void DebayerCpu::process4(uint32_t frame, const uint8_t *src, uint8_t *dst) +void DebayerCpuThread::process4(uint32_t frame, const uint8_t *src, uint8_t *dst) { + unsigned int outputStride = debayer_->outputConfig_.stride; + unsigned int inputStride = debayer_->inputConfig_.stride; + /* * This holds pointers to [0] 2-lines-up [1] 1-line-up [2] current-line * [3] 1-line-down [4] 2-lines-down. */ const uint8_t *linePointers[5]; - /* Adjust src to top left corner of the window */ - src += window_.y * inputConfig_.stride + window_.x * inputConfig_.bpp / 8; - /* [x] becomes [x - 1] after initial shiftLinePointers() call */ - linePointers[1] = src - 2 * inputConfig_.stride; - linePointers[2] = src - inputConfig_.stride; + linePointers[1] = src - 2 * inputStride; + linePointers[2] = src - inputStride; linePointers[3] = src; - linePointers[4] = src + inputConfig_.stride; + linePointers[4] = src + inputStride; setupInputMemcpy(linePointers); - for (unsigned int y = 0; y < window_.height; y += 4) { + /* + * Note y is the line-number *inside* the window, since stats_' window + * is the stats window inside/relative to the debayer window. IOW for + * single thread rendering y goes from 0 to window.height. + */ + for (unsigned int y = yStart_; y < yEnd_; y += 4) { shiftLinePointers(linePointers, src); memcpyNextLine(linePointers); - stats_->processLine0(frame, y, linePointers); - (this->*debayer0_)(dst, linePointers); - src += inputConfig_.stride; - dst += outputConfig_.stride; + debayer_->stats_->processLine0(frame, y, linePointers, threadIndex_); + debayer_->debayer0(dst, linePointers); + src += inputStride; + dst += outputStride; shiftLinePointers(linePointers, src); memcpyNextLine(linePointers); - (this->*debayer1_)(dst, linePointers); - src += inputConfig_.stride; - dst += outputConfig_.stride; + debayer_->debayer1(dst, linePointers); + src += inputStride; + dst += outputStride; shiftLinePointers(linePointers, src); memcpyNextLine(linePointers); - stats_->processLine2(frame, y, linePointers); - (this->*debayer2_)(dst, linePointers); - src += inputConfig_.stride; - dst += outputConfig_.stride; + debayer_->stats_->processLine2(frame, y, linePointers, threadIndex_); + debayer_->debayer2(dst, linePointers); + src += inputStride; + dst += outputStride; shiftLinePointers(linePointers, src); memcpyNextLine(linePointers); - (this->*debayer3_)(dst, linePointers); - src += inputConfig_.stride; - dst += outputConfig_.stride; + debayer_->debayer3(dst, linePointers); + src += inputStride; + dst += outputStride; } } @@ -867,10 +985,7 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output stats_->startFrame(frame); - if (inputConfig_.patternSize.height == 2) - process2(frame, in.planes()[0].data(), out.planes()[0].data()); - else - process4(frame, in.planes()[0].data(), out.planes()[0].data()); + threads_[0]->process(frame, in.planes()[0].data(), out.planes()[0].data()); metadata.planes()[0].bytesused = out.planes()[0].size(); diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 7a6517462..8e57c273b 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -26,6 +26,7 @@ namespace libcamera { +class DebayerCpuThread; class DebayerCpu : public Debayer { public: @@ -44,6 +45,8 @@ public: const SharedFD &getStatsFD() { return stats_->getStatsFD(); } private: + friend class DebayerCpuThread; + /** * \brief Called to debayer 1 line of Bayer input data to output format * \param[out] dst Pointer to the start of the output line to write @@ -74,6 +77,11 @@ private: */ using debayerFn = void (DebayerCpu::*)(uint8_t *dst, const uint8_t *src[]); + void debayer0(uint8_t *dst, const uint8_t *src[]) { (this->*debayer0_)(dst, src); } + void debayer1(uint8_t *dst, const uint8_t *src[]) { (this->*debayer1_)(dst, src); } + void debayer2(uint8_t *dst, const uint8_t *src[]) { (this->*debayer2_)(dst, src); } + void debayer3(uint8_t *dst, const uint8_t *src[]) { (this->*debayer3_)(dst, src); } + /* 8-bit raw bayer format */ template void debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]); @@ -105,17 +113,9 @@ private: int setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputFormat, bool ccmEnabled); - void setupInputMemcpy(const uint8_t *linePointers[]); - void shiftLinePointers(const uint8_t *linePointers[], const uint8_t *src); - void memcpyNextLine(const uint8_t *linePointers[]); - void process2(uint32_t frame, const uint8_t *src, uint8_t *dst); - void process4(uint32_t frame, const uint8_t *src, uint8_t *dst); void updateGammaTable(const DebayerParams ¶ms); void updateLookupTables(const DebayerParams ¶ms); - /* Max. supported Bayer pattern height is 4, debayering this requires 5 lines */ - static constexpr unsigned int kMaxLineBuffers = 5; - static constexpr unsigned int kRGBLookupSize = 256; static constexpr unsigned int kGammaLookupSize = 1024; struct CcmColumn { @@ -142,12 +142,9 @@ private: debayerFn debayer3_; Rectangle window_; std::unique_ptr stats_; - std::vector lineBuffers_[kMaxLineBuffers]; - unsigned int lineBufferLength_; - unsigned int lineBufferPadding_; - unsigned int lineBufferIndex_; unsigned int xShift_; /* Offset of 0/1 applied to window_.x */ - bool enableInputMemcpy_; + + std::vector> threads_; }; } /* namespace libcamera */ From patchwork Tue Mar 10 12:01:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 26272 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 1A945BE086 for ; Tue, 10 Mar 2026 12:01:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DC92B62645; Tue, 10 Mar 2026 13:01:20 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.b="fF/rb/Ne"; dkim=pass (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="HL0w5Z1O"; dkim-atps=neutral Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F346C62626 for ; Tue, 10 Mar 2026 13:01:18 +0100 (CET) Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 62A9I8Vt2460651 for ; Tue, 10 Mar 2026 12:01:17 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= j8iK55wVYltfsPQzWGh2pIi5AXAitYIIZhZveZC8niU=; b=fF/rb/NeczPdcfpR gu7jEtVCj2eBGg3F9Se41p9kk/pUJXlJzoivPHbtS9yiG0FSYYy7sqep2qZPXsUR VO3dSI9BBNU8s6dmI8GODfdNs0CYVxhUl2j5m7+ujpLnBEWTGPGdHlFKmkyq/LDv GyZH1lP3Zo9nWKyhvfxx3caCk9lTH3MvFts/CT9n5VtEj//uWuHBas2JkK88Fia9 uc0G22krnlk9TxqzPShWiFh5UH3mG/CGrXhrQ/KoxQhMA+tg7XhPWN8myuAbTSRM ozvaIcGC89voDNypGEgNweyOf8LVs5Xr22mpJ3S3tHnhYCSwVgdW7f0d3M3UpIoN VFoqig== Received: from mail-vs1-f72.google.com (mail-vs1-f72.google.com [209.85.217.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4csyv1c5eg-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Tue, 10 Mar 2026 12:01:17 +0000 (GMT) Received: by mail-vs1-f72.google.com with SMTP id ada2fe7eead31-5ffbe27449cso34544749137.0 for ; Tue, 10 Mar 2026 05:01:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1773144076; x=1773748876; 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=j8iK55wVYltfsPQzWGh2pIi5AXAitYIIZhZveZC8niU=; b=HL0w5Z1O5oPySme9OkfgKqTKRdlBXodvbMurXYvJ/4o3w6AzGybDKMfE1vI3tbUbeb 9db0EFU2Xy32IWXewPWS2ElteS+cdA7yJHxarud09oFXRGxFnnMac6tSgSsAKJgpdrKW y8BHcB7lhgjbxyd8MtFXxplqqTMo189418sSYenECOiFOrmkV2/SykH1nWF6lLjBDoqB 2Ci4Z+RXacu9fPkYs+/clTyfRYLKruAsSqum0Gru9UqLoos+/2scGZW3MfMW5S1YqIkp AgIrwv1XEfaeRTn8nLKYQALGgDQIwWeliATzwKVebt9/1Xmn9cSzOCOReJnczwcqPnF7 PYzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773144076; x=1773748876; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=j8iK55wVYltfsPQzWGh2pIi5AXAitYIIZhZveZC8niU=; b=bgd+UlwvXxmDR0rce/LjC7IllLL/dduZUdzVQE/oUNJTNTk/ktPrdimRdj6lI65anU 8iNVAi1VdpvlM/opfPozN8ByVG/WodVBtKt1rh7Ciz7yxFSJ7LQHRs6tDIfSgOLBXIJ7 QhfWlqzU2oMVGZo56gCU7uobEBpl5OS97lAEwY0+za6BIIn4JCnbrkcSzwaU1C75Jbrr oLdS9gep8NVQKSVzUNc/sXt6KdHpcVWlxVi5UFBC0w/hoze9vPPL4OPQpMCNlWzk/rPF yw3Mb/clOmB2ODv0lL/Rjnrpz5d4gAez0Dp8x6epye8cqwcyODbt8ratV45p4pLhN7Ru Txlw== X-Gm-Message-State: AOJu0Yyzc5PmszAsiW2CVdt8u2qQLBFnbmAWZI+NArP7HIi2ucrngw+3 rqD7xA9pamRcTtiTWVTza0nW+9sEeyLpQ2rxHn2ORo961NGC4a8an3HmS5Mb9hHD4fVTW4Jz73o Mdj1va5wjGtEpC2d9OFVXIv9RNgLj3SJ+3OFarZ89KBL/XE+VALigH5imGJCKD782v1xscT436Z 6yyXZaVRdj X-Gm-Gg: ATEYQzx0SEKCNKCw7Sy+LwTQVVO0w8ukKLCLZsTIog4LqFezADaVMcSEwjN+G6NddGI XS2MBxDclxY76sddJ3yFNH+RdKHusTB8AtNEW3/DA3rcQI1cKu09g6zy1dQJwYcTQDuM1zyA/yC L5n0e/AjNxvEF8lqEqTjAF4h1WRIBCwK/V0dwarJIM+I64Gps1e9lhQLLEODqKzjGHsW64a5+pG x0QoM/eBPoIBBCibLfB7ejt7/+o9TioiX1D83TKpYXTTIAHAHsUSGmFQFWeF7uBIk+CzZARYVto MeSyTCMI4nrxQTZzd+mmW6MFDaimZbDe2JFVpGMvEPDdKlsUs4teOrKDrdpjHzIeXdToRpfVjF2 i6shMofsMJIQxN2kME+2yIpH7zH0zesNDcIKJtLdhUyQP3E5KWXroBtdwpcoWX/ZuNodpsVkJuu AVGLlPZ4KPHWDAq0TNEI3jFxJdwsq6kNb+dA== X-Received: by 2002:a05:6102:26d4:b0:5ff:de83:3e46 with SMTP id ada2fe7eead31-6003a341f56mr1157373137.7.1773144075524; Tue, 10 Mar 2026 05:01:15 -0700 (PDT) X-Received: by 2002:a05:6102:26d4:b0:5ff:de83:3e46 with SMTP id ada2fe7eead31-6003a341f56mr1157345137.7.1773144074769; Tue, 10 Mar 2026 05:01:14 -0700 (PDT) Received: from t14s (2001-1c00-0c32-7800-beb3-9058-f5fe-3f2e.cable.dynamic.v6.ziggo.nl. [2001:1c00:c32:7800:beb3:9058:f5fe:3f2e]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48541aa7aacsm87843405e9.13.2026.03.10.05.01.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2026 05:01:13 -0700 (PDT) From: Hans de Goede To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Hans de Goede , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [PATCH v7 3/5] software_isp: debayer_cpu: Add multi-threading support Date: Tue, 10 Mar 2026 13:01:04 +0100 Message-ID: <20260310120106.79922-4-johannes.goede@oss.qualcomm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310120106.79922-1-johannes.goede@oss.qualcomm.com> References: <20260310120106.79922-1-johannes.goede@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-GUID: 3MAOpUKOEH6MDNmz17NZUs5fzruURrkD X-Proofpoint-ORIG-GUID: 3MAOpUKOEH6MDNmz17NZUs5fzruURrkD X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzEwMDEwNCBTYWx0ZWRfX2MDRV3635NWZ M/+MboujdkJjSqIEYIga1Xp8Annc7S19W61qh6AB+eixy4j36tRU7jXWpzbdBd0n90mHJFOVQLq Dnpw1yYmQGZ8v98hE/eUIa5lm7Skyo8uLRP/HBlxfAAFUwrOjGI4WO6bXyWxF6zMWS7gJwLXQdO P7cpKsFcpyZp+QvnE4kamTUmNXw3AMdpLzCJDGonWxmuZfTf7hEsnJVkbO2BSYoqsL4lBhj3RzG IuiccQsP6GKQP/ECvtGOZNoveO8NnFGehcFToV6cB5qKfnnNn/o4Wq3T/NjHNsibkEGCGhqFWVR YIKDN6mTvYM+2j9XU8IaVcWflkSvarkRU6oSX6xtQHehwduGGvtTHnkQaP6kBhKag9xgedMGjb8 XickuVKrIABqBYQY2plNz8AdWcolHoMA57fr95dYTw7amVofA8KXRDKKbnzWJ00iXQOxSU3SCP0 SEn0BxYhMDF1+MbyF7Q== X-Authority-Analysis: v=2.4 cv=Cuays34D c=1 sm=1 tr=0 ts=69b0080d cx=c_pps a=DUEm7b3gzWu7BqY5nP7+9g==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=Yq5XynenixoA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=P1BnusSwAAAA:8 a=20KFwNOVAAAA:8 a=EUspDBNiAAAA:8 a=4i1XYD-pSnUufzSozdQA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=-aSRE8QhW-JAV6biHavz:22 a=D0XLA9XvdZm18NrgonBM:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293, Aquarius:18.0.1143, Hydra:6.1.51, FMLib:17.12.100.49 definitions=2026-03-10_02,2026-03-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 clxscore=1015 spamscore=0 adultscore=0 priorityscore=1501 phishscore=0 suspectscore=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603100104 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" Add CPU soft ISP multi-threading support. Benchmark results for the Arduino Uno-Q with a weak CPU which is good for performance testing, all numbers with an IMX219 running at 3280x2464 -> 3272x2464: 1 thread : 147ms / frame, ~6.5 fps 2 threads: 80ms / frame, ~12.5 fps 3 threads: 65ms / frame, ~15 fps Adding a 4th thread does not improve performance. Tested-by: Barnabás Pőcze # ThinkPad X1 Yoga Gen 7 + ov2740 Reviewed-by: Milan Zamazal Signed-off-by: Hans de Goede --- Changes in v7: - Add Debug message logging thread count Changes in v5: - Extend software_isp.threads docs in runtime_configuration.rst Changes in v4: - Document software_isp.threads option in runtime_configuration.rst - Add an use constants for min/max/default number of threads Changes in v3: - Adjust for DebayerCpuThread now inheriting from Thread - Use for (auto &thread : threads_) Changes in v2: - Adjust to use the new DebayerCpuThread class introduced in the v2 patch-series - Re-use threads instead of starting new threads every frame --- Documentation/runtime_configuration.rst | 8 ++++ src/libcamera/software_isp/debayer_cpu.cpp | 47 ++++++++++++++++++++-- src/libcamera/software_isp/debayer_cpu.h | 10 +++++ 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst index e99ef2fb9..651929a4d 100644 --- a/Documentation/runtime_configuration.rst +++ b/Documentation/runtime_configuration.rst @@ -51,6 +51,7 @@ file structure: measure: skip: # non-negative integer, frames to skip initially number: # non-negative integer, frames to measure + threads: # integer >= 1, number of render threads to use, default 2 Configuration file example -------------------------- @@ -84,6 +85,7 @@ Configuration file example measure: skip: 50 number: 30 + threads: 2 List of variables and configuration options ------------------------------------------- @@ -167,6 +169,12 @@ software_isp.measure.skip, software_isp.measure.number Example `number` value: ``30`` +software_isp.threads + Number of render threads the software ISP uses when using the CPU. + This must be between 1 and 8 and the default is 2. + + Example value: ``2`` + Further details --------------- diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index fc3305d2e..1de70b3b7 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -76,6 +76,7 @@ DebayerCpuThread::DebayerCpuThread(DebayerCpu *debayer, unsigned int threadIndex debayer_(debayer), threadIndex_(threadIndex), enableInputMemcpy_(enableInputMemcpy) { + moveToThread(this); } /** @@ -107,11 +108,15 @@ DebayerCpu::DebayerCpu(std::unique_ptr stats, const GlobalConfigurat bool enableInputMemcpy = configuration.option({ "software_isp", "copy_input_buffer" }).value_or(true); - /* Just one thread object for now, which will be called inline rather than async */ - threads_.resize(1); + unsigned int threadCount = + configuration.option({ "software_isp", "threads" }).value_or(kDefaultThreads); + threadCount = std::clamp(threadCount, kMinThreads, kMaxThreads); + threads_.resize(threadCount); for (unsigned int i = 0; i < threads_.size(); i++) threads_[i] = std::make_unique(this, i, enableInputMemcpy); + + LOG(Debayer, Debug) << "Thread count " << threadCount; } DebayerCpu::~DebayerCpu() = default; @@ -746,6 +751,11 @@ void DebayerCpuThread::process(uint32_t frame, const uint8_t *src, uint8_t *dst) process2(frame, src, dst); else process4(frame, src, dst); + + debayer_->workPendingMutex_.lock(); + debayer_->workPending_ &= ~(1 << threadIndex_); + debayer_->workPendingMutex_.unlock(); + debayer_->workPendingCv_.notify_one(); } void DebayerCpuThread::process2(uint32_t frame, const uint8_t *src, uint8_t *dst) @@ -985,7 +995,21 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output stats_->startFrame(frame); - threads_[0]->process(frame, in.planes()[0].data(), out.planes()[0].data()); + workPendingMutex_.lock(); + workPending_ = (1 << threads_.size()) - 1; + workPendingMutex_.unlock(); + + for (auto &thread : threads_) + thread->invokeMethod(&DebayerCpuThread::process, + ConnectionTypeQueued, frame, + in.planes()[0].data(), out.planes()[0].data()); + + { + MutexLocker locker(workPendingMutex_); + workPendingCv_.wait(locker, [&]() LIBCAMERA_TSA_REQUIRES(workPendingMutex_) { + return workPending_ == 0; + }); + } metadata.planes()[0].bytesused = out.planes()[0].size(); @@ -1004,6 +1028,23 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output inputBufferReady.emit(input); } +int DebayerCpu::start() +{ + for (auto &thread : threads_) + thread->start(); + + return 0; +} + +void DebayerCpu::stop() +{ + for (auto &thread : threads_) + thread->exit(); + + for (auto &thread : threads_) + thread->wait(); +} + SizeRange DebayerCpu::sizes(PixelFormat inputFormat, const Size &inputSize) { Size patternSize = this->patternSize(inputFormat); diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h index 8e57c273b..a96998e92 100644 --- a/src/libcamera/software_isp/debayer_cpu.h +++ b/src/libcamera/software_isp/debayer_cpu.h @@ -16,6 +16,7 @@ #include #include +#include #include "libcamera/internal/bayer_format.h" #include "libcamera/internal/global_configuration.h" @@ -41,6 +42,8 @@ public: std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size); void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms); + int start(); + void stop(); SizeRange sizes(PixelFormat inputFormat, const Size &inputSize); const SharedFD &getStatsFD() { return stats_->getStatsFD(); } @@ -144,6 +147,13 @@ private: std::unique_ptr stats_; unsigned int xShift_; /* Offset of 0/1 applied to window_.x */ + static constexpr unsigned int kMinThreads = 1; + static constexpr unsigned int kMaxThreads = 8; + static constexpr unsigned int kDefaultThreads = 2; + + unsigned int workPending_ LIBCAMERA_TSA_GUARDED_BY(workPendingMutex_); + Mutex workPendingMutex_; + ConditionVariable workPendingCv_; std::vector> threads_; }; From patchwork Tue Mar 10 12:01:05 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 26274 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 BE2E5C32B5 for ; Tue, 10 Mar 2026 12:01:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 724216266B; Tue, 10 Mar 2026 13:01:24 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.b="OBko4Tav"; dkim=pass (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="RaHAvyMi"; dkim-atps=neutral Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 45A7462663 for ; Tue, 10 Mar 2026 13:01:20 +0100 (CET) Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 62A8jpRB2460657 for ; Tue, 10 Mar 2026 12:01:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= TmCwSNRDjMXD7FyELSBffXtyHj68sIz12Xk5gBuElFA=; b=OBko4Tavv52bT+tT N9PwwFNwre35pWL35EvgWQOJeJZioPtS6cBKWnXQuOJqfHVMLI+bMOg9gw6RQiiU 7f5OIS8sS2Zh3E0+gCrnVAE4JzYXxDH/BmTPouWTZh95CrAlFc/Uwvx25KxWdeRU BBtlyGAI/U33EOw1NQhPkAdNVw7ALCPeoQcPJlXBLluD+quvyUQ+CX1ByMkZjxuP o2lFY2U7eJghnKLq0INQWF/PbA77ZVg1hlsDgPTwR8awNaw132SQRNC0m5a0iJNf +FtjJojkEBHHffHRhacAVKdyxumsZz1ET6ylmcnT/5hLwVc86VeRFsAY9iMp1JR/ zxNGyw== Received: from mail-ua1-f69.google.com (mail-ua1-f69.google.com [209.85.222.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4csyv1c5ek-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Tue, 10 Mar 2026 12:01:18 +0000 (GMT) Received: by mail-ua1-f69.google.com with SMTP id a1e0cc1a2514c-94e9c0edfcfso24791316241.0 for ; Tue, 10 Mar 2026 05:01:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1773144077; x=1773748877; 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=TmCwSNRDjMXD7FyELSBffXtyHj68sIz12Xk5gBuElFA=; b=RaHAvyMi6jDQk6wRAjDLW1R0M5BHBs7q+ZbylXRZZyBmUAFsW663oDZAlCpQMmcEkM yFv2DvnPFNUoZlxhKdxremHoQwjbS2pQ8GVG57dxq5FjO1N779NSGYWxxWL+wQETaTWV 3tfwj32wS33zu6eMv+BoCRlUD+q61qcKChDSxBfNJHnYymdipGHR4MAANjojLReaCK9p 42VdGLpBykcReul5hecF1/ZIgTdg6o00o0e3VVFR+IZX/4fgVtrBLa5xAvjvTrYuuYGo PTIbVzMy058xo8WkYhIb8GHYo7525u3JO1o6vv4Kvp8U5tIU60+EgZkNmtIS2e0/vD+b Piew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773144077; x=1773748877; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=TmCwSNRDjMXD7FyELSBffXtyHj68sIz12Xk5gBuElFA=; b=DSTS+YvnaoZoLT005PCe0A6XaHwKWDOg93UTPhKQ7/OZqEA4lNgALpnwQp1CtvlYlk fgsUuBjR7lGOFXWsRLininRyyAlDh3CbpbBMT48rsVWKOO69/FhccaHfUWa7+Yxwqzhv RvlzlNUseuxjcny+QeJ80yfnaf7a+NTtThBfP55zk4y/cZWCgwheDB1YVGuI6GKuQKm2 viT2rjIL8aVBp+aUnd/cDr7O9PgJgn6kkMpQu+pA0rTp6ZeQlsinrytj+ikfJrPqPSHI yyMw86faMX3A7XU9t4wDfuxRM08z/UCnpeYwGdVv60IeGsMceKwLdxfcyGNF6eooz8f9 /7xg== X-Gm-Message-State: AOJu0YxZEHwfmTAcsGJSvP41bbkHAAfpGZG8+qzGfUZVtj3Fk13dFFLO Bx52C1FhmDltvhIwTuIfuAif3IBYCEXkFOQPxuGjXj9vk6fw+Hlwul7yvwRK0VkOQkL9tGs71VL BTemAHyPGRBh1okVmLb6BuoWWyKio0d5h6QyAawuXd6LEeEFfff6Yuykc2ZowENgZIYwPtkkc8y Tp0tOx5uGs X-Gm-Gg: ATEYQzy/9Ey2b7M+k4WmhuBnC2cdB/aqX5X5DGgB4hhC7EGTjkpLI1MXRYxUfCQqY6x RutVNho9Zw+q0JYnadZ0/Bn+1RTFfs9zUBfK2kvwS2WLpAPCPNHsY+aj2HARjrQfgjrAKaDbgx9 unJQ5tEk/CrXn61JSQM5LbIctBtauep7tgflZmXHrKFiGerksuAp+cLBAvjteVsfVp5pVdB8xZy 8uCkvEq41IBF+lk8SuW5fwZKxrKEQDAhaeREwzLst1WKhvKCDKa5ciZDg43ZC8CVxw0IXLN4A3R y+TSu4P7mdD034PWMvXOy2AyAqIhsc5tOisB3LVDQ/ZTlJu8Tu51IFd0GxmCVHu35beL/4aOUGY m3al8BH2sIo/S8eywUab/iwqTFTcl/5sV22uwAEHcjGU3bWGZg66Y9472jr+mIUPFZ/s10Lw3vr eTgSLk4fjxLnFVrlK2kGV9eEK93sS64vDAnA== X-Received: by 2002:a05:6102:a51:b0:5ff:d434:b507 with SMTP id ada2fe7eead31-5ffe5fcffc4mr5824044137.17.1773144076999; Tue, 10 Mar 2026 05:01:16 -0700 (PDT) X-Received: by 2002:a05:6102:a51:b0:5ff:d434:b507 with SMTP id ada2fe7eead31-5ffe5fcffc4mr5823993137.17.1773144076369; Tue, 10 Mar 2026 05:01:16 -0700 (PDT) Received: from t14s (2001-1c00-0c32-7800-beb3-9058-f5fe-3f2e.cable.dynamic.v6.ziggo.nl. [2001:1c00:c32:7800:beb3:9058:f5fe:3f2e]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48541aa7aacsm87843405e9.13.2026.03.10.05.01.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2026 05:01:15 -0700 (PDT) From: Hans de Goede To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Hans de Goede , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [PATCH v7 4/5] software_isp: Log input config from configure() Date: Tue, 10 Mar 2026 13:01:05 +0100 Message-ID: <20260310120106.79922-5-johannes.goede@oss.qualcomm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310120106.79922-1-johannes.goede@oss.qualcomm.com> References: <20260310120106.79922-1-johannes.goede@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-GUID: jEx6vGWOmmJtkGjIMqU_cKy4p9_KA2ar X-Proofpoint-ORIG-GUID: jEx6vGWOmmJtkGjIMqU_cKy4p9_KA2ar X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzEwMDEwNCBTYWx0ZWRfX9NepCGqlBNSA JuwZTD9iNeDnQxUjR0F56Yux78yAc63wyKTcCBjLinvTtxhlck4Y35IFw/jV8rHE7VGklwTWAUa sBXhbEg1AYpNDWU8kNzmkF2RnDgfbXFgmSZ/njRMJM4vG9MXMOBzrFDxse8TEy1mCgzZgPYPvEO BGR+MmSHVEVSu5F04hNVCuVFOp6tICEXjBibn8rRHsSYYlgwUBmbth90mpXyrLJTKCf2uuPMIr5 tvU84zTqJ5jZMlfZOy2j5fYO/YUZOhyCw5wSG+8AYUaieRh7Em2oPWIgk0iWjaijfn4NaYKU893 RSrYBQ/dF0pISbQQrswYgdCJKu3+oZ2aWdooMVHnKU4KlBGlwXXbM/CZqlEP/xTsjbL+zt+ePQk ldMozuK7Z6+rTfahGDCGECjrNhRCH/Ua8epKbZsXeJCF3b8d0GQ3AMDV/B9ojIoLz9R0bLxtVDj XnCVrFar7E6isFV948w== X-Authority-Analysis: v=2.4 cv=Cuays34D c=1 sm=1 tr=0 ts=69b0080e cx=c_pps a=UbhLPJ621ZpgOD2l3yZY1w==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=Yq5XynenixoA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=20KFwNOVAAAA:8 a=P1BnusSwAAAA:8 a=EUspDBNiAAAA:8 a=mKg8M22OkPar6P-70WAA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=TOPH6uDL9cOC6tEoww4z:22 a=D0XLA9XvdZm18NrgonBM:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293, Aquarius:18.0.1143, Hydra:6.1.51, FMLib:17.12.100.49 definitions=2026-03-10_02,2026-03-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 clxscore=1015 spamscore=0 adultscore=0 priorityscore=1501 phishscore=0 suspectscore=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603100104 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" As shown by commit 94d32fdc55a3 ("pipeline: simple: Consider output sizes when choosing pipe config"), the extra pixel columns CPU debayering requires on the input side makes resolution selection non trivial. Add logging of the selected input config on a successful configure() so that the logs clearly show which sensor mode has been selected. Reviewed-by: Milan Zamazal Reviewed-by: Barnabás Pőcze Signed-off-by: Hans de Goede --- Changes in v2: - Move from DebayerCpu::configure() to SoftwareIsp::configure() so that the input fmt also gets logged when using the DebayerEgl class --- src/libcamera/software_isp/software_isp.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 562cdba22..4cf5639d9 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -21,6 +21,7 @@ #include #include +#include "libcamera/internal/bayer_format.h" #include "libcamera/internal/framebuffer.h" #include "libcamera/internal/ipa_manager.h" #include "libcamera/internal/software_isp/debayer_params.h" @@ -270,7 +271,16 @@ int SoftwareIsp::configure(const StreamConfiguration &inputCfg, if (ret < 0) return ret; - return debayer_->configure(inputCfg, outputCfgs, ccmEnabled_); + ret = debayer_->configure(inputCfg, outputCfgs, ccmEnabled_); + if (ret < 0) + return ret; + + LOG(SoftwareIsp, Info) + << "Input " << inputCfg.size + << "-" << BayerFormat::fromPixelFormat(inputCfg.pixelFormat) + << " stride " << inputCfg.stride; + + return 0; } /** From patchwork Tue Mar 10 12:01:06 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 26275 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 A1692C32EF for ; Tue, 10 Mar 2026 12:01:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2AE3762663; Tue, 10 Mar 2026 13:01:25 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.b="G5SFmQ34"; dkim=pass (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="cDJbSlId"; dkim-atps=neutral Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D203462643 for ; Tue, 10 Mar 2026 13:01:21 +0100 (CET) Received: from pps.filterd (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 62AAREWD4188504 for ; Tue, 10 Mar 2026 12:01:20 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=IfNCP/oNcWB sIg2Zu4ss/xnRftQ6vlXQs7T7fOA2KS8=; b=G5SFmQ34lFPu7TFETtjtIL4BB6S gaoSpL7bMYdrGYKs8epbaS2HdZqrE3blZGWLk2AswmhYseMIbglv9EMLw9RM0ziB LR79F1gYjL06TmvQBO7qFezBv7eHo4laAuLd+oadc6aJiPm++XhMuBOiBrCOBcYr AgKTD9TF5QeequBV566Eh5G6a8VF5uNfUDuc6tWxoQWYTSFy7rnF7xYjqTAIK+nx rH30orKOqbobbW5M18bwV4ZCE4HVYnNm/cBdmS8xaYyKkHtptBLefinLPBzJXPRg zv1SNiNzyF7MqgZcBvq+DFOUifT968c3DYqbZEqRkjefX1iPcmUObD0GIaw== Received: from mail-vs1-f69.google.com (mail-vs1-f69.google.com [209.85.217.69]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4cthjf0c0s-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Tue, 10 Mar 2026 12:01:20 +0000 (GMT) Received: by mail-vs1-f69.google.com with SMTP id ada2fe7eead31-5ffe4912235so4762503137.3 for ; Tue, 10 Mar 2026 05:01:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1773144079; x=1773748879; 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=IfNCP/oNcWBsIg2Zu4ss/xnRftQ6vlXQs7T7fOA2KS8=; b=cDJbSlIdGwIiKPElYoXnnfL/dC8x59hCtoiQf1VsHT6f/bnXRQB7w+shTMsROXL3cN M/hv+12q1uxsq5sAy9BsSb4tvWo0tUkn5oxI1RGweH+J4nmWAhgIanPhcgWNHWkKLFf3 rhy9ekoxwMlMgsESzNgtQS+d2zmjAVgpZB5QADvuDBNzQU/PtoQ9YlicCLUM/fFx/t4O yKlT7ZSaiubGN4Be7P1iy9HhFY1FU6qIe99HaYJ41ps1TDP/nUky9nKxIRoRKwyvh9ji BHrYMTuYgXtlr+7Wo8sMAXZGb7AqQDTKptyPI0jM+Km/5UzwXDzm0Y2296bWzMZ/MHDd CHow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773144079; x=1773748879; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=IfNCP/oNcWBsIg2Zu4ss/xnRftQ6vlXQs7T7fOA2KS8=; b=X9bS3/2/IFx1b2Uzj1jkuQ50kprCOPNbRPKn3zcfnuzvBa3PsyeNa47I0kYBvIjAwh DJdxLXSS1Dr0HcbAXwY5ThjnkUkI46dSvlz8qM2lFe90pPHxo/WZx/N4QVE0p9t5Vd/r 1+g5pQhaYSv6+t4lP6jRhrXCHyWkXtJ4H+TX5q/8Ym1Qsanf7/MCG4BOa/eIeavXV+o1 xtlt7fLEr8QkocconzFtjLYyT6tzDF6g39F4QdbAXlDmy7gCldNr063LvHIzZXQl0WM+ StyczB8Mbx41x2lX+JJO/iUN1v3dwNwk8nhkevEw6zTk89PPFeHbX7mZziT07fBlGlYV chpQ== X-Gm-Message-State: AOJu0YwiSvWTicT7j8x0CB/9QWSo7Hg5iIWYtDvkR7VmDaRtQFItivK0 Eu3FeyTEtGc0FolsIZeCgoHl9Nt/4RbYyLxpvx4Js1GQTd66BN5QWvDzvswDQpxYq7nzPn0EHEb 0jBXobHY1tXHkFV0mm5VVYu72sNXcHBMY7tKKr8umpu9pxQ3Yli3goI9EP7VTdcRHq3z4a9AyL8 60ZYA+PEop X-Gm-Gg: ATEYQzwrwzx5LUgBD9LQlk9QmtAydtu1m1ocpZCCDzAO6Mat0nRUXTWQqvZ1HJOQk5u 0QqD3MuYuvsGOxTzFq6FE0f4KX8IuBYRoQbas/Ny4C81m6IKT0o0MBo0t50aM3AkO6AzVtq7M1/ U0gmGxvpGeD/TElewlSsC+MNUgEyhCk+WxcHiSUX7M/VZt6BGEtgj2TOQs6+V1C8zF03GwY4V7D Lqrvz3hectv4SA/HvC3wmmYFWoHuba9xsgG0rwaQSCl47eqnyTFCfeUH9MERZ+TWZ4ZJ/t8Owix NOnHm0lDTQ0NsRNUxeCBnn8zs/b8HPPrF2vVYAh5W0wl1K6c42C08iiKJPSwEjpU9D280kysbJY w3mmT61PLBcomraKouBPw6q5f/yQUo6UPKL7HaDZO/1IEExR/igzYC9WxukQA9Av+HN5c5JedDB iZyuTcyK4fhR+C17T5XfwNV0Jt+hF1ix+2zA== X-Received: by 2002:a05:6102:cc7:b0:5ff:f84d:eedd with SMTP id ada2fe7eead31-5fff84e5adbmr4679582137.32.1773144079125; Tue, 10 Mar 2026 05:01:19 -0700 (PDT) X-Received: by 2002:a05:6102:cc7:b0:5ff:f84d:eedd with SMTP id ada2fe7eead31-5fff84e5adbmr4679538137.32.1773144078585; Tue, 10 Mar 2026 05:01:18 -0700 (PDT) Received: from t14s (2001-1c00-0c32-7800-beb3-9058-f5fe-3f2e.cable.dynamic.v6.ziggo.nl. [2001:1c00:c32:7800:beb3:9058:f5fe:3f2e]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48541aa7aacsm87843405e9.13.2026.03.10.05.01.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2026 05:01:16 -0700 (PDT) From: Hans de Goede To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Hans de Goede Subject: [PATCH v7 5/5] Documentation/runtime_configuration: Add missing software_isp.mode doc Date: Tue, 10 Mar 2026 13:01:06 +0100 Message-ID: <20260310120106.79922-6-johannes.goede@oss.qualcomm.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260310120106.79922-1-johannes.goede@oss.qualcomm.com> References: <20260310120106.79922-1-johannes.goede@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-GUID: H3hXW3lPVqxq-b-ovKWagqw3xCOZEWRi X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzEwMDEwNCBTYWx0ZWRfX/9q1q/Q/dZT7 8wxQ/ryx3KzkvQTDKzJdO65IYtgP1oStSdZRbeYA8WTzcQJKVD99PeqXYnFkcBawcQtvoMiQ5mT vhVf5Wm4rnTnNh3Zjk/2o1wVXZf1OVJ6Esit+1VksLOULA8VT1GIaGm+HRyn/Yy1STULGa51dNK DWsHGsPCu7l6IQzM6ufa0vBSIc2nWY7pMbjGtY4kO0gggtv/EPNcz5rq8m3+3glUaDxNd1tezAE XkdJHQEAe7VGkRV6EgeOtGHzzM1N20zITGchjCYKtj6ZPAOebDdHw3s/WMiwrKDf8AL32SRxlbC vJ8KJfDNITLyl0g7/0vD+yx8Gn9nInooZiSYmMWWk0CcIptBpmWf+kWcpqkJz1tLhWn3+dRrTIq TsYJB8mIkMhODdUSju+c+QBygn9Gf5zpgf4CtTAiphJ940KWtnBBN9z1bK9TkVF/hRRjBfapaVs 0bTnlGbWo8+7bJCx8+g== X-Authority-Analysis: v=2.4 cv=A71h/qWG c=1 sm=1 tr=0 ts=69b00810 cx=c_pps a=5HAIKLe1ejAbszaTRHs9Ug==:117 a=xqWC_Br6kY4A:10 a=Yq5XynenixoA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=Um2Pa8k9VHT-vaBCBUpS:22 a=20KFwNOVAAAA:8 a=EUspDBNiAAAA:8 a=vqn-7YPdvggCubZ9BQoA:9 a=gYDTvv6II1OnSo0itH1n:22 X-Proofpoint-ORIG-GUID: H3hXW3lPVqxq-b-ovKWagqw3xCOZEWRi X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293, Aquarius:18.0.1143, Hydra:6.1.51, FMLib:17.12.100.49 definitions=2026-03-10_02,2026-03-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 phishscore=0 clxscore=1015 suspectscore=0 bulkscore=0 adultscore=0 spamscore=0 lowpriorityscore=0 priorityscore=1501 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603100104 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" The software_isp.mode setting was missing from the runtime_configuration documentation, add it. Reviewed-by: Milan Zamazal Signed-off-by: Hans de Goede Reviewed-by: Kieran Bingham --- Changes in v7: - Move back to being part of the series, sorry for the confusion Changes in v6: - Use "LIBCAMERA_SOFTISP_MODE, software_isp.mode" as item title - Add Milan's Reviewed-by - Send out as standalone patch, v5 of rest of series is ready as is Changes in v5: - New patch in v5 of this series --- Documentation/runtime_configuration.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst index 651929a4d..a95de2f43 100644 --- a/Documentation/runtime_configuration.rst +++ b/Documentation/runtime_configuration.rst @@ -51,6 +51,7 @@ file structure: measure: skip: # non-negative integer, frames to skip initially number: # non-negative integer, frames to measure + mode: # cpu/gpu threads: # integer >= 1, number of render threads to use, default 2 Configuration file example @@ -85,6 +86,7 @@ Configuration file example measure: skip: 50 number: 30 + mode: gpu threads: 2 List of variables and configuration options @@ -141,6 +143,13 @@ LIBCAMERA__TUNING_FILE Example value: ``/usr/local/share/libcamera/ipa/rpi/vc4/custom_sensor.json`` +LIBCAMERA_SOFTISP_MODE, software_isp.mode + Select if the software ISP should use GPU or CPU image processsing, + one of ``cpu`` or ``gpu``. When set to ``gpu`` and EGL is not available + the software ISP will automatically fall back to the CPU. + + Example value: ``gpu`` + pipelines.simple.supported_devices.driver, pipelines.simple.supported_devices.software_isp Override whether software ISP is enabled for the given driver.