Patch Detail
Show a patch.
GET /api/1.1/patches/1980/?format=api
{ "id": 1980, "url": "https://patchwork.libcamera.org/api/1.1/patches/1980/?format=api", "web_url": "https://patchwork.libcamera.org/patch/1980/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/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": "<20190918103133.14296-3-jacopo@jmondi.org>", "date": "2019-09-18T10:31:30", "name": "[libcamera-devel,2/5] libcamera: controls: Use DataType and DataValue", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "4edb9b69ba94e287ffc40c3d19f4a2f10e747cd8", "submitter": { "id": 3, "url": "https://patchwork.libcamera.org/api/1.1/people/3/?format=api", "name": "Jacopo Mondi", "email": "jacopo@jmondi.org" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/1980/mbox/", "series": [ { "id": 500, "url": "https://patchwork.libcamera.org/api/1.1/series/500/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=500", "date": "2019-09-18T10:31:28", "name": "libcamera: Control framework backend rework", "version": 1, "mbox": "https://patchwork.libcamera.org/series/500/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/1980/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/1980/checks/", "tags": {}, "headers": { "Return-Path": "<jacopo@jmondi.org>", "Received": [ "from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net\n\t[217.70.183.201])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DA21E60DED;\n\tWed, 18 Sep 2019 12:30:01 +0200 (CEST)", "from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101])\n\t(Authenticated sender: jacopo@jmondi.org)\n\tby relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 474DA1BF208;\n\tWed, 18 Sep 2019 10:30:01 +0000 (UTC)" ], "X-Originating-IP": "2.224.242.101", "From": "Jacopo Mondi <jacopo@jmondi.org>", "To": "libcamera-devel@lists.libcamera.org,\n\tTo:libcamera-devel@lists.libcamera.org", "Date": "Wed, 18 Sep 2019 12:31:30 +0200", "Message-Id": "<20190918103133.14296-3-jacopo@jmondi.org>", "X-Mailer": "git-send-email 2.23.0", "In-Reply-To": "<20190918103133.14296-1-jacopo@jmondi.org>", "References": "<20190918103133.14296-1-jacopo@jmondi.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH 2/5] libcamera: controls: Use DataType and\n\tDataValue", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.23", "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>", "X-List-Received-Date": "Wed, 18 Sep 2019 10:30:02 -0000" }, "content": "Replace the use of ControlValue with DataValue and make ControlInfo a\nDataInfo derived class to maximize the code reuse with V4L2Control which\nwill be modified in the next patch.\n\nRemove the now unused control_value test, replaced in the previous patch\nby data_value test.\n\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\n---\n include/libcamera/controls.h | 77 ++-------\n src/libcamera/controls.cpp | 237 ++--------------------------\n src/libcamera/gen-controls.awk | 2 +-\n src/libcamera/pipeline/uvcvideo.cpp | 2 +-\n src/libcamera/pipeline/vimc.cpp | 2 +-\n test/controls/control_info.cpp | 4 +-\n test/controls/control_value.cpp | 69 --------\n test/controls/meson.build | 1 -\n 8 files changed, 26 insertions(+), 368 deletions(-)\n delete mode 100644 test/controls/control_value.cpp", "diff": "diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\nindex fbb3a62274c6..e46cd8a78679 100644\n--- a/include/libcamera/controls.h\n+++ b/include/libcamera/controls.h\n@@ -13,98 +13,39 @@\n #include <unordered_map>\n \n #include <libcamera/control_ids.h>\n+#include <libcamera/data_value.h>\n \n namespace libcamera {\n \n class Camera;\n \n-enum ControlValueType {\n-\tControlValueNone,\n-\tControlValueBool,\n-\tControlValueInteger,\n-\tControlValueInteger64,\n-};\n-\n-class ControlValue\n-{\n-public:\n-\tControlValue();\n-\tControlValue(bool value);\n-\tControlValue(int value);\n-\tControlValue(int64_t value);\n-\n-\tControlValueType type() const { return type_; };\n-\tbool isNone() const { return type_ == ControlValueNone; };\n-\n-\tvoid set(bool value);\n-\tvoid set(int value);\n-\tvoid set(int64_t value);\n-\n-\tbool getBool() const;\n-\tint getInt() const;\n-\tint64_t getInt64() const;\n-\n-\tstd::string toString() const;\n-\n-private:\n-\tControlValueType type_;\n-\n-\tunion {\n-\t\tbool bool_;\n-\t\tint integer_;\n-\t\tint64_t integer64_;\n-\t};\n-};\n-\n struct ControlIdentifier {\n \tControlId id;\n \tconst char *name;\n-\tControlValueType type;\n+\tDataType type;\n };\n \n-class ControlInfo\n+class ControlInfo : public DataInfo\n {\n public:\n-\texplicit ControlInfo(ControlId id, const ControlValue &min = 0,\n-\t\t\t const ControlValue &max = 0);\n-\n+\texplicit ControlInfo(ControlId id, const DataValue &min = 0,\n+\t\t\t const DataValue &max = 0);\n \tControlId id() const { return ident_->id; }\n \tconst char *name() const { return ident_->name; }\n-\tControlValueType type() const { return ident_->type; }\n-\n-\tconst ControlValue &min() const { return min_; }\n-\tconst ControlValue &max() const { return max_; }\n+\tDataType type() const { return ident_->type; }\n \n \tstd::string toString() const;\n \n private:\n \tconst struct ControlIdentifier *ident_;\n-\tControlValue min_;\n-\tControlValue max_;\n };\n \n-bool operator==(const ControlInfo &lhs, const ControlInfo &rhs);\n-bool operator==(const ControlId &lhs, const ControlInfo &rhs);\n-bool operator==(const ControlInfo &lhs, const ControlId &rhs);\n-static inline bool operator!=(const ControlInfo &lhs, const ControlInfo &rhs)\n-{\n-\treturn !(lhs == rhs);\n-}\n-static inline bool operator!=(const ControlId &lhs, const ControlInfo &rhs)\n-{\n-\treturn !(lhs == rhs);\n-}\n-static inline bool operator!=(const ControlInfo &lhs, const ControlId &rhs)\n-{\n-\treturn !(lhs == rhs);\n-}\n-\n using ControlInfoMap = std::unordered_map<ControlId, ControlInfo>;\n \n class ControlList\n {\n private:\n-\tusing ControlListMap = std::unordered_map<const ControlInfo *, ControlValue>;\n+\tusing ControlListMap = std::unordered_map<const ControlInfo *, DataValue>;\n \n public:\n \tControlList(Camera *camera);\n@@ -123,8 +64,8 @@ public:\n \tstd::size_t size() const { return controls_.size(); }\n \tvoid clear() { controls_.clear(); }\n \n-\tControlValue &operator[](ControlId id);\n-\tControlValue &operator[](const ControlInfo *info) { return controls_[info]; }\n+\tDataValue &operator[](ControlId id);\n+\tDataValue &operator[](const ControlInfo *info) { return controls_[info]; }\n \n \tvoid update(const ControlList &list);\n \ndiff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\nindex 727fdbd9450d..2d8adde5688e 100644\n--- a/src/libcamera/controls.cpp\n+++ b/src/libcamera/controls.cpp\n@@ -24,163 +24,6 @@ namespace libcamera {\n \n LOG_DEFINE_CATEGORY(Controls)\n \n-/**\n- * \\enum ControlValueType\n- * \\brief Define the data type of value represented by a ControlValue\n- * \\var ControlValueNone\n- * Identifies an unset control value\n- * \\var ControlValueBool\n- * Identifies controls storing a boolean value\n- * \\var ControlValueInteger\n- * Identifies controls storing an integer value\n- * \\var ControlValueInteger64\n- * Identifies controls storing a 64-bit integer value\n- */\n-\n-/**\n- * \\class ControlValue\n- * \\brief Abstract type representing the value of a control\n- */\n-\n-/**\n- * \\brief Construct an empty ControlValue.\n- */\n-ControlValue::ControlValue()\n-\t: type_(ControlValueNone)\n-{\n-}\n-\n-/**\n- * \\brief Construct a Boolean ControlValue\n- * \\param[in] value Boolean value to store\n- */\n-ControlValue::ControlValue(bool value)\n-\t: type_(ControlValueBool), bool_(value)\n-{\n-}\n-\n-/**\n- * \\brief Construct an integer ControlValue\n- * \\param[in] value Integer value to store\n- */\n-ControlValue::ControlValue(int value)\n-\t: type_(ControlValueInteger), integer_(value)\n-{\n-}\n-\n-/**\n- * \\brief Construct a 64 bit integer ControlValue\n- * \\param[in] value Integer value to store\n- */\n-ControlValue::ControlValue(int64_t value)\n-\t: type_(ControlValueInteger64), integer64_(value)\n-{\n-}\n-\n-/**\n- * \\fn ControlValue::type()\n- * \\brief Retrieve the data type of the value\n- * \\return The value data type\n- */\n-\n-/**\n- * \\fn ControlValue::isNone()\n- * \\brief Determine if the value is not initialised\n- * \\return True if the value type is ControlValueNone, false otherwise\n- */\n-\n-/**\n- * \\brief Set the value with a boolean\n- * \\param[in] value Boolean value to store\n- */\n-void ControlValue::set(bool value)\n-{\n-\ttype_ = ControlValueBool;\n-\tbool_ = value;\n-}\n-\n-/**\n- * \\brief Set the value with an integer\n- * \\param[in] value Integer value to store\n- */\n-void ControlValue::set(int value)\n-{\n-\ttype_ = ControlValueInteger;\n-\tinteger_ = value;\n-}\n-\n-/**\n- * \\brief Set the value with a 64 bit integer\n- * \\param[in] value 64 bit integer value to store\n- */\n-void ControlValue::set(int64_t value)\n-{\n-\ttype_ = ControlValueInteger64;\n-\tinteger64_ = value;\n-}\n-\n-/**\n- * \\brief Get the boolean value\n- *\n- * The value type must be Boolean.\n- *\n- * \\return The boolean value\n- */\n-bool ControlValue::getBool() const\n-{\n-\tASSERT(type_ == ControlValueBool);\n-\n-\treturn bool_;\n-}\n-\n-/**\n- * \\brief Get the integer value\n- *\n- * The value type must be Integer or Integer64.\n- *\n- * \\return The integer value\n- */\n-int ControlValue::getInt() const\n-{\n-\tASSERT(type_ == ControlValueInteger || type_ == ControlValueInteger64);\n-\n-\treturn integer_;\n-}\n-\n-/**\n- * \\brief Get the 64-bit integer value\n- *\n- * The value type must be Integer or Integer64.\n- *\n- * \\return The 64-bit integer value\n- */\n-int64_t ControlValue::getInt64() const\n-{\n-\tASSERT(type_ == ControlValueInteger || type_ == ControlValueInteger64);\n-\n-\treturn integer64_;\n-}\n-\n-/**\n- * \\brief Assemble and return a string describing the value\n- * \\return A string describing the ControlValue\n- */\n-std::string ControlValue::toString() const\n-{\n-\tswitch (type_) {\n-\tcase ControlValueNone:\n-\t\treturn \"<None>\";\n-\tcase ControlValueBool:\n-\t\treturn bool_ ? \"True\" : \"False\";\n-\tcase ControlValueInteger:\n-\t\treturn std::to_string(integer_);\n-\tcase ControlValueInteger64:\n-\t\treturn std::to_string(integer64_);\n-\t}\n-\n-\treturn \"<ValueType Error>\";\n-}\n-\n /**\n * \\enum ControlId\n * \\brief Numerical control ID\n@@ -269,9 +112,9 @@ extern const std::unordered_map<ControlId, ControlIdentifier> controlTypes;\n * \\param[in] min The control minimum value\n * \\param[in] max The control maximum value\n */\n-ControlInfo::ControlInfo(ControlId id, const ControlValue &min,\n-\t\t\t const ControlValue &max)\n-\t: min_(min), max_(max)\n+ControlInfo::ControlInfo(ControlId id, const DataValue &min,\n+\t\t\t const DataValue &max)\n+\t: DataInfo(min, max)\n {\n \tauto iter = controlTypes.find(id);\n \tif (iter == controlTypes.end()) {\n@@ -296,79 +139,23 @@ ControlInfo::ControlInfo(ControlId id, const ControlValue &min,\n \n /**\n * \\fn ControlInfo::type()\n- * \\brief Retrieve the control data type\n- * \\return The control data type\n- */\n-\n-/**\n- * \\fn ControlInfo::min()\n- * \\brief Retrieve the minimum value of the control\n- * \\return A ControlValue with the minimum value for the control\n- */\n-\n-/**\n- * \\fn ControlInfo::max()\n- * \\brief Retrieve the maximum value of the control\n- * \\return A ControlValue with the maximum value for the control\n+ * \\brief Retrieve the control designated type\n+ * \\return The control type\n */\n \n /**\n * \\brief Provide a string representation of the ControlInfo\n+ * \\return The control name\n */\n std::string ControlInfo::toString() const\n {\n \tstd::stringstream ss;\n \n-\tss << name() << \"[\" << min_.toString() << \"..\" << max_.toString() << \"]\";\n+\tss << name() << \"[\" << min().toString() << \"..\" << max().toString() << \"]\";\n \n \treturn ss.str();\n }\n \n-/**\n- * \\brief Compare control information for equality\n- * \\param[in] lhs Left-hand side control information\n- * \\param[in] rhs Right-hand side control information\n- *\n- * Control information is compared based on the ID only, as a camera may not\n- * have two separate controls with the same ID.\n- *\n- * \\return True if \\a lhs and \\a rhs are equal, false otherwise\n- */\n-bool operator==(const ControlInfo &lhs, const ControlInfo &rhs)\n-{\n-\treturn lhs.id() == rhs.id();\n-}\n-\n-/**\n- * \\brief Compare control ID and information for equality\n- * \\param[in] lhs Left-hand side control identifier\n- * \\param[in] rhs Right-hand side control information\n- *\n- * Control information is compared based on the ID only, as a camera may not\n- * have two separate controls with the same ID.\n- *\n- * \\return True if \\a lhs and \\a rhs are equal, false otherwise\n- */\n-bool operator==(const ControlId &lhs, const ControlInfo &rhs)\n-{\n-\treturn lhs == rhs.id();\n-}\n-\n-/**\n- * \\brief Compare control information and ID for equality\n- * \\param[in] lhs Left-hand side control information\n- * \\param[in] rhs Right-hand side control identifier\n- *\n- * Control information is compared based on the ID only, as a camera may not\n- * have two separate controls with the same ID.\n- *\n- * \\return True if \\a lhs and \\a rhs are equal, false otherwise\n- */\n-bool operator==(const ControlInfo &lhs, const ControlId &rhs)\n-{\n-\treturn lhs.id() == rhs;\n-}\n-\n /**\n * \\typedef ControlInfoMap\n * \\brief A map of ControlId to ControlInfo\n@@ -378,7 +165,7 @@ bool operator==(const ControlInfo &lhs, const ControlId &rhs)\n * \\class ControlList\n * \\brief Associate a list of ControlId with their values for a camera\n *\n- * A ControlList wraps a map of ControlId to ControlValue and provide\n+ * A ControlList wraps a map of ControlId to DataValue and provide\n * additional validation against the control information exposed by a Camera.\n *\n * A list is only valid for as long as the camera it refers to is valid. After\n@@ -474,7 +261,7 @@ bool ControlList::contains(const ControlInfo *info) const\n /**\n * \\fn ControlList::size()\n * \\brief Retrieve the number of controls in the list\n- * \\return The number of Control entries stored in the list\n+ * \\return The number of DataValue entries stored in the list\n */\n \n /**\n@@ -494,7 +281,7 @@ bool ControlList::contains(const ControlInfo *info) const\n *\n * \\return A reference to the value of the control identified by \\a id\n */\n-ControlValue &ControlList::operator[](ControlId id)\n+DataValue &ControlList::operator[](ControlId id)\n {\n \tconst ControlInfoMap &controls = camera_->controls();\n \tconst auto iter = controls.find(id);\n@@ -503,7 +290,7 @@ ControlValue &ControlList::operator[](ControlId id)\n \t\t\t<< \"Camera \" << camera_->name()\n \t\t\t<< \" does not support control \" << id;\n \n-\t\tstatic ControlValue empty;\n+\t\tstatic DataValue empty;\n \t\treturn empty;\n \t}\n \n@@ -543,7 +330,7 @@ void ControlList::update(const ControlList &other)\n \n \tfor (auto it : other) {\n \t\tconst ControlInfo *info = it.first;\n-\t\tconst ControlValue &value = it.second;\n+\t\tconst DataValue &value = it.second;\n \n \t\tcontrols_[info] = value;\n \t}\ndiff --git a/src/libcamera/gen-controls.awk b/src/libcamera/gen-controls.awk\nindex f3d068123012..abeb0218546b 100755\n--- a/src/libcamera/gen-controls.awk\n+++ b/src/libcamera/gen-controls.awk\n@@ -92,7 +92,7 @@ function GenerateTable(file) {\n \tprint \"extern const std::unordered_map<ControlId, ControlIdentifier>\" > file\n \tprint \"controlTypes {\" > file\n \tfor (i=1; i <= id; ++i) {\n-\t\tprintf \"\\t{ %s, { %s, \\\"%s\\\", ControlValue%s } },\\n\", names[i], names[i], names[i], types[i] > file\n+\t\tprintf \"\\t{ %s, { %s, \\\"%s\\\", DataType%s } },\\n\", names[i], names[i], names[i], types[i] > file\n \t}\n \tprint \"};\" > file\n \tExitNameSpace(file)\ndiff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\nindex 8965210550d2..dd253f94ca3d 100644\n--- a/src/libcamera/pipeline/uvcvideo.cpp\n+++ b/src/libcamera/pipeline/uvcvideo.cpp\n@@ -231,7 +231,7 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)\n \n \tfor (auto it : request->controls()) {\n \t\tconst ControlInfo *ci = it.first;\n-\t\tControlValue &value = it.second;\n+\t\tDataValue &value = it.second;\n \n \t\tswitch (ci->id()) {\n \t\tcase Brightness:\ndiff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp\nindex f26a91f86ec1..3df239bdb277 100644\n--- a/src/libcamera/pipeline/vimc.cpp\n+++ b/src/libcamera/pipeline/vimc.cpp\n@@ -284,7 +284,7 @@ int PipelineHandlerVimc::processControls(VimcCameraData *data, Request *request)\n \n \tfor (auto it : request->controls()) {\n \t\tconst ControlInfo *ci = it.first;\n-\t\tControlValue &value = it.second;\n+\t\tDataValue &value = it.second;\n \n \t\tswitch (ci->id()) {\n \t\tcase Brightness:\ndiff --git a/test/controls/control_info.cpp b/test/controls/control_info.cpp\nindex aa3a65b1e5ef..c3f9b85580a7 100644\n--- a/test/controls/control_info.cpp\n+++ b/test/controls/control_info.cpp\n@@ -26,7 +26,7 @@ protected:\n \t\tControlInfo info(Brightness);\n \n \t\tif (info.id() != Brightness ||\n-\t\t info.type() != ControlValueInteger ||\n+\t\t info.type() != DataTypeInteger ||\n \t\t info.name() != std::string(\"Brightness\")) {\n \t\t\tcout << \"Invalid control identification for Brightness\" << endl;\n \t\t\treturn TestFail;\n@@ -44,7 +44,7 @@ protected:\n \t\tinfo = ControlInfo(Contrast, 10, 200);\n \n \t\tif (info.id() != Contrast ||\n-\t\t info.type() != ControlValueInteger ||\n+\t\t info.type() != DataTypeInteger ||\n \t\t info.name() != std::string(\"Contrast\")) {\n \t\t\tcout << \"Invalid control identification for Contrast\" << endl;\n \t\t\treturn TestFail;\ndiff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp\ndeleted file mode 100644\nindex 778efe5c115f..000000000000\n--- a/test/controls/control_value.cpp\n+++ /dev/null\n@@ -1,69 +0,0 @@\n-/* SPDX-License-Identifier: GPL-2.0-or-later */\n-/*\n- * Copyright (C) 2019, Google Inc.\n- *\n- * control_value.cpp - ControlValue tests\n- */\n-\n-#include <iostream>\n-\n-#include <libcamera/controls.h>\n-\n-#include \"test.h\"\n-\n-using namespace std;\n-using namespace libcamera;\n-\n-class ControlValueTest : public Test\n-{\n-protected:\n-\tint run()\n-\t{\n-\t\tControlValue integer(1234);\n-\t\tControlValue boolean(true);\n-\n-\t\t/* Just a string conversion output test... no validation */\n-\t\tcout << \"Int: \" << integer.toString()\n-\t\t << \" Bool: \" << boolean.toString()\n-\t\t << endl;\n-\n-\t\tif (integer.getInt() != 1234) {\n-\t\t\tcerr << \"Failed to get Integer\" << endl;\n-\t\t\treturn TestFail;\n-\t\t}\n-\n-\t\tif (boolean.getBool() != true) {\n-\t\t\tcerr << \"Failed to get Boolean\" << endl;\n-\t\t\treturn TestFail;\n-\t\t}\n-\n-\t\t/* Test an uninitialised value, and updating it. */\n-\n-\t\tControlValue value;\n-\t\tif (!value.isNone()) {\n-\t\t\tcerr << \"Empty value is non-null\" << endl;\n-\t\t\treturn TestFail;\n-\t\t}\n-\n-\t\tvalue.set(true);\n-\t\tif (value.isNone()) {\n-\t\t\tcerr << \"Failed to set an empty object\" << endl;\n-\t\t\treturn TestFail;\n-\t\t}\n-\n-\t\tif (value.getBool() != true) {\n-\t\t\tcerr << \"Failed to get Booleans\" << endl;\n-\t\t\treturn TestFail;\n-\t\t}\n-\n-\t\tvalue.set(10);\n-\t\tif (value.getInt() != 10) {\n-\t\t\tcerr << \"Failed to get Integer\" << endl;\n-\t\t\treturn TestFail;\n-\t\t}\n-\n-\t\treturn TestPass;\n-\t}\n-};\n-\n-TEST_REGISTER(ControlValueTest)\ndiff --git a/test/controls/meson.build b/test/controls/meson.build\nindex f4fc7b947dd9..9070be85718b 100644\n--- a/test/controls/meson.build\n+++ b/test/controls/meson.build\n@@ -1,7 +1,6 @@\n control_tests = [\n [ 'control_info', 'control_info.cpp' ],\n [ 'control_list', 'control_list.cpp' ],\n- [ 'control_value', 'control_value.cpp' ],\n ]\n \n foreach t : control_tests\n", "prefixes": [ "libcamera-devel", "2/5" ] }