[{"id":37121,"web_url":"https://patchwork.libcamera.org/comment/37121/","msgid":"<3f9df1db-b6cc-4d6d-b36a-9e40d0b80a88@ideasonboard.com>","date":"2025-12-01T09:57:10","subject":"Re: [PATCH v2 2/3] libcamera: request: Move metadata_ to Private","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n2025. 11. 26. 10:38 keltezéssel, Jacopo Mondi írta:\n> Address a long standing \\todo item that suggested to implement a\n> read-only interface for the Request::metadata() accessor and deflect to\n> the internal implementation for the read-write accessor used by pipeline\n> handlers.\n> \n> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> ---\n>   include/libcamera/internal/request.h               |  3 ++\n>   include/libcamera/request.h                        |  3 +-\n>   src/libcamera/pipeline/imx8-isi/imx8-isi.cpp       |  3 +-\n>   src/libcamera/pipeline/ipu3/ipu3.cpp               | 16 +++++-----\n>   src/libcamera/pipeline/mali-c55/mali-c55.cpp       |  2 +-\n>   src/libcamera/pipeline/rkisp1/rkisp1.cpp           | 10 +++---\n>   .../pipeline/rpi/common/pipeline_base.cpp          | 13 ++++----\n>   src/libcamera/pipeline/rpi/common/pipeline_base.h  |  2 +-\n>   src/libcamera/pipeline/simple/simple.cpp           |  8 ++---\n>   src/libcamera/pipeline/uvcvideo/uvcvideo.cpp       |  6 ++--\n>   src/libcamera/pipeline/vimc/vimc.cpp               |  6 ++--\n>   src/libcamera/pipeline/virtual/virtual.cpp         |  4 +--\n>   src/libcamera/request.cpp                          | 37 ++++++++++++----------\n>   13 files changed, 61 insertions(+), 52 deletions(-)\n> \n> diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h\n> index 78cb99f3604504dfb7145c605835b7493b656ced..643f67cabf5778f7515c0117d06d4e0a3fdec4f8 100644\n> --- a/include/libcamera/internal/request.h\n> +++ b/include/libcamera/internal/request.h\n> @@ -36,6 +36,8 @@ public:\n>   \tCamera *camera() const { return camera_; }\n>   \tbool hasPendingBuffers() const;\n>   \n> +\tControlList &metadata() { return *metadata_; }\n> +\n>   \tbool completeBuffer(FrameBuffer *buffer);\n>   \tvoid complete();\n>   \tvoid cancel();\n> @@ -61,6 +63,7 @@ private:\n>   \tstd::unordered_set<FrameBuffer *> pending_;\n>   \tstd::map<FrameBuffer *, EventNotifier> notifiers_;\n>   \tstd::unique_ptr<Timer> timer_;\n> +\tControlList *metadata_;\n\nI think it should be just `ControlList metadata_`, no pointer.\n\n\n>   };\n>   \n>   } /* namespace libcamera */\n> [...]\n> diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp\n> index 2544a059f6984d930ec909c74e0b621c9fe82726..a661b2f5c8ae9ae2bcbab2dcdceeef7dcb8d0930 100644\n> --- a/src/libcamera/request.cpp\n> +++ b/src/libcamera/request.cpp\n> @@ -57,11 +57,16 @@ LOG_DEFINE_CATEGORY(Request)\n>   Request::Private::Private(Camera *camera)\n>   \t: camera_(camera), cancelled_(false)\n\nThen\n\n   metadata_(controls::controls)\n\nhere.\n\n\nRegards,\nBarnabás Pőcze\n\n>   {\n> +\t/**\n> +\t * \\todo Add a validator for metadata controls.\n> +\t */\n> +\tmetadata_ = new ControlList(controls::controls);\n>   }\n>   \n> [...]","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 3B434C0F1B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  1 Dec 2025 09:57:17 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 22E7060AB1;\n\tMon,  1 Dec 2025 10:57:16 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BE640609D8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  1 Dec 2025 10:57:14 +0100 (CET)","from [192.168.33.24] (185.182.214.104.nat.pool.zt.hu\n\t[185.182.214.104])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 346E44F1;\n\tMon,  1 Dec 2025 10:55:01 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"kE66w9lp\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1764582901;\n\tbh=Elfl4eYPyVOpO1NvZdvhXxAO2cjwGzSsJP8SsVOfMIQ=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=kE66w9lpZBZSYgS7WXvDTbt00uf9YNGPpYraFqO3/N32V8ojEhYGa8e71DuVuXJyq\n\temaoQENhUeTLY5MJ8d0RcDV7eLmYBdCEq0ItVnCLLsIzlCg+pu/Jn5+seMEcvcXGP/\n\tpQVmBC07C29PuZx3ExIdrhVcFUuHGPFl21DTPRZE=","Message-ID":"<3f9df1db-b6cc-4d6d-b36a-9e40d0b80a88@ideasonboard.com>","Date":"Mon, 1 Dec 2025 10:57:10 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2 2/3] libcamera: request: Move metadata_ to Private","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20251126-cam-control-override-v2-0-305024a1f190@ideasonboard.com>\n\t<20251126-cam-control-override-v2-2-305024a1f190@ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20251126-cam-control-override-v2-2-305024a1f190@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":37125,"web_url":"https://patchwork.libcamera.org/comment/37125/","msgid":"<bqtxfzsmplmh52chvdy4fadu77naswupfjt3c73vfxaivzwogk@xioamhdwb4sz>","date":"2025-12-01T10:11:41","subject":"Re: [PATCH v2 2/3] libcamera: request: Move metadata_ to Private","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/people/143/","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"content":"Hi Barnabás\n\nOn Mon, Dec 01, 2025 at 10:57:10AM +0100, Barnabás Pőcze wrote:\n> Hi\n>\n> 2025. 11. 26. 10:38 keltezéssel, Jacopo Mondi írta:\n> > Address a long standing \\todo item that suggested to implement a\n> > read-only interface for the Request::metadata() accessor and deflect to\n> > the internal implementation for the read-write accessor used by pipeline\n> > handlers.\n> >\n> > Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> > ---\n> >   include/libcamera/internal/request.h               |  3 ++\n> >   include/libcamera/request.h                        |  3 +-\n> >   src/libcamera/pipeline/imx8-isi/imx8-isi.cpp       |  3 +-\n> >   src/libcamera/pipeline/ipu3/ipu3.cpp               | 16 +++++-----\n> >   src/libcamera/pipeline/mali-c55/mali-c55.cpp       |  2 +-\n> >   src/libcamera/pipeline/rkisp1/rkisp1.cpp           | 10 +++---\n> >   .../pipeline/rpi/common/pipeline_base.cpp          | 13 ++++----\n> >   src/libcamera/pipeline/rpi/common/pipeline_base.h  |  2 +-\n> >   src/libcamera/pipeline/simple/simple.cpp           |  8 ++---\n> >   src/libcamera/pipeline/uvcvideo/uvcvideo.cpp       |  6 ++--\n> >   src/libcamera/pipeline/vimc/vimc.cpp               |  6 ++--\n> >   src/libcamera/pipeline/virtual/virtual.cpp         |  4 +--\n> >   src/libcamera/request.cpp                          | 37 ++++++++++++----------\n> >   13 files changed, 61 insertions(+), 52 deletions(-)\n> >\n> > diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h\n> > index 78cb99f3604504dfb7145c605835b7493b656ced..643f67cabf5778f7515c0117d06d4e0a3fdec4f8 100644\n> > --- a/include/libcamera/internal/request.h\n> > +++ b/include/libcamera/internal/request.h\n> > @@ -36,6 +36,8 @@ public:\n> >   \tCamera *camera() const { return camera_; }\n> >   \tbool hasPendingBuffers() const;\n> > +\tControlList &metadata() { return *metadata_; }\n> > +\n> >   \tbool completeBuffer(FrameBuffer *buffer);\n> >   \tvoid complete();\n> >   \tvoid cancel();\n> > @@ -61,6 +63,7 @@ private:\n> >   \tstd::unordered_set<FrameBuffer *> pending_;\n> >   \tstd::map<FrameBuffer *, EventNotifier> notifiers_;\n> >   \tstd::unique_ptr<Timer> timer_;\n> > +\tControlList *metadata_;\n>\n> I think it should be just `ControlList metadata_`, no pointer.\n\nit could, but I'm moving code around, not modifying it in this patch,\nso  prefer to keep it as it was. We can change it on top ?\n\n>\n>\n> >   };\n> >   } /* namespace libcamera */\n> > [...]\n> > diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp\n> > index 2544a059f6984d930ec909c74e0b621c9fe82726..a661b2f5c8ae9ae2bcbab2dcdceeef7dcb8d0930 100644\n> > --- a/src/libcamera/request.cpp\n> > +++ b/src/libcamera/request.cpp\n> > @@ -57,11 +57,16 @@ LOG_DEFINE_CATEGORY(Request)\n> >   Request::Private::Private(Camera *camera)\n> >   \t: camera_(camera), cancelled_(false)\n>\n> Then\n>\n>   metadata_(controls::controls)\n>\n> here.\n>\n>\n> Regards,\n> Barnabás Pőcze\n>\n> >   {\n> > +\t/**\n> > +\t * \\todo Add a validator for metadata controls.\n> > +\t */\n> > +\tmetadata_ = new ControlList(controls::controls);\n> >   }\n> > [...]","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 813A2C0F1B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  1 Dec 2025 10:11:46 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 363F660AB7;\n\tMon,  1 Dec 2025 11:11:46 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C8DC4609D8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  1 Dec 2025 11:11:44 +0100 (CET)","from ideasonboard.com (net-93-65-100-155.cust.vodafonedsl.it\n\t[93.65.100.155])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AEC656AC;\n\tMon,  1 Dec 2025 11:09:31 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Ak1dTl3g\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1764583771;\n\tbh=qxy6nmkq4aaT/lu1G3aldULED1t0XcsxZUekYa+OP5k=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Ak1dTl3g5QoKaNs94X0stVSuBTYPnoy9zfq97f+FW0+PjK4bh4v3NIDFPVAQFI2hh\n\thZmvftslSjrT+9h/rNgjCU6Q+CemGMva4ypmfMcly1Oynqq5cGElzN7IZQuYiVPMMc\n\tLflxdoa64FA1kPyRemGkM0UvpH6HmeKURXQlXFts=","Date":"Mon, 1 Dec 2025 11:11:41 +0100","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>, \n\tlibcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v2 2/3] libcamera: request: Move metadata_ to Private","Message-ID":"<bqtxfzsmplmh52chvdy4fadu77naswupfjt3c73vfxaivzwogk@xioamhdwb4sz>","References":"<20251126-cam-control-override-v2-0-305024a1f190@ideasonboard.com>\n\t<20251126-cam-control-override-v2-2-305024a1f190@ideasonboard.com>\n\t<3f9df1db-b6cc-4d6d-b36a-9e40d0b80a88@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<3f9df1db-b6cc-4d6d-b36a-9e40d0b80a88@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":37129,"web_url":"https://patchwork.libcamera.org/comment/37129/","msgid":"<176458460532.3882822.9317716653022151998@neptunite.rasen.tech>","date":"2025-12-01T10:23:25","subject":"Re: [PATCH v2 2/3] libcamera: request: Move metadata_ to Private","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Quoting Jacopo Mondi (2025-11-26 18:38:52)\n> Address a long standing \\todo item that suggested to implement a\n> read-only interface for the Request::metadata() accessor and deflect to\n> the internal implementation for the read-write accessor used by pipeline\n> handlers.\n> \n> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n\nLooks good to me.\n\nAcked-by: Paul Elder <paul.elder@ideasonboard.com>\n\n> ---\n>  include/libcamera/internal/request.h               |  3 ++\n>  include/libcamera/request.h                        |  3 +-\n>  src/libcamera/pipeline/imx8-isi/imx8-isi.cpp       |  3 +-\n>  src/libcamera/pipeline/ipu3/ipu3.cpp               | 16 +++++-----\n>  src/libcamera/pipeline/mali-c55/mali-c55.cpp       |  2 +-\n>  src/libcamera/pipeline/rkisp1/rkisp1.cpp           | 10 +++---\n>  .../pipeline/rpi/common/pipeline_base.cpp          | 13 ++++----\n>  src/libcamera/pipeline/rpi/common/pipeline_base.h  |  2 +-\n>  src/libcamera/pipeline/simple/simple.cpp           |  8 ++---\n>  src/libcamera/pipeline/uvcvideo/uvcvideo.cpp       |  6 ++--\n>  src/libcamera/pipeline/vimc/vimc.cpp               |  6 ++--\n>  src/libcamera/pipeline/virtual/virtual.cpp         |  4 +--\n>  src/libcamera/request.cpp                          | 37 ++++++++++++----------\n>  13 files changed, 61 insertions(+), 52 deletions(-)\n> \n> diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h\n> index 78cb99f3604504dfb7145c605835b7493b656ced..643f67cabf5778f7515c0117d06d4e0a3fdec4f8 100644\n> --- a/include/libcamera/internal/request.h\n> +++ b/include/libcamera/internal/request.h\n> @@ -36,6 +36,8 @@ public:\n>         Camera *camera() const { return camera_; }\n>         bool hasPendingBuffers() const;\n>  \n> +       ControlList &metadata() { return *metadata_; }\n> +\n>         bool completeBuffer(FrameBuffer *buffer);\n>         void complete();\n>         void cancel();\n> @@ -61,6 +63,7 @@ private:\n>         std::unordered_set<FrameBuffer *> pending_;\n>         std::map<FrameBuffer *, EventNotifier> notifiers_;\n>         std::unique_ptr<Timer> timer_;\n> +       ControlList *metadata_;\n>  };\n>  \n>  } /* namespace libcamera */\n> diff --git a/include/libcamera/request.h b/include/libcamera/request.h\n> index 0c5939f7b3336fd089a2fe231f4f6f266cc422f7..c9aeddb62680923dc3490a23dc6c3f70f70cc075 100644\n> --- a/include/libcamera/request.h\n> +++ b/include/libcamera/request.h\n> @@ -50,7 +50,7 @@ public:\n>         void reuse(ReuseFlag flags = Default);\n>  \n>         ControlList &controls() { return *controls_; }\n> -       ControlList &metadata() { return *metadata_; }\n> +       const ControlList &metadata() const;\n>         const BufferMap &buffers() const { return bufferMap_; }\n>         int addBuffer(const Stream *stream, FrameBuffer *buffer,\n>                       std::unique_ptr<Fence> &&fence = {});\n> @@ -68,7 +68,6 @@ private:\n>         LIBCAMERA_DISABLE_COPY(Request)\n>  \n>         ControlList *controls_;\n> -       ControlList *metadata_;\n>         BufferMap bufferMap_;\n>  \n>         const uint64_t cookie_;\n> diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n> index 9550f54600c4d98e9d110a5e255d1ac85e2b5660..b0fb117b52e2a00fe9b5289c957442c1142fe7c6 100644\n> --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n> +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n> @@ -26,6 +26,7 @@\n>  #include \"libcamera/internal/device_enumerator.h\"\n>  #include \"libcamera/internal/media_device.h\"\n>  #include \"libcamera/internal/pipeline_handler.h\"\n> +#include \"libcamera/internal/request.h\"\n>  #include \"libcamera/internal/v4l2_subdevice.h\"\n>  #include \"libcamera/internal/v4l2_videodevice.h\"\n>  \n> @@ -1151,7 +1152,7 @@ void PipelineHandlerISI::bufferReady(FrameBuffer *buffer)\n>         Request *request = buffer->request();\n>  \n>         /* Record the sensor's timestamp in the request metadata. */\n> -       ControlList &metadata = request->metadata();\n> +       ControlList &metadata = request->_d()->metadata();\n>         if (!metadata.contains(controls::SensorTimestamp.id()))\n>                 metadata.set(controls::SensorTimestamp,\n>                              buffer->metadata().timestamp);\n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index d6b7edcb5a7f9fcb4083d4105a193978e265ef67..49df8fe5b41035b164c3a6828b791ef084ff18c8 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -19,7 +19,6 @@\n>  #include <libcamera/control_ids.h>\n>  #include <libcamera/formats.h>\n>  #include <libcamera/property_ids.h>\n> -#include <libcamera/request.h>\n>  #include <libcamera/stream.h>\n>  \n>  #include <libcamera/ipa/ipu3_ipa_interface.h>\n> @@ -35,6 +34,7 @@\n>  #include \"libcamera/internal/ipa_manager.h\"\n>  #include \"libcamera/internal/media_device.h\"\n>  #include \"libcamera/internal/pipeline_handler.h\"\n> +#include \"libcamera/internal/request.h\"\n>  \n>  #include \"cio2.h\"\n>  #include \"frames.h\"\n> @@ -1249,7 +1249,7 @@ void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)\n>                 return;\n>  \n>         Request *request = info->request;\n> -       request->metadata().merge(metadata);\n> +       request->_d()->metadata().merge(metadata);\n>  \n>         info->metadataProcessed = true;\n>         if (frameInfos_.tryComplete(info))\n> @@ -1276,12 +1276,12 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)\n>  \n>         pipe()->completeBuffer(request, buffer);\n>  \n> -       request->metadata().set(controls::draft::PipelineDepth, 3);\n> +       request->_d()->metadata().set(controls::draft::PipelineDepth, 3);\n>         /* \\todo Actually apply the scaler crop region to the ImgU. */\n>         const auto &scalerCrop = request->controls().get(controls::ScalerCrop);\n>         if (scalerCrop)\n>                 cropRegion_ = *scalerCrop;\n> -       request->metadata().set(controls::ScalerCrop, cropRegion_);\n> +       request->_d()->metadata().set(controls::ScalerCrop, cropRegion_);\n>  \n>         if (frameInfos_.tryComplete(info))\n>                 pipe()->completeRequest(request);\n> @@ -1321,8 +1321,8 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)\n>          * \\todo The sensor timestamp should be better estimated by connecting\n>          * to the V4L2Device::frameStart signal.\n>          */\n> -       request->metadata().set(controls::SensorTimestamp,\n> -                               buffer->metadata().timestamp);\n> +       request->_d()->metadata().set(controls::SensorTimestamp,\n> +                                     buffer->metadata().timestamp);\n>  \n>         info->effectiveSensorControls = delayedCtrls_->get(buffer->metadata().sequence);\n>  \n> @@ -1416,8 +1416,8 @@ void IPU3CameraData::frameStart(uint32_t sequence)\n>                 return;\n>         }\n>  \n> -       request->metadata().set(controls::draft::TestPatternMode,\n> -                               *testPatternMode);\n> +       request->_d()->metadata().set(controls::draft::TestPatternMode,\n> +                                     *testPatternMode);\n>  }\n>  \n>  REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3, \"ipu3\")\n> diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n> index 38bdc6138ed167a2c05f43ca30e60ed549fd953c..68be4cd66050b56e50805336efa5da8dafa4d3b9 100644\n> --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n> +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n> @@ -1528,7 +1528,7 @@ void PipelineHandlerMaliC55::statsProcessed(unsigned int requestId,\n>         MaliC55FrameInfo &frameInfo = frameInfoMap_[requestId];\n>  \n>         frameInfo.statsDone = true;\n> -       frameInfo.request->metadata().merge(metadata);\n> +       frameInfo.request->_d()->metadata().merge(metadata);\n>  \n>         tryComplete(&frameInfo);\n>  }\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index d7195b6c484d091857a91de709e0e060810c7c32..823160f58d989600ff3213df6bbec2a015d8745f 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -25,7 +25,6 @@\n>  #include <libcamera/formats.h>\n>  #include <libcamera/framebuffer.h>\n>  #include <libcamera/property_ids.h>\n> -#include <libcamera/request.h>\n>  #include <libcamera/stream.h>\n>  #include <libcamera/transform.h>\n>  \n> @@ -44,6 +43,7 @@\n>  #include \"libcamera/internal/media_device.h\"\n>  #include \"libcamera/internal/media_pipeline.h\"\n>  #include \"libcamera/internal/pipeline_handler.h\"\n> +#include \"libcamera/internal/request.h\"\n>  #include \"libcamera/internal/v4l2_subdevice.h\"\n>  #include \"libcamera/internal/v4l2_videodevice.h\"\n>  \n> @@ -452,7 +452,7 @@ void RkISP1CameraData::metadataReady(unsigned int frame, const ControlList &meta\n>         if (!info)\n>                 return;\n>  \n> -       info->request->metadata().merge(metadata);\n> +       info->request->_d()->metadata().merge(metadata);\n>         info->metadataProcessed = true;\n>  \n>         pipe()->tryCompleteRequest(info);\n> @@ -1518,8 +1518,8 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)\n>                  * \\todo The sensor timestamp should be better estimated by connecting\n>                  * to the V4L2Device::frameStart signal.\n>                  */\n> -               request->metadata().set(controls::SensorTimestamp,\n> -                                       metadata.timestamp);\n> +               request->_d()->metadata().set(controls::SensorTimestamp,\n> +                                             metadata.timestamp);\n>  \n>                 if (isRaw_) {\n>                         const ControlList &ctrls =\n> @@ -1602,7 +1602,7 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)\n>                 LOG(RkISP1, Error) << \"Cannot queue buffers to dewarper: \"\n>                                    << strerror(-ret);\n>  \n> -       request->metadata().set(controls::ScalerCrop, activeCrop_.value());\n> +       request->_d()->metadata().set(controls::ScalerCrop, activeCrop_.value());\n>  }\n>  \n>  void PipelineHandlerRkISP1::dewarpBufferReady(FrameBuffer *buffer)\n> diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n> index c209aa596311a7d902e32caedc3f98cfa3da2b09..4a15839afbc32c3e57caff11904484540a61745e 100644\n> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n> @@ -1219,7 +1219,7 @@ void CameraData::metadataReady(const ControlList &metadata)\n>         /* Add to the Request metadata buffer what the IPA has provided. */\n>         /* Last thing to do is to fill up the request metadata. */\n>         Request *request = requestQueue_.front();\n> -       request->metadata().merge(metadata);\n> +       request->_d()->metadata().merge(metadata);\n>  \n>         /*\n>          * Inform the sensor of the latest colour gains if it has the\n> @@ -1490,9 +1490,9 @@ void CameraData::checkRequestCompleted()\n>  void CameraData::fillRequestMetadata(const ControlList &bufferControls, Request *request)\n>  {\n>         if (auto x = bufferControls.get(controls::SensorTimestamp))\n> -               request->metadata().set(controls::SensorTimestamp, *x);\n> +               request->_d()->metadata().set(controls::SensorTimestamp, *x);\n>         if (auto x = bufferControls.get(controls::FrameWallClock))\n> -               request->metadata().set(controls::FrameWallClock, *x);\n> +               request->_d()->metadata().set(controls::FrameWallClock, *x);\n>  \n>         if (cropParams_.size()) {\n>                 std::vector<Rectangle> crops;\n> @@ -1500,10 +1500,11 @@ void CameraData::fillRequestMetadata(const ControlList &bufferControls, Request\n>                 for (auto const &[k, v] : cropParams_)\n>                         crops.push_back(scaleIspCrop(v.ispCrop));\n>  \n> -               request->metadata().set(controls::ScalerCrop, crops[0]);\n> +               request->_d()->metadata().set(controls::ScalerCrop, crops[0]);\n>                 if (crops.size() > 1) {\n> -                       request->metadata().set(controls::rpi::ScalerCrops,\n> -                                               Span<const Rectangle>(crops.data(), crops.size()));\n> +                       request->_d()->metadata().set(controls::rpi::ScalerCrops,\n> +                                                     Span<const Rectangle>(crops.data(),\n> +                                                                           crops.size()));\n>                 }\n>         }\n>  }\n> diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> index 4bce4ec4f978cedd7d10d354ce2231c9296a3e39..d9114f1cb954e541b2a35a748a95cca0af59ebbe 100644\n> --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n> @@ -15,7 +15,6 @@\n>  #include <vector>\n>  \n>  #include <libcamera/controls.h>\n> -#include <libcamera/request.h>\n>  \n>  #include \"libcamera/internal/bayer_format.h\"\n>  #include \"libcamera/internal/camera.h\"\n> @@ -25,6 +24,7 @@\n>  #include \"libcamera/internal/media_device.h\"\n>  #include \"libcamera/internal/media_object.h\"\n>  #include \"libcamera/internal/pipeline_handler.h\"\n> +#include \"libcamera/internal/request.h\"\n>  #include \"libcamera/internal/v4l2_videodevice.h\"\n>  #include \"libcamera/internal/yaml_parser.h\"\n>  \n> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\n> index 97009fbc03c64108a23f9edf6df95177593f9035..58cac390eb5be7231101c92fda1caf8e8b088e63 100644\n> --- a/src/libcamera/pipeline/simple/simple.cpp\n> +++ b/src/libcamera/pipeline/simple/simple.cpp\n> @@ -27,7 +27,6 @@\n>  #include <libcamera/camera.h>\n>  #include <libcamera/color_space.h>\n>  #include <libcamera/control_ids.h>\n> -#include <libcamera/request.h>\n>  #include <libcamera/stream.h>\n>  \n>  #include \"libcamera/internal/camera.h\"\n> @@ -41,6 +40,7 @@\n>  #include \"libcamera/internal/global_configuration.h\"\n>  #include \"libcamera/internal/media_device.h\"\n>  #include \"libcamera/internal/pipeline_handler.h\"\n> +#include \"libcamera/internal/request.h\"\n>  #include \"libcamera/internal/software_isp/software_isp.h\"\n>  #include \"libcamera/internal/v4l2_subdevice.h\"\n>  #include \"libcamera/internal/v4l2_videodevice.h\"\n> @@ -926,8 +926,8 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)\n>         }\n>  \n>         if (request)\n> -               request->metadata().set(controls::SensorTimestamp,\n> -                                       buffer->metadata().timestamp);\n> +               request->_d()->metadata().set(controls::SensorTimestamp,\n> +                                             buffer->metadata().timestamp);\n>  \n>         /*\n>          * Queue the captured and the request buffer to the converter or Software\n> @@ -1014,7 +1014,7 @@ void SimpleCameraData::metadataReady(uint32_t frame, const ControlList &metadata\n>         if (!info)\n>                 return;\n>  \n> -       info->request->metadata().merge(metadata);\n> +       info->request->_d()->metadata().merge(metadata);\n>         info->metadataProcessed = true;\n>         tryCompleteRequest(info->request);\n>  }\n> diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> index 48d6b39d532009bc32a2148f1d35b3a3be0bc0d4..21f2d28399bdfe97e0d97bf2e025721de36607c8 100644\n> --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> @@ -24,13 +24,13 @@\n>  #include <libcamera/control_ids.h>\n>  #include <libcamera/controls.h>\n>  #include <libcamera/property_ids.h>\n> -#include <libcamera/request.h>\n>  #include <libcamera/stream.h>\n>  \n>  #include \"libcamera/internal/camera.h\"\n>  #include \"libcamera/internal/device_enumerator.h\"\n>  #include \"libcamera/internal/media_device.h\"\n>  #include \"libcamera/internal/pipeline_handler.h\"\n> +#include \"libcamera/internal/request.h\"\n>  #include \"libcamera/internal/sysfs.h\"\n>  #include \"libcamera/internal/v4l2_videodevice.h\"\n>  \n> @@ -895,8 +895,8 @@ void UVCCameraData::imageBufferReady(FrameBuffer *buffer)\n>         Request *request = buffer->request();\n>  \n>         /* \\todo Use the UVC metadata to calculate a more precise timestamp */\n> -       request->metadata().set(controls::SensorTimestamp,\n> -                               buffer->metadata().timestamp);\n> +       request->_d()->metadata().set(controls::SensorTimestamp,\n> +                                     buffer->metadata().timestamp);\n>  \n>         pipe()->completeBuffer(request, buffer);\n>         pipe()->completeRequest(request);\n> diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp\n> index 5022101505a15af1ebf6a8be4a52bcefb1fccfa0..9b1cfb090a7a274894b90969c4dad361c6748cea 100644\n> --- a/src/libcamera/pipeline/vimc/vimc.cpp\n> +++ b/src/libcamera/pipeline/vimc/vimc.cpp\n> @@ -24,7 +24,6 @@\n>  #include <libcamera/formats.h>\n>  #include <libcamera/framebuffer.h>\n>  #include <libcamera/geometry.h>\n> -#include <libcamera/request.h>\n>  #include <libcamera/stream.h>\n>  \n>  #include <libcamera/ipa/ipa_interface.h>\n> @@ -39,6 +38,7 @@\n>  #include \"libcamera/internal/ipa_manager.h\"\n>  #include \"libcamera/internal/media_device.h\"\n>  #include \"libcamera/internal/pipeline_handler.h\"\n> +#include \"libcamera/internal/request.h\"\n>  #include \"libcamera/internal/v4l2_subdevice.h\"\n>  #include \"libcamera/internal/v4l2_videodevice.h\"\n>  \n> @@ -618,8 +618,8 @@ void VimcCameraData::imageBufferReady(FrameBuffer *buffer)\n>         }\n>  \n>         /* Record the sensor's timestamp in the request metadata. */\n> -       request->metadata().set(controls::SensorTimestamp,\n> -                               buffer->metadata().timestamp);\n> +       request->_d()->metadata().set(controls::SensorTimestamp,\n> +                                     buffer->metadata().timestamp);\n>  \n>         pipe->completeBuffer(request, buffer);\n>         pipe->completeRequest(request);\n> diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp\n> index 7855e8b9db0c3bdfb3662a0b6e71332ed463a0ed..40c35264c5687c0f94458e19a272612cefb76285 100644\n> --- a/src/libcamera/pipeline/virtual/virtual.cpp\n> +++ b/src/libcamera/pipeline/virtual/virtual.cpp\n> @@ -29,13 +29,13 @@\n>  #include <libcamera/formats.h>\n>  #include <libcamera/pixel_format.h>\n>  #include <libcamera/property_ids.h>\n> -#include <libcamera/request.h>\n>  \n>  #include \"libcamera/internal/camera.h\"\n>  #include \"libcamera/internal/dma_buf_allocator.h\"\n>  #include \"libcamera/internal/formats.h\"\n>  #include \"libcamera/internal/framebuffer.h\"\n>  #include \"libcamera/internal/pipeline_handler.h\"\n> +#include \"libcamera/internal/request.h\"\n>  #include \"libcamera/internal/yaml_parser.h\"\n>  \n>  #include \"pipeline/virtual/config_parser.h\"\n> @@ -366,7 +366,7 @@ int PipelineHandlerVirtual::queueRequestDevice([[maybe_unused]] Camera *camera,\n>         VirtualCameraData *data = cameraData(camera);\n>         const auto timestamp = currentTimestamp();\n>  \n> -       request->metadata().set(controls::SensorTimestamp, timestamp);\n> +       request->_d()->metadata().set(controls::SensorTimestamp, timestamp);\n>         data->invokeMethod(&VirtualCameraData::processRequest,\n>                            ConnectionTypeQueued, request);\n>  \n> diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp\n> index 2544a059f6984d930ec909c74e0b621c9fe82726..a661b2f5c8ae9ae2bcbab2dcdceeef7dcb8d0930 100644\n> --- a/src/libcamera/request.cpp\n> +++ b/src/libcamera/request.cpp\n> @@ -57,11 +57,16 @@ LOG_DEFINE_CATEGORY(Request)\n>  Request::Private::Private(Camera *camera)\n>         : camera_(camera), cancelled_(false)\n>  {\n> +       /**\n> +        * \\todo Add a validator for metadata controls.\n> +        */\n> +       metadata_ = new ControlList(controls::controls);\n>  }\n>  \n>  Request::Private::~Private()\n>  {\n>         doCancelRequest();\n> +       delete metadata_;\n>  }\n>  \n>  /**\n> @@ -82,6 +87,12 @@ bool Request::Private::hasPendingBuffers() const\n>         return !pending_.empty();\n>  }\n>  \n> +/**\n> + * \\fn Request::Private::metadata()\n> + * \\brief Retrieve the request's metadata\n> + * \\return The metadata associated with the request\n> + */\n> +\n>  /**\n>   * \\brief Complete a buffer for the request\n>   * \\param[in] buffer The buffer that has completed\n> @@ -359,11 +370,6 @@ Request::Request(Camera *camera, uint64_t cookie)\n>         controls_ = new ControlList(camera->controls(),\n>                                     camera->_d()->validator());\n>  \n> -       /**\n> -        * \\todo Add a validator for metadata controls.\n> -        */\n> -       metadata_ = new ControlList(controls::controls);\n> -\n>         LIBCAMERA_TRACEPOINT(request_construct, this);\n>  \n>         LOG(Request, Debug) << \"Created request - cookie: \" << cookie_;\n> @@ -372,8 +378,6 @@ Request::Request(Camera *camera, uint64_t cookie)\n>  Request::~Request()\n>  {\n>         LIBCAMERA_TRACEPOINT(request_destroy, this);\n> -\n> -       delete metadata_;\n>         delete controls_;\n>  }\n>  \n> @@ -406,7 +410,7 @@ void Request::reuse(ReuseFlag flags)\n>         status_ = RequestPending;\n>  \n>         controls_->clear();\n> -       metadata_->clear();\n> +       _d()->metadata_->clear();\n>  }\n>  \n>  /**\n> @@ -425,6 +429,15 @@ void Request::reuse(ReuseFlag flags)\n>   * \\return A reference to the ControlList in this request\n>   */\n>  \n> +/**\n> + * \\brief Retrieve the request's metadata\n> + * \\return The a const reference to the metadata associated with the request\n> + */\n> +const ControlList &Request::metadata() const\n> +{\n> +       return *_d()->metadata_;\n> +}\n> +\n>  /**\n>   * \\fn Request::buffers()\n>   * \\brief Retrieve the request's streams to buffers map\n> @@ -525,14 +538,6 @@ FrameBuffer *Request::findBuffer(const Stream *stream) const\n>         return it->second;\n>  }\n>  \n> -/**\n> - * \\fn Request::metadata()\n> - * \\brief Retrieve the request's metadata\n> - * \\todo Offer a read-only API towards applications while keeping a read/write\n> - * API internally.\n> - * \\return The metadata associated with the request\n> - */\n> -\n>  /**\n>   * \\brief Retrieve the sequence number for the request\n>   *\n> \n> -- \n> 2.51.1\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 7C680C0F1B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  1 Dec 2025 10:23:32 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 29DA360AC8;\n\tMon,  1 Dec 2025 11:23:32 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 074AF609D8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  1 Dec 2025 11:23:31 +0100 (CET)","from neptunite.rasen.tech (unknown\n\t[IPv6:2404:7a81:160:2100:67cc:a360:f133:b401])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 6FE766AC;\n\tMon,  1 Dec 2025 11:21:17 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"tFnReSlS\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1764584478;\n\tbh=8rR7vj9Jb6Ikyj8+q97CwOPFDMvQ+peuzp0C91fznBo=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=tFnReSlSP/80U3M9TONR5dslKuQ8APOPHBGQ0FBQPgx3UU0yVqB00Cxmj/H4QptIZ\n\tXqpOIFGM7rYiNortrg3jenSzVf3abje1x5HTssXg4qGsGpEVDpKHoR0mI/6Z0Jx46h\n\tC9zEbEnSquB2TRAIUUkv1kmx0SF8+Y0OPoyd66mo=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20251126-cam-control-override-v2-2-305024a1f190@ideasonboard.com>","References":"<20251126-cam-control-override-v2-0-305024a1f190@ideasonboard.com>\n\t<20251126-cam-control-override-v2-2-305024a1f190@ideasonboard.com>","Subject":"Re: [PATCH v2 2/3] libcamera: request: Move metadata_ to Private","From":"Paul Elder <paul.elder@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Mon, 01 Dec 2025 19:23:25 +0900","Message-ID":"<176458460532.3882822.9317716653022151998@neptunite.rasen.tech>","User-Agent":"alot/0.0.0","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]