From patchwork Tue Dec 2 14:49:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 25338 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 AD3C1BD80A for ; Tue, 2 Dec 2025 14:49:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D992060D24; Tue, 2 Dec 2025 15:49:38 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="H4Yyw5d2"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 66FE960C8A for ; Tue, 2 Dec 2025 15:49:36 +0100 (CET) Received: from [192.168.1.104] (net-93-65-100-155.cust.vodafonedsl.it [93.65.100.155]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C97E7110; Tue, 2 Dec 2025 15:47:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1764686842; bh=IwWrCI6ckKMAC8VXcFGr+hdS1KUDbLOTw8EpSuR3A6I=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=H4Yyw5d2sko12ukc7CXMuXXRuQHQfjL5JHg9h8pcxO9cJ7nLNNKch2wfhAioslFW8 IuxirroQCoLLWWQT67RbE71Iom5gNHyZnlN+ldNK560o0fOeuzx97OU1YIfqcGyzHU CqJ0/92ddnejEvypeWOAIeR5BUTW+RjPkZ3eL9Cs= From: Jacopo Mondi Date: Tue, 02 Dec 2025 15:49:26 +0100 Subject: [PATCH v3 1/5] libcamera: request: Create control list with Camera info map MIME-Version: 1.0 Message-Id: <20251202-cam-control-override-v3-1-eacab052798d@ideasonboard.com> References: <20251202-cam-control-override-v3-0-eacab052798d@ideasonboard.com> In-Reply-To: <20251202-cam-control-override-v3-0-eacab052798d@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi , Kieran Bingham , Paul Elder X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1617; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=IwWrCI6ckKMAC8VXcFGr+hdS1KUDbLOTw8EpSuR3A6I=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBpLvx+WpWPoeeDqm/lEIAWoiN/XTOEdfEK5uCyC XTrbEbMBe6JAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCaS78fgAKCRByNAaPFqFW POklD/wOUDCRCzyRxuG2lUyVBfH1wtJdtOr47kgN2t5A+mL8tZi/v+BnOHpVgA8xS3I8lC/srP6 JqIAEQV+GRALnV1Pm6i5EHvaJP3BfJbbTVPtv0H+NXGQ4ZsLBE2MZa2j9z+LDXrTA3kELu8z0ZY eGj3cnuBt3mvXW2TuWh23ocZNsPxjzSO19ofg73wAhHh1G79yMzAMCvsRfDCpsoC0nEuiigyMXI ajbxCbPHgy17fBPf0VCcRq17CelR2tjLVd2IL0yWIO5lXRN8XkpJNm/6lkHpROq+0U0UcXeThXR b+rqMbII8GYCY8LkgfOlQwvxhFhaOX5943Y+jxyhXppNrdE6niKq6iAvm+yrNI2WKgKSmS7/5A+ hhkKtaQuTOujBvcEGQEbuZWIZHQ5uNl71OD+7IuVQmd2UJuSPcypt/301YhtwthA2IVG+se2Sne 70k/Pyvx0Nwyo7m0QzdVXsKa23seZ9yq3+X4KaMB4ZMVOhBEJzwy5UoABQGEJgmeUkc6T5xuT04 /RGiGD/7zEJx4MCRMu7rLebLsr/6EfcYuuzzzSM6YvFDGMmle1m674y8xIwyYeAO+nwW2rHAfxL D0U9N8MNWOJ82cBgLZm+NGNqKS8D3Bi/Sp9mseJLpnZWZeiySA/CVs9k6cv+COISyHylnaZUpQi h3z2MhishnumtYA== X-Developer-Key: i=jacopo.mondi@ideasonboard.com; a=openpgp; fpr=72392EDC88144A65C701EA9BA5826A2587AD026B 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 control lists associated with a Request is created with the global libcamera::controls::controls id map. This is fine as the idmap/info map used to contruct a ControlList are not used for any control validation purposes by the libcamera code. However creating a ControlList with the camera ControlInfoMap has two advantages: 1) The idmap can be extracted from the info map, but not the other way around 2) The control list is constructed with a valid map of info to the controls it can actually supports, instead of the global map of libcamera controls Initialize the ControlList part of a Request with the Camera control info map, as the association between a Request and a Camera is permanent and valid for the whole lifetime of a Request. Signed-off-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder --- src/libcamera/request.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 60565f5984971c7ab34e119a15b8141799f71071..2544a059f6984d930ec909c74e0b621c9fe82726 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -356,7 +356,7 @@ Request::Request(Camera *camera, uint64_t cookie) : Extensible(std::make_unique(camera)), cookie_(cookie), status_(RequestPending) { - controls_ = new ControlList(controls::controls, + controls_ = new ControlList(camera->controls(), camera->_d()->validator()); /** From patchwork Tue Dec 2 14:49:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 25339 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 DE965C3260 for ; Tue, 2 Dec 2025 14:49:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 09A6F60D3A; Tue, 2 Dec 2025 15:49:42 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="pCjCoy6N"; 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 7FBFA6096B for ; Tue, 2 Dec 2025 15:49:36 +0100 (CET) Received: from [192.168.1.104] (net-93-65-100-155.cust.vodafonedsl.it [93.65.100.155]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1E5B43E6; Tue, 2 Dec 2025 15:47:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1764686842; bh=YuWVXKCIjzmJND0G77WDeXmPHN/1+rKHaSFTIacqhrU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pCjCoy6NLKzwc4T9c8S1zCjmcKwIJyLeuQMkwCzPxXRafx0fEUatNzMmKttZDNSNJ A0ladCV3u6ckQDO6wD0A9Cp80/u5Kotj3o/8g9o+qaO+MYKlB1AOCaeHy3psNeUvu7 5/JpL2pqbikd0i/yloFS4xVyaSHkF5tAaKxWMTKI= From: Jacopo Mondi Date: Tue, 02 Dec 2025 15:49:27 +0100 Subject: [PATCH v3 2/5] libcamera: request: Move metadata_ to Private MIME-Version: 1.0 Message-Id: <20251202-cam-control-override-v3-2-eacab052798d@ideasonboard.com> References: <20251202-cam-control-override-v3-0-eacab052798d@ideasonboard.com> In-Reply-To: <20251202-cam-control-override-v3-0-eacab052798d@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi , Paul Elder X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=19873; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=YuWVXKCIjzmJND0G77WDeXmPHN/1+rKHaSFTIacqhrU=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBpLvx+OQ2qGND3KhdQDOUjtxOAZqUBCjnqHVFje vxgOJPGltKJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCaS78fgAKCRByNAaPFqFW PEYxD/47RaWCt+NPWS3TeuMqHKZ85LS4tpjjq0SnwIXBR+6G+ymx4tppu+DppwMQkBk/3TYKJpK Y4pKuKU8Hh4YqtSDGBNP3vFyWJJTHLz4EdPaI0vsc0DQI18QcJB87pUtnuUYhSyVf+1Sx9Wc0KD xs6/0IRo5JfBYrhjYzxAhuAxXyAt8v01ShaMzIVkkIAi3RRMl8YqZCEVrYMLjKyljGjjNEvZCK9 LozDNst+JidRDKJHNUUEyh7dlgLOYhem33U0G4zXEgy7e8uNY6reLK90OVewfoXkQawWSldO2R8 rJBFoBT9ylXHTcwn17J/vuiAK5cAte8P4JM/04ILEoet+Vh0oU5P+iBzG8H2TyiRY0I89Rv63FV I5vkqKksDN3QIwymJtf0eTaspbA+AEl42a50N5GbtENzzCiZ8+XYt0Lsft4DHsMgiy/oO8fo4Wo nyOIVBOlySGL8F2oZpjthufrEN1dvTL8Tq5SxQ8X1k9q4CY5zMTyyN8JOx4DDj5RXySI7f1sIgk rVjSPEWxb7D58PBXcbX8cG+THD5wrT39p5l98rzw3RMlJV81Y6ySD/APY5cNXufTaUvSkOJ8g4r J/RUnXe4RKUvQp5iPqUjQDJYAgDhQwKrh/WcSHDoMlqxxA3MY0WNEzJqvaDCcCTRKnhoy4XMej2 Jq/2Gzq+7VrekUw== X-Developer-Key: i=jacopo.mondi@ideasonboard.com; a=openpgp; fpr=72392EDC88144A65C701EA9BA5826A2587AD026B 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" Address a long standing \todo item that suggested to implement a read-only interface for the Request::metadata() accessor and deflect to the internal implementation for the read-write accessor used by pipeline handlers. Signed-off-by: Jacopo Mondi Acked-by: Paul Elder --- include/libcamera/internal/request.h | 3 ++ include/libcamera/request.h | 3 +- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 3 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 16 +++++----- src/libcamera/pipeline/mali-c55/mali-c55.cpp | 2 +- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 10 +++--- .../pipeline/rpi/common/pipeline_base.cpp | 13 ++++---- src/libcamera/pipeline/rpi/common/pipeline_base.h | 2 +- src/libcamera/pipeline/simple/simple.cpp | 8 ++--- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 6 ++-- src/libcamera/pipeline/vimc/vimc.cpp | 6 ++-- src/libcamera/pipeline/virtual/virtual.cpp | 4 +-- src/libcamera/request.cpp | 37 ++++++++++++---------- 13 files changed, 61 insertions(+), 52 deletions(-) diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h index 78cb99f3604504dfb7145c605835b7493b656ced..643f67cabf5778f7515c0117d06d4e0a3fdec4f8 100644 --- a/include/libcamera/internal/request.h +++ b/include/libcamera/internal/request.h @@ -36,6 +36,8 @@ public: Camera *camera() const { return camera_; } bool hasPendingBuffers() const; + ControlList &metadata() { return *metadata_; } + bool completeBuffer(FrameBuffer *buffer); void complete(); void cancel(); @@ -61,6 +63,7 @@ private: std::unordered_set pending_; std::map notifiers_; std::unique_ptr timer_; + ControlList *metadata_; }; } /* namespace libcamera */ diff --git a/include/libcamera/request.h b/include/libcamera/request.h index 0c5939f7b3336fd089a2fe231f4f6f266cc422f7..c9aeddb62680923dc3490a23dc6c3f70f70cc075 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -50,7 +50,7 @@ public: void reuse(ReuseFlag flags = Default); ControlList &controls() { return *controls_; } - ControlList &metadata() { return *metadata_; } + const ControlList &metadata() const; const BufferMap &buffers() const { return bufferMap_; } int addBuffer(const Stream *stream, FrameBuffer *buffer, std::unique_ptr &&fence = {}); @@ -68,7 +68,6 @@ private: LIBCAMERA_DISABLE_COPY(Request) ControlList *controls_; - ControlList *metadata_; BufferMap bufferMap_; const uint64_t cookie_; diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index 008155ff21a7b398ef6bbe3c1379444ced26bdc5..706681fce5629bc4bd832923294e87a1ac8794cf 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -27,6 +27,7 @@ #include "libcamera/internal/media_device.h" #include "libcamera/internal/media_pipeline.h" #include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/request.h" #include "libcamera/internal/v4l2_subdevice.h" #include "libcamera/internal/v4l2_videodevice.h" @@ -1125,7 +1126,7 @@ void PipelineHandlerISI::bufferReady(FrameBuffer *buffer) Request *request = buffer->request(); /* Record the sensor's timestamp in the request metadata. */ - ControlList &metadata = request->metadata(); + ControlList &metadata = request->_d()->metadata(); if (!metadata.contains(controls::SensorTimestamp.id())) metadata.set(controls::SensorTimestamp, buffer->metadata().timestamp); diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 695762c750f89b5c8d10c221c6a9b3d7bd9ac6e7..0190f677e6794979b04b5729b2ffa88451a08ccb 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -35,6 +34,7 @@ #include "libcamera/internal/ipa_manager.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/request.h" #include "cio2.h" #include "frames.h" @@ -1249,7 +1249,7 @@ void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata) return; Request *request = info->request; - request->metadata().merge(metadata); + request->_d()->metadata().merge(metadata); info->metadataProcessed = true; if (frameInfos_.tryComplete(info)) @@ -1276,12 +1276,12 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer) pipe()->completeBuffer(request, buffer); - request->metadata().set(controls::draft::PipelineDepth, 3); + request->_d()->metadata().set(controls::draft::PipelineDepth, 3); /* \todo Actually apply the scaler crop region to the ImgU. */ const auto &scalerCrop = request->controls().get(controls::ScalerCrop); if (scalerCrop) cropRegion_ = *scalerCrop; - request->metadata().set(controls::ScalerCrop, cropRegion_); + request->_d()->metadata().set(controls::ScalerCrop, cropRegion_); if (frameInfos_.tryComplete(info)) pipe()->completeRequest(request); @@ -1321,8 +1321,8 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer) * \todo The sensor timestamp should be better estimated by connecting * to the V4L2Device::frameStart signal. */ - request->metadata().set(controls::SensorTimestamp, - buffer->metadata().timestamp); + request->_d()->metadata().set(controls::SensorTimestamp, + buffer->metadata().timestamp); info->effectiveSensorControls = delayedCtrls_->get(buffer->metadata().sequence); @@ -1416,8 +1416,8 @@ void IPU3CameraData::frameStart(uint32_t sequence) return; } - request->metadata().set(controls::draft::TestPatternMode, - *testPatternMode); + request->_d()->metadata().set(controls::draft::TestPatternMode, + *testPatternMode); } REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3, "ipu3") diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp index cf0cb15f8bb39143eea38aa8acb8d2b1268f5530..77f251416f718c8715d9df5d69a9c004e01b6561 100644 --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp @@ -1528,7 +1528,7 @@ void PipelineHandlerMaliC55::statsProcessed(unsigned int requestId, MaliC55FrameInfo &frameInfo = frameInfoMap_[requestId]; frameInfo.statsDone = true; - frameInfo.request->metadata().merge(metadata); + frameInfo.request->_d()->metadata().merge(metadata); tryComplete(&frameInfo); } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 5fd1102695070667e76daaf868e8d801f0ff70dd..320a4dc5a899b11cf56141a841f63436f0d29a37 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -45,6 +44,7 @@ #include "libcamera/internal/media_device.h" #include "libcamera/internal/media_pipeline.h" #include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/request.h" #include "libcamera/internal/v4l2_subdevice.h" #include "libcamera/internal/v4l2_videodevice.h" #include "libcamera/internal/yaml_parser.h" @@ -507,7 +507,7 @@ void RkISP1CameraData::metadataReady(unsigned int frame, const ControlList &meta if (!info) return; - info->request->metadata().merge(metadata); + info->request->_d()->metadata().merge(metadata); info->metadataProcessed = true; pipe()->tryCompleteRequest(info); @@ -1643,8 +1643,8 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer) * \todo The sensor timestamp should be better estimated by connecting * to the V4L2Device::frameStart signal. */ - request->metadata().set(controls::SensorTimestamp, - metadata.timestamp); + request->_d()->metadata().set(controls::SensorTimestamp, + metadata.timestamp); if (isRaw_) { const ControlList &ctrls = @@ -1686,7 +1686,7 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer) return; } - dewarper_->populateMetadata(&data->mainPathStream_, request->metadata()); + dewarper_->populateMetadata(&data->mainPathStream_, request->_d()->metadata()); } void PipelineHandlerRkISP1::dewarpBufferReady(FrameBuffer *buffer) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 9d65dc83573b88a4c8fd5410594085c21d91b1b1..7de45f4e5d0722a9b6425f01596455f838101900 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -1221,7 +1221,7 @@ void CameraData::metadataReady(const ControlList &metadata) /* Add to the Request metadata buffer what the IPA has provided. */ /* Last thing to do is to fill up the request metadata. */ Request *request = requestQueue_.front(); - request->metadata().merge(metadata); + request->_d()->metadata().merge(metadata); /* * Inform the sensor of the latest colour gains if it has the @@ -1492,9 +1492,9 @@ void CameraData::checkRequestCompleted() void CameraData::fillRequestMetadata(const ControlList &bufferControls, Request *request) { if (auto x = bufferControls.get(controls::SensorTimestamp)) - request->metadata().set(controls::SensorTimestamp, *x); + request->_d()->metadata().set(controls::SensorTimestamp, *x); if (auto x = bufferControls.get(controls::FrameWallClock)) - request->metadata().set(controls::FrameWallClock, *x); + request->_d()->metadata().set(controls::FrameWallClock, *x); if (cropParams_.size()) { std::vector crops; @@ -1502,10 +1502,11 @@ void CameraData::fillRequestMetadata(const ControlList &bufferControls, Request for (auto const &[k, v] : cropParams_) crops.push_back(scaleIspCrop(v.ispCrop)); - request->metadata().set(controls::ScalerCrop, crops[0]); + request->_d()->metadata().set(controls::ScalerCrop, crops[0]); if (crops.size() > 1) { - request->metadata().set(controls::rpi::ScalerCrops, - Span(crops.data(), crops.size())); + request->_d()->metadata().set(controls::rpi::ScalerCrops, + Span(crops.data(), + crops.size())); } } } diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h index 15628259afc6a90511052e8ec463d4d1cad9b30b..7735d0a9ed4311d731b7ed9b01c5970fa5d2b381 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h @@ -15,7 +15,6 @@ #include #include -#include #include "libcamera/internal/bayer_format.h" #include "libcamera/internal/camera.h" @@ -25,6 +24,7 @@ #include "libcamera/internal/media_device.h" #include "libcamera/internal/media_object.h" #include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/request.h" #include "libcamera/internal/v4l2_videodevice.h" #include "libcamera/internal/yaml_parser.h" diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index a06a52926441ba826972b70bc8aef068e354d843..f58208f28149fef561b9bd00d5fab18b2dd8ef9b 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "libcamera/internal/camera.h" @@ -41,6 +40,7 @@ #include "libcamera/internal/global_configuration.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/request.h" #include "libcamera/internal/software_isp/software_isp.h" #include "libcamera/internal/v4l2_subdevice.h" #include "libcamera/internal/v4l2_videodevice.h" @@ -927,8 +927,8 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer) } if (request) - request->metadata().set(controls::SensorTimestamp, - buffer->metadata().timestamp); + request->_d()->metadata().set(controls::SensorTimestamp, + buffer->metadata().timestamp); /* * Queue the captured and the request buffer to the converter or Software @@ -1015,7 +1015,7 @@ void SimpleCameraData::metadataReady(uint32_t frame, const ControlList &metadata if (!info) return; - info->request->metadata().merge(metadata); + info->request->_d()->metadata().merge(metadata); info->metadataProcessed = true; tryCompleteRequest(info->request); } diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index cb8cc82dffd551183fbeccd5041982b1d44e9f77..3bd51733d4005347c0bdfe83db0ea5f827be441e 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -24,13 +24,13 @@ #include #include #include -#include #include #include "libcamera/internal/camera.h" #include "libcamera/internal/device_enumerator.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/request.h" #include "libcamera/internal/sysfs.h" #include "libcamera/internal/v4l2_videodevice.h" @@ -895,8 +895,8 @@ void UVCCameraData::imageBufferReady(FrameBuffer *buffer) Request *request = buffer->request(); /* \todo Use the UVC metadata to calculate a more precise timestamp */ - request->metadata().set(controls::SensorTimestamp, - buffer->metadata().timestamp); + request->_d()->metadata().set(controls::SensorTimestamp, + buffer->metadata().timestamp); pipe()->completeBuffer(request, buffer); pipe()->completeRequest(request); diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index cd3370e3d41911f6935bead7f2d0dc5b39ee0038..4a03c149a61739d3596c11f91696db3ee5a43568 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -39,6 +38,7 @@ #include "libcamera/internal/ipa_manager.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/request.h" #include "libcamera/internal/v4l2_subdevice.h" #include "libcamera/internal/v4l2_videodevice.h" @@ -618,8 +618,8 @@ void VimcCameraData::imageBufferReady(FrameBuffer *buffer) } /* Record the sensor's timestamp in the request metadata. */ - request->metadata().set(controls::SensorTimestamp, - buffer->metadata().timestamp); + request->_d()->metadata().set(controls::SensorTimestamp, + buffer->metadata().timestamp); pipe->completeBuffer(request, buffer); pipe->completeRequest(request); diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index 7855e8b9db0c3bdfb3662a0b6e71332ed463a0ed..40c35264c5687c0f94458e19a272612cefb76285 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -29,13 +29,13 @@ #include #include #include -#include #include "libcamera/internal/camera.h" #include "libcamera/internal/dma_buf_allocator.h" #include "libcamera/internal/formats.h" #include "libcamera/internal/framebuffer.h" #include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/request.h" #include "libcamera/internal/yaml_parser.h" #include "pipeline/virtual/config_parser.h" @@ -366,7 +366,7 @@ int PipelineHandlerVirtual::queueRequestDevice([[maybe_unused]] Camera *camera, VirtualCameraData *data = cameraData(camera); const auto timestamp = currentTimestamp(); - request->metadata().set(controls::SensorTimestamp, timestamp); + request->_d()->metadata().set(controls::SensorTimestamp, timestamp); data->invokeMethod(&VirtualCameraData::processRequest, ConnectionTypeQueued, request); diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 2544a059f6984d930ec909c74e0b621c9fe82726..a661b2f5c8ae9ae2bcbab2dcdceeef7dcb8d0930 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -57,11 +57,16 @@ LOG_DEFINE_CATEGORY(Request) Request::Private::Private(Camera *camera) : camera_(camera), cancelled_(false) { + /** + * \todo Add a validator for metadata controls. + */ + metadata_ = new ControlList(controls::controls); } Request::Private::~Private() { doCancelRequest(); + delete metadata_; } /** @@ -82,6 +87,12 @@ bool Request::Private::hasPendingBuffers() const return !pending_.empty(); } +/** + * \fn Request::Private::metadata() + * \brief Retrieve the request's metadata + * \return The metadata associated with the request + */ + /** * \brief Complete a buffer for the request * \param[in] buffer The buffer that has completed @@ -359,11 +370,6 @@ Request::Request(Camera *camera, uint64_t cookie) controls_ = new ControlList(camera->controls(), camera->_d()->validator()); - /** - * \todo Add a validator for metadata controls. - */ - metadata_ = new ControlList(controls::controls); - LIBCAMERA_TRACEPOINT(request_construct, this); LOG(Request, Debug) << "Created request - cookie: " << cookie_; @@ -372,8 +378,6 @@ Request::Request(Camera *camera, uint64_t cookie) Request::~Request() { LIBCAMERA_TRACEPOINT(request_destroy, this); - - delete metadata_; delete controls_; } @@ -406,7 +410,7 @@ void Request::reuse(ReuseFlag flags) status_ = RequestPending; controls_->clear(); - metadata_->clear(); + _d()->metadata_->clear(); } /** @@ -425,6 +429,15 @@ void Request::reuse(ReuseFlag flags) * \return A reference to the ControlList in this request */ +/** + * \brief Retrieve the request's metadata + * \return The a const reference to the metadata associated with the request + */ +const ControlList &Request::metadata() const +{ + return *_d()->metadata_; +} + /** * \fn Request::buffers() * \brief Retrieve the request's streams to buffers map @@ -525,14 +538,6 @@ FrameBuffer *Request::findBuffer(const Stream *stream) const return it->second; } -/** - * \fn Request::metadata() - * \brief Retrieve the request's metadata - * \todo Offer a read-only API towards applications while keeping a read/write - * API internally. - * \return The metadata associated with the request - */ - /** * \brief Retrieve the sequence number for the request * From patchwork Tue Dec 2 14:49:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 25340 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 0C1D5BD80A for ; Tue, 2 Dec 2025 14:49:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0649660C92; Tue, 2 Dec 2025 15:49:44 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="NTQw+vM3"; 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 A2BDC60C92 for ; Tue, 2 Dec 2025 15:49:36 +0100 (CET) Received: from [192.168.1.104] (net-93-65-100-155.cust.vodafonedsl.it [93.65.100.155]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6907B6DC; Tue, 2 Dec 2025 15:47:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1764686842; bh=IkgEXBKlqck2eAqwvx7gGB84F3eYcFxd62i3UJZmIjM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NTQw+vM3QY19fMJ15XGnbBpZfTzX9uR5Kix2aEJMZNsJkGGrJTP8OJDT4zsO+f9Zm fF3qOmZXnNSqSsfZhhThmtHGZL2hEWhX/Ak+CCEQ5afi8lL2j9dYOoMyQrSGa3ba1C MXog81IAospwhMJJ7/3QMm24KSG0zrxLZZcpiEg4= From: Jacopo Mondi Date: Tue, 02 Dec 2025 15:49:28 +0100 Subject: [PATCH v3 3/5] libcamera: request: Make metadata_ a class instance MIME-Version: 1.0 Message-Id: <20251202-cam-control-override-v3-3-eacab052798d@ideasonboard.com> References: <20251202-cam-control-override-v3-0-eacab052798d@ideasonboard.com> In-Reply-To: <20251202-cam-control-override-v3-0-eacab052798d@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi , =?utf-8?b?QmFybmFiw6Fz?= =?utf-8?q?_P=C5=91cze?= X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2423; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=IkgEXBKlqck2eAqwvx7gGB84F3eYcFxd62i3UJZmIjM=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBpLvx+rHcDF6RCevOHDUQFHswt8NlAM+YHzqgmE 0prkf+NDPeJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCaS78fgAKCRByNAaPFqFW PItsD/9s/LyhnTQvBKqq+vwN+EU3jJAkxelhOn3TdXbXpk6AKwUWJ9Vo97vR5LH7VhegVqRMI/M uPE5tpA78YzDljh2XdMLt9sUtmYvunWaEiuJ6HwNzc8iEeGbWyYg/0Ssz063XkGXwVMifyjZg9t bCdm/K+gB2pXAyyKme4gU3N/jW4Py/ufRya0iQTNzSlOEs6Mv4w0aZES09yBwlFfkWUNfrSCU3N TwmOj30ovwrmmr3RP+fzYuzhxcpdVSKTXxP1EM4DPND+EqyGy9PdvzRR8yFGxlZ93tfLrB4SXtB aF0Kelx0dUK3AUk2yoJdUsPcxsKOKfpSTH/1ZN0pMIvxdX+u5ttPjaIkwKzm2Y5Yan1/qaoovVq d0nQ9qjKryv6nyaoy3ptaXc23TB4rUYY3jWjTswqAy+zCpNvrlIksfZwZU2b0dCm1ehFB5ytacC wOIvfeqBde7qp41XEqgxxES91S+umlv4HgvNGTaaAzc3Io8GmILg57n1gDyb1uCTNoZdfBF3Cet eUS5f6Zr+KMa2bwk33CkdIBZMnSLF7yM5LPYL+rvxMumSuKd8YuKqyCnr3aN5EKs5tf1DSutHRX 7X12cYEsEpb570EzFLZZY0C2gmqsxQxfistHzBQ7erDQnsRE8HKIWZysKrg/jHE/zoIyLJBgWJm LnCDEWZdIErvYpg== X-Developer-Key: i=jacopo.mondi@ideasonboard.com; a=openpgp; fpr=72392EDC88144A65C701EA9BA5826A2587AD026B 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 metadata_ member variable is a pointer, for no specific reason. Make it an instance and simplify the class destructor. Suggested-by: Barnabás Pőcze Signed-off-by: Jacopo Mondi Reviewed-by: Barnabás Pőcze --- include/libcamera/internal/request.h | 4 ++-- src/libcamera/request.cpp | 13 +++++-------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h index 643f67cabf5778f7515c0117d06d4e0a3fdec4f8..693097ee9a263be5b4217d5e5393ea93cc30a239 100644 --- a/include/libcamera/internal/request.h +++ b/include/libcamera/internal/request.h @@ -36,7 +36,7 @@ public: Camera *camera() const { return camera_; } bool hasPendingBuffers() const; - ControlList &metadata() { return *metadata_; } + ControlList &metadata() { return metadata_; } bool completeBuffer(FrameBuffer *buffer); void complete(); @@ -63,7 +63,7 @@ private: std::unordered_set pending_; std::map notifiers_; std::unique_ptr timer_; - ControlList *metadata_; + ControlList metadata_; }; } /* namespace libcamera */ diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index a661b2f5c8ae9ae2bcbab2dcdceeef7dcb8d0930..0d6c4a0ce9aec5f328c1f66cea43abb37c82544a 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -53,20 +53,17 @@ LOG_DEFINE_CATEGORY(Request) /** * \brief Create a Request::Private * \param camera The Camera that creates the request + * + * \todo Add a validator for metadata controls. */ Request::Private::Private(Camera *camera) - : camera_(camera), cancelled_(false) + : camera_(camera), cancelled_(false), metadata_(controls::controls) { - /** - * \todo Add a validator for metadata controls. - */ - metadata_ = new ControlList(controls::controls); } Request::Private::~Private() { doCancelRequest(); - delete metadata_; } /** @@ -410,7 +407,7 @@ void Request::reuse(ReuseFlag flags) status_ = RequestPending; controls_->clear(); - _d()->metadata_->clear(); + _d()->metadata_.clear(); } /** @@ -435,7 +432,7 @@ void Request::reuse(ReuseFlag flags) */ const ControlList &Request::metadata() const { - return *_d()->metadata_; + return _d()->metadata_; } /** From patchwork Tue Dec 2 14:49:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 25342 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 5D212C32AF for ; Tue, 2 Dec 2025 14:49:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 26F9360D28; Tue, 2 Dec 2025 15:49:46 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="YJsLQIwI"; 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 C027760C94 for ; Tue, 2 Dec 2025 15:49:36 +0100 (CET) Received: from [192.168.1.104] (net-93-65-100-155.cust.vodafonedsl.it [93.65.100.155]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AC1989FC; Tue, 2 Dec 2025 15:47:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1764686842; bh=HoU7dOwRB7cOcAkftp7Y35n6xGnB8hwQfgT5IpZzrlg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=YJsLQIwIg8kwX3aTlDYSuW0smTHT6f9IEK/Q4wEetHesQ4dmOGT+ihkg3zTylUvIa 8o4MNGZzAiYp3AUSc2Ak62llk9p+XYQqxN8uW32tZDiGOBo/BkiKp9gVGqS6BLHwv9 sL4VDXNpH92QyYGSpUhCLbgR2e1L9FRYGhIorMus= From: Jacopo Mondi Date: Tue, 02 Dec 2025 15:49:29 +0100 Subject: [PATCH v3 4/5] libcamera: request: Make controls_ a class instance MIME-Version: 1.0 Message-Id: <20251202-cam-control-override-v3-4-eacab052798d@ideasonboard.com> References: <20251202-cam-control-override-v3-0-eacab052798d@ideasonboard.com> In-Reply-To: <20251202-cam-control-override-v3-0-eacab052798d@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2171; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=HoU7dOwRB7cOcAkftp7Y35n6xGnB8hwQfgT5IpZzrlg=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBpLvx+JWkkpDLURN9siFv3tTFU0ng3vDfj+nfAa m9YtnQNyoiJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCaS78fgAKCRByNAaPFqFW PHaGEACiKLxp98hbn/aiFVYaBjpo0DlG/X4qkLJaChCCYfXak/hCflI+Xjk0sK4ogouRvgDArcc 0sC1xReSyOcucp4IYmYkIdqcPoNvQOKs/PA/N0w6x4EmOL9ef8eLinlsgbg8j2fWWtSWT4Uoe/P DAHqljxpJZ9Nd4+9nVp10bhqTKaN/MHzg874Jle2qcWbAFdHWbPEcaKshOtzh8sAcAXQeTiJgkb DyC3ZY1gdUsLCcmiIV+h+3h63PshBKj+Kt46WaNrDEW4qMragWQUtWH/FgwuMNKeWUqqiw3aKcx x0DJqQWuEoCdR1/psjlug40zMrPAnFoPbO+k9p8e+LLgH4AjL8QMMSei7MwBi93kBD5a1lD2XAP nVylKB4QnVVNESPcGP8reEI56GCcBu9p/DPEDGnOfTclV31+8Xz6BFsKF2yfcKjGkotIkWXebgp flBIDltNq7KduAe07w1gNprfXCrvqkO1CpP0Xt7Pe5xec/u3FmqoXLodpQsJvz7/dsi54ij28xc hoZ0RweksPU3RlQPfkCp3VeFZGjiRGGp0papHQVoDYBhSv4UR7PIvSNQ+lgNmi6sb681oudiq+a c+ibq5OekqqDGWtmmuRY5b292S2uteQfAj0GmYXMeGj5KZFET1NmBBwraJ8DsZCH1q2AIec9nPv i640mbeEDE/VGXw== X-Developer-Key: i=jacopo.mondi@ideasonboard.com; a=openpgp; fpr=72392EDC88144A65C701EA9BA5826A2587AD026B 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 controls_ member variable is a pointer, for no specific reason. Make it an instance and simplify the class destructor. Signed-off-by: Jacopo Mondi Reviewed-by: Barnabás Pőcze --- include/libcamera/request.h | 4 ++-- src/libcamera/request.cpp | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/include/libcamera/request.h b/include/libcamera/request.h index c9aeddb62680923dc3490a23dc6c3f70f70cc075..290983f613520f136f1d56100c665b0e3124ec02 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -49,7 +49,7 @@ public: void reuse(ReuseFlag flags = Default); - ControlList &controls() { return *controls_; } + ControlList &controls() { return controls_; } const ControlList &metadata() const; const BufferMap &buffers() const { return bufferMap_; } int addBuffer(const Stream *stream, FrameBuffer *buffer, @@ -67,7 +67,7 @@ public: private: LIBCAMERA_DISABLE_COPY(Request) - ControlList *controls_; + ControlList controls_; BufferMap bufferMap_; const uint64_t cookie_; diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 0d6c4a0ce9aec5f328c1f66cea43abb37c82544a..57f1f060d5b48bfde97132793e96ef5ce33e252f 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -362,11 +362,9 @@ void Request::Private::timeout() */ Request::Request(Camera *camera, uint64_t cookie) : Extensible(std::make_unique(camera)), + controls_(camera->controls(), camera->_d()->validator()), cookie_(cookie), status_(RequestPending) { - controls_ = new ControlList(camera->controls(), - camera->_d()->validator()); - LIBCAMERA_TRACEPOINT(request_construct, this); LOG(Request, Debug) << "Created request - cookie: " << cookie_; @@ -375,7 +373,6 @@ Request::Request(Camera *camera, uint64_t cookie) Request::~Request() { LIBCAMERA_TRACEPOINT(request_destroy, this); - delete controls_; } /** @@ -406,7 +403,7 @@ void Request::reuse(ReuseFlag flags) status_ = RequestPending; - controls_->clear(); + controls_.clear(); _d()->metadata_.clear(); } From patchwork Tue Dec 2 14:49:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 25341 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 78F3FC326B for ; Tue, 2 Dec 2025 14:49:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 096E760D1F; Tue, 2 Dec 2025 15:49:45 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="k6F7gx+K"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D97BE60D0E for ; Tue, 2 Dec 2025 15:49:36 +0100 (CET) Received: from [192.168.1.104] (net-93-65-100-155.cust.vodafonedsl.it [93.65.100.155]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E5110A06; Tue, 2 Dec 2025 15:47:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1764686843; bh=Fpi3rz7Vx1tuMGiAVwEVqdnb7Z/TYH8Mbn7AHFJLZLU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=k6F7gx+KD2TACBAXTUgCyHQfEvWgOk0QTVBuuBnJVaEox8T1MRTL/Y1VHdAkrjZhw kYn6UiMRRO7fGvSw4fexGDPqECPwt00W+BYrxtZUwRVT0L4E1ZRyAXh6BDR72csb1N EJHXJDgYyjtbM49VhtkOfhIG/Vcxt3iZmqwLu6ik= From: Jacopo Mondi Date: Tue, 02 Dec 2025 15:49:30 +0100 Subject: [PATCH v3 5/5] libcamera: camera: Ensure a request's controls are valid MIME-Version: 1.0 Message-Id: <20251202-cam-control-override-v3-5-eacab052798d@ideasonboard.com> References: <20251202-cam-control-override-v3-0-eacab052798d@ideasonboard.com> In-Reply-To: <20251202-cam-control-override-v3-0-eacab052798d@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1209; i=jacopo.mondi@ideasonboard.com; h=from:subject:message-id; bh=Fpi3rz7Vx1tuMGiAVwEVqdnb7Z/TYH8Mbn7AHFJLZLU=; b=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBpLvx+BAv2sTk3WmxNGkxeqqFyAQ0R98wXaJE/y PT+jUZutUWJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCaS78fgAKCRByNAaPFqFW PDqYD/0Xi2qGNoZFwgws8zecYAOO9u+lsWC/3ajOlJ4HQNJQLrhHNcP6oIOEq7ftNLJCFPZheAv Cjb2juapIKhaSSXMaMEYt82xRbAtlg78Ro5QWUwq8p0Vw6jWfrrH99Yf28IyH5bfO+kz3G5FL4x jC8VyK6kVLZBYM38UR8BFs5Iai6Df6CbuBkqw1I/uVZugtm4mzATiUCwQDljK1aoicxTWkDZiMr eL3QE7S1HJgOak3qyMWrm7WTnret/TmlEUtx0YwpskO+HYyutrfoMZ//2CtuHA2KMgOiJq5iaDF cdSVKjY2YqC5Oy3xCmaxoYFQgpWejCC5rfHTnOliOEShjjb+iUIj0y91cqq/FYqXe49FwbS337/ 4qY4SGzPGLMBXX5o1c3yvt6CXDJI9yQ95cIFcRPrX9Jl8dj8E8V0hC7IQlHPL+UZRihVpH8i1un uOOR+Ehws5PMO1eE5yumjUBK/W3C5I5ha/aZJhi7uIdeMOyT6o35HZxWrtGDi8A7IaeOjQj3arE ooq0sjjl9hkySCHP/MqigZSQeVDz0N35Mco0B4R+HjFm4eXLfvBo7DOimJzb6ARJUQ1lcIggUyt jB8ei/B7/Y0alk5kAVKLamd1nvj9SR+dz3ewvU6lsrGmnRp84pB4JOkQt0M6Eap/p+Lj4C48asu 11JZyWXXpguZXxQ== X-Developer-Key: i=jacopo.mondi@ideasonboard.com; a=openpgp; fpr=72392EDC88144A65C701EA9BA5826A2587AD026B 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 list of controls part of a Request is initialized with the ControlInfoMap of the Camera the Request is created from. Applications can re-assign the controls list in a Request which could cause issues during serialization. Validate that the ControlList in a Request is valid when the Request is queued to the Camera by inspecting the ControlInfoMap pointer. Signed-off-by: Jacopo Mondi --- src/libcamera/camera.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 2e1e146a25b13b94f3a0df5935c0861f78c949ed..93cd4d5f334f982133a12cbc4caec5cdf7bb52c6 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -1345,6 +1345,12 @@ int Camera::queueRequest(Request *request) return -EINVAL; } + /* Make sure the Request has a valid control list. */ + if (request->controls().infoMap() != &controls()) { + LOG(Camera, Error) << "Invalid control list in the Request"; + return -EINVAL; + } + /* * The camera state may change until the end of the function. No locking * is however needed as PipelineHandler::queueRequest() will handle