libcamera: v4l2_videodevice: Make V4L2PixelFormat constructor explicit

To achieve the goal of preventing unwanted conversion between a DRM and
a V4L2 FourCC, make the V4L2PixelFormat constructor that takes an
integer value explicit. All users of V4L2 pixel formats flagged by the
compiler are fixed.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
Laurent Pinchart 2020-03-17 01:33:58 +02:00
parent 6015d9702e
commit 6c34a2d386
6 changed files with 35 additions and 31 deletions

View file

@ -157,7 +157,7 @@ public:
{ {
} }
V4L2PixelFormat(uint32_t fourcc) explicit V4L2PixelFormat(uint32_t fourcc)
: fourcc_(fourcc) : fourcc_(fourcc)
{ {
} }

View file

@ -121,7 +121,7 @@ public:
int start(); int start();
int stop(); int stop();
static int mediaBusToFormat(unsigned int code); static V4L2PixelFormat mediaBusToFormat(unsigned int code);
V4L2VideoDevice *output_; V4L2VideoDevice *output_;
V4L2Subdevice *csi2_; V4L2Subdevice *csi2_;
@ -1447,19 +1447,19 @@ int CIO2Device::stop()
return output_->streamOff(); return output_->streamOff();
} }
int CIO2Device::mediaBusToFormat(unsigned int code) V4L2PixelFormat CIO2Device::mediaBusToFormat(unsigned int code)
{ {
switch (code) { switch (code) {
case MEDIA_BUS_FMT_SBGGR10_1X10: case MEDIA_BUS_FMT_SBGGR10_1X10:
return V4L2_PIX_FMT_IPU3_SBGGR10; return V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10);
case MEDIA_BUS_FMT_SGBRG10_1X10: case MEDIA_BUS_FMT_SGBRG10_1X10:
return V4L2_PIX_FMT_IPU3_SGBRG10; return V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10);
case MEDIA_BUS_FMT_SGRBG10_1X10: case MEDIA_BUS_FMT_SGRBG10_1X10:
return V4L2_PIX_FMT_IPU3_SGRBG10; return V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10);
case MEDIA_BUS_FMT_SRGGB10_1X10: case MEDIA_BUS_FMT_SRGGB10_1X10:
return V4L2_PIX_FMT_IPU3_SRGGB10; return V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10);
default: default:
return -EINVAL; return {};
} }
} }

View file

@ -642,13 +642,13 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
} }
V4L2DeviceFormat paramFormat = {}; V4L2DeviceFormat paramFormat = {};
paramFormat.fourcc = V4L2_META_FMT_RK_ISP1_PARAMS; paramFormat.fourcc = V4L2PixelFormat(V4L2_META_FMT_RK_ISP1_PARAMS);
ret = param_->setFormat(&paramFormat); ret = param_->setFormat(&paramFormat);
if (ret) if (ret)
return ret; return ret;
V4L2DeviceFormat statFormat = {}; V4L2DeviceFormat statFormat = {};
statFormat.fourcc = V4L2_META_FMT_RK_ISP1_STAT_3A; statFormat.fourcc = V4L2PixelFormat(V4L2_META_FMT_RK_ISP1_STAT_3A);
ret = stat_->setFormat(&statFormat); ret = stat_->setFormat(&statFormat);
if (ret) if (ret)
return ret; return ret;

View file

@ -244,7 +244,7 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config)
* Format has to be set on the raw capture video node, otherwise the * Format has to be set on the raw capture video node, otherwise the
* vimc driver will fail pipeline validation. * vimc driver will fail pipeline validation.
*/ */
format.fourcc = V4L2_PIX_FMT_SGRBG8; format.fourcc = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8);
format.size = { cfg.size.width / 3, cfg.size.height / 3 }; format.size = { cfg.size.width / 3, cfg.size.height / 3 };
ret = data->raw_->setFormat(&format); ret = data->raw_->setFormat(&format);

View file

@ -287,6 +287,10 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const
* V4L2 pixel formats. Its purpose is to prevent unintentional confusion of * V4L2 pixel formats. Its purpose is to prevent unintentional confusion of
* V4L2 and DRM FourCCs in code by catching implicit conversion attempts at * V4L2 and DRM FourCCs in code by catching implicit conversion attempts at
* compile time. * compile time.
*
* To achieve this goal, construction of a V4L2PixelFormat from an integer value
* is explicit. To retrieve the integer value of a V4L2PixelFormat, both the
* explicit value() and implicit uint32_t conversion operators may be used.
*/ */
/** /**
@ -795,7 +799,7 @@ int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format)
format->size.width = 0; format->size.width = 0;
format->size.height = 0; format->size.height = 0;
format->fourcc = pix->dataformat; format->fourcc = V4L2PixelFormat(pix->dataformat);
format->planesCount = 1; format->planesCount = 1;
format->planes[0].bpl = pix->buffersize; format->planes[0].bpl = pix->buffersize;
format->planes[0].size = pix->buffersize; format->planes[0].size = pix->buffersize;
@ -847,7 +851,7 @@ int V4L2VideoDevice::getFormatMultiplane(V4L2DeviceFormat *format)
format->size.width = pix->width; format->size.width = pix->width;
format->size.height = pix->height; format->size.height = pix->height;
format->fourcc = pix->pixelformat; format->fourcc = V4L2PixelFormat(pix->pixelformat);
format->planesCount = pix->num_planes; format->planesCount = pix->num_planes;
for (unsigned int i = 0; i < format->planesCount; ++i) { for (unsigned int i = 0; i < format->planesCount; ++i) {
@ -888,7 +892,7 @@ int V4L2VideoDevice::setFormatMultiplane(V4L2DeviceFormat *format)
*/ */
format->size.width = pix->width; format->size.width = pix->width;
format->size.height = pix->height; format->size.height = pix->height;
format->fourcc = pix->pixelformat; format->fourcc = V4L2PixelFormat(pix->pixelformat);
format->planesCount = pix->num_planes; format->planesCount = pix->num_planes;
for (unsigned int i = 0; i < format->planesCount; ++i) { for (unsigned int i = 0; i < format->planesCount; ++i) {
format->planes[i].bpl = pix->plane_fmt[i].bytesperline; format->planes[i].bpl = pix->plane_fmt[i].bytesperline;
@ -913,7 +917,7 @@ int V4L2VideoDevice::getFormatSingleplane(V4L2DeviceFormat *format)
format->size.width = pix->width; format->size.width = pix->width;
format->size.height = pix->height; format->size.height = pix->height;
format->fourcc = pix->pixelformat; format->fourcc = V4L2PixelFormat(pix->pixelformat);
format->planesCount = 1; format->planesCount = 1;
format->planes[0].bpl = pix->bytesperline; format->planes[0].bpl = pix->bytesperline;
format->planes[0].size = pix->sizeimage; format->planes[0].size = pix->sizeimage;
@ -945,7 +949,7 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)
*/ */
format->size.width = pix->width; format->size.width = pix->width;
format->size.height = pix->height; format->size.height = pix->height;
format->fourcc = pix->pixelformat; format->fourcc = V4L2PixelFormat(pix->pixelformat);
format->planesCount = 1; format->planesCount = 1;
format->planes[0].bpl = pix->bytesperline; format->planes[0].bpl = pix->bytesperline;
format->planes[0].size = pix->sizeimage; format->planes[0].size = pix->sizeimage;
@ -996,7 +1000,7 @@ std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats()
if (ret) if (ret)
break; break;
formats.push_back(pixelformatEnum.pixelformat); formats.push_back(V4L2PixelFormat(pixelformatEnum.pixelformat));
} }
if (ret && ret != -EINVAL) { if (ret && ret != -EINVAL) {
@ -1713,21 +1717,21 @@ V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelForma
switch (pixelFormat) { switch (pixelFormat) {
/* RGB formats. */ /* RGB formats. */
case DRM_FORMAT_BGR888: case DRM_FORMAT_BGR888:
return V4L2_PIX_FMT_RGB24; return V4L2PixelFormat(V4L2_PIX_FMT_RGB24);
case DRM_FORMAT_RGB888: case DRM_FORMAT_RGB888:
return V4L2_PIX_FMT_BGR24; return V4L2PixelFormat(V4L2_PIX_FMT_BGR24);
case DRM_FORMAT_BGRA8888: case DRM_FORMAT_BGRA8888:
return V4L2_PIX_FMT_ARGB32; return V4L2PixelFormat(V4L2_PIX_FMT_ARGB32);
/* YUV packed formats. */ /* YUV packed formats. */
case DRM_FORMAT_YUYV: case DRM_FORMAT_YUYV:
return V4L2_PIX_FMT_YUYV; return V4L2PixelFormat(V4L2_PIX_FMT_YUYV);
case DRM_FORMAT_YVYU: case DRM_FORMAT_YVYU:
return V4L2_PIX_FMT_YVYU; return V4L2PixelFormat(V4L2_PIX_FMT_YVYU);
case DRM_FORMAT_UYVY: case DRM_FORMAT_UYVY:
return V4L2_PIX_FMT_UYVY; return V4L2PixelFormat(V4L2_PIX_FMT_UYVY);
case DRM_FORMAT_VYUY: case DRM_FORMAT_VYUY:
return V4L2_PIX_FMT_VYUY; return V4L2PixelFormat(V4L2_PIX_FMT_VYUY);
/* /*
* YUY planar formats. * YUY planar formats.
@ -1736,17 +1740,17 @@ V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelForma
* also take into account the formats supported by the device. * also take into account the formats supported by the device.
*/ */
case DRM_FORMAT_NV16: case DRM_FORMAT_NV16:
return V4L2_PIX_FMT_NV16; return V4L2PixelFormat(V4L2_PIX_FMT_NV16);
case DRM_FORMAT_NV61: case DRM_FORMAT_NV61:
return V4L2_PIX_FMT_NV61; return V4L2PixelFormat(V4L2_PIX_FMT_NV61);
case DRM_FORMAT_NV12: case DRM_FORMAT_NV12:
return V4L2_PIX_FMT_NV12; return V4L2PixelFormat(V4L2_PIX_FMT_NV12);
case DRM_FORMAT_NV21: case DRM_FORMAT_NV21:
return V4L2_PIX_FMT_NV21; return V4L2PixelFormat(V4L2_PIX_FMT_NV21);
/* Compressed formats. */ /* Compressed formats. */
case DRM_FORMAT_MJPEG: case DRM_FORMAT_MJPEG:
return V4L2_PIX_FMT_MJPEG; return V4L2PixelFormat(V4L2_PIX_FMT_MJPEG);
} }
/* /*
@ -1755,7 +1759,7 @@ V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelForma
*/ */
libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(), LogError).stream() libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(), LogError).stream()
<< "Unsupported V4L2 pixel format " << pixelFormat.toString(); << "Unsupported V4L2 pixel format " << pixelFormat.toString();
return 0; return {};
} }
/** /**

View file

@ -69,7 +69,7 @@ int V4L2VideoDeviceTest::init()
if (debayer_->open()) if (debayer_->open())
return TestFail; return TestFail;
format.fourcc = V4L2_PIX_FMT_SBGGR8; format.fourcc = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8);
V4L2SubdeviceFormat subformat = {}; V4L2SubdeviceFormat subformat = {};
subformat.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8; subformat.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8;