libcamera: Add support for V4L2 requests
The V4L2 requests API provides support to atomically tie controls to a set of buffers. This is especially common for m2m devices. Such a request is represented by an fd that is allocated via MEDIA_IOC_REQUEST_ALLOC and then passed to the various V4L2 functions. Implement a V4L2Request class to wrap such an fd and add the corresponding utility functions. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
@@ -162,6 +162,7 @@ void V4L2Device::close()
|
||||
/**
|
||||
* \brief Read controls from the device
|
||||
* \param[in] ids The list of controls to read, specified by their ID
|
||||
* \param[in] request An optional request
|
||||
*
|
||||
* This function reads the value of all controls contained in \a ids, and
|
||||
* returns their values as a ControlList.
|
||||
@@ -171,10 +172,12 @@ void V4L2Device::close()
|
||||
* during validation of the requested controls, no control is read and this
|
||||
* function returns an empty control list.
|
||||
*
|
||||
* If \a request is specified the controls tied to that request are read.
|
||||
*
|
||||
* \return The control values in a ControlList on success, or an empty list on
|
||||
* error
|
||||
*/
|
||||
ControlList V4L2Device::getControls(Span<const uint32_t> ids)
|
||||
ControlList V4L2Device::getControls(Span<const uint32_t> ids, const V4L2Request *request)
|
||||
{
|
||||
if (ids.empty())
|
||||
return {};
|
||||
@@ -242,10 +245,16 @@ ControlList V4L2Device::getControls(Span<const uint32_t> ids)
|
||||
}
|
||||
|
||||
struct v4l2_ext_controls v4l2ExtCtrls = {};
|
||||
v4l2ExtCtrls.which = V4L2_CTRL_WHICH_CUR_VAL;
|
||||
v4l2ExtCtrls.controls = v4l2Ctrls.data();
|
||||
v4l2ExtCtrls.count = v4l2Ctrls.size();
|
||||
|
||||
if (request) {
|
||||
v4l2ExtCtrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
|
||||
v4l2ExtCtrls.request_fd = request->fd();
|
||||
} else {
|
||||
v4l2ExtCtrls.which = V4L2_CTRL_WHICH_CUR_VAL;
|
||||
}
|
||||
|
||||
int ret = ioctl(VIDIOC_G_EXT_CTRLS, &v4l2ExtCtrls);
|
||||
if (ret) {
|
||||
unsigned int errorIdx = v4l2ExtCtrls.error_idx;
|
||||
@@ -273,6 +282,7 @@ ControlList V4L2Device::getControls(Span<const uint32_t> ids)
|
||||
/**
|
||||
* \brief Write controls to the device
|
||||
* \param[in] ctrls The list of controls to write
|
||||
* \param[in] request An optional request
|
||||
*
|
||||
* This function writes the value of all controls contained in \a ctrls, and
|
||||
* stores the values actually applied to the device in the corresponding
|
||||
@@ -288,11 +298,16 @@ ControlList V4L2Device::getControls(Span<const uint32_t> ids)
|
||||
* are written and their values are updated in \a ctrls, while all other
|
||||
* controls are not written and their values are not changed.
|
||||
*
|
||||
* If \a request is set, the controls will be applied to that request. If the
|
||||
* device doesn't support requests, -EACCESS will be returned. If \a request is
|
||||
* invalid, -EINVAL will be returned.
|
||||
*
|
||||
* \return 0 on success or an error code otherwise
|
||||
* \retval -EINVAL One of the control is not supported or not accessible
|
||||
* \retval -EINVAL One of the controls is not supported or not accessible
|
||||
* \retval -EACCESS The device does not support requests
|
||||
* \retval i The index of the control that failed
|
||||
*/
|
||||
int V4L2Device::setControls(ControlList *ctrls)
|
||||
int V4L2Device::setControls(ControlList *ctrls, const V4L2Request *request)
|
||||
{
|
||||
if (ctrls->empty())
|
||||
return 0;
|
||||
@@ -377,10 +392,16 @@ int V4L2Device::setControls(ControlList *ctrls)
|
||||
}
|
||||
|
||||
struct v4l2_ext_controls v4l2ExtCtrls = {};
|
||||
v4l2ExtCtrls.which = V4L2_CTRL_WHICH_CUR_VAL;
|
||||
v4l2ExtCtrls.controls = v4l2Ctrls.data();
|
||||
v4l2ExtCtrls.count = v4l2Ctrls.size();
|
||||
|
||||
if (request) {
|
||||
v4l2ExtCtrls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
|
||||
v4l2ExtCtrls.request_fd = request->fd();
|
||||
} else {
|
||||
v4l2ExtCtrls.which = V4L2_CTRL_WHICH_CUR_VAL;
|
||||
}
|
||||
|
||||
int ret = ioctl(VIDIOC_S_EXT_CTRLS, &v4l2ExtCtrls);
|
||||
if (ret) {
|
||||
unsigned int errorIdx = v4l2ExtCtrls.error_idx;
|
||||
|
||||
Reference in New Issue
Block a user