From patchwork Thu Jan 29 08:28:06 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 26028 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 8360DC3226 for ; Thu, 29 Jan 2026 08:28:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A552961FD2; Thu, 29 Jan 2026 09:28:26 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="wn4zB5FE"; 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 EB345615B2 for ; Thu, 29 Jan 2026 09:28:24 +0100 (CET) Received: from neptunite.flets-east.jp (unknown [IPv6:2404:7a81:160:2100:2eea:f891:1bd7:2691]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2D1596A6; Thu, 29 Jan 2026 09:27:44 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1769675267; bh=GLdZSCGcD3ryJAxc7EZvZJ0FdBnOHm2A16U1DGxWy78=; h=From:To:Cc:Subject:Date:From; b=wn4zB5FE0keePC/gOCwEV3tulAwY+QIbXT1o6BmDsfg5clpRB/PP+7k5a18qNPcmd komKzOuR3clpX9/K5DvS0/ApYvBN/0fsDPfH/Yq5zcVTd5Kh5iSbHqQyYPk/vj9jYg z4kXb+nIWeGdO42hPNxq/qUwxQreH64nnOnsTzBI= From: Paul Elder To: libcamera-devel@lists.libcamera.org Cc: Paul Elder , kieran.bingham@ideasonboard.com, stefan.klug@ideasonboard.com, barnabas.pocze@ideasonboard.com Subject: [PATCH v6 0/8] Add Layers support Date: Thu, 29 Jan 2026 17:28:06 +0900 Message-ID: <20260129082814.1777779-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 introduces a new concept to libcamera, called Layers. They sit between the application and the Camera, and hook into a subset of the Camera calls. This allows things that don't belong inside a Camera/IPA nor inside an application to be implemented, such as the Sync algorithm. As a light demonstration of the capabilities of Layers, this series implements a Layer that intercepts all control-related calls to implement the AeEnable control transparently. Patches 1~3 are refactoring and reorganizing existing code. Patch 4 implements the LayerManager, which is the main component. Patch 5~6 connects the Camera to the layer infrastructure. Finally patches 7~8 implement a simple layer that implements the AeEnable control, to demonstrate how a Layer might work. v2 most notably reorganizes the LayerManager to be under the CameraManager instead of the Camera, and adds support for closures so that each layer can store its data per camera. v3 adds the LayerController that belongs to each Camera, one to simplify code and to make it more correct in terms of ownership, but also to pave the way for each Camera to select different layers. This is not implemented at the moment however as it requires configuration file support. v4 adds a LayerInstance class that bundles a LayerLoaded together with its closure, and simplifies code for LayerController when it checks that the layer implements a function before calling it from its vtable No changes in v5; just a rebase and resend because it's been a long time since v4. v6 fixes an API change that wasn't caught in v5, that metadata of Request can no longer be modified directly. Paul Elder (8): libcamera: ipa_manager: Factor out .so file searching libcamera: ipa_module: Factor out ELF file handling libcamera: camera: Add indirection to Camera signal emissions libcamera: layer_manager: Add Layer handling implementation libcamera: camera_manager: Add LayerManager libcamera: camera: Hook into the LayerManager layer: Add layer to inject AeEnable control camera, ipa: all: Remove AeEnable handling include/libcamera/internal/camera.h | 8 + include/libcamera/internal/camera_manager.h | 3 + include/libcamera/internal/ipa_manager.h | 4 - include/libcamera/internal/layer_manager.h | 205 ++++++ include/libcamera/internal/meson.build | 2 + include/libcamera/internal/utils.h | 29 + include/libcamera/layer.h | 54 ++ include/libcamera/meson.build | 1 + src/ipa/mali-c55/algorithms/agc.cpp | 1 + src/ipa/rkisp1/algorithms/agc.cpp | 2 - src/ipa/rpi/common/ipa_base.cpp | 2 - src/layer/inject_controls/inject_controls.cpp | 177 +++++ src/layer/inject_controls/inject_controls.h | 24 + src/layer/inject_controls/meson.build | 16 + src/layer/meson.build | 16 + src/libcamera/camera.cpp | 115 ++-- src/libcamera/camera_manager.cpp | 1 + src/libcamera/ipa_manager.cpp | 107 +-- src/libcamera/ipa_module.cpp | 152 +---- src/libcamera/layer.cpp | 179 +++++ src/libcamera/layer_manager.cpp | 612 ++++++++++++++++++ src/libcamera/meson.build | 3 + src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 5 - src/libcamera/pipeline_handler.cpp | 2 +- src/libcamera/request.cpp | 2 +- src/libcamera/utils.cpp | 269 ++++++++ src/meson.build | 1 + 27 files changed, 1698 insertions(+), 294 deletions(-) create mode 100644 include/libcamera/internal/layer_manager.h create mode 100644 include/libcamera/internal/utils.h create mode 100644 include/libcamera/layer.h create mode 100644 src/layer/inject_controls/inject_controls.cpp create mode 100644 src/layer/inject_controls/inject_controls.h create mode 100644 src/layer/inject_controls/meson.build create mode 100644 src/layer/meson.build create mode 100644 src/libcamera/layer.cpp create mode 100644 src/libcamera/layer_manager.cpp create mode 100644 src/libcamera/utils.cpp