[libcamera-devel] [PATCH v2 3/6] libcamera: Add V4L2Controls

Laurent Pinchart laurent.pinchart at ideasonboard.com
Tue Jun 11 13:41:57 CEST 2019


Hi Jacopo,

Thank you for the patch.

On Mon, Jun 10, 2019 at 06:40:49PM +0200, Jacopo Mondi wrote:
> Add Libcamera V4L2 control support, implemented using the V4L2 Extended
> Control APIs. This patch defines the types used to define and manage controls.
> 
> Signed-off-by: Jacopo Mondi <jacopo at jmondi.org>
> ---
>  src/libcamera/include/v4l2_controls.h | 210 +++++++++
>  src/libcamera/meson.build             |   1 +
>  src/libcamera/v4l2_controls.cpp       | 632 ++++++++++++++++++++++++++
>  3 files changed, 843 insertions(+)
>  create mode 100644 src/libcamera/include/v4l2_controls.h
>  create mode 100644 src/libcamera/v4l2_controls.cpp
> 
> diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h
> new file mode 100644
> index 000000000000..bca5ccc29de3
> --- /dev/null
> +++ b/src/libcamera/include/v4l2_controls.h
> @@ -0,0 +1,210 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * v4l2_controls.h - V4L2 Extended Control Support
> + */
> +
> +#ifndef __LIBCAMERA_V4L2_CONTROLS_H__
> +#define __LIBCAMERA_V4L2_CONTROLS_H__
> +
> +#include <cstring>
> +#include <string>
> +#include <vector>
> +
> +#include <stdint.h>
> +
> +#include <linux/v4l2-controls.h>
> +#include <linux/videodev2.h>
> +
> +namespace libcamera {
> +
> +class V4L2Control
> +{
> +public:
> +	virtual ~V4L2Control()
> +	{
> +	}
> +
> +	unsigned int id() { return id_; }
> +	unsigned int size() { return size_; }
> +	enum v4l2_ctrl_type type() const { return type_; }
> +
> +protected:
> +	V4L2Control(unsigned int id, unsigned int size,
> +		    enum v4l2_ctrl_type type)
> +		: id_(id), size_(size), type_(type)
> +	{
> +	}
> +
> +private:
> +	unsigned int id_;
> +	unsigned int size_;
> +	enum v4l2_ctrl_type type_;
> +};
> +
> +template<typename T>
> +class V4L2ControlValue : public V4L2Control
> +{
> +public:
> +	T value() const { return value_; }
> +	T *mem() const { return mem_; }
> +
> +protected:
> +	V4L2ControlValue(unsigned int id, unsigned int size,
> +			 enum v4l2_ctrl_type type, T value)
> +		: V4L2Control(id, size, type)
> +	{
> +		value_ = value;
> +		mem_ = nullptr;
> +	}
> +
> +	V4L2ControlValue(unsigned int id, unsigned int size,
> +			 enum v4l2_ctrl_type type, T *value)
> +		: V4L2Control(id, size, type)
> +	{
> +		value_ = 0;
> +		mem_ = static_cast<T *>(new T[size]);
> +		memcpy(mem_, value, size);
> +	}
> +
> +	~V4L2ControlValue()
> +	{
> +		delete[] mem_;
> +	}
> +
> +private:
> +	T value_;
> +	T *mem_;
> +};
> +
> +class V4L2IntControl : public V4L2ControlValue<int32_t>
> +{
> +private:
> +	friend class V4L2Controls;
> +
> +	V4L2IntControl(unsigned int id, int32_t value)
> +		: V4L2ControlValue<int32_t>(id, sizeof(int32_t),
> +					    V4L2_CTRL_TYPE_INTEGER, value)
> +	{
> +	}
> +};
> +
> +class V4L2Int64Control : public V4L2ControlValue<int64_t>
> +{
> +private:
> +	friend class V4L2Controls;
> +
> +	V4L2Int64Control(unsigned int id, int64_t value)
> +		: V4L2ControlValue<int64_t>(id, sizeof(int64_t),
> +					    V4L2_CTRL_TYPE_INTEGER64, value)
> +	{
> +	}
> +};
> +
> +class V4L2BoolControl : public V4L2ControlValue<bool>
> +{
> +private:
> +	friend class V4L2Controls;
> +
> +	V4L2BoolControl(unsigned int id, bool value)
> +		: V4L2ControlValue<bool>(id, sizeof(bool),
> +					 V4L2_CTRL_TYPE_BOOLEAN, value)
> +	{
> +	}
> +};
> +
> +class V4L2StringControl : public V4L2ControlValue<std::string>
> +{
> +private:
> +	friend class V4L2Controls;
> +
> +	V4L2StringControl(unsigned int id, std::string value)
> +		: V4L2ControlValue<std::string>(id, value.length(),
> +						V4L2_CTRL_TYPE_STRING, value)
> +	{
> +	}
> +};
> +
> +class V4L2U8Control : public V4L2ControlValue<uint8_t>
> +{
> +private:
> +	friend class V4L2Controls;
> +
> +	V4L2U8Control(unsigned int id, unsigned int size, uint8_t *mem)
> +		: V4L2ControlValue<uint8_t>(id, size, V4L2_CTRL_TYPE_U8, mem)
> +	{
> +	}
> +};
> +
> +class V4L2U16Control : public V4L2ControlValue<uint16_t>
> +{
> +private:
> +	friend class V4L2Controls;
> +
> +	V4L2U16Control(unsigned int id, unsigned int size, uint16_t *mem)
> +		: V4L2ControlValue<uint16_t>(id, size, V4L2_CTRL_TYPE_U16, mem)
> +	{
> +	}
> +};
> +
> +class V4L2U32Control : public V4L2ControlValue<uint32_t>
> +{
> +private:
> +	friend class V4L2Controls;
> +
> +	V4L2U32Control(unsigned int id, unsigned int size, uint32_t *mem)
> +		: V4L2ControlValue<uint32_t>(id, size, V4L2_CTRL_TYPE_U32, mem)
> +	{
> +	}
> +};
> +
> +class V4L2Controls {
> +public:
> +	~V4L2Controls()
> +	{
> +		clear();
> +	}
> +
> +	using iterator = std::vector<V4L2Control *>::iterator;
> +	using const_iterator = std::vector<V4L2Control *>::const_iterator;
> +
> +	iterator begin() { return controls_.begin(); }
> +	const_iterator begin() const { return controls_.begin(); }
> +	iterator end() { return controls_.end(); }
> +	const_iterator end() const { return controls_.end(); }
> +
> +	size_t size() { return controls_.size(); }
> +	void clear();

I would move clear() after empty(), to group all the methods the merely
delegate to std::vector together, followed by the custom methods.

> +
> +	V4L2Control *operator[](unsigned int index) const
> +	{
> +		return controls_[index];
> +	}
> +
> +	bool empty() const { return controls_.size() == 0; }

	return controls_.empty();

> +
> +	void set(unsigned int id, unsigned int value);
> +	void set(unsigned int id, int32_t value);
> +	void set(unsigned int id, int64_t value);

This will be quite error-prone, especially the first two variants. Users
of the class will have to be very careful about the type passed to the
function, and C++ type deduction rules are not easy to keep in mind.

> +	void set(unsigned int id, bool value);
> +	void set(unsigned int id, std::string value);
> +	void set(unsigned int id, size_t size, uint8_t *value);
> +	void set(unsigned int id, size_t size, uint16_t *value);
> +	void set(unsigned int id, size_t size, uint32_t *value);
> +
> +	int32_t getInt(unsigned int id);
> +	int64_t getInt64(unsigned int id);
> +	bool getBool(unsigned int id);
> +	std::string getString(unsigned int id);
> +	uint8_t *getU8(unsigned int id);
> +	uint16_t *getU16(unsigned int id);
> +	uint32_t *getU32(unsigned int id);
> +
> +private:
> +	std::vector<V4L2Control *> controls_;

I still dislike storing pointers here, as it means individual
allocation and free. If you add the fact that array control values also
allocate memory internally, that's quite a bit of overhead. However, now
that the details are hidden from the user, it becomes more of an
implementation issue, which can evolve without impacting the users.

> +};
> +
> +}; /* namespace libcamera */
> +
> +#endif /* __LIBCAMERA_V4L2_CONTROLS_H__ */
> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
> index 6d858a22531e..fa1fbcb5faf5 100644
> --- a/src/libcamera/meson.build
> +++ b/src/libcamera/meson.build
> @@ -22,6 +22,7 @@ libcamera_sources = files([
>      'timer.cpp',
>      'utils.cpp',
>      'v4l2_base.cpp',
> +    'v4l2_controls.cpp',
>      'v4l2_device.cpp',
>      'v4l2_subdevice.cpp',
>  ])
> diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp
> new file mode 100644
> index 000000000000..bd68d07f37bf
> --- /dev/null
> +++ b/src/libcamera/v4l2_controls.cpp
> @@ -0,0 +1,632 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * v4l2_controls.cpp - V4L2 Extended Control Support
> + */
> +
> +#include "v4l2_controls.h"
> +
> +/**
> + * \file v4l2_controls.h
> + * \brief Support for V4L2 Controls using the V4L2 Extended Controls APIs.
> + *
> + * The V4L2 defined "Control API" allows application to inspect and modify set
> + * of configurable parameters on the video device or subdevice of interest. The
> + * nature of the parameters an application could modify using the control
> + * framework depends on what the driver implements support for, and on the
> + * characteristics of the underlying hardware platform. Generally controls are
> + * used to modify user visible settings, such as the image brightness and
> + * exposure time, or non-standard parameters which cannot be controlled through
> + * the V4L2 format negotiation API.
> + *
> + * Controls are identified by a numerical id, defined by the V4L2 kernel headers
> + * and have an associated type and class. Each control has a 'value', which is
> + * the data that can be modified with a 'V4L2Base::setControl()' operation call
> + * or retrieved with a 'V4L2Base::getControl()' one.
> + *
> + * A control class defines the control purpose while its type (along with the
> + * control's flags) defines the type of the control's value content. Controls
> + * might transport a single data value stored in variable inside the control, or
> + * they might as well deal with more complex data types, such as arrays of
> + * matrices, stored in a contiguous memory locations associated with the control
> + * and called 'the payload'. The content have to be opportunely copied into the
> + * application memory when retrieving a control's value and provided to the V4L2
> + * device when setting it.
> + *
> + * Libcamera supports control using the V4L2 'Extended Control' framework, which
> + * allows easier handling of controls with payloads of arbitrary sizes.
> + *
> + * The Libcamera V4L2 Controls framework operates on lists of controls, wrapped
> + * by the V4L2Controls class, to match the V4L2 extended controls framework.
> + * The interface to set and get control is implemented by the V4L2Base class,
> + * while this file only provides the data type definitions.
> + *
> + * The Libcamera V4L2 control framework define a base class
> + * V4L2Control that contains the fields common to all controls, regardless of
> + * their type, such as the  control's id, its type and the expected control's
> + * value data size. The V4L2Control class is not meant to be instantiated
> + * directly, but is instead used as placeholder to store controls inside the
> + * publicly constructible V4L2Controls class.
> + *
> + * A parametric derived class V4L2ControlValue stores the control's value and
> + * provide accessors to the data values for controls with no payload, or to the
> + * memory area that contains the control's data payload. These classes are not
> + * intended to be directly used and cannot be constructed, but are used instead
> + * to define specialized derived classes which provide accessors to the
> + * control's data values.
> + *
> + * In order to set and get controls, user of the Libcamera V4L2 control
> + * framework should operate on instances of the V4L2Controls class, iterating
> + * on the V4L2Controls it contains, and use the V4L2Controls::set() and
> + * V4L2Controls::get() methods to set or access the control's data
> + * content.
> + *
> + * \todo Support setting controls with data payload.
> + */
> +
> +namespace libcamera {
> +
> +/**
> + * \class V4L2Control
> + * \brief Base class for V4L2 Controls
> + *
> + * The V4L2Control base class is the base class that contains the fields common
> + * to all controls (id, type and size).
> + *
> + * This class is not meant to be instantiated directly, but is instead used as a
> + * place holder to store controls in arrays or other containers. User of the
> + * libcamera V4L2 control framework should access the controls content by
> + * using accessors provided by the V4L2Controls class.
> + */
> +
> +/**
> + * \fn V4L2Control::V4L2Control
> + * \brief Construct a V4L2Control instance
> + * \param id The control's id
> + * \param size The control's data size
> + * \param type The control's type
> + */
> +
> +/**
> + * \fn V4L2Control::id()
> + * \brief Retrieve the control's id
> + *
> + * Retrieve the control's numerical id value as defined by the V4L2
> + * specification.
> + *
> + * \return The control's id
> + */
> +
> +/**
> + * \fn V4L2Control::size()
> + * \brief Retrieve the control's data value size in bytes
> + *
> + * \todo Better define the value of size() for controls with payload data.
> + *
> + * \return The control's size
> + */
> +
> +/**
> + * \fn V4L2Control::type()
> + * \brief Retrieve the control's type
> + *
> + * Retrieve the control's type as defined by the V4L2 specification.
> + *
> + * \return The control's type
> + */
> +
> +/**
> + * \class V4L2ControlValue
> + * \brief Template base class that represent values of a V4L2 control
> + *
> + * The V4L2ControlValue template base class represents a V4L2 control with
> + * its different value types.
> + *
> + * It provides two operations to access the control's value or the pointer
> + * to the memory location that contains to the control's value data payload.
> + */
> +
> +/**
> + * \fn V4L2ControlValue::V4L2ControlValue(unsigned int id, unsigned int size, enum v4l2_ctrl_type type, T value)
> + * \brief Contruct a V4L2ControlValue with a parametric value
> + * \param id The control's id
> + * \param size The control's size
> + * \param type The control's type
> + * \param value The control's value
> + */
> +
> +/**
> + * \fn V4L2ControlValue::V4L2ControlValue(unsigned int id, unsigned int size, enum v4l2_ctrl_type type, T* value)
> + * \brief Contruct a V4L2ControlValue with a pointer to a data payload
> + * \param id The control's id
> + * \param size The control's size
> + * \param type The control's type
> + * \param value The pointer to the control's data payload
> + */
> +
> +/**
> + * \fn V4L2ControlValue::~V4L2ControlValue
> + * \brief Release the memory reserved for the control's data payload, if any
> + */
> +
> +/**
> + * \fn V4L2ControlValue::value()
> + * \brief Retrieve the control's value
> + *
> + * Retrieve the control's value. Valid only for controls with no payload.
> + */
> +
> +/**
> + * \fn V4L2ControlValue::mem()
> + * \brief Retrieve a pointer to the memory location of the control's data
> + *
> + * Retrieve a pointer to the memory location that contains the control's data
> + * payload. Valid only for controls with data payload.
> + */
> +
> +/**
> + * \class V4L2IntControl
> + * \brief Specialized V4L2Control class that handles controls of
> + *        V4L2_CTRL_TYPE_INTEGER type.
> + *
> + * Access to the control's data value by using the value() operation is
> + * restricted to the proxy V4L2Controls class.
> + */
> +
> +/**
> + * \fn V4L2IntControl::V4L2IntControl()
> + * \brief Construct a V4L2Control that contains an int value
> + * \param id The control's id
> + * \param value The control's value
> + */
> +
> +/**
> + * \class V4L2Int64Control
> + * \brief Specialized V4L2Control class that handles controls of
> + *        V4L2_CTRL_TYPE_INTEGER64 type.
> + *
> + * Access to the control's data value by using the value() operation is
> + * restricted to the proxy V4L2Controls class.
> + */
> +
> +/**
> + * \fn V4L2Int64Control::V4L2Int64Control()
> + * \brief Construct a V4L2Control that contains an int64 value
> + * \param id The control's id
> + * \param value The control's value
> + */
> +
> +/**
> + * \class V4L2BoolControl
> + * \brief Specialized V4L2Control class that handles controls of
> + *        V4L2_CTRL_TYPE_BOOLEAN type.
> + *
> + *
> + * Access to the control's data value by using the value() operation is
> + * restricted to the proxy V4L2Controls class.
> + */
> +
> +/**
> + * \fn V4L2BoolControl::V4L2BoolControl()
> + * \brief Construct a V4L2Control that contains a boolean value
> + * \param id The control's id
> + * \param value The control's value
> + */
> +
> +/**
> + * \class V4L2StringControl
> + * \brief Specialized V4L2Control class that handles controls of
> + *        V4L2_CTRL_TYPE_STRING type.
> + *
> + * Access to the control's data value by using the value() operation is
> + * restricted to the proxy V4L2Controls class.
> + */
> +
> +/**
> + * \fn V4L2StringControl::V4L2StringControl()
> + * \brief Construct a V4L2Control that contains a string value
> + * \param id The control's id
> + * \param value The control's value
> + */
> +
> +/**
> + * \class V4L2U8Control
> + * \brief Specialized V4L2Control class that handles controls with payload of
> + *        V4L2_CTRL_TYPE_U8 type.
> + *
> + * Access to the control's mem() operation is reserved to the V4L2Controls
> + * proxy class. The size of the payload data can be retrieved with the size()
> + * operation.
> + */
> +
> +/**
> + * \fn V4L2U8Control::V4L2U8Control()
> + * \brief Construct a V4L2Control with payload of uin8_t data
> + * \param id The control's id
> + * \param size The size in bytes of the payload content
> + * \param mem Pointer to the memory location of the payload content
> + *
> + * Memory is reserved in the newly created instance to hold the data payload
> + * and the data content is copied there. The reserved memory is then freed when
> + * the Control is destroyed. The memory where the control's payload was copied
> + * from should be released by the caller.
> + */
> +
> +/**
> + * \class V4L2U16Control
> + * \brief Specialized V4L2Control class that handles controls with payload of
> + *        V4L2_CTRL_TYPE_U16 type.
> + *
> + * Access to the control's mem() operation is reserved to the V4L2Controls
> + * proxy class. The size of the payload data can be retrieved with the size()
> + * operation.
> + */
> +
> +/**
> + * \fn V4L2U16Control::V4L2U16Control(unsigned int id, unsigned int size, uint16_t *mem)
> + * \brief Construct a V4L2Control with payload of uin16_t data
> + * \param id The control's id
> + * \param size The size in bytes of the payload content
> + * \param mem Pointer to the memory location of the payload content
> + *
> + * Memory is reserved in the newly created instance to hold the data payload
> + * and the data content is copied there. The reserved memory is then freed when
> + * the Control is destroyed. The memory where the control's payload was copied
> + * from should be released by the caller.
> + */
> +
> +/**
> + * \class V4L2U32Control
> + * \brief Specialized V4L2Control class that handles controls with payload of
> + *        V4L2_CTRL_TYPE_U32 type.
> + *
> + * Access to the control's mem() operation is reserved to the V4L2Controls
> + * proxy class. The size of the payload data can be retrieved with the size()
> + * operation.
> + */
> +
> +/**
> + * \fn V4L2U32Control::V4L2U32Control(unsigned int id, unsigned int size, uint32_t *mem)
> + * \brief Construct a V4L2Control with payload of uin32_t data
> + * \param id The control's id
> + * \param size The size in bytes of the payload content
> + * \param mem Pointer to the memory location of the payload content
> + *
> + * Memory is reserved in the newly created instance to hold the data payload
> + * and the data content is copied there. The reserved memory is then freed when
> + * the Control is destroyed. The memory where the control's payload was copied
> + * from should be released by the caller.
> + */
> +
> +/**
> + * \class V4L2Controls
> + * \brief Wraps a list of V4L2Control and provide accessors to each control's
> + * data
> + *
> + * The V4L2Controls class works as a wrapper for a list of V4L2Control
> + * instances. The class provides operations to add a new control (set()) and
> + * to get back it's content.
> + *
> + * User of the Libcamera V4L2 control framework which want to set controls on
> + * a video device or subdevice should create instances of the V4L2Controls
> + * class and start filling it with control values. Once ready the instance
> + * should be passed to the V4L2Base::setControls() operation, that applies the
> + * control values to the underlying hardware.
> + *
> + * When reading control, a V4L2Controls instance is passed to the
> + * V4L2Base::getControls() operation, along with a list of control IDs, and it
> + * filled by the V4L2Base operation with V4L2Control instances, the user can
> + * access by ID using on the provided V4L2Controls::get() operations.
> + */
> +
> +/**
> + * \fn V4L2Controls::~V4L2Controls()
> + * \brief Destroy all V4L2Control stored in the instance
> + *
> + * \sa V4L2Controls::clear()
> + */
> +
> +/**
> + * \typedef V4L2Controls::iterator
> + * \brief Iterator on the V4L2 controls contained in the V4L2Controls
> + */
> +
> +/**
> + * \typedef CameraConfiguration::const_iterator
> + * \brief Const iterator on the  V4L2 controls contained in the V4L2Controls
> + */
> +
> +/**
> + * \fn V4L2Controls::begin
> + * \brief Retrieve an iterator to the first V4L2Control in the sequence
> + * \return An iterator to the first V4L2 control
> + */
> +
> +/**
> + * \fn iterator V4L2Controls::begin()
> + * \brief Retrieve an iterator to the first V4L2Control in the sequence
> + * \return An iterator to the first V4L2 control
> + */
> +
> +/**
> + * \fn const_iterator V4L2Controls::begin() const
> + * \brief Retrieve a constant iterator to the first V4L2Control in the sequence
> + * \return A constant iterator to the first V4L2 control
> + */
> +
> +/**
> + * \fn iterator V4L2Controls::end()
> + * \brief Retrieve an iterator pointing to the past-the-end V4L2Control in the
> + * sequence
> + * \return An iterator to the element following the last V4L2 control in the
> + * sequence
> + */
> +
> +/**
> + * \fn const_iterator V4L2Controls::end() const
> + * \brief Retrieve a constant iterator pointing to the past-the-end V4L2Control
> + * in the sequence
> + * \return A constant iterator to the element following the last V4L2 control
> + * in the sequence
> + */
> +
> +/**
> + * \fn V4L2Controls::size()
> + * \brief Retrieve the number on stored controls
> + * \return The number of V4L2Control stored in the instance
> + */
> +
> +/**
> + * \brief Destroy each control stored in the instance
> + *
> + * Destroy all the V4L2Control instances stored in this V4L2Controls instance.
> + * Reset the instance size to 0, and release all memory reserved by each
> + * control.
> + */
> +void V4L2Controls::clear()
> +{
> +	for (unsigned int i = 0; i < controls_.size(); ++i)
> +		delete controls_[i];
> +
> +	controls_.clear();
> +}
> +
> +/**
> + * \fn V4L2Controls::operator[]
> + * \brief Access the control at index \a index
> + * \param index The index to access
> + */
> +
> +/**
> + * \fn V4L2Controls::empty()
> + * \brief Retrieve if the instance is empty
> + * \return True if the instance does not contain any control, false otherwise
> + */
> +
> +/**
> + * \brief Store a new control with integer value
> + * \param id The control's id
> + * \param value The control's value
> + */
> +void V4L2Controls::set(unsigned int id, unsigned int value)
> +{
> +	set(id, static_cast<int32_t>(value));
> +}
> +
> +/**
> + * \brief Store a new control with integer value
> + * \param id The control's id
> + * \param value The control's value
> + */
> +void V4L2Controls::set(unsigned int id, int32_t value)
> +{
> +	V4L2IntControl *c = new V4L2IntControl(id, value);
> +	controls_.push_back(c);
> +}
> +
> +/**
> + * \brief Store a new control with 64-bit integer value
> + * \param id The control's id
> + * \param value The control's value
> + */
> +void V4L2Controls::set(unsigned int id, int64_t value)
> +{
> +	V4L2Int64Control *c = new V4L2Int64Control(id, value);
> +	controls_.push_back(c);
> +}
> +
> +/**
> + * \brief Store a new control with boolean value
> + * \param id The control's id
> + * \param value The control's value
> + */
> +void V4L2Controls::set(unsigned int id, bool value)
> +{
> +	V4L2BoolControl *c = new V4L2BoolControl(id, value);
> +	controls_.push_back(c);
> +}
> +
> +/**
> + * \brief Store a new control with string value
> + * \param id The control's id
> + * \param value The control's value
> + */
> +void V4L2Controls::set(unsigned int id, std::string value)
> +{
> +	V4L2StringControl *c = new V4L2StringControl(id, value);
> +	controls_.push_back(c);
> +}
> +
> +/**
> + * \brief Store a new control with pointer to payload
> + * \param id The control's id
> + * \param size The payload size
> + * \param value The pointer to the data payload
> + */
> +void V4L2Controls::set(unsigned int id, size_t size, uint8_t *value)
> +{
> +	V4L2U8Control *c = new V4L2U8Control(id, size, value);
> +	controls_.push_back(c);
> +}
> +
> +/**
> + * \brief Store a new control with pointer to payload
> + * \param id The control's id
> + * \param size The payload size
> + * \param value The pointer to the data payload
> + */
> +void V4L2Controls::set(unsigned int id, size_t size, uint16_t *value)
> +{
> +	V4L2U16Control *c = new V4L2U16Control(id, size, value);
> +	controls_.push_back(c);
> +}
> +
> +/**
> + * \brief Store a new control with pointer to payload
> + * \param id The control's id
> + * \param size The payload size
> + * \param value The pointer to the data payload
> + */
> +void V4L2Controls::set(unsigned int id, size_t size, uint32_t *value)
> +{
> +	V4L2U32Control *c = new V4L2U32Control(id, size, value);
> +	controls_.push_back(c);
> +
> +}
> +
> +/**
> + * \brief Retrieve the control's integer value
> + * \param id The control's id
> + * \return The value of control with \a id, a negative error code if the control
> + * does not exist in the instance
> + */
> +int32_t V4L2Controls::getInt(unsigned int id)
> +{
> +	for (V4L2Control *c : controls_) {
> +		if (c->id() != id)
> +			continue;
> +
> +		V4L2IntControl *ic = static_cast<V4L2IntControl *>(c);
> +		return ic->value();
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +/**
> + * \brief Retrieve the control's 64-bit integer value
> + * \param id The control's id
> + * \return The value of control with \a id, a negative error code if the control
> + * does not exist in the instance
> + */
> +int64_t V4L2Controls::getInt64(unsigned int id)
> +{
> +	for (V4L2Control *c : controls_) {
> +		if (c->id() != id)
> +			continue;
> +
> +		V4L2Int64Control *ic = static_cast<V4L2Int64Control *>(c);
> +		return ic->value();
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +/**
> + * \brief Retrieve the control's boolean value
> + * \param id The control's id
> + * \return The value of control with \a id, false if the control does not exist
> + * in the instance
> + */
> +bool V4L2Controls::getBool(unsigned int id)
> +{
> +	for (V4L2Control *c : controls_) {
> +		if (c->id() != id)
> +			continue;
> +
> +		V4L2BoolControl *ic = static_cast<V4L2BoolControl *>(c);
> +		return ic->value();
> +	}
> +
> +	return false;
> +}
> +
> +/**
> + * \brief Retrieve the control's string value
> + * \param id The control's id
> + * \return The value of control with \a id, an empty string if the control
> + * does not exist in the instance
> + */
> +std::string V4L2Controls::getString(unsigned int id)
> +{
> +	for (V4L2Control *c : controls_) {
> +		if (c->id() != id)
> +			continue;
> +
> +		V4L2StringControl *ic = static_cast<V4L2StringControl *>(c);
> +		return ic->value();
> +	}
> +
> +	return "";
> +}
> +
> +/**
> + * \brief Retrieve a pointer to the control's payload
> + * \param id The control's id
> + * \return A pointer to the control's payload, nullptr if the control
> + * does not exist in the instance
> + */
> +uint8_t *V4L2Controls::getU8(unsigned int id)
> +{
> +	for (V4L2Control *c : controls_) {
> +		if (c->id() != id)
> +			continue;
> +
> +		V4L2U8Control *ic = static_cast<V4L2U8Control *>(c);
> +		return ic->mem();
> +	}
> +
> +	return nullptr;
> +
> +}
> +
> +/**
> + * \brief Retrieve a pointer to the control's payload
> + * \param id The control's id
> + * \return A pointer to the control's payload, nullptr if the control
> + * does not exist in the instance
> + */
> +uint16_t *V4L2Controls::getU16(unsigned int id)
> +{
> +	for (V4L2Control *c : controls_) {
> +		if (c->id() != id)
> +			continue;
> +
> +		V4L2U16Control *ic = static_cast<V4L2U16Control *>(c);
> +		return ic->mem();
> +	}
> +
> +	return nullptr;
> +}
> +
> +/**
> + * \brief Retrieve a pointer to the control's payload
> + * \param id The control's id
> + * \return A pointer to the control's payload, nullptr if the control
> + * does not exist in the instance
> + */
> +uint32_t *V4L2Controls::getU32(unsigned int id)
> +{
> +	for (V4L2Control *c : controls_) {
> +		if (c->id() != id)
> +			continue;
> +
> +		V4L2U32Control *ic = static_cast<V4L2U32Control *>(c);
> +		return ic->mem();
> +	}
> +
> +	return nullptr;
> +}
> +
> +}; /* namespace libcamera */

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list