From patchwork Sun Oct 13 23:27:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2183 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5464361563 for ; Mon, 14 Oct 2019 01:28:03 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CA6DA80B for ; Mon, 14 Oct 2019 01:28:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1571009282; bh=NCqyGMry2g4r6rw9Pzmv/oLQwsqOyF7thxVr+RN9MZ0=; h=From:To:Subject:Date:In-Reply-To:References:From; b=c1YE8cWzdjJkFmeTEILvHSSYadLIyM26f1c+0hE2EEsfs74uZ9xPomgEsiizeo/cC epj5TzaSJSXOwMsmVQ51u542Or8LofkDUiqqRofQhIQCm9CuoepLonU2D6jJu8oOmB svxw0eNVp/0d2a6FCIOQ3it5OQI9odjzdZrTNFt8= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 14 Oct 2019 02:27:47 +0300 Message-Id: <20191013232755.3292-2-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 Subject: [libcamera-devel] [PATCH 01/10] libcamera: v4l2_controls: Remove V4L2ControlInfo::size() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Oct 2019 23:28:03 -0000 We don't support V4L2 compound controls, the size field is thus unused. Remove it to ease merging of the libcamera and V4L2 control info classes. Support for array controls can then be added later on top, and would be useful for libcamera controls too. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- src/libcamera/include/v4l2_controls.h | 4 ---- src/libcamera/v4l2_controls.cpp | 8 -------- src/libcamera/v4l2_device.cpp | 14 ++++++++++++-- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h index 89cc74485e6f..133f5262febf 100644 --- a/src/libcamera/include/v4l2_controls.h +++ b/src/libcamera/include/v4l2_controls.h @@ -31,14 +31,10 @@ public: V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl); const ControlId &id() const { return id_; } - size_t size() const { return size_; } - const ControlRange &range() const { return range_; } private: V4L2ControlId id_; - size_t size_; - ControlRange range_; }; diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp index c45d3fda2e1f..dcf31b7a8f26 100644 --- a/src/libcamera/v4l2_controls.cpp +++ b/src/libcamera/v4l2_controls.cpp @@ -127,8 +127,6 @@ V4L2ControlId::V4L2ControlId(const struct v4l2_query_ext_ctrl &ctrl) V4L2ControlInfo::V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl) : id_(ctrl) { - size_ = ctrl.elem_size * ctrl.elems; - if (ctrl.type == V4L2_CTRL_TYPE_INTEGER64) range_ = ControlRange(static_cast(ctrl.minimum), static_cast(ctrl.maximum)); @@ -143,12 +141,6 @@ V4L2ControlInfo::V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl) * \return The V4L2 control ID */ -/** - * \fn V4L2ControlInfo::size() - * \brief Retrieve the control value data size (in bytes) - * \return The V4L2 control value data size - */ - /** * \fn V4L2ControlInfo::range() * \brief Retrieve the control value range diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index b47ba448f354..54cc214ecce9 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -8,11 +8,13 @@ #include "v4l2_device.h" #include +#include #include #include #include #include "log.h" +#include "utils.h" #include "v4l2_controls.h" /** @@ -360,6 +362,13 @@ void V4L2Device::listControls() ctrl.flags & V4L2_CTRL_FLAG_DISABLED) continue; + if (ctrl.elems != 1 || ctrl.nr_of_dims) { + LOG(V4L2, Debug) + << "Array control " << utils::hex(ctrl.id) + << " not supported"; + continue; + } + switch (ctrl.type) { case V4L2_CTRL_TYPE_INTEGER: case V4L2_CTRL_TYPE_BOOLEAN: @@ -371,8 +380,9 @@ void V4L2Device::listControls() break; /* \todo Support compound controls. */ default: - LOG(V4L2, Debug) << "Control type '" << ctrl.type - << "' not supported"; + LOG(V4L2, Debug) + << "Control " << utils::hex(ctrl.id) + << " has unsupported type " << ctrl.type; continue; } From patchwork Sun Oct 13 23:27:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2184 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 852FE6196E for ; Mon, 14 Oct 2019 01:28:03 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 227FAA46 for ; Mon, 14 Oct 2019 01:28:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1571009283; bh=HMIS5efzZzpaKBFnqhQZd0FDqFMk4jydgsem8D3T9mc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=oU0uP15IHFyPG0I8gwsR38Qo3t8dySwzvIqCLZuAk10vWdBCcMekg0mCwLNX/eoOF rt10Xq5e7taiCVsf7i82jly0EGTIIrhLTDoz9X9Nxupy/yMnIHrr000G6lbHRc5MaZ HEsGi1Isch9ux5FpJnwaavE9dg4R8eBarS+MQw2Q= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 14 Oct 2019 02:27:48 +0300 Message-Id: <20191013232755.3292-3-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 Subject: [libcamera-devel] [PATCH 02/10] libcamera: v4l2_controls: Move V4L2ControlId out of V4L2ControlInfo X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Oct 2019 23:28:03 -0000 From: Jacopo Mondi In order to reconcile the libcamera and V4L2 control info maps, we need to move the V4L2ControlId embedded in V4L2ControlInfo map out of the class. Store the V4L2ControlId instances in the V4L2Device that creates them, and only reference them from V4L2ControlInfo. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- src/libcamera/include/v4l2_controls.h | 7 ++++--- src/libcamera/include/v4l2_device.h | 4 +++- src/libcamera/v4l2_controls.cpp | 6 ++++-- src/libcamera/v4l2_device.cpp | 3 ++- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h index 133f5262febf..4d7ac1a133c7 100644 --- a/src/libcamera/include/v4l2_controls.h +++ b/src/libcamera/include/v4l2_controls.h @@ -28,13 +28,14 @@ public: class V4L2ControlInfo { public: - V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl); + V4L2ControlInfo(const V4L2ControlId &id, + const struct v4l2_query_ext_ctrl &ctrl); - const ControlId &id() const { return id_; } + const ControlId &id() const { return *id_; } const ControlRange &range() const { return range_; } private: - V4L2ControlId id_; + const V4L2ControlId *id_; ControlRange range_; }; diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index daa762d58d2b..5a5b85827f23 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -8,7 +8,8 @@ #define __LIBCAMERA_V4L2_DEVICE_H__ #include -#include +#include +#include #include @@ -48,6 +49,7 @@ private: const struct v4l2_ext_control *v4l2Ctrls, unsigned int count); + std::vector> controlIds_; V4L2ControlInfoMap controls_; std::string deviceNode_; int fd_; diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp index dcf31b7a8f26..12c4fb271ba5 100644 --- a/src/libcamera/v4l2_controls.cpp +++ b/src/libcamera/v4l2_controls.cpp @@ -122,10 +122,12 @@ V4L2ControlId::V4L2ControlId(const struct v4l2_query_ext_ctrl &ctrl) /** * \brief Construct a V4L2ControlInfo from a struct v4l2_query_ext_ctrl + * \param[in] id The V4L2 control ID * \param[in] ctrl The struct v4l2_query_ext_ctrl as returned by the kernel */ -V4L2ControlInfo::V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl) - : id_(ctrl) +V4L2ControlInfo::V4L2ControlInfo(const V4L2ControlId &id, + const struct v4l2_query_ext_ctrl &ctrl) + : id_(&id) { if (ctrl.type == V4L2_CTRL_TYPE_INTEGER64) range_ = ControlRange(static_cast(ctrl.minimum), diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 54cc214ecce9..144a60b4fe93 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -386,9 +386,10 @@ void V4L2Device::listControls() continue; } + controlIds_.emplace_back(utils::make_unique(ctrl)); ctrls.emplace(std::piecewise_construct, std::forward_as_tuple(ctrl.id), - std::forward_as_tuple(ctrl)); + std::forward_as_tuple(*controlIds_.back().get(), ctrl)); } controls_ = std::move(ctrls); From patchwork Sun Oct 13 23:27:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2185 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CF4636196E for ; Mon, 14 Oct 2019 01:28:03 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6F1C933A for ; Mon, 14 Oct 2019 01:28:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1571009283; bh=q/SCJ6Yq4hXUsx5bb0H6QxnjzRdVXL9/wz89SxmhqHo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=pKQGCvDg99q6jiSmrx6KcWnT85w/BssSSsERKrvI4u3rf5qLF8sCGarMnFj2PM/Vv QYAU8WsDmdxphby0EVUfbSUuRh89GYTE+r28Dkm/fJyczKj7RqEq3tNwvEBAsDE1kk rXB8Q4bJTLU0ZeRVWJvdVIHOLSc3DXuuIhopPyZM= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 14 Oct 2019 02:27:49 +0300 Message-Id: <20191013232755.3292-4-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 Subject: [libcamera-devel] [PATCH 03/10] libcamera: controls: Prevent copies of ControlId class X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Oct 2019 23:28:04 -0000 Now that the V4L2ControlId embedded in V4L2ControlInfo has been moved out and doesn't require to be copied anymore, the base ControlId class doesn't need to be copyable either. Delete the ControlId copy constructor and copy assignment operator. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- include/libcamera/controls.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index ebc4204f98fd..5534a2edb567 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -68,12 +68,11 @@ protected: : id_(id), name_(name), type_(type) { } -#ifndef __DOXYGEN__ - ControlId &operator=(const ControlId &) = default; - ControlId(const ControlId &) = default; -#endif private: + ControlId &operator=(const ControlId &) = delete; + ControlId(const ControlId &) = delete; + unsigned int id_; std::string name_; ControlType type_; From patchwork Sun Oct 13 23:27:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2186 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2FDB36196E for ; Mon, 14 Oct 2019 01:28:04 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BC71280B for ; Mon, 14 Oct 2019 01:28:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1571009283; bh=EZLtkoM3RrjKVvtc5pNKZPhdJcTkqu/72qfBk4GIEJM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=lmhOTBUxCKR5TkV2as3TJ4UePbkrw+1Fgo4VBIxdUmpQsMCscmu8tnFlI2LcK2jhZ hBfmh7R2tH9xq8DmY4gAGZKSe+YUnYfxJZJcc5cIt+fUGR52a2CPWa1GRzz3hiQDQk uUrSnEAHf+WwcMoJ3iy7Vwz7Zvb1ps5t94c4hSFs= From: Laurent Pinchart 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 Subject: [libcamera-devel] [PATCH 04/10] libcamera: v4l2_controls: Index V4L2ControlInfoMap by ControlId * X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Oct 2019 23:28:04 -0000 To bring the libcamera and V4L2 control info maps closer, index the latter by ControlId * like the former. As V4L2ControlInfoMap is widely indexed by V4L2 numerical IDs, add accessors based on numerical IDs. This allows complete removal of the ControId pointer from the V4L2ControlInfo, as the ControId is accessible as the key when iterating over the map. A handful of users have to be modified to adapt to the change. The controlInfo argument from V4L2Device::updateControls() can also be removed as it itsn't used anymore. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- src/libcamera/include/v4l2_controls.h | 40 +++++++++------ src/libcamera/include/v4l2_device.h | 1 - src/libcamera/pipeline/uvcvideo.cpp | 2 +- src/libcamera/pipeline/vimc.cpp | 2 +- src/libcamera/v4l2_controls.cpp | 71 +++++++++++++++++++++------ src/libcamera/v4l2_device.cpp | 25 +++------- 6 files changed, 92 insertions(+), 49 deletions(-) diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h index 4d7ac1a133c7..ca7217501256 100644 --- a/src/libcamera/include/v4l2_controls.h +++ b/src/libcamera/include/v4l2_controls.h @@ -28,31 +28,41 @@ public: class V4L2ControlInfo { public: - V4L2ControlInfo(const V4L2ControlId &id, - const struct v4l2_query_ext_ctrl &ctrl); + V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl); - const ControlId &id() const { return *id_; } const ControlRange &range() const { return range_; } private: - const V4L2ControlId *id_; ControlRange range_; }; -class V4L2ControlInfoMap : private std::map +class V4L2ControlInfoMap : private std::map { public: - V4L2ControlInfoMap &operator=(std::map &&info); + V4L2ControlInfoMap &operator=(std::map &&info); - using std::map::begin; - using std::map::cbegin; - using std::map::end; - using std::map::cend; - using std::map::at; - using std::map::empty; - using std::map::size; - using std::map::count; - using std::map::find; + using std::map::key_type; + using std::map::mapped_type; + using std::map::value_type; + using std::map::size_type; + using std::map::iterator; + using std::map::const_iterator; + + using std::map::begin; + using std::map::cbegin; + using std::map::end; + using std::map::cend; + using std::map::at; + using std::map::empty; + using std::map::size; + using std::map::count; + using std::map::find; + + mapped_type &at(unsigned int key); + const mapped_type &at(unsigned int key) const; + size_type count(unsigned int key) const; + iterator find(unsigned int key); + const_iterator find(unsigned int key) const; const ControlIdMap &idmap() const { return idmap_; } diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index 5a5b85827f23..f30b1c2cde34 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -45,7 +45,6 @@ protected: private: void listControls(); void updateControls(ControlList *ctrls, - const V4L2ControlInfo **controlInfo, const struct v4l2_ext_control *v4l2Ctrls, unsigned int count); diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 547ad5ca4e55..4d76b5fd9347 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -340,7 +340,7 @@ int UVCCameraData::init(MediaEntity *entity) const V4L2ControlInfo &info = ctrl.second; const ControlId *id; - switch (info.id().id()) { + switch (ctrl.first->id()) { case V4L2_CID_BRIGHTNESS: id = &controls::Brightness; break; diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 53d00360eb6e..78c0fe5ae509 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -416,7 +416,7 @@ int VimcCameraData::init(MediaDevice *media) const V4L2ControlInfo &info = ctrl.second; const ControlId *id; - switch (info.id().id()) { + switch (ctrl.first->id()) { case V4L2_CID_BRIGHTNESS: id = &controls::Brightness; break; diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp index 12c4fb271ba5..9a5e4830db91 100644 --- a/src/libcamera/v4l2_controls.cpp +++ b/src/libcamera/v4l2_controls.cpp @@ -122,12 +122,9 @@ V4L2ControlId::V4L2ControlId(const struct v4l2_query_ext_ctrl &ctrl) /** * \brief Construct a V4L2ControlInfo from a struct v4l2_query_ext_ctrl - * \param[in] id The V4L2 control ID * \param[in] ctrl The struct v4l2_query_ext_ctrl as returned by the kernel */ -V4L2ControlInfo::V4L2ControlInfo(const V4L2ControlId &id, - const struct v4l2_query_ext_ctrl &ctrl) - : id_(&id) +V4L2ControlInfo::V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl) { if (ctrl.type == V4L2_CTRL_TYPE_INTEGER64) range_ = ControlRange(static_cast(ctrl.minimum), @@ -137,12 +134,6 @@ V4L2ControlInfo::V4L2ControlInfo(const V4L2ControlId &id, static_cast(ctrl.maximum)); } -/** - * \fn V4L2ControlInfo::id() - * \brief Retrieve the control ID - * \return The V4L2 control ID - */ - /** * \fn V4L2ControlInfo::range() * \brief Retrieve the control value range @@ -151,7 +142,7 @@ V4L2ControlInfo::V4L2ControlInfo(const V4L2ControlId &id, /** * \class V4L2ControlInfoMap - * \brief A map of control ID to V4L2ControlInfo + * \brief A map of controlID to V4L2ControlInfo */ /** @@ -165,17 +156,69 @@ V4L2ControlInfo::V4L2ControlInfo(const V4L2ControlId &id, * * \return The populated V4L2ControlInfoMap */ -V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(std::map &&info) +V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(std::map &&info) { - std::map::operator=(std::move(info)); + std::map::operator=(std::move(info)); idmap_.clear(); for (const auto &ctrl : *this) - idmap_[ctrl.first] = &ctrl.second.id(); + idmap_[ctrl.first->id()] = ctrl.first; return *this; } +/** + * \brief Access specified element by numerical ID + * \param[in] id The numerical ID + * \return A reference to the element whose ID is equal to \a id + */ +V4L2ControlInfoMap::mapped_type &V4L2ControlInfoMap::at(unsigned int id) +{ + return at(idmap_.at(id)); +} + +/** + * \brief Access specified element by numerical ID + * \param[in] id The numerical ID + * \return A const reference to the element whose ID is equal to \a id + */ +const V4L2ControlInfoMap::mapped_type &V4L2ControlInfoMap::at(unsigned int id) const +{ + return at(idmap_.at(id)); +} + +/** + * \brief Count the number of elements matching a numerical ID + * \param[in] id The numerical ID + * \return The number of elements matching the numerical \a id + */ +V4L2ControlInfoMap::size_type V4L2ControlInfoMap::count(unsigned int id) const +{ + return count(idmap_.at(id)); +} + +/** + * \brief Find the element matching a numerical ID + * \param[in] id The numerical ID + * \return An iterator pointing to the element matching the numerical \a id, or + * end() if no such element exists + */ +V4L2ControlInfoMap::iterator V4L2ControlInfoMap::find(unsigned int id) +{ + return find(idmap_.at(id)); +} + +/** + * \brief Find the element matching a numerical ID + * \param[in] id The numerical ID + * \return A const iterator pointing to the element matching the numerical + * \a id, or end() if no such element exists + */ +V4L2ControlInfoMap::const_iterator V4L2ControlInfoMap::find(unsigned int id) const +{ + return find(idmap_.at(id)); +} + /** * \fn const ControlIdMap &V4L2ControlInfoMap::idmap() const * \brief Retrieve the ControlId map diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 144a60b4fe93..4bb7d5950f3a 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -171,7 +171,6 @@ int V4L2Device::getControls(ControlList *ctrls) if (count == 0) return 0; - const V4L2ControlInfo *controlInfo[count]; struct v4l2_ext_control v4l2Ctrls[count]; memset(v4l2Ctrls, 0, sizeof(v4l2Ctrls)); @@ -185,10 +184,7 @@ int V4L2Device::getControls(ControlList *ctrls) return -EINVAL; } - const V4L2ControlInfo *info = &iter->second; - controlInfo[i] = info; v4l2Ctrls[i].id = id->id(); - i++; } @@ -215,7 +211,7 @@ int V4L2Device::getControls(ControlList *ctrls) ret = errorIdx; } - updateControls(ctrls, controlInfo, v4l2Ctrls, count); + updateControls(ctrls, v4l2Ctrls, count); return ret; } @@ -249,7 +245,6 @@ int V4L2Device::setControls(ControlList *ctrls) if (count == 0) return 0; - const V4L2ControlInfo *controlInfo[count]; struct v4l2_ext_control v4l2Ctrls[count]; memset(v4l2Ctrls, 0, sizeof(v4l2Ctrls)); @@ -263,13 +258,11 @@ int V4L2Device::setControls(ControlList *ctrls) return -EINVAL; } - const V4L2ControlInfo *info = &iter->second; - controlInfo[i] = info; v4l2Ctrls[i].id = id->id(); /* Set the v4l2_ext_control value for the write operation. */ const ControlValue &value = ctrl.second; - switch (info->id().type()) { + switch (id->type()) { case ControlTypeInteger64: v4l2Ctrls[i].value64 = value.get(); break; @@ -308,7 +301,7 @@ int V4L2Device::setControls(ControlList *ctrls) ret = errorIdx; } - updateControls(ctrls, controlInfo, v4l2Ctrls, count); + updateControls(ctrls, v4l2Ctrls, count); return ret; } @@ -349,7 +342,7 @@ int V4L2Device::ioctl(unsigned long request, void *argp) */ void V4L2Device::listControls() { - std::map ctrls; + std::map ctrls; struct v4l2_query_ext_ctrl ctrl = {}; /* \todo Add support for menu and compound controls. */ @@ -388,8 +381,8 @@ void V4L2Device::listControls() controlIds_.emplace_back(utils::make_unique(ctrl)); ctrls.emplace(std::piecewise_construct, - std::forward_as_tuple(ctrl.id), - std::forward_as_tuple(*controlIds_.back().get(), ctrl)); + std::forward_as_tuple(controlIds_.back().get()), + std::forward_as_tuple(ctrl)); } controls_ = std::move(ctrls); @@ -399,12 +392,10 @@ void V4L2Device::listControls() * \brief Update the value of the first \a count V4L2 controls in \a ctrls using * values in \a v4l2Ctrls * \param[inout] ctrls List of V4L2 controls to update - * \param[in] controlInfo List of V4L2 control information * \param[in] v4l2Ctrls List of V4L2 extended controls as returned by the driver * \param[in] count The number of controls to update */ void V4L2Device::updateControls(ControlList *ctrls, - const V4L2ControlInfo **controlInfo, const struct v4l2_ext_control *v4l2Ctrls, unsigned int count) { @@ -414,10 +405,10 @@ void V4L2Device::updateControls(ControlList *ctrls, break; const struct v4l2_ext_control *v4l2Ctrl = &v4l2Ctrls[i]; - const V4L2ControlInfo *info = controlInfo[i]; + const ControlId *id = ctrl.first; ControlValue &value = ctrl.second; - switch (info->id().type()) { + switch (id->type()) { case ControlTypeInteger64: value.set(v4l2Ctrl->value64); break; From patchwork Sun Oct 13 23:27:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2187 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7C67D6196E for ; Mon, 14 Oct 2019 01:28:04 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 28D7133A for ; Mon, 14 Oct 2019 01:28:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1571009284; bh=/H7aqonVgd5lCv5aiG8/6QeUPuxnfX0i39jGFD3TiPw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=tjdA7i0IqGUSjDhpDhyjqJw7Xo/J92welx/GuyKJBsCpCdAJ+Z1ggqQtGr65bcDJZ hgJWloCbqusxOb9E797c7U6hBdpfI3txbqjMjVQe99Pt1FItFv5wzYfHayzTMjg/uO KtXtHVwXpJelwD3UV33ts7NLq51kby6qQZ2gOw/A= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 14 Oct 2019 02:27:51 +0300 Message-Id: <20191013232755.3292-6-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 Subject: [libcamera-devel] [PATCH 05/10] test: v4l2_videodevice: controls: Use correct control range in check X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Oct 2019 23:28:04 -0000 A value check on the V4L2_CID_CONTRAST control is using the brightness control range. Fix it. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- test/v4l2_videodevice/controls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp index e59387ab9eba..3add6e67d2cf 100644 --- a/test/v4l2_videodevice/controls.cpp +++ b/test/v4l2_videodevice/controls.cpp @@ -87,7 +87,7 @@ protected: } if (ctrls.get(V4L2_CID_BRIGHTNESS) != brightness.range().min() || - ctrls.get(V4L2_CID_CONTRAST) != brightness.range().max() || + ctrls.get(V4L2_CID_CONTRAST) != contrast.range().max() || ctrls.get(V4L2_CID_SATURATION) != saturation.range().min().get() + 1) { cerr << "Controls not updated when set" << endl; return TestFail; From patchwork Sun Oct 13 23:27:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2188 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C85AE6196E for ; Mon, 14 Oct 2019 01:28:04 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 738A280B for ; Mon, 14 Oct 2019 01:28:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1571009284; bh=2207Q+vgrysFUFCGDBxd6SzFiHatE8Q74PP4SpXJ+RM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=fE1m8gKYDCoFJkhW1pmVHCfpk9Hn16ZXM4hzJZ6RLgf9sBXqWV/SBkmpfbTpouYQS q8VJxk4ddtHrNw3ILRJ95irzhD6phYacWSJJJ6aO9JepxDekHxu0yFtxXs9+B/mNO/ 4CS2hUHoXB1sqp6W+si3XHqn/ZsQS+YIW9G2WtLc= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 14 Oct 2019 02:27:52 +0300 Message-Id: <20191013232755.3292-7-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 Subject: [libcamera-devel] [PATCH 06/10] libcamera: v4l2_controls: Replace V4L2ControlInfo with V4L2ControlRange X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Oct 2019 23:28:06 -0000 The V4L2ControlInfo class only stores a ControlRange. Make it inherit from ControlRange to provide a convenience constructor from a struct v4l2_query_ext_ctrl and rename it to V4L2ControlRange. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- src/ipa/rkisp1/rkisp1.cpp | 8 ++--- src/libcamera/include/v4l2_controls.h | 43 ++++++++++++--------------- src/libcamera/pipeline/uvcvideo.cpp | 4 +-- src/libcamera/pipeline/vimc.cpp | 4 +-- src/libcamera/v4l2_controls.cpp | 30 ++++++++----------- src/libcamera/v4l2_device.cpp | 2 +- test/v4l2_videodevice/controls.cpp | 24 +++++++-------- 7 files changed, 52 insertions(+), 63 deletions(-) diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 13059d99036c..d64c334cbf0c 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -83,12 +83,12 @@ void IPARkISP1::configure(const std::map &streamConfig, autoExposure_ = true; - minExposure_ = std::max(itExp->second.range().min().get(), 1); - maxExposure_ = itExp->second.range().max().get(); + minExposure_ = std::max(itExp->second.min().get(), 1); + maxExposure_ = itExp->second.max().get(); exposure_ = minExposure_; - minGain_ = std::max(itGain->second.range().min().get(), 1); - maxGain_ = itGain->second.range().max().get(); + minGain_ = std::max(itGain->second.min().get(), 1); + maxGain_ = itGain->second.max().get(); gain_ = minGain_; LOG(IPARkISP1, Info) diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h index ca7217501256..741569824b68 100644 --- a/src/libcamera/include/v4l2_controls.h +++ b/src/libcamera/include/v4l2_controls.h @@ -25,38 +25,33 @@ public: V4L2ControlId(const struct v4l2_query_ext_ctrl &ctrl); }; -class V4L2ControlInfo +class V4L2ControlRange : public ControlRange { public: - V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl); - - const ControlRange &range() const { return range_; } - -private: - ControlRange range_; + V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl); }; -class V4L2ControlInfoMap : private std::map +class V4L2ControlInfoMap : private std::map { public: - V4L2ControlInfoMap &operator=(std::map &&info); + V4L2ControlInfoMap &operator=(std::map &&info); - using std::map::key_type; - using std::map::mapped_type; - using std::map::value_type; - using std::map::size_type; - using std::map::iterator; - using std::map::const_iterator; + using std::map::key_type; + using std::map::mapped_type; + using std::map::value_type; + using std::map::size_type; + using std::map::iterator; + using std::map::const_iterator; - using std::map::begin; - using std::map::cbegin; - using std::map::end; - using std::map::cend; - using std::map::at; - using std::map::empty; - using std::map::size; - using std::map::count; - using std::map::find; + using std::map::begin; + using std::map::cbegin; + using std::map::end; + using std::map::cend; + using std::map::at; + using std::map::empty; + using std::map::size; + using std::map::count; + using std::map::find; mapped_type &at(unsigned int key); const mapped_type &at(unsigned int key) const; diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 4d76b5fd9347..7356585b982e 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -337,7 +337,7 @@ int UVCCameraData::init(MediaEntity *entity) /* Initialise the supported controls. */ const V4L2ControlInfoMap &controls = video_->controls(); for (const auto &ctrl : controls) { - const V4L2ControlInfo &info = ctrl.second; + const V4L2ControlRange &range = ctrl.second; const ControlId *id; switch (ctrl.first->id()) { @@ -362,7 +362,7 @@ int UVCCameraData::init(MediaEntity *entity) controlInfo_.emplace(std::piecewise_construct, std::forward_as_tuple(id), - std::forward_as_tuple(info.range())); + std::forward_as_tuple(range)); } return 0; diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 78c0fe5ae509..87e7e54e964f 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -413,7 +413,7 @@ int VimcCameraData::init(MediaDevice *media) /* Initialise the supported controls. */ const V4L2ControlInfoMap &controls = sensor_->controls(); for (const auto &ctrl : controls) { - const V4L2ControlInfo &info = ctrl.second; + const V4L2ControlRange &range = ctrl.second; const ControlId *id; switch (ctrl.first->id()) { @@ -432,7 +432,7 @@ int VimcCameraData::init(MediaDevice *media) controlInfo_.emplace(std::piecewise_construct, std::forward_as_tuple(id), - std::forward_as_tuple(info.range())); + std::forward_as_tuple(range)); } return 0; diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp index 9a5e4830db91..4aab34b9a2b4 100644 --- a/src/libcamera/v4l2_controls.cpp +++ b/src/libcamera/v4l2_controls.cpp @@ -104,14 +104,14 @@ V4L2ControlId::V4L2ControlId(const struct v4l2_query_ext_ctrl &ctrl) } /** - * \class V4L2ControlInfo + * \class V4L2ControlRange * \brief Information on a V4L2 control * - * The V4L2ControlInfo class represents all the information related to a V4L2 + * The V4L2ControlRange class represents all the information related to a V4L2 * control, such as its ID, its type, its user-readable name and the expected * size of its value data. * - * V4L2ControlInfo instances are created by inspecting the fieldS of a struct + * V4L2ControlRange instances are created by inspecting the fieldS of a struct * v4l2_query_ext_ctrl structure, after it has been filled by the device driver * as a consequence of a VIDIOC_QUERY_EXT_CTRL ioctl call. * @@ -121,28 +121,22 @@ V4L2ControlId::V4L2ControlId(const struct v4l2_query_ext_ctrl &ctrl) */ /** - * \brief Construct a V4L2ControlInfo from a struct v4l2_query_ext_ctrl + * \brief Construct a V4L2ControlRange from a struct v4l2_query_ext_ctrl * \param[in] ctrl The struct v4l2_query_ext_ctrl as returned by the kernel */ -V4L2ControlInfo::V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl) +V4L2ControlRange::V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl) { if (ctrl.type == V4L2_CTRL_TYPE_INTEGER64) - range_ = ControlRange(static_cast(ctrl.minimum), - static_cast(ctrl.maximum)); + ControlRange::operator=(ControlRange(static_cast(ctrl.minimum), + static_cast(ctrl.maximum))); else - range_ = ControlRange(static_cast(ctrl.minimum), - static_cast(ctrl.maximum)); + ControlRange::operator=(ControlRange(static_cast(ctrl.minimum), + static_cast(ctrl.maximum))); } -/** - * \fn V4L2ControlInfo::range() - * \brief Retrieve the control value range - * \return The V4L2 control value range - */ - /** * \class V4L2ControlInfoMap - * \brief A map of controlID to V4L2ControlInfo + * \brief A map of controlID to V4L2ControlRange */ /** @@ -156,9 +150,9 @@ V4L2ControlInfo::V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl) * * \return The populated V4L2ControlInfoMap */ -V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(std::map &&info) +V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(std::map &&info) { - std::map::operator=(std::move(info)); + std::map::operator=(std::move(info)); idmap_.clear(); for (const auto &ctrl : *this) diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 4bb7d5950f3a..133f8abc8f13 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -342,7 +342,7 @@ int V4L2Device::ioctl(unsigned long request, void *argp) */ void V4L2Device::listControls() { - std::map ctrls; + std::map ctrls; struct v4l2_query_ext_ctrl ctrl = {}; /* \todo Add support for menu and compound controls. */ diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp index 3add6e67d2cf..d4b7588eb362 100644 --- a/test/v4l2_videodevice/controls.cpp +++ b/test/v4l2_videodevice/controls.cpp @@ -41,9 +41,9 @@ protected: return TestFail; } - const V4L2ControlInfo &brightness = info.find(V4L2_CID_BRIGHTNESS)->second; - const V4L2ControlInfo &contrast = info.find(V4L2_CID_CONTRAST)->second; - const V4L2ControlInfo &saturation = info.find(V4L2_CID_SATURATION)->second; + const V4L2ControlRange &brightness = info.find(V4L2_CID_BRIGHTNESS)->second; + const V4L2ControlRange &contrast = info.find(V4L2_CID_CONTRAST)->second; + const V4L2ControlRange &saturation = info.find(V4L2_CID_SATURATION)->second; /* Test getting controls. */ V4L2ControlList ctrls(info); @@ -65,9 +65,9 @@ protected: } /* Test setting controls. */ - ctrls.set(V4L2_CID_BRIGHTNESS, brightness.range().min()); - ctrls.set(V4L2_CID_CONTRAST, contrast.range().max()); - ctrls.set(V4L2_CID_SATURATION, saturation.range().min()); + ctrls.set(V4L2_CID_BRIGHTNESS, brightness.min()); + ctrls.set(V4L2_CID_CONTRAST, contrast.max()); + ctrls.set(V4L2_CID_SATURATION, saturation.min()); ret = capture_->setControls(&ctrls); if (ret) { @@ -76,9 +76,9 @@ protected: } /* Test setting controls outside of range. */ - ctrls.set(V4L2_CID_BRIGHTNESS, brightness.range().min().get() - 1); - ctrls.set(V4L2_CID_CONTRAST, contrast.range().max().get() + 1); - ctrls.set(V4L2_CID_SATURATION, saturation.range().min().get() + 1); + ctrls.set(V4L2_CID_BRIGHTNESS, brightness.min().get() - 1); + ctrls.set(V4L2_CID_CONTRAST, contrast.max().get() + 1); + ctrls.set(V4L2_CID_SATURATION, saturation.min().get() + 1); ret = capture_->setControls(&ctrls); if (ret) { @@ -86,9 +86,9 @@ protected: return TestFail; } - if (ctrls.get(V4L2_CID_BRIGHTNESS) != brightness.range().min() || - ctrls.get(V4L2_CID_CONTRAST) != contrast.range().max() || - ctrls.get(V4L2_CID_SATURATION) != saturation.range().min().get() + 1) { + if (ctrls.get(V4L2_CID_BRIGHTNESS) != brightness.min() || + ctrls.get(V4L2_CID_CONTRAST) != contrast.max() || + ctrls.get(V4L2_CID_SATURATION) != saturation.min().get() + 1) { cerr << "Controls not updated when set" << endl; return TestFail; } From patchwork Sun Oct 13 23:27:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2189 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 29BF161975 for ; Mon, 14 Oct 2019 01:28:05 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C045533A for ; Mon, 14 Oct 2019 01:28:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1571009284; bh=Lhpf6CquKnki7wmWt03nVOJCygOR7YB7fRmQ+ZfIox8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=El34xbXksxGUcM47xOTQWPon6JMcrpgEdHgu1N+q8kyuJGjakrVN48uBjlWxAzldy HXnZ5lbNEZfF68RK0VBzJxljQkaUXBOEwNdWRUPeQqF0oyuMyBY5iyp78inhRp0u9k /YDaKKnAeZepn7wDQvOZNsombVKQKU2nDFzFTTog= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 14 Oct 2019 02:27:53 +0300 Message-Id: <20191013232755.3292-8-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 Subject: [libcamera-devel] [PATCH 07/10] libcamera: v4l2_controls: Store a ControlRange in V4L2ControlInfoMap X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Oct 2019 23:28:06 -0000 V4L2ControlRange only offers a convenience constructor for a ControlRange. Store the ControlRange instead of V4L2ControlRange in V4L2ControlInfoMap to make the map less dependent on V4L2 types. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- src/libcamera/include/v4l2_controls.h | 34 +++++++++++++-------------- src/libcamera/pipeline/uvcvideo.cpp | 2 +- src/libcamera/pipeline/vimc.cpp | 2 +- src/libcamera/v4l2_controls.cpp | 6 ++--- src/libcamera/v4l2_device.cpp | 6 ++--- test/v4l2_videodevice/controls.cpp | 6 ++--- 6 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h index 741569824b68..7d3528b07f94 100644 --- a/src/libcamera/include/v4l2_controls.h +++ b/src/libcamera/include/v4l2_controls.h @@ -31,27 +31,27 @@ public: V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl); }; -class V4L2ControlInfoMap : private std::map +class V4L2ControlInfoMap : private std::map { public: - V4L2ControlInfoMap &operator=(std::map &&info); + V4L2ControlInfoMap &operator=(std::map &&info); - using std::map::key_type; - using std::map::mapped_type; - using std::map::value_type; - using std::map::size_type; - using std::map::iterator; - using std::map::const_iterator; + using std::map::key_type; + using std::map::mapped_type; + using std::map::value_type; + using std::map::size_type; + using std::map::iterator; + using std::map::const_iterator; - using std::map::begin; - using std::map::cbegin; - using std::map::end; - using std::map::cend; - using std::map::at; - using std::map::empty; - using std::map::size; - using std::map::count; - using std::map::find; + using std::map::begin; + using std::map::cbegin; + using std::map::end; + using std::map::cend; + using std::map::at; + using std::map::empty; + using std::map::size; + using std::map::count; + using std::map::find; mapped_type &at(unsigned int key); const mapped_type &at(unsigned int key) const; diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 7356585b982e..018c7691d263 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -337,7 +337,7 @@ int UVCCameraData::init(MediaEntity *entity) /* Initialise the supported controls. */ const V4L2ControlInfoMap &controls = video_->controls(); for (const auto &ctrl : controls) { - const V4L2ControlRange &range = ctrl.second; + const ControlRange &range = ctrl.second; const ControlId *id; switch (ctrl.first->id()) { diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 87e7e54e964f..f7f82edc6530 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -413,7 +413,7 @@ int VimcCameraData::init(MediaDevice *media) /* Initialise the supported controls. */ const V4L2ControlInfoMap &controls = sensor_->controls(); for (const auto &ctrl : controls) { - const V4L2ControlRange &range = ctrl.second; + const ControlRange &range = ctrl.second; const ControlId *id; switch (ctrl.first->id()) { diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp index 4aab34b9a2b4..e27c70eeec87 100644 --- a/src/libcamera/v4l2_controls.cpp +++ b/src/libcamera/v4l2_controls.cpp @@ -136,7 +136,7 @@ V4L2ControlRange::V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl) /** * \class V4L2ControlInfoMap - * \brief A map of controlID to V4L2ControlRange + * \brief A map of controlID to ControlRange for V4L2 controls */ /** @@ -150,9 +150,9 @@ V4L2ControlRange::V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl) * * \return The populated V4L2ControlInfoMap */ -V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(std::map &&info) +V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(std::map &&info) { - std::map::operator=(std::move(info)); + std::map::operator=(std::move(info)); idmap_.clear(); for (const auto &ctrl : *this) diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 133f8abc8f13..47999e70073c 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -342,7 +342,7 @@ int V4L2Device::ioctl(unsigned long request, void *argp) */ void V4L2Device::listControls() { - std::map ctrls; + std::map ctrls; struct v4l2_query_ext_ctrl ctrl = {}; /* \todo Add support for menu and compound controls. */ @@ -380,9 +380,7 @@ void V4L2Device::listControls() } controlIds_.emplace_back(utils::make_unique(ctrl)); - ctrls.emplace(std::piecewise_construct, - std::forward_as_tuple(controlIds_.back().get()), - std::forward_as_tuple(ctrl)); + ctrls.emplace(controlIds_.back().get(), V4L2ControlRange(ctrl)); } controls_ = std::move(ctrls); diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp index d4b7588eb362..182228f3a5b1 100644 --- a/test/v4l2_videodevice/controls.cpp +++ b/test/v4l2_videodevice/controls.cpp @@ -41,9 +41,9 @@ protected: return TestFail; } - const V4L2ControlRange &brightness = info.find(V4L2_CID_BRIGHTNESS)->second; - const V4L2ControlRange &contrast = info.find(V4L2_CID_CONTRAST)->second; - const V4L2ControlRange &saturation = info.find(V4L2_CID_SATURATION)->second; + const ControlRange &brightness = info.find(V4L2_CID_BRIGHTNESS)->second; + const ControlRange &contrast = info.find(V4L2_CID_CONTRAST)->second; + const ControlRange &saturation = info.find(V4L2_CID_SATURATION)->second; /* Test getting controls. */ V4L2ControlList ctrls(info); From patchwork Sun Oct 13 23:27:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2190 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6D6BE61971 for ; Mon, 14 Oct 2019 01:28:05 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1943B80B for ; Mon, 14 Oct 2019 01:28:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1571009285; bh=wKnuwDnnphu8EA/z0eb2NMwskL1qBamB2RGEB0mKBt0=; h=From:To:Subject:Date:In-Reply-To:References:From; b=H88eo5nAvmMtPNvaV9P+O77LGhHkmhAHhz7mmOkAiyeAyjxmf8ndUGmggZRlsDvQJ TUUABznJBWj0CA8TvELfz9xS+X/oNvYfANrTtAS63kXmsS7qoTnmXbdf1ChAQBZH/3 NJ0IkZer1JEdCHGoIb1tR8vyUGjiyjjw9/zsG62U= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 14 Oct 2019 02:27:54 +0300 Message-Id: <20191013232755.3292-9-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 Subject: [libcamera-devel] [PATCH 08/10] libcamera: v4l2_controls: Derive V4L2ControlInfoMap from ControlInfoMap X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Oct 2019 23:28:06 -0000 Replace the std::map<> used as the base type for V4L2ControlInfoMap by ControlInfoMap, which is an alias for an std::unsorted_map<> with the same key and value types. This shortens the code. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/libcamera/include/v4l2_controls.h | 34 +++++++++++++-------------- src/libcamera/v4l2_controls.cpp | 6 ++--- src/libcamera/v4l2_device.cpp | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h index 7d3528b07f94..c427b845d8b4 100644 --- a/src/libcamera/include/v4l2_controls.h +++ b/src/libcamera/include/v4l2_controls.h @@ -31,27 +31,27 @@ public: V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl); }; -class V4L2ControlInfoMap : private std::map +class V4L2ControlInfoMap : private ControlInfoMap { public: - V4L2ControlInfoMap &operator=(std::map &&info); + V4L2ControlInfoMap &operator=(ControlInfoMap &&info); - using std::map::key_type; - using std::map::mapped_type; - using std::map::value_type; - using std::map::size_type; - using std::map::iterator; - using std::map::const_iterator; + using ControlInfoMap::key_type; + using ControlInfoMap::mapped_type; + using ControlInfoMap::value_type; + using ControlInfoMap::size_type; + using ControlInfoMap::iterator; + using ControlInfoMap::const_iterator; - using std::map::begin; - using std::map::cbegin; - using std::map::end; - using std::map::cend; - using std::map::at; - using std::map::empty; - using std::map::size; - using std::map::count; - using std::map::find; + using ControlInfoMap::begin; + using ControlInfoMap::cbegin; + using ControlInfoMap::end; + using ControlInfoMap::cend; + using ControlInfoMap::at; + using ControlInfoMap::empty; + using ControlInfoMap::size; + using ControlInfoMap::count; + using ControlInfoMap::find; mapped_type &at(unsigned int key); const mapped_type &at(unsigned int key) const; diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp index e27c70eeec87..e783457caf94 100644 --- a/src/libcamera/v4l2_controls.cpp +++ b/src/libcamera/v4l2_controls.cpp @@ -140,7 +140,7 @@ V4L2ControlRange::V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl) */ /** - * \brief Move assignment operator from plain map + * \brief Move assignment operator from a ControlInfoMap * \param[in] info The control info map * * Populate the map by replacing its contents with those of \a info using move @@ -150,9 +150,9 @@ V4L2ControlRange::V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl) * * \return The populated V4L2ControlInfoMap */ -V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(std::map &&info) +V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(ControlInfoMap &&info) { - std::map::operator=(std::move(info)); + ControlInfoMap::operator=(std::move(info)); idmap_.clear(); for (const auto &ctrl : *this) diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 47999e70073c..06155eb51c03 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -342,7 +342,7 @@ int V4L2Device::ioctl(unsigned long request, void *argp) */ void V4L2Device::listControls() { - std::map ctrls; + ControlInfoMap ctrls; struct v4l2_query_ext_ctrl ctrl = {}; /* \todo Add support for menu and compound controls. */ From patchwork Sun Oct 13 23:27:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2191 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CFA1E6197F for ; Mon, 14 Oct 2019 01:28:05 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6693C33A for ; Mon, 14 Oct 2019 01:28:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1571009285; bh=MDpr4eiKwDRMeXtOsR14gb1dyNY2IM5IeXVqOjFy6Yc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=rcuCFC+B3zIsJFBcUVs5Mj34IrRfAoCu/T7Rk0b5DeOlhFJJBp5XBZ2Klzy4vdBqg yjK18njjix4YQnJofM02P18BXz7nArmPwmm6WQgBTfAezEUZq10tYhXwxTh+AhTAwU bN7jvQ/+thX47yPFxQckbzbEQ51GYlhTP7bPtn2A= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 14 Oct 2019 02:27:55 +0300 Message-Id: <20191013232755.3292-10-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 Subject: [libcamera-devel] [PATCH 09/10] libcamera: controls: Merge ControlInfoMap and V4L2ControlInfoMap X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Oct 2019 23:28:06 -0000 The ControlInfoMap and V4L2ControlInfoMap classes are very similar, with the latter adding convenience accessors based on numerical IDs for the former, as well as a cached idmap. Both features can be useful for ControlInfoMap in the context of serialisation, and merging the two classes will further simplify the IPA API. Import all the features of V4L2ControlInfoMap into ControlInfoMap, turning the latter into a real class. A few new constructors and assignment operators are added for completeness. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- include/ipa/ipa_interface.h | 2 +- include/libcamera/controls.h | 45 +++++++- src/ipa/ipa_vimc.cpp | 2 +- src/ipa/rkisp1/rkisp1.cpp | 6 +- src/libcamera/camera_sensor.cpp | 2 +- src/libcamera/controls.cpp | 139 ++++++++++++++++++++++- src/libcamera/include/camera_sensor.h | 4 +- src/libcamera/include/v4l2_controls.h | 36 +----- src/libcamera/include/v4l2_device.h | 4 +- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 11 +- src/libcamera/pipeline/uvcvideo.cpp | 12 +- src/libcamera/pipeline/vimc.cpp | 11 +- src/libcamera/proxy/ipa_proxy_linux.cpp | 2 +- src/libcamera/v4l2_controls.cpp | 94 +-------------- src/libcamera/v4l2_device.cpp | 2 +- test/v4l2_videodevice/controls.cpp | 2 +- 16 files changed, 220 insertions(+), 154 deletions(-) diff --git a/include/ipa/ipa_interface.h b/include/ipa/ipa_interface.h index dfb1bcbee516..8fd658af5fdb 100644 --- a/include/ipa/ipa_interface.h +++ b/include/ipa/ipa_interface.h @@ -43,7 +43,7 @@ public: virtual int init() = 0; virtual void configure(const std::map &streamConfig, - const std::map &entityControls) = 0; + const std::map &entityControls) = 0; virtual void mapBuffers(const std::vector &buffers) = 0; virtual void unmapBuffers(const std::vector &ids) = 0; diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 5534a2edb567..80414c6f0748 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -118,7 +118,50 @@ private: }; using ControlIdMap = std::unordered_map; -using ControlInfoMap = std::unordered_map; + +class ControlInfoMap : private std::unordered_map +{ +public: + using Map = std::unordered_map; + + ControlInfoMap() = default; + ControlInfoMap(const ControlInfoMap &other) = default; + ControlInfoMap(std::initializer_list init); + + ControlInfoMap &operator=(const ControlInfoMap &other) = default; + ControlInfoMap &operator=(std::initializer_list init); + ControlInfoMap &operator=(Map &&info); + + using Map::key_type; + using Map::mapped_type; + using Map::value_type; + using Map::size_type; + using Map::iterator; + using Map::const_iterator; + + using Map::begin; + using Map::cbegin; + using Map::end; + using Map::cend; + using Map::at; + using Map::empty; + using Map::size; + using Map::count; + using Map::find; + + mapped_type &at(unsigned int key); + const mapped_type &at(unsigned int key) const; + size_type count(unsigned int key) const; + iterator find(unsigned int key); + const_iterator find(unsigned int key) const; + + const ControlIdMap &idmap() const { return idmap_; } + +private: + void generateIdmap(); + + ControlIdMap idmap_; +}; class ControlList { diff --git a/src/ipa/ipa_vimc.cpp b/src/ipa/ipa_vimc.cpp index 620dc25f456e..63d578b4e2aa 100644 --- a/src/ipa/ipa_vimc.cpp +++ b/src/ipa/ipa_vimc.cpp @@ -31,7 +31,7 @@ public: int init() override; void configure(const std::map &streamConfig, - const std::map &entityControls) override {} + const std::map &entityControls) override {} void mapBuffers(const std::vector &buffers) override {} void unmapBuffers(const std::vector &ids) override {} void processEvent(const IPAOperationData &event) override {} diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index d64c334cbf0c..bd703898c523 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -33,7 +33,7 @@ public: int init() override { return 0; } void configure(const std::map &streamConfig, - const std::map &entityControls) override; + const std::map &entityControls) override; void mapBuffers(const std::vector &buffers) override; void unmapBuffers(const std::vector &ids) override; void processEvent(const IPAOperationData &event) override; @@ -49,7 +49,7 @@ private: std::map bufferInfo_; - V4L2ControlInfoMap ctrls_; + ControlInfoMap ctrls_; /* Camera sensor controls. */ bool autoExposure_; @@ -62,7 +62,7 @@ private: }; void IPARkISP1::configure(const std::map &streamConfig, - const std::map &entityControls) + const std::map &entityControls) { if (entityControls.empty()) return; diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 1b8e8c0e07da..86f0c772861b 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -251,7 +251,7 @@ int CameraSensor::setFormat(V4L2SubdeviceFormat *format) * \brief Retrieve the supported V4L2 controls and their information * \return A map of the V4L2 controls supported by the sensor */ -const V4L2ControlInfoMap &CameraSensor::controls() const +const ControlInfoMap &CameraSensor::controls() const { return subdev_->controls(); } diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 6a0301f3a2ae..bf7634aab470 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -393,10 +393,147 @@ std::string ControlRange::toString() const */ /** - * \typedef ControlInfoMap + * \class ControlInfoMap * \brief A map of ControlId to ControlRange + * + * The ControlInfoMap class describes controls supported by an object as an + * unsorted map of ControlId pointers to ControlRange instances. Unlike the + * standard std::unsorted_map<> class, it is designed the be immutable once + * constructed, and thus only exposes the read accessors of the + * std::unsorted_map<> base class. + * + * In addition to the features of the standard unsorted map, this class also + * provides access to the mapped elements using numerical ID keys. It maintains + * an internal map of numerical ID to ControlId for this purpose, and exposes it + * through the idmap() method to help construction of ControlList instances. */ +/** + * \typedef ControlInfoMap::Map + * \brief The base std::unsorted_map<> container + */ + +/** + * \fn ControlInfoMap::ControlInfoMap(const ControlInfoMap &other) + * \brief Copy constructor, construct a ControlInfoMap from a copy of \a other + * \param[in] other The other ControlInfoMap + */ + +/** + * \brief Construct a ControlInfoMap from an initializer list + * \param[in] init The initializer list + */ +ControlInfoMap::ControlInfoMap(std::initializer_list init) + : Map(init) +{ + generateIdmap(); +} + +/** + * \fn ControlInfoMap &ControlInfoMap::operator=(const ControlInfoMap &other) + * \brief Copy assignment operator, replace the contents with a copy of \a other + * \param[in] other The other ControlInfoMap + * \return A reference to the ControlInfoMap + */ + +/** + * \brief Replace the contents with those from the initializer list + * \param[in] init The initializer list + * \return A reference to the ControlInfoMap + */ +ControlInfoMap &ControlInfoMap::operator=(std::initializer_list init) +{ + Map::operator=(init); + generateIdmap(); + return *this; +} + +/** + * \brief Move assignment operator from a plain map + * \param[in] info The control info plain map + * + * Populate the map by replacing its contents with those of \a info using move + * semantics. Upon return the \a info map will be empty. + * + * \return A reference to the populated ControlInfoMap + */ +ControlInfoMap &ControlInfoMap::operator=(Map &&info) +{ + Map::operator=(std::move(info)); + generateIdmap(); + return *this; +} + +/** + * \brief Access specified element by numerical ID + * \param[in] id The numerical ID + * \return A reference to the element whose ID is equal to \a id + */ +ControlInfoMap::mapped_type &ControlInfoMap::at(unsigned int id) +{ + return at(idmap_.at(id)); +} + +/** + * \brief Access specified element by numerical ID + * \param[in] id The numerical ID + * \return A const reference to the element whose ID is equal to \a id + */ +const ControlInfoMap::mapped_type &ControlInfoMap::at(unsigned int id) const +{ + return at(idmap_.at(id)); +} + +/** + * \brief Count the number of elements matching a numerical ID + * \param[in] id The numerical ID + * \return The number of elements matching the numerical \a id + */ +ControlInfoMap::size_type ControlInfoMap::count(unsigned int id) const +{ + return count(idmap_.at(id)); +} + +/** + * \brief Find the element matching a numerical ID + * \param[in] id The numerical ID + * \return An iterator pointing to the element matching the numerical \a id, or + * end() if no such element exists + */ +ControlInfoMap::iterator ControlInfoMap::find(unsigned int id) +{ + return find(idmap_.at(id)); +} + +/** + * \brief Find the element matching a numerical ID + * \param[in] id The numerical ID + * \return A const iterator pointing to the element matching the numerical + * \a id, or end() if no such element exists + */ +ControlInfoMap::const_iterator ControlInfoMap::find(unsigned int id) const +{ + return find(idmap_.at(id)); +} + +/** + * \fn const ControlIdMap &ControlInfoMap::idmap() const + * \brief Retrieve the ControlId map + * + * Constructing ControlList instances for V4L2 controls requires a ControlIdMap + * for the V4L2 device that the control list targets. This helper method + * returns a suitable idmap for that purpose. + * + * \return The ControlId map + */ + +void ControlInfoMap::generateIdmap() +{ + idmap_.clear(); + for (const auto &ctrl : *this) + idmap_[ctrl.first->id()] = ctrl.first; +} + /** * \class ControlList * \brief Associate a list of ControlId with their values for an object diff --git a/src/libcamera/include/camera_sensor.h b/src/libcamera/include/camera_sensor.h index f426e29b84bf..1fb36a4f4951 100644 --- a/src/libcamera/include/camera_sensor.h +++ b/src/libcamera/include/camera_sensor.h @@ -16,9 +16,9 @@ namespace libcamera { +class ControlInfoMap; class ControlList; class MediaEntity; -class V4L2ControlInfoMap; class V4L2Subdevice; struct V4L2SubdeviceFormat; @@ -43,7 +43,7 @@ public: const Size &size) const; int setFormat(V4L2SubdeviceFormat *format); - const V4L2ControlInfoMap &controls() const; + const ControlInfoMap &controls() const; int getControls(ControlList *ctrls); int setControls(ControlList *ctrls); diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h index c427b845d8b4..e16c4957f9d1 100644 --- a/src/libcamera/include/v4l2_controls.h +++ b/src/libcamera/include/v4l2_controls.h @@ -31,44 +31,10 @@ public: V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl); }; -class V4L2ControlInfoMap : private ControlInfoMap -{ -public: - V4L2ControlInfoMap &operator=(ControlInfoMap &&info); - - using ControlInfoMap::key_type; - using ControlInfoMap::mapped_type; - using ControlInfoMap::value_type; - using ControlInfoMap::size_type; - using ControlInfoMap::iterator; - using ControlInfoMap::const_iterator; - - using ControlInfoMap::begin; - using ControlInfoMap::cbegin; - using ControlInfoMap::end; - using ControlInfoMap::cend; - using ControlInfoMap::at; - using ControlInfoMap::empty; - using ControlInfoMap::size; - using ControlInfoMap::count; - using ControlInfoMap::find; - - mapped_type &at(unsigned int key); - const mapped_type &at(unsigned int key) const; - size_type count(unsigned int key) const; - iterator find(unsigned int key); - const_iterator find(unsigned int key) const; - - const ControlIdMap &idmap() const { return idmap_; } - -private: - ControlIdMap idmap_; -}; - class V4L2ControlList : public ControlList { public: - V4L2ControlList(const V4L2ControlInfoMap &info) + V4L2ControlList(const ControlInfoMap &info) : ControlList(info.idmap()) { } diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h index f30b1c2cde34..6bfddefe336c 100644 --- a/src/libcamera/include/v4l2_device.h +++ b/src/libcamera/include/v4l2_device.h @@ -24,7 +24,7 @@ public: void close(); bool isOpen() const { return fd_ != -1; } - const V4L2ControlInfoMap &controls() const { return controls_; } + const ControlInfoMap &controls() const { return controls_; } int getControls(ControlList *ctrls); int setControls(ControlList *ctrls); @@ -49,7 +49,7 @@ private: unsigned int count); std::vector> controlIds_; - V4L2ControlInfoMap controls_; + ControlInfoMap controls_; std::string deviceNode_; int fd_; }; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 9b19bde8a274..7a28b03b8d38 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -776,7 +776,7 @@ int PipelineHandlerRkISP1::start(Camera *camera) .size = data->stream_.configuration().size, }; - std::map entityControls; + std::map entityControls; entityControls.emplace(0, data->sensor_->controls()); data->ipa_->configure(streamConfig, entityControls); @@ -875,9 +875,12 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) std::unique_ptr data = utils::make_unique(this); - data->controlInfo_.emplace(std::piecewise_construct, - std::forward_as_tuple(&controls::AeEnable), - std::forward_as_tuple(false, true)); + ControlInfoMap::Map ctrls; + ctrls.emplace(std::piecewise_construct, + std::forward_as_tuple(&controls::AeEnable), + std::forward_as_tuple(false, true)); + + data->controlInfo_ = std::move(ctrls); data->sensor_ = new CameraSensor(sensor); ret = data->sensor_->init(); diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 018c7691d263..a64e1af4c550 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -335,7 +335,9 @@ int UVCCameraData::init(MediaEntity *entity) video_->bufferReady.connect(this, &UVCCameraData::bufferReady); /* Initialise the supported controls. */ - const V4L2ControlInfoMap &controls = video_->controls(); + const ControlInfoMap &controls = video_->controls(); + ControlInfoMap::Map ctrls; + for (const auto &ctrl : controls) { const ControlRange &range = ctrl.second; const ControlId *id; @@ -360,11 +362,13 @@ int UVCCameraData::init(MediaEntity *entity) continue; } - controlInfo_.emplace(std::piecewise_construct, - std::forward_as_tuple(id), - std::forward_as_tuple(range)); + ctrls.emplace(std::piecewise_construct, + std::forward_as_tuple(id), + std::forward_as_tuple(range)); } + controlInfo_ = std::move(ctrls); + return 0; } diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index f7f82edc6530..6a4244119dc5 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -411,7 +411,9 @@ int VimcCameraData::init(MediaDevice *media) return -ENODEV; /* Initialise the supported controls. */ - const V4L2ControlInfoMap &controls = sensor_->controls(); + const ControlInfoMap &controls = sensor_->controls(); + ControlInfoMap::Map ctrls; + for (const auto &ctrl : controls) { const ControlRange &range = ctrl.second; const ControlId *id; @@ -430,11 +432,12 @@ int VimcCameraData::init(MediaDevice *media) continue; } - controlInfo_.emplace(std::piecewise_construct, - std::forward_as_tuple(id), - std::forward_as_tuple(range)); + ctrls.emplace(std::piecewise_construct, + std::forward_as_tuple(id), + std::forward_as_tuple(range)); } + controlInfo_ = std::move(ctrls); return 0; } diff --git a/src/libcamera/proxy/ipa_proxy_linux.cpp b/src/libcamera/proxy/ipa_proxy_linux.cpp index 41bd965f0284..4e6fa6899e07 100644 --- a/src/libcamera/proxy/ipa_proxy_linux.cpp +++ b/src/libcamera/proxy/ipa_proxy_linux.cpp @@ -28,7 +28,7 @@ public: int init() override { return 0; } void configure(const std::map &streamConfig, - const std::map &entityControls) override {} + const std::map &entityControls) override {} void mapBuffers(const std::vector &buffers) override {} void unmapBuffers(const std::vector &ids) override {} void processEvent(const IPAOperationData &event) override {} diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp index e783457caf94..bd5e18590b76 100644 --- a/src/libcamera/v4l2_controls.cpp +++ b/src/libcamera/v4l2_controls.cpp @@ -134,102 +134,12 @@ V4L2ControlRange::V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl) static_cast(ctrl.maximum))); } -/** - * \class V4L2ControlInfoMap - * \brief A map of controlID to ControlRange for V4L2 controls - */ - -/** - * \brief Move assignment operator from a ControlInfoMap - * \param[in] info The control info map - * - * Populate the map by replacing its contents with those of \a info using move - * semantics. Upon return the \a info map will be empty. - * - * This is the only supported way to populate a V4L2ControlInfoMap. - * - * \return The populated V4L2ControlInfoMap - */ -V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(ControlInfoMap &&info) -{ - ControlInfoMap::operator=(std::move(info)); - - idmap_.clear(); - for (const auto &ctrl : *this) - idmap_[ctrl.first->id()] = ctrl.first; - - return *this; -} - -/** - * \brief Access specified element by numerical ID - * \param[in] id The numerical ID - * \return A reference to the element whose ID is equal to \a id - */ -V4L2ControlInfoMap::mapped_type &V4L2ControlInfoMap::at(unsigned int id) -{ - return at(idmap_.at(id)); -} - -/** - * \brief Access specified element by numerical ID - * \param[in] id The numerical ID - * \return A const reference to the element whose ID is equal to \a id - */ -const V4L2ControlInfoMap::mapped_type &V4L2ControlInfoMap::at(unsigned int id) const -{ - return at(idmap_.at(id)); -} - -/** - * \brief Count the number of elements matching a numerical ID - * \param[in] id The numerical ID - * \return The number of elements matching the numerical \a id - */ -V4L2ControlInfoMap::size_type V4L2ControlInfoMap::count(unsigned int id) const -{ - return count(idmap_.at(id)); -} - -/** - * \brief Find the element matching a numerical ID - * \param[in] id The numerical ID - * \return An iterator pointing to the element matching the numerical \a id, or - * end() if no such element exists - */ -V4L2ControlInfoMap::iterator V4L2ControlInfoMap::find(unsigned int id) -{ - return find(idmap_.at(id)); -} - -/** - * \brief Find the element matching a numerical ID - * \param[in] id The numerical ID - * \return A const iterator pointing to the element matching the numerical - * \a id, or end() if no such element exists - */ -V4L2ControlInfoMap::const_iterator V4L2ControlInfoMap::find(unsigned int id) const -{ - return find(idmap_.at(id)); -} - -/** - * \fn const ControlIdMap &V4L2ControlInfoMap::idmap() const - * \brief Retrieve the ControlId map - * - * Constructing ControlList instances for V4L2 controls requires a ControlIdMap - * for the V4L2 device that the control list targets. This helper method - * returns a suitable idmap for that purpose. - * - * \return The ControlId map - */ - /** * \class V4L2ControlList * \brief A list of controls for a V4L2 device * * This class specialises the ControList class for use with V4L2 devices. It - * offers a convenience API to create a ControlList from a V4L2ControlInfoMap. + * offers a convenience API to create a ControlList from a ControlInfoMap. * * V4L2ControlList allows easy construction of a ControlList containing V4L2 * controls for a device. It can be used to construct the list of controls @@ -239,7 +149,7 @@ V4L2ControlInfoMap::const_iterator V4L2ControlInfoMap::find(unsigned int id) con */ /** - * \fn V4L2ControlList::V4L2ControlList(const V4L2ControlInfoMap &info) + * \fn V4L2ControlList::V4L2ControlList(const ControlInfoMap &info) * \brief Construct a V4L2ControlList associated with a V4L2 device * \param[in] info The V4L2 device control info map */ diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 06155eb51c03..a2b0d891b12f 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -342,7 +342,7 @@ int V4L2Device::ioctl(unsigned long request, void *argp) */ void V4L2Device::listControls() { - ControlInfoMap ctrls; + ControlInfoMap::Map ctrls; struct v4l2_query_ext_ctrl ctrl = {}; /* \todo Add support for menu and compound controls. */ diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp index 182228f3a5b1..31879b794ed0 100644 --- a/test/v4l2_videodevice/controls.cpp +++ b/test/v4l2_videodevice/controls.cpp @@ -26,7 +26,7 @@ public: protected: int run() { - const V4L2ControlInfoMap &info = capture_->controls(); + const ControlInfoMap &info = capture_->controls(); /* Test control enumeration. */ if (info.empty()) { From patchwork Sun Oct 13 23:33:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 2192 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8631961563 for ; Mon, 14 Oct 2019 01:33:21 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0C81C33A for ; Mon, 14 Oct 2019 01:33:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1571009601; bh=BPWhUKkkGasKdBMhZF2Tha1m7WZpEfLt4jka6PbfKeQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=WgBKv4qS3UfPULkTtsCvTRIueVZJKTGRQCjrYukqBtczI/56bpOeNzfFsV28jK57L VYeZy0dZLpLygTMfzVheHSMi+VrKy3bUZV1X29AYqpg6oRxozG12GOAIvhT17+lZ+H mgUQ3VMAtFRAPPOVKlGj+E3aLoNNjlNLC55B2mho= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Mon, 14 Oct 2019 02:33:14 +0300 Message-Id: <20191013233314.4434-1-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 Subject: [libcamera-devel] [PATCH 10/10] libcamera: v4l2_controls: Remove V4L2ControlList class X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Oct 2019 23:33:21 -0000 The V4L2ControlList class only provides a convenience constructor for the ControlList, which can easily be moved to the ControlList class and may benefit it later (to construct a ControlList from controls supported by a camera). Move the constructor and remove V4L2ControlList. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- include/libcamera/controls.h | 1 + src/ipa/rkisp1/rkisp1.cpp | 2 +- src/libcamera/controls.cpp | 10 ++++++++++ src/libcamera/include/v4l2_controls.h | 14 -------------- src/libcamera/pipeline/ipu3/ipu3.cpp | 2 +- src/libcamera/pipeline/uvcvideo.cpp | 2 +- src/libcamera/pipeline/vimc.cpp | 2 +- src/libcamera/v4l2_controls.cpp | 20 -------------------- test/v4l2_videodevice/controls.cpp | 2 +- 9 files changed, 16 insertions(+), 39 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 80414c6f0748..0d279d508dcc 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -170,6 +170,7 @@ private: public: ControlList(const ControlIdMap &idmap, ControlValidator *validator = nullptr); + ControlList(const ControlInfoMap &info, ControlValidator *validator = nullptr); using iterator = ControlListMap::iterator; using const_iterator = ControlListMap::const_iterator; diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index bd703898c523..570145ce71b2 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -212,7 +212,7 @@ void IPARkISP1::setControls(unsigned int frame) IPAOperationData op; op.operation = RKISP1_IPA_ACTION_V4L2_SET; - V4L2ControlList ctrls(ctrls_); + ControlList ctrls(ctrls_); ctrls.set(V4L2_CID_EXPOSURE, static_cast(exposure_)); ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast(gain_)); op.controls.push_back(ctrls); diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index bf7634aab470..93ad2fc6a276 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -561,6 +561,16 @@ ControlList::ControlList(const ControlIdMap &idmap, ControlValidator *validator) { } +/** + * \brief Construct a ControlList with the idmap of a control info map + * \param[in] info The ControlInfoMap for the control list target object + * \param[in] validator The validator (may be null) + */ +ControlList::ControlList(const ControlInfoMap &info, ControlValidator *validator) + : validator_(validator), idmap_(&info.idmap()) +{ +} + /** * \typedef ControlList::iterator * \brief Iterator for the controls contained within the list diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h index e16c4957f9d1..882546a89340 100644 --- a/src/libcamera/include/v4l2_controls.h +++ b/src/libcamera/include/v4l2_controls.h @@ -8,11 +8,6 @@ #ifndef __LIBCAMERA_V4L2_CONTROLS_H__ #define __LIBCAMERA_V4L2_CONTROLS_H__ -#include -#include -#include -#include - #include #include @@ -31,15 +26,6 @@ public: V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl); }; -class V4L2ControlList : public ControlList -{ -public: - V4L2ControlList(const ControlInfoMap &info) - : ControlList(info.idmap()) - { - } -}; - } /* namespace libcamera */ #endif /* __LIBCAMERA_V4L2_CONTROLS_H__ */ diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 9776b36b88cd..8d3ad568d16e 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -604,7 +604,7 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) return ret; /* Apply the "pipe_mode" control to the ImgU subdevice. */ - V4L2ControlList ctrls(imgu->imgu_->controls()); + ControlList ctrls(imgu->imgu_->controls()); ctrls.set(V4L2_CID_IPU3_PIPE_MODE, static_cast(vfStream->active_ ? IPU3PipeModeVideo : IPU3PipeModeStillCapture)); diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index a64e1af4c550..fae0ffc4de30 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -228,7 +228,7 @@ void PipelineHandlerUVC::stop(Camera *camera) int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request) { - V4L2ControlList controls(data->video_->controls()); + ControlList controls(data->video_->controls()); for (auto it : request->controls()) { const ControlId &id = *it.first; diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 6a4244119dc5..dcdaef120ad1 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -279,7 +279,7 @@ void PipelineHandlerVimc::stop(Camera *camera) int PipelineHandlerVimc::processControls(VimcCameraData *data, Request *request) { - V4L2ControlList controls(data->sensor_->controls()); + ControlList controls(data->sensor_->controls()); for (auto it : request->controls()) { const ControlId &id = *it.first; diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp index bd5e18590b76..83ac7b0dc666 100644 --- a/src/libcamera/v4l2_controls.cpp +++ b/src/libcamera/v4l2_controls.cpp @@ -134,24 +134,4 @@ V4L2ControlRange::V4L2ControlRange(const struct v4l2_query_ext_ctrl &ctrl) static_cast(ctrl.maximum))); } -/** - * \class V4L2ControlList - * \brief A list of controls for a V4L2 device - * - * This class specialises the ControList class for use with V4L2 devices. It - * offers a convenience API to create a ControlList from a ControlInfoMap. - * - * V4L2ControlList allows easy construction of a ControlList containing V4L2 - * controls for a device. It can be used to construct the list of controls - * passed to the V4L2Device::getControls() and V4L2Device::setControls() - * methods. The class should however not be used in place of ControlList in - * APIs. - */ - -/** - * \fn V4L2ControlList::V4L2ControlList(const ControlInfoMap &info) - * \brief Construct a V4L2ControlList associated with a V4L2 device - * \param[in] info The V4L2 device control info map - */ - } /* namespace libcamera */ diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp index 31879b794ed0..975c852b8cbf 100644 --- a/test/v4l2_videodevice/controls.cpp +++ b/test/v4l2_videodevice/controls.cpp @@ -46,7 +46,7 @@ protected: const ControlRange &saturation = info.find(V4L2_CID_SATURATION)->second; /* Test getting controls. */ - V4L2ControlList ctrls(info); + ControlList ctrls(info); ctrls.set(V4L2_CID_BRIGHTNESS, -1); ctrls.set(V4L2_CID_CONTRAST, -1); ctrls.set(V4L2_CID_SATURATION, -1);