Patch Detail
Show a patch.
GET /api/patches/24062/?format=api
{ "id": 24062, "url": "https://patchwork.libcamera.org/api/patches/24062/?format=api", "web_url": "https://patchwork.libcamera.org/patch/24062/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20250806-control_storage-v1-2-2ec8424f6f7d@ideasonboard.com>", "date": "2025-08-06T12:30:46", "name": "[2/3] libcamera: Rename ControlValue to ControlStorage", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "040d3a97c18b84b6177bef4a562cf4101cae02c2", "submitter": { "id": 143, "url": "https://patchwork.libcamera.org/api/people/143/?format=api", "name": "Jacopo Mondi", "email": "jacopo.mondi@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/24062/mbox/", "series": [ { "id": 5358, "url": "https://patchwork.libcamera.org/api/series/5358/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5358", "date": "2025-08-06T12:30:44", "name": "libcamera: Make ControlValue a view", "version": 1, "mbox": "https://patchwork.libcamera.org/series/5358/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/24062/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/24062/checks/", "tags": {}, "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 9F8EDBDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 6 Aug 2025 12:31:06 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0B9D66921B;\n\tWed, 6 Aug 2025 14:31:05 +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 E610D6921B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 6 Aug 2025 14:31:00 +0200 (CEST)", "from [192.168.0.172] (mob-5-90-59-79.net.vodafone.it [5.90.59.79])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 17DA3CF;\n\tWed, 6 Aug 2025 14:30:12 +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=\"LTddZYAc\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1754483412;\n\tbh=vSKqXi1EP2wo4ONMUCkZUR6ZmgF5KV06Oyc0Qqv09so=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:From;\n\tb=LTddZYAcX8gfURbsilGFLAZsUCQkXe+SYgQZ0dnAVLgJ5E7DyYTrZLAR4Eeeys66Y\n\tGEGqWHPfv92MUbutCgAt3UU2KB2uV80x4akkywxogCJrhZzSfNNF74hTIsD/AK2807\n\t6CmUBalTTorBUIq+Id73orqTSjPVEGbwYUVHF5X0=", "From": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>", "Date": "Wed, 06 Aug 2025 14:30:46 +0200", "Subject": "[PATCH 2/3] libcamera: Rename ControlValue to ControlStorage", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20250806-control_storage-v1-2-2ec8424f6f7d@ideasonboard.com>", "References": "<20250806-control_storage-v1-0-2ec8424f6f7d@ideasonboard.com>", "In-Reply-To": "<20250806-control_storage-v1-0-2ec8424f6f7d@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>", "X-Mailer": "b4 0.14.2", "X-Developer-Signature": "v=1; a=openpgp-sha256; l=64772;\n\ti=jacopo.mondi@ideasonboard.com; h=from:subject:message-id;\n\tbh=vSKqXi1EP2wo4ONMUCkZUR6ZmgF5KV06Oyc0Qqv09so=;\n\tb=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBok0sCZK7jdTEc+HdjEqo4CiCnS2FrRrEgkUA5V\n\twG3JqA0guGJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCaJNLAgAKCRByNAaPFqFW\n\tPLSFD/9EbvaRHvco0E1CNF0G8w7tsoSYHmlfjcVRuKeMaumYb1FSb172hSTuoujuwCTKRyyZ8JS\n\tsQnaARSSafPne5dULmGeOfG0VxSv6fQ0P+dfnUdeWOGYtHd04Tw+z7FX+fbONUPVZ8Q5JQvDK+3\n\tEub1gWQ8GZLgapsemcklzHaAPNyOJifE+Nv2GwdpvkcKMk9obihgcB+4Z+ntNIwoa1p3EZcZcqL\n\tIfgnry4RkAbUUBnmwWEP+3DPzLa0kKuzrT+bSU40vOa0BufOLoLbD4/r9jbCQRJ7L4U3A/wqzUd\n\trj0ZK2S2WPGw2Y6/RmB6Uh0BJeOCcBaJjYkihXcmltZHBLYwUaGwr3m2aUj8CW107c4CwoI+Tct\n\tV+Pb7cdwersWbxM7zUyPExU5s+Ff+efbh04GOh8vj/kDBTOT8/DN13/gURYzoAXiiSh9e0LMgIi\n\tIoBP8LlvLHKmLEm9JYJcRhVqxlR6DN51n2SQcq4qYeg9b2UWpTxE1OAXwyM8TQSffFSxjyPdqZB\n\tJWQmo2uMKPaMTNRnxCxYdqP+zLatMUz4eWtVTsvxMutCeXBHv9vZn9r9d3M4h1t8zRj3aQtHVgM\n\t1iTpJuT2BH5hRXQxOdB9uN7seCekID+ECUNPFZiXg8NWDgtFNNZorjaqYVCQP7VmbqB8dM+Wxis\n\tc18wAyERZqJnhHQ==", "X-Developer-Key": "i=jacopo.mondi@ideasonboard.com; a=openpgp;\n\tfpr=72392EDC88144A65C701EA9BA5826A2587AD026B", "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>" }, "content": "The ControlValue class in libcamera represents the storage location\nof the values a Control represents.\n\nWhen a ControlValue is constructed, assigned or set() the values\nreceived as parameters are mem-copied inside the storage space allocated\ninside the ControlValue.\n\nThis implies that creating ControlValue effectively mem-copies a\nControl creating multiple storages from the same information.\n\nTo prepare to use wherever possible the newly introduced\nControlValueView in the libcamera API, rename the ControlValue\nto ControlStorage.\n\nSigned-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n---\n include/libcamera/control_ids.h.in | 2 +-\n include/libcamera/controls.h | 64 ++++----\n include/libcamera/internal/control_serializer.h | 6 +-\n include/libcamera/internal/debug_controls.h | 2 +-\n include/libcamera/internal/delayed_controls.h | 6 +-\n src/apps/cam/capture_script.cpp | 16 +-\n src/apps/cam/capture_script.h | 8 +-\n src/gstreamer/gstlibcamera-controls.cpp.in | 4 +-\n src/ipa/libipa/agc_mean_luminance.cpp | 4 +-\n src/ipa/libipa/awb.cpp | 4 +-\n src/ipa/libipa/awb.h | 2 +-\n src/ipa/rkisp1/algorithms/agc.cpp | 16 +-\n src/ipa/rkisp1/algorithms/ccm.cpp | 6 +-\n src/ipa/rpi/common/ipa_base.cpp | 18 +--\n src/ipa/rpi/pisp/pisp.cpp | 2 +-\n src/ipa/rpi/vc4/vc4.cpp | 20 +--\n src/libcamera/control_ids.cpp.in | 2 +-\n src/libcamera/control_serializer.cpp | 18 +--\n src/libcamera/controls.cpp | 162 ++++++++++-----------\n src/libcamera/debug_controls.cpp | 4 +-\n src/libcamera/ipa_controls.cpp | 2 +-\n src/libcamera/pipeline/ipu3/ipu3.cpp | 4 +-\n .../pipeline/rpi/common/delayed_controls.h | 6 +-\n .../pipeline/rpi/common/pipeline_base.cpp | 2 +-\n src/libcamera/pipeline/rpi/vc4/vc4.cpp | 4 +-\n src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 12 +-\n src/libcamera/pipeline/virtual/config_parser.cpp | 2 +-\n src/libcamera/sensor/camera_sensor_legacy.cpp | 2 +-\n src/libcamera/sensor/camera_sensor_raw.cpp | 2 +-\n src/libcamera/v4l2_device.cpp | 12 +-\n src/py/libcamera/py_helpers.cpp | 22 +--\n src/py/libcamera/py_helpers.h | 4 +-\n test/controls/control_value.cpp | 8 +-\n test/serialization/serialization_test.cpp | 8 +-\n 34 files changed, 228 insertions(+), 228 deletions(-)", "diff": "diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\nindex 6b5712339a3a1633700cc4d9741ccb8d284cffbe..bd2cb0878a8158b7d0bf2e6070539fa06c11504e 100644\n--- a/include/libcamera/control_ids.h.in\n+++ b/include/libcamera/control_ids.h.in\n@@ -45,7 +45,7 @@ enum {{ctrl.name}}Enum {\n \t{{enum.name}} = {{enum.value}},\n {%- endfor %}\n };\n-extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.name}}Values;\n+extern const std::array<const ControlStorage, {{ctrl.enum_values_count}}> {{ctrl.name}}Values;\n extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap;\n {% endif -%}\n extern const Control<{{ctrl.type}}> {{ctrl.name}};\ndiff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\nindex 3b691804fce18909fccdb420c212413a97d33be7..8c531cca25538edadd08b8e1662227ba56065e40 100644\n--- a/include/libcamera/controls.h\n+++ b/include/libcamera/controls.h\n@@ -132,17 +132,17 @@ struct control_type<T, std::enable_if_t<std::is_enum_v<T> && sizeof(T) == sizeof\n \n } /* namespace details */\n \n-class ControlValue\n+class ControlStorage\n {\n public:\n-\tControlValue();\n+\tControlStorage();\n \n #ifndef __DOXYGEN__\n \ttemplate<typename T, std::enable_if_t<!details::is_span<T>::value &&\n \t\t\t\t\t details::control_type<T>::value &&\n \t\t\t\t\t !std::is_same<std::string, std::remove_cv_t<T>>::value,\n \t\t\t\t\t std::nullptr_t> = nullptr>\n-\tControlValue(const T &value)\n+\tControlStorage(const T &value)\n \t\t: type_(ControlTypeNone), numElements_(0)\n \t{\n \t\tset(details::control_type<std::remove_cv_t<T>>::value, false,\n@@ -155,19 +155,19 @@ public:\n #else\n \ttemplate<typename T>\n #endif\n-\tControlValue(const T &value)\n+\tControlStorage(const T &value)\n \t\t: type_(ControlTypeNone), numElements_(0)\n \t{\n \t\tset(details::control_type<std::remove_cv_t<T>>::value, true,\n \t\t value.data(), value.size(), sizeof(typename T::value_type));\n \t}\n \n-\texplicit ControlValue(const ControlValueView &cvv);\n+\texplicit ControlStorage(const ControlValueView &cvv);\n \n-\t~ControlValue();\n+\t~ControlStorage();\n \n-\tControlValue(const ControlValue &other);\n-\tControlValue &operator=(const ControlValue &other);\n+\tControlStorage(const ControlStorage &other);\n+\tControlStorage &operator=(const ControlStorage &other);\n \n \tControlType type() const { return type_; }\n \tbool isNone() const { return type_ == ControlTypeNone; }\n@@ -178,8 +178,8 @@ public:\n \n \tstd::string toString() const;\n \n-\tbool operator==(const ControlValue &other) const;\n-\tbool operator!=(const ControlValue &other) const\n+\tbool operator==(const ControlStorage &other) const;\n+\tbool operator!=(const ControlStorage &other) const\n \t{\n \t\treturn !(*this == other);\n \t}\n@@ -259,7 +259,7 @@ public:\n \t{\n \t}\n \n-\tControlValueView(const ControlValue &cv) noexcept\n+\tControlValueView(const ControlStorage &cv) noexcept\n \t\t: ControlValueView(cv.type(), cv.isArray(), cv.numElements(),\n \t\t\t\t reinterpret_cast<const std::byte *>(cv.data().data()))\n \t{\n@@ -397,18 +397,18 @@ private:\n class ControlInfo\n {\n public:\n-\texplicit ControlInfo(const ControlValue &min = {},\n-\t\t\t const ControlValue &max = {},\n-\t\t\t const ControlValue &def = {});\n-\texplicit ControlInfo(Span<const ControlValue> values,\n-\t\t\t const ControlValue &def = {});\n+\texplicit ControlInfo(const ControlStorage &min = {},\n+\t\t\t const ControlStorage &max = {},\n+\t\t\t const ControlStorage &def = {});\n+\texplicit ControlInfo(Span<const ControlStorage> values,\n+\t\t\t const ControlStorage &def = {});\n \texplicit ControlInfo(std::set<bool> values, bool def);\n \texplicit ControlInfo(bool value);\n \n-\tconst ControlValue &min() const { return min_; }\n-\tconst ControlValue &max() const { return max_; }\n-\tconst ControlValue &def() const { return def_; }\n-\tconst std::vector<ControlValue> &values() const { return values_; }\n+\tconst ControlStorage &min() const { return min_; }\n+\tconst ControlStorage &max() const { return max_; }\n+\tconst ControlStorage &def() const { return def_; }\n+\tconst std::vector<ControlStorage> &values() const { return values_; }\n \n \tstd::string toString() const;\n \n@@ -423,10 +423,10 @@ public:\n \t}\n \n private:\n-\tControlValue min_;\n-\tControlValue max_;\n-\tControlValue def_;\n-\tstd::vector<ControlValue> values_;\n+\tControlStorage min_;\n+\tControlStorage max_;\n+\tControlStorage def_;\n+\tstd::vector<ControlStorage> values_;\n };\n \n using ControlIdMap = std::unordered_map<unsigned int, const ControlId *>;\n@@ -478,7 +478,7 @@ private:\n class ControlList\n {\n private:\n-\tusing ControlListMap = std::unordered_map<unsigned int, ControlValue>;\n+\tusing ControlListMap = std::unordered_map<unsigned int, ControlStorage>;\n \n public:\n \tenum class MergePolicy {\n@@ -513,14 +513,14 @@ public:\n \t\tif (entry == controls_.end())\n \t\t\treturn std::nullopt;\n \n-\t\tconst ControlValue &val = entry->second;\n+\t\tconst ControlStorage &val = entry->second;\n \t\treturn val.get<T>();\n \t}\n \n \ttemplate<typename T, typename V>\n \tvoid set(const Control<T> &ctrl, const V &value)\n \t{\n-\t\tControlValue *val = find(ctrl.id());\n+\t\tControlStorage *val = find(ctrl.id());\n \t\tif (!val)\n \t\t\treturn;\n \n@@ -530,22 +530,22 @@ public:\n \ttemplate<typename T, typename V, size_t Size>\n \tvoid set(const Control<Span<T, Size>> &ctrl, const std::initializer_list<V> &value)\n \t{\n-\t\tControlValue *val = find(ctrl.id());\n+\t\tControlStorage *val = find(ctrl.id());\n \t\tif (!val)\n \t\t\treturn;\n \n \t\tval->set(Span<const typename std::remove_cv_t<V>, Size>{ value.begin(), value.size() });\n \t}\n \n-\tconst ControlValue &get(unsigned int id) const;\n-\tvoid set(unsigned int id, const ControlValue &value);\n+\tconst ControlStorage &get(unsigned int id) const;\n+\tvoid set(unsigned int id, const ControlStorage &value);\n \n \tconst ControlInfoMap *infoMap() const { return infoMap_; }\n \tconst ControlIdMap *idMap() const { return idmap_; }\n \n private:\n-\tconst ControlValue *find(unsigned int id) const;\n-\tControlValue *find(unsigned int id);\n+\tconst ControlStorage *find(unsigned int id) const;\n+\tControlStorage *find(unsigned int id);\n \n \tconst ControlValidator *validator_;\n \tconst ControlIdMap *idmap_;\ndiff --git a/include/libcamera/internal/control_serializer.h b/include/libcamera/internal/control_serializer.h\nindex 8a63ae44a13ed6f9b8162d86eef96bbc5fa82b30..a63f8675e3076eddfdda8c7b684499237451596b 100644\n--- a/include/libcamera/internal/control_serializer.h\n+++ b/include/libcamera/internal/control_serializer.h\n@@ -41,13 +41,13 @@ public:\n \tbool isCached(const ControlInfoMap &infoMap);\n \n private:\n-\tstatic size_t binarySize(const ControlValue &value);\n+\tstatic size_t binarySize(const ControlStorage &value);\n \tstatic size_t binarySize(const ControlInfo &info);\n \n-\tstatic void store(const ControlValue &value, ByteStreamBuffer &buffer);\n+\tstatic void store(const ControlStorage &value, ByteStreamBuffer &buffer);\n \tstatic void store(const ControlInfo &info, ByteStreamBuffer &buffer);\n \n-\tControlValue loadControlValue(ByteStreamBuffer &buffer,\n+\tControlStorage loadControlValue(ByteStreamBuffer &buffer,\n \t\t\t\t bool isArray = false, unsigned int count = 1);\n \tControlInfo loadControlInfo(ByteStreamBuffer &buffer);\n \ndiff --git a/include/libcamera/internal/debug_controls.h b/include/libcamera/internal/debug_controls.h\nindex 0b049f48e246f0f857abbddfa25018e9dc3e58d1..efb5f5acb98ce39d933458e4f698029d68b9a531 100644\n--- a/include/libcamera/internal/debug_controls.h\n+++ b/include/libcamera/internal/debug_controls.h\n@@ -35,7 +35,7 @@ public:\n \t\tcache_.set(ctrl, value);\n \t}\n \n-\tvoid set(unsigned int id, const ControlValue &value);\n+\tvoid set(unsigned int id, const ControlStorage &value);\n \n private:\n \tbool enabled_ = false;\ndiff --git a/include/libcamera/internal/delayed_controls.h b/include/libcamera/internal/delayed_controls.h\nindex b64d8bba7cf73e10491d13d64bb4b3f7db80681b..edb3ef8eba0a10fa2e083a8831ee820dac1628d2 100644\n--- a/include/libcamera/internal/delayed_controls.h\n+++ b/include/libcamera/internal/delayed_controls.h\n@@ -37,7 +37,7 @@ public:\n \tvoid applyControls(uint32_t sequence);\n \n private:\n-\tclass Info : public ControlValue\n+\tclass Info : public ControlStorage\n \t{\n \tpublic:\n \t\tInfo()\n@@ -45,8 +45,8 @@ private:\n \t\t{\n \t\t}\n \n-\t\tInfo(const ControlValue &v, bool updated_ = true)\n-\t\t\t: ControlValue(v), updated(updated_)\n+\t\tInfo(const ControlStorage &v, bool updated_ = true)\n+\t\t\t: ControlStorage(v), updated(updated_)\n \t\t{\n \t\t}\n \ndiff --git a/src/apps/cam/capture_script.cpp b/src/apps/cam/capture_script.cpp\nindex fdf82efc06332b5f04f1e8cd3071bd2ec75cddde..8f713cd3c4d70ec66aedb17a8515023f3e428aac 100644\n--- a/src/apps/cam/capture_script.cpp\n+++ b/src/apps/cam/capture_script.cpp\n@@ -311,7 +311,7 @@ int CaptureScript::parseControl(EventPtr event, ControlList &controls)\n \n \tconst ControlId *controlId = it->second;\n \n-\tControlValue val = unpackControl(controlId);\n+\tControlStorage val = unpackControl(controlId);\n \tif (val.isNone()) {\n \t\tstd::cerr << \"Error unpacking control '\" << name << \"'\"\n \t\t\t << std::endl;\n@@ -332,7 +332,7 @@ std::string CaptureScript::parseScalar()\n \treturn eventScalarValue(event);\n }\n \n-ControlValue CaptureScript::parseRectangles()\n+ControlStorage CaptureScript::parseRectangles()\n {\n \tstd::vector<libcamera::Rectangle> rectangles;\n \n@@ -351,7 +351,7 @@ ControlValue CaptureScript::parseRectangles()\n \t\trectangles.push_back(rect);\n \t}\n \n-\tControlValue controlValue;\n+\tControlStorage controlValue;\n \tif (rectangles.size() == 1)\n \t\tcontrolValue.set(rectangles.at(0));\n \telse\n@@ -458,10 +458,10 @@ void CaptureScript::unpackFailure(const ControlId *id, const std::string &repr)\n \t\t << typeName << \" control \" << id->name() << std::endl;\n }\n \n-ControlValue CaptureScript::parseScalarControl(const ControlId *id,\n+ControlStorage CaptureScript::parseScalarControl(const ControlId *id,\n \t\t\t\t\t const std::string repr)\n {\n-\tControlValue value{};\n+\tControlStorage value{};\n \n \tswitch (id->type()) {\n \tcase ControlTypeNone:\n@@ -513,10 +513,10 @@ ControlValue CaptureScript::parseScalarControl(const ControlId *id,\n \treturn value;\n }\n \n-ControlValue CaptureScript::parseArrayControl(const ControlId *id,\n+ControlStorage CaptureScript::parseArrayControl(const ControlId *id,\n \t\t\t\t\t const std::vector<std::string> &repr)\n {\n-\tControlValue value{};\n+\tControlStorage value{};\n \n \tswitch (id->type()) {\n \tcase ControlTypeNone:\n@@ -586,7 +586,7 @@ ControlValue CaptureScript::parseArrayControl(const ControlId *id,\n \treturn value;\n }\n \n-ControlValue CaptureScript::unpackControl(const ControlId *id)\n+ControlStorage CaptureScript::unpackControl(const ControlId *id)\n {\n \t/* Parse complex types. */\n \tswitch (id->type()) {\ndiff --git a/src/apps/cam/capture_script.h b/src/apps/cam/capture_script.h\nindex 294b920363bae01b55bd91343f94a71e31168b3b..8b7aeb1ca79f192d33e7f6a70a8a79494711fe37 100644\n--- a/src/apps/cam/capture_script.h\n+++ b/src/apps/cam/capture_script.h\n@@ -56,18 +56,18 @@ private:\n \tint parseFrame(EventPtr event);\n \tint parseControl(EventPtr event, libcamera::ControlList &controls);\n \n-\tlibcamera::ControlValue parseScalarControl(const libcamera::ControlId *id,\n+\tlibcamera::ControlStorage parseScalarControl(const libcamera::ControlId *id,\n \t\t\t\t\t\t const std::string repr);\n-\tlibcamera::ControlValue parseArrayControl(const libcamera::ControlId *id,\n+\tlibcamera::ControlStorage parseArrayControl(const libcamera::ControlId *id,\n \t\t\t\t\t\t const std::vector<std::string> &repr);\n \n \tstd::string parseScalar();\n-\tlibcamera::ControlValue parseRectangles();\n+\tlibcamera::ControlStorage parseRectangles();\n \tstd::vector<std::vector<std::string>> parseArrays();\n \tstd::vector<std::string> parseSingleArray();\n \n \tvoid unpackFailure(const libcamera::ControlId *id,\n \t\t\t const std::string &repr);\n-\tlibcamera::ControlValue unpackControl(const libcamera::ControlId *id);\n+\tlibcamera::ControlStorage unpackControl(const libcamera::ControlId *id);\n \tlibcamera::Rectangle unpackRectangle(const std::vector<std::string> &strVec);\n };\ndiff --git a/src/gstreamer/gstlibcamera-controls.cpp.in b/src/gstreamer/gstlibcamera-controls.cpp.in\nindex 2a16b39a93d95938022b38c57aab74efa10678cf..346bf83fac076c8fa7c7d6f8a9b281626849aaa1 100644\n--- a/src/gstreamer/gstlibcamera-controls.cpp.in\n+++ b/src/gstreamer/gstlibcamera-controls.cpp.in\n@@ -159,7 +159,7 @@ bool GstCameraControls::getProperty(guint propId, GValue *value,\n \t\t\t controls::controls.at(propId)->name().c_str());\n \t\treturn true;\n \t}\n-\tconst ControlValue &cv = controls_acc_.get(propId);\n+\tconst ControlStorage &cv = controls_acc_.get(propId);\n \n \tswitch (propId) {\n {%- for vendor, ctrls in controls %}\n@@ -296,7 +296,7 @@ void GstCameraControls::setCamera(const std::shared_ptr<libcamera::Camera> &cam)\n \t control != controls_acc_.end();\n \t ++control) {\n \t\tunsigned int id = control->first;\n-\t\tControlValue value = control->second;\n+\t\tControlStorage value = control->second;\n \n \t\tconst ControlId *cid = capabilities_.idmap().at(id);\n \t\tauto info = capabilities_.find(cid);\ndiff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp\nindex ff96a381ffce9fe67a259a60e0382d61cf423bc6..29d679d7d3bdd4fbbb9b2759c5dff3ad70ca664c 100644\n--- a/src/ipa/libipa/agc_mean_luminance.cpp\n+++ b/src/ipa/libipa/agc_mean_luminance.cpp\n@@ -186,7 +186,7 @@ void AgcMeanLuminance::parseConstraint(const YamlObject &modeDict, int32_t id)\n \n int AgcMeanLuminance::parseConstraintModes(const YamlObject &tuningData)\n {\n-\tstd::vector<ControlValue> availableConstraintModes;\n+\tstd::vector<ControlStorage> availableConstraintModes;\n \n \tconst YamlObject &yamlConstraintModes = tuningData[controls::AeConstraintMode.name()];\n \tif (yamlConstraintModes.isDictionary()) {\n@@ -238,7 +238,7 @@ int AgcMeanLuminance::parseConstraintModes(const YamlObject &tuningData)\n \n int AgcMeanLuminance::parseExposureModes(const YamlObject &tuningData)\n {\n-\tstd::vector<ControlValue> availableExposureModes;\n+\tstd::vector<ControlStorage> availableExposureModes;\n \n \tconst YamlObject &yamlExposureModes = tuningData[controls::AeExposureMode.name()];\n \tif (yamlExposureModes.isDictionary()) {\ndiff --git a/src/ipa/libipa/awb.cpp b/src/ipa/libipa/awb.cpp\nindex 214bac8b56a6ca7b0ac9954f0aa742cd613e6141..5e0defd8badbc9a559d8fe31f3e7080c982bde99 100644\n--- a/src/ipa/libipa/awb.cpp\n+++ b/src/ipa/libipa/awb.cpp\n@@ -163,9 +163,9 @@ namespace ipa {\n * \\return Zero on success, negative error code otherwise\n */\n int AwbAlgorithm::parseModeConfigs(const YamlObject &tuningData,\n-\t\t\t\t const ControlValue &def)\n+\t\t\t\t const ControlStorage &def)\n {\n-\tstd::vector<ControlValue> availableModes;\n+\tstd::vector<ControlStorage> availableModes;\n \n \tconst YamlObject &yamlModes = tuningData[controls::AwbMode.name()];\n \tif (!yamlModes.isDictionary()) {\ndiff --git a/src/ipa/libipa/awb.h b/src/ipa/libipa/awb.h\nindex f4a86038635f984ac03b1e466c0fcd4e6d5e22bd..8d126242859b4a9296ec412a2681537d73223118 100644\n--- a/src/ipa/libipa/awb.h\n+++ b/src/ipa/libipa/awb.h\n@@ -51,7 +51,7 @@ public:\n \n protected:\n \tint parseModeConfigs(const YamlObject &tuningData,\n-\t\t\t const ControlValue &def = {});\n+\t\t\t const ControlStorage &def = {});\n \n \tstruct ModeConfig {\n \t\tdouble ctHi;\ndiff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp\nindex 35440b67e999b7a307c9ca7cc32fffd6cafb168b..284f83f5256b2a275451f94a38d9142e422e7a1c 100644\n--- a/src/ipa/rkisp1/algorithms/agc.cpp\n+++ b/src/ipa/rkisp1/algorithms/agc.cpp\n@@ -73,11 +73,11 @@ int Agc::parseMeteringModes(IPAContext &context, const YamlObject &tuningData)\n \t\tmeteringModes_[controls::MeteringMatrix] = weights;\n \t}\n \n-\tstd::vector<ControlValue> meteringModes;\n+\tstd::vector<ControlStorage> meteringModes;\n \tstd::vector<int> meteringModeKeys = utils::map_keys(meteringModes_);\n \tstd::transform(meteringModeKeys.begin(), meteringModeKeys.end(),\n \t\t std::back_inserter(meteringModes),\n-\t\t [](int x) { return ControlValue(x); });\n+\t\t [](int x) { return ControlStorage(x); });\n \tcontext.ctrlMap[&controls::AeMeteringMode] = ControlInfo(meteringModes);\n \n \treturn 0;\n@@ -148,13 +148,13 @@ int Agc::init(IPAContext &context, const YamlObject &tuningData)\n \t\treturn ret;\n \n \tcontext.ctrlMap[&controls::ExposureTimeMode] =\n-\t\tControlInfo({ { ControlValue(controls::ExposureTimeModeAuto),\n-\t\t\t\tControlValue(controls::ExposureTimeModeManual) } },\n-\t\t\t ControlValue(controls::ExposureTimeModeAuto));\n+\t\tControlInfo({ { ControlStorage(controls::ExposureTimeModeAuto),\n+\t\t\t\tControlStorage(controls::ExposureTimeModeManual) } },\n+\t\t\t ControlStorage(controls::ExposureTimeModeAuto));\n \tcontext.ctrlMap[&controls::AnalogueGainMode] =\n-\t\tControlInfo({ { ControlValue(controls::AnalogueGainModeAuto),\n-\t\t\t\tControlValue(controls::AnalogueGainModeManual) } },\n-\t\t\t ControlValue(controls::AnalogueGainModeAuto));\n+\t\tControlInfo({ { ControlStorage(controls::AnalogueGainModeAuto),\n+\t\t\t\tControlStorage(controls::AnalogueGainModeManual) } },\n+\t\t\t ControlStorage(controls::AnalogueGainModeAuto));\n \t/* \\todo Move this to the Camera class */\n \tcontext.ctrlMap[&controls::AeEnable] = ControlInfo(false, true, true);\n \tcontext.ctrlMap[&controls::ExposureValue] = ControlInfo(-8.0f, 8.0f, 0.0f);\ndiff --git a/src/ipa/rkisp1/algorithms/ccm.cpp b/src/ipa/rkisp1/algorithms/ccm.cpp\nindex de2b6fe775aa7cb3a9a9d73f1c56ca58fde22e64..f709adad2bd85c88fc57aa801c60764dcb628b64 100644\n--- a/src/ipa/rkisp1/algorithms/ccm.cpp\n+++ b/src/ipa/rkisp1/algorithms/ccm.cpp\n@@ -45,9 +45,9 @@ int Ccm::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData\n {\n \tauto &cmap = context.ctrlMap;\n \tcmap[&controls::ColourCorrectionMatrix] = ControlInfo(\n-\t\tControlValue(-8.0f),\n-\t\tControlValue(7.993f),\n-\t\tControlValue(kIdentity3x3.data()));\n+\t\tControlStorage(-8.0f),\n+\t\tControlStorage(7.993f),\n+\t\tControlStorage(kIdentity3x3.data()));\n \n \tint ret = ccm_.readYaml(tuningData[\"ccms\"], \"ct\", \"ccm\");\n \tif (ret < 0) {\ndiff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp\nindex ce2343e91cdee92776f7d4a36de6d107c47ce0ac..532cc3f89463775943c389bd70b1cd9a491c2f53 100644\n--- a/src/ipa/rpi/common/ipa_base.cpp\n+++ b/src/ipa/rpi/common/ipa_base.cpp\n@@ -58,24 +58,24 @@ const ControlInfoMap::Map ipaControls{\n \t/* \\todo Move this to the Camera class */\n \t{ &controls::AeEnable, ControlInfo(false, true, true) },\n \t{ &controls::ExposureTimeMode,\n-\t ControlInfo({ { ControlValue(controls::ExposureTimeModeAuto),\n-\t\t\t ControlValue(controls::ExposureTimeModeManual) } },\n-\t\t ControlValue(controls::ExposureTimeModeAuto)) },\n+\t ControlInfo({ { ControlStorage(controls::ExposureTimeModeAuto),\n+\t\t\t ControlStorage(controls::ExposureTimeModeManual) } },\n+\t\t ControlStorage(controls::ExposureTimeModeAuto)) },\n \t{ &controls::ExposureTime,\n \t ControlInfo(1, 66666, static_cast<int32_t>(defaultExposureTime.get<std::micro>())) },\n \t{ &controls::AnalogueGainMode,\n-\t ControlInfo({ { ControlValue(controls::AnalogueGainModeAuto),\n-\t\t\t ControlValue(controls::AnalogueGainModeManual) } },\n-\t\t ControlValue(controls::AnalogueGainModeAuto)) },\n+\t ControlInfo({ { ControlStorage(controls::AnalogueGainModeAuto),\n+\t\t\t ControlStorage(controls::AnalogueGainModeManual) } },\n+\t\t ControlStorage(controls::AnalogueGainModeAuto)) },\n \t{ &controls::AnalogueGain, ControlInfo(1.0f, 16.0f, 1.0f) },\n \t{ &controls::AeMeteringMode, ControlInfo(controls::AeMeteringModeValues) },\n \t{ &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) },\n \t{ &controls::AeExposureMode, ControlInfo(controls::AeExposureModeValues) },\n \t{ &controls::ExposureValue, ControlInfo(-8.0f, 8.0f, 0.0f) },\n \t{ &controls::AeFlickerMode,\n-\t ControlInfo({ { ControlValue(controls::FlickerOff),\n-\t\t\t ControlValue(controls::FlickerManual) } },\n-\t\t ControlValue(controls::FlickerOff)) },\n+\t ControlInfo({ { ControlStorage(controls::FlickerOff),\n+\t\t\t ControlStorage(controls::FlickerManual) } },\n+\t\t ControlStorage(controls::FlickerOff)) },\n \t{ &controls::AeFlickerPeriod, ControlInfo(100, 1000000) },\n \t{ &controls::Brightness, ControlInfo(-1.0f, 1.0f, 0.0f) },\n \t{ &controls::Contrast, ControlInfo(0.0f, 32.0f, 1.0f) },\ndiff --git a/src/ipa/rpi/pisp/pisp.cpp b/src/ipa/rpi/pisp/pisp.cpp\nindex 829b912585223a0296a9709aca433d5240caea1b..e793998cbee506af437ebe283853ecc5e7fd3924 100644\n--- a/src/ipa/rpi/pisp/pisp.cpp\n+++ b/src/ipa/rpi/pisp/pisp.cpp\n@@ -927,7 +927,7 @@ void IpaPiSP::applyFocusStats(const NoiseStatus *noiseStatus)\n void IpaPiSP::applyAF(const struct AfStatus *afStatus, ControlList &lensCtrls)\n {\n \tif (afStatus->lensSetting) {\n-\t\tControlValue v(afStatus->lensSetting.value());\n+\t\tControlStorage v(afStatus->lensSetting.value());\n \t\tlensCtrls.set(V4L2_CID_FOCUS_ABSOLUTE, v);\n \t}\n }\ndiff --git a/src/ipa/rpi/vc4/vc4.cpp b/src/ipa/rpi/vc4/vc4.cpp\nindex b2fec934480487c0c0566d510afd7a72129e441c..250426a3bae2e3ec89349f73490c9d859bfeaaa0 100644\n--- a/src/ipa/rpi/vc4/vc4.cpp\n+++ b/src/ipa/rpi/vc4/vc4.cpp\n@@ -369,7 +369,7 @@ void IpaVc4::applyCCM(const struct CcmStatus *ccmStatus, ControlList &ctrls)\n \tccm.enabled = 1;\n \tccm.ccm.offsets[0] = ccm.ccm.offsets[1] = ccm.ccm.offsets[2] = 0;\n \n-\tControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&ccm),\n+\tControlStorage c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&ccm),\n \t\t\t\t\t sizeof(ccm) });\n \tctrls.set(V4L2_CID_USER_BCM2835_ISP_CC_MATRIX, c);\n }\n@@ -383,7 +383,7 @@ void IpaVc4::applyBlackLevel(const struct BlackLevelStatus *blackLevelStatus, Co\n \tblackLevel.black_level_g = blackLevelStatus->blackLevelG;\n \tblackLevel.black_level_b = blackLevelStatus->blackLevelB;\n \n-\tControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&blackLevel),\n+\tControlStorage c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&blackLevel),\n \t\t\t\t\t sizeof(blackLevel) });\n \tctrls.set(V4L2_CID_USER_BCM2835_ISP_BLACK_LEVEL, c);\n }\n@@ -405,7 +405,7 @@ void IpaVc4::applyGamma(const struct ContrastStatus *contrastStatus, ControlList\n \tgamma.y[numGammaPoints - 1] = 65535;\n \tgamma.enabled = 1;\n \n-\tControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&gamma),\n+\tControlStorage c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&gamma),\n \t\t\t\t\t sizeof(gamma) });\n \tctrls.set(V4L2_CID_USER_BCM2835_ISP_GAMMA, c);\n }\n@@ -419,7 +419,7 @@ void IpaVc4::applyGEQ(const struct GeqStatus *geqStatus, ControlList &ctrls)\n \tgeq.slope.den = 1000;\n \tgeq.slope.num = 1000 * geqStatus->slope;\n \n-\tControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&geq),\n+\tControlStorage c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&geq),\n \t\t\t\t\t sizeof(geq) });\n \tctrls.set(V4L2_CID_USER_BCM2835_ISP_GEQ, c);\n }\n@@ -453,11 +453,11 @@ void IpaVc4::applyDenoise(const struct DenoiseStatus *denoiseStatus, ControlList\n \t\tcdn.enabled = 0;\n \t}\n \n-\tControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&denoise),\n+\tControlStorage c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&denoise),\n \t\t\t\t\t sizeof(denoise) });\n \tctrls.set(V4L2_CID_USER_BCM2835_ISP_DENOISE, c);\n \n-\tc = ControlValue(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&cdn),\n+\tc = ControlStorage(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&cdn),\n \t\t\t\t\t sizeof(cdn) });\n \tctrls.set(V4L2_CID_USER_BCM2835_ISP_CDN, c);\n }\n@@ -474,7 +474,7 @@ void IpaVc4::applySharpen(const struct SharpenStatus *sharpenStatus, ControlList\n \tsharpen.limit.num = 1000 * sharpenStatus->limit;\n \tsharpen.limit.den = 1000;\n \n-\tControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&sharpen),\n+\tControlStorage c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&sharpen),\n \t\t\t\t\t sizeof(sharpen) });\n \tctrls.set(V4L2_CID_USER_BCM2835_ISP_SHARPEN, c);\n }\n@@ -486,7 +486,7 @@ void IpaVc4::applyDPC(const struct DpcStatus *dpcStatus, ControlList &ctrls)\n \tdpc.enabled = 1;\n \tdpc.strength = dpcStatus->strength;\n \n-\tControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&dpc),\n+\tControlStorage c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&dpc),\n \t\t\t\t\t sizeof(dpc) });\n \tctrls.set(V4L2_CID_USER_BCM2835_ISP_DPC, c);\n }\n@@ -543,7 +543,7 @@ void IpaVc4::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls)\n \t\tresampleTable(grid + 3 * w * h, lsStatus->b, w, h);\n \t}\n \n-\tControlValue c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&ls),\n+\tControlStorage c(Span<const uint8_t>{ reinterpret_cast<uint8_t *>(&ls),\n \t\t\t\t\t sizeof(ls) });\n \tctrls.set(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING, c);\n }\n@@ -551,7 +551,7 @@ void IpaVc4::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls)\n void IpaVc4::applyAF(const struct AfStatus *afStatus, ControlList &lensCtrls)\n {\n \tif (afStatus->lensSetting) {\n-\t\tControlValue v(afStatus->lensSetting.value());\n+\t\tControlStorage v(afStatus->lensSetting.value());\n \t\tlensCtrls.set(V4L2_CID_FOCUS_ABSOLUTE, v);\n \t}\n }\ndiff --git a/src/libcamera/control_ids.cpp.in b/src/libcamera/control_ids.cpp.in\nindex 65668d486dbc1be5f8af241dc6dc2f6d963bd29c..dcfd8ba240189dcc52e36d3d567fde13ae374dd4 100644\n--- a/src/libcamera/control_ids.cpp.in\n+++ b/src/libcamera/control_ids.cpp.in\n@@ -79,7 +79,7 @@ namespace {{vendor}} {\n \n {%- for ctrl in ctrls %}\n {% if ctrl.is_enum -%}\n-extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.name}}Values = {\n+extern const std::array<const ControlStorage, {{ctrl.enum_values_count}}> {{ctrl.name}}Values = {\n {%- for enum in ctrl.enum_values %}\n \tstatic_cast<{{ctrl.type}}>({{enum.name}}),\n {%- endfor %}\ndiff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp\nindex 050f8512bd5285609da6cc12a989e1ea1bac418d..df8bcd8a938c6fd3db252ae56673483fa9923b7d 100644\n--- a/src/libcamera/control_serializer.cpp\n+++ b/src/libcamera/control_serializer.cpp\n@@ -36,7 +36,7 @@ LOG_DEFINE_CATEGORY(Serializer)\n * \\brief Serializer and deserializer for control-related classes\n *\n * The control serializer is a helper to serialize and deserialize\n- * ControlInfoMap and ControlValue instances for the purpose of communication\n+ * ControlInfoMap and ControlStorage instances for the purpose of communication\n * with IPA modules.\n *\n * Neither the ControlInfoMap nor the ControlList are self-contained data\n@@ -142,7 +142,7 @@ void ControlSerializer::reset()\n \tcontrolIdMaps_.clear();\n }\n \n-size_t ControlSerializer::binarySize(const ControlValue &value)\n+size_t ControlSerializer::binarySize(const ControlStorage &value)\n {\n \treturn sizeof(ControlType) + value.data().size_bytes();\n }\n@@ -192,7 +192,7 @@ size_t ControlSerializer::binarySize(const ControlList &list)\n \treturn size;\n }\n \n-void ControlSerializer::store(const ControlValue &value,\n+void ControlSerializer::store(const ControlStorage &value,\n \t\t\t ByteStreamBuffer &buffer)\n {\n \tconst ControlType type = value.type();\n@@ -363,7 +363,7 @@ int ControlSerializer::serialize(const ControlList &list,\n \t/* Serialize all entries. */\n \tfor (const auto &ctrl : list) {\n \t\tunsigned int id = ctrl.first;\n-\t\tconst ControlValue &value = ctrl.second;\n+\t\tconst ControlStorage &value = ctrl.second;\n \n \t\tstruct ipa_control_value_entry entry;\n \t\tentry.id = id;\n@@ -382,14 +382,14 @@ int ControlSerializer::serialize(const ControlList &list,\n \treturn 0;\n }\n \n-ControlValue ControlSerializer::loadControlValue(ByteStreamBuffer &buffer,\n+ControlStorage ControlSerializer::loadControlValue(ByteStreamBuffer &buffer,\n \t\t\t\t\t\t bool isArray,\n \t\t\t\t\t\t unsigned int count)\n {\n \tControlType type;\n \tbuffer.read(&type);\n \n-\tControlValue value;\n+\tControlStorage value;\n \n \tvalue.reserve(type, isArray, count);\n \tbuffer.read(value.data());\n@@ -399,9 +399,9 @@ ControlValue ControlSerializer::loadControlValue(ByteStreamBuffer &buffer,\n \n ControlInfo ControlSerializer::loadControlInfo(ByteStreamBuffer &b)\n {\n-\tControlValue min = loadControlValue(b);\n-\tControlValue max = loadControlValue(b);\n-\tControlValue def = loadControlValue(b);\n+\tControlStorage min = loadControlValue(b);\n+\tControlStorage max = loadControlValue(b);\n+\tControlStorage def = loadControlValue(b);\n \n \treturn ControlInfo(min, max, def);\n }\ndiff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\nindex a238141a5c34856242bed7f76e938e706d49f1ff..cdc4f12d1048d58c558feaa8a17b25814d2dae13 100644\n--- a/src/libcamera/controls.cpp\n+++ b/src/libcamera/controls.cpp\n@@ -91,44 +91,44 @@ static constexpr size_t ControlValueSize[] = {\n */\n \n /**\n- * \\class ControlValue\n+ * \\class ControlStorage\n * \\brief Abstract type representing the value of a control\n */\n \n-/** \\todo Revisit the ControlValue layout when stabilizing the ABI */\n-static_assert(sizeof(ControlValue) == 16, \"Invalid size of ControlValue class\");\n+/** \\todo Revisit the ControlStorage layout when stabilizing the ABI */\n+static_assert(sizeof(ControlStorage) == 16, \"Invalid size of ControlStorage class\");\n \n /**\n- * \\brief Construct an empty ControlValue.\n+ * \\brief Construct an empty ControlStorage\n */\n-ControlValue::ControlValue()\n+ControlStorage::ControlStorage()\n \t: type_(ControlTypeNone), isArray_(false), numElements_(0)\n {\n }\n \n /**\n- * \\brief Construct a ControlValue from a ControlValueView\n+ * \\brief Construct a ControlStorage from a ControlValueView\n */\n-ControlValue::ControlValue(const ControlValueView &cvv)\n-\t: ControlValue()\n+ControlStorage::ControlStorage(const ControlValueView &cvv)\n+\t: ControlStorage()\n {\n \tset(cvv.type(), cvv.isArray(), cvv.data().data(),\n \t cvv.numElements(), ControlValueSize[cvv.type()]);\n }\n \n /**\n- * \\fn template<typename T> T ControlValue::ControlValue(const T &value)\n- * \\brief Construct a ControlValue of type T\n+ * \\fn template<typename T> T ControlStorage::ControlStorage(const T &value)\n+ * \\brief Construct a ControlStorage of type T\n * \\param[in] value Initial value\n *\n- * This function constructs a new instance of ControlValue and stores the \\a\n+ * This function constructs a new instance of ControlStorage and stores the \\a\n * value inside it. If the type \\a T is equivalent to Span<R>, the instance\n * stores an array of values of type \\a R. Otherwise the instance stores a\n * single value of type \\a T. The numElements() and type() are updated to\n * reflect the stored value.\n */\n \n-void ControlValue::release()\n+void ControlStorage::release()\n {\n \tstd::size_t size = numElements_ * ControlValueSize[type_];\n \n@@ -138,28 +138,28 @@ void ControlValue::release()\n \t}\n }\n \n-ControlValue::~ControlValue()\n+ControlStorage::~ControlStorage()\n {\n \trelease();\n }\n \n /**\n- * \\brief Construct a ControlValue with the content of \\a other\n- * \\param[in] other The ControlValue to copy content from\n+ * \\brief Construct a ControlStorage with the content of \\a other\n+ * \\param[in] other The ControlStorage to copy content from\n */\n-ControlValue::ControlValue(const ControlValue &other)\n+ControlStorage::ControlStorage(const ControlStorage &other)\n \t: type_(ControlTypeNone), numElements_(0)\n {\n \t*this = other;\n }\n \n /**\n- * \\brief Replace the content of the ControlValue with a copy of the content\n+ * \\brief Replace the content of the ControlStorage with a copy of the content\n * of \\a other\n- * \\param[in] other The ControlValue to copy content from\n- * \\return The ControlValue with its content replaced with the one of \\a other\n+ * \\param[in] other The ControlStorage to copy content from\n+ * \\return The ControlStorage with its content replaced with the one of \\a other\n */\n-ControlValue &ControlValue::operator=(const ControlValue &other)\n+ControlStorage &ControlStorage::operator=(const ControlStorage &other)\n {\n \tset(other.type_, other.isArray_, other.data().data(),\n \t other.numElements_, ControlValueSize[other.type_]);\n@@ -167,39 +167,39 @@ ControlValue &ControlValue::operator=(const ControlValue &other)\n }\n \n /**\n- * \\fn ControlValue::type()\n+ * \\fn ControlStorage::type()\n * \\brief Retrieve the data type of the value\n * \\return The value data type\n */\n \n /**\n- * \\fn ControlValue::isNone()\n+ * \\fn ControlStorage::isNone()\n * \\brief Determine if the value is not initialised\n * \\return True if the value type is ControlTypeNone, false otherwise\n */\n \n /**\n- * \\fn ControlValue::isArray()\n+ * \\fn ControlStorage::isArray()\n * \\brief Determine if the value stores an array\n * \\return True if the value stores an array, false otherwise\n */\n \n /**\n- * \\fn ControlValue::numElements()\n- * \\brief Retrieve the number of elements stored in the ControlValue\n+ * \\fn ControlStorage::numElements()\n+ * \\brief Retrieve the number of elements stored in the ControlStorage\n *\n * For instances storing an array, this function returns the number of elements\n * in the array. For instances storing a string, it returns the length of the\n * string, not counting the terminating '\\0'. Otherwise, it returns 1.\n *\n- * \\return The number of elements stored in the ControlValue\n+ * \\return The number of elements stored in the ControlStorage\n */\n \n /**\n * \\brief Retrieve the raw data of a control value\n * \\return The raw data of the control value as a span of uint8_t\n */\n-Span<const uint8_t> ControlValue::data() const\n+Span<const uint8_t> ControlStorage::data() const\n {\n \tstd::size_t size = numElements_ * ControlValueSize[type_];\n \tconst uint8_t *data = size > sizeof(value_)\n@@ -209,28 +209,28 @@ Span<const uint8_t> ControlValue::data() const\n }\n \n /**\n- * \\copydoc ControlValue::data() const\n+ * \\copydoc ControlStorage::data() const\n */\n-Span<uint8_t> ControlValue::data()\n+Span<uint8_t> ControlStorage::data()\n {\n-\tSpan<const uint8_t> data = const_cast<const ControlValue *>(this)->data();\n+\tSpan<const uint8_t> data = const_cast<const ControlStorage *>(this)->data();\n \treturn { const_cast<uint8_t *>(data.data()), data.size() };\n }\n \n /**\n * \\brief Assemble and return a string describing the value\n- * \\return A string describing the ControlValue\n+ * \\return A string describing the ControlStorage\n */\n-std::string ControlValue::toString() const\n+std::string ControlStorage::toString() const\n {\n \treturn static_cast<std::ostringstream&&>(std::ostringstream{} << ControlValueView(*this)).str();\n }\n \n /**\n- * \\brief Compare ControlValue instances for equality\n+ * \\brief Compare ControlStorage instances for equality\n * \\return True if the values have identical types and values, false otherwise\n */\n-bool ControlValue::operator==(const ControlValue &other) const\n+bool ControlStorage::operator==(const ControlStorage &other) const\n {\n \tif (type_ != other.type_)\n \t\treturn false;\n@@ -245,22 +245,22 @@ bool ControlValue::operator==(const ControlValue &other) const\n }\n \n /**\n- * \\fn bool ControlValue::operator!=()\n- * \\brief Compare ControlValue instances for non equality\n+ * \\fn bool ControlStorage::operator!=()\n+ * \\brief Compare ControlStorage instances for non equality\n * \\return False if the values have identical types and values, true otherwise\n */\n \n /**\n- * \\fn template<typename T> T ControlValue::get() const\n+ * \\fn template<typename T> T ControlStorage::get() const\n * \\brief Get the control value\n *\n * This function returns the contained value as an instance of \\a T. If the\n- * ControlValue instance stores a single value, the type \\a T shall match the\n+ * ControlStorage instance stores a single value, the type \\a T shall match the\n * stored value type(). If the instance stores an array of values, the type\n * \\a T should be equal to Span<const R>, and the type \\a R shall match the\n * stored value type(). The behaviour is undefined otherwise.\n *\n- * Note that a ControlValue instance that stores a non-array value is not\n+ * Note that a ControlStorage instance that stores a non-array value is not\n * equivalent to an instance that stores an array value containing a single\n * element. The latter shall be accessed through a Span<const R> type, while\n * the former shall be accessed through a type \\a T corresponding to type().\n@@ -269,7 +269,7 @@ bool ControlValue::operator==(const ControlValue &other) const\n */\n \n /**\n- * \\fn template<typename T> void ControlValue::set(const T &value)\n+ * \\fn template<typename T> void ControlStorage::set(const T &value)\n * \\brief Set the control value to \\a value\n * \\param[in] value The control value\n *\n@@ -283,14 +283,14 @@ bool ControlValue::operator==(const ControlValue &other) const\n * operation for Span<> values that refer to large arrays.\n */\n \n-void ControlValue::set(ControlType type, bool isArray, const void *data,\n+void ControlStorage::set(ControlType type, bool isArray, const void *data,\n \t\t std::size_t numElements, std::size_t elementSize)\n {\n \tASSERT(elementSize == ControlValueSize[type]);\n \n \treserve(type, isArray, numElements);\n \n-\tSpan<uint8_t> storage = ControlValue::data();\n+\tSpan<uint8_t> storage = ControlStorage::data();\n \tmemcpy(storage.data(), data, storage.size());\n }\n \n@@ -306,7 +306,7 @@ void ControlValue::set(ControlType type, bool isArray, const void *data,\n * Otherwise the instance becomes a simple control, numElements is ignored, and\n * storage for the single element is reserved.\n */\n-void ControlValue::reserve(ControlType type, bool isArray, std::size_t numElements)\n+void ControlStorage::reserve(ControlType type, bool isArray, std::size_t numElements)\n {\n \tif (!isArray)\n \t\tnumElements = 1;\n@@ -336,17 +336,17 @@ void ControlValue::reserve(ControlType type, bool isArray, std::size_t numElemen\n /**\n * \\fn ControlValueView::ControlValueView()\n * \\brief Construct an empty view\n- * \\sa ControlValue::ControlValue()\n+ * \\sa ControlStorage::ControlStorage()\n */\n \n /**\n- * \\fn ControlValueView::ControlValueView(const ControlValue &v)\n+ * \\fn ControlValueView::ControlValueView(const ControlStorage &v)\n * \\brief Construct a view referring to \\a v\n *\n * The constructed view will refer to the value stored by \\a v, and\n * thus \\a v must not be modified or destroyed before the view.\n *\n- * \\sa ControlValue::ControlValue()\n+ * \\sa ControlStorage::ControlStorage()\n */\n \n /**\n@@ -357,31 +357,31 @@ void ControlValue::reserve(ControlType type, bool isArray, std::size_t numElemen\n \n /**\n * \\fn ControlType ControlValueView::type() const\n- * \\copydoc ControlValue::type()\n- * \\sa ControlValue::type()\n+ * \\copydoc ControlStorage::type()\n+ * \\sa ControlStorage::type()\n */\n \n /**\n * \\fn ControlValueView::isNone() const\n- * \\copydoc ControlValue::isNone()\n- * \\sa ControlValue::isNone()\n+ * \\copydoc ControlStorage::isNone()\n+ * \\sa ControlStorage::isNone()\n */\n \n /**\n * \\fn ControlValueView::isArray() const\n- * \\copydoc ControlValue::isArray()\n- * \\sa ControlValue::isArray()\n+ * \\copydoc ControlStorage::isArray()\n+ * \\sa ControlStorage::isArray()\n */\n \n /**\n * \\fn ControlValueView::numElements() const\n- * \\copydoc ControlValue::numElements()\n- * \\sa ControlValue::numElements()\n+ * \\copydoc ControlStorage::numElements()\n+ * \\sa ControlStorage::numElements()\n */\n \n /**\n- * \\copydoc ControlValue::data()\n- * \\sa ControlValue::data()\n+ * \\copydoc ControlStorage::data()\n+ * \\sa ControlStorage::data()\n */\n Span<const std::byte> ControlValueView::data() const\n {\n@@ -389,8 +389,8 @@ Span<const std::byte> ControlValueView::data() const\n }\n \n /**\n- * \\copydoc ControlValue::operator==()\n- * \\sa ControlValue::operator==()\n+ * \\copydoc ControlStorage::operator==()\n+ * \\sa ControlStorage::operator==()\n * \\sa ControlValueView::operator!=()\n */\n bool ControlValueView::operator==(const ControlValueView &other) const\n@@ -411,20 +411,20 @@ bool ControlValueView::operator==(const ControlValueView &other) const\n \n /**\n * \\fn ControlValueView::operator!=() const\n- * \\copydoc ControlValue::operator!=()\n- * \\sa ControlValue::operator!=()\n+ * \\copydoc ControlStorage::operator!=()\n+ * \\sa ControlStorage::operator!=()\n * \\sa ControlValueView::operator==()\n */\n \n /**\n * \\fn template<typename T> T ControlValueView::get() const\n- * \\copydoc ControlValue::get()\n- * \\sa ControlValue::get()\n+ * \\copydoc ControlStorage::get()\n+ * \\sa ControlStorage::get()\n */\n \n /**\n * \\brief Insert a text representation of a value into an output stream\n- * \\sa ControlValue::toString()\n+ * \\sa ControlStorage::toString()\n */\n std::ostream &operator<<(std::ostream &s, const ControlValueView &v)\n {\n@@ -713,9 +713,9 @@ ControlId::ControlId(unsigned int id, const std::string &name,\n * \\param[in] max The control maximum value\n * \\param[in] def The control default value\n */\n-ControlInfo::ControlInfo(const ControlValue &min,\n-\t\t\t const ControlValue &max,\n-\t\t\t const ControlValue &def)\n+ControlInfo::ControlInfo(const ControlStorage &min,\n+\t\t\t const ControlStorage &max,\n+\t\t\t const ControlStorage &def)\n \t: min_(min), max_(max), def_(def)\n {\n }\n@@ -730,15 +730,15 @@ ControlInfo::ControlInfo(const ControlValue &min,\n * values list respectively. The default value is set to \\a def if provided, or\n * to the minimum value otherwise.\n */\n-ControlInfo::ControlInfo(Span<const ControlValue> values,\n-\t\t\t const ControlValue &def)\n+ControlInfo::ControlInfo(Span<const ControlStorage> values,\n+\t\t\t const ControlStorage &def)\n {\n \tmin_ = values.front();\n \tmax_ = values.back();\n \tdef_ = !def.isNone() ? def : values.front();\n \n \tvalues_.reserve(values.size());\n-\tfor (const ControlValue &value : values)\n+\tfor (const ControlStorage &value : values)\n \t\tvalues_.push_back(value);\n }\n \n@@ -779,7 +779,7 @@ ControlInfo::ControlInfo(bool value)\n * the terminating '\\0'. For all other control types, this is the minimum value\n * of each element.\n *\n- * \\return A ControlValue with the minimum value for the control\n+ * \\return A ControlStorage with the minimum value for the control\n */\n \n /**\n@@ -790,13 +790,13 @@ ControlInfo::ControlInfo(bool value)\n * the terminating '\\0'. For all other control types, this is the maximum value\n * of each element.\n *\n- * \\return A ControlValue with the maximum value for the control\n+ * \\return A ControlStorage with the maximum value for the control\n */\n \n /**\n * \\fn ControlInfo::def()\n * \\brief Retrieve the default value of the control\n- * \\return A ControlValue with the default value for the control\n+ * \\return A ControlStorage with the default value for the control\n */\n \n /**\n@@ -804,10 +804,10 @@ ControlInfo::ControlInfo(bool value)\n * \\brief Retrieve the list of valid values\n *\n * For controls that support a pre-defined number of values, the enumeration of\n- * those is reported through a vector of ControlValue instances accessible with\n+ * those is reported through a vector of ControlStorage instances accessible with\n * this function.\n *\n- * \\return A vector of ControlValue representing the control valid values\n+ * \\return A vector of ControlStorage representing the control valid values\n */\n \n /**\n@@ -1234,11 +1234,11 @@ bool ControlList::contains(unsigned int id) const\n *\n * \\return The control value\n */\n-const ControlValue &ControlList::get(unsigned int id) const\n+const ControlStorage &ControlList::get(unsigned int id) const\n {\n-\tstatic const ControlValue zero;\n+\tstatic const ControlStorage zero;\n \n-\tconst ControlValue *val = find(id);\n+\tconst ControlStorage *val = find(id);\n \tif (!val)\n \t\treturn zero;\n \n@@ -1257,9 +1257,9 @@ const ControlValue &ControlList::get(unsigned int id) const\n * The behaviour is undefined if the control \\a id is not supported by the\n * object that the list refers to.\n */\n-void ControlList::set(unsigned int id, const ControlValue &value)\n+void ControlList::set(unsigned int id, const ControlStorage &value)\n {\n-\tControlValue *val = find(id);\n+\tControlStorage *val = find(id);\n \tif (!val)\n \t\treturn;\n \n@@ -1284,7 +1284,7 @@ void ControlList::set(unsigned int id, const ControlValue &value)\n * nullptr is returned in that case.\n */\n \n-const ControlValue *ControlList::find(unsigned int id) const\n+const ControlStorage *ControlList::find(unsigned int id) const\n {\n \tconst auto iter = controls_.find(id);\n \tif (iter == controls_.end()) {\n@@ -1297,7 +1297,7 @@ const ControlValue *ControlList::find(unsigned int id) const\n \treturn &iter->second;\n }\n \n-ControlValue *ControlList::find(unsigned int id)\n+ControlStorage *ControlList::find(unsigned int id)\n {\n \tif (validator_ && !validator_->validate(id)) {\n \t\tLOG(Controls, Error)\ndiff --git a/src/libcamera/debug_controls.cpp b/src/libcamera/debug_controls.cpp\nindex 339602313facbb14f408d38f3998d9bfc80b1dea..d5046a221c3b201e9cc59a27ea8d3f40bf045167 100644\n--- a/src/libcamera/debug_controls.cpp\n+++ b/src/libcamera/debug_controls.cpp\n@@ -138,7 +138,7 @@ void DebugMetadata::moveEntries(ControlList &list)\n */\n \n /**\n- * \\fn DebugMetadata::set(unsigned int id, const ControlValue &value)\n+ * \\fn DebugMetadata::set(unsigned int id, const ControlStorage &value)\n * \\brief Set the value of control \\a id to \\a value\n * \\param[in] id The id of the control\n * \\param[in] value The control value\n@@ -148,7 +148,7 @@ void DebugMetadata::moveEntries(ControlList &list)\n *\n * \\sa enable()\n */\n-void DebugMetadata::set(unsigned int id, const ControlValue &value)\n+void DebugMetadata::set(unsigned int id, const ControlStorage &value)\n {\n \tif (parent_) {\n \t\tparent_->set(id, value);\ndiff --git a/src/libcamera/ipa_controls.cpp b/src/libcamera/ipa_controls.cpp\nindex 12d92ebe894d6616733bf45035cf2838065123d9..e9d655b35e0cc82450499fc8eedf8f47002f76da 100644\n--- a/src/libcamera/ipa_controls.cpp\n+++ b/src/libcamera/ipa_controls.cpp\n@@ -191,7 +191,7 @@ static_assert(sizeof(ipa_controls_header) == 32,\n \n /**\n * \\struct ipa_control_value_entry\n- * \\brief Description of a serialized ControlValue entry\n+ * \\brief Description of a serialized ControlStorage entry\n * \\var ipa_control_value_entry::id\n * The numerical ID of the control\n * \\var ipa_control_value_entry::type\ndiff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex e31e3879dcc9f59425aac18c81492c9f68b4642b..2e7b9f094621d2f39198fc966fb5d4d42928027a 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -955,7 +955,7 @@ int PipelineHandlerIPU3::updateControls(IPU3CameraData *data)\n \tconst std::vector<controls::draft::TestPatternModeEnum>\n \t\t&testPatternModes = sensor->testPatternModes();\n \tif (!testPatternModes.empty()) {\n-\t\tstd::vector<ControlValue> values;\n+\t\tstd::vector<ControlStorage> values;\n \t\tvalues.reserve(testPatternModes.size());\n \n \t\tfor (auto pattern : testPatternModes)\n@@ -1209,7 +1209,7 @@ void IPU3CameraData::setSensorControls([[maybe_unused]] unsigned int id,\n \tif (!lensControls.contains(V4L2_CID_FOCUS_ABSOLUTE))\n \t\treturn;\n \n-\tconst ControlValue &focusValue = lensControls.get(V4L2_CID_FOCUS_ABSOLUTE);\n+\tconst ControlStorage &focusValue = lensControls.get(V4L2_CID_FOCUS_ABSOLUTE);\n \n \tfocusLens->setFocusPosition(focusValue.get<int32_t>());\n }\ndiff --git a/src/libcamera/pipeline/rpi/common/delayed_controls.h b/src/libcamera/pipeline/rpi/common/delayed_controls.h\nindex 487b0057b2f58e6ec1506fb5bc17fa42aa52daca..2d5fa6678b507b54c7d28466ebb48f63fa33635b 100644\n--- a/src/libcamera/pipeline/rpi/common/delayed_controls.h\n+++ b/src/libcamera/pipeline/rpi/common/delayed_controls.h\n@@ -40,7 +40,7 @@ public:\n \tvoid applyControls(uint32_t sequence);\n \n private:\n-\tclass Info : public ControlValue\n+\tclass Info : public ControlStorage\n \t{\n \tpublic:\n \t\tInfo()\n@@ -48,8 +48,8 @@ private:\n \t\t{\n \t\t}\n \n-\t\tInfo(const ControlValue &v, bool updated_ = true)\n-\t\t\t: ControlValue(v), updated(updated_)\n+\t\tInfo(const ControlStorage &v, bool updated_ = true)\n+\t\t\t: ControlStorage(v), updated(updated_)\n \t\t{\n \t\t}\n \ndiff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\nindex 563df198e6e45698115bfe6c3c84279f6672771d..2999b71afa643dee15c304737b0d64f6c0382af9 100644\n--- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n@@ -1250,7 +1250,7 @@ void CameraData::setLensControls(const ControlList &controls)\n \tCameraLens *lens = sensor_->focusLens();\n \n \tif (lens && controls.contains(V4L2_CID_FOCUS_ABSOLUTE)) {\n-\t\tControlValue const &focusValue = controls.get(V4L2_CID_FOCUS_ABSOLUTE);\n+\t\tControlStorage const &focusValue = controls.get(V4L2_CID_FOCUS_ABSOLUTE);\n \t\tlens->setFocusPosition(focusValue.get<int32_t>());\n \t}\n }\ndiff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\nindex 99d43bd0a2f544039f8634fc2d6493d88c04a20c..3cfc8497455d56c9b3f42f3292c97e58381aca6d 100644\n--- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n+++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n@@ -886,8 +886,8 @@ void Vc4CameraData::setIspControls(const ControlList &controls)\n \tControlList ctrls = controls;\n \n \tif (ctrls.contains(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING)) {\n-\t\tControlValue &value =\n-\t\t\tconst_cast<ControlValue &>(ctrls.get(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING));\n+\t\tControlStorage &value =\n+\t\t\tconst_cast<ControlStorage &>(ctrls.get(V4L2_CID_USER_BCM2835_ISP_LENS_SHADING));\n \t\tSpan<uint8_t> s = value.data();\n \t\tbcm2835_isp_lens_shading *ls =\n \t\t\treinterpret_cast<bcm2835_isp_lens_shading *>(s.data());\ndiff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\nindex 4b5816dfdde08c44f23f5b0ea55de228a59c39d8..627aa69be294d89f796cfac148c315b29d6de633 100644\n--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n@@ -99,7 +99,7 @@ public:\n \n private:\n \tint processControl(const UVCCameraData *data, ControlList *controls,\n-\t\t\t unsigned int id, const ControlValue &value);\n+\t\t\t unsigned int id, const ControlStorage &value);\n \tint processControls(UVCCameraData *data, const ControlList &reqControls);\n \n \tbool acquireDevice(Camera *camera) override;\n@@ -322,7 +322,7 @@ void PipelineHandlerUVC::stopDevice(Camera *camera)\n }\n \n int PipelineHandlerUVC::processControl(const UVCCameraData *data, ControlList *controls,\n-\t\t\t\t unsigned int id, const ControlValue &value)\n+\t\t\t\t unsigned int id, const ControlStorage &value)\n {\n \tuint32_t cid;\n \n@@ -721,7 +721,7 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,\n \t}\n \n \t/* Map the control info. */\n-\tconst std::vector<ControlValue> &v4l2Values = v4l2Info.values();\n+\tconst std::vector<ControlStorage> &v4l2Values = v4l2Info.values();\n \tint32_t min = v4l2Info.min().get<int32_t>();\n \tint32_t max = v4l2Info.max().get<int32_t>();\n \tint32_t def = v4l2Info.def().get<int32_t>();\n@@ -793,7 +793,7 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,\n \t\t> exposureModes;\n \t\tstd::optional<controls::ExposureTimeModeEnum> lcDef;\n \n-\t\tfor (const ControlValue &value : v4l2Values) {\n+\t\tfor (const ControlStorage &value : v4l2Values) {\n \t\t\tconst auto x = value.get<int32_t>();\n \n \t\t\tif (0 <= x && static_cast<std::size_t>(x) < exposureModes.size()) {\n@@ -814,7 +814,7 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,\n \t\telse if (exposureModes[V4L2_EXPOSURE_MANUAL])\n \t\t\tmanualExposureMode_ = V4L2_EXPOSURE_MANUAL;\n \n-\t\tstd::array<ControlValue, 2> values;\n+\t\tstd::array<ControlStorage, 2> values;\n \t\tstd::size_t count = 0;\n \n \t\tif (autoExposureMode_)\n@@ -827,7 +827,7 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,\n \t\t\treturn;\n \n \t\tinfo = ControlInfo{\n-\t\t\tSpan<const ControlValue>{ values.data(), count },\n+\t\t\tSpan<const ControlStorage>{ values.data(), count },\n \t\t\t!lcDef ? values.front() : *lcDef,\n \t\t};\n \t\tbreak;\ndiff --git a/src/libcamera/pipeline/virtual/config_parser.cpp b/src/libcamera/pipeline/virtual/config_parser.cpp\nindex 1d3d9ba87ec0991c5a1bd08d3a177a320cd4c182..47448533f98e38dcdd517446f2cb0a4563a52c8d 100644\n--- a/src/libcamera/pipeline/virtual/config_parser.cpp\n+++ b/src/libcamera/pipeline/virtual/config_parser.cpp\n@@ -59,7 +59,7 @@ ConfigParser::parseConfigFile(File &file, PipelineHandler *pipe)\n \t\t\tControlInfo(1000000 / data->config_.resolutions[0].frameRates[1],\n \t\t\t\t 1000000 / data->config_.resolutions[0].frameRates[0]);\n \n-\t\tstd::vector<ControlValue> supportedFaceDetectModes{\n+\t\tstd::vector<ControlStorage> supportedFaceDetectModes{\n \t\t\tstatic_cast<int32_t>(controls::draft::FaceDetectModeOff),\n \t\t};\n \t\tcontrols[&controls::draft::FaceDetectMode] = ControlInfo(supportedFaceDetectModes);\ndiff --git a/src/libcamera/sensor/camera_sensor_legacy.cpp b/src/libcamera/sensor/camera_sensor_legacy.cpp\nindex ba0a5c331d066a4010400620715234729705c349..366a66880ff0525b8198acccdaca946da538faad 100644\n--- a/src/libcamera/sensor/camera_sensor_legacy.cpp\n+++ b/src/libcamera/sensor/camera_sensor_legacy.cpp\n@@ -538,7 +538,7 @@ void CameraSensorLegacy::initTestPatternModes()\n \tfor (const auto &it : testPatternModes)\n \t\tindexToTestPatternMode[it.second] = it.first;\n \n-\tfor (const ControlValue &value : v4l2TestPattern->second.values()) {\n+\tfor (const ControlStorage &value : v4l2TestPattern->second.values()) {\n \t\tconst int32_t index = value.get<int32_t>();\n \n \t\tconst auto it = indexToTestPatternMode.find(index);\ndiff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp\nindex f9aef054e6779fe122b5a83d32eee1678904608d..fc41ee1b71c360c7e1b2ac1aed15a44c277ad7a1 100644\n--- a/src/libcamera/sensor/camera_sensor_raw.cpp\n+++ b/src/libcamera/sensor/camera_sensor_raw.cpp\n@@ -720,7 +720,7 @@ void CameraSensorRaw::initTestPatternModes()\n \tfor (const auto &it : testPatternModes)\n \t\tindexToTestPatternMode[it.second] = it.first;\n \n-\tfor (const ControlValue &value : v4l2TestPattern->second.values()) {\n+\tfor (const ControlStorage &value : v4l2TestPattern->second.values()) {\n \t\tconst int32_t index = value.get<int32_t>();\n \n \t\tconst auto it = indexToTestPatternMode.find(index);\ndiff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\nindex 0db92c19ca4a5f1d0e4b4f4973f36a98e6401ec5..9be9df78416d8a5a4c6891b2926fcea41f808233 100644\n--- a/src/libcamera/v4l2_device.cpp\n+++ b/src/libcamera/v4l2_device.cpp\n@@ -205,7 +205,7 @@ ControlList V4L2Device::getControls(const std::vector<uint32_t> &ids)\n \n \t\tif (info.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) {\n \t\t\tControlType type;\n-\t\t\tControlValue &value = ctrl.second;\n+\t\t\tControlStorage &value = ctrl.second;\n \t\t\tSpan<uint8_t> data;\n \n \t\t\tswitch (info.type) {\n@@ -312,7 +312,7 @@ int V4L2Device::setControls(ControlList *ctrls)\n \t\tv4l2Ctrl.id = id;\n \n \t\t/* Set the v4l2_ext_control value for the write operation. */\n-\t\tControlValue &value = ctrl->second;\n+\t\tControlStorage &value = ctrl->second;\n \t\tswitch (iter->first->type()) {\n \t\tcase ControlTypeUnsigned16: {\n \t\t\tif (value.isArray()) {\n@@ -652,7 +652,7 @@ std::optional<ControlInfo> V4L2Device::v4l2ControlInfo(const v4l2_query_ext_ctrl\n */\n std::optional<ControlInfo> V4L2Device::v4l2MenuControlInfo(const struct v4l2_query_ext_ctrl &ctrl)\n {\n-\tstd::vector<ControlValue> indices;\n+\tstd::vector<ControlStorage> indices;\n \tstruct v4l2_querymenu menu = {};\n \tmenu.id = ctrl.id;\n \n@@ -676,7 +676,7 @@ std::optional<ControlInfo> V4L2Device::v4l2MenuControlInfo(const struct v4l2_que\n \t\treturn std::nullopt;\n \n \treturn ControlInfo(indices,\n-\t\t\t ControlValue(static_cast<int32_t>(ctrl.default_value)));\n+\t\t\t ControlStorage(static_cast<int32_t>(ctrl.default_value)));\n }\n \n /*\n@@ -790,11 +790,11 @@ void V4L2Device::updateControls(ControlList *ctrls,\n \tfor (const v4l2_ext_control &v4l2Ctrl : v4l2Ctrls) {\n \t\tconst unsigned int id = v4l2Ctrl.id;\n \n-\t\tControlValue value = ctrls->get(id);\n+\t\tControlStorage value = ctrls->get(id);\n \t\tif (value.isArray()) {\n \t\t\t/*\n \t\t\t * No action required, the VIDIOC_[GS]_EXT_CTRLS ioctl\n-\t\t\t * accessed the ControlValue storage directly for array\n+\t\t\t * accessed the ControlStorage storage directly for array\n \t\t\t * controls.\n \t\t\t */\n \t\t\tcontinue;\ndiff --git a/src/py/libcamera/py_helpers.cpp b/src/py/libcamera/py_helpers.cpp\nindex 1ad1d4c1a1cd45d50d0a731a4d69b14998b613f2..75283396b1dca7b5e16695e11630496cf1104e3a 100644\n--- a/src/py/libcamera/py_helpers.cpp\n+++ b/src/py/libcamera/py_helpers.cpp\n@@ -16,7 +16,7 @@ namespace py = pybind11;\n using namespace libcamera;\n \n template<typename T>\n-static py::object valueOrTuple(const ControlValue &cv)\n+static py::object valueOrTuple(const ControlStorage &cv)\n {\n \tif (cv.isArray()) {\n \t\tconst T *v = reinterpret_cast<const T *>(cv.data().data());\n@@ -31,7 +31,7 @@ static py::object valueOrTuple(const ControlValue &cv)\n \treturn py::cast(cv.get<T>());\n }\n \n-py::object controlValueToPy(const ControlValue &cv)\n+py::object controlValueToPy(const ControlStorage &cv)\n {\n \tswitch (cv.type()) {\n \tcase ControlTypeNone:\n@@ -57,28 +57,28 @@ py::object controlValueToPy(const ControlValue &cv)\n \tcase ControlTypePoint:\n \t\treturn valueOrTuple<Point>(cv);\n \tdefault:\n-\t\tthrow std::runtime_error(\"Unsupported ControlValue type\");\n+\t\tthrow std::runtime_error(\"Unsupported ControlStorage type\");\n \t}\n }\n \n template<typename T>\n-static ControlValue controlValueMaybeArray(const py::object &ob)\n+static ControlStorage controlValueMaybeArray(const py::object &ob)\n {\n \tif (py::isinstance<py::list>(ob) || py::isinstance<py::tuple>(ob)) {\n \t\tstd::vector<T> vec = ob.cast<std::vector<T>>();\n-\t\treturn ControlValue(Span<const T>(vec));\n+\t\treturn ControlStorage(Span<const T>(vec));\n \t}\n \n-\treturn ControlValue(ob.cast<T>());\n+\treturn ControlStorage(ob.cast<T>());\n }\n \n-ControlValue pyToControlValue(const py::object &ob, ControlType type)\n+ControlStorage pyToControlValue(const py::object &ob, ControlType type)\n {\n \tswitch (type) {\n \tcase ControlTypeNone:\n-\t\treturn ControlValue();\n+\t\treturn ControlStorage();\n \tcase ControlTypeBool:\n-\t\treturn ControlValue(ob.cast<bool>());\n+\t\treturn ControlStorage(ob.cast<bool>());\n \tcase ControlTypeByte:\n \t\treturn controlValueMaybeArray<uint8_t>(ob);\n \tcase ControlTypeInteger32:\n@@ -88,11 +88,11 @@ ControlValue pyToControlValue(const py::object &ob, ControlType type)\n \tcase ControlTypeFloat:\n \t\treturn controlValueMaybeArray<float>(ob);\n \tcase ControlTypeString:\n-\t\treturn ControlValue(ob.cast<std::string>());\n+\t\treturn ControlStorage(ob.cast<std::string>());\n \tcase ControlTypeRectangle:\n \t\treturn controlValueMaybeArray<Rectangle>(ob);\n \tcase ControlTypeSize:\n-\t\treturn ControlValue(ob.cast<Size>());\n+\t\treturn ControlStorage(ob.cast<Size>());\n \tcase ControlTypePoint:\n \t\treturn controlValueMaybeArray<Point>(ob);\n \tdefault:\ndiff --git a/src/py/libcamera/py_helpers.h b/src/py/libcamera/py_helpers.h\nindex 983969dfff0373b14bc87f082a4de10888d0dd7b..47a0ee462c3c3396504c22a99173d83b0d549366 100644\n--- a/src/py/libcamera/py_helpers.h\n+++ b/src/py/libcamera/py_helpers.h\n@@ -9,5 +9,5 @@\n \n #include <pybind11/pybind11.h>\n \n-pybind11::object controlValueToPy(const libcamera::ControlValue &cv);\n-libcamera::ControlValue pyToControlValue(const pybind11::object &ob, libcamera::ControlType type);\n+pybind11::object controlValueToPy(const libcamera::ControlStorage &cv);\n+libcamera::ControlStorage pyToControlValue(const pybind11::object &ob, libcamera::ControlType type);\ndiff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp\nindex 5084fd0cf47087395873fa75b496d37c3f9307a2..17cfe547d617cc9e2de7173d025b2e99bf27b105 100644\n--- a/test/controls/control_value.cpp\n+++ b/test/controls/control_value.cpp\n@@ -2,7 +2,7 @@\n /*\n * Copyright (C) 2019, Google Inc.\n *\n- * ControlValue tests\n+ * ControlStorage tests\n */\n \n #include <algorithm>\n@@ -15,7 +15,7 @@\n using namespace std;\n using namespace libcamera;\n \n-class ControlValueTest : public Test\n+class ControlStorageTest : public Test\n {\n protected:\n \tint run()\n@@ -23,7 +23,7 @@ protected:\n \t\t/*\n \t\t * None type.\n \t\t */\n-\t\tControlValue value;\n+\t\tControlStorage value;\n \t\tif (!value.isNone() || value.isArray()) {\n \t\t\tcerr << \"Empty value is non-null\" << endl;\n \t\t\treturn TestFail;\n@@ -341,4 +341,4 @@ protected:\n \t}\n };\n \n-TEST_REGISTER(ControlValueTest)\n+TEST_REGISTER(ControlStorageTest)\ndiff --git a/test/serialization/serialization_test.cpp b/test/serialization/serialization_test.cpp\nindex af9969fdd11ff821de104b98b013acb891d2a8c8..4b5188972deed3f473f75527fb279148a1d52c40 100644\n--- a/test/serialization/serialization_test.cpp\n+++ b/test/serialization/serialization_test.cpp\n@@ -56,17 +56,17 @@ bool SerializationTest::equals(const ControlInfoMap &lhs, const ControlInfoMap &\n \n bool SerializationTest::equals(const ControlList &lhs, const ControlList &rhs)\n {\n-\tstd::map<unsigned int, ControlValue> rlhs;\n+\tstd::map<unsigned int, ControlStorage> rlhs;\n \tstd::transform(lhs.begin(), lhs.end(), std::inserter(rlhs, rlhs.end()),\n-\t\t\t[](const std::pair<unsigned int, ControlValue> &v)\n+\t\t\t[](const std::pair<unsigned int, ControlStorage> &v)\n \t\t\t\t-> decltype(rlhs)::value_type\n \t\t\t{\n \t\t\t\treturn { v.first, v.second };\n \t\t\t});\n \n-\tstd::map<unsigned int, ControlValue> rrhs;\n+\tstd::map<unsigned int, ControlStorage> rrhs;\n \tstd::transform(rhs.begin(), rhs.end(), std::inserter(rrhs, rrhs.end()),\n-\t\t\t[](const std::pair<unsigned int, ControlValue> &v)\n+\t\t\t[](const std::pair<unsigned int, ControlStorage> &v)\n \t\t\t\t-> decltype(rrhs)::value_type\n \t\t\t{\n \t\t\t\treturn { v.first, v.second };\n", "prefixes": [ "2/3" ] }