From 2bc657f47b9fd5690697b1adc805e0f923f3ef8a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 30 Apr 2020 03:16:53 +0300 Subject: libcamera: v4l2_pixelformat: Move DRM/V4L2 format conversion Move the DRM/V4L2 format conversion code from V4L2VideoDevice to V4L2PixelFormat. This is a more natural home for the code. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/v4l2_pixelformat.cpp | 134 +++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) (limited to 'src/libcamera/v4l2_pixelformat.cpp') diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp index 57d65c38..876f5de3 100644 --- a/src/libcamera/v4l2_pixelformat.cpp +++ b/src/libcamera/v4l2_pixelformat.cpp @@ -103,4 +103,138 @@ std::string V4L2PixelFormat::toString() const return ss; } +/** + * \brief Convert the V4L2 pixel format to the corresponding PixelFormat + * \return The PixelFormat corresponding to the V4L2 pixel format + */ +PixelFormat V4L2PixelFormat::toPixelFormat() const +{ + switch (fourcc_) { + /* RGB formats. */ + case V4L2_PIX_FMT_RGB24: + return PixelFormat(DRM_FORMAT_BGR888); + case V4L2_PIX_FMT_BGR24: + return PixelFormat(DRM_FORMAT_RGB888); + case V4L2_PIX_FMT_RGBA32: + return PixelFormat(DRM_FORMAT_ABGR8888); + case V4L2_PIX_FMT_ABGR32: + return PixelFormat(DRM_FORMAT_ARGB8888); + case V4L2_PIX_FMT_ARGB32: + return PixelFormat(DRM_FORMAT_BGRA8888); + case V4L2_PIX_FMT_BGRA32: + return PixelFormat(DRM_FORMAT_RGBA8888); + + /* YUV packed formats. */ + case V4L2_PIX_FMT_YUYV: + return PixelFormat(DRM_FORMAT_YUYV); + case V4L2_PIX_FMT_YVYU: + return PixelFormat(DRM_FORMAT_YVYU); + case V4L2_PIX_FMT_UYVY: + return PixelFormat(DRM_FORMAT_UYVY); + case V4L2_PIX_FMT_VYUY: + return PixelFormat(DRM_FORMAT_VYUY); + + /* YUY planar formats. */ + case V4L2_PIX_FMT_NV16: + case V4L2_PIX_FMT_NV16M: + return PixelFormat(DRM_FORMAT_NV16); + case V4L2_PIX_FMT_NV61: + case V4L2_PIX_FMT_NV61M: + return PixelFormat(DRM_FORMAT_NV61); + case V4L2_PIX_FMT_NV12: + case V4L2_PIX_FMT_NV12M: + return PixelFormat(DRM_FORMAT_NV12); + case V4L2_PIX_FMT_NV21: + case V4L2_PIX_FMT_NV21M: + return PixelFormat(DRM_FORMAT_NV21); + + /* Greyscale formats. */ + case V4L2_PIX_FMT_GREY: + return PixelFormat(DRM_FORMAT_R8); + + /* Compressed formats. */ + case V4L2_PIX_FMT_MJPEG: + return PixelFormat(DRM_FORMAT_MJPEG); + + /* V4L2 formats not yet supported by DRM. */ + default: + LOG(V4L2, Warning) + << "Unsupported V4L2 pixel format " + << toString(); + return PixelFormat(); + } +} + +/** + * \brief Convert \a pixelFormat to its corresponding V4L2PixelFormat + * \param[in] pixelFormat The PixelFormat to convert + * \param[in] multiplanar V4L2 Multiplanar API support flag + * + * Multiple V4L2 formats may exist for one PixelFormat when the format uses + * multiple planes, as V4L2 defines separate 4CCs for contiguous and separate + * planes formats. Set the \a multiplanar parameter to false to select a format + * with contiguous planes, or to true to select a format with non-contiguous + * planes. + * + * \return The V4L2PixelFormat corresponding to \a pixelFormat + */ +V4L2PixelFormat V4L2PixelFormat::fromPixelFormat(const PixelFormat &pixelFormat, + bool multiplanar) +{ + switch (pixelFormat) { + /* RGB formats. */ + case DRM_FORMAT_BGR888: + return V4L2PixelFormat(V4L2_PIX_FMT_RGB24); + case DRM_FORMAT_RGB888: + return V4L2PixelFormat(V4L2_PIX_FMT_BGR24); + case DRM_FORMAT_ABGR8888: + return V4L2PixelFormat(V4L2_PIX_FMT_RGBA32); + case DRM_FORMAT_ARGB8888: + return V4L2PixelFormat(V4L2_PIX_FMT_ABGR32); + case DRM_FORMAT_BGRA8888: + return V4L2PixelFormat(V4L2_PIX_FMT_ARGB32); + case DRM_FORMAT_RGBA8888: + return V4L2PixelFormat(V4L2_PIX_FMT_BGRA32); + + /* YUV packed formats. */ + case DRM_FORMAT_YUYV: + return V4L2PixelFormat(V4L2_PIX_FMT_YUYV); + case DRM_FORMAT_YVYU: + return V4L2PixelFormat(V4L2_PIX_FMT_YVYU); + case DRM_FORMAT_UYVY: + return V4L2PixelFormat(V4L2_PIX_FMT_UYVY); + case DRM_FORMAT_VYUY: + return V4L2PixelFormat(V4L2_PIX_FMT_VYUY); + + /* + * YUY planar formats. + * \todo Add support for non-contiguous memory planes + * \todo Select the format variant not only based on \a multiplanar but + * also take into account the formats supported by the device. + */ + case DRM_FORMAT_NV16: + return V4L2PixelFormat(V4L2_PIX_FMT_NV16); + case DRM_FORMAT_NV61: + return V4L2PixelFormat(V4L2_PIX_FMT_NV61); + case DRM_FORMAT_NV12: + return V4L2PixelFormat(V4L2_PIX_FMT_NV12); + case DRM_FORMAT_NV21: + return V4L2PixelFormat(V4L2_PIX_FMT_NV21); + + /* Greyscale formats. */ + case DRM_FORMAT_R8: + return V4L2PixelFormat(V4L2_PIX_FMT_GREY); + + /* Compressed formats. */ + case DRM_FORMAT_MJPEG: + return V4L2PixelFormat(V4L2_PIX_FMT_MJPEG); + + default: + LOG(V4L2, Warning) + << "Unsupported pixel format " + << pixelFormat.toString(); + return V4L2PixelFormat(); + } +} + } /* namespace libcamera */ -- cgit v1.2.1