libcamera: v4l2_device: Add methods to get/set format
Add methods to set and get the image format programmed on a V4L2Device for both the single and multi planar use case. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
parent
267b91373b
commit
ba8da0f2fc
2 changed files with 138 additions and 0 deletions
|
@ -86,10 +86,20 @@ public:
|
|||
const char *deviceName() const { return caps_.card(); }
|
||||
const char *busName() const { return caps_.bus_info(); }
|
||||
|
||||
int format(V4L2DeviceFormat *fmt);
|
||||
int setFormat(V4L2DeviceFormat *fmt);
|
||||
|
||||
private:
|
||||
int getFormatSingleplane(V4L2DeviceFormat *fmt);
|
||||
int setFormatSingleplane(V4L2DeviceFormat *fmt);
|
||||
|
||||
int getFormatMultiplane(V4L2DeviceFormat *fmt);
|
||||
int setFormatMultiplane(V4L2DeviceFormat *fmt);
|
||||
|
||||
std::string deviceNode_;
|
||||
int fd_;
|
||||
V4L2Capability caps_;
|
||||
enum v4l2_buf_type bufferType_;
|
||||
};
|
||||
|
||||
} /* namespace libcamera */
|
||||
|
|
|
@ -227,6 +227,15 @@ int V4L2Device::open()
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (caps_.isCapture())
|
||||
bufferType_ = caps_.isMultiplanar()
|
||||
? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
|
||||
: V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
else
|
||||
bufferType_ = caps_.isMultiplanar()
|
||||
? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
|
||||
: V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -269,4 +278,123 @@ void V4L2Device::close()
|
|||
* \return The string containing the device location
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Retrieve the image format set on the V4L2 device
|
||||
* \return 0 for success, a negative error code otherwise
|
||||
*/
|
||||
int V4L2Device::format(V4L2DeviceFormat *fmt)
|
||||
{
|
||||
return caps_.isMultiplanar() ? getFormatMultiplane(fmt) :
|
||||
getFormatSingleplane(fmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure an image format on the V4L2 device
|
||||
* \return 0 for success, a negative error code otherwise
|
||||
*/
|
||||
int V4L2Device::setFormat(V4L2DeviceFormat *fmt)
|
||||
{
|
||||
return caps_.isMultiplanar() ? setFormatMultiplane(fmt) :
|
||||
setFormatSingleplane(fmt);
|
||||
}
|
||||
|
||||
int V4L2Device::getFormatSingleplane(V4L2DeviceFormat *fmt)
|
||||
{
|
||||
struct v4l2_format v4l2Fmt;
|
||||
struct v4l2_pix_format *pix = &v4l2Fmt.fmt.pix;
|
||||
int ret;
|
||||
|
||||
v4l2Fmt.type = bufferType_;
|
||||
ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Fmt);
|
||||
if (ret) {
|
||||
ret = -errno;
|
||||
LOG(Error) << "Unable to get format: " << strerror(-ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fmt->width = pix->width;
|
||||
fmt->height = pix->height;
|
||||
fmt->fourcc = pix->pixelformat;
|
||||
fmt->planes = 1;
|
||||
fmt->planesFmt[0].bpl = pix->bytesperline;
|
||||
fmt->planesFmt[0].size = pix->sizeimage;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int V4L2Device::setFormatSingleplane(V4L2DeviceFormat *fmt)
|
||||
{
|
||||
struct v4l2_format v4l2Fmt;
|
||||
struct v4l2_pix_format *pix = &v4l2Fmt.fmt.pix;
|
||||
int ret;
|
||||
|
||||
v4l2Fmt.type = bufferType_;
|
||||
pix->width = fmt->width;
|
||||
pix->height = fmt->height;
|
||||
pix->pixelformat = fmt->fourcc;
|
||||
|
||||
ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Fmt);
|
||||
if (ret) {
|
||||
ret = -errno;
|
||||
LOG(Error) << "Unable to set format: " << strerror(-ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int V4L2Device::getFormatMultiplane(V4L2DeviceFormat *fmt)
|
||||
{
|
||||
struct v4l2_format v4l2Fmt;
|
||||
struct v4l2_pix_format_mplane *pix = &v4l2Fmt.fmt.pix_mp;
|
||||
int ret;
|
||||
|
||||
v4l2Fmt.type = bufferType_;
|
||||
ret = ioctl(fd_, VIDIOC_G_FMT, &v4l2Fmt);
|
||||
if (ret) {
|
||||
ret = -errno;
|
||||
LOG(Error) << "Unable to get format: " << strerror(-ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fmt->width = pix->width;
|
||||
fmt->height = pix->height;
|
||||
fmt->fourcc = pix->pixelformat;
|
||||
fmt->planes = pix->num_planes;
|
||||
|
||||
for (unsigned int i = 0; i < fmt->planes; ++i) {
|
||||
fmt->planesFmt[i].bpl = pix->plane_fmt[i].bytesperline;
|
||||
fmt->planesFmt[i].size = pix->plane_fmt[i].sizeimage;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int V4L2Device::setFormatMultiplane(V4L2DeviceFormat *fmt)
|
||||
{
|
||||
struct v4l2_format v4l2Fmt;
|
||||
struct v4l2_pix_format_mplane *pix = &v4l2Fmt.fmt.pix_mp;
|
||||
int ret;
|
||||
|
||||
v4l2Fmt.type = bufferType_;
|
||||
pix->width = fmt->width;
|
||||
pix->height = fmt->height;
|
||||
pix->pixelformat = fmt->fourcc;
|
||||
pix->num_planes = fmt->planes;
|
||||
|
||||
for (unsigned int i = 0; i < pix->num_planes; ++i) {
|
||||
pix->plane_fmt[i].bytesperline = fmt->planesFmt[i].bpl;
|
||||
pix->plane_fmt[i].sizeimage = fmt->planesFmt[i].size;
|
||||
}
|
||||
|
||||
ret = ioctl(fd_, VIDIOC_S_FMT, &v4l2Fmt);
|
||||
if (ret) {
|
||||
ret = -errno;
|
||||
LOG(Error) << "Unable to set format: " << strerror(-ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} /* namespace libcamera */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue