libcamera: controls: Index ControlList by unsigned int
In preparation for serialization, index the ControlList by unsigned int. This will allow deserializing a ControlList without requiring external information. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
parent
c27b7c103a
commit
e89c2b2295
8 changed files with 60 additions and 64 deletions
|
@ -78,12 +78,22 @@ private:
|
||||||
ControlType type_;
|
ControlType type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool operator==(const ControlId &lhs, const ControlId &rhs)
|
static inline bool operator==(unsigned int lhs, const ControlId &rhs)
|
||||||
{
|
{
|
||||||
return lhs.id() == rhs.id();
|
return lhs == rhs.id();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool operator!=(const ControlId &lhs, const ControlId &rhs)
|
static inline bool operator!=(unsigned int lhs, const ControlId &rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool operator==(const ControlId &lhs, unsigned int rhs)
|
||||||
|
{
|
||||||
|
return lhs.id() == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool operator!=(const ControlId &lhs, unsigned int rhs)
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +186,7 @@ private:
|
||||||
class ControlList
|
class ControlList
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
using ControlListMap = std::unordered_map<const ControlId *, ControlValue>;
|
using ControlListMap = std::unordered_map<unsigned int, ControlValue>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ControlList(const ControlIdMap &idmap, ControlValidator *validator = nullptr);
|
ControlList(const ControlIdMap &idmap, ControlValidator *validator = nullptr);
|
||||||
|
@ -200,7 +210,7 @@ public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const T &get(const Control<T> &ctrl) const
|
const T &get(const Control<T> &ctrl) const
|
||||||
{
|
{
|
||||||
const ControlValue *val = find(ctrl);
|
const ControlValue *val = find(ctrl.id());
|
||||||
if (!val) {
|
if (!val) {
|
||||||
static T t(0);
|
static T t(0);
|
||||||
return t;
|
return t;
|
||||||
|
@ -212,7 +222,7 @@ public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void set(const Control<T> &ctrl, const T &value)
|
void set(const Control<T> &ctrl, const T &value)
|
||||||
{
|
{
|
||||||
ControlValue *val = find(ctrl);
|
ControlValue *val = find(ctrl.id());
|
||||||
if (!val)
|
if (!val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -223,8 +233,8 @@ public:
|
||||||
void set(unsigned int id, const ControlValue &value);
|
void set(unsigned int id, const ControlValue &value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ControlValue *find(const ControlId &id) const;
|
const ControlValue *find(unsigned int id) const;
|
||||||
ControlValue *find(const ControlId &id);
|
ControlValue *find(unsigned int id);
|
||||||
|
|
||||||
ControlValidator *validator_;
|
ControlValidator *validator_;
|
||||||
const ControlIdMap *idmap_;
|
const ControlIdMap *idmap_;
|
||||||
|
|
|
@ -44,10 +44,10 @@ const std::string &CameraControlValidator::name() const
|
||||||
* \param[in] id The control ID
|
* \param[in] id The control ID
|
||||||
* \return True if the control is valid, false otherwise
|
* \return True if the control is valid, false otherwise
|
||||||
*/
|
*/
|
||||||
bool CameraControlValidator::validate(const ControlId &id) const
|
bool CameraControlValidator::validate(unsigned int id) const
|
||||||
{
|
{
|
||||||
const ControlInfoMap &controls = camera_->controls();
|
const ControlInfoMap &controls = camera_->controls();
|
||||||
return controls.find(&id) != controls.end();
|
return controls.find(id) != controls.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -259,16 +259,21 @@ bool ControlValue::operator==(const ControlValue &other) const
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \fn bool operator==(const ControlId &lhs, const ControlId &rhs)
|
* \fn bool operator==(unsigned int lhs, const ControlId &rhs)
|
||||||
* \brief Compare two ControlId instances for equality
|
* \brief Compare a ControlId with a control numerical ID
|
||||||
* \param[in] lhs Left-hand side ControlId
|
* \param[in] lhs Left-hand side numerical ID
|
||||||
* \param[in] rhs Right-hand side ControlId
|
* \param[in] rhs Right-hand side ControlId
|
||||||
*
|
*
|
||||||
* ControlId instances are compared based on the numerical ControlId::id()
|
* \return True if \a lhs is equal to \a rhs.id(), false otherwise
|
||||||
* only, as an object may not have two separate controls with the same
|
*/
|
||||||
* numerical ID.
|
|
||||||
|
/**
|
||||||
|
* \fn bool operator==(const ControlId &lhs, unsigned int rhs)
|
||||||
|
* \brief Compare a ControlId with a control numerical ID
|
||||||
|
* \param[in] lhs Left-hand side ControlId
|
||||||
|
* \param[in] rhs Right-hand side numerical ID
|
||||||
*
|
*
|
||||||
* \return True if \a lhs and \a rhs have equal control IDs, false otherwise
|
* \return True if \a lhs.id() is equal to \a rhs, false otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -657,7 +662,7 @@ ControlList::ControlList(const ControlInfoMap &info, ControlValidator *validator
|
||||||
*/
|
*/
|
||||||
bool ControlList::contains(const ControlId &id) const
|
bool ControlList::contains(const ControlId &id) const
|
||||||
{
|
{
|
||||||
return controls_.find(&id) != controls_.end();
|
return controls_.find(id.id()) != controls_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -668,11 +673,7 @@ bool ControlList::contains(const ControlId &id) const
|
||||||
*/
|
*/
|
||||||
bool ControlList::contains(unsigned int id) const
|
bool ControlList::contains(unsigned int id) const
|
||||||
{
|
{
|
||||||
const auto iter = idmap_->find(id);
|
return controls_.find(id) != controls_.end();
|
||||||
if (iter == idmap_->end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return contains(*iter->second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -718,15 +719,7 @@ const ControlValue &ControlList::get(unsigned int id) const
|
||||||
{
|
{
|
||||||
static ControlValue zero;
|
static ControlValue zero;
|
||||||
|
|
||||||
const auto ctrl = idmap_->find(id);
|
const ControlValue *val = find(id);
|
||||||
if (ctrl == idmap_->end()) {
|
|
||||||
LOG(Controls, Error)
|
|
||||||
<< "Control " << utils::hex(id)
|
|
||||||
<< " is not supported";
|
|
||||||
return zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ControlValue *val = find(*ctrl->second);
|
|
||||||
if (!val)
|
if (!val)
|
||||||
return zero;
|
return zero;
|
||||||
|
|
||||||
|
@ -747,27 +740,19 @@ const ControlValue &ControlList::get(unsigned int id) const
|
||||||
*/
|
*/
|
||||||
void ControlList::set(unsigned int id, const ControlValue &value)
|
void ControlList::set(unsigned int id, const ControlValue &value)
|
||||||
{
|
{
|
||||||
const auto ctrl = idmap_->find(id);
|
ControlValue *val = find(id);
|
||||||
if (ctrl == idmap_->end()) {
|
|
||||||
LOG(Controls, Error)
|
|
||||||
<< "Control 0x" << utils::hex(id)
|
|
||||||
<< " is not supported";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ControlValue *val = find(*ctrl->second);
|
|
||||||
if (!val)
|
if (!val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
*val = value;
|
*val = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ControlValue *ControlList::find(const ControlId &id) const
|
const ControlValue *ControlList::find(unsigned int id) const
|
||||||
{
|
{
|
||||||
const auto iter = controls_.find(&id);
|
const auto iter = controls_.find(id);
|
||||||
if (iter == controls_.end()) {
|
if (iter == controls_.end()) {
|
||||||
LOG(Controls, Error)
|
LOG(Controls, Error)
|
||||||
<< "Control " << id.name() << " not found";
|
<< "Control " << utils::hex(id) << " not found";
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -775,16 +760,16 @@ const ControlValue *ControlList::find(const ControlId &id) const
|
||||||
return &iter->second;
|
return &iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlValue *ControlList::find(const ControlId &id)
|
ControlValue *ControlList::find(unsigned int id)
|
||||||
{
|
{
|
||||||
if (validator_ && !validator_->validate(id)) {
|
if (validator_ && !validator_->validate(id)) {
|
||||||
LOG(Controls, Error)
|
LOG(Controls, Error)
|
||||||
<< "Control " << id.name()
|
<< "Control " << utils::hex(id)
|
||||||
<< " is not valid for " << validator_->name();
|
<< " is not valid for " << validator_->name();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &controls_[&id];
|
return &controls_[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -19,7 +19,7 @@ public:
|
||||||
CameraControlValidator(Camera *camera);
|
CameraControlValidator(Camera *camera);
|
||||||
|
|
||||||
const std::string &name() const override;
|
const std::string &name() const override;
|
||||||
bool validate(const ControlId &id) const override;
|
bool validate(unsigned int id) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Camera *camera_;
|
Camera *camera_;
|
||||||
|
|
|
@ -19,7 +19,7 @@ public:
|
||||||
virtual ~ControlValidator() {}
|
virtual ~ControlValidator() {}
|
||||||
|
|
||||||
virtual const std::string &name() const = 0;
|
virtual const std::string &name() const = 0;
|
||||||
virtual bool validate(const ControlId &id) const = 0;
|
virtual bool validate(unsigned int id) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -231,7 +231,7 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
|
||||||
ControlList controls(data->video_->controls());
|
ControlList controls(data->video_->controls());
|
||||||
|
|
||||||
for (auto it : request->controls()) {
|
for (auto it : request->controls()) {
|
||||||
const ControlId &id = *it.first;
|
unsigned int id = it.first;
|
||||||
ControlValue &value = it.second;
|
ControlValue &value = it.second;
|
||||||
|
|
||||||
if (id == controls::Brightness) {
|
if (id == controls::Brightness) {
|
||||||
|
@ -250,7 +250,7 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
|
||||||
|
|
||||||
for (const auto &ctrl : controls)
|
for (const auto &ctrl : controls)
|
||||||
LOG(UVC, Debug)
|
LOG(UVC, Debug)
|
||||||
<< "Setting control " << ctrl.first->name()
|
<< "Setting control " << utils::hex(ctrl.first)
|
||||||
<< " to " << ctrl.second.toString();
|
<< " to " << ctrl.second.toString();
|
||||||
|
|
||||||
int ret = data->video_->setControls(&controls);
|
int ret = data->video_->setControls(&controls);
|
||||||
|
|
|
@ -298,7 +298,7 @@ int PipelineHandlerVimc::processControls(VimcCameraData *data, Request *request)
|
||||||
ControlList controls(data->sensor_->controls());
|
ControlList controls(data->sensor_->controls());
|
||||||
|
|
||||||
for (auto it : request->controls()) {
|
for (auto it : request->controls()) {
|
||||||
const ControlId &id = *it.first;
|
unsigned int id = it.first;
|
||||||
ControlValue &value = it.second;
|
ControlValue &value = it.second;
|
||||||
|
|
||||||
if (id == controls::Brightness)
|
if (id == controls::Brightness)
|
||||||
|
@ -311,7 +311,7 @@ int PipelineHandlerVimc::processControls(VimcCameraData *data, Request *request)
|
||||||
|
|
||||||
for (const auto &ctrl : controls)
|
for (const auto &ctrl : controls)
|
||||||
LOG(VIMC, Debug)
|
LOG(VIMC, Debug)
|
||||||
<< "Setting control " << ctrl.first->name()
|
<< "Setting control " << utils::hex(ctrl.first)
|
||||||
<< " to " << ctrl.second.toString();
|
<< " to " << ctrl.second.toString();
|
||||||
|
|
||||||
int ret = data->sensor_->setControls(&controls);
|
int ret = data->sensor_->setControls(&controls);
|
||||||
|
|
|
@ -176,15 +176,15 @@ int V4L2Device::getControls(ControlList *ctrls)
|
||||||
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (const auto &ctrl : *ctrls) {
|
for (const auto &ctrl : *ctrls) {
|
||||||
const ControlId *id = ctrl.first;
|
unsigned int id = ctrl.first;
|
||||||
const auto iter = controls_.find(id->id());
|
const auto iter = controls_.find(id);
|
||||||
if (iter == controls_.end()) {
|
if (iter == controls_.end()) {
|
||||||
LOG(V4L2, Error)
|
LOG(V4L2, Error)
|
||||||
<< "Control '" << id->name() << "' not found";
|
<< "Control " << utils::hex(id) << " not found";
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
v4l2Ctrls[i].id = id->id();
|
v4l2Ctrls[i].id = id;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,19 +250,19 @@ int V4L2Device::setControls(ControlList *ctrls)
|
||||||
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (const auto &ctrl : *ctrls) {
|
for (const auto &ctrl : *ctrls) {
|
||||||
const ControlId *id = ctrl.first;
|
unsigned int id = ctrl.first;
|
||||||
const auto iter = controls_.find(id->id());
|
const auto iter = controls_.find(id);
|
||||||
if (iter == controls_.end()) {
|
if (iter == controls_.end()) {
|
||||||
LOG(V4L2, Error)
|
LOG(V4L2, Error)
|
||||||
<< "Control '" << id->name() << "' not found";
|
<< "Control " << utils::hex(id) << " not found";
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
v4l2Ctrls[i].id = id->id();
|
v4l2Ctrls[i].id = id;
|
||||||
|
|
||||||
/* Set the v4l2_ext_control value for the write operation. */
|
/* Set the v4l2_ext_control value for the write operation. */
|
||||||
const ControlValue &value = ctrl.second;
|
const ControlValue &value = ctrl.second;
|
||||||
switch (id->type()) {
|
switch (iter->first->type()) {
|
||||||
case ControlTypeInteger64:
|
case ControlTypeInteger64:
|
||||||
v4l2Ctrls[i].value64 = value.get<int64_t>();
|
v4l2Ctrls[i].value64 = value.get<int64_t>();
|
||||||
break;
|
break;
|
||||||
|
@ -403,10 +403,11 @@ void V4L2Device::updateControls(ControlList *ctrls,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const struct v4l2_ext_control *v4l2Ctrl = &v4l2Ctrls[i];
|
const struct v4l2_ext_control *v4l2Ctrl = &v4l2Ctrls[i];
|
||||||
const ControlId *id = ctrl.first;
|
unsigned int id = ctrl.first;
|
||||||
ControlValue &value = ctrl.second;
|
ControlValue &value = ctrl.second;
|
||||||
|
|
||||||
switch (id->type()) {
|
const auto iter = controls_.find(id);
|
||||||
|
switch (iter->first->type()) {
|
||||||
case ControlTypeInteger64:
|
case ControlTypeInteger64:
|
||||||
value.set<int64_t>(v4l2Ctrl->value64);
|
value.set<int64_t>(v4l2Ctrl->value64);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue