libcamera: v4l2_device: Add META support in g/s_fmt
Add two operations to set and get format on devices implementing the V4L2 Metadata Interface, identified by the META_OUTPUT or META_CAPTURE capabilities. While at it, sort get/setFormat operations alphabetically and unify their style (eg. no empty line before ioctl). Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
81e004e0ff
commit
629e9301c5
2 changed files with 90 additions and 26 deletions
|
@ -150,12 +150,15 @@ protected:
|
||||||
std::string logPrefix() const;
|
std::string logPrefix() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int getFormatSingleplane(V4L2DeviceFormat *format);
|
int getFormatMeta(V4L2DeviceFormat *format);
|
||||||
int setFormatSingleplane(V4L2DeviceFormat *format);
|
int setFormatMeta(V4L2DeviceFormat *format);
|
||||||
|
|
||||||
int getFormatMultiplane(V4L2DeviceFormat *format);
|
int getFormatMultiplane(V4L2DeviceFormat *format);
|
||||||
int setFormatMultiplane(V4L2DeviceFormat *format);
|
int setFormatMultiplane(V4L2DeviceFormat *format);
|
||||||
|
|
||||||
|
int getFormatSingleplane(V4L2DeviceFormat *format);
|
||||||
|
int setFormatSingleplane(V4L2DeviceFormat *format);
|
||||||
|
|
||||||
int requestBuffers(unsigned int count);
|
int requestBuffers(unsigned int count);
|
||||||
int createPlane(Buffer *buffer, unsigned int plane,
|
int createPlane(Buffer *buffer, unsigned int plane,
|
||||||
unsigned int length);
|
unsigned int length);
|
||||||
|
|
|
@ -428,8 +428,12 @@ std::string V4L2Device::logPrefix() const
|
||||||
*/
|
*/
|
||||||
int V4L2Device::getFormat(V4L2DeviceFormat *format)
|
int V4L2Device::getFormat(V4L2DeviceFormat *format)
|
||||||
{
|
{
|
||||||
return caps_.isMultiplanar() ? getFormatMultiplane(format) :
|
if (caps_.isMeta())
|
||||||
getFormatSingleplane(format);
|
return getFormatMeta(format);
|
||||||
|
else if (caps_.isMultiplanar())
|
||||||
|
return getFormatMultiplane(format);
|
||||||
|
else
|
||||||
|
return getFormatSingleplane(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -443,14 +447,18 @@ int V4L2Device::getFormat(V4L2DeviceFormat *format)
|
||||||
*/
|
*/
|
||||||
int V4L2Device::setFormat(V4L2DeviceFormat *format)
|
int V4L2Device::setFormat(V4L2DeviceFormat *format)
|
||||||
{
|
{
|
||||||
return caps_.isMultiplanar() ? setFormatMultiplane(format) :
|
if (caps_.isMeta())
|
||||||
setFormatSingleplane(format);
|
return setFormatMeta(format);
|
||||||
|
else if (caps_.isMultiplanar())
|
||||||
|
return setFormatMultiplane(format);
|
||||||
|
else
|
||||||
|
return setFormatSingleplane(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
int V4L2Device::getFormatSingleplane(V4L2DeviceFormat *format)
|
int V4L2Device::getFormatMeta(V4L2DeviceFormat *format)
|
||||||
{
|
{
|
||||||
struct v4l2_format v4l2Format = {};
|
struct v4l2_format v4l2Format = {};
|
||||||
struct v4l2_pix_format *pix = &v4l2Format.fmt.pix;
|
struct v4l2_meta_format *pix = &v4l2Format.fmt.meta;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
v4l2Format.type = bufferType_;
|
v4l2Format.type = bufferType_;
|
||||||
|
@ -461,29 +469,25 @@ int V4L2Device::getFormatSingleplane(V4L2DeviceFormat *format)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
format->size.width = pix->width;
|
format->size.width = 0;
|
||||||
format->size.height = pix->height;
|
format->size.height = 0;
|
||||||
format->fourcc = pix->pixelformat;
|
format->fourcc = pix->dataformat;
|
||||||
format->planesCount = 1;
|
format->planesCount = 1;
|
||||||
format->planes[0].bpl = pix->bytesperline;
|
format->planes[0].bpl = pix->buffersize;
|
||||||
format->planes[0].size = pix->sizeimage;
|
format->planes[0].size = pix->buffersize;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int V4L2Device::setFormatSingleplane(V4L2DeviceFormat *format)
|
int V4L2Device::setFormatMeta(V4L2DeviceFormat *format)
|
||||||
{
|
{
|
||||||
struct v4l2_format v4l2Format = {};
|
struct v4l2_format v4l2Format = {};
|
||||||
struct v4l2_pix_format *pix = &v4l2Format.fmt.pix;
|
struct v4l2_meta_format *pix = &v4l2Format.fmt.meta;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
v4l2Format.type = bufferType_;
|
v4l2Format.type = bufferType_;
|
||||||
pix->width = format->size.width;
|
pix->dataformat = format->fourcc;
|
||||||
pix->height = format->size.height;
|
pix->buffersize = format->planes[0].size;
|
||||||
pix->pixelformat = format->fourcc;
|
|
||||||
pix->bytesperline = format->planes[0].bpl;
|
|
||||||
pix->field = V4L2_FIELD_NONE;
|
|
||||||
|
|
||||||
ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Format);
|
ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Format);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
|
@ -495,12 +499,12 @@ int V4L2Device::setFormatSingleplane(V4L2DeviceFormat *format)
|
||||||
* Return to caller the format actually applied on the device,
|
* Return to caller the format actually applied on the device,
|
||||||
* which might differ from the requested one.
|
* which might differ from the requested one.
|
||||||
*/
|
*/
|
||||||
format->size.width = pix->width;
|
format->size.width = 0;
|
||||||
format->size.height = pix->height;
|
format->size.height = 0;
|
||||||
format->fourcc = pix->pixelformat;
|
format->fourcc = format->fourcc;
|
||||||
format->planesCount = 1;
|
format->planesCount = 1;
|
||||||
format->planes[0].bpl = pix->bytesperline;
|
format->planes[0].bpl = pix->buffersize;
|
||||||
format->planes[0].size = pix->sizeimage;
|
format->planes[0].size = pix->buffersize;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -573,6 +577,63 @@ int V4L2Device::setFormatMultiplane(V4L2DeviceFormat *format)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int V4L2Device::getFormatSingleplane(V4L2DeviceFormat *format)
|
||||||
|
{
|
||||||
|
struct v4l2_format v4l2Format = {};
|
||||||
|
struct v4l2_pix_format *pix = &v4l2Format.fmt.pix;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
v4l2Format.type = bufferType_;
|
||||||
|
ret = ioctl(fd_, VIDIOC_G_FMT, &v4l2Format);
|
||||||
|
if (ret) {
|
||||||
|
ret = -errno;
|
||||||
|
LOG(V4L2, Error) << "Unable to get format: " << strerror(-ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
format->size.width = pix->width;
|
||||||
|
format->size.height = pix->height;
|
||||||
|
format->fourcc = pix->pixelformat;
|
||||||
|
format->planesCount = 1;
|
||||||
|
format->planes[0].bpl = pix->bytesperline;
|
||||||
|
format->planes[0].size = pix->sizeimage;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int V4L2Device::setFormatSingleplane(V4L2DeviceFormat *format)
|
||||||
|
{
|
||||||
|
struct v4l2_format v4l2Format = {};
|
||||||
|
struct v4l2_pix_format *pix = &v4l2Format.fmt.pix;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
v4l2Format.type = bufferType_;
|
||||||
|
pix->width = format->size.width;
|
||||||
|
pix->height = format->size.height;
|
||||||
|
pix->pixelformat = format->fourcc;
|
||||||
|
pix->bytesperline = format->planes[0].bpl;
|
||||||
|
pix->field = V4L2_FIELD_NONE;
|
||||||
|
ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Format);
|
||||||
|
if (ret) {
|
||||||
|
ret = -errno;
|
||||||
|
LOG(V4L2, Error) << "Unable to set format: " << strerror(-ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return to caller the format actually applied on the device,
|
||||||
|
* which might differ from the requested one.
|
||||||
|
*/
|
||||||
|
format->size.width = pix->width;
|
||||||
|
format->size.height = pix->height;
|
||||||
|
format->fourcc = pix->pixelformat;
|
||||||
|
format->planesCount = 1;
|
||||||
|
format->planes[0].bpl = pix->bytesperline;
|
||||||
|
format->planes[0].size = pix->sizeimage;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int V4L2Device::requestBuffers(unsigned int count)
|
int V4L2Device::requestBuffers(unsigned int count)
|
||||||
{
|
{
|
||||||
struct v4l2_requestbuffers rb = {};
|
struct v4l2_requestbuffers rb = {};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue