From patchwork Tue Mar 24 14:32:07 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 26324 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 A40A3C32DE for ; Tue, 24 Mar 2026 15:17:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DFD7762790; Tue, 24 Mar 2026 16:17:20 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="lHZ8tF6X"; dkim-atps=neutral Received: from mail-wm1-x32b.google.com (mail-wm1-x32b.google.com [IPv6:2a00:1450:4864:20::32b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F0E566277D for ; Tue, 24 Mar 2026 16:17:18 +0100 (CET) Received: by mail-wm1-x32b.google.com with SMTP id 5b1f17b1804b1-486ff3a0fc1so35172645e9.2 for ; Tue, 24 Mar 2026 08:17:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1774365438; x=1774970238; 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=6aADIWBAWxWqOxkg3S/oIUwyQIh5VxmPUzgQyo+Vg5M=; b=lHZ8tF6X3107F424gmPji4pT542umVZgTImJvuu4tZUEt7hBRqW6SGtzSHY/sWj+7q As+IQJrrkY+2Z2MtuanaEmYyvbTfM+OnCwr+EU8JMUxfoFyZkQmx+JC2v5yXB8qPb5HX KQQPwWcK8zOEB+4i01ZWfYZD4IXmnOrsOfGR2WrVqcf7xqRIJ3RI2I/u4/zejOd/Pbhl e3mgVj3TOnkn52YCopCH9OZFjKziscDqFiToQ6QY0TuPBBf1ZNnUv2OJQ+ULdyQOok2F e87YnQR1EGappiVa864zZWogbmibK7r8eZPkNZFaJBPFfZ6/8Jt526hnEoD6xDhT1Ig5 wRCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774365438; x=1774970238; 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=6aADIWBAWxWqOxkg3S/oIUwyQIh5VxmPUzgQyo+Vg5M=; b=SmAikSdcZ4xjWfyHiE7ONlKpdUdfwyce4d7fm1bVzxg3Ua6wTK0XW0pnilKu3FM/1F OnrkrtpDLdRS/+E353h9vzWEiwwMdxc4RjhMD6y8yubBgsRYZkyXkTyPbolh7hWIpsof b37j3ZpOgySlHML6UsINtGzMYQTtXkcNXqOFwZfExLqz7scxoXE04MxsWW2cXqs1KPe1 T0AvQTVs98mGrDw6eorpokr4/Pw2/1scV0iA8jLcfQGnduwC8JpSbi8hXHgT/TCFv/x/ gy502HzR88ELZ2zk1DRfwZQaNOov8thkIZiloQA4C+uCfDJacpjj6s/KaO9pFMMS+6si HDwQ== X-Gm-Message-State: AOJu0YzOkEz0Ogu1S9WSTU2KuLY07fn5h44BdiEQebITog3aZrzMa7Da CnaPKm6FRrjtHdiw1VG2sViIrPsVCFZv7TT2aeiRSImketQiMysogvU6EiABL/bJhgqxift5VPx MYXyZ X-Gm-Gg: ATEYQzxVfWe8+nH3LHfPIhTJpdI7LH9ffRLJwqIdYBa+jCNcZX2Y5MCFKkYW8s01+Cf BRjzdt0Kg+MFYJPGSyDLiiqfTI3HR86xjb7HORrBvAK4+N35BjGfTImP67WPiTDBqzWIV7F6Hv7 04pHqaFpQLthYLDcKiY7pjRtF6D/5FjwGWolWrja5FaMTQje2s8MuSSfKWdP439ougtvVeBU8d8 lAy8yGQB1kjuE14t11bU+AOy/IRXNm3e57QX9mAkCcUZC9Rf7Zd3hh1S2eiyo3riq8TAmrzHAC7 +zcj2QrxpZXCH3zqWGpRZoEcMcYaoezkyLW03oDyrywk5JaFcezIxEdY86YSR5GiJABF0DM81BK Q6J5SphQNvWRd/XGLVP4EDVgXYTYEu+9IGb+0nfOScA5Nn5KFfHCyR25B7Glp7rwfqonWWZuxUV uQQNm7+o1l0sH9v4P6XyX9G8WqQb0S4Utez4ZB49NSpqEKhh/0wsA4J+xvLHYJWczeyKeqNK6uW QEcJeB0S+gaZwmgF9OOf7StXPrxsmj4t/NFpiCJDg== X-Received: by 2002:a05:600c:1d02:b0:487:716:2fa2 with SMTP id 5b1f17b1804b1-48716039accmr1911365e9.16.1774365438088; Tue, 24 Mar 2026 08:17:18 -0700 (PDT) Received: from davidp-pi5.pitowers.org ([2a00:1098:3142:1f:88ea:c658:5b20:5e46]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-487116c44bfsm63826065e9.9.2026.03.24.08.17.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Mar 2026 08:17:17 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Cc: David Plowman Subject: [PATCH v1 1/3] pipeline: rpi: Simplify delayed controls Date: Tue, 24 Mar 2026 14:32:07 +0000 Message-ID: <20260324151714.3345-2-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260324151714.3345-1-david.plowman@raspberrypi.com> References: <20260324151714.3345-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The queueCount field in the DelayedControls is actually redundant. Remove it. Signed-off-by: David Plowman --- .../pipeline/rpi/common/delayed_controls.cpp | 22 +++++++++---------- .../pipeline/rpi/common/delayed_controls.h | 1 - 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/libcamera/pipeline/rpi/common/delayed_controls.cpp b/src/libcamera/pipeline/rpi/common/delayed_controls.cpp index 19c71946..c06bd784 100644 --- a/src/libcamera/pipeline/rpi/common/delayed_controls.cpp +++ b/src/libcamera/pipeline/rpi/common/delayed_controls.cpp @@ -119,7 +119,6 @@ DelayedControls::DelayedControls(V4L2Device *device, */ void DelayedControls::reset(unsigned int cookie) { - queueCount_ = 1; writeCount_ = 0; cookies_[0] = cookie; @@ -155,8 +154,8 @@ bool DelayedControls::push(const ControlList &controls, const unsigned int cooki { /* Copy state from previous frame. */ for (auto &ctrl : values_) { - Info &info = ctrl.second[queueCount_]; - info = values_[ctrl.first][queueCount_ - 1]; + Info &info = ctrl.second[writeCount_]; + info = values_[ctrl.first][writeCount_ - 1]; info.updated = false; } @@ -175,18 +174,17 @@ bool DelayedControls::push(const ControlList &controls, const unsigned int cooki if (controlParams_.find(id) == controlParams_.end()) return false; - Info &info = values_[id][queueCount_]; + Info &info = values_[id][writeCount_]; info = Info(control.second); LOG(RPiDelayedControls, Debug) << "Queuing " << id->name() << " to " << info.toString() - << " at index " << queueCount_; + << " at index " << writeCount_; } - cookies_[queueCount_] = cookie; - queueCount_++; + cookies_[writeCount_] = cookie; return true; } @@ -277,12 +275,12 @@ void DelayedControls::applyControls(uint32_t sequence) } } - writeCount_ = sequence + 1; - - while (writeCount_ > queueCount_) { + while (writeCount_ < sequence + 1) { + writeCount_++; LOG(RPiDelayedControls, Debug) - << "Queue is empty, auto queue no-op."; - push({}, cookies_[queueCount_ - 1]); + << "Pushing noop with for index " << writeCount_ + << " with cookie " << cookies_[writeCount_ - 1]; + push({}, cookies_[writeCount_ - 1]); } device_->setControls(&out); diff --git a/src/libcamera/pipeline/rpi/common/delayed_controls.h b/src/libcamera/pipeline/rpi/common/delayed_controls.h index 487b0057..48ad5a0f 100644 --- a/src/libcamera/pipeline/rpi/common/delayed_controls.h +++ b/src/libcamera/pipeline/rpi/common/delayed_controls.h @@ -76,7 +76,6 @@ private: std::unordered_map controlParams_; unsigned int maxDelay_; - uint32_t queueCount_; uint32_t writeCount_; std::unordered_map> values_; RingBuffer cookies_; From patchwork Tue Mar 24 14:32:08 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 26325 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 03421C32F5 for ; Tue, 24 Mar 2026 15:17:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 87270627A0; Tue, 24 Mar 2026 16:17:23 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="V0LR71ar"; dkim-atps=neutral Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 73ACC62780 for ; Tue, 24 Mar 2026 16:17:19 +0100 (CET) Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-486fba7ce4cso13677965e9.3 for ; Tue, 24 Mar 2026 08:17:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1774365439; x=1774970239; 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=jwfTXc4D3DydDsUGThxajQYHqBUHYtIuWTR29C53rJU=; b=V0LR71arB+C1l0SyAMCfURTEyYqZ2OP9Tp/3YQrTO3ztb0cmfwygmhi7fVsG8g3Us9 6oGoJuYhrY7oQTymCxH9VSCefPoy8xm3jFPcN9rbmlexLHsnnYi5TpZFOjUxMrMuQHR3 YuZHWRMLdq76j4FXzp7p7F6lNK145scACfMMbhk+PmbQuXxBI3Xp8qgQazFcKj8jfRYg P0/dZ9vPVLy5bvw5+Dg6tdiNix9BRcN+c4rLc/cevjo7IRzK6yoFnxCa8duXTNwYhY39 PHp1VtcBmYN/ailJo/q38ygB5GVZ4dQpktXKuki+wgGEiuAatjw7ExLF7F5SAbl73DY7 3+uQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774365439; x=1774970239; 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=jwfTXc4D3DydDsUGThxajQYHqBUHYtIuWTR29C53rJU=; b=ZqYtMxtAmeQs50IW47h7fuL9NgTen3vPvmsg48VMpRh2pR7v42L1NuPs0K6PcYMyss yWcIBtjQHx9srEGnjgRQrdTAQt9Kcd8+EWpLKyqdok3wpkxSOdB2AGub88MWA8FDVbed XBg2W/upIRlmtBAstIhJRWuwEsnOiyUCXSxuQAdGNzX8VDqoqzckRSJPi0FjjT4aNX4f 7FvX1yDSxsA61coMSCh1J3WFsncBKTHXvPFseBnPB8l83AtUOfPmGHbyLBhratbzKxmA 3kNGcnFOFEtzm4Co+h3N4njWcAkZdN0Zul8TU+dLutbM/RAKoEkPVP1xKSOXDnyjHzW0 /eUg== X-Gm-Message-State: AOJu0YzRj1kboLUPyqn4lroEq9AxXdJzSGYzj/8Wiqon99THcTdk8cVa oIuhhCBFCfeCXMdcShrvOFQmucHe9x4iIdrhLK9V4eOXNzivp12WKfR1/39KJNbNqwONv8qqGMh qPNQN X-Gm-Gg: ATEYQzzbcfDRFu83DzaenWERmadEbHNq/jws35l/0Zze7FOG9m27bU/G5shx5WQWVt2 YKIGzLc/jI3JnqxNuB1Iyx4/sQwvVhew9Ob7Am8MABRxkX20qGbxrdWMML6uvkfT8lx1HAdC5ia st420DXnVSjEmRg+MrEG9ZlT9qBYBPJLBnLCchjXunDjEFe10DiFIbLl0EHdzvv6fUIMgfsOuP0 pIcmDg5qTPz/QVC8+G4868Xq9oBZCOr69R8GRobwNH62hjVYTj6tAmsYDfdaYPENuEFDnvETwxI Nwm4BvKrR95RCNkoNBa3BCgY4I197xvcTSUUmOD3FMfRusUNo1/H/MoKty/h/YhOKHMoSHxU8Jw GofldFn/EP1XaXQy/5AO9nt9reeatywHFmpev/71oklQ7edE++qmQPM3g4EI+On7wX2ZRpEImri 2+DJxAlXlp8biu4eEpnkNhEdyg549BHS/RGIO5x/RA1qNpw24Cd1LhhUQ0FxDQ7/3RgBFXVE7na waIQZgb0XweAALqx5ekVU45GRtayV95zCmozGTB/A== X-Received: by 2002:a05:600c:a0a:b0:487:288:1198 with SMTP id 5b1f17b1804b1-4871605ce9fmr2193705e9.22.1774365438597; Tue, 24 Mar 2026 08:17:18 -0700 (PDT) Received: from davidp-pi5.pitowers.org ([2a00:1098:3142:1f:88ea:c658:5b20:5e46]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-487116c44bfsm63826065e9.9.2026.03.24.08.17.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Mar 2026 08:17:18 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Cc: David Plowman Subject: [PATCH v1 2/3] controls: rpi: Add ControlId control Date: Tue, 24 Mar 2026 14:32:08 +0000 Message-ID: <20260324151714.3345-3-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260324151714.3345-1-david.plowman@raspberrypi.com> References: <20260324151714.3345-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The ControlId identifies the sequence number of the request whose controls have been applied to the images in this request for the first time. Signed-off-by: David Plowman --- src/libcamera/control_ids_rpi.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libcamera/control_ids_rpi.yaml b/src/libcamera/control_ids_rpi.yaml index a8615112..aca023d7 100644 --- a/src/libcamera/control_ids_rpi.yaml +++ b/src/libcamera/control_ids_rpi.yaml @@ -183,4 +183,14 @@ controls: \sa SyncMode \sa SyncReady \sa SyncTimer + + - ControlId: + type: int64_t + direction: out + description: | + This is the sequence number of the request whose control list has + just been applied. Controls normally take several frames to apply, + so the number here will refer to a request submitted a number of + frames earlier. + ... From patchwork Tue Mar 24 14:32:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 26326 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 E83C7C32F6 for ; Tue, 24 Mar 2026 15:17:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 795466278D; Tue, 24 Mar 2026 16:17:24 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="WJ3j3b12"; dkim-atps=neutral Received: from mail-wm1-x32b.google.com (mail-wm1-x32b.google.com [IPv6:2a00:1450:4864:20::32b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8141762784 for ; Tue, 24 Mar 2026 16:17:20 +0100 (CET) Received: by mail-wm1-x32b.google.com with SMTP id 5b1f17b1804b1-48374014a77so54137695e9.3 for ; Tue, 24 Mar 2026 08:17:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1774365439; x=1774970239; 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=Felfuv/vx6wuAkWZ2K+rXbJMlM17aSgPLpgoMJipYjY=; b=WJ3j3b12kYbxenCgaf4BcYpuE2CKJTeGf7DyOD7C8lo32g0ULX2ZEepdlbPD6ruLRs YM8owPNlVAEmR9nAoZCKdYMoO+PWZMSWcDlPUqwvmoHd1+rRcAKS8TYRNBTcFw36uu3I Pn1ZHRybDKMvLg7c2e0PCww8Y8krSjnSFxnkQ+lUbWxF7sGV1nos0uUkvIVdv9ejNaV4 k1NTMi3i8AhBVOOnSaSaZvwLrBngqPzwIyOawEOgQp+9ecCuKAfunRwmjuOSjflQ7iWz s+DKVGwzzhBL6/sCJp8RoeVmyIbyQi4FlkbK39q3OD5/U85HBkb0MKfOSJWVJPxxufAT Pceg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774365439; x=1774970239; 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=Felfuv/vx6wuAkWZ2K+rXbJMlM17aSgPLpgoMJipYjY=; b=rhHVLtngdF9x0isGrtd0K8FOiqWwgHtjYneVOjRahymFQpND+UMBPCv8PkP0ncy8K9 1gjrvuC3sfUTNMKUkSfs/Wf6PNggT4I3pJNWtYhP/lbOBsTq8XCnHGwlT9oli3fThZzg teyhEdj1G0VwWB6h3bc13YyQZaHDdME147+DIq7aD9pboZJWAh40S48EWNWnYP3XFPlG /F5GcU+QEAXoM8QbxGPAH9IkPgElhcfv62O1VzMOPOzWmF+kwkukFhheEdD/PRUrS514 7Ab5zpcypK8lacjsrGV8tRnEapageVCvb3Tl5xSPHqfDIIDBtHqye6S0MEc9Xy5/yBXC e4qA== X-Gm-Message-State: AOJu0Yxk7hpAok1yplAUU0TuhNOB3VwIsFk1k1IbRvKa2rlHcRiRUylw ubPW5O+HErvq9zJnxzjyjFmyPwpTl9WkVc6nNiUNF8xuBssW5L2WqTN9n++Usetgf0kHf44Mgsy uj1aD X-Gm-Gg: ATEYQzzyuybYypMrFBRamHF/2/ZlYfqrGiKM2cL72G/6JIMeZh4955JLdOF9D3eTTd6 M4JiOW0AAw96EX+6s1zEzyQwy7seA2P44FQ6QVgymhnVpY1CB9+HgoHuYGBIZDQye9MwIEUPLpD 5yLWhpUfB5G/tu8YGlBAz4L35l4rhRYzr/SdWG6wVMrynaxmjR+1bJHqPJfb56NTtYbC6Snud+d fplVkwzaJB/ZtB62tTV5pGl2ppRU0O+k/RY2552vRi6HTDKjk0osVhOj6REZbba52UD0K5Pvji+ QLngkhyV/HqwMW7n7/VIrp0ECP5Ve6OPpFtwc7UrCbozpktTHge15yEh2iQF1etM2drlOHYgx/5 035JKBXz5Q2R5wuwilfqiqbGOYHUztWok8VRP3UouUvzpqbqTpkkX1cJ25uhFjXIs8qzCwF3TK8 /LDxpBi5P9BhqpECMgVqh5CS886l8TCm6+3EUlipWICWuYFSKI10sVRKZ1rMPyf+XSYlIiw3KFj NO2basp6JntY1sJAu/cSzGvBd4GBJgRNI9tPtXWaA== X-Received: by 2002:a05:600c:3ba1:b0:485:3ff1:d5c3 with SMTP id 5b1f17b1804b1-48715fc322bmr2570915e9.5.1774365439283; Tue, 24 Mar 2026 08:17:19 -0700 (PDT) Received: from davidp-pi5.pitowers.org ([2a00:1098:3142:1f:88ea:c658:5b20:5e46]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-487116c44bfsm63826065e9.9.2026.03.24.08.17.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Mar 2026 08:17:18 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Cc: David Plowman Subject: [PATCH v1 3/3] pipeline: rpi: Make control lists in requests properly atomic Date: Tue, 24 Mar 2026 14:32:09 +0000 Message-ID: <20260324151714.3345-4-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260324151714.3345-1-david.plowman@raspberrypi.com> References: <20260324151714.3345-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When a request is about to be processed, this commit separates "delayed controls" (camera-related ones that take "a few frames" to apply) from "immediate controls" (ISP-related controls) that will happen instantly. The immediate controls are held back until the delayed controls that they were submitted with, have happened. This means all the controls submitted in a request happen atomically. We therefore already have the sequence number of the request whose controls have just been applied, so we additionally attach this to the current request as "ControlId" metadata. Signed-off-by: David Plowman --- src/ipa/rpi/common/ipa_base.cpp | 24 ++++++---- .../pipeline/rpi/common/pipeline_base.cpp | 46 +++++++++++++++++++ .../pipeline/rpi/common/pipeline_base.h | 8 ++++ src/libcamera/pipeline/rpi/pisp/pisp.cpp | 3 ++ src/libcamera/pipeline/rpi/vc4/vc4.cpp | 3 ++ 5 files changed, 76 insertions(+), 8 deletions(-) diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index faa77719..dacafa57 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -431,6 +431,15 @@ void IpaBase::prepareIsp(const PrepareParams ¶ms) rpiMetadata.clear(); fillDeviceStatus(params.sensorControls, ipaContext); + /* + * When there are controls, it's important that we don't skip running the + * IPAs, as that can mess with synchronisation. Crucially though, we need + * to know whether there were controls when this comes back as the + * _delayed_ metadata, hence why we flag this in the metadata itself. + */ + if (!params.requestControls.empty()) + rpiMetadata.set("ipa.request_controls", true); + if (params.buffers.embedded) { /* * Pipeline handler has supplied us with an embedded data buffer, @@ -451,7 +460,7 @@ void IpaBase::prepareIsp(const PrepareParams ¶ms) */ AgcStatus agcStatus; bool hdrChange = false; - RPiController::Metadata &delayedMetadata = rpiMetadata_[params.delayContext]; + RPiController::Metadata &delayedMetadata = rpiMetadata_[params.delayContext % rpiMetadata_.size()]; if (!delayedMetadata.get("agc.status", agcStatus)) { rpiMetadata.set("agc.delayed_status", agcStatus); hdrChange = agcStatus.hdr.mode != hdrStatus_.mode; @@ -464,9 +473,13 @@ void IpaBase::prepareIsp(const PrepareParams ¶ms) */ helper_->prepare(embeddedBuffer, rpiMetadata); + bool delayedRequestControls = false; + delayedMetadata.get("ipa.request_controls", delayedRequestControls); + /* Allow a 10% margin on the comparison below. */ Duration delta = (frameTimestamp - lastRunTimestamp_) * 1.0ns; - if (lastRunTimestamp_ && frameCount_ > invalidCount_ && + if (!delayedRequestControls && params.requestControls.empty() && + lastRunTimestamp_ && frameCount_ > invalidCount_ && delta < controllerMinFrameDuration_ * 0.9 && !hdrChange) { /* * Ensure we merge the previous frame's metadata with the current @@ -535,7 +548,7 @@ void IpaBase::processStats(const ProcessParams ¶ms) ControlList ctrls(sensorCtrls_); applyAGC(&agcStatus, ctrls); rpiMetadata.set("agc.status", agcStatus); - setDelayedControls.emit(ctrls, ipaContext); + setDelayedControls.emit(ctrls, params.ipaContext); setCameraTimeoutValue(); } @@ -951,8 +964,6 @@ void IpaBase::applyControls(const ControlList &controls) /* The control provides units of microseconds. */ agc->setFixedExposureTime(0, ctrl.second.get() * 1.0us); - - libcameraMetadata_.set(controls::ExposureTime, ctrl.second.get()); break; } @@ -976,9 +987,6 @@ void IpaBase::applyControls(const ControlList &controls) break; agc->setFixedGain(0, ctrl.second.get()); - - libcameraMetadata_.set(controls::AnalogueGain, - ctrl.second.get()); break; } diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 867ecf1b..9e162870 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -1528,4 +1528,50 @@ void CameraData::fillRequestMetadata(const ControlList &bufferControls, Request } } +static bool isControlDelayed(unsigned int id) +{ + return id == controls::ExposureTime || + id == controls::AnalogueGain || + id == controls::FrameDurationLimits || + id == controls::AeEnable || + id == controls::ExposureTimeMode || + id == controls::AnalogueGainMode; +} + +void CameraData::handleControlLists(uint32_t delayContext) +{ + /* + * THe delayContext is the sequence number after it's gone through the various + * pipeline delays, so that's what gets reported as the "ControlId" in the + * metadata, being the sequence number of the request whose ControlList has + * just been applied. + */ + Request *request = requestQueue_.front(); + request->_d()->metadata().set(controls::rpi::ControlId, delayContext); + + /* + * Controls that take effect immediately (typically ISP controls) have to be + * delayed so as to synchronise with those controls that do get delayed. So we + * must remove them from the current request, and push them onto a queue so + * that they can be used later. + */ + ControlList controls = std::move(request->controls()); + request->controls().clear(); + immediateControls_.push({ request->sequence(), {} }); + for (const auto &ctrl : controls) { + if (isControlDelayed(ctrl.first)) + request->controls().set(ctrl.first, ctrl.second); + else + immediateControls_.back().controls.set(ctrl.first, ctrl.second); + } + + /* "Immediate" controls that have become due are now merged back into this request. */ + while (!immediateControls_.empty() && + immediateControls_.front().controlListId <= delayContext) { + request->controls().merge(immediateControls_.front().controls, + ControlList::MergePolicy::OverwriteExisting); + immediateControls_.pop(); + } +} + } /* namespace libcamera */ diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h index 597eb587..65d8efdc 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h @@ -180,10 +180,18 @@ public: ClockRecovery wallClockRecovery_; + struct ImmediateControlsEntry { + uint64_t controlListId; + ControlList controls; + }; + std::queue immediateControls_; + protected: void fillRequestMetadata(const ControlList &bufferControls, Request *request); + void handleControlLists(uint32_t delayContext); + virtual void tryRunPipeline() = 0; private: diff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp index dff73a79..cc8aa4d4 100644 --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp @@ -2322,6 +2322,9 @@ void PiSPCameraData::tryRunPipeline() fillRequestMetadata(job.sensorControls, request); + /* This sorts out synchronisation with ControlLists in earlier requests. */ + handleControlLists(job.delayContext); + /* Set our state to say the pipeline is active. */ state_ = State::Busy; diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index b734889d..f743c8a7 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -939,6 +939,9 @@ void Vc4CameraData::tryRunPipeline() fillRequestMetadata(bayerFrame.controls, request); + /* This sorts out synchronisation with ControlLists in earlier requests. */ + handleControlLists(bayerFrame.delayContext); + /* Set our state to say the pipeline is active. */ state_ = State::Busy;