{"id":2841,"url":"https://patchwork.libcamera.org/api/patches/2841/?format=json","web_url":"https://patchwork.libcamera.org/patch/2841/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20200217142609.22837-2-naush@raspberrypi.com>","date":"2020-02-17T14:26:07","name":"[libcamera-devel,1/3] libcamera: controls: Add std::string and double ControlValue type.","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"5139d1c423b33851474d9c6773ec71911dd5f976","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/?format=json","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/2841/mbox/","series":[{"id":679,"url":"https://patchwork.libcamera.org/api/series/679/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=679","date":"2020-02-17T14:26:06","name":"Patchset for libcamera controls","version":1,"mbox":"https://patchwork.libcamera.org/series/679/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/2841/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/2841/checks/","tags":{},"headers":{"Return-Path":"<naush@raspberrypi.com>","Received":["from mail-wr1-x431.google.com (mail-wr1-x431.google.com\n\t[IPv6:2a00:1450:4864:20::431])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BC817617B6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 17 Feb 2020 15:28:20 +0100 (CET)","by mail-wr1-x431.google.com with SMTP id y17so19967095wrh.5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 17 Feb 2020 06:28:20 -0800 (PST)","from naushir-VirtualBox.pitowers.org (cust51-dsl50.idnet.net.\n\t[212.69.50.51]) by smtp.gmail.com with ESMTPSA id\n\tp15sm760960wma.40.2020.02.17.06.28.19\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 17 Feb 2020 06:28:19 -0800 (PST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=ylPR30yh3hEPaSqmXUBgYdKNFJBSVfN9rHKln9M5vmQ=;\n\tb=qqjpDoxjrRY3h4njTn8Gbe0jUHg2ejUf3pBXxPM6IRgKgzzqwLhO8zKnki1MGKSgcZ\n\tNyiIws951D3lp6swK+ZwdCba2gkKNnSW71DlSUj6w0Q70XRsN6NhdQInEFMzJtEIQfCw\n\t5SLOV0wNwJiUf6s0vEyaasGDbLF1thP1WTyblmhlQbEyy5viH/SOAAgFCmYUlT+FrZ5/\n\tJG0DZK9af3CXT5DwJFnTP3BH+IymPoSOtETLpE/GAHRO79LTy7vzGfKGDbQww6xaIf6b\n\tyU2XlVSbMge2KjG4JVIURJJbLFowsVRjca2ifDoAg9s0L4BZEYcB/G4WFMV8+V7D4iBx\n\t6M4A==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=ylPR30yh3hEPaSqmXUBgYdKNFJBSVfN9rHKln9M5vmQ=;\n\tb=S7Gv9b4xeFBORPWkcqKriOQEm8x45Rx8iMJ8Q1LVitFR+3tAniT78vRMe2FZUJrj78\n\tPqKVAfWlEwVh2PR4J4jjWF6oZf3JgxHETZI7LVDSFwHgji9NNgBDV5Ae9NKNK7w0ofDp\n\tfXik3WYIt/EDAir0cg+SrMYrCJWMFZTqrZBV/UaPtEH/BFYp87xgUtk8gF6t+zy1gmZ2\n\tMt4RPIbCj074VT5ntzQhIAR4EmX41mVj/cIBv6BKAkny9TWWsbAHWScEoi1WYXoqHm27\n\t2vSlI8mrvkYUr9uSi1yK8z8xIahahP2mudXw6BDOz6H7sk06ovDYxJj3uRBgJfGh3MBw\n\tbhfg==","X-Gm-Message-State":"APjAAAXRu6MMhyCMJy0bPQUhztN0gH+CTQTVg+EDQ2K5DSsjN3/swnKw\n\tjgPYxHlyV1/Sf8XoKXVzG9xZ3f6IPF9ZOg==","X-Google-Smtp-Source":"APXvYqwOb1NItIJZSplNcKEb+eZ9J7dGD+RTjaXGoG5OjuZAzKbfC0OFNfGj91cEl75xPChmTdWArA==","X-Received":"by 2002:adf:b605:: with SMTP id\n\tf5mr21452730wre.383.1581949700134; \n\tMon, 17 Feb 2020 06:28:20 -0800 (PST)","From":"Naushir Patuck <naush@raspberrypi.com>","To":"libcamera-devel@lists.libcamera.org","Date":"Mon, 17 Feb 2020 14:26:07 +0000","Message-Id":"<20200217142609.22837-2-naush@raspberrypi.com>","X-Mailer":"git-send-email 2.17.1","In-Reply-To":"<20200217142609.22837-1-naush@raspberrypi.com>","References":"<20200217142609.22837-1-naush@raspberrypi.com>","Subject":"[libcamera-devel] [PATCH 1/3] libcamera: controls: Add std::string\n\tand double ControlValue type.","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>","X-List-Received-Date":"Mon, 17 Feb 2020 14:28:20 -0000"},"content":"Strings are a convenient control type for controls such as\nAWB mode (\"indoor\", \"outdoor\", \"halogen\", etc.) or AGC mode (\"sports\",\n\"long exposure\", \"spot\", etc.).\n\nDouble control values are useful for control values such as EV and even\ngains.\n\nThis commit adds support for std::string and double control types.\nFunctionality such as ControlRange on std::string types do not really\nmake sense, so do nothing with that for now. Also add appropriate test\nfor the new ControlValue types.\n\nSigned-off-by: Naushir Patuck <naush@raspberrypi.com>\n---\n include/libcamera/controls.h    |  6 +++\n src/libcamera/controls.cpp      | 72 ++++++++++++++++++++++++++++++++-\n test/controls/control_value.cpp | 26 ++++++++++++\n 3 files changed, 103 insertions(+), 1 deletion(-)","diff":"diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h\nindex 458b84e..ac74122 100644\n--- a/include/libcamera/controls.h\n+++ b/include/libcamera/controls.h\n@@ -20,6 +20,8 @@ enum ControlType {\n \tControlTypeBool,\n \tControlTypeInteger32,\n \tControlTypeInteger64,\n+\tControlTypeString,\n+\tControlTypeDouble,\n };\n \n class ControlValue\n@@ -29,6 +31,8 @@ public:\n \tControlValue(bool value);\n \tControlValue(int32_t value);\n \tControlValue(int64_t value);\n+\tControlValue(std::string value);\n+\tControlValue(double value);\n \n \tControlType type() const { return type_; }\n \tbool isNone() const { return type_ == ControlTypeNone; }\n@@ -53,7 +57,9 @@ private:\n \t\tbool bool_;\n \t\tint32_t integer32_;\n \t\tint64_t integer64_;\n+\t\tdouble double_;\n \t};\n+\tstd::string string_;\n };\n \n class ControlId\ndiff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp\nindex 0031cd0..6eb79c9 100644\n--- a/src/libcamera/controls.cpp\n+++ b/src/libcamera/controls.cpp\n@@ -58,6 +58,10 @@ LOG_DEFINE_CATEGORY(Controls)\n  * The control stores a 32-bit integer value\n  * \\var ControlTypeInteger64\n  * The control stores a 64-bit integer value\n+ * \\var ControlTypeString\n+ * The control stores a std::string value\n+ * \\var ControlTypeDouble\n+ * The control stores a double value\n  */\n \n /**\n@@ -100,6 +104,24 @@ ControlValue::ControlValue(int64_t value)\n {\n }\n \n+/**\n+ * \\brief Construct a std::string ControlValue\n+ * \\param[in] value String value to store\n+ */\n+ControlValue::ControlValue(std::string value)\n+\t: type_(ControlTypeString), string_(value)\n+{\n+}\n+\n+/**\n+ * \\brief Construct a double ControlValue\n+ * \\param[in] value Double value to store\n+ */\n+ControlValue::ControlValue(double value)\n+\t: type_(ControlTypeDouble), double_(value)\n+{\n+}\n+\n /**\n  * \\fn ControlValue::type()\n  * \\brief Retrieve the data type of the value\n@@ -153,6 +175,18 @@ const int64_t &ControlValue::get<int64_t>() const\n \treturn integer64_;\n }\n \n+template<>\n+const std::string &ControlValue::get<std::string>() const\n+{\n+\treturn string_;\n+}\n+\n+template<>\n+const double &ControlValue::get<double>() const\n+{\n+\treturn double_;\n+}\n+\n template<>\n void ControlValue::set<bool>(const bool &value)\n {\n@@ -173,6 +207,21 @@ void ControlValue::set<int64_t>(const int64_t &value)\n \ttype_ = ControlTypeInteger64;\n \tinteger64_ = value;\n }\n+\n+template<>\n+void ControlValue::set<std::string>(const std::string &value)\n+{\n+\ttype_ = ControlTypeString;\n+\tstring_ = value;\n+}\n+\n+template<>\n+void ControlValue::set<double>(const double &value)\n+{\n+\ttype_ = ControlTypeDouble;\n+\tdouble_ = value;\n+}\n+\n #endif /* __DOXYGEN__ */\n \n /**\n@@ -190,6 +239,10 @@ std::string ControlValue::toString() const\n \t\treturn std::to_string(integer32_);\n \tcase ControlTypeInteger64:\n \t\treturn std::to_string(integer64_);\n+\tcase ControlTypeString:\n+\t\treturn string_;\n+\tcase ControlTypeDouble:\n+\t\treturn std::to_string(double_);\n \t}\n \n \treturn \"<ValueType Error>\";\n@@ -211,6 +264,10 @@ bool ControlValue::operator==(const ControlValue &other) const\n \t\treturn integer32_ == other.integer32_;\n \tcase ControlTypeInteger64:\n \t\treturn integer64_ == other.integer64_;\n+\tcase ControlTypeString:\n+\t\treturn string_ == other.string_;\n+\tcase ControlTypeDouble:\n+\t\treturn double_ == other.double_;\n \tdefault:\n \t\treturn false;\n \t}\n@@ -341,6 +398,18 @@ Control<int64_t>::Control(unsigned int id, const char *name)\n \t: ControlId(id, name, ControlTypeInteger64)\n {\n }\n+\n+template<>\n+Control<std::string>::Control(unsigned int id, const char *name)\n+\t: ControlId(id, name, ControlTypeString)\n+{\n+}\n+\n+template<>\n+Control<double>::Control(unsigned int id, const char *name)\n+\t: ControlId(id, name, ControlTypeDouble)\n+{\n+}\n #endif /* __DOXYGEN__ */\n \n /**\n@@ -583,7 +652,8 @@ void ControlInfoMap::generateIdmap()\n \tidmap_.clear();\n \n \tfor (const auto &ctrl : *this) {\n-\t\tif (ctrl.first->type() != ctrl.second.min().type()) {\n+\t\tif (ctrl.first->type() != ControlTypeString &&\n+\t\t\t(ctrl.first->type() != ctrl.second.min().type())) {\n \t\t\tLOG(Controls, Error)\n \t\t\t\t<< \"Control \" << utils::hex(ctrl.first->id())\n \t\t\t\t<< \" type and range type mismatch\";\ndiff --git a/test/controls/control_value.cpp b/test/controls/control_value.cpp\nindex a1ffa84..55174da 100644\n--- a/test/controls/control_value.cpp\n+++ b/test/controls/control_value.cpp\n@@ -21,10 +21,14 @@ protected:\n \t{\n \t\tControlValue integer(1234);\n \t\tControlValue boolean(true);\n+\t\tControlValue fractional(3.142);\n+\t\tControlValue string(std::string(\"MyString\"));\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     << \" Frac: \" << fractional.toString()\n+\t\t     << \" String: \" << string.toString()\n \t\t     << endl;\n \n \t\tif (integer.get<int32_t>() != 1234) {\n@@ -37,6 +41,16 @@ protected:\n \t\t\treturn TestFail;\n \t\t}\n \n+\t\tif (fractional.get<double>() != 3.142) {\n+\t\t\tcerr << \"Failed to get Fractional\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tif (string.get<std::string>() != std::string(\"MyString\")) {\n+\t\t\tcerr << \"Failed to get String\" << 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@@ -62,6 +76,18 @@ protected:\n \t\t\treturn TestFail;\n \t\t}\n \n+\t\tvalue.set<double>(2.718);\n+\t\tif (value.get<double>() != 2.718) {\n+\t\t\tcerr << \"Failed to get Fractional\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n+\t\tvalue.set<std::string>(std::string(\"Test\"));\n+\t\tif (value.get<std::string>() != std::string(\"Test\")) {\n+\t\t\tcerr << \"Failed to get String\" << endl;\n+\t\t\treturn TestFail;\n+\t\t}\n+\n \t\treturn TestPass;\n \t}\n };\n","prefixes":["libcamera-devel","1/3"]}