libcamera: v4l2_device: List valid controls at open
Enumerate all the valid controls a device supports at open() time. A control is valid only if its type is supported. Store the control information in a map inside the device to save querying the control when setting or getting its value from the device and provide an operation to retrieve information by control ID. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
bab8b01895
commit
030ce6491e
2 changed files with 65 additions and 0 deletions
|
@ -7,18 +7,23 @@
|
||||||
#ifndef __LIBCAMERA_V4L2_DEVICE_H__
|
#ifndef __LIBCAMERA_V4L2_DEVICE_H__
|
||||||
#define __LIBCAMERA_V4L2_DEVICE_H__
|
#define __LIBCAMERA_V4L2_DEVICE_H__
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
|
|
||||||
|
class V4L2ControlInfo;
|
||||||
|
|
||||||
class V4L2Device : protected Loggable
|
class V4L2Device : protected Loggable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void close();
|
void close();
|
||||||
bool isOpen() const { return fd_ != -1; }
|
bool isOpen() const { return fd_ != -1; }
|
||||||
|
|
||||||
|
const V4L2ControlInfo *getControlInfo(unsigned int id) const;
|
||||||
|
|
||||||
const std::string &deviceNode() const { return deviceNode_; }
|
const std::string &deviceNode() const { return deviceNode_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -32,6 +37,9 @@ protected:
|
||||||
int fd() { return fd_; }
|
int fd() { return fd_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void listControls();
|
||||||
|
|
||||||
|
std::map<unsigned int, V4L2ControlInfo> controls_;
|
||||||
std::string deviceNode_;
|
std::string deviceNode_;
|
||||||
int fd_;
|
int fd_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "v4l2_controls.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file v4l2_device.h
|
* \file v4l2_device.h
|
||||||
|
@ -82,6 +83,8 @@ int V4L2Device::open(unsigned int flags)
|
||||||
|
|
||||||
fd_ = ret;
|
fd_ = ret;
|
||||||
|
|
||||||
|
listControls();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +110,21 @@ void V4L2Device::close()
|
||||||
* \return True if the V4L2 device node is open, false otherwise
|
* \return True if the V4L2 device node is open, false otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieve information about a control
|
||||||
|
* \param[in] id The control ID
|
||||||
|
* \return A pointer to the V4L2ControlInfo for control \a id, or nullptr
|
||||||
|
* if the device doesn't have such a control
|
||||||
|
*/
|
||||||
|
const V4L2ControlInfo *V4L2Device::getControlInfo(unsigned int id) const
|
||||||
|
{
|
||||||
|
auto it = controls_.find(id);
|
||||||
|
if (it == controls_.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &it->second;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Perform an IOCTL system call on the device node
|
* \brief Perform an IOCTL system call on the device node
|
||||||
* \param[in] request The IOCTL request code
|
* \param[in] request The IOCTL request code
|
||||||
|
@ -137,4 +155,43 @@ int V4L2Device::ioctl(unsigned long request, void *argp)
|
||||||
* \return The V4L2 device file descriptor, -1 if the device node is not open
|
* \return The V4L2 device file descriptor, -1 if the device node is not open
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \brief List and store information about all controls supported by the
|
||||||
|
* V4L2 device
|
||||||
|
*/
|
||||||
|
void V4L2Device::listControls()
|
||||||
|
{
|
||||||
|
struct v4l2_query_ext_ctrl ctrl = {};
|
||||||
|
|
||||||
|
/* \todo Add support for menu and compound controls. */
|
||||||
|
ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
|
||||||
|
while (ioctl(VIDIOC_QUERY_EXT_CTRL, &ctrl) == 0) {
|
||||||
|
if (ctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS ||
|
||||||
|
ctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
|
||||||
|
ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
V4L2ControlInfo info(ctrl);
|
||||||
|
switch (info.type()) {
|
||||||
|
case V4L2_CTRL_TYPE_INTEGER:
|
||||||
|
case V4L2_CTRL_TYPE_BOOLEAN:
|
||||||
|
case V4L2_CTRL_TYPE_MENU:
|
||||||
|
case V4L2_CTRL_TYPE_BUTTON:
|
||||||
|
case V4L2_CTRL_TYPE_INTEGER64:
|
||||||
|
case V4L2_CTRL_TYPE_BITMASK:
|
||||||
|
case V4L2_CTRL_TYPE_INTEGER_MENU:
|
||||||
|
break;
|
||||||
|
/* \todo Support compound controls. */
|
||||||
|
default:
|
||||||
|
LOG(V4L2, Error) << "Control type '" << info.type()
|
||||||
|
<< "' not supported";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
controls_.emplace(ctrl.id, info);
|
||||||
|
ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue