libcamera: v4l2_subdevice: Collect subdev capabilities

Collect subdev capabilities at open() time.

Model the V4L2SubdevCapabilties as V4L2Capability from the video
device class.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Jacopo Mondi 2022-03-30 11:08:43 +02:00 committed by Laurent Pinchart
parent 8695e02916
commit 39d4917619
2 changed files with 62 additions and 1 deletions

View file

@ -29,6 +29,17 @@ namespace libcamera {
class MediaDevice; class MediaDevice;
struct V4L2SubdeviceCapability final : v4l2_subdev_capability {
bool isReadOnly() const
{
return capabilities & V4L2_SUBDEV_CAP_RO_SUBDEV;
}
bool hasStreams() const
{
return capabilities & V4L2_SUBDEV_CAP_MPLEXED;
}
};
struct V4L2SubdeviceFormat { struct V4L2SubdeviceFormat {
uint32_t mbus_code; uint32_t mbus_code;
Size size; Size size;
@ -70,6 +81,7 @@ public:
Whence whence = ActiveFormat); Whence whence = ActiveFormat);
const std::string &model(); const std::string &model();
const V4L2SubdeviceCapability &caps() const { return caps_; }
static std::unique_ptr<V4L2Subdevice> static std::unique_ptr<V4L2Subdevice>
fromEntityName(const MediaDevice *media, const std::string &entity); fromEntityName(const MediaDevice *media, const std::string &entity);
@ -87,6 +99,7 @@ private:
const MediaEntity *entity_; const MediaEntity *entity_;
std::string model_; std::string model_;
struct V4L2SubdeviceCapability caps_;
}; };
} /* namespace libcamera */ } /* namespace libcamera */

View file

@ -133,6 +133,30 @@ const std::map<uint32_t, V4L2SubdeviceFormatInfo> formatInfoMap = {
} /* namespace */ } /* namespace */
/**
* \struct V4L2SubdeviceCapability
* \brief struct v4l2_subdev_capability object wrapper and helpers
*
* The V4L2SubdeviceCapability structure manages the information returned by the
* VIDIOC_SUBDEV_QUERYCAP ioctl.
*/
/**
* \fn V4L2SubdeviceCapability::isReadOnly()
* \brief Retrieve if a subdevice is registered as read-only
*
* A V4L2 subdevice is registered as read-only if V4L2_SUBDEV_CAP_RO_SUBDEV
* is listed as part of its capabilities.
*
* \return True if the subdevice is registered as read-only, false otherwise
*/
/**
* \fn V4L2SubdeviceCapability::hasStreams()
* \brief Retrieve if a subdevice supports the V4L2 streams API
* \return True if the subdevice supports the streams API, false otherwise
*/
/** /**
* \struct V4L2SubdeviceFormat * \struct V4L2SubdeviceFormat
* \brief The V4L2 sub-device image format and sizes * \brief The V4L2 sub-device image format and sizes
@ -284,7 +308,25 @@ V4L2Subdevice::~V4L2Subdevice()
*/ */
int V4L2Subdevice::open() int V4L2Subdevice::open()
{ {
return V4L2Device::open(O_RDWR); int ret = V4L2Device::open(O_RDWR);
if (ret)
return ret;
/*
* Try to query the subdev capabilities. The VIDIOC_SUBDEV_QUERYCAP API
* was introduced in kernel v5.8, ENOTTY errors must be ignored to
* support older kernels.
*/
caps_ = {};
ret = ioctl(VIDIOC_SUBDEV_QUERYCAP, &caps_);
if (ret < 0 && errno != ENOTTY) {
ret = -errno;
LOG(V4L2, Error)
<< "Unable to query capabilities: " << strerror(-ret);
return ret;
}
return 0;
} }
/** /**
@ -527,6 +569,12 @@ const std::string &V4L2Subdevice::model()
return model_; return model_;
} }
/**
* \fn V4L2Subdevice::caps()
* \brief Retrieve the subdevice V4L2 capabilities
* \return The subdevice V4L2 capabilities
*/
/** /**
* \brief Create a new video subdevice instance from \a entity in media device * \brief Create a new video subdevice instance from \a entity in media device
* \a media * \a media