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:
parent
5791fdc1cb
commit
f1b449476c
2 changed files with 42 additions and 15 deletions
|
@ -186,6 +186,7 @@ public:
|
||||||
const V4L2Capability &caps() const { return caps_; }
|
const V4L2Capability &caps() const { return caps_; }
|
||||||
|
|
||||||
int getFormat(V4L2DeviceFormat *format);
|
int getFormat(V4L2DeviceFormat *format);
|
||||||
|
int tryFormat(V4L2DeviceFormat *format);
|
||||||
int setFormat(V4L2DeviceFormat *format);
|
int setFormat(V4L2DeviceFormat *format);
|
||||||
std::map<V4L2PixelFormat, std::vector<SizeRange>> formats(uint32_t code = 0);
|
std::map<V4L2PixelFormat, std::vector<SizeRange>> formats(uint32_t code = 0);
|
||||||
|
|
||||||
|
@ -217,13 +218,13 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int getFormatMeta(V4L2DeviceFormat *format);
|
int getFormatMeta(V4L2DeviceFormat *format);
|
||||||
int setFormatMeta(V4L2DeviceFormat *format);
|
int trySetFormatMeta(V4L2DeviceFormat *format, bool set);
|
||||||
|
|
||||||
int getFormatMultiplane(V4L2DeviceFormat *format);
|
int getFormatMultiplane(V4L2DeviceFormat *format);
|
||||||
int setFormatMultiplane(V4L2DeviceFormat *format);
|
int trySetFormatMultiplane(V4L2DeviceFormat *format, bool set);
|
||||||
|
|
||||||
int getFormatSingleplane(V4L2DeviceFormat *format);
|
int getFormatSingleplane(V4L2DeviceFormat *format);
|
||||||
int setFormatSingleplane(V4L2DeviceFormat *format);
|
int trySetFormatSingleplane(V4L2DeviceFormat *format, bool set);
|
||||||
|
|
||||||
std::vector<V4L2PixelFormat> enumPixelformats(uint32_t code);
|
std::vector<V4L2PixelFormat> enumPixelformats(uint32_t code);
|
||||||
std::vector<SizeRange> enumSizes(V4L2PixelFormat pixelFormat);
|
std::vector<SizeRange> enumSizes(V4L2PixelFormat pixelFormat);
|
||||||
|
|
|
@ -723,6 +723,26 @@ int V4L2VideoDevice::getFormat(V4L2DeviceFormat *format)
|
||||||
return getFormatSingleplane(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
|
* \brief Configure an image format on the V4L2 video device
|
||||||
* \param[inout] format The image format to apply to the 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)
|
int V4L2VideoDevice::setFormat(V4L2DeviceFormat *format)
|
||||||
{
|
{
|
||||||
if (caps_.isMeta())
|
if (caps_.isMeta())
|
||||||
return setFormatMeta(format);
|
return trySetFormatMeta(format, true);
|
||||||
else if (caps_.isMultiplanar())
|
else if (caps_.isMultiplanar())
|
||||||
return setFormatMultiplane(format);
|
return trySetFormatMultiplane(format, true);
|
||||||
else
|
else
|
||||||
return setFormatSingleplane(format);
|
return trySetFormatSingleplane(format, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format)
|
int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format)
|
||||||
|
@ -765,7 +785,7 @@ int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int V4L2VideoDevice::setFormatMeta(V4L2DeviceFormat *format)
|
int V4L2VideoDevice::trySetFormatMeta(V4L2DeviceFormat *format, bool set)
|
||||||
{
|
{
|
||||||
struct v4l2_format v4l2Format = {};
|
struct v4l2_format v4l2Format = {};
|
||||||
struct v4l2_meta_format *pix = &v4l2Format.fmt.meta;
|
struct v4l2_meta_format *pix = &v4l2Format.fmt.meta;
|
||||||
|
@ -774,9 +794,11 @@ int V4L2VideoDevice::setFormatMeta(V4L2DeviceFormat *format)
|
||||||
v4l2Format.type = bufferType_;
|
v4l2Format.type = bufferType_;
|
||||||
pix->dataformat = format->fourcc;
|
pix->dataformat = format->fourcc;
|
||||||
pix->buffersize = format->planes[0].size;
|
pix->buffersize = format->planes[0].size;
|
||||||
ret = ioctl(VIDIOC_S_FMT, &v4l2Format);
|
ret = ioctl(set ? VIDIOC_S_FMT : VIDIOC_TRY_FMT, &v4l2Format);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret);
|
LOG(V4L2, Error)
|
||||||
|
<< "Unable to " << (set ? "set" : "try")
|
||||||
|
<< " format: " << strerror(-ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,7 +842,7 @@ int V4L2VideoDevice::getFormatMultiplane(V4L2DeviceFormat *format)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int V4L2VideoDevice::setFormatMultiplane(V4L2DeviceFormat *format)
|
int V4L2VideoDevice::trySetFormatMultiplane(V4L2DeviceFormat *format, bool set)
|
||||||
{
|
{
|
||||||
struct v4l2_format v4l2Format = {};
|
struct v4l2_format v4l2Format = {};
|
||||||
struct v4l2_pix_format_mplane *pix = &v4l2Format.fmt.pix_mp;
|
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;
|
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) {
|
if (ret) {
|
||||||
LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret);
|
LOG(V4L2, Error)
|
||||||
|
<< "Unable to " << (set ? "set" : "try")
|
||||||
|
<< " format: " << strerror(-ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -883,7 +907,7 @@ int V4L2VideoDevice::getFormatSingleplane(V4L2DeviceFormat *format)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)
|
int V4L2VideoDevice::trySetFormatSingleplane(V4L2DeviceFormat *format, bool set)
|
||||||
{
|
{
|
||||||
struct v4l2_format v4l2Format = {};
|
struct v4l2_format v4l2Format = {};
|
||||||
struct v4l2_pix_format *pix = &v4l2Format.fmt.pix;
|
struct v4l2_pix_format *pix = &v4l2Format.fmt.pix;
|
||||||
|
@ -895,9 +919,11 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)
|
||||||
pix->pixelformat = format->fourcc;
|
pix->pixelformat = format->fourcc;
|
||||||
pix->bytesperline = format->planes[0].bpl;
|
pix->bytesperline = format->planes[0].bpl;
|
||||||
pix->field = V4L2_FIELD_NONE;
|
pix->field = V4L2_FIELD_NONE;
|
||||||
ret = ioctl(VIDIOC_S_FMT, &v4l2Format);
|
ret = ioctl(set ? VIDIOC_S_FMT : VIDIOC_TRY_FMT, &v4l2Format);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret);
|
LOG(V4L2, Error)
|
||||||
|
<< "Unable to " << (set ? "set" : "try")
|
||||||
|
<< " format: " << strerror(-ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue