libcamera: V4L2VideoDevice: Add tryFormat

Add tryFormat and its variations (meta, single-plane, multi-plane) to
V4L2VideoDevice.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
Paul Elder 2020-07-04 17:51:27 +09:00
parent 5791fdc1cb
commit f1b449476c
2 changed files with 42 additions and 15 deletions

View file

@ -723,6 +723,26 @@ int V4L2VideoDevice::getFormat(V4L2DeviceFormat *format)
return getFormatSingleplane(format);
}
/**
* \brief Try an image format on the V4L2 video device
* \param[inout] format The image format to test applicability to the video device
*
* Try the supplied \a format on the video device without applying it, returning
* the format that would be applied. This is equivalent to setFormat(), except
* that the device configuration is not changed.
*
* \return 0 on success or a negative error code otherwise
*/
int V4L2VideoDevice::tryFormat(V4L2DeviceFormat *format)
{
if (caps_.isMeta())
return trySetFormatMeta(format, false);
else if (caps_.isMultiplanar())
return trySetFormatMultiplane(format, false);
else
return trySetFormatSingleplane(format, false);
}
/**
* \brief Configure an image format on the V4L2 video device
* \param[inout] format The image format to apply to the video device
@ -735,11 +755,11 @@ int V4L2VideoDevice::getFormat(V4L2DeviceFormat *format)
int V4L2VideoDevice::setFormat(V4L2DeviceFormat *format)
{
if (caps_.isMeta())
return setFormatMeta(format);
return trySetFormatMeta(format, true);
else if (caps_.isMultiplanar())
return setFormatMultiplane(format);
return trySetFormatMultiplane(format, true);
else
return setFormatSingleplane(format);
return trySetFormatSingleplane(format, true);
}
int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format)
@ -765,7 +785,7 @@ int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format)
return 0;
}
int V4L2VideoDevice::setFormatMeta(V4L2DeviceFormat *format)
int V4L2VideoDevice::trySetFormatMeta(V4L2DeviceFormat *format, bool set)
{
struct v4l2_format v4l2Format = {};
struct v4l2_meta_format *pix = &v4l2Format.fmt.meta;
@ -774,9 +794,11 @@ int V4L2VideoDevice::setFormatMeta(V4L2DeviceFormat *format)
v4l2Format.type = bufferType_;
pix->dataformat = format->fourcc;
pix->buffersize = format->planes[0].size;
ret = ioctl(VIDIOC_S_FMT, &v4l2Format);
ret = ioctl(set ? VIDIOC_S_FMT : VIDIOC_TRY_FMT, &v4l2Format);
if (ret) {
LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret);
LOG(V4L2, Error)
<< "Unable to " << (set ? "set" : "try")
<< " format: " << strerror(-ret);
return ret;
}
@ -820,7 +842,7 @@ int V4L2VideoDevice::getFormatMultiplane(V4L2DeviceFormat *format)
return 0;
}
int V4L2VideoDevice::setFormatMultiplane(V4L2DeviceFormat *format)
int V4L2VideoDevice::trySetFormatMultiplane(V4L2DeviceFormat *format, bool set)
{
struct v4l2_format v4l2Format = {};
struct v4l2_pix_format_mplane *pix = &v4l2Format.fmt.pix_mp;
@ -838,9 +860,11 @@ int V4L2VideoDevice::setFormatMultiplane(V4L2DeviceFormat *format)
pix->plane_fmt[i].sizeimage = format->planes[i].size;
}
ret = ioctl(VIDIOC_S_FMT, &v4l2Format);
ret = ioctl(set ? VIDIOC_S_FMT : VIDIOC_TRY_FMT, &v4l2Format);
if (ret) {
LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret);
LOG(V4L2, Error)
<< "Unable to " << (set ? "set" : "try")
<< " format: " << strerror(-ret);
return ret;
}
@ -883,7 +907,7 @@ int V4L2VideoDevice::getFormatSingleplane(V4L2DeviceFormat *format)
return 0;
}
int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)
int V4L2VideoDevice::trySetFormatSingleplane(V4L2DeviceFormat *format, bool set)
{
struct v4l2_format v4l2Format = {};
struct v4l2_pix_format *pix = &v4l2Format.fmt.pix;
@ -895,9 +919,11 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)
pix->pixelformat = format->fourcc;
pix->bytesperline = format->planes[0].bpl;
pix->field = V4L2_FIELD_NONE;
ret = ioctl(VIDIOC_S_FMT, &v4l2Format);
ret = ioctl(set ? VIDIOC_S_FMT : VIDIOC_TRY_FMT, &v4l2Format);
if (ret) {
LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret);
LOG(V4L2, Error)
<< "Unable to " << (set ? "set" : "try")
<< " format: " << strerror(-ret);
return ret;
}