summaryrefslogtreecommitdiff
path: root/src/libcamera/v4l2_controls.cpp
blob: 84258d9954d070be20d521daf7d768b1c29f6be9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * v4l2_controls.cpp - V4L2 Controls Support
 */

#include "v4l2_controls.h"

/**
 * \file v4l2_controls.h
 * \brief Support for V4L2 Controls using the V4L2 Extended Controls APIs
 *
 * The V4L2 Control API allows application to inspect and modify sets of
 * configurable parameters on a video device or subdevice. The nature of the
 * parameters an application can 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. Each control has a value, which is the data that
 * can be modified with V4L2Device::setControls() or retrieved with
 * V4L2Device::getControls().
 *
 * The control's type along with the control's flags define the type of the
 * control's value content. Controls can 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'. Such controls
 * are called 'compound controls' and are currently not supported by the
 * libcamera V4L2 control framework.
 *
 * libcamera implements support for controls using the V4L2 Extended Control
 * API, which allows future handling of controls with payloads of arbitrary
 * sizes.
 *
 * The libcamera V4L2 Controls framework operates on lists of controls, wrapped
 * by the V4L2ControlList class, to match the V4L2 extended controls API. The
 * interface to set and get control is implemented by the V4L2Device class, and
 * this file only provides the data type definitions.
 *
 * \todo Add support for compound controls
 */

namespace libcamera {

/**
 * \class V4L2ControlInfo
 * \brief Information on a V4L2 control
 *
 * The V4L2ControlInfo 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
 * 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.
 *
 * This class does not contain the control value, but only static information on
 * the control, which shall be cached by the caller at initialisation time or
 * the first time the control information is accessed.
 */

/**
 * \brief Construct a V4L2ControlInfo from a struct v4l2_query_ext_ctrl
 * \param ctrl The struct v4l2_query_ext_ctrl as returned by the kernel
 */
V4L2ControlInfo::V4L2ControlInfo(const struct v4l2_query_ext_ctrl &ctrl)
{
	id_ = ctrl.id;
	type_ = ctrl.type;
	name_ = static_cast<const char *>(ctrl.name);
	size_ = ctrl.elem_size * ctrl.elems;
	min_ = ctrl.minimum;
	max_ = ctrl.maximum;
}

/**
 * \fn V4L2ControlInfo::id()
 * \brief Retrieve the control ID
 * \return The V4L2 control ID
 */

/**
 * \fn V4L2ControlInfo::type()
 * \brief Retrieve the control type as defined by V4L2_CTRL_TYPE_*
 * \return The V4L2 control type
 */

/**
 * \fn V4L2ControlInfo::size()
 * \brief Retrieve the control value data size (in bytes)
 * \return The V4L2 control value data size
 */

/**
 * \fn V4L2ControlInfo::name()
 * \brief Retrieve the control user readable name
 * \return The V4L2 control user readable name
 */

/**
 * \fn V4L2ControlInfo::min()
 * \brief Retrieve the control minimum value
 * \return The V4L2 control minimum value
 */

/**
 * \fn V4L2ControlInfo::max()
 * \brief Retrieve the control maximum value
 * \return The V4L2 control maximum value
 */

/**
 * \typedef V4L2ControlInfoMap
 * \brief A map of control ID to V4L2ControlInfo
 */

/**
 * \class V4L2Control
 * \brief A V4L2 control value
 *
 * The V4L2Control class represent the value of a V4L2 control. The class
 * stores values that have been read from or will be applied to a V4L2 device.
 *
 * The value stored in the class instances does not reflect what is actually
 * applied to the hardware but is a pure software cache optionally initialized
 * at control creation time and modified by a control read or write operation.
 *
 * The write and read controls the V4L2Control class instances are not meant
 * to be directly used but are instead intended to be grouped in
 * V4L2ControlList instances, which are then passed as parameters to
 * V4L2Device::setControls() and V4L2Device::getControls() operations.
 */

/**
 * \fn V4L2Control::V4L2Control
 * \brief Construct a V4L2 control with \a id and \a value
 * \param id The V4L2 control ID
 * \param value The control value
 */

/**
 * \fn V4L2Control::value()
 * \brief Retrieve the value of the control
 *
 * This method returns the cached control value, initially set by
 * V4L2ControlList::add() and then updated when the controls are read or
 * written with V4L2Device::getControls() and V4L2Device::setControls().
 *
 * \return The V4L2 control value
 */

/**
 * \fn V4L2Control::setValue()
 * \brief Set the value of the control
 * \param value The new V4L2 control value
 *
 * This method stores the control value, which will be applied to the
 * device when calling V4L2Device::setControls().
 */

/**
 * \fn V4L2Control::id()
 * \brief Retrieve the control ID this instance refers to
 * \return The V4L2Control ID
 */

/**
 * \class V4L2ControlList
 * \brief Container of V4L2Control instances
 *
 * The V4L2ControlList class works as a container for a list of V4L2Control
 * instances. The class provides operations to add a new control to the list,
 * get back a control value, and reset the list of controls it contains.
 *
 * In order to set and get controls, user of the libcamera V4L2 control
 * framework should operate on instances of the V4L2ControlList class, and use
 * them as argument for the V4L2Device::setControls() and
 * V4L2Device::getControls() operations, which write and read a list of
 * controls to or from a V4L2 device (a video device or a subdevice).
 *
 * Controls are added to a V4L2ControlList instance with the add() method, with
 * or without a value.
 *
 * To write controls to a device, the controls of interest shall be added with
 * an initial value by calling V4L2ControlList::add(unsigned int id, int64_t
 * value) to prepare for a write operation. Once the values of all controls of
 * interest have been added, the V4L2ControlList instance is passed to the
 * V4L2Device::setControls(), which sets the controls on the device.
 *
 * To read controls from a device, the desired controls are added with
 * V4L2ControlList::add(unsigned int id) to prepare for a read operation. The
 * V4L2ControlList instance is then passed to V4L2Device::getControls(), which
 * reads the controls from the device and updates the values stored in
 * V4L2ControlList.
 *
 * V4L2ControlList instances can be reset to remove all controls they contain
 * and prepare to be re-used for a new control write/read sequence.
 */

/**
 * \typedef V4L2ControlList::iterator
 * \brief Iterator on the V4L2 controls contained in the instance
 */

/**
 * \typedef V4L2ControlList::const_iterator
 * \brief Const iterator on the V4L2 controls contained in the instance
 */

/**
 * \fn iterator V4L2ControlList::begin()
 * \brief Retrieve an iterator to the first V4L2Control in the instance
 * \return An iterator to the first V4L2 control
 */

/**
 * \fn const_iterator V4L2ControlList::begin() const
 * \brief Retrieve a constant iterator to the first V4L2Control in the instance
 * \return A constant iterator to the first V4L2 control
 */

/**
 * \fn iterator V4L2ControlList::end()
 * \brief Retrieve an iterator pointing to the past-the-end V4L2Control in the
 * instance
 * \return An iterator to the element following the last V4L2 control in the
 * instance
 */

/**
 * \fn const_iterator V4L2ControlList::end() const
 * \brief Retrieve a constant iterator pointing to the past-the-end V4L2Control
 * in the instance
 * \return A constant iterator to the element following the last V4L2 control
 * in the instance
 */

/**
 * \fn V4L2ControlList::empty()
 * \brief Verify if the instance does not contain any control
 * \return True if the instance does not contain any control, false otherwise
 */

/**
 * \fn V4L2ControlList::size()
 * \brief Retrieve the number on controls in the instance
 * \return The number of V4L2Control stored in the instance
 */

/**
 * \fn V4L2ControlList::clear()
 * \brief Remove all controls in the instance
 */

/**
 * \brief Add control with \a id and optional \a value to the instance
 * \param id The V4L2 control ID (V4L2_CID_*)
 * \param value The V4L2 control value
 *
 * This method adds a new V4L2 control to the V4L2ControlList. The newly
 * inserted control shall not already be present in the control lists, otherwise
 * this method, and further use of the control list lead to undefined behaviour.
 */
void V4L2ControlList::add(unsigned int id, int64_t value)
{
	controls_.emplace_back(id, value);
}

/**
 * \brief Retrieve the control at \a index
 * \param[in] index The control index
 *
 * Controls are stored in a V4L2ControlList in order of insertion and this
 * method retrieves the control at \a index.
 *
 * \return A pointer to the V4L2Control at \a index or nullptr if the
 * index is larger than the number of controls
 */
V4L2Control *V4L2ControlList::getByIndex(unsigned int index)
{
	if (index >= controls_.size())
		return nullptr;

	return &controls_[index];
}

/**
 * \brief Retrieve the control with \a id
 * \param[in] id The V4L2 control ID (V4L2_CID_xx)
 * \return A pointer to the V4L2Control with \a id or nullptr if the
 * control ID is not part of this instance.
 */
V4L2Control *V4L2ControlList::operator[](unsigned int id)
{
	for (V4L2Control &ctrl : controls_) {
		if (ctrl.id() == id)
			return &ctrl;
	}

	return nullptr;
}

} /* namespace libcamera */