From patchwork Wed Mar 4 07:50:48 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: 26249 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 A8CF3C32EA for ; Wed, 4 Mar 2026 07:51:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BD64F62393; Wed, 4 Mar 2026 08:51:00 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.b="eThPLdMH"; dkim=pass (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="gDL7Ip0/"; dkim-atps=neutral Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BD59F62385 for ; Wed, 4 Mar 2026 08:50:58 +0100 (CET) Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6245SQc8945115 for ; Wed, 4 Mar 2026 07:50:57 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=Q9h8k+AeUz8 t+HWwjwjc7na33VwWe6woYgARNnc/Hyc=; b=eThPLdMHVr6ANYs7SKK8ctRTPRQ b0RJwit4F08qbh/7W86/Evqkt9C6l08019JBwUOIrdfVcJZn64MIVF/voNjkFdrR XmW4VE8eGmg0Y8ckhd/Qup2rKtvq5WFSv2ALhwVmE+Bp9hM+Z+P6vC0E7pIKTYLE bS9TGk65/KG3OmvbsDc4F2iTua7b8wRIv6Id+bnCESr06AD+krfni6JMJfXASKbO kJy9mwr4m3O2qa1PfMG8keYQyliEr57HqpKqP2ZAC9UZsEBxksQ1iEBbb1IZQTtI hcweV6LptiWM+3Mf4uP5hWN8xie8h9TT8mWJ8PaD0gzEkfDMV9WJfkdnoGA== Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4cnvxfc48y-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 04 Mar 2026 07:50:57 +0000 (GMT) Received: by mail-qk1-f197.google.com with SMTP id af79cd13be357-8c70ed6c849so915904385a.1 for ; Tue, 03 Mar 2026 23:50:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1772610656; x=1773215456; 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=Q9h8k+AeUz8t+HWwjwjc7na33VwWe6woYgARNnc/Hyc=; b=gDL7Ip0/vtS3lnBXrBYPT5kUi1vm1QL44a1WOCurmQOtZO29CFfkCzmkABGOtWWvtf c0uxVNqKrwrzOOTZQA5ZcWU/KTjy7NK9y9tT19bJLmjTyu+SzX+4oPCmISUHSDoP7xCw WXt/YLnMquoDiOhpoyaTj1d1Ga4tpMnWVFskjrVQAB9QrZQ+wiUKCFXyTv7mPC92+1+P wg3GMXXqxSPfsA+SHq7ON9IaGTltbmxMLBc8B3Y7erHfI9dcbInhxml2O+DxgSBnMXTo XE/zJuwv1Hv+ZUh+wqRsynTXP1LROhlMW3/erNzOm+Rr4Jt7UFOFdsmJ1p5e8LihhhfM NiAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772610656; x=1773215456; 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=Q9h8k+AeUz8t+HWwjwjc7na33VwWe6woYgARNnc/Hyc=; b=vphXNA2ze8tGGVpnF6jxXIJ0b6/To6Y3Py5TJetYrbIDWFsrdWg7q5tflTo1t0hKOR m1vUHqY+H8sgt8fj25G8/e789ZsHimPAt0KhtY6TsLEseK69YU8AdoLFSygxlzwsPaY1 gO7+WOC1YfAaZuQt5Z9FDyYguRE6bJkjFbIH2ZwSDMjtxEfKL7ZAFwbiMri+qBuH7y3Y eUd6MUj7oHswfR83cBSDTt9Ip6LgaDsxHUU9q8rFCXjYiPCe4sGAD9yan1AbLAxJ4bXP taJu7s1SMoHG4yjfdQaZcAOUoGhU6KDUCW8GljwOooBqjaZy4fdq2URafWXZr00CiOVN XO2A== X-Gm-Message-State: AOJu0YwdIEmYU8MJY3a4ccma6IgpjDAJ5sdc6CkDafmVfVou3MNoPT0F OEjweThrnCdNSUJor5FHs09zmExE4/esqZODM6fqXJBMJS4zDWzZfk+Hh3C+YzmTqssoWYgjMhT tRMcP3p40pPp8sAgnMyu+yirBoARF0/wLopMm7sqq8X3pF8suoqFDQiRKCL/nmFj4LTM6+U6tUT DCaNeW+grx X-Gm-Gg: ATEYQzyqEnP88l4seFOBe8c9XVLZJdQZiMpU5viXZ6oMfiQpFA2VZZDpClxz3Yb+WCi L8OQdJf9z+T4HR5/r91oleaSRHhhDjwG91gTr98+Pu0RAS3xuzIzY4vMCnk9Da9GUW0XKWj+WCn mLcP6DwsDU3hWIPXKWCFPEONiihA5uogYibnJ1hEEYD/eN7t1zlZoIFPDP+6tX4i2HCbAnL4mYL KElpFc+7BdDi1oJZEs3gyGKXTk+d5xzKCS5z2Y5MZjNL4A2kBTtNha+JcGDvNfqmkHDE7lC/U6r NA79/7HPO+71IuAxyGU2/iScGJh4HxCHiIwnuQ6AfgAAUpk1JRhhIMG0MU6VNOuBFeHaGySwIM4 V+khj29xljfBUb0W3kYTCVR0zWKSLSJ5qKyCje1aPZnLvP6zPL53kQ9KCAzLWcdFMch4iyFySG9 iyA3gpBB0Lc2OLnGUDgcndwGeEUoNTpr6pnrGp X-Received: by 2002:a05:620a:4092:b0:8ca:2cf9:819c with SMTP id af79cd13be357-8cd5af8030fmr134516485a.40.1772610656283; Tue, 03 Mar 2026 23:50:56 -0800 (PST) X-Received: by 2002:a05:620a:4092:b0:8ca:2cf9:819c with SMTP id af79cd13be357-8cd5af8030fmr134514385a.40.1772610655575; Tue, 03 Mar 2026 23:50:55 -0800 (PST) Received: from shalem (2001-1c00-0c32-7800-5bfa-a036-83f0-f9ec.cable.dynamic.v6.ziggo.nl. [2001:1c00:c32:7800:5bfa:a036:83f0:f9ec]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b935ac73a5dsm693263366b.25.2026.03.03.23.50.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Mar 2026 23:50:54 -0800 (PST) From: Hans de Goede To: libcamera-devel@lists.libcamera.org, Milan Zamazal Cc: Hans de Goede Subject: [PATCH v5 1/5] software_isp: swstats_cpu: Prepare for multi-threading support Date: Wed, 4 Mar 2026 08:50:48 +0100 Message-ID: <20260304075052.11599-2-johannes.goede@oss.qualcomm.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260304075052.11599-1-johannes.goede@oss.qualcomm.com> References: <20260304075052.11599-1-johannes.goede@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzA0MDA2MiBTYWx0ZWRfX/g1av0/Ai38r bUP9Rd2RuKxNbGZ6M2wHV7d9OAAT5102kpT1fzy0RbdCL114AyDMUCQ0V1IOAt8yLbyvCx+3Vk8 YmP7piFhiM8VlqY6wIbRZ6zTKCyEWgJHGq6zSsD3JfqXLEx0FwGyQ09F60N7w7eSCBCgNxva719 GLnO+4+1OPjSdD7nXtKts9jGKVUYVc8K3/BkcrHQI7LbqJNJMSP4xJ4uFsrXyMPUI5DDMuIvevD lRWs8/2KNA7tof1c0jhRMp3UC8K33nBhOvYPNw9NeNdDwH1v/dUkGmWPp9sp9c1Zj1iSgvzaYuO O/43bpIaU0FflQAbpGVUA5cc6/giE6ik1PmxgbwWZFjcZ2kJtoALhjApKa25ph+ooFxKCQKUGV0 g7wrOdrcSHj92LPcNo+uOjxTnAEkcc6ycCQqhTaXHwB4/+hvaLQu6u6ntLGxOzCzu5tXEYh7elG fClaGU5b7d5/idSTVlA== X-Proofpoint-ORIG-GUID: L-_8Ch2F4ohKYdUAwgPDm6pbuTzh7Gkb X-Authority-Analysis: v=2.4 cv=S+HUAYsP c=1 sm=1 tr=0 ts=69a7e461 cx=c_pps a=50t2pK5VMbmlHzFWWp8p/g==:117 a=xqWC_Br6kY4A:10 a=Yq5XynenixoA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=20KFwNOVAAAA:8 a=EUspDBNiAAAA:8 a=VvikW9XIONpR7lsxkDIA:9 a=IoWCM6iH3mJn3m4BftBB:22 X-Proofpoint-GUID: L-_8Ch2F4ohKYdUAwgPDm6pbuTzh7Gkb X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293, Aquarius:18.0.1121, Hydra:6.1.51, FMLib:17.12.100.49 definitions=2026-03-04_02,2026-03-03_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 suspectscore=0 clxscore=1015 spamscore=0 priorityscore=1501 adultscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603040062 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 Wed Mar 4 07:50:49 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: 26250 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 B0AD3BE086 for ; Wed, 4 Mar 2026 07:51:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 640B66239C; Wed, 4 Mar 2026 08:51:03 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.b="KnGYgS2I"; dkim=pass (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Y2ozPG9U"; 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 09BAC62396 for ; Wed, 4 Mar 2026 08:51:00 +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 6245SedC1678073 for ; Wed, 4 Mar 2026 07:50:59 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=lj7q66a95nk SRrYrRSIi8jiFgvLhiP3E04FCMHJ3vrU=; b=KnGYgS2IFDYpIpMhDU7qbEJ5bR0 VqpDP2sK/PQXMBoRlbMYt5A6QCnXjIX8RlkD9/QsfpKEtPfei8bAb/2PIER2nJQY USNpkd2U8+QipMj+zbv8kWNBpZDTMScPf7XHBHkJWMEFWZZzylRfmq+nkFa23n1W Km6uu1RxxQuo9L5eathbiPpWl1mDZC7s/oXRqwgqCclCD8hz0JRTux4WztnsKcaz obyINn0dAcWHzX7FKNRoEQm7z6JenEQcpvoe5uZ3FkKg8TbIeMnMatmoN2KZrzoE G8WTY9cySiGQoa1/Gaaq4ytyemjHJnBFbD/FkjnAngZhmF15YJkBqmFHdnw== Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4cp73h9vh9-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 04 Mar 2026 07:50:58 +0000 (GMT) Received: by mail-qk1-f197.google.com with SMTP id af79cd13be357-8c70ab7f67fso6882167885a.3 for ; Tue, 03 Mar 2026 23:50:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1772610658; x=1773215458; 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=lj7q66a95nkSRrYrRSIi8jiFgvLhiP3E04FCMHJ3vrU=; b=Y2ozPG9UcjnbK0IXvCr2siYqchJvFBDTjFYW7NC4sjpc827b7SvyScECtb1T21gMZs OrsOlCmyBWfMOto7OXVYn2TDV7TtjuNYTwYOh4B4ROz1HvpqoY6l7durI7KgYayW37LC RJ4/FxnJwSYPq1RDepNatUSlK3bY+nAimFYjh2Sv6mwHB2FED534czpsVKGePvS3yDl/ yf6ituVkN4lJEv/ahQ4xFQDcpcqFhNrdSD6hzHTcqFf7oZSaYdU+D4KVV5ISuzOi9SgQ Ysd0Ag+IqLsAyg6idgNXDzkw8vENBNClsnffrbTzUrGszf7LKS6owxhR1n8fXDgtBHdA cdvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772610658; x=1773215458; 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=lj7q66a95nkSRrYrRSIi8jiFgvLhiP3E04FCMHJ3vrU=; b=lgIKXXnhnsTarpYOTG7AedpAz1/P5U7QxrwS9AH5XV0CGc/qtUJ4x8GXWgpa6UYFCE 1C33uEozNT9RxN1jm6apYr9nVl6tT3JgvtQGduONwr6LvzUz3MAzMp5Bfky/jF4JmR7p XM/tNxeJGbvCi/77Hilfh92KKjT9b8Bmsgl2mUY3ExmssOP5T3CaFIo+nf9R8oJ9TQeB pMuM1hM5Sc0pwgXKdZ5pHIKmycQ9fASBRrr3D2jdAi0mdZS12+NjkVQk7tknT9H7bRtO qqPOca9QpJnKg3eREa+Oi6ankq5pswoTCrxZYHL0UbduDqb3qxS7je0tppzKuppau08S nuAg== X-Gm-Message-State: AOJu0YzakoA0IrslLgmpRSau0/r5Rk9XXEPO8kuSq/eGwX2yi5F9wv6x I9xds9tl7vQIjFWRhXl2+uBnK7TeztzreCV9mnY1c/ed/gI9W3KNpCy/GvMafsRl/5DVasTBAG6 83L5jCfXVvCfIGujz2vS+MrIcUtMbML26Sq1mUJjpJGA5+GLTbySB2jY6O5+Xt0R9PDK+CSK2/J mCtK9DLCq/ X-Gm-Gg: ATEYQzw6XAmPytD/3wAEoSnXbYP8HYgc84ibnBnwfPb9EW1haeWGj7vK02d1wGxDHCE vp9gbH91PLGmZS+SlPBEeIZm+vvhfXsvPgCYJo7gMIBzHjfhFw+SA1jQe95z0a7ZoyNdUcCwtB0 vvp2mh7K/fh//ZlmJ9dB93KUJdIczuWgA8Y08DP4/XBhSBvoJWb7JvotqKLQeswgPP0P2dAt636 stSB+OOMOHVU/VjxmIsBNnrqVKQdo07KeEqqMEXdM8ZJjol9U/xfQQFRGUE/6hGa4Z9HGYddVSK XFlqs72wJU0r/LTGKoGKDu/gGh1O85Ywc3h6xMzWlgD6/o2EHToayPsaJ9Wygv2OKO9DkGnP9Up V8i6tT2pUIFZPcaMGVJhUyg1cOA6OM7HTh/4GqxtWmJl7MBfrUo+2kfa2gdKvniqq2mb1E9EWiw tdkGwvLEBLqe4Sth2MXZba2N9i8wQoGVOlKGQk X-Received: by 2002:a05:620a:4495:b0:8b2:f0dd:2a97 with SMTP id af79cd13be357-8cd5af760a1mr126113685a.37.1772610657406; Tue, 03 Mar 2026 23:50:57 -0800 (PST) X-Received: by 2002:a05:620a:4495:b0:8b2:f0dd:2a97 with SMTP id af79cd13be357-8cd5af760a1mr126112485a.37.1772610656864; Tue, 03 Mar 2026 23:50:56 -0800 (PST) Received: from shalem (2001-1c00-0c32-7800-5bfa-a036-83f0-f9ec.cable.dynamic.v6.ziggo.nl. [2001:1c00:c32:7800:5bfa:a036:83f0:f9ec]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b935ac73a5dsm693263366b.25.2026.03.03.23.50.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Mar 2026 23:50:56 -0800 (PST) From: Hans de Goede To: libcamera-devel@lists.libcamera.org, Milan Zamazal Cc: Hans de Goede Subject: [PATCH v5 2/5] software_isp: debayer_cpu: Add DebayerCpuThread class Date: Wed, 4 Mar 2026 08:50:49 +0100 Message-ID: <20260304075052.11599-3-johannes.goede@oss.qualcomm.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260304075052.11599-1-johannes.goede@oss.qualcomm.com> References: <20260304075052.11599-1-johannes.goede@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-GUID: VvcgkqAg5YENpbDi_NV9NZkg2rSqatE6 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzA0MDA2MiBTYWx0ZWRfX3bbrPlPL8ax1 sSCrJ+wKTvlfYcND9nKRx2OKaUuqlapgWREJtDWVzp9p20SxALHEIgl4YOuhJSnwqKPAdEbEMjt qPaKl45kDcJxnQvUWsgtQQo7CLLfSKg+kLvcc8LT2qbf72OrdwZLcxl3cQfyp7SvTSYy0eS7KkD Gz7avUloyEnHyd36t/9p9OEHhC1+XL/LtoVlsYO5dCyApfd8R3kOMWY8r5GnbBq4rf7ffARvLmb NpgnZsgOiSfRpa90xHsMk9dHBH3s6ydLXc4eAP3gmgWNQ6GSk9KBQtwOHVoQvX5vukUz4DzuA3B f7wgWrxrKCFrmK06OO7OkYJQ2xcEEh4IUh6j7b8Bnjy3H+MhpxGYf5LDmNG6VIAu5ZTaiFIZPiz v4ZdxH/YkxrorUYBP6at73IlSPMvQhIyouJym6rymJ1RP2RUMtpxCRDPrwAlpPqsz3lEIhKpdBf 4Lcs7+JtwPFbVyFc63g== X-Proofpoint-ORIG-GUID: VvcgkqAg5YENpbDi_NV9NZkg2rSqatE6 X-Authority-Analysis: v=2.4 cv=BpWQAIX5 c=1 sm=1 tr=0 ts=69a7e462 cx=c_pps a=50t2pK5VMbmlHzFWWp8p/g==: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=Ba8D0n3WaO7QZ3tp1_0A:9 a=IoWCM6iH3mJn3m4BftBB:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293, Aquarius:18.0.1121, Hydra:6.1.51, FMLib:17.12.100.49 definitions=2026-03-04_02,2026-03-03_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 suspectscore=0 bulkscore=0 adultscore=0 malwarescore=0 lowpriorityscore=0 impostorscore=0 priorityscore=1501 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603040062 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. Reviewed-by: Milan Zamazal Signed-off-by: Hans de Goede --- 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..d57d640df 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 yStart - (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..780576090 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 Wed Mar 4 07:50:50 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: 26252 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 28680C32EF for ; Wed, 4 Mar 2026 07:51:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BD656623A8; Wed, 4 Mar 2026 08:51:05 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.b="LryNL55/"; dkim=pass (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="kNFev4bo"; 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 71E9A6239C for ; Wed, 4 Mar 2026 08:51:02 +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 6245SiB8152731 for ; Wed, 4 Mar 2026 07:51:00 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=2pTT2vd9CrP iuo7G72w3VpawJDhZAO0mN9LyY+btYmM=; b=LryNL55/S7qHtwXA63kzh/HyvPP RVCxLNEPfb8MAU7e0yE7g1TLb7B+FECzIwHIDxp3rUFREGToEFWUVpBp/yEyQcmi aVWSQskdD5EKQeXb1+S52D9vbPaF2pGPbr0I/s7c7KpvRTpJRLYEF5wA4S+d5TDV jigGw7bBC12dF+vmm5u95WMU5eMOIvHwHECS2fLAC8YSWpgtGktUzM0JhQ6jscPQ OAweCUitnlmgRwtiRPIrSGoz7W/MqZiLiMtVJ13ym5QuDe2plE3TqQxdVlHtlBor lKe+1SHx/7byhMuOjbFZdEAQ/bE1PdSa57C4KrigwSFLsFk0toRccQMmawg== Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4cp3tvjnpf-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 04 Mar 2026 07:50:59 +0000 (GMT) Received: by mail-qk1-f200.google.com with SMTP id af79cd13be357-8c70b6a5821so3532893485a.0 for ; Tue, 03 Mar 2026 23:50:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1772610658; x=1773215458; 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=2pTT2vd9CrPiuo7G72w3VpawJDhZAO0mN9LyY+btYmM=; b=kNFev4boXZFvkOCB+hBVMwg/bx220UHss050Lfj4kky8pZg/E2Gpkxtv8cqK4nZu6f qg9NM75zPqpcGaUZKLnjN0hpF1g2CwWTiRsg8D0NbxKfBzN5hsp4iN42CZ00IU61Iry2 TMhqYUswcqn+jTgtjKYHa954PDhdcZTzlHnRtPYwqLyvXwjC7+5J+ZcYNHHyAZ0m6Pcr kmn5fNynu9fdS4jCHvw0wOrhiYCOg8dRnM2FKtfqbXHu4F9c9q3ILqopOubVrsQzqTe+ 2O4GK0OmrgE1qfKOz1cjCDqbm0v0h8LmEm+NHfStU3UsLjE/hlvOiz2WfzkvUTDvK8xy Jz4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772610658; x=1773215458; 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=2pTT2vd9CrPiuo7G72w3VpawJDhZAO0mN9LyY+btYmM=; b=rcr1FJuX8rE4BXG83HqV5OttLwXAXqS4033pIvZmKLaE5f3u5vBJXGqJaSpM8IRgkH DnJxC6BtW8JY1nDmapRuvshLOBfYOncj68pDIblh0t9r6jx6xUNUEQ+61TKc0GQDQ6Ag CHsLRsbME+dWjKqYCpMiTwnAGQitQXyOmkiSomYOrm4NFpH7JhkNg5Mp0b3ul9VvLYo1 qyHV7ugAY5BA1gB47CFWlFQ+F5vjRxYNKaiTLZ7dz4TL4UxMQ748BAecuq80reFG39/5 LqJxUDYYieEbIxvmvBpTyHMNowQJ/fHYhmQ7NJVRVaoR/igFsLDq67wTNMM7roIO8MEw gUBA== X-Gm-Message-State: AOJu0YycYX1D1WZpadjxnyZVCktJ7Rjfc8QN2fvPFYAcv5A0f5w7ki/k kF7mlIRRop6BEDfZFthAl2TvCJHHss8ubwEeZAHvSPnuzBnAucTh23ObeWcUIWKHwwxibvLYKHu YEzRzwXagwLRAyV2c9K3ZvdZnc0f0SLW6sEO7Z22bfskWt9xSBbSMVBIl8O+2yPipaxmm/mWkbh 6oQjF4jFSC X-Gm-Gg: ATEYQzzK8jvHC8yMnowrpHChafcllD/bjQZSiTiLvqC4+bKXxzLCwAmgJRLDa5x6eQZ qE/IAS5yj48VX5d42+iHENf8RNBcKX89cPX7PljTed91Xk3bvkwrLI9JwpUSo30ZhMnkToPOoa3 dCy443z1NxBtpGdfO+7JWu9GdUyo9hTpyeYOiKu83WcsZzBvs/Re74o/Flkk6xNmfmJ2hBigx1m lJ6pgMRDvdHZcn27jLPUqjN21zl8B0I6J6THxsunzvO7eksFjC8TgoM8h6hBQIhX0KjN5enBcfF NlVNaGHRdsKyD1roUPhZUCW4Vfb0aZSKO80ykHOdJRUErJejqVkCikrsD80fVB4RaBC4A8b60vg j3ELIjnREL2bYcQnlLv8+wcenCAXXdjwBgtICTwlkdQhqzVkc3rwD7fQmpANAGSFTj5apxKw3PS GaIc4hki26LpMo8drsEcZcinSzUkPiLDUSLQBq X-Received: by 2002:a05:620a:25cf:b0:8b2:ec1e:fe24 with SMTP id af79cd13be357-8cd5af7852dmr133029085a.42.1772610658371; Tue, 03 Mar 2026 23:50:58 -0800 (PST) X-Received: by 2002:a05:620a:25cf:b0:8b2:ec1e:fe24 with SMTP id af79cd13be357-8cd5af7852dmr133028185a.42.1772610657870; Tue, 03 Mar 2026 23:50:57 -0800 (PST) Received: from shalem (2001-1c00-0c32-7800-5bfa-a036-83f0-f9ec.cable.dynamic.v6.ziggo.nl. [2001:1c00:c32:7800:5bfa:a036:83f0:f9ec]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b935ac73a5dsm693263366b.25.2026.03.03.23.50.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Mar 2026 23:50:57 -0800 (PST) From: Hans de Goede To: libcamera-devel@lists.libcamera.org, Milan Zamazal Cc: Hans de Goede Subject: [PATCH v5 3/5] software_isp: debayer_cpu: Add multi-threading support Date: Wed, 4 Mar 2026 08:50:50 +0100 Message-ID: <20260304075052.11599-4-johannes.goede@oss.qualcomm.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260304075052.11599-1-johannes.goede@oss.qualcomm.com> References: <20260304075052.11599-1-johannes.goede@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzA0MDA2MiBTYWx0ZWRfX04yOHmJTkvo+ 0fnprhJIhRyBGL9DNZAcLsV1kA4PA2fhQlv9tYhDb5xrM6rstxfQHSVqSXI5j6kRbEXaQHQQ9U6 jyUVRCG4dEeVTHzYQirYs+72abiJfE1X9yGMURCo+Deuf4xIAxq56lomsw2ufSuAjBUUtXMMt35 HYscxBJ9BIDo2a4Z5zKopBJBQ//nWujgzqRNYkMbzGK5cVxd8jE37gRWtqMvhuq4pH432LpPZLM YVOOmHmRPxesw55Efzfnb38clqvx4FHwtLMHPWENRp/0mPZMoP7Yr2bd7SA/CZqY3huqUs/pFkO SMXQj7ZwAcAEj149KMSO/jwLHPeisq9Ov7HO9YPdKjTxTh6sC3gsqH2foHZx8eCnAkZ4iIBiaTe AbUlWNDhJdafLypHz8eirxvnIVpL29OOhAqym8HiQ4s/IgXiyLs2eOqcjS+IbhC3qbSZVLjWeQl SJAogZ7d5BkW+T3LjHA== X-Authority-Analysis: v=2.4 cv=VYv6/Vp9 c=1 sm=1 tr=0 ts=69a7e463 cx=c_pps a=hnmNkyzTK/kJ09Xio7VxxA==:117 a=xqWC_Br6kY4A:10 a=Yq5XynenixoA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=YMgV9FUhrdKAYTUUvYB2:22 a=EUspDBNiAAAA:8 a=4i1XYD-pSnUufzSozdQA:9 a=PEH46H7Ffwr30OY-TuGO:22 X-Proofpoint-GUID: qVGW4iuvJhaBZHaEVmSlfEUl9BBZrR9a X-Proofpoint-ORIG-GUID: qVGW4iuvJhaBZHaEVmSlfEUl9BBZrR9a X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293, Aquarius:18.0.1121, Hydra:6.1.51, FMLib:17.12.100.49 definitions=2026-03-04_02,2026-03-03_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 suspectscore=0 bulkscore=0 adultscore=0 spamscore=0 phishscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603040062 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. Signed-off-by: Hans de Goede Reviewed-by: Milan Zamazal --- 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 | 45 ++++++++++++++++++++-- src/libcamera/software_isp/debayer_cpu.h | 10 +++++ 3 files changed, 60 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 d57d640df..f7c3e1751 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,8 +108,10 @@ 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); @@ -746,6 +749,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 +993,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 +1026,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 780576090..11280c0a1 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 Wed Mar 4 07:50:51 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: 26251 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 83C9CC32EA for ; Wed, 4 Mar 2026 07:51:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 318DD623A5; Wed, 4 Mar 2026 08:51:05 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.b="YOZFi/Bo"; dkim=pass (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Zw4UHxQe"; 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 65B8562391 for ; Wed, 4 Mar 2026 08:51:02 +0100 (CET) Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6245SXee3110522 for ; Wed, 4 Mar 2026 07:51:00 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=8Gvil8HmgAm ctZLXvrxDYw8ceQF1zFMUNkBVOjwGEfg=; b=YOZFi/Bofk/Ull9bZzx74gmaaeh qKF9HjoFTZMoeIE2RiuQSVaW67FPjD7X/eXF4bDtasCvnYc0zVmUdyoMR+IZYPKh IA2I9eRLj2d4+u5ahAfjs5RS6czTWShL98nl2JMml0nhLTmxHVaIshepAbFbyuWt K0piwc9I0GG0gekK7YkPUvxG82Eb8NpEvJB8b0fu4/G86yL/IR2xdI7/C6EFEC6F dZTnJG7XgMpNC0iGrhggplF9mifP/JhGKCRLs6GCoxKStf+fJYcMgF1KoOFJ/W6k y+PkgLVArOKsxKR82UmUg/JyOhawYXUzAlTkDENrxhCnAD2vOU5Cy+YPwMg== Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4cp5h2a7t7-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 04 Mar 2026 07:51:00 +0000 (GMT) Received: by mail-qk1-f198.google.com with SMTP id af79cd13be357-8c711251ac5so4135334785a.1 for ; Tue, 03 Mar 2026 23:51:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1772610659; x=1773215459; 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=8Gvil8HmgAmctZLXvrxDYw8ceQF1zFMUNkBVOjwGEfg=; b=Zw4UHxQeST4YWlpbjgZJtNQh+9h+Jvryo6h+U/dtEnyk/7z36o2DhTtM9cYqHpZ7Cc zJ8lh7qOpvS221yQ4vIb7Fv4FOhjMx6ay+rNaZH4Ahtq9uuy3Ywk8n+kRoUu3d4dtOFI j6VtRaw1/Ih6LHP+CEGS3ApAJkmu2bnmbH/VThroXypWWG6kq9fy8HRRYwDngRvvAcwe yEuonx/zoH3n7BLIA7H6NveB525OMLhF73rWNRn9pNz4kvVCtNpbapwr8DgWa3b4mFgz tSIcO2Xi0Zt2hlSXDdj3yrnzw22J4zkDTkqGVf2GStJ59/K+GHaOnlZ2YVvC9/3zE7xz DRCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772610659; x=1773215459; 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=8Gvil8HmgAmctZLXvrxDYw8ceQF1zFMUNkBVOjwGEfg=; b=j2BFEqaCeLYtYE6fEUD5wXc31znIRiSwNDJtLmr/8+Hoa+YyeFGxsdo7S1dHAKgoD6 FlEYnk1coDp0ooqwIAlJ6/aypHLqLZ612qRwpxArSmFN/E/UIC/KBOG8m8t1bPoTNZMj DUIZ+c0LmQl73lmprxQ2tcbcj69E8TwkgGgakYJe21FT7ZkN4ra7Bi8x4cyRr4yU4iZ7 4suOFbCTgp9zA7Qp6d+V1uvszuiMASM5qNgHG38r0pLiN0WrsAgkSAtlJgte0F9o04jd GA81X/wzXMEOpS7JvF0mEOTsAdHH8E8GDnfH4KH50UKD8UVdqcCnNMIwdtlZ25Yfzpg1 w3ag== X-Gm-Message-State: AOJu0YzZpSl7Olo8Cjwedwb4Xuy9SWk5qfLbLg7GEsnQaem4yv8FdYGR yoOEihs46nCNgJlKb34f1lhn4qOaAx6RBB70Ti3LPLdJxvcpoKlKasDlGHPgEK+hbQ/8s30Fbpa LcfsfGZFZ28jczI5yG3SfSPH4ES2bMKqkhYwQ9QWOTTuTjHaOT5mqJJaTu+jBJ744+hzwfRdNUR wv0UywBljp X-Gm-Gg: ATEYQzymA58Ga7ct0xpSnfIcgY6ouA5ve5PD8FU3KGujsFdV33Ab7DGhIMg7RdgK/uy Gchdweie5T6rSyvARMXHwijFj43GG8SvTjJRD/93GpscLJXFdSWWueMMunklDySEcLFTo0kcCw1 OvxHniRyKWxGxCD40p4kP8ifgeg9UFEFlnOTWN+/5b/1hpWS8n1UnL/pWOpLCsuzb+DOaF0/BO6 PS/vTT749AQ5grM0sk761aseN2icsWIipAJ2RTLUPTJPaqschjCzYhQH4f/tksQyf9U1tDiTVnz TjAI9ztQd0NflQSOmNpYRGPw3+ohx2mO9Jeb6j08S8DJSfgfVYukRDBNxWAECmkDgxWAvw0Jta+ Lp8l442PSQQwYVAUC0mzf9gEk8bZGSqohnYefqKwPi1D5zRRE4OyUyUmN8TtQapb8YB7Zd5v7iu P4DK1m/iqmlXUBYT+tUf6BL7Kb7/+LKdexOK4N X-Received: by 2002:a05:620a:4096:b0:8b2:74e5:b36 with SMTP id af79cd13be357-8cd5afa5ad6mr133601985a.68.1772610659329; Tue, 03 Mar 2026 23:50:59 -0800 (PST) X-Received: by 2002:a05:620a:4096:b0:8b2:74e5:b36 with SMTP id af79cd13be357-8cd5afa5ad6mr133600485a.68.1772610658856; Tue, 03 Mar 2026 23:50:58 -0800 (PST) Received: from shalem (2001-1c00-0c32-7800-5bfa-a036-83f0-f9ec.cable.dynamic.v6.ziggo.nl. [2001:1c00:c32:7800:5bfa:a036:83f0:f9ec]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b935ac73a5dsm693263366b.25.2026.03.03.23.50.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Mar 2026 23:50:58 -0800 (PST) From: Hans de Goede To: libcamera-devel@lists.libcamera.org, Milan Zamazal Cc: Hans de Goede Subject: [PATCH v5 4/5] software_isp: Log input config from configure() Date: Wed, 4 Mar 2026 08:50:51 +0100 Message-ID: <20260304075052.11599-5-johannes.goede@oss.qualcomm.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260304075052.11599-1-johannes.goede@oss.qualcomm.com> References: <20260304075052.11599-1-johannes.goede@oss.qualcomm.com> MIME-Version: 1.0 X-Authority-Analysis: v=2.4 cv=JqL8bc4C c=1 sm=1 tr=0 ts=69a7e464 cx=c_pps a=qKBjSQ1v91RyAK45QCPf5w==:117 a=xqWC_Br6kY4A:10 a=Yq5XynenixoA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_K5XuSEh1TEqbUxoQ0s3:22 a=20KFwNOVAAAA:8 a=EUspDBNiAAAA:8 a=mKg8M22OkPar6P-70WAA:9 a=NFOGd7dJGGMPyQGDc5-O:22 X-Proofpoint-ORIG-GUID: G4PKVQMS25KC8Fy7LK0fW8Ss69w5gQ2f X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzA0MDA2MiBTYWx0ZWRfX1RmgWT/+if/N HPn0tkHuXMmqlDnhQ8CUqQkOt/QzoYAUJzy/QEQYAjH8m5ivyWnbQ91iYFy1JC4N/iYnFDvG8MI 7GvJAPebmwxDyFfE/sTU4YJ6UrEAWxqo287LS167dK+u5czpAKzC15a7NKx5NVVLDXHk3BLSYad 8YvvlRiW9kZLaZvjlWTWp0XY6mFVCwOdTWodkfNRfqCkfQTL/c/hqgBBmAKlb4XVnrR0f3cnEym ocWm9tzLmCohkKOoTPHTzsWraYeqEYzpWhmrKsa0iWXlfarEbMKmw7sZZswM88nLIew/DOmonaL 164Stu657R4Cgzol5+owED0LrthmnuE5AGnVXUSewUpVm56NVKO1wgkiqPuboVbl0oCqYmatU8J C8NZw0PD718M19POdI3xSPeWmImYTw76V+38eqKU5kgT6s54FqWFaAWiuFFCx08PXORLidRQ9uI 7ceMJPLiZmJnyqOGTtQ== X-Proofpoint-GUID: G4PKVQMS25KC8Fy7LK0fW8Ss69w5gQ2f X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293, Aquarius:18.0.1121, Hydra:6.1.51, FMLib:17.12.100.49 definitions=2026-03-04_02,2026-03-03_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 adultscore=0 priorityscore=1501 lowpriorityscore=0 clxscore=1015 phishscore=0 spamscore=0 suspectscore=0 malwarescore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603040062 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 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 Wed Mar 4 07:50:52 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: 26253 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 12B35BE086 for ; Wed, 4 Mar 2026 07:51:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7D81D623AB; Wed, 4 Mar 2026 08:51:06 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.b="d3gMY//h"; dkim=pass (2048-bit key; unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="ZsjP5ZPX"; dkim-atps=neutral Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A40C0623A8 for ; Wed, 4 Mar 2026 08:51:03 +0100 (CET) Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6245ScWr957475 for ; Wed, 4 Mar 2026 07:51:02 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=EKjThyVT7ep 2go4Ot2fsP1nbs+kragzoyIS371FF1V8=; b=d3gMY//hN//vfK+LnGIYLsQDym1 oxXvV0qY6bv3hGFoI35dkwbkuI59/vbMobs8+l0o/uCj4DExfB1yR553argPBiLj 8Az9ANMdmkL8EP6pbmRpjd8I8MhJfYnRQJZbJwmj4nGkX941EnzLUK/FjWr9JxfI Gw6be3xFX6bBBb5P7eGK4HedHhBWYjs/BCylMu0up5knK4KO735OdwJyh5aDl62d 3tnoAGRKf1jYNwABfzqcf5mJMqbjUUmIzygayDj6NNW6ttb4WcJ9y6HnLpAn68pO vDSKzWzylxlsg6+baeJbzz4v+Jauk2OglMjFAPv35w+HqMMJUbdRD8idPpw== Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4cp6qg9xd4-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Wed, 04 Mar 2026 07:51:02 +0000 (GMT) Received: by mail-qv1-f72.google.com with SMTP id 6a1803df08f44-89a0796368eso124296866d6.0 for ; Tue, 03 Mar 2026 23:51:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1772610661; x=1773215461; 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=EKjThyVT7ep2go4Ot2fsP1nbs+kragzoyIS371FF1V8=; b=ZsjP5ZPXIHko0lfkm9XQOvWtTl1A2UFTVpaczKpheBWlwHgbPwwIk0jtI3BaYU/k62 j6NwoDkbl5Fwjl8MQG6RpI3Fyb1FSLqrM1NhKLZN21tbu1A+D/9GvBKfXvP3B6Xag4Tp w2ae8uUZCSSMeR/8jnUFDsYs5gibsUrtc7UhMmMnnGCaeyxQkQVzKS4Zkv9FdgVHThRQ gz9J1RfuRgDqIp+1PlnR9Vf3fSHTBaaTBqVx9/s4l/Pow5bgGvp2cLS5i0JY2HZM+f0H BjKVR/kUHm9yjMBPzPt+TZKiKErhWzYgPLhJpiG07Dzce9cE2hZB9B0RrZnNFVdKHMHJ UDlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772610661; x=1773215461; 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=EKjThyVT7ep2go4Ot2fsP1nbs+kragzoyIS371FF1V8=; b=xULXxhQYw6BKf05joe1KcdqRpGbOM6T9M6raRc2akqJnUY84tS0kKNjFTSkCPx4nTr 2H6ttuWue7z9mSj3BPFfpJSZjll1Ub+SnGdXc28L/WidrGggzkU9JAxYUOFInZzrJo47 zH10MCHl8gsfwWJEzTCj6HUt7al7xcTxkT8KQr/kv/RhyuqFhLGd6O4hWZWL4jhZmy94 EZ642yWjHkqkriRp8gkJWhWI0m7SrcMXyu9kdrV+WpmHXxakfH5XbfSfBuTWX5GdCZIY 38ErbVFxsrmnEk0ySOuqBAlnwg05lrpUAAEKxlQEsw0NOESySwgqXxrklGgbSB8NqRpg XM4A== X-Gm-Message-State: AOJu0YyW2ggDz9ONbPwVgy2R8TU3hO1EgUjEC+xir7XXmTVKEVf4Q8k4 sKb79Nocgu9sn5QAbU3b7VJmlDiizoLEfRVYA0qTpWeL4jMTB0K/yrVtFvBifKEOXzsqiFTwVPr tELagQCu111WxMaL9+M3QgNelJmrWR+53j/8PhaKzWHL5Jfi08yQ/WwrQQQFc1tlithK3Ck3q4j javn9JoMfz X-Gm-Gg: ATEYQzyB+W+Y31WE3KJLxy2kME0qdE0tNl6fdtcEtl21o+xsk16DLth3H3yAF490o4E 2qa99HSI3qIkcZKYdqadGKGP7ewq1BrztwxycHg7CqdgQ0WlEFhO8nzK3ZJjPfuy4wqqJU3vBz0 SfPKBCDejmgxhB9g3vaao7kaKq0GC8uJigPVfBiWosNf77ch+72BSIweijJGa8Ty2VeN8S7ESuj 25w3M6acHbWXyQJ9eTEXdH0+BQjBgw9A2v/TTGZgbvI9u7RUO0MJUkOzZB+VU1HRP9vyYJEsTGY VKjyiRXIpdlN+6SZS5YkARbRXjnXxZCS8P4cDI3Ai5nLgaTwMfNNmqV2JxztzzE3hJYjnoYleQn A53WQ+FHnwtdWl8s6FjKNmDn6OUqPN32wVKUDnTCFaGxIgobHlshX65OipR29wMG7HTM5XoFbGu nmPJwu0nUosbBoP6fGaEyfFIhiLVoCaWiiq7e1 X-Received: by 2002:a05:6214:dac:b0:899:f5d3:321c with SMTP id 6a1803df08f44-89a19abc34fmr12214966d6.10.1772610661151; Tue, 03 Mar 2026 23:51:01 -0800 (PST) X-Received: by 2002:a05:6214:dac:b0:899:f5d3:321c with SMTP id 6a1803df08f44-89a19abc34fmr12214796d6.10.1772610660679; Tue, 03 Mar 2026 23:51:00 -0800 (PST) Received: from shalem (2001-1c00-0c32-7800-5bfa-a036-83f0-f9ec.cable.dynamic.v6.ziggo.nl. [2001:1c00:c32:7800:5bfa:a036:83f0:f9ec]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b935ac73a5dsm693263366b.25.2026.03.03.23.50.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Mar 2026 23:50:59 -0800 (PST) From: Hans de Goede To: libcamera-devel@lists.libcamera.org, Milan Zamazal Cc: Hans de Goede Subject: [PATCH v5 5/5] Documentation/runtime_configuration: Add missing software_isp.mode doc Date: Wed, 4 Mar 2026 08:50:52 +0100 Message-ID: <20260304075052.11599-6-johannes.goede@oss.qualcomm.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260304075052.11599-1-johannes.goede@oss.qualcomm.com> References: <20260304075052.11599-1-johannes.goede@oss.qualcomm.com> MIME-Version: 1.0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzA0MDA2MiBTYWx0ZWRfX4vlH+X+LtLcP 0nejqc7hTLXoXBRxQQIVSDO49ADknqLruCifrkkMj0jwPMf6omKkh1h66Oo/y0KTQDJV77P1xPA V9wlwG4z5MZb/ZrkG6c52DKOW5te96WUKf8bSJJK553eQJiP96Fa/epJ2pIIowywQGSnfIUcJ4c oKqLDmT0JtYCFAYDOXU9i6tpin7KoNAB57CXAACJg5JzCMrCItLOFmjrKVOh8GthjdUZYqjKgxs LAcX6K7RiEomWdmPychaogV8cxChSsMfO+Ez3IAwuCchH3cgTBNLLRwusODYU5xaRSxjNCwFq9v g1a3jLB0LuGsKINaXOtaEgOptNV+plvMqVIntJ4WAJsC0yF2KFFc1xOz6KblvjCGaBlz4QbTKuB FeUdVc2meJmMa5QMVvB7NrACiQht4d0eMjQH9h8n2S/BxwtXjF6qv8CESMTsYdfVxHbaCUMe0tK VzxGf6Rzed1PqXFZiHg== X-Authority-Analysis: v=2.4 cv=UJ3Q3Sfy c=1 sm=1 tr=0 ts=69a7e466 cx=c_pps a=7E5Bxpl4vBhpaufnMqZlrw==:117 a=xqWC_Br6kY4A:10 a=Yq5XynenixoA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=EUspDBNiAAAA:8 a=AwfkMlB2NLtm-T6jQ-oA:9 a=pJ04lnu7RYOZP9TFuWaZ:22 X-Proofpoint-ORIG-GUID: 4RD2Mqa6JB22PgtSvdklarNQtamQfJ6p X-Proofpoint-GUID: 4RD2Mqa6JB22PgtSvdklarNQtamQfJ6p X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293, Aquarius:18.0.1121, Hydra:6.1.51, FMLib:17.12.100.49 definitions=2026-03-04_02,2026-03-03_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 priorityscore=1501 clxscore=1015 malwarescore=0 spamscore=0 adultscore=0 bulkscore=0 phishscore=0 impostorscore=0 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603040062 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. Signed-off-by: Hans de Goede Reviewed-by: Milan Zamazal --- Changes in v5: - New patch in v5 of this series --- Documentation/runtime_configuration.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/runtime_configuration.rst b/Documentation/runtime_configuration.rst index 651929a4d..e34321ee0 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 @@ -169,6 +171,16 @@ software_isp.measure.skip, software_isp.measure.number Example `number` value: ``30`` +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. + + This can be overridden through the ``LIBCAMERA_SOFTISP_MODE`` environment + variable. + + Example value: ``gpu`` + 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.