[{"id":34983,"web_url":"https://patchwork.libcamera.org/comment/34983/","msgid":"<175312277729.50296.10508013107287248447@ping.linuxembedded.co.uk>","date":"2025-07-21T18:32:57","subject":"Re: [PATCH v1 1/2] libcamera: camera_sensor: getControls(): Use span","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Barnabás Pőcze (2025-03-03 19:33:48)\n> Do not force the caller to construct a vector.\n> \n\nPerhaps we could expand this:\n\n\n\"\"\"\nThe V4L2 getControls implementation currently requires a std::vector to\nbe constructed.\n\nUpdate this to use a Span to make it possible to store static const\narrays of the required ControlIds to remove dynamic allocation while\ncalling for a fixed range of controls.\n\nConvert relevant callers as part of the change.\n\"\"\"\n\n\nThis passed CI in March (for both commits in this series)\n\nhttps://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1376848\n\nAnd still applies cleanly.\n\nRunning CI now :\n\nhttps://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1475482\n\nSucceeded.\n\nI think such a change is reasonable.\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> ---\n>  include/libcamera/internal/camera_sensor.h    |  3 ++-\n>  include/libcamera/internal/v4l2_device.h      |  2 +-\n>  src/libcamera/sensor/camera_sensor_legacy.cpp | 14 +++++++++-----\n>  src/libcamera/sensor/camera_sensor_raw.cpp    | 14 +++++++++-----\n>  src/libcamera/v4l2_device.cpp                 |  2 +-\n>  test/v4l2_videodevice/controls.cpp            | 14 +++++++++-----\n>  6 files changed, 31 insertions(+), 18 deletions(-)\n> \n> diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h\n> index 13048f327..59a1604c5 100644\n> --- a/include/libcamera/internal/camera_sensor.h\n> +++ b/include/libcamera/internal/camera_sensor.h\n> @@ -14,6 +14,7 @@\n>  #include <vector>\n>  \n>  #include <libcamera/base/class.h>\n> +#include <libcamera/base/span.h>\n>  \n>  #include <libcamera/control_ids.h>\n>  #include <libcamera/controls.h>\n> @@ -74,7 +75,7 @@ public:\n>         virtual BayerFormat::Order bayerOrder(Transform t) const = 0;\n>  \n>         virtual const ControlInfoMap &controls() const = 0;\n> -       virtual ControlList getControls(const std::vector<uint32_t> &ids) = 0;\n> +       virtual ControlList getControls(Span<const uint32_t> ids) = 0;\n>         virtual int setControls(ControlList *ctrls) = 0;\n>  \n>         virtual const std::vector<controls::draft::TestPatternModeEnum> &\n> diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h\n> index affe52c2a..4ab818d90 100644\n> --- a/include/libcamera/internal/v4l2_device.h\n> +++ b/include/libcamera/internal/v4l2_device.h\n> @@ -37,7 +37,7 @@ public:\n>  \n>         const ControlInfoMap &controls() const { return controls_; }\n>  \n> -       ControlList getControls(const std::vector<uint32_t> &ids);\n> +       ControlList getControls(Span<const uint32_t> ids);\n>         int setControls(ControlList *ctrls);\n>  \n>         const struct v4l2_query_ext_ctrl *controlInfo(uint32_t id) const;\n> diff --git a/src/libcamera/sensor/camera_sensor_legacy.cpp b/src/libcamera/sensor/camera_sensor_legacy.cpp\n> index 32989c19c..1eccca519 100644\n> --- a/src/libcamera/sensor/camera_sensor_legacy.cpp\n> +++ b/src/libcamera/sensor/camera_sensor_legacy.cpp\n> @@ -90,7 +90,7 @@ public:\n>         BayerFormat::Order bayerOrder(Transform t) const override;\n>  \n>         const ControlInfoMap &controls() const override;\n> -       ControlList getControls(const std::vector<uint32_t> &ids) override;\n> +       ControlList getControls(Span<const uint32_t> ids) override;\n>         int setControls(ControlList *ctrls) override;\n>  \n>         const std::vector<controls::draft::TestPatternModeEnum> &\n> @@ -907,9 +907,13 @@ int CameraSensorLegacy::sensorInfo(IPACameraSensorInfo *info) const\n>          * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE,\n>          * V4L2_CID_HBLANK and V4L2_CID_VBLANK controls is mandatory.\n>          */\n> -       ControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,\n> -                                                  V4L2_CID_HBLANK,\n> -                                                  V4L2_CID_VBLANK });\n> +       static constexpr uint32_t cids[] = {\n> +               V4L2_CID_PIXEL_RATE,\n> +               V4L2_CID_HBLANK,\n> +               V4L2_CID_VBLANK,\n> +       };\n> +\n> +       ControlList ctrls = subdev_->getControls(cids);\n>         if (ctrls.empty()) {\n>                 LOG(CameraSensor, Error)\n>                         << \"Failed to retrieve camera info controls\";\n> @@ -983,7 +987,7 @@ const ControlInfoMap &CameraSensorLegacy::controls() const\n>         return subdev_->controls();\n>  }\n>  \n> -ControlList CameraSensorLegacy::getControls(const std::vector<uint32_t> &ids)\n> +ControlList CameraSensorLegacy::getControls(Span<const uint32_t> ids)\n>  {\n>         return subdev_->getControls(ids);\n>  }\n> diff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp\n> index ab75b1f82..c65ecbb86 100644\n> --- a/src/libcamera/sensor/camera_sensor_raw.cpp\n> +++ b/src/libcamera/sensor/camera_sensor_raw.cpp\n> @@ -96,7 +96,7 @@ public:\n>         BayerFormat::Order bayerOrder(Transform t) const override;\n>  \n>         const ControlInfoMap &controls() const override;\n> -       ControlList getControls(const std::vector<uint32_t> &ids) override;\n> +       ControlList getControls(Span<const uint32_t> ids) override;\n>         int setControls(ControlList *ctrls) override;\n>  \n>         const std::vector<controls::draft::TestPatternModeEnum> &\n> @@ -1022,9 +1022,13 @@ int CameraSensorRaw::sensorInfo(IPACameraSensorInfo *info) const\n>          * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE,\n>          * V4L2_CID_HBLANK and V4L2_CID_VBLANK controls is mandatory.\n>          */\n> -       ControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,\n> -                                                  V4L2_CID_HBLANK,\n> -                                                  V4L2_CID_VBLANK });\n> +       static constexpr uint32_t cids[] = {\n> +               V4L2_CID_PIXEL_RATE,\n> +               V4L2_CID_HBLANK,\n> +               V4L2_CID_VBLANK,\n> +       };\n> +\n> +       ControlList ctrls = subdev_->getControls(cids);\n>         if (ctrls.empty()) {\n>                 LOG(CameraSensor, Error)\n>                         << \"Failed to retrieve camera info controls\";\n> @@ -1095,7 +1099,7 @@ const ControlInfoMap &CameraSensorRaw::controls() const\n>         return subdev_->controls();\n>  }\n>  \n> -ControlList CameraSensorRaw::getControls(const std::vector<uint32_t> &ids)\n> +ControlList CameraSensorRaw::getControls(Span<const uint32_t> ids)\n>  {\n>         return subdev_->getControls(ids);\n>  }\n> diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> index 2f65a43a0..089f45afd 100644\n> --- a/src/libcamera/v4l2_device.cpp\n> +++ b/src/libcamera/v4l2_device.cpp\n> @@ -174,7 +174,7 @@ void V4L2Device::close()\n>   * \\return The control values in a ControlList on success, or an empty list on\n>   * error\n>   */\n> -ControlList V4L2Device::getControls(const std::vector<uint32_t> &ids)\n> +ControlList V4L2Device::getControls(Span<const uint32_t> ids)\n>  {\n>         if (ids.empty())\n>                 return {};\n> diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp\n> index b0130295e..7990f37dc 100644\n> --- a/test/v4l2_videodevice/controls.cpp\n> +++ b/test/v4l2_videodevice/controls.cpp\n> @@ -60,11 +60,15 @@ protected:\n>                 const ControlInfo &u8 = infoMap.find(VIVID_CID_U8_4D_ARRAY)->second;\n>  \n>                 /* Test getting controls. */\n> -               ControlList ctrls = capture_->getControls({ V4L2_CID_BRIGHTNESS,\n> -                                                           V4L2_CID_CONTRAST,\n> -                                                           V4L2_CID_SATURATION,\n> -                                                           VIVID_CID_INTEGER64,\n> -                                                           VIVID_CID_U8_4D_ARRAY });\n> +               static constexpr uint32_t cids[] = {\n> +                       V4L2_CID_BRIGHTNESS,\n> +                       V4L2_CID_CONTRAST,\n> +                       V4L2_CID_SATURATION,\n> +                       VIVID_CID_INTEGER64,\n> +                       VIVID_CID_U8_4D_ARRAY,\n> +               };\n> +\n> +               ControlList ctrls = capture_->getControls(cids);\n>                 if (ctrls.empty()) {\n>                         cerr << \"Failed to get controls\" << endl;\n>                         return TestFail;\n> -- \n> 2.48.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 8FC69BDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 21 Jul 2025 18:33:02 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6295568FFD;\n\tMon, 21 Jul 2025 20:33:01 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B030468FB1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 21 Jul 2025 20:33:00 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8C9C07908;\n\tMon, 21 Jul 2025 20:32:23 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"QcJqYP9R\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753122743;\n\tbh=uKc6eB4wwvyA4YfXdVPVvKWknL9oGUOJHXxGpBnSCzs=;\n\th=In-Reply-To:References:Subject:From:To:Date:From;\n\tb=QcJqYP9RxG2TzGiNtD1KJpnLg386JCnZc/NZ6/puMTDzL2YywIFjPQ58Xa4M7CkV9\n\tVnZyRnsfDmt57EzjRJXZJ0x60erKNMapUvatq1ho+/bReLGrHkNwpJMwq+RfRSev9I\n\ttVa5pE8jVlDGmRDYhIsyofXovgKyQnPOpl7nhGeg=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250303193349.785692-1-barnabas.pocze@ideasonboard.com>","References":"<20250303193349.785692-1-barnabas.pocze@ideasonboard.com>","Subject":"Re: [PATCH v1 1/2] libcamera: camera_sensor: getControls(): Use span","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Mon, 21 Jul 2025 19:32:57 +0100","Message-ID":"<175312277729.50296.10508013107287248447@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","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":35070,"web_url":"https://patchwork.libcamera.org/comment/35070/","msgid":"<2f88b792-5d6e-41be-b052-b96bbc9aa140@ideasonboard.com>","date":"2025-07-24T07:02:35","subject":"Re: [PATCH v1 1/2] libcamera: camera_sensor: getControls(): Use span","submitter":{"id":156,"url":"https://patchwork.libcamera.org/api/people/156/","name":"Dan Scally","email":"dan.scally@ideasonboard.com"},"content":"Hi Barnabas, thanks for the patch\n\nOn 03/03/2025 19:33, Barnabás Pőcze wrote:\n> Do not force the caller to construct a vector.\n>\n> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> ---\nReviewed-by: Daniel Scally <dan.scally@ideasonboard.com>\n>   include/libcamera/internal/camera_sensor.h    |  3 ++-\n>   include/libcamera/internal/v4l2_device.h      |  2 +-\n>   src/libcamera/sensor/camera_sensor_legacy.cpp | 14 +++++++++-----\n>   src/libcamera/sensor/camera_sensor_raw.cpp    | 14 +++++++++-----\n>   src/libcamera/v4l2_device.cpp                 |  2 +-\n>   test/v4l2_videodevice/controls.cpp            | 14 +++++++++-----\n>   6 files changed, 31 insertions(+), 18 deletions(-)\n>\n> diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h\n> index 13048f327..59a1604c5 100644\n> --- a/include/libcamera/internal/camera_sensor.h\n> +++ b/include/libcamera/internal/camera_sensor.h\n> @@ -14,6 +14,7 @@\n>   #include <vector>\n>   \n>   #include <libcamera/base/class.h>\n> +#include <libcamera/base/span.h>\n>   \n>   #include <libcamera/control_ids.h>\n>   #include <libcamera/controls.h>\n> @@ -74,7 +75,7 @@ public:\n>   \tvirtual BayerFormat::Order bayerOrder(Transform t) const = 0;\n>   \n>   \tvirtual const ControlInfoMap &controls() const = 0;\n> -\tvirtual ControlList getControls(const std::vector<uint32_t> &ids) = 0;\n> +\tvirtual ControlList getControls(Span<const uint32_t> ids) = 0;\n>   \tvirtual int setControls(ControlList *ctrls) = 0;\n>   \n>   \tvirtual const std::vector<controls::draft::TestPatternModeEnum> &\n> diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h\n> index affe52c2a..4ab818d90 100644\n> --- a/include/libcamera/internal/v4l2_device.h\n> +++ b/include/libcamera/internal/v4l2_device.h\n> @@ -37,7 +37,7 @@ public:\n>   \n>   \tconst ControlInfoMap &controls() const { return controls_; }\n>   \n> -\tControlList getControls(const std::vector<uint32_t> &ids);\n> +\tControlList getControls(Span<const uint32_t> ids);\n>   \tint setControls(ControlList *ctrls);\n>   \n>   \tconst struct v4l2_query_ext_ctrl *controlInfo(uint32_t id) const;\n> diff --git a/src/libcamera/sensor/camera_sensor_legacy.cpp b/src/libcamera/sensor/camera_sensor_legacy.cpp\n> index 32989c19c..1eccca519 100644\n> --- a/src/libcamera/sensor/camera_sensor_legacy.cpp\n> +++ b/src/libcamera/sensor/camera_sensor_legacy.cpp\n> @@ -90,7 +90,7 @@ public:\n>   \tBayerFormat::Order bayerOrder(Transform t) const override;\n>   \n>   \tconst ControlInfoMap &controls() const override;\n> -\tControlList getControls(const std::vector<uint32_t> &ids) override;\n> +\tControlList getControls(Span<const uint32_t> ids) override;\n>   \tint setControls(ControlList *ctrls) override;\n>   \n>   \tconst std::vector<controls::draft::TestPatternModeEnum> &\n> @@ -907,9 +907,13 @@ int CameraSensorLegacy::sensorInfo(IPACameraSensorInfo *info) const\n>   \t * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE,\n>   \t * V4L2_CID_HBLANK and V4L2_CID_VBLANK controls is mandatory.\n>   \t */\n> -\tControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,\n> -\t\t\t\t\t\t   V4L2_CID_HBLANK,\n> -\t\t\t\t\t\t   V4L2_CID_VBLANK });\n> +\tstatic constexpr uint32_t cids[] = {\n> +\t\tV4L2_CID_PIXEL_RATE,\n> +\t\tV4L2_CID_HBLANK,\n> +\t\tV4L2_CID_VBLANK,\n> +\t};\n> +\n> +\tControlList ctrls = subdev_->getControls(cids);\n>   \tif (ctrls.empty()) {\n>   \t\tLOG(CameraSensor, Error)\n>   \t\t\t<< \"Failed to retrieve camera info controls\";\n> @@ -983,7 +987,7 @@ const ControlInfoMap &CameraSensorLegacy::controls() const\n>   \treturn subdev_->controls();\n>   }\n>   \n> -ControlList CameraSensorLegacy::getControls(const std::vector<uint32_t> &ids)\n> +ControlList CameraSensorLegacy::getControls(Span<const uint32_t> ids)\n>   {\n>   \treturn subdev_->getControls(ids);\n>   }\n> diff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp\n> index ab75b1f82..c65ecbb86 100644\n> --- a/src/libcamera/sensor/camera_sensor_raw.cpp\n> +++ b/src/libcamera/sensor/camera_sensor_raw.cpp\n> @@ -96,7 +96,7 @@ public:\n>   \tBayerFormat::Order bayerOrder(Transform t) const override;\n>   \n>   \tconst ControlInfoMap &controls() const override;\n> -\tControlList getControls(const std::vector<uint32_t> &ids) override;\n> +\tControlList getControls(Span<const uint32_t> ids) override;\n>   \tint setControls(ControlList *ctrls) override;\n>   \n>   \tconst std::vector<controls::draft::TestPatternModeEnum> &\n> @@ -1022,9 +1022,13 @@ int CameraSensorRaw::sensorInfo(IPACameraSensorInfo *info) const\n>   \t * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE,\n>   \t * V4L2_CID_HBLANK and V4L2_CID_VBLANK controls is mandatory.\n>   \t */\n> -\tControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,\n> -\t\t\t\t\t\t   V4L2_CID_HBLANK,\n> -\t\t\t\t\t\t   V4L2_CID_VBLANK });\n> +\tstatic constexpr uint32_t cids[] = {\n> +\t\tV4L2_CID_PIXEL_RATE,\n> +\t\tV4L2_CID_HBLANK,\n> +\t\tV4L2_CID_VBLANK,\n> +\t};\n> +\n> +\tControlList ctrls = subdev_->getControls(cids);\n>   \tif (ctrls.empty()) {\n>   \t\tLOG(CameraSensor, Error)\n>   \t\t\t<< \"Failed to retrieve camera info controls\";\n> @@ -1095,7 +1099,7 @@ const ControlInfoMap &CameraSensorRaw::controls() const\n>   \treturn subdev_->controls();\n>   }\n>   \n> -ControlList CameraSensorRaw::getControls(const std::vector<uint32_t> &ids)\n> +ControlList CameraSensorRaw::getControls(Span<const uint32_t> ids)\n>   {\n>   \treturn subdev_->getControls(ids);\n>   }\n> diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> index 2f65a43a0..089f45afd 100644\n> --- a/src/libcamera/v4l2_device.cpp\n> +++ b/src/libcamera/v4l2_device.cpp\n> @@ -174,7 +174,7 @@ void V4L2Device::close()\n>    * \\return The control values in a ControlList on success, or an empty list on\n>    * error\n>    */\n> -ControlList V4L2Device::getControls(const std::vector<uint32_t> &ids)\n> +ControlList V4L2Device::getControls(Span<const uint32_t> ids)\n>   {\n>   \tif (ids.empty())\n>   \t\treturn {};\n> diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp\n> index b0130295e..7990f37dc 100644\n> --- a/test/v4l2_videodevice/controls.cpp\n> +++ b/test/v4l2_videodevice/controls.cpp\n> @@ -60,11 +60,15 @@ protected:\n>   \t\tconst ControlInfo &u8 = infoMap.find(VIVID_CID_U8_4D_ARRAY)->second;\n>   \n>   \t\t/* Test getting controls. */\n> -\t\tControlList ctrls = capture_->getControls({ V4L2_CID_BRIGHTNESS,\n> -\t\t\t\t\t\t\t    V4L2_CID_CONTRAST,\n> -\t\t\t\t\t\t\t    V4L2_CID_SATURATION,\n> -\t\t\t\t\t\t\t    VIVID_CID_INTEGER64,\n> -\t\t\t\t\t\t\t    VIVID_CID_U8_4D_ARRAY });\n> +\t\tstatic constexpr uint32_t cids[] = {\n> +\t\t\tV4L2_CID_BRIGHTNESS,\n> +\t\t\tV4L2_CID_CONTRAST,\n> +\t\t\tV4L2_CID_SATURATION,\n> +\t\t\tVIVID_CID_INTEGER64,\n> +\t\t\tVIVID_CID_U8_4D_ARRAY,\n> +\t\t};\n> +\n> +\t\tControlList ctrls = capture_->getControls(cids);\n>   \t\tif (ctrls.empty()) {\n>   \t\t\tcerr << \"Failed to get controls\" << endl;\n>   \t\t\treturn TestFail;","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 009A4C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 24 Jul 2025 07:02:41 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D2D4E690AD;\n\tThu, 24 Jul 2025 09:02:40 +0200 (CEST)","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 F157861508\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 24 Jul 2025 09:02:38 +0200 (CEST)","from [192.168.0.43]\n\t(cpc141996-chfd3-2-0-cust928.12-3.cable.virginm.net [86.13.91.161])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id EB287C74\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 24 Jul 2025 09:01:59 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"L+8vCM0l\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753340520;\n\tbh=02tW0zGQo5hd9XJvldT7dJ06dX9iPtOVFLzVnalSH70=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=L+8vCM0lgXGDmzuUzijjSR71zVVeHbtN5AChf4wQfV4DyTNIvoOuBzxYvfxoTrs2a\n\t6WY5xfxo3xfejSit4A4issWlH5eyTjnDlL0UT73m5AU9SbgvYfL945Gtbm6QDa5qD/\n\tuBFBenDAY/cLaOtMh7aKaWp7NsKCMNcoXy8He0aQ=","Message-ID":"<2f88b792-5d6e-41be-b052-b96bbc9aa140@ideasonboard.com>","Date":"Thu, 24 Jul 2025 08:02:35 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v1 1/2] libcamera: camera_sensor: getControls(): Use span","To":"libcamera-devel@lists.libcamera.org","References":"<20250303193349.785692-1-barnabas.pocze@ideasonboard.com>","Content-Language":"en-US","From":"Dan Scally <dan.scally@ideasonboard.com>","Autocrypt":"addr=dan.scally@ideasonboard.com; keydata=\n\t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","In-Reply-To":"<20250303193349.785692-1-barnabas.pocze@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":35100,"web_url":"https://patchwork.libcamera.org/comment/35100/","msgid":"<20250724121444.GM11202@pendragon.ideasonboard.com>","date":"2025-07-24T12:14:44","subject":"Re: [PATCH v1 1/2] libcamera: camera_sensor: getControls(): Use span","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Mon, Jul 21, 2025 at 07:32:57PM +0100, Kieran Bingham wrote:\n> Quoting Barnabás Pőcze (2025-03-03 19:33:48)\n> > Do not force the caller to construct a vector.\n> \n> Perhaps we could expand this:\n> \n> \"\"\"\n> The V4L2 getControls implementation currently requires a std::vector to\n> be constructed.\n> \n> Update this to use a Span to make it possible to store static const\n> arrays of the required ControlIds to remove dynamic allocation while\n> calling for a fixed range of controls.\n> \n> Convert relevant callers as part of the change.\n> \"\"\"\n> \n> This passed CI in March (for both commits in this series)\n> \n> https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1376848\n> \n> And still applies cleanly.\n> \n> Running CI now :\n> \n> https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1475482\n> \n> Succeeded.\n> \n> I think such a change is reasonable.\n> \n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> > Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> > ---\n> >  include/libcamera/internal/camera_sensor.h    |  3 ++-\n> >  include/libcamera/internal/v4l2_device.h      |  2 +-\n> >  src/libcamera/sensor/camera_sensor_legacy.cpp | 14 +++++++++-----\n> >  src/libcamera/sensor/camera_sensor_raw.cpp    | 14 +++++++++-----\n> >  src/libcamera/v4l2_device.cpp                 |  2 +-\n> >  test/v4l2_videodevice/controls.cpp            | 14 +++++++++-----\n> >  6 files changed, 31 insertions(+), 18 deletions(-)\n> > \n> > diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h\n> > index 13048f327..59a1604c5 100644\n> > --- a/include/libcamera/internal/camera_sensor.h\n> > +++ b/include/libcamera/internal/camera_sensor.h\n> > @@ -14,6 +14,7 @@\n> >  #include <vector>\n> >  \n> >  #include <libcamera/base/class.h>\n> > +#include <libcamera/base/span.h>\n> >  \n> >  #include <libcamera/control_ids.h>\n> >  #include <libcamera/controls.h>\n> > @@ -74,7 +75,7 @@ public:\n> >         virtual BayerFormat::Order bayerOrder(Transform t) const = 0;\n> >  \n> >         virtual const ControlInfoMap &controls() const = 0;\n> > -       virtual ControlList getControls(const std::vector<uint32_t> &ids) = 0;\n> > +       virtual ControlList getControls(Span<const uint32_t> ids) = 0;\n> >         virtual int setControls(ControlList *ctrls) = 0;\n> >  \n> >         virtual const std::vector<controls::draft::TestPatternModeEnum> &\n> > diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h\n> > index affe52c2a..4ab818d90 100644\n> > --- a/include/libcamera/internal/v4l2_device.h\n> > +++ b/include/libcamera/internal/v4l2_device.h\n> > @@ -37,7 +37,7 @@ public:\n> >  \n> >         const ControlInfoMap &controls() const { return controls_; }\n> >  \n> > -       ControlList getControls(const std::vector<uint32_t> &ids);\n> > +       ControlList getControls(Span<const uint32_t> ids);\n> >         int setControls(ControlList *ctrls);\n> >  \n> >         const struct v4l2_query_ext_ctrl *controlInfo(uint32_t id) const;\n> > diff --git a/src/libcamera/sensor/camera_sensor_legacy.cpp b/src/libcamera/sensor/camera_sensor_legacy.cpp\n> > index 32989c19c..1eccca519 100644\n> > --- a/src/libcamera/sensor/camera_sensor_legacy.cpp\n> > +++ b/src/libcamera/sensor/camera_sensor_legacy.cpp\n> > @@ -90,7 +90,7 @@ public:\n> >         BayerFormat::Order bayerOrder(Transform t) const override;\n> >  \n> >         const ControlInfoMap &controls() const override;\n> > -       ControlList getControls(const std::vector<uint32_t> &ids) override;\n> > +       ControlList getControls(Span<const uint32_t> ids) override;\n> >         int setControls(ControlList *ctrls) override;\n> >  \n> >         const std::vector<controls::draft::TestPatternModeEnum> &\n> > @@ -907,9 +907,13 @@ int CameraSensorLegacy::sensorInfo(IPACameraSensorInfo *info) const\n> >          * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE,\n> >          * V4L2_CID_HBLANK and V4L2_CID_VBLANK controls is mandatory.\n> >          */\n> > -       ControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,\n> > -                                                  V4L2_CID_HBLANK,\n> > -                                                  V4L2_CID_VBLANK });\n> > +       static constexpr uint32_t cids[] = {\n> > +               V4L2_CID_PIXEL_RATE,\n> > +               V4L2_CID_HBLANK,\n> > +               V4L2_CID_VBLANK,\n> > +       };\n> > +\n> > +       ControlList ctrls = subdev_->getControls(cids);\n> >         if (ctrls.empty()) {\n> >                 LOG(CameraSensor, Error)\n> >                         << \"Failed to retrieve camera info controls\";\n> > @@ -983,7 +987,7 @@ const ControlInfoMap &CameraSensorLegacy::controls() const\n> >         return subdev_->controls();\n> >  }\n> >  \n> > -ControlList CameraSensorLegacy::getControls(const std::vector<uint32_t> &ids)\n> > +ControlList CameraSensorLegacy::getControls(Span<const uint32_t> ids)\n> >  {\n> >         return subdev_->getControls(ids);\n> >  }\n> > diff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp\n> > index ab75b1f82..c65ecbb86 100644\n> > --- a/src/libcamera/sensor/camera_sensor_raw.cpp\n> > +++ b/src/libcamera/sensor/camera_sensor_raw.cpp\n> > @@ -96,7 +96,7 @@ public:\n> >         BayerFormat::Order bayerOrder(Transform t) const override;\n> >  \n> >         const ControlInfoMap &controls() const override;\n> > -       ControlList getControls(const std::vector<uint32_t> &ids) override;\n> > +       ControlList getControls(Span<const uint32_t> ids) override;\n> >         int setControls(ControlList *ctrls) override;\n> >  \n> >         const std::vector<controls::draft::TestPatternModeEnum> &\n> > @@ -1022,9 +1022,13 @@ int CameraSensorRaw::sensorInfo(IPACameraSensorInfo *info) const\n> >          * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE,\n> >          * V4L2_CID_HBLANK and V4L2_CID_VBLANK controls is mandatory.\n> >          */\n> > -       ControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,\n> > -                                                  V4L2_CID_HBLANK,\n> > -                                                  V4L2_CID_VBLANK });\n> > +       static constexpr uint32_t cids[] = {\n> > +               V4L2_CID_PIXEL_RATE,\n> > +               V4L2_CID_HBLANK,\n> > +               V4L2_CID_VBLANK,\n> > +       };\n> > +\n> > +       ControlList ctrls = subdev_->getControls(cids);\n> >         if (ctrls.empty()) {\n> >                 LOG(CameraSensor, Error)\n> >                         << \"Failed to retrieve camera info controls\";\n> > @@ -1095,7 +1099,7 @@ const ControlInfoMap &CameraSensorRaw::controls() const\n> >         return subdev_->controls();\n> >  }\n> >  \n> > -ControlList CameraSensorRaw::getControls(const std::vector<uint32_t> &ids)\n> > +ControlList CameraSensorRaw::getControls(Span<const uint32_t> ids)\n> >  {\n> >         return subdev_->getControls(ids);\n> >  }\n> > diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> > index 2f65a43a0..089f45afd 100644\n> > --- a/src/libcamera/v4l2_device.cpp\n> > +++ b/src/libcamera/v4l2_device.cpp\n> > @@ -174,7 +174,7 @@ void V4L2Device::close()\n> >   * \\return The control values in a ControlList on success, or an empty list on\n> >   * error\n> >   */\n> > -ControlList V4L2Device::getControls(const std::vector<uint32_t> &ids)\n> > +ControlList V4L2Device::getControls(Span<const uint32_t> ids)\n> >  {\n> >         if (ids.empty())\n> >                 return {};\n> > diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp\n> > index b0130295e..7990f37dc 100644\n> > --- a/test/v4l2_videodevice/controls.cpp\n> > +++ b/test/v4l2_videodevice/controls.cpp\n> > @@ -60,11 +60,15 @@ protected:\n> >                 const ControlInfo &u8 = infoMap.find(VIVID_CID_U8_4D_ARRAY)->second;\n> >  \n> >                 /* Test getting controls. */\n> > -               ControlList ctrls = capture_->getControls({ V4L2_CID_BRIGHTNESS,\n> > -                                                           V4L2_CID_CONTRAST,\n> > -                                                           V4L2_CID_SATURATION,\n> > -                                                           VIVID_CID_INTEGER64,\n> > -                                                           VIVID_CID_U8_4D_ARRAY });\n> > +               static constexpr uint32_t cids[] = {\n> > +                       V4L2_CID_BRIGHTNESS,\n> > +                       V4L2_CID_CONTRAST,\n> > +                       V4L2_CID_SATURATION,\n> > +                       VIVID_CID_INTEGER64,\n> > +                       VIVID_CID_U8_4D_ARRAY,\n> > +               };\n> > +\n> > +               ControlList ctrls = capture_->getControls(cids);\n> >                 if (ctrls.empty()) {\n> >                         cerr << \"Failed to get controls\" << endl;\n> >                         return TestFail;","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 DC592BDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 24 Jul 2025 12:14:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 71830690F6;\n\tThu, 24 Jul 2025 14:14:54 +0200 (CEST)","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 93B9D690E2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 24 Jul 2025 14:14:48 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 34BC7C74;\n\tThu, 24 Jul 2025 14:14:09 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"SpoCuDxM\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753359249;\n\tbh=phGN2hHKuNKQtU9SQu7gYMC84kVF7wK/6TRYl3B5AsY=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=SpoCuDxMTGxxwcsk8ghCKiRbvl1bEjJy0YkvbZx0f4RNqPoiKV/WSRylGZ9XDExwo\n\t30dspcAL0ooYkqQWJXyAmzVJRK29SWz0xUrhLO/Zrg2AORiVCQfFcYlMkosXXcY6Wj\n\t2lW0ZZrifCL0+COLykvICL33xmP7WnGNbfcqMrfo=","Date":"Thu, 24 Jul 2025 15:14:44 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v1 1/2] libcamera: camera_sensor: getControls(): Use span","Message-ID":"<20250724121444.GM11202@pendragon.ideasonboard.com>","References":"<20250303193349.785692-1-barnabas.pocze@ideasonboard.com>\n\t<175312277729.50296.10508013107287248447@ping.linuxembedded.co.uk>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<175312277729.50296.10508013107287248447@ping.linuxembedded.co.uk>","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":35165,"web_url":"https://patchwork.libcamera.org/comment/35165/","msgid":"<e2402fcd-4a11-4816-95a6-b77376159739@ideasonboard.com>","date":"2025-07-27T18:13:55","subject":"Re: [PATCH v1 1/2] libcamera: camera_sensor: getControls(): Use span","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. 07. 21. 20:32 keltezéssel, Kieran Bingham írta:\n> Quoting Barnabás Pőcze (2025-03-03 19:33:48)\n>> Do not force the caller to construct a vector.\n>>\n> \n> Perhaps we could expand this:\n> \n> \n> \"\"\"\n> The V4L2 getControls implementation currently requires a std::vector to\n> be constructed.\n> \n> Update this to use a Span to make it possible to store static const\n> arrays of the required ControlIds to remove dynamic allocation while\n> calling for a fixed range of controls.\n> \n> Convert relevant callers as part of the change.\n> \"\"\"\n\nMy proposal is the following:\n\n\"\"\"\nThe function takes a const std::vector reference, but it does\nnot actually need an `std::vector`. So use a `libcamera::Span`\ninstead to avoid forcing the caller to construct a vector.\n\"\"\"\n\nRegards,\nBarnabás Pőcze\n\n> \n> \n> This passed CI in March (for both commits in this series)\n> \n> https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1376848\n> \n> And still applies cleanly.\n> \n> Running CI now :\n> \n> https://gitlab.freedesktop.org/camera/libcamera/-/pipelines/1475482\n> \n> Succeeded.\n> \n> I think such a change is reasonable.\n> \n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> \n>> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n>> ---\n>>   include/libcamera/internal/camera_sensor.h    |  3 ++-\n>>   include/libcamera/internal/v4l2_device.h      |  2 +-\n>>   src/libcamera/sensor/camera_sensor_legacy.cpp | 14 +++++++++-----\n>>   src/libcamera/sensor/camera_sensor_raw.cpp    | 14 +++++++++-----\n>>   src/libcamera/v4l2_device.cpp                 |  2 +-\n>>   test/v4l2_videodevice/controls.cpp            | 14 +++++++++-----\n>>   6 files changed, 31 insertions(+), 18 deletions(-)\n>>\n>> diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h\n>> index 13048f327..59a1604c5 100644\n>> --- a/include/libcamera/internal/camera_sensor.h\n>> +++ b/include/libcamera/internal/camera_sensor.h\n>> @@ -14,6 +14,7 @@\n>>   #include <vector>\n>>   \n>>   #include <libcamera/base/class.h>\n>> +#include <libcamera/base/span.h>\n>>   \n>>   #include <libcamera/control_ids.h>\n>>   #include <libcamera/controls.h>\n>> @@ -74,7 +75,7 @@ public:\n>>          virtual BayerFormat::Order bayerOrder(Transform t) const = 0;\n>>   \n>>          virtual const ControlInfoMap &controls() const = 0;\n>> -       virtual ControlList getControls(const std::vector<uint32_t> &ids) = 0;\n>> +       virtual ControlList getControls(Span<const uint32_t> ids) = 0;\n>>          virtual int setControls(ControlList *ctrls) = 0;\n>>   \n>>          virtual const std::vector<controls::draft::TestPatternModeEnum> &\n>> diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h\n>> index affe52c2a..4ab818d90 100644\n>> --- a/include/libcamera/internal/v4l2_device.h\n>> +++ b/include/libcamera/internal/v4l2_device.h\n>> @@ -37,7 +37,7 @@ public:\n>>   \n>>          const ControlInfoMap &controls() const { return controls_; }\n>>   \n>> -       ControlList getControls(const std::vector<uint32_t> &ids);\n>> +       ControlList getControls(Span<const uint32_t> ids);\n>>          int setControls(ControlList *ctrls);\n>>   \n>>          const struct v4l2_query_ext_ctrl *controlInfo(uint32_t id) const;\n>> diff --git a/src/libcamera/sensor/camera_sensor_legacy.cpp b/src/libcamera/sensor/camera_sensor_legacy.cpp\n>> index 32989c19c..1eccca519 100644\n>> --- a/src/libcamera/sensor/camera_sensor_legacy.cpp\n>> +++ b/src/libcamera/sensor/camera_sensor_legacy.cpp\n>> @@ -90,7 +90,7 @@ public:\n>>          BayerFormat::Order bayerOrder(Transform t) const override;\n>>   \n>>          const ControlInfoMap &controls() const override;\n>> -       ControlList getControls(const std::vector<uint32_t> &ids) override;\n>> +       ControlList getControls(Span<const uint32_t> ids) override;\n>>          int setControls(ControlList *ctrls) override;\n>>   \n>>          const std::vector<controls::draft::TestPatternModeEnum> &\n>> @@ -907,9 +907,13 @@ int CameraSensorLegacy::sensorInfo(IPACameraSensorInfo *info) const\n>>           * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE,\n>>           * V4L2_CID_HBLANK and V4L2_CID_VBLANK controls is mandatory.\n>>           */\n>> -       ControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,\n>> -                                                  V4L2_CID_HBLANK,\n>> -                                                  V4L2_CID_VBLANK });\n>> +       static constexpr uint32_t cids[] = {\n>> +               V4L2_CID_PIXEL_RATE,\n>> +               V4L2_CID_HBLANK,\n>> +               V4L2_CID_VBLANK,\n>> +       };\n>> +\n>> +       ControlList ctrls = subdev_->getControls(cids);\n>>          if (ctrls.empty()) {\n>>                  LOG(CameraSensor, Error)\n>>                          << \"Failed to retrieve camera info controls\";\n>> @@ -983,7 +987,7 @@ const ControlInfoMap &CameraSensorLegacy::controls() const\n>>          return subdev_->controls();\n>>   }\n>>   \n>> -ControlList CameraSensorLegacy::getControls(const std::vector<uint32_t> &ids)\n>> +ControlList CameraSensorLegacy::getControls(Span<const uint32_t> ids)\n>>   {\n>>          return subdev_->getControls(ids);\n>>   }\n>> diff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp\n>> index ab75b1f82..c65ecbb86 100644\n>> --- a/src/libcamera/sensor/camera_sensor_raw.cpp\n>> +++ b/src/libcamera/sensor/camera_sensor_raw.cpp\n>> @@ -96,7 +96,7 @@ public:\n>>          BayerFormat::Order bayerOrder(Transform t) const override;\n>>   \n>>          const ControlInfoMap &controls() const override;\n>> -       ControlList getControls(const std::vector<uint32_t> &ids) override;\n>> +       ControlList getControls(Span<const uint32_t> ids) override;\n>>          int setControls(ControlList *ctrls) override;\n>>   \n>>          const std::vector<controls::draft::TestPatternModeEnum> &\n>> @@ -1022,9 +1022,13 @@ int CameraSensorRaw::sensorInfo(IPACameraSensorInfo *info) const\n>>           * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE,\n>>           * V4L2_CID_HBLANK and V4L2_CID_VBLANK controls is mandatory.\n>>           */\n>> -       ControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,\n>> -                                                  V4L2_CID_HBLANK,\n>> -                                                  V4L2_CID_VBLANK });\n>> +       static constexpr uint32_t cids[] = {\n>> +               V4L2_CID_PIXEL_RATE,\n>> +               V4L2_CID_HBLANK,\n>> +               V4L2_CID_VBLANK,\n>> +       };\n>> +\n>> +       ControlList ctrls = subdev_->getControls(cids);\n>>          if (ctrls.empty()) {\n>>                  LOG(CameraSensor, Error)\n>>                          << \"Failed to retrieve camera info controls\";\n>> @@ -1095,7 +1099,7 @@ const ControlInfoMap &CameraSensorRaw::controls() const\n>>          return subdev_->controls();\n>>   }\n>>   \n>> -ControlList CameraSensorRaw::getControls(const std::vector<uint32_t> &ids)\n>> +ControlList CameraSensorRaw::getControls(Span<const uint32_t> ids)\n>>   {\n>>          return subdev_->getControls(ids);\n>>   }\n>> diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n>> index 2f65a43a0..089f45afd 100644\n>> --- a/src/libcamera/v4l2_device.cpp\n>> +++ b/src/libcamera/v4l2_device.cpp\n>> @@ -174,7 +174,7 @@ void V4L2Device::close()\n>>    * \\return The control values in a ControlList on success, or an empty list on\n>>    * error\n>>    */\n>> -ControlList V4L2Device::getControls(const std::vector<uint32_t> &ids)\n>> +ControlList V4L2Device::getControls(Span<const uint32_t> ids)\n>>   {\n>>          if (ids.empty())\n>>                  return {};\n>> diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp\n>> index b0130295e..7990f37dc 100644\n>> --- a/test/v4l2_videodevice/controls.cpp\n>> +++ b/test/v4l2_videodevice/controls.cpp\n>> @@ -60,11 +60,15 @@ protected:\n>>                  const ControlInfo &u8 = infoMap.find(VIVID_CID_U8_4D_ARRAY)->second;\n>>   \n>>                  /* Test getting controls. */\n>> -               ControlList ctrls = capture_->getControls({ V4L2_CID_BRIGHTNESS,\n>> -                                                           V4L2_CID_CONTRAST,\n>> -                                                           V4L2_CID_SATURATION,\n>> -                                                           VIVID_CID_INTEGER64,\n>> -                                                           VIVID_CID_U8_4D_ARRAY });\n>> +               static constexpr uint32_t cids[] = {\n>> +                       V4L2_CID_BRIGHTNESS,\n>> +                       V4L2_CID_CONTRAST,\n>> +                       V4L2_CID_SATURATION,\n>> +                       VIVID_CID_INTEGER64,\n>> +                       VIVID_CID_U8_4D_ARRAY,\n>> +               };\n>> +\n>> +               ControlList ctrls = capture_->getControls(cids);\n>>                  if (ctrls.empty()) {\n>>                          cerr << \"Failed to get controls\" << endl;\n>>                          return TestFail;\n>> -- \n>> 2.48.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 4036EBDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 27 Jul 2025 18:14:08 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 17B426912B;\n\tSun, 27 Jul 2025 20:14:07 +0200 (CEST)","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 5BA4769080\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 27 Jul 2025 20:14:03 +0200 (CEST)","from [192.168.33.14] (185.221.140.39.nat.pool.zt.hu\n\t[185.221.140.39])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 9892655A;\n\tSun, 27 Jul 2025 20:13:20 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"iKMm4arL\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1753640001;\n\tbh=2To02mVa58YOQ/KIOPlMM9eQ7g3OwUb7xOEBJI6x6IY=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=iKMm4arLqTr99uvpa1K1ufuumyx6MoigI5hl/vSlFChe/NlIMcjOA8fnxcMPrdDbJ\n\tbketGz8kP4lxsk3mZJHMjququCIWRrZ+g8hg7wt4DUck0Eal+VLcmdrYFrqJodTIRl\n\tPO23duHFNIY5TSVSUjh5RCVGY7bq1Tw1F+6hNHuc=","Message-ID":"<e2402fcd-4a11-4816-95a6-b77376159739@ideasonboard.com>","Date":"Sun, 27 Jul 2025 20:13:55 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v1 1/2] libcamera: camera_sensor: getControls(): Use span","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20250303193349.785692-1-barnabas.pocze@ideasonboard.com>\n\t<175312277729.50296.10508013107287248447@ping.linuxembedded.co.uk>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<175312277729.50296.10508013107287248447@ping.linuxembedded.co.uk>","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>"}}]