[libcamera-devel,v3,06/14] libcamera: controls: Extend ControlList to access controls by ID

Message ID 20190630233817.10130-7-laurent.pinchart@ideasonboard.com
State Superseded
Headers show
Series
  • libcamera Controls
Related show

Commit Message

Laurent Pinchart June 30, 2019, 11:38 p.m. UTC
The ControlList class implements a map from control specifier to control
ID. To avoid constant lookups of ControlInfo when using the class in the
libcamera core or in pipeline handlers, the map uses ControlInfo
pointers instead of ControlId values. This is however not very
convenient.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 include/libcamera/controls.h |  2 ++
 src/libcamera/controls.cpp   | 57 ++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

Comments

Kieran Bingham July 1, 2019, 9:25 a.m. UTC | #1
Hi Laurent,

On 01/07/2019 00:38, Laurent Pinchart wrote:
> The ControlList class implements a map from control specifier to control
> ID. To avoid constant lookups of ControlInfo when using the class in the
> libcamera core or in pipeline handlers, the map uses ControlInfo
> pointers instead of ControlId values. This is however not very
> convenient.

This paragraph sort of 'stops'. Perhaps needs a finishing:

"""
Facilitate ease of use of ControlLists by implementing an internal
lookup of the ControlInfo from the controls provided by the Camera.
"""

<minor spell fix below>

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  include/libcamera/controls.h |  2 ++
>  src/libcamera/controls.cpp   | 57 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 59 insertions(+)
> 
> diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
> index 9b37dfb16b89..d827318ee0fa 100644
> --- a/include/libcamera/controls.h
> +++ b/include/libcamera/controls.h
> @@ -117,11 +117,13 @@ public:
>  	const_iterator begin() const { return controls_.begin(); }
>  	const_iterator end() const { return controls_.end(); }
>  
> +	bool contains(ControlId id) const;
>  	bool contains(const ControlInfo *info) const { return controls_.count(info); };
>  	bool empty() const { return controls_.empty(); }
>  	std::size_t size() const { return controls_.size(); }
>  	void clear() { controls_.clear(); }
>  
> +	ControlValue &operator[](ControlId id);
>  	ControlValue &operator[](const ControlInfo *info) { return controls_[info]; }
>  
>  	void update(const ControlList &list);
> diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
> index e4c41b97a354..17e09fc7f153 100644
> --- a/src/libcamera/controls.cpp
> +++ b/src/libcamera/controls.cpp
> @@ -10,6 +10,8 @@
>  #include <sstream>
>  #include <string>
>  
> +#include <libcamera/camera.h>
> +
>  #include "log.h"
>  #include "utils.h"
>  
> @@ -372,6 +374,30 @@ ControlList::ControlList(Camera *camera)
>   * instance
>   */
>  
> +/**
> + * \brief Check if the ist contains a control with the specified \a id

s/ist/List/

> + * \param[in] id The control ID
> + *
> + * The behaviour is undefined if the control \a id is not supported by the
> + * camera that the ControlList refers to.
> + *
> + * \return True if the list contains a matching control, false otherwise
> + */
> +bool ControlList::contains(ControlId id) const
> +{
> +	const ControlInfoMap &controls = camera_->controls();
> +	const auto iter = controls.find(id);
> +	if (iter == controls.end()) {
> +		LOG(Controls, Error)
> +			<< "Camera " << camera_->name()
> +			<< " does not support control " << id;
> +
> +		return false;
> +	}
> +
> +	return controls_.find(&iter->second) != controls_.end();
> +}
> +
>  /**
>   * \fn ControlList::contains(const ControlInfo *info) const
>   * \brief Check if the ist contains a control with the specified \a info
> @@ -396,6 +422,34 @@ ControlList::ControlList(Camera *camera)
>   * \brief Removes all controls from the list
>   */
>  
> +/**
> + * \brief Access or insert the control specified by \a id
> + * \param[in] id The control ID
> + *
> + * This method returns a reference to the control identified by \a id, inserting
> + * it in the list if the ID is not already present.
> + *
> + * The behaviour is undefined if the control \a id is not supported by the
> + * camera that the ControlList refers to.
> + *
> + * \return A reference to the value of the control identified by \a id
> + */
> +ControlValue &ControlList::operator[](ControlId id)
> +{
> +	const ControlInfoMap &controls = camera_->controls();
> +	const auto iter = controls.find(id);
> +	if (iter == controls.end()) {
> +		LOG(Controls, Error)
> +			<< "Camera " << camera_->name()
> +			<< " does not support control " << id;
> +
> +		static ControlValue empty;
> +		return empty;
> +	}
> +
> +	return controls_[&iter->second];
> +}
> +
>  /**
>   * \fn ControlList::operator[](const ControlInfo *info)
>   * \brief Access or insert the control specified by \a info
> @@ -413,6 +467,9 @@ ControlList::ControlList(Camera *camera)
>   *
>   * Update all controls in the ControlList, by the values given by \a list
>   * If the list already contains a control of this ID then it will be overwritten
> + *
> + * The behaviour is undefined if the two lists refer to different Camera
> + * instances.
>   */
>  void ControlList::update(const ControlList &list)
>  {
>
Laurent Pinchart July 1, 2019, 11:11 a.m. UTC | #2
On Mon, Jul 01, 2019 at 10:25:10AM +0100, Kieran Bingham wrote:
> Hi Laurent,
> 
> On 01/07/2019 00:38, Laurent Pinchart wrote:
> > The ControlList class implements a map from control specifier to control
> > ID. To avoid constant lookups of ControlInfo when using the class in the
> > libcamera core or in pipeline handlers, the map uses ControlInfo
> > pointers instead of ControlId values. This is however not very
> > convenient.
> 
> This paragraph sort of 'stops'. Perhaps needs a finishing:
> 
> """
> Facilitate ease of use of ControlLists by implementing an internal
> lookup of the ControlInfo from the controls provided by the Camera.
> """

Indeed. I started writing the commit message, got interrupted, and then
forgot about it.

"The ControlList class implements a map from control specifier to control
ID. To avoid constant lookups of ControlInfo when using the class in the
libcamera core or in pipeline handlers, the map uses ControlInfo
pointers instead of ControlId values. This is however not very
convenient for applications or pipeline handlers, as they would be 
forced to first look up the ControlInfo pointers for the controls they 
want to access. Facilitate ease of use of ControlLists by implementing 
an internal lookup of the ControlInfo from the controls provided by the
Camera."

> <minor spell fix below>
> 
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> > ---
> >  include/libcamera/controls.h |  2 ++
> >  src/libcamera/controls.cpp   | 57 ++++++++++++++++++++++++++++++++++++
> >  2 files changed, 59 insertions(+)
> > 
> > diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
> > index 9b37dfb16b89..d827318ee0fa 100644
> > --- a/include/libcamera/controls.h
> > +++ b/include/libcamera/controls.h
> > @@ -117,11 +117,13 @@ public:
> >  	const_iterator begin() const { return controls_.begin(); }
> >  	const_iterator end() const { return controls_.end(); }
> >  
> > +	bool contains(ControlId id) const;
> >  	bool contains(const ControlInfo *info) const { return controls_.count(info); };
> >  	bool empty() const { return controls_.empty(); }
> >  	std::size_t size() const { return controls_.size(); }
> >  	void clear() { controls_.clear(); }
> >  
> > +	ControlValue &operator[](ControlId id);
> >  	ControlValue &operator[](const ControlInfo *info) { return controls_[info]; }
> >  
> >  	void update(const ControlList &list);
> > diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
> > index e4c41b97a354..17e09fc7f153 100644
> > --- a/src/libcamera/controls.cpp
> > +++ b/src/libcamera/controls.cpp
> > @@ -10,6 +10,8 @@
> >  #include <sstream>
> >  #include <string>
> >  
> > +#include <libcamera/camera.h>
> > +
> >  #include "log.h"
> >  #include "utils.h"
> >  
> > @@ -372,6 +374,30 @@ ControlList::ControlList(Camera *camera)
> >   * instance
> >   */
> >  
> > +/**
> > + * \brief Check if the ist contains a control with the specified \a id
> 
> s/ist/List/
> 
> > + * \param[in] id The control ID
> > + *
> > + * The behaviour is undefined if the control \a id is not supported by the
> > + * camera that the ControlList refers to.
> > + *
> > + * \return True if the list contains a matching control, false otherwise
> > + */
> > +bool ControlList::contains(ControlId id) const
> > +{
> > +	const ControlInfoMap &controls = camera_->controls();
> > +	const auto iter = controls.find(id);
> > +	if (iter == controls.end()) {
> > +		LOG(Controls, Error)
> > +			<< "Camera " << camera_->name()
> > +			<< " does not support control " << id;
> > +
> > +		return false;
> > +	}
> > +
> > +	return controls_.find(&iter->second) != controls_.end();
> > +}
> > +
> >  /**
> >   * \fn ControlList::contains(const ControlInfo *info) const
> >   * \brief Check if the ist contains a control with the specified \a info
> > @@ -396,6 +422,34 @@ ControlList::ControlList(Camera *camera)
> >   * \brief Removes all controls from the list
> >   */
> >  
> > +/**
> > + * \brief Access or insert the control specified by \a id
> > + * \param[in] id The control ID
> > + *
> > + * This method returns a reference to the control identified by \a id, inserting
> > + * it in the list if the ID is not already present.
> > + *
> > + * The behaviour is undefined if the control \a id is not supported by the
> > + * camera that the ControlList refers to.
> > + *
> > + * \return A reference to the value of the control identified by \a id
> > + */
> > +ControlValue &ControlList::operator[](ControlId id)
> > +{
> > +	const ControlInfoMap &controls = camera_->controls();
> > +	const auto iter = controls.find(id);
> > +	if (iter == controls.end()) {
> > +		LOG(Controls, Error)
> > +			<< "Camera " << camera_->name()
> > +			<< " does not support control " << id;
> > +
> > +		static ControlValue empty;
> > +		return empty;
> > +	}
> > +
> > +	return controls_[&iter->second];
> > +}
> > +
> >  /**
> >   * \fn ControlList::operator[](const ControlInfo *info)
> >   * \brief Access or insert the control specified by \a info
> > @@ -413,6 +467,9 @@ ControlList::ControlList(Camera *camera)
> >   *
> >   * Update all controls in the ControlList, by the values given by \a list
> >   * If the list already contains a control of this ID then it will be overwritten
> > + *
> > + * The behaviour is undefined if the two lists refer to different Camera
> > + * instances.
> >   */
> >  void ControlList::update(const ControlList &list)
> >  {
> > 
> 
> -- 
> Regards
> --
> Kieran
Jacopo Mondi July 1, 2019, 4:50 p.m. UTC | #3
HI Laurent,

On Mon, Jul 01, 2019 at 02:38:09AM +0300, Laurent Pinchart wrote:
> The ControlList class implements a map from control specifier to control
> ID. To avoid constant lookups of ControlInfo when using the class in the
> libcamera core or in pipeline handlers, the map uses ControlInfo
> pointers instead of ControlId values. This is however not very
> convenient.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

With Kieran's spelling comment addressed

Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>

Thanks
   j

> ---
>  include/libcamera/controls.h |  2 ++
>  src/libcamera/controls.cpp   | 57 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 59 insertions(+)
>
> diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
> index 9b37dfb16b89..d827318ee0fa 100644
> --- a/include/libcamera/controls.h
> +++ b/include/libcamera/controls.h
> @@ -117,11 +117,13 @@ public:
>  	const_iterator begin() const { return controls_.begin(); }
>  	const_iterator end() const { return controls_.end(); }
>
> +	bool contains(ControlId id) const;
>  	bool contains(const ControlInfo *info) const { return controls_.count(info); };
>  	bool empty() const { return controls_.empty(); }
>  	std::size_t size() const { return controls_.size(); }
>  	void clear() { controls_.clear(); }
>
> +	ControlValue &operator[](ControlId id);
>  	ControlValue &operator[](const ControlInfo *info) { return controls_[info]; }
>
>  	void update(const ControlList &list);
> diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
> index e4c41b97a354..17e09fc7f153 100644
> --- a/src/libcamera/controls.cpp
> +++ b/src/libcamera/controls.cpp
> @@ -10,6 +10,8 @@
>  #include <sstream>
>  #include <string>
>
> +#include <libcamera/camera.h>
> +
>  #include "log.h"
>  #include "utils.h"
>
> @@ -372,6 +374,30 @@ ControlList::ControlList(Camera *camera)
>   * instance
>   */
>
> +/**
> + * \brief Check if the ist contains a control with the specified \a id
> + * \param[in] id The control ID
> + *
> + * The behaviour is undefined if the control \a id is not supported by the
> + * camera that the ControlList refers to.
> + *
> + * \return True if the list contains a matching control, false otherwise
> + */
> +bool ControlList::contains(ControlId id) const
> +{
> +	const ControlInfoMap &controls = camera_->controls();
> +	const auto iter = controls.find(id);
> +	if (iter == controls.end()) {
> +		LOG(Controls, Error)
> +			<< "Camera " << camera_->name()
> +			<< " does not support control " << id;
> +
> +		return false;
> +	}
> +
> +	return controls_.find(&iter->second) != controls_.end();
> +}
> +
>  /**
>   * \fn ControlList::contains(const ControlInfo *info) const
>   * \brief Check if the ist contains a control with the specified \a info
> @@ -396,6 +422,34 @@ ControlList::ControlList(Camera *camera)
>   * \brief Removes all controls from the list
>   */
>
> +/**
> + * \brief Access or insert the control specified by \a id
> + * \param[in] id The control ID
> + *
> + * This method returns a reference to the control identified by \a id, inserting
> + * it in the list if the ID is not already present.
> + *
> + * The behaviour is undefined if the control \a id is not supported by the
> + * camera that the ControlList refers to.
> + *
> + * \return A reference to the value of the control identified by \a id
> + */
> +ControlValue &ControlList::operator[](ControlId id)
> +{
> +	const ControlInfoMap &controls = camera_->controls();
> +	const auto iter = controls.find(id);
> +	if (iter == controls.end()) {
> +		LOG(Controls, Error)
> +			<< "Camera " << camera_->name()
> +			<< " does not support control " << id;
> +
> +		static ControlValue empty;
> +		return empty;
> +	}
> +
> +	return controls_[&iter->second];
> +}
> +
>  /**
>   * \fn ControlList::operator[](const ControlInfo *info)
>   * \brief Access or insert the control specified by \a info
> @@ -413,6 +467,9 @@ ControlList::ControlList(Camera *camera)
>   *
>   * Update all controls in the ControlList, by the values given by \a list
>   * If the list already contains a control of this ID then it will be overwritten
> + *
> + * The behaviour is undefined if the two lists refer to different Camera
> + * instances.
>   */
>  void ControlList::update(const ControlList &list)
>  {
> --
> Regards,
>
> Laurent Pinchart
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

Patch

diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
index 9b37dfb16b89..d827318ee0fa 100644
--- a/include/libcamera/controls.h
+++ b/include/libcamera/controls.h
@@ -117,11 +117,13 @@  public:
 	const_iterator begin() const { return controls_.begin(); }
 	const_iterator end() const { return controls_.end(); }
 
+	bool contains(ControlId id) const;
 	bool contains(const ControlInfo *info) const { return controls_.count(info); };
 	bool empty() const { return controls_.empty(); }
 	std::size_t size() const { return controls_.size(); }
 	void clear() { controls_.clear(); }
 
+	ControlValue &operator[](ControlId id);
 	ControlValue &operator[](const ControlInfo *info) { return controls_[info]; }
 
 	void update(const ControlList &list);
diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
index e4c41b97a354..17e09fc7f153 100644
--- a/src/libcamera/controls.cpp
+++ b/src/libcamera/controls.cpp
@@ -10,6 +10,8 @@ 
 #include <sstream>
 #include <string>
 
+#include <libcamera/camera.h>
+
 #include "log.h"
 #include "utils.h"
 
@@ -372,6 +374,30 @@  ControlList::ControlList(Camera *camera)
  * instance
  */
 
+/**
+ * \brief Check if the ist contains a control with the specified \a id
+ * \param[in] id The control ID
+ *
+ * The behaviour is undefined if the control \a id is not supported by the
+ * camera that the ControlList refers to.
+ *
+ * \return True if the list contains a matching control, false otherwise
+ */
+bool ControlList::contains(ControlId id) const
+{
+	const ControlInfoMap &controls = camera_->controls();
+	const auto iter = controls.find(id);
+	if (iter == controls.end()) {
+		LOG(Controls, Error)
+			<< "Camera " << camera_->name()
+			<< " does not support control " << id;
+
+		return false;
+	}
+
+	return controls_.find(&iter->second) != controls_.end();
+}
+
 /**
  * \fn ControlList::contains(const ControlInfo *info) const
  * \brief Check if the ist contains a control with the specified \a info
@@ -396,6 +422,34 @@  ControlList::ControlList(Camera *camera)
  * \brief Removes all controls from the list
  */
 
+/**
+ * \brief Access or insert the control specified by \a id
+ * \param[in] id The control ID
+ *
+ * This method returns a reference to the control identified by \a id, inserting
+ * it in the list if the ID is not already present.
+ *
+ * The behaviour is undefined if the control \a id is not supported by the
+ * camera that the ControlList refers to.
+ *
+ * \return A reference to the value of the control identified by \a id
+ */
+ControlValue &ControlList::operator[](ControlId id)
+{
+	const ControlInfoMap &controls = camera_->controls();
+	const auto iter = controls.find(id);
+	if (iter == controls.end()) {
+		LOG(Controls, Error)
+			<< "Camera " << camera_->name()
+			<< " does not support control " << id;
+
+		static ControlValue empty;
+		return empty;
+	}
+
+	return controls_[&iter->second];
+}
+
 /**
  * \fn ControlList::operator[](const ControlInfo *info)
  * \brief Access or insert the control specified by \a info
@@ -413,6 +467,9 @@  ControlList::ControlList(Camera *camera)
  *
  * Update all controls in the ControlList, by the values given by \a list
  * If the list already contains a control of this ID then it will be overwritten
+ *
+ * The behaviour is undefined if the two lists refer to different Camera
+ * instances.
  */
 void ControlList::update(const ControlList &list)
 {