summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ipa/rkisp1/rkisp1.cpp18
-rw-r--r--src/libcamera/camera_sensor.cpp4
-rw-r--r--src/libcamera/include/camera_sensor.h7
-rw-r--r--src/libcamera/include/v4l2_controls.h42
-rw-r--r--src/libcamera/include/v4l2_device.h6
-rw-r--r--src/libcamera/pipeline/ipu3/ipu3.cpp9
-rw-r--r--src/libcamera/pipeline/uvcvideo.cpp24
-rw-r--r--src/libcamera/pipeline/vimc.cpp25
-rw-r--r--src/libcamera/v4l2_controls.cpp196
-rw-r--r--src/libcamera/v4l2_device.cpp51
-rw-r--r--test/v4l2_videodevice/controls.cpp33
11 files changed, 127 insertions, 288 deletions
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index b0d23dd1..69ced840 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -49,6 +49,8 @@ private:
std::map<unsigned int, BufferMemory> bufferInfo_;
+ V4L2ControlInfoMap ctrls_;
+
/* Camera sensor controls. */
bool autoExposure_;
uint32_t exposure_;
@@ -65,16 +67,16 @@ void IPARkISP1::configure(const std::map<unsigned int, IPAStream> &streamConfig,
if (entityControls.empty())
return;
- const V4L2ControlInfoMap &ctrls = entityControls.at(0);
+ ctrls_ = entityControls.at(0);
- const auto itExp = ctrls.find(V4L2_CID_EXPOSURE);
- if (itExp == ctrls.end()) {
+ const auto itExp = ctrls_.find(V4L2_CID_EXPOSURE);
+ if (itExp == ctrls_.end()) {
LOG(IPARkISP1, Error) << "Can't find exposure control";
return;
}
- const auto itGain = ctrls.find(V4L2_CID_ANALOGUE_GAIN);
- if (itGain == ctrls.end()) {
+ const auto itGain = ctrls_.find(V4L2_CID_ANALOGUE_GAIN);
+ if (itGain == ctrls_.end()) {
LOG(IPARkISP1, Error) << "Can't find gain control";
return;
}
@@ -210,9 +212,9 @@ void IPARkISP1::setControls(unsigned int frame)
IPAOperationData op;
op.operation = RKISP1_IPA_ACTION_V4L2_SET;
- V4L2ControlList ctrls;
- ctrls.add(V4L2_CID_EXPOSURE, exposure_);
- ctrls.add(V4L2_CID_ANALOGUE_GAIN, gain_);
+ V4L2ControlList ctrls(ctrls_);
+ ctrls.set(V4L2_CID_EXPOSURE, static_cast<int32_t>(exposure_));
+ ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast<int32_t>(gain_));
op.v4l2controls.push_back(ctrls);
queueFrameAction.emit(frame, op);
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index a7670b44..9e8b44a2 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -279,7 +279,7 @@ const V4L2ControlInfoMap &CameraSensor::controls() const
* \retval -EINVAL One of the control is not supported or not accessible
* \retval i The index of the control that failed
*/
-int CameraSensor::getControls(V4L2ControlList *ctrls)
+int CameraSensor::getControls(ControlList *ctrls)
{
return subdev_->getControls(ctrls);
}
@@ -309,7 +309,7 @@ int CameraSensor::getControls(V4L2ControlList *ctrls)
* \retval -EINVAL One of the control is not supported or not accessible
* \retval i The index of the control that failed
*/
-int CameraSensor::setControls(V4L2ControlList *ctrls)
+int CameraSensor::setControls(ControlList *ctrls)
{
return subdev_->setControls(ctrls);
}
diff --git a/src/libcamera/include/camera_sensor.h b/src/libcamera/include/camera_sensor.h
index fe033fb3..f426e29b 100644
--- a/src/libcamera/include/camera_sensor.h
+++ b/src/libcamera/include/camera_sensor.h
@@ -13,11 +13,12 @@
#include <libcamera/geometry.h>
#include "log.h"
-#include "v4l2_controls.h"
namespace libcamera {
+class ControlList;
class MediaEntity;
+class V4L2ControlInfoMap;
class V4L2Subdevice;
struct V4L2SubdeviceFormat;
@@ -43,8 +44,8 @@ public:
int setFormat(V4L2SubdeviceFormat *format);
const V4L2ControlInfoMap &controls() const;
- int getControls(V4L2ControlList *ctrls);
- int setControls(V4L2ControlList *ctrls);
+ int getControls(ControlList *ctrls);
+ int setControls(ControlList *ctrls);
protected:
std::string logPrefix() const;
diff --git a/src/libcamera/include/v4l2_controls.h b/src/libcamera/include/v4l2_controls.h
index 8990e755..89cc7448 100644
--- a/src/libcamera/include/v4l2_controls.h
+++ b/src/libcamera/include/v4l2_controls.h
@@ -13,7 +13,6 @@
#include <string>
#include <vector>
-#include <linux/v4l2-controls.h>
#include <linux/videodev2.h>
#include <libcamera/controls.h>
@@ -57,47 +56,20 @@ public:
using std::map<unsigned int, V4L2ControlInfo>::size;
using std::map<unsigned int, V4L2ControlInfo>::count;
using std::map<unsigned int, V4L2ControlInfo>::find;
-};
-class V4L2Control
-{
-public:
- V4L2Control(unsigned int id, const ControlValue &value = ControlValue())
- : id_(id), value_(value)
- {
- }
-
- unsigned int id() const { return id_; }
- const ControlValue &value() const { return value_; }
- ControlValue &value() { return value_; }
+ const ControlIdMap &idmap() const { return idmap_; }
private:
- unsigned int id_;
- ControlValue value_;
+ ControlIdMap idmap_;
};
-class V4L2ControlList
+class V4L2ControlList : public ControlList
{
public:
- 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(); }
-
- bool empty() const { return controls_.empty(); }
- std::size_t size() const { return controls_.size(); }
-
- void clear() { controls_.clear(); }
- void add(unsigned int id, int64_t value = 0);
-
- V4L2Control *getByIndex(unsigned int index);
- V4L2Control *operator[](unsigned int id);
-
-private:
- std::vector<V4L2Control> controls_;
+ V4L2ControlList(const V4L2ControlInfoMap &info)
+ : ControlList(info.idmap())
+ {
+ }
};
} /* namespace libcamera */
diff --git a/src/libcamera/include/v4l2_device.h b/src/libcamera/include/v4l2_device.h
index 75a52c33..daa762d5 100644
--- a/src/libcamera/include/v4l2_device.h
+++ b/src/libcamera/include/v4l2_device.h
@@ -25,8 +25,8 @@ public:
const V4L2ControlInfoMap &controls() const { return controls_; }
- int getControls(V4L2ControlList *ctrls);
- int setControls(V4L2ControlList *ctrls);
+ int getControls(ControlList *ctrls);
+ int setControls(ControlList *ctrls);
const std::string &deviceNode() const { return deviceNode_; }
@@ -43,7 +43,7 @@ protected:
private:
void listControls();
- void updateControls(V4L2ControlList *ctrls,
+ void updateControls(ControlList *ctrls,
const V4L2ControlInfo **controlInfo,
const struct v4l2_ext_control *v4l2Ctrls,
unsigned int count);
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 827906d5..9776b36b 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -199,6 +199,7 @@ class PipelineHandlerIPU3 : public PipelineHandler
{
public:
static constexpr unsigned int V4L2_CID_IPU3_PIPE_MODE = 0x009819c1;
+
enum IPU3PipeModes {
IPU3PipeModeVideo = 0,
IPU3PipeModeStillCapture = 1,
@@ -603,10 +604,10 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
return ret;
/* Apply the "pipe_mode" control to the ImgU subdevice. */
- V4L2ControlList ctrls;
- ctrls.add(V4L2_CID_IPU3_PIPE_MODE, vfStream->active_ ?
- IPU3PipeModeVideo :
- IPU3PipeModeStillCapture);
+ V4L2ControlList ctrls(imgu->imgu_->controls());
+ ctrls.set(V4L2_CID_IPU3_PIPE_MODE,
+ static_cast<int32_t>(vfStream->active_ ? IPU3PipeModeVideo :
+ IPU3PipeModeStillCapture));
ret = imgu->imgu_->setControls(&ctrls);
if (ret) {
LOG(IPU3, Error) << "Unable to set pipe_mode control";
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 88f7fb9b..547ad5ca 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -228,31 +228,30 @@ void PipelineHandlerUVC::stop(Camera *camera)
int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
{
- V4L2ControlList controls;
+ V4L2ControlList controls(data->video_->controls());
for (auto it : request->controls()) {
const ControlId &id = *it.first;
ControlValue &value = it.second;
if (id == controls::Brightness) {
- controls.add(V4L2_CID_BRIGHTNESS, value.get<int32_t>());
+ controls.set(V4L2_CID_BRIGHTNESS, value);
} else if (id == controls::Contrast) {
- controls.add(V4L2_CID_CONTRAST, value.get<int32_t>());
+ controls.set(V4L2_CID_CONTRAST, value);
} else if (id == controls::Saturation) {
- controls.add(V4L2_CID_SATURATION, value.get<int32_t>());
+ controls.set(V4L2_CID_SATURATION, value);
} else if (id == controls::ManualExposure) {
- controls.add(V4L2_CID_EXPOSURE_AUTO, 1);
- controls.add(V4L2_CID_EXPOSURE_ABSOLUTE, value.get<int32_t>());
+ controls.set(V4L2_CID_EXPOSURE_AUTO, static_cast<int32_t>(1));
+ controls.set(V4L2_CID_EXPOSURE_ABSOLUTE, value);
} else if (id == controls::ManualGain) {
- controls.add(V4L2_CID_GAIN, value.get<int32_t>());
+ controls.set(V4L2_CID_GAIN, value);
}
}
- for (const V4L2Control &ctrl : controls)
+ for (const auto &ctrl : controls)
LOG(UVC, Debug)
- << "Setting control 0x"
- << std::hex << std::setw(8) << ctrl.id() << std::dec
- << " to " << ctrl.value().toString();
+ << "Setting control " << ctrl.first->name()
+ << " to " << ctrl.second.toString();
int ret = data->video_->setControls(&controls);
if (ret) {
@@ -338,11 +337,10 @@ int UVCCameraData::init(MediaEntity *entity)
/* Initialise the supported controls. */
const V4L2ControlInfoMap &controls = video_->controls();
for (const auto &ctrl : controls) {
- unsigned int v4l2Id = ctrl.first;
const V4L2ControlInfo &info = ctrl.second;
const ControlId *id;
- switch (v4l2Id) {
+ switch (info.id().id()) {
case V4L2_CID_BRIGHTNESS:
id = &controls::Brightness;
break;
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index f1cfd0ed..53d00360 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -279,26 +279,24 @@ void PipelineHandlerVimc::stop(Camera *camera)
int PipelineHandlerVimc::processControls(VimcCameraData *data, Request *request)
{
- V4L2ControlList controls;
+ V4L2ControlList controls(data->sensor_->controls());
for (auto it : request->controls()) {
const ControlId &id = *it.first;
ControlValue &value = it.second;
- if (id == controls::Brightness) {
- controls.add(V4L2_CID_BRIGHTNESS, value.get<int32_t>());
- } else if (id == controls::Contrast) {
- controls.add(V4L2_CID_CONTRAST, value.get<int32_t>());
- } else if (id == controls::Saturation) {
- controls.add(V4L2_CID_SATURATION, value.get<int32_t>());
- }
+ if (id == controls::Brightness)
+ controls.set(V4L2_CID_BRIGHTNESS, value);
+ else if (id == controls::Contrast)
+ controls.set(V4L2_CID_CONTRAST, value);
+ else if (id == controls::Saturation)
+ controls.set(V4L2_CID_SATURATION, value);
}
- for (const V4L2Control &ctrl : controls)
+ for (const auto &ctrl : controls)
LOG(VIMC, Debug)
- << "Setting control 0x"
- << std::hex << std::setw(8) << ctrl.id() << std::dec
- << " to " << ctrl.value().toString();
+ << "Setting control " << ctrl.first->name()
+ << " to " << ctrl.second.toString();
int ret = data->sensor_->setControls(&controls);
if (ret) {
@@ -415,11 +413,10 @@ int VimcCameraData::init(MediaDevice *media)
/* Initialise the supported controls. */
const V4L2ControlInfoMap &controls = sensor_->controls();
for (const auto &ctrl : controls) {
- unsigned int v4l2Id = ctrl.first;
const V4L2ControlInfo &info = ctrl.second;
const ControlId *id;
- switch (v4l2Id) {
+ switch (info.id().id()) {
case V4L2_CID_BRIGHTNESS:
id = &controls::Brightness;
break;
diff --git a/src/libcamera/v4l2_controls.cpp b/src/libcamera/v4l2_controls.cpp
index 3be21997..c45d3fda 100644
--- a/src/libcamera/v4l2_controls.cpp
+++ b/src/libcamera/v4l2_controls.cpp
@@ -40,7 +40,7 @@
* sizes.
*
* The libcamera V4L2 Controls framework operates on lists of controls, wrapped
- * by the V4L2ControlList class, to match the V4L2 extended controls API. The
+ * by the ControlList 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.
*
@@ -175,194 +175,42 @@ V4L2ControlInfoMap &V4L2ControlInfoMap::operator=(std::map<unsigned int, V4L2Con
{
std::map<unsigned int, V4L2ControlInfo>::operator=(std::move(info));
+ idmap_.clear();
+ for (const auto &ctrl : *this)
+ idmap_[ctrl.first] = &ctrl.second.id();
+
return *this;
}
/**
- * \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.
+ * \fn const ControlIdMap &V4L2ControlInfoMap::idmap() const
+ * \brief Retrieve the ControlId map
*
- * 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() const
- * \brief Retrieve the value of the control
+ * 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.
*
- * This method is a const version of V4L2Control::value(), returning a const
- * reference to the value.
- *
- * \return The V4L2 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::id()
- * \brief Retrieve the control ID this instance refers to
- * \return The V4L2Control ID
+ * \return The ControlId map
*/
/**
* \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.
+ * \brief A list of controls for a V4L2 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.
+ * This class specialises the ControList class for use with V4L2 devices. It
+ * offers a convenience API to create a ControlList from a V4L2ControlInfoMap.
*
- * 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
+ * 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 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 V4L2ControlList::V4L2ControlList(const V4L2ControlInfoMap &info)
+ * \brief Construct a V4L2ControlList associated with a V4L2 device
+ * \param[in] info The V4L2 device control info map
*/
-/**
- * \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 */
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
index 1f755f0f..b47ba448 100644
--- a/src/libcamera/v4l2_device.cpp
+++ b/src/libcamera/v4l2_device.cpp
@@ -163,7 +163,7 @@ void V4L2Device::close()
* \retval -EINVAL One of the control is not supported or not accessible
* \retval i The index of the control that failed
*/
-int V4L2Device::getControls(V4L2ControlList *ctrls)
+int V4L2Device::getControls(ControlList *ctrls)
{
unsigned int count = ctrls->size();
if (count == 0)
@@ -173,18 +173,21 @@ int V4L2Device::getControls(V4L2ControlList *ctrls)
struct v4l2_ext_control v4l2Ctrls[count];
memset(v4l2Ctrls, 0, sizeof(v4l2Ctrls));
- for (unsigned int i = 0; i < count; ++i) {
- const V4L2Control *ctrl = ctrls->getByIndex(i);
- const auto iter = controls_.find(ctrl->id());
+ unsigned int i = 0;
+ for (const auto &ctrl : *ctrls) {
+ const ControlId *id = ctrl.first;
+ const auto iter = controls_.find(id->id());
if (iter == controls_.end()) {
LOG(V4L2, Error)
- << "Control '" << ctrl->id() << "' not found";
+ << "Control '" << id->name() << "' not found";
return -EINVAL;
}
const V4L2ControlInfo *info = &iter->second;
controlInfo[i] = info;
- v4l2Ctrls[i].id = ctrl->id();
+ v4l2Ctrls[i].id = id->id();
+
+ i++;
}
struct v4l2_ext_controls v4l2ExtCtrls = {};
@@ -238,7 +241,7 @@ int V4L2Device::getControls(V4L2ControlList *ctrls)
* \retval -EINVAL One of the control is not supported or not accessible
* \retval i The index of the control that failed
*/
-int V4L2Device::setControls(V4L2ControlList *ctrls)
+int V4L2Device::setControls(ControlList *ctrls)
{
unsigned int count = ctrls->size();
if (count == 0)
@@ -248,32 +251,36 @@ int V4L2Device::setControls(V4L2ControlList *ctrls)
struct v4l2_ext_control v4l2Ctrls[count];
memset(v4l2Ctrls, 0, sizeof(v4l2Ctrls));
- for (unsigned int i = 0; i < count; ++i) {
- const V4L2Control *ctrl = ctrls->getByIndex(i);
- const auto iter = controls_.find(ctrl->id());
+ unsigned int i = 0;
+ for (const auto &ctrl : *ctrls) {
+ const ControlId *id = ctrl.first;
+ const auto iter = controls_.find(id->id());
if (iter == controls_.end()) {
LOG(V4L2, Error)
- << "Control '" << ctrl->id() << "' not found";
+ << "Control '" << id->name() << "' not found";
return -EINVAL;
}
const V4L2ControlInfo *info = &iter->second;
controlInfo[i] = info;
- v4l2Ctrls[i].id = ctrl->id();
+ v4l2Ctrls[i].id = id->id();
/* Set the v4l2_ext_control value for the write operation. */
+ const ControlValue &value = ctrl.second;
switch (info->id().type()) {
case ControlTypeInteger64:
- v4l2Ctrls[i].value64 = ctrl->value().get<int64_t>();
+ v4l2Ctrls[i].value64 = value.get<int64_t>();
break;
default:
/*
* \todo To be changed when support for string and
* compound controls will be added.
*/
- v4l2Ctrls[i].value = ctrl->value().get<int32_t>();
+ v4l2Ctrls[i].value = value.get<int32_t>();
break;
}
+
+ i++;
}
struct v4l2_ext_controls v4l2ExtCtrls = {};
@@ -385,28 +392,34 @@ void V4L2Device::listControls()
* \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(V4L2ControlList *ctrls,
+void V4L2Device::updateControls(ControlList *ctrls,
const V4L2ControlInfo **controlInfo,
const struct v4l2_ext_control *v4l2Ctrls,
unsigned int count)
{
- for (unsigned int i = 0; i < count; ++i) {
+ unsigned int i = 0;
+ for (auto &ctrl : *ctrls) {
+ if (i == count)
+ break;
+
const struct v4l2_ext_control *v4l2Ctrl = &v4l2Ctrls[i];
const V4L2ControlInfo *info = controlInfo[i];
- V4L2Control *ctrl = ctrls->getByIndex(i);
+ ControlValue &value = ctrl.second;
switch (info->id().type()) {
case ControlTypeInteger64:
- ctrl->value().set<int64_t>(v4l2Ctrl->value64);
+ value.set<int64_t>(v4l2Ctrl->value64);
break;
default:
/*
* \todo To be changed when support for string and
* compound controls will be added.
*/
- ctrl->value().set<int32_t>(v4l2Ctrl->value);
+ value.set<int32_t>(v4l2Ctrl->value);
break;
}
+
+ i++;
}
}
diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp
index cfd47454..e59387ab 100644
--- a/test/v4l2_videodevice/controls.cpp
+++ b/test/v4l2_videodevice/controls.cpp
@@ -46,10 +46,10 @@ protected:
const V4L2ControlInfo &saturation = info.find(V4L2_CID_SATURATION)->second;
/* Test getting controls. */
- V4L2ControlList ctrls;
- ctrls.add(V4L2_CID_BRIGHTNESS);
- ctrls.add(V4L2_CID_CONTRAST);
- ctrls.add(V4L2_CID_SATURATION);
+ V4L2ControlList ctrls(info);
+ ctrls.set(V4L2_CID_BRIGHTNESS, -1);
+ ctrls.set(V4L2_CID_CONTRAST, -1);
+ ctrls.set(V4L2_CID_SATURATION, -1);
int ret = capture_->getControls(&ctrls);
if (ret) {
@@ -57,10 +57,17 @@ protected:
return TestFail;
}
+ if (ctrls.get(V4L2_CID_BRIGHTNESS).get<int32_t>() == -1 ||
+ ctrls.get(V4L2_CID_CONTRAST).get<int32_t>() == -1 ||
+ ctrls.get(V4L2_CID_SATURATION).get<int32_t>() == -1) {
+ cerr << "Incorrect value for retrieved controls" << endl;
+ return TestFail;
+ }
+
/* Test setting controls. */
- ctrls[V4L2_CID_BRIGHTNESS]->value() = brightness.range().min();
- ctrls[V4L2_CID_CONTRAST]->value() = contrast.range().max();
- ctrls[V4L2_CID_SATURATION]->value() = saturation.range().min();
+ ctrls.set(V4L2_CID_BRIGHTNESS, brightness.range().min());
+ ctrls.set(V4L2_CID_CONTRAST, contrast.range().max());
+ ctrls.set(V4L2_CID_SATURATION, saturation.range().min());
ret = capture_->setControls(&ctrls);
if (ret) {
@@ -69,9 +76,9 @@ protected:
}
/* Test setting controls outside of range. */
- ctrls[V4L2_CID_BRIGHTNESS]->value() = brightness.range().min().get<int32_t>() - 1;
- ctrls[V4L2_CID_CONTRAST]->value() = contrast.range().max().get<int32_t>() + 1;
- ctrls[V4L2_CID_SATURATION]->value() = saturation.range().min().get<int32_t>() + 1;
+ ctrls.set(V4L2_CID_BRIGHTNESS, brightness.range().min().get<int32_t>() - 1);
+ ctrls.set(V4L2_CID_CONTRAST, contrast.range().max().get<int32_t>() + 1);
+ ctrls.set(V4L2_CID_SATURATION, saturation.range().min().get<int32_t>() + 1);
ret = capture_->setControls(&ctrls);
if (ret) {
@@ -79,9 +86,9 @@ protected:
return TestFail;
}
- if (ctrls[V4L2_CID_BRIGHTNESS]->value() != brightness.range().min() ||
- ctrls[V4L2_CID_CONTRAST]->value() != brightness.range().max() ||
- ctrls[V4L2_CID_SATURATION]->value() != saturation.range().min().get<int32_t>() + 1) {
+ if (ctrls.get(V4L2_CID_BRIGHTNESS) != brightness.range().min() ||
+ ctrls.get(V4L2_CID_CONTRAST) != brightness.range().max() ||
+ ctrls.get(V4L2_CID_SATURATION) != saturation.range().min().get<int32_t>() + 1) {
cerr << "Controls not updated when set" << endl;
return TestFail;
}