{"id":2186,"url":"https://patchwork.libcamera.org/api/patches/2186/?format=json","web_url":"https://patchwork.libcamera.org/patch/2186/","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":"<20191013232755.3292-5-laurent.pinchart@ideasonboard.com>","date":"2019-10-13T23:27:50","name":"[libcamera-devel,04/10] libcamera: v4l2_controls: Index V4L2ControlInfoMap by ControlId *","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"ebc0ebda7d1f93344823feac9b2db6aacf294f1f","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/?format=json","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/2186/mbox/","series":[{"id":534,"url":"https://patchwork.libcamera.org/api/series/534/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=534","date":"2019-10-13T23:27:46","name":"Merge V4L2ControlInfoMap and ControlInfoMap","version":1,"mbox":"https://patchwork.libcamera.org/series/534/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/2186/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/2186/checks/","tags":{},"headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["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 2FDB36196E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 14 Oct 2019 01:28:04 +0200 (CEST)","from pendragon.bb.dnainternet.fi\n\t(dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id BC71280B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 14 Oct 2019 01:28:03 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1571009283;\n\tbh=EZLtkoM3RrjKVvtc5pNKZPhdJcTkqu/72qfBk4GIEJM=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=lmhOTBUxCKR5TkV2as3TJ4UePbkrw+1Fgo4VBIxdUmpQsMCscmu8tnFlI2LcK2jhZ\n\thBfmh7R2tH9xq8DmY4gAGZKSe+YUnYfxJZJcc5cIt+fUGR52a2CPWa1GRzz3hiQDQk\n\tuUrSnEAHf+WwcMoJ3iy7Vwz7Zvb1ps5t94c4hSFs=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Date":"Mon, 14 Oct 2019 02:27:50 +0300","Message-Id":"<20191013232755.3292-5-laurent.pinchart@ideasonboard.com>","X-Mailer":"git-send-email 2.21.0","In-Reply-To":"<20191013232755.3292-1-laurent.pinchart@ideasonboard.com>","References":"<20191013232755.3292-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH 04/10] libcamera: v4l2_controls: Index\n\tV4L2ControlInfoMap by ControlId *","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":"Sun, 13 Oct 2019 23:28:04 -0000"},"content":"To bring the libcamera and V4L2 control info maps closer, index the\nlatter by ControlId * like the former. As V4L2ControlInfoMap is widely\nindexed by V4L2 numerical IDs, add accessors based on numerical IDs.\n\nThis allows complete removal of the ControId pointer from the\nV4L2ControlInfo, as the ControId is accessible as the key when iterating\nover the map. A handful of users have to be modified to adapt to the\nchange.\n\nThe controlInfo argument from V4L2Device::updateControls() can also be\nremoved as it itsn't used anymore.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n src/libcamera/include/v4l2_controls.h | 40 +++++++++------\n src/libcamera/include/v4l2_device.h   |  1 -\n src/libcamera/pipeline/uvcvideo.cpp   |  2 +-\n src/libcamera/pipeline/vimc.cpp       |  2 +-\n src/libcamera/v4l2_controls.cpp       | 71 +++++++++++++++++++++------\n src/libcamera/v4l2_device.cpp         | 25 +++-------\n 6 files changed, 92 insertions(+), 49 deletions(-)","diff":"diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h\nindex 4d7ac1a133c7..ca7217501256 100644\n--- a/src/libcamera/include/v4l2_controls.h\n+++ b/src/libcamera/include/v4l2_controls.h\n@@ -28,31 +28,41 @@ public:\n class V4L2ControlInfo\n {\n public:\n-\tV4L2ControlInfo(const V4L2ControlId &id,\n-\t\t\tconst struct v4l2_query_ext_ctrl &ctrl);\n+\tV4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl);\n \n-\tconst ControlId &id() const { return *id_; }\n \tconst ControlRange &range() const { return range_; }\n \n private:\n-\tconst V4L2ControlId *id_;\n \tControlRange range_;\n };\n \n-class V4L2ControlInfoMap : private std::map<unsigned int, V4L2ControlInfo>\n+class V4L2ControlInfoMap : private std::map<const ControlId *, V4L2ControlInfo>\n {\n public:\n-\tV4L2ControlInfoMap &operator=(std::map<unsigned int, V4L2ControlInfo> &&info);\n+\tV4L2ControlInfoMap &operator=(std::map<const ControlId *, V4L2ControlInfo> &&info);\n \n-\tusing std::map<unsigned int, V4L2ControlInfo>::begin;\n-\tusing std::map<unsigned int, V4L2ControlInfo>::cbegin;\n-\tusing std::map<unsigned int, V4L2ControlInfo>::end;\n-\tusing std::map<unsigned int, V4L2ControlInfo>::cend;\n-\tusing std::map<unsigned int, V4L2ControlInfo>::at;\n-\tusing std::map<unsigned int, V4L2ControlInfo>::empty;\n-\tusing std::map<unsigned int, V4L2ControlInfo>::size;\n-\tusing std::map<unsigned int, V4L2ControlInfo>::count;\n-\tusing std::map<unsigned int, V4L2ControlInfo>::find;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::key_type;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::mapped_type;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::value_type;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::size_type;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::iterator;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::const_iterator;\n+\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::begin;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::cbegin;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::end;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::cend;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::at;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::empty;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::size;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::count;\n+\tusing std::map<const ControlId *, V4L2ControlInfo>::find;\n+\n+\tmapped_type &at(unsigned int key);\n+\tconst mapped_type &at(unsigned int key) const;\n+\tsize_type count(unsigned int key) const;\n+\titerator find(unsigned int key);\n+\tconst_iterator find(unsigned int key) const;\n \n \tconst ControlIdMap &idmap() const { return idmap_; }\n \ndiff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h\nindex 5a5b85827f23..f30b1c2cde34 100644\n--- a/src/libcamera/include/v4l2_device.h\n+++ b/src/libcamera/include/v4l2_device.h\n@@ -45,7 +45,6 @@ protected:\n private:\n \tvoid listControls();\n \tvoid updateControls(ControlList *ctrls,\n-\t\t\t    const V4L2ControlInfo **controlInfo,\n \t\t\t    const struct v4l2_ext_control *v4l2Ctrls,\n \t\t\t    unsigned int count);\n \ndiff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\nindex 547ad5ca4e55..4d76b5fd9347 100644\n--- a/src/libcamera/pipeline/uvcvideo.cpp\n+++ b/src/libcamera/pipeline/uvcvideo.cpp\n@@ -340,7 +340,7 @@ int UVCCameraData::init(MediaEntity *entity)\n \t\tconst V4L2ControlInfo &info = ctrl.second;\n \t\tconst ControlId *id;\n \n-\t\tswitch (info.id().id()) {\n+\t\tswitch (ctrl.first->id()) {\n \t\tcase V4L2_CID_BRIGHTNESS:\n \t\t\tid = &controls::Brightness;\n \t\t\tbreak;\ndiff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp\nindex 53d00360eb6e..78c0fe5ae509 100644\n--- a/src/libcamera/pipeline/vimc.cpp\n+++ b/src/libcamera/pipeline/vimc.cpp\n@@ -416,7 +416,7 @@ int VimcCameraData::init(MediaDevice *media)\n \t\tconst V4L2ControlInfo &info = ctrl.second;\n \t\tconst ControlId *id;\n \n-\t\tswitch (info.id().id()) {\n+\t\tswitch (ctrl.first->id()) {\n \t\tcase V4L2_CID_BRIGHTNESS:\n \t\t\tid = &controls::Brightness;\n \t\t\tbreak;\ndiff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp\nindex 12c4fb271ba5..9a5e4830db91 100644\n--- a/src/libcamera/v4l2_controls.cpp\n+++ b/src/libcamera/v4l2_controls.cpp\n@@ -122,12 +122,9 @@ V4L2ControlId::V4L2ControlId(const struct v4l2_query_ext_ctrl &ctrl)\n \n /**\n  * \\brief Construct a V4L2ControlInfo from a struct v4l2_query_ext_ctrl\n- * \\param[in] id The V4L2 control ID\n  * \\param[in] ctrl The struct v4l2_query_ext_ctrl as returned by the kernel\n  */\n-V4L2ControlInfo::V4L2ControlInfo(const V4L2ControlId &id,\n-\t\t\t\t const struct v4l2_query_ext_ctrl &ctrl)\n-\t: id_(&id)\n+V4L2ControlInfo::V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl)\n {\n \tif (ctrl.type == V4L2_CTRL_TYPE_INTEGER64)\n \t\trange_ = ControlRange(static_cast<int64_t>(ctrl.minimum),\n@@ -137,12 +134,6 @@ V4L2ControlInfo::V4L2ControlInfo(const V4L2ControlId &id,\n \t\t\t\t      static_cast<int32_t>(ctrl.maximum));\n }\n \n-/**\n- * \\fn V4L2ControlInfo::id()\n- * \\brief Retrieve the control ID\n- * \\return The V4L2 control ID\n- */\n-\n /**\n  * \\fn V4L2ControlInfo::range()\n  * \\brief Retrieve the control value range\n@@ -151,7 +142,7 @@ V4L2ControlInfo::V4L2ControlInfo(const V4L2ControlId &id,\n \n /**\n  * \\class V4L2ControlInfoMap\n- * \\brief A map of control ID to V4L2ControlInfo\n+ * \\brief A map of controlID to V4L2ControlInfo\n  */\n \n /**\n@@ -165,17 +156,69 @@ V4L2ControlInfo::V4L2ControlInfo(const V4L2ControlId &id,\n  *\n  * \\return The populated V4L2ControlInfoMap\n  */\n-V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(std::map<unsigned int, V4L2ControlInfo> &&info)\n+V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(std::map<const ControlId *, V4L2ControlInfo> &&info)\n {\n-\tstd::map<unsigned int, V4L2ControlInfo>::operator=(std::move(info));\n+\tstd::map<const ControlId *, V4L2ControlInfo>::operator=(std::move(info));\n \n \tidmap_.clear();\n \tfor (const auto &ctrl : *this)\n-\t\tidmap_[ctrl.first] = &ctrl.second.id();\n+\t\tidmap_[ctrl.first->id()] = ctrl.first;\n \n \treturn *this;\n }\n \n+/**\n+ * \\brief Access specified element by numerical ID\n+ * \\param[in] id The numerical ID\n+ * \\return A reference to the element whose ID is equal to \\a id\n+ */\n+V4L2ControlInfoMap::mapped_type &V4L2ControlInfoMap::at(unsigned int id)\n+{\n+\treturn at(idmap_.at(id));\n+}\n+\n+/**\n+ * \\brief Access specified element by numerical ID\n+ * \\param[in] id The numerical ID\n+ * \\return A const reference to the element whose ID is equal to \\a id\n+ */\n+const V4L2ControlInfoMap::mapped_type &V4L2ControlInfoMap::at(unsigned int id) const\n+{\n+\treturn at(idmap_.at(id));\n+}\n+\n+/**\n+ * \\brief Count the number of elements matching a numerical ID\n+ * \\param[in] id The numerical ID\n+ * \\return The number of elements matching the numerical \\a id\n+ */\n+V4L2ControlInfoMap::size_type V4L2ControlInfoMap::count(unsigned int id) const\n+{\n+\treturn count(idmap_.at(id));\n+}\n+\n+/**\n+ * \\brief Find the element matching a numerical ID\n+ * \\param[in] id The numerical ID\n+ * \\return An iterator pointing to the element matching the numerical \\a id, or\n+ * end() if no such element exists\n+ */\n+V4L2ControlInfoMap::iterator V4L2ControlInfoMap::find(unsigned int id)\n+{\n+\treturn find(idmap_.at(id));\n+}\n+\n+/**\n+ * \\brief Find the element matching a numerical ID\n+ * \\param[in] id The numerical ID\n+ * \\return A const iterator pointing to the element matching the numerical\n+ * \\a id, or end() if no such element exists\n+ */\n+V4L2ControlInfoMap::const_iterator V4L2ControlInfoMap::find(unsigned int id) const\n+{\n+\treturn find(idmap_.at(id));\n+}\n+\n /**\n  * \\fn const ControlIdMap &V4L2ControlInfoMap::idmap() const\n  * \\brief Retrieve the ControlId map\ndiff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\nindex 144a60b4fe93..4bb7d5950f3a 100644\n--- a/src/libcamera/v4l2_device.cpp\n+++ b/src/libcamera/v4l2_device.cpp\n@@ -171,7 +171,6 @@ int V4L2Device::getControls(ControlList *ctrls)\n \tif (count == 0)\n \t\treturn 0;\n \n-\tconst V4L2ControlInfo *controlInfo[count];\n \tstruct v4l2_ext_control v4l2Ctrls[count];\n \tmemset(v4l2Ctrls, 0, sizeof(v4l2Ctrls));\n \n@@ -185,10 +184,7 @@ int V4L2Device::getControls(ControlList *ctrls)\n \t\t\treturn -EINVAL;\n \t\t}\n \n-\t\tconst V4L2ControlInfo *info = &iter->second;\n-\t\tcontrolInfo[i] = info;\n \t\tv4l2Ctrls[i].id = id->id();\n-\n \t\ti++;\n \t}\n \n@@ -215,7 +211,7 @@ int V4L2Device::getControls(ControlList *ctrls)\n \t\tret = errorIdx;\n \t}\n \n-\tupdateControls(ctrls, controlInfo, v4l2Ctrls, count);\n+\tupdateControls(ctrls, v4l2Ctrls, count);\n \n \treturn ret;\n }\n@@ -249,7 +245,6 @@ int V4L2Device::setControls(ControlList *ctrls)\n \tif (count == 0)\n \t\treturn 0;\n \n-\tconst V4L2ControlInfo *controlInfo[count];\n \tstruct v4l2_ext_control v4l2Ctrls[count];\n \tmemset(v4l2Ctrls, 0, sizeof(v4l2Ctrls));\n \n@@ -263,13 +258,11 @@ int V4L2Device::setControls(ControlList *ctrls)\n \t\t\treturn -EINVAL;\n \t\t}\n \n-\t\tconst V4L2ControlInfo *info = &iter->second;\n-\t\tcontrolInfo[i] = info;\n \t\tv4l2Ctrls[i].id = id->id();\n \n \t\t/* Set the v4l2_ext_control value for the write operation. */\n \t\tconst ControlValue &value = ctrl.second;\n-\t\tswitch (info->id().type()) {\n+\t\tswitch (id->type()) {\n \t\tcase ControlTypeInteger64:\n \t\t\tv4l2Ctrls[i].value64 = value.get<int64_t>();\n \t\t\tbreak;\n@@ -308,7 +301,7 @@ int V4L2Device::setControls(ControlList *ctrls)\n \t\tret = errorIdx;\n \t}\n \n-\tupdateControls(ctrls, controlInfo, v4l2Ctrls, count);\n+\tupdateControls(ctrls, v4l2Ctrls, count);\n \n \treturn ret;\n }\n@@ -349,7 +342,7 @@ int V4L2Device::ioctl(unsigned long request, void *argp)\n  */\n void V4L2Device::listControls()\n {\n-\tstd::map<unsigned int, V4L2ControlInfo> ctrls;\n+\tstd::map<const ControlId *, V4L2ControlInfo> ctrls;\n \tstruct v4l2_query_ext_ctrl ctrl = {};\n \n \t/* \\todo Add support for menu and compound controls. */\n@@ -388,8 +381,8 @@ void V4L2Device::listControls()\n \n \t\tcontrolIds_.emplace_back(utils::make_unique<V4L2ControlId>(ctrl));\n \t\tctrls.emplace(std::piecewise_construct,\n-\t\t\t      std::forward_as_tuple(ctrl.id),\n-\t\t\t      std::forward_as_tuple(*controlIds_.back().get(), ctrl));\n+\t\t\t      std::forward_as_tuple(controlIds_.back().get()),\n+\t\t\t      std::forward_as_tuple(ctrl));\n \t}\n \n \tcontrols_ = std::move(ctrls);\n@@ -399,12 +392,10 @@ void V4L2Device::listControls()\n  * \\brief Update the value of the first \\a count V4L2 controls in \\a ctrls using\n  * values in \\a v4l2Ctrls\n  * \\param[inout] ctrls List of V4L2 controls to update\n- * \\param[in] controlInfo List of V4L2 control information\n  * \\param[in] v4l2Ctrls List of V4L2 extended controls as returned by the driver\n  * \\param[in] count The number of controls to update\n  */\n void V4L2Device::updateControls(ControlList *ctrls,\n-\t\t\t\tconst V4L2ControlInfo **controlInfo,\n \t\t\t\tconst struct v4l2_ext_control *v4l2Ctrls,\n \t\t\t\tunsigned int count)\n {\n@@ -414,10 +405,10 @@ void V4L2Device::updateControls(ControlList *ctrls,\n \t\t\tbreak;\n \n \t\tconst struct v4l2_ext_control *v4l2Ctrl = &v4l2Ctrls[i];\n-\t\tconst V4L2ControlInfo *info = controlInfo[i];\n+\t\tconst ControlId *id = ctrl.first;\n \t\tControlValue &value = ctrl.second;\n \n-\t\tswitch (info->id().type()) {\n+\t\tswitch (id->type()) {\n \t\tcase ControlTypeInteger64:\n \t\t\tvalue.set<int64_t>(v4l2Ctrl->value64);\n \t\t\tbreak;\n","prefixes":["libcamera-devel","04/10"]}