From patchwork Fri Aug 29 09:10:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 24259 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 51EE9BD87C for ; Fri, 29 Aug 2025 09:10:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id ED3976931A; Fri, 29 Aug 2025 11:10:28 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ChsmIKm1"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CD95C692DF for ; Fri, 29 Aug 2025 11:10:26 +0200 (CEST) Received: from neptunite.hamster-moth.ts.net (unknown [IPv6:2404:7a81:160:2100:af44:1f54:23d7:1088]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BA8E51340; Fri, 29 Aug 2025 11:09:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1756458561; bh=MH6HTxIwGWzdm1ug/N9HstyZlbSIZst64Bbw9/YJgTI=; h=From:To:Cc:Subject:Date:From; b=ChsmIKm1sHLQu4rc6mTjPvPmlu1Urp8vLvhbgDLfftL7FIGWOuIAj/z316Tw5yYDR kBQVmA4NohDiyMoPZV+r/ak0iYwA3+3c3ymFBS1p9lDhDrmiMcc1T1nGA3CYpimgPA zcGtTZZr2UFReBmUiFQe5eEhip/g9Kbrd4ePa8Rw= From: Paul Elder To: libcamera-devel@lists.libcamera.org Cc: Paul Elder , david.plowman@raspberrypi.com, naush@raspberrypi.com, kieran.bingham@ideasonboard.com, stefan.klug@ideasonboard.com Subject: [PATCH 0/4] Add Sync Layer Date: Fri, 29 Aug 2025 18:10:06 +0900 Message-ID: <20250829091011.2628954-1-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.47.2 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" This series depends on: - v4 of "Add Layers support" [0] - v1 of "libcamera: clock_recovery: Use nanoseconds in addSample()" [1] - v1 of "utils: Add unary negation operation to Duration" [2] There is a branch available at [3]. There is another version of the branch available at [4], which is the same branch rebased on top of Raspberry Pi's next [5] branch with an additional patch [6] on top to make Raspberry Pi use the Sync Layer instead of RPiSync. This patch series adds a layer implementation of the Sync algorithm, where any number cameras can synchronize the timing of their captures. This allows any camera to use the Sync algorithm, as long as it implements the SyncAdjustment control and SensorTimestamp. I tested this on a pi5 (with an imx219 and imx708) and a Debix SOM (with an imx335 and imx283) with the following capture scripts, running the client first before running the server in separate terminals: $ cat cscript-sync-client.yaml frames: - 1: FrameDurationLimits: [33333, 33333] SyncMode: 2 $ cat cscript-sync-server.yaml frames: - 1: FrameDurationLimits: [33333, 33333] SyncMode: 1 I ran: - pi5 with pure rpi/next (RPiSync) [7] - pi5 with this series on top of rpi/next (SyncLayer) [8] - som with this series (SyncLayer) [9] And I logged the correction time over a single run each of 8+ minutes at 30fps. Here are the descriptive statistics for the correction values (all in microseconds): pi5 with RPiSync Min. 1st Qu. Median Mean 3rd Qu. Max. 225.0 243.0 249.0 248.8 255.0 274.0 pi5 with SyncLayer Min. 1st Qu. Median Mean 3rd Qu. Max. 233 244 249 249 254 262 som with SyncLayer Min. 1st Qu. Median Mean 3rd Qu. Max. -16623 -11205 -5373 -1936 11363 16585 I have graphs of these runs here [10] [0] https://patchwork.libcamera.org/project/libcamera/list/?series=5401 [1] https://patchwork.libcamera.org/project/libcamera/list/?series=5403 [2] https://patchwork.libcamera.org/project/libcamera/list/?series=5404 [3] https://git.uk.ideasonboard.com/epaul/libcamera/src/branch/epaul/dev/sync [4] https://git.uk.ideasonboard.com/epaul/libcamera/src/branch/epaul/dev/layer-pi5 [5] https://github.com/raspberrypi/libcamera/tree/next [6] https://git.uk.ideasonboard.com/epaul/libcamera/commit/d5a389405040c6cf2f37686ca3cbfbc13bb68150 [7] https://git.uk.ideasonboard.com/epaul/libcamera/src/commit/c576b4375a4b630ba0a8fad4bec4c16786d9dd8b [8] https://git.uk.ideasonboard.com/epaul/libcamera/commit/d5a389405040c6cf2f37686ca3cbfbc13bb68150 [9] https://git.uk.ideasonboard.com/epaul/libcamera/commit/28c4f9fe2db8c772fbba5db48ced2ab9572b8363 [10] https://git.uk.ideasonboard.com/epaul/libcamera/pulls/1#issuecomment-18703 Paul Elder (4): controls: Add SyncAdjustment and SyncInterface controls layer: Add layer that implements the sync algorithm libipa: Add SyncHelper ipa: rkisp1: agc: Add support for sync src/ipa/libipa/meson.build | 2 + src/ipa/libipa/sync_helper.cpp | 99 ++++++ src/ipa/libipa/sync_helper.h | 36 +++ src/ipa/rkisp1/algorithms/agc.cpp | 22 +- src/ipa/rkisp1/algorithms/agc.h | 3 +- src/ipa/rkisp1/ipa_context.h | 1 + src/layer/meson.build | 1 + src/layer/sync/meson.build | 16 + src/layer/sync/sync.cpp | 465 ++++++++++++++++++++++++++++ src/layer/sync/sync.h | 96 ++++++ src/libcamera/control_ids_core.yaml | 23 ++ 11 files changed, 762 insertions(+), 2 deletions(-) create mode 100644 src/ipa/libipa/sync_helper.cpp create mode 100644 src/ipa/libipa/sync_helper.h create mode 100644 src/layer/sync/meson.build create mode 100644 src/layer/sync/sync.cpp create mode 100644 src/layer/sync/sync.h