[libcamera-devel] [PATCH v2 13/13] libcamera: controls: Use ControlValidator to validate ControlList

Niklas Söderlund niklas.soderlund at ragnatech.se
Thu Oct 3 21:51:01 CEST 2019


Hi Laurent,

Thanks for your patch.

On 2019-09-29 22:02:54 +0300, Laurent Pinchart wrote:
> Replace the manual validation of controls against a Camera with usage of
> the new ControlValidator interface.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

Reviewed-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>

> ---
>  include/libcamera/controls.h   |  6 +++---
>  include/libcamera/request.h    |  7 ++++---
>  src/libcamera/controls.cpp     | 27 ++++++++++-----------------
>  src/libcamera/request.cpp      | 14 ++++++++++++--
>  test/controls/control_list.cpp | 15 ++++++++++++++-
>  5 files changed, 43 insertions(+), 26 deletions(-)
> 
> diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h
> index d3eea643c0ec..90426753f40f 100644
> --- a/include/libcamera/controls.h
> +++ b/include/libcamera/controls.h
> @@ -13,7 +13,7 @@
>  
>  namespace libcamera {
>  
> -class Camera;
> +class ControlValidator;
>  
>  enum ControlType {
>  	ControlTypeNone,
> @@ -119,7 +119,7 @@ private:
>  	using ControlListMap = std::unordered_map<const ControlId *, ControlValue>;
>  
>  public:
> -	ControlList(Camera *camera);
> +	ControlList(ControlValidator *validator);
>  
>  	using iterator = ControlListMap::iterator;
>  	using const_iterator = ControlListMap::const_iterator;
> @@ -160,7 +160,7 @@ private:
>  	const ControlValue *find(const ControlId &id) const;
>  	ControlValue *find(const ControlId &id);
>  
> -	Camera *camera_;
> +	ControlValidator *validator_;
>  	ControlListMap controls_;
>  };
>  
> diff --git a/include/libcamera/request.h b/include/libcamera/request.h
> index 9edf1cedc054..e3db5243aaf3 100644
> --- a/include/libcamera/request.h
> +++ b/include/libcamera/request.h
> @@ -19,9 +19,9 @@ namespace libcamera {
>  
>  class Buffer;
>  class Camera;
> +class CameraControlValidator;
>  class Stream;
>  
> -
>  class Request
>  {
>  public:
> @@ -36,7 +36,7 @@ public:
>  	Request &operator=(const Request &) = delete;
>  	~Request();
>  
> -	ControlList &controls() { return controls_; }
> +	ControlList &controls() { return *controls_; }
>  	const std::map<Stream *, Buffer *> &buffers() const { return bufferMap_; }
>  	int addBuffer(std::unique_ptr<Buffer> buffer);
>  	Buffer *findBuffer(Stream *stream) const;
> @@ -56,7 +56,8 @@ private:
>  	bool completeBuffer(Buffer *buffer);
>  
>  	Camera *camera_;
> -	ControlList controls_;
> +	CameraControlValidator *validator_;
> +	ControlList *controls_;
>  	std::map<Stream *, Buffer *> bufferMap_;
>  	std::unordered_set<Buffer *> pending_;
>  
> diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp
> index a7e9d069b31a..f3260edce0bc 100644
> --- a/src/libcamera/controls.cpp
> +++ b/src/libcamera/controls.cpp
> @@ -10,8 +10,7 @@
>  #include <sstream>
>  #include <string>
>  
> -#include <libcamera/camera.h>
> -
> +#include "control_validator.h"
>  #include "log.h"
>  #include "utils.h"
>  
> @@ -365,20 +364,16 @@ std::string ControlRange::toString() const
>   * \class ControlList
>   * \brief Associate a list of ControlId with their values for a camera
>   *
> - * A ControlList wraps a map of ControlId to ControlValue and provide
> - * additional validation against the control information exposed by a Camera.
> - *
> - * A list is only valid for as long as the camera it refers to is valid. After
> - * that calling any method of the ControlList class other than its destructor
> - * will cause undefined behaviour.
> + * A ControlList wraps a map of ControlId to ControlValue and optionally
> + * validates controls against a ControlValidator.
>   */
>  
>  /**
> - * \brief Construct a ControlList with a reference to the Camera it applies on
> - * \param[in] camera The camera
> + * \brief Construct a ControlList with an optional control validator
> + * \param[in] validator The validator (may be null)
>   */
> -ControlList::ControlList(Camera *camera)
> -	: camera_(camera)
> +ControlList::ControlList(ControlValidator *validator)
> +	: validator_(validator)
>  {
>  }
>  
> @@ -493,12 +488,10 @@ const ControlValue *ControlList::find(const ControlId &id) const
>  
>  ControlValue *ControlList::find(const ControlId &id)
>  {
> -	const ControlInfoMap &controls = camera_->controls();
> -	const auto iter = controls.find(&id);
> -	if (iter == controls.end()) {
> +	if (validator_ && !validator_->validate(id)) {
>  		LOG(Controls, Error)
> -			<< "Camera " << camera_->name()
> -			<< " does not support control " << id.name();
> +			<< "Control " << id.name()
> +			<< " is not valid for " << validator_->name();
>  		return nullptr;
>  	}
>  
> diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp
> index ee2158fc7a9c..19f6d0b9a0ae 100644
> --- a/src/libcamera/request.cpp
> +++ b/src/libcamera/request.cpp
> @@ -13,6 +13,7 @@
>  #include <libcamera/camera.h>
>  #include <libcamera/stream.h>
>  
> +#include "camera_controls.h"
>  #include "log.h"
>  
>  /**
> @@ -55,9 +56,15 @@ LOG_DEFINE_CATEGORY(Request)
>   *
>   */
>  Request::Request(Camera *camera, uint64_t cookie)
> -	: camera_(camera), controls_(camera), cookie_(cookie),
> -	  status_(RequestPending), cancelled_(false)
> +	: camera_(camera), cookie_(cookie), status_(RequestPending),
> +	  cancelled_(false)
>  {
> +	/**
> +	 * \todo Should the Camera expose a validator instance, to avoid
> +	 * creating a new instance for each request?
> +	 */
> +	validator_ = new CameraControlValidator(camera);
> +	controls_ = new ControlList(validator_);
>  }
>  
>  Request::~Request()
> @@ -66,6 +73,9 @@ Request::~Request()
>  		Buffer *buffer = it.second;
>  		delete buffer;
>  	}
> +
> +	delete controls_;
> +	delete validator_;
>  }
>  
>  /**
> diff --git a/test/controls/control_list.cpp b/test/controls/control_list.cpp
> index 8469ecf09439..1bcfecc467b5 100644
> --- a/test/controls/control_list.cpp
> +++ b/test/controls/control_list.cpp
> @@ -12,6 +12,7 @@
>  #include <libcamera/control_ids.h>
>  #include <libcamera/controls.h>
>  
> +#include "camera_controls.h"
>  #include "test.h"
>  
>  using namespace std;
> @@ -40,7 +41,8 @@ protected:
>  
>  	int run()
>  	{
> -		ControlList list(camera_.get());
> +		CameraControlValidator validator(camera_.get());
> +		ControlList list(&validator);
>  
>  		/* Test that the list is initially empty. */
>  		if (!list.empty()) {
> @@ -141,6 +143,17 @@ protected:
>  			return TestFail;
>  		}
>  
> +		/*
> +		 * Attempt to set an invalid control and verify that the
> +		 * operation failed.
> +		 */
> +		list.set(controls::AwbEnable, true);
> +
> +		if (list.contains(controls::AwbEnable)) {
> +			cout << "List shouldn't contain AwbEnable control" << endl;
> +			return TestFail;
> +		}
> +
>  		return TestPass;
>  	}
>  
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

-- 
Regards,
Niklas Söderlund


More information about the libcamera-devel mailing list