From patchwork Thu Apr 30 03:07:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3627 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 47655613F3 for ; Thu, 30 Apr 2020 05:07:28 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="b+DeUSBe"; dkim-atps=neutral Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C911072C for ; Thu, 30 Apr 2020 05:07:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1588216047; bh=2078x2Dxc4mWcYrGEoswjkiES9YjkZaknzyImmycANE=; h=From:To:Subject:Date:In-Reply-To:References:From; b=b+DeUSBeo9RMIEFuleREAf95RaOiqBmVkisuDZT71h39wg/doJ7W5bvtKPNIpzJrR 5lgyXt/iaNHDsD8HuBy2jLYqDB3J1+HZ2FAPRCsK7ccPEiamkDd6c2WgqqXlcWypBA AxCps0MBftdp/9R+8M6hpQhcyQsW54T5WcdXNlak= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Apr 2020 06:07:18 +0300 Message-Id: <20200430030723.8908-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.25.3 In-Reply-To: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> References: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/6] libcamera: v4l2_pixelformat: Move V4L2PixelFormat to a new file X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Apr 2020 03:07:28 -0000 Move the V4L2PixelFormat class to a new file to prepare for additional changes that will make it grow. No functional modification is included. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Niklas Söderlund --- src/libcamera/include/meson.build | 1 + src/libcamera/include/v4l2_pixelformat.h | 45 ++++++++++ src/libcamera/include/v4l2_videodevice.h | 24 +---- src/libcamera/meson.build | 1 + src/libcamera/v4l2_pixelformat.cpp | 106 +++++++++++++++++++++++ src/libcamera/v4l2_videodevice.cpp | 77 ---------------- 6 files changed, 154 insertions(+), 100 deletions(-) create mode 100644 src/libcamera/include/v4l2_pixelformat.h create mode 100644 src/libcamera/v4l2_pixelformat.cpp diff --git a/src/libcamera/include/meson.build b/src/libcamera/include/meson.build index 5aaa99472e4a..683d06133741 100644 --- a/src/libcamera/include/meson.build +++ b/src/libcamera/include/meson.build @@ -27,6 +27,7 @@ libcamera_headers = files([ 'utils.h', 'v4l2_controls.h', 'v4l2_device.h', + 'v4l2_pixelformat.h', 'v4l2_subdevice.h', 'v4l2_videodevice.h', ]) diff --git a/src/libcamera/include/v4l2_pixelformat.h b/src/libcamera/include/v4l2_pixelformat.h new file mode 100644 index 000000000000..4d277569cb8c --- /dev/null +++ b/src/libcamera/include/v4l2_pixelformat.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * Copyright (C) 2020, Raspberry Pi (Trading) Ltd. + * + * v4l2_pixelformat.h - V4L2 Pixel Format + */ +#ifndef __LIBCAMERA_V4L2_PIXELFORMAT_H__ +#define __LIBCAMERA_V4L2_PIXELFORMAT_H__ + +#include +#include + +#include + +#include + +namespace libcamera { + +class V4L2PixelFormat +{ +public: + V4L2PixelFormat() + : fourcc_(0) + { + } + + explicit V4L2PixelFormat(uint32_t fourcc) + : fourcc_(fourcc) + { + } + + bool isValid() const { return fourcc_ != 0; } + uint32_t fourcc() const { return fourcc_; } + operator uint32_t() const { return fourcc_; } + + std::string toString() const; + +private: + uint32_t fourcc_; +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_V4L2_PIXELFORMAT_H__ */ diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h index 976ef9b6dc50..ff64bb357c7e 100644 --- a/src/libcamera/include/v4l2_videodevice.h +++ b/src/libcamera/include/v4l2_videodevice.h @@ -23,6 +23,7 @@ #include "formats.h" #include "log.h" #include "v4l2_device.h" +#include "v4l2_pixelformat.h" namespace libcamera { @@ -149,29 +150,6 @@ private: unsigned int missCounter_; }; -class V4L2PixelFormat -{ -public: - V4L2PixelFormat() - : fourcc_(0) - { - } - - explicit V4L2PixelFormat(uint32_t fourcc) - : fourcc_(fourcc) - { - } - - bool isValid() const { return fourcc_ != 0; } - uint32_t fourcc() const { return fourcc_; } - operator uint32_t() const { return fourcc_; } - - std::string toString() const; - -private: - uint32_t fourcc_; -}; - class V4L2DeviceFormat { public: diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 874d25904693..d8b4d7206aba 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -44,6 +44,7 @@ libcamera_sources = files([ 'utils.cpp', 'v4l2_controls.cpp', 'v4l2_device.cpp', + 'v4l2_pixelformat.cpp', 'v4l2_subdevice.cpp', 'v4l2_videodevice.cpp', ]) diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp new file mode 100644 index 000000000000..57d65c380b0d --- /dev/null +++ b/src/libcamera/v4l2_pixelformat.cpp @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * Copyright (C) 2020, Raspberry Pi (Trading) Ltd. + * + * v4l2_pixelformat.cpp - V4L2 Pixel Format + */ + +#include "v4l2_pixelformat.h" + +#include +#include +#include + +#include + +#include + +#include "log.h" + +/** + * \file v4l2_pixelformat.h + * \brief V4L2 Pixel Format + */ +namespace libcamera { + +LOG_DECLARE_CATEGORY(V4L2) + +/** + * \class V4L2PixelFormat + * \brief V4L2 pixel format FourCC wrapper + * + * The V4L2PixelFormat class describes the pixel format of a V4L2 buffer. It + * wraps the V4L2 numerical FourCC, and shall be used in all APIs that deal with + * V4L2 pixel formats. Its purpose is to prevent unintentional confusion of + * V4L2 and DRM FourCCs in code by catching implicit conversion attempts at + * 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. + */ + +/** + * \fn V4L2PixelFormat::V4L2PixelFormat() + * \brief Construct a V4L2PixelFormat with an invalid format + * + * V4L2PixelFormat instances constructed with the default constructor are + * invalid, calling the isValid() function returns false. + */ + +/** + * \fn V4L2PixelFormat::V4L2PixelFormat(uint32_t fourcc) + * \brief Construct a V4L2PixelFormat from a FourCC value + * \param[in] fourcc The pixel format FourCC numerical value + */ + +/** + * \fn bool V4L2PixelFormat::isValid() const + * \brief Check if the pixel format is valid + * + * V4L2PixelFormat instances constructed with the default constructor are + * invalid. Instances constructed with a FourCC defined in the V4L2 API are + * valid. The behaviour is undefined otherwise. + * + * \return True if the pixel format is valid, false otherwise + */ + +/** + * \fn uint32_t V4L2PixelFormat::fourcc() const + * \brief Retrieve the pixel format FourCC numerical value + * \return The pixel format FourCC numerical value + */ + +/** + * \fn V4L2PixelFormat::operator uint32_t() const + * \brief Convert to the pixel format FourCC numerical value + * \return The pixel format FourCC numerical value + */ + +/** + * \brief Assemble and return a string describing the pixel format + * \return A string describing the pixel format + */ +std::string V4L2PixelFormat::toString() const +{ + if (fourcc_ == 0) + return ""; + + char ss[8] = { static_cast(fourcc_ & 0x7f), + static_cast((fourcc_ >> 8) & 0x7f), + static_cast((fourcc_ >> 16) & 0x7f), + static_cast((fourcc_ >> 24) & 0x7f) }; + + for (unsigned int i = 0; i < 4; i++) { + if (!isprint(ss[i])) + ss[i] = '.'; + } + + if (fourcc_ & (1 << 31)) + strcat(ss, "-BE"); + + return ss; +} + +} /* namespace libcamera */ diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index e8d4f17dfdf1..21df4f524212 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -278,83 +278,6 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const return true; } -/** - * \class V4L2PixelFormat - * \brief V4L2 pixel format FourCC wrapper - * - * The V4L2PixelFormat class describes the pixel format of a V4L2 buffer. It - * wraps the V4L2 numerical FourCC, and shall be used in all APIs that deal with - * V4L2 pixel formats. Its purpose is to prevent unintentional confusion of - * V4L2 and DRM FourCCs in code by catching implicit conversion attempts at - * 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. - */ - -/** - * \fn V4L2PixelFormat::V4L2PixelFormat() - * \brief Construct a V4L2PixelFormat with an invalid format - * - * V4L2PixelFormat instances constructed with the default constructor are - * invalid, calling the isValid() function returns false. - */ - -/** - * \fn V4L2PixelFormat::V4L2PixelFormat(uint32_t fourcc) - * \brief Construct a V4L2PixelFormat from a FourCC value - * \param[in] fourcc The pixel format FourCC numerical value - */ - -/** - * \fn bool V4L2PixelFormat::isValid() const - * \brief Check if the pixel format is valid - * - * V4L2PixelFormat instances constructed with the default constructor are - * invalid. Instances constructed with a FourCC defined in the V4L2 API are - * valid. The behaviour is undefined otherwise. - * - * \return True if the pixel format is valid, false otherwise - */ - -/** - * \fn uint32_t V4L2PixelFormat::fourcc() const - * \brief Retrieve the pixel format FourCC numerical value - * \return The pixel format FourCC numerical value - */ - -/** - * \fn V4L2PixelFormat::operator uint32_t() const - * \brief Convert to the pixel format FourCC numerical value - * \return The pixel format FourCC numerical value - */ - -/** - * \brief Assemble and return a string describing the pixel format - * \return A string describing the pixel format - */ -std::string V4L2PixelFormat::toString() const -{ - if (fourcc_ == 0) - return ""; - - char ss[8] = { static_cast(fourcc_ & 0x7f), - static_cast((fourcc_ >> 8) & 0x7f), - static_cast((fourcc_ >> 16) & 0x7f), - static_cast((fourcc_ >> 24) & 0x7f) }; - - for (unsigned int i = 0; i < 4; i++) { - if (!isprint(ss[i])) - ss[i] = '.'; - } - - if (fourcc_ & (1 << 31)) - strcat(ss, "-BE"); - - return ss; -} - /** * \class V4L2DeviceFormat * \brief The V4L2 video device image format and sizes From patchwork Thu Apr 30 03:07:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3628 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 90353603F7 for ; Thu, 30 Apr 2020 05:07:28 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="DLPwxAOi"; dkim-atps=neutral Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 30C3E503 for ; Thu, 30 Apr 2020 05:07:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1588216048; bh=1DPv91SrE0vT/B5mRyUlCvpnBNwWFn6rgo55EeunE1E=; h=From:To:Subject:Date:In-Reply-To:References:From; b=DLPwxAOignSRUqRhbF1FtR/uahu1P1kz9Z9jKBBPQ8Pc4Zs9nSqVPx9VSNUprkLe2 VBXmzVq8mtFsEJ9ATAgGEYQvkQgj+2PcPrMb//mYxqpz+stCpbU87uBpR7q3OdV414 r8ZiDMtL1DqJ+AOvB63oVp1dQiP4R6qJ5aKi3nTg= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Apr 2020 06:07:19 +0300 Message-Id: <20200430030723.8908-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.25.3 In-Reply-To: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> References: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/6] libcamera: v4l2_pixelformat: Move DRM/V4L2 format conversion X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Apr 2020 03:07:28 -0000 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/include/v4l2_pixelformat.h | 4 + src/libcamera/include/v4l2_videodevice.h | 3 - src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 2 +- src/libcamera/v4l2_pixelformat.cpp | 134 +++++++++++++++++ src/libcamera/v4l2_videodevice.cpp | 147 +------------------ test/libtest/buffer_source.cpp | 4 +- 6 files changed, 143 insertions(+), 151 deletions(-) diff --git a/src/libcamera/include/v4l2_pixelformat.h b/src/libcamera/include/v4l2_pixelformat.h index 4d277569cb8c..0fe8a017de34 100644 --- a/src/libcamera/include/v4l2_pixelformat.h +++ b/src/libcamera/include/v4l2_pixelformat.h @@ -36,6 +36,10 @@ public: std::string toString() const; + PixelFormat toPixelFormat() const; + static V4L2PixelFormat fromPixelFormat(const PixelFormat &pixelFormat, + bool multiplanar); + private: uint32_t fourcc_; }; diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h index ff64bb357c7e..982fee6bf740 100644 --- a/src/libcamera/include/v4l2_videodevice.h +++ b/src/libcamera/include/v4l2_videodevice.h @@ -210,10 +210,7 @@ public: static V4L2VideoDevice *fromEntityName(const MediaDevice *media, const std::string &entity); - static PixelFormat toPixelFormat(V4L2PixelFormat v4l2Fourcc); V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat); - static V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat, - bool multiplanar); protected: std::string logPrefix() const; diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 030ac6864752..455693264c2e 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -166,7 +166,7 @@ CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera, std::inserter(deviceFormats, deviceFormats.begin()), [&](const decltype(v4l2Formats)::value_type &format) { return decltype(deviceFormats)::value_type{ - data->video_->toPixelFormat(format.first), + format.first.toPixelFormat(), format.second }; }); diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp index 57d65c380b0d..876f5de321f6 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 */ diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index 21df4f524212..e95b0c01cc85 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -1634,74 +1633,6 @@ V4L2VideoDevice *V4L2VideoDevice::fromEntityName(const MediaDevice *media, return new V4L2VideoDevice(mediaEntity); } -/** - * \brief Convert a \a v4l2Fourcc to the corresponding PixelFormat - * \param[in] v4l2Fourcc The V4L2 pixel format (V4L2_PIX_FORMAT_*) - * \return The PixelFormat corresponding to \a v4l2Fourcc - */ -PixelFormat V4L2VideoDevice::toPixelFormat(V4L2PixelFormat v4l2Fourcc) -{ - switch (v4l2Fourcc) { - /* 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: - /* - * \todo We can't use LOG() in a static method of a Loggable - * class. Until we fix the logger, work around it. - */ - libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(), - LogWarning).stream() - << "Unsupported V4L2 pixel format " - << v4l2Fourcc.toString(); - return PixelFormat(); - } -} - /** * \brief Convert \a PixelFormat to its corresponding V4L2 FourCC * \param[in] pixelFormat The PixelFormat to convert @@ -1715,82 +1646,8 @@ PixelFormat V4L2VideoDevice::toPixelFormat(V4L2PixelFormat v4l2Fourcc) */ V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelFormat) { - return toV4L2PixelFormat(pixelFormat, caps_.isMultiplanar()); -} - -/** - * \brief Convert \a pixelFormat to its corresponding V4L2 FourCC - * \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 V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat - */ -V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(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); - } - - /* - * \todo We can't use LOG() in a static method of a Loggable - * class. Until we fix the logger, work around it. - */ - libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(), - LogWarning).stream() - << "Unsupported V4L2 pixel format " << pixelFormat.toString(); - return {}; + return V4L2PixelFormat::fromPixelFormat(pixelFormat, + caps_.isMultiplanar()); } /** diff --git a/test/libtest/buffer_source.cpp b/test/libtest/buffer_source.cpp index dae3cb9f7a6c..d1dad2a0f8cf 100644 --- a/test/libtest/buffer_source.cpp +++ b/test/libtest/buffer_source.cpp @@ -70,8 +70,8 @@ int BufferSource::allocate(const StreamConfiguration &config) } format.size = config.size; - format.fourcc = V4L2VideoDevice::toV4L2PixelFormat(config.pixelFormat, - false); + format.fourcc = V4L2PixelFormat::fromPixelFormat(config.pixelFormat, + false); if (video->setFormat(&format)) { std::cout << "Failed to set format on output device" << std::endl; return TestFail; From patchwork Thu Apr 30 03:07:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3629 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2688F603F7 for ; Thu, 30 Apr 2020 05:07:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="GyKxnItx"; dkim-atps=neutral Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 85B2F72C for ; Thu, 30 Apr 2020 05:07:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1588216048; bh=lEgrlfuG0LzK4oz0NCVGwTHlz7lSF0qTsEd7URnmYmI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=GyKxnItxPjYYLrCosQ9Jl1uIwYCe+zaJ/1InR1uQwJcCSGY7x/6/fPwqajEMSVqg2 NVmq1nmvRkgAHLX7nHaByRF7k9wOV3EV4P3hEOHQ8uR6st5I5RXqlNtX6g+BAWTyj/ ZnGeIMQWHIsfbRjxb0tIONgpOG5me1LH0j+I6v9Y= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Apr 2020 06:07:20 +0300 Message-Id: <20200430030723.8908-4-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.25.3 In-Reply-To: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> References: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/6] libcamera: v4l2_pixelformat: Use maps to convert between DRM and V4L2 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Apr 2020 03:07:29 -0000 Replace the two big manual switch...case with maps. This should not just improve efficiency when we will have a larger number of formats, but also paves the way to storing more format information to create additional helpers. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/v4l2_pixelformat.cpp | 204 +++++++++++++++-------------- 1 file changed, 106 insertions(+), 98 deletions(-) diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp index 876f5de321f6..e1c96b9862c3 100644 --- a/src/libcamera/v4l2_pixelformat.cpp +++ b/src/libcamera/v4l2_pixelformat.cpp @@ -41,6 +41,103 @@ LOG_DECLARE_CATEGORY(V4L2) * explicit value() and implicit uint32_t conversion operators may be used. */ +namespace { + +struct PixelFormatInfo { + /* \todo Add support for non-contiguous memory planes */ + V4L2PixelFormat v4l2Format; +}; + +const std::map pf2vpf{ + /* RGB formats. */ + { PixelFormat(DRM_FORMAT_BGR888), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGB24), + } }, + { PixelFormat(DRM_FORMAT_RGB888), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGR24), + } }, + { PixelFormat(DRM_FORMAT_ABGR8888), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGBA32), + } }, + { PixelFormat(DRM_FORMAT_ARGB8888), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ABGR32), + } }, + { PixelFormat(DRM_FORMAT_BGRA8888), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ARGB32), + } }, + { PixelFormat(DRM_FORMAT_RGBA8888), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGRA32), + } }, + + /* YUV packed formats. */ + { PixelFormat(DRM_FORMAT_YUYV), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YUYV), + } }, + { PixelFormat(DRM_FORMAT_YVYU), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YVYU), + } }, + { PixelFormat(DRM_FORMAT_UYVY), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_UYVY), + } }, + { PixelFormat(DRM_FORMAT_VYUY), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_VYUY), + } }, + + /* YUV planar formats. */ + { PixelFormat(DRM_FORMAT_NV16), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV16), + } }, + { PixelFormat(DRM_FORMAT_NV61), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV61), + } }, + { PixelFormat(DRM_FORMAT_NV12), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV12), + } }, + { PixelFormat(DRM_FORMAT_NV21), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV21), + } }, + + /* Greyscale formats. */ + { PixelFormat(DRM_FORMAT_R8), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_GREY), + } }, + + /* Compressed formats. */ + { PixelFormat(DRM_FORMAT_MJPEG), { + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_MJPEG), + } }, +}; + +const std::map vpf2pf{ + /* RGB formats. */ + { V4L2PixelFormat(V4L2_PIX_FMT_RGB24), PixelFormat(DRM_FORMAT_BGR888) }, + { V4L2PixelFormat(V4L2_PIX_FMT_BGR24), PixelFormat(DRM_FORMAT_RGB888) }, + { V4L2PixelFormat(V4L2_PIX_FMT_RGBA32), PixelFormat(DRM_FORMAT_ABGR8888) }, + { V4L2PixelFormat(V4L2_PIX_FMT_ABGR32), PixelFormat(DRM_FORMAT_ARGB8888) }, + { V4L2PixelFormat(V4L2_PIX_FMT_ARGB32), PixelFormat(DRM_FORMAT_BGRA8888) }, + { V4L2PixelFormat(V4L2_PIX_FMT_BGRA32), PixelFormat(DRM_FORMAT_RGBA8888) }, + + /* YUV packed formats. */ + { V4L2PixelFormat(V4L2_PIX_FMT_YUYV), PixelFormat(DRM_FORMAT_YUYV) }, + { V4L2PixelFormat(V4L2_PIX_FMT_YVYU), PixelFormat(DRM_FORMAT_YVYU) }, + { V4L2PixelFormat(V4L2_PIX_FMT_UYVY), PixelFormat(DRM_FORMAT_UYVY) }, + { V4L2PixelFormat(V4L2_PIX_FMT_VYUY), PixelFormat(DRM_FORMAT_VYUY) }, + + /* YUV planar formats. */ + { V4L2PixelFormat(V4L2_PIX_FMT_NV16), PixelFormat(DRM_FORMAT_NV16) }, + { V4L2PixelFormat(V4L2_PIX_FMT_NV61), PixelFormat(DRM_FORMAT_NV61) }, + { V4L2PixelFormat(V4L2_PIX_FMT_NV12), PixelFormat(DRM_FORMAT_NV12) }, + { V4L2PixelFormat(V4L2_PIX_FMT_NV21), PixelFormat(DRM_FORMAT_NV21) }, + + /* Greyscale formats. */ + { V4L2PixelFormat(V4L2_PIX_FMT_GREY), PixelFormat(DRM_FORMAT_R8) }, + + /* Compressed formats. */ + { V4L2PixelFormat(V4L2_PIX_FMT_MJPEG), PixelFormat(DRM_FORMAT_MJPEG) }, +}; + +} /* namespace */ + /** * \fn V4L2PixelFormat::V4L2PixelFormat() * \brief Construct a V4L2PixelFormat with an invalid format @@ -109,60 +206,15 @@ std::string V4L2PixelFormat::toString() const */ 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: + const auto iter = vpf2pf.find(*this); + if (iter == vpf2pf.end()) { LOG(V4L2, Warning) << "Unsupported V4L2 pixel format " << toString(); return PixelFormat(); } + + return iter->second; } /** @@ -181,60 +233,16 @@ PixelFormat V4L2PixelFormat::toPixelFormat() const 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: + const auto iter = pf2vpf.find(pixelFormat); + if (iter == pf2vpf.end()) { LOG(V4L2, Warning) << "Unsupported pixel format " << pixelFormat.toString(); return V4L2PixelFormat(); } + + const PixelFormatInfo &info = iter->second; + return info.v4l2Format; } } /* namespace libcamera */ From patchwork Thu Apr 30 03:07:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3630 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BE8AC613F6 for ; Thu, 30 Apr 2020 05:07:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="RAdiqFJe"; dkim-atps=neutral Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1DBEC503 for ; Thu, 30 Apr 2020 05:07:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1588216049; bh=IjCYSCJYvuIdU9TTcvdZO2iIDTHGLKZPr7jhP41Xhzs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=RAdiqFJeXhtd5jqNrpODWoiErwi/1rTFOd28amnJqKLJ2TkcdvkhV5Br42KvU6VV7 fx8Bh7KWw9/kBmmY2/SNWGbazTwazdC565a6smt4WtZksCZMj0qIzfr2T/u7pdxIv/ q3akpUNyuFMc7Gox5UoNp5jfvkGf3mTOP6vB2K+I= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Apr 2020 06:07:21 +0300 Message-Id: <20200430030723.8908-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.25.3 In-Reply-To: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> References: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/6] libcamera: formats: Expose PixelFormatInfo as an internal API X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Apr 2020 03:07:31 -0000 To prepare for storing more information about pixel formats in PixelFormatInfo, move the class to formats.cpp and document it. The pixel formats database is moved to the same file, and a new static function is added to PixelFormatInfo to retrieve a PixelFormatInfo for a PixelFormat. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/formats.cpp | 126 +++++++++++++++++++++++++++++ src/libcamera/include/formats.h | 15 ++++ src/libcamera/v4l2_pixelformat.cpp | 75 +---------------- 3 files changed, 144 insertions(+), 72 deletions(-) diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp index 5f6552a4e06c..4a351020b0d9 100644 --- a/src/libcamera/formats.cpp +++ b/src/libcamera/formats.cpp @@ -9,6 +9,8 @@ #include +#include "log.h" + /** * \file formats.h * \brief Types and helper methods to handle libcamera image formats @@ -16,6 +18,8 @@ namespace libcamera { +LOG_DEFINE_CATEGORY(Formats) + /** * \class ImageFormats * \brief Describe V4L2Device and V4L2SubDevice image formats @@ -104,4 +108,126 @@ const std::map> &ImageFormats::data() const return data_; } +/** + * \class PixelFormatInfo + * \brief Information about pixel formats + * + * The PixelFormatInfo class groups together information describing a pixel + * format. It facilitates handling of pixel formats by providing data commonly + * used in pipeline handlers. + * + * \var PixelFormatInfo::format + * \brief The PixelFormat described by this instance + * + * \var PixelFormatInfo::v4l2Format + * \brief The V4L2 pixel format corresponding to the PixelFormat + */ + +namespace { + +const std::map pixelFormatInfo{ + /* RGB formats. */ + { PixelFormat(DRM_FORMAT_BGR888), { + .format = PixelFormat(DRM_FORMAT_BGR888), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGB24), + } }, + { PixelFormat(DRM_FORMAT_RGB888), { + .format = PixelFormat(DRM_FORMAT_RGB888), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGR24), + } }, + { PixelFormat(DRM_FORMAT_ABGR8888), { + .format = PixelFormat(DRM_FORMAT_ABGR8888), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGBA32), + } }, + { PixelFormat(DRM_FORMAT_ARGB8888), { + .format = PixelFormat(DRM_FORMAT_ARGB8888), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ABGR32), + } }, + { PixelFormat(DRM_FORMAT_BGRA8888), { + .format = PixelFormat(DRM_FORMAT_BGRA8888), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ARGB32), + } }, + { PixelFormat(DRM_FORMAT_RGBA8888), { + .format = PixelFormat(DRM_FORMAT_RGBA8888), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGRA32), + } }, + + /* YUV packed formats. */ + { PixelFormat(DRM_FORMAT_YUYV), { + .format = PixelFormat(DRM_FORMAT_YUYV), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YUYV), + } }, + { PixelFormat(DRM_FORMAT_YVYU), { + .format = PixelFormat(DRM_FORMAT_YVYU), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YVYU), + } }, + { PixelFormat(DRM_FORMAT_UYVY), { + .format = PixelFormat(DRM_FORMAT_UYVY), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_UYVY), + } }, + { PixelFormat(DRM_FORMAT_VYUY), { + .format = PixelFormat(DRM_FORMAT_VYUY), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_VYUY), + } }, + + /* YUV planar formats. */ + { PixelFormat(DRM_FORMAT_NV16), { + .format = PixelFormat(DRM_FORMAT_NV16), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV16), + } }, + { PixelFormat(DRM_FORMAT_NV61), { + .format = PixelFormat(DRM_FORMAT_NV61), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV61), + } }, + { PixelFormat(DRM_FORMAT_NV12), { + .format = PixelFormat(DRM_FORMAT_NV12), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV12), + } }, + { PixelFormat(DRM_FORMAT_NV21), { + .format = PixelFormat(DRM_FORMAT_NV21), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV21), + } }, + + /* Greyscale formats. */ + { PixelFormat(DRM_FORMAT_R8), { + .format = PixelFormat(DRM_FORMAT_R8), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_GREY), + } }, + + /* Compressed formats. */ + { PixelFormat(DRM_FORMAT_MJPEG), { + .format = PixelFormat(DRM_FORMAT_MJPEG), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_MJPEG), + } }, +}; + +} /* namespace */ + +/** + * \fn bool PixelFormatInfo::isValid() const + * \brief Check if the pixel format info is valid + * \return True if the pixel format info is valid, false otherwise + */ + +/** + * \brief Retrieve information about a pixel format + * \param[in] format The pixel format + * \return The PixelFormatInfo describing the \a format if known, or an invalid + * PixelFormatInfo otherwise + */ +const PixelFormatInfo &PixelFormatInfo::info(const PixelFormat &format) +{ + static const PixelFormatInfo invalid{}; + + const auto iter = pixelFormatInfo.find(format); + if (iter == pixelFormatInfo.end()) { + LOG(Formats, Warning) + << "Unsupported pixel format " + << format.toString(); + return invalid; + } + + return iter->second; +} + } /* namespace libcamera */ diff --git a/src/libcamera/include/formats.h b/src/libcamera/include/formats.h index f43bc8c004f6..560df07c4451 100644 --- a/src/libcamera/include/formats.h +++ b/src/libcamera/include/formats.h @@ -12,6 +12,9 @@ #include #include +#include + +#include "v4l2_pixelformat.h" namespace libcamera { @@ -29,6 +32,18 @@ private: std::map> data_; }; +class PixelFormatInfo +{ +public: + bool isValid() const { return format.isValid(); } + + static const PixelFormatInfo &info(const PixelFormat &format); + + /* \todo Add support for non-contiguous memory planes */ + PixelFormat format; + V4L2PixelFormat v4l2Format; +}; + } /* namespace libcamera */ #endif /* __LIBCAMERA_FORMATS_H__ */ diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp index e1c96b9862c3..580c0fc9d983 100644 --- a/src/libcamera/v4l2_pixelformat.cpp +++ b/src/libcamera/v4l2_pixelformat.cpp @@ -16,6 +16,7 @@ #include +#include "formats.h" #include "log.h" /** @@ -43,71 +44,6 @@ LOG_DECLARE_CATEGORY(V4L2) namespace { -struct PixelFormatInfo { - /* \todo Add support for non-contiguous memory planes */ - V4L2PixelFormat v4l2Format; -}; - -const std::map pf2vpf{ - /* RGB formats. */ - { PixelFormat(DRM_FORMAT_BGR888), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGB24), - } }, - { PixelFormat(DRM_FORMAT_RGB888), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGR24), - } }, - { PixelFormat(DRM_FORMAT_ABGR8888), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGBA32), - } }, - { PixelFormat(DRM_FORMAT_ARGB8888), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ABGR32), - } }, - { PixelFormat(DRM_FORMAT_BGRA8888), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ARGB32), - } }, - { PixelFormat(DRM_FORMAT_RGBA8888), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGRA32), - } }, - - /* YUV packed formats. */ - { PixelFormat(DRM_FORMAT_YUYV), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YUYV), - } }, - { PixelFormat(DRM_FORMAT_YVYU), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YVYU), - } }, - { PixelFormat(DRM_FORMAT_UYVY), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_UYVY), - } }, - { PixelFormat(DRM_FORMAT_VYUY), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_VYUY), - } }, - - /* YUV planar formats. */ - { PixelFormat(DRM_FORMAT_NV16), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV16), - } }, - { PixelFormat(DRM_FORMAT_NV61), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV61), - } }, - { PixelFormat(DRM_FORMAT_NV12), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV12), - } }, - { PixelFormat(DRM_FORMAT_NV21), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV21), - } }, - - /* Greyscale formats. */ - { PixelFormat(DRM_FORMAT_R8), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_GREY), - } }, - - /* Compressed formats. */ - { PixelFormat(DRM_FORMAT_MJPEG), { - .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_MJPEG), - } }, -}; - const std::map vpf2pf{ /* RGB formats. */ { V4L2PixelFormat(V4L2_PIX_FMT_RGB24), PixelFormat(DRM_FORMAT_BGR888) }, @@ -233,15 +169,10 @@ PixelFormat V4L2PixelFormat::toPixelFormat() const V4L2PixelFormat V4L2PixelFormat::fromPixelFormat(const PixelFormat &pixelFormat, bool multiplanar) { - const auto iter = pf2vpf.find(pixelFormat); - if (iter == pf2vpf.end()) { - LOG(V4L2, Warning) - << "Unsupported pixel format " - << pixelFormat.toString(); + const PixelFormatInfo &info = PixelFormatInfo::info(pixelFormat); + if (!info.isValid()) return V4L2PixelFormat(); - } - const PixelFormatInfo &info = iter->second; return info.v4l2Format; } From patchwork Thu Apr 30 03:07:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3631 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1B6056140E for ; Thu, 30 Apr 2020 05:07:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ICS1JXgj"; dkim-atps=neutral Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B32C472C for ; Thu, 30 Apr 2020 05:07:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1588216049; bh=3bGDKeMUM1sVEPXT/hIfiZyJUP97NpuPb9ClwC7g1MA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ICS1JXgjTzcs2TM4RgF1zVAt4U0FzD7c8CQ2skkPbAL/1J4a21g5W8gLoAhuZSZvl O2hKYE4ODrmiEYn3ZQWqRiHOElkn6auUM+clzTQjZnptXAszUXCUAefFovB+hpalNC +DEQq1/proriLbOXuEUQAaQekAuK0G6XccNrWonc= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Apr 2020 06:07:22 +0300 Message-Id: <20200430030723.8908-6-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.25.3 In-Reply-To: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> References: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 5/6] libcamera: formats: Add support for 8-, 10- and 12-bit Bayer formats X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Apr 2020 03:07:32 -0000 Add the 8-, 10- and 12-but Bayer formats, in both unpacked and MIPI-packed variants, to the format tables in PixelFormatInfo and V4L2PixelFormat. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/formats.cpp | 82 ++++++++++++++++++++++++++++++ src/libcamera/v4l2_pixelformat.cpp | 30 +++++++++++ 2 files changed, 112 insertions(+) diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp index 4a351020b0d9..f6f8bc1202c2 100644 --- a/src/libcamera/formats.cpp +++ b/src/libcamera/formats.cpp @@ -194,6 +194,88 @@ const std::map pixelFormatInfo{ .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_GREY), } }, + /* Bayer formats. */ + { PixelFormat(DRM_FORMAT_SBGGR8), { + .format = PixelFormat(DRM_FORMAT_SBGGR8), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8), + } }, + { PixelFormat(DRM_FORMAT_SGBRG8), { + .format = PixelFormat(DRM_FORMAT_SGBRG8), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8), + } }, + { PixelFormat(DRM_FORMAT_SGRBG8), { + .format = PixelFormat(DRM_FORMAT_SGRBG8), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8), + } }, + { PixelFormat(DRM_FORMAT_SRGGB8), { + .format = PixelFormat(DRM_FORMAT_SRGGB8), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8), + } }, + { PixelFormat(DRM_FORMAT_SBGGR10), { + .format = PixelFormat(DRM_FORMAT_SBGGR10), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10), + } }, + { PixelFormat(DRM_FORMAT_SGBRG10), { + .format = PixelFormat(DRM_FORMAT_SGBRG10), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10), + } }, + { PixelFormat(DRM_FORMAT_SGRBG10), { + .format = PixelFormat(DRM_FORMAT_SGRBG10), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10), + } }, + { PixelFormat(DRM_FORMAT_SRGGB10), { + .format = PixelFormat(DRM_FORMAT_SRGGB10), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10), + } }, + { PixelFormat(DRM_FORMAT_SBGGR10, MIPI_FORMAT_MOD_CSI2_PACKED), { + .format = PixelFormat(DRM_FORMAT_SBGGR10, MIPI_FORMAT_MOD_CSI2_PACKED), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P), + } }, + { PixelFormat(DRM_FORMAT_SGBRG10, MIPI_FORMAT_MOD_CSI2_PACKED), { + .format = PixelFormat(DRM_FORMAT_SGBRG10, MIPI_FORMAT_MOD_CSI2_PACKED), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P), + } }, + { PixelFormat(DRM_FORMAT_SGRBG10, MIPI_FORMAT_MOD_CSI2_PACKED), { + .format = PixelFormat(DRM_FORMAT_SGRBG10, MIPI_FORMAT_MOD_CSI2_PACKED), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P), + } }, + { PixelFormat(DRM_FORMAT_SRGGB10, MIPI_FORMAT_MOD_CSI2_PACKED), { + .format = PixelFormat(DRM_FORMAT_SRGGB10, MIPI_FORMAT_MOD_CSI2_PACKED), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P), + } }, + { PixelFormat(DRM_FORMAT_SBGGR12), { + .format = PixelFormat(DRM_FORMAT_SBGGR12), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12), + } }, + { PixelFormat(DRM_FORMAT_SGBRG12), { + .format = PixelFormat(DRM_FORMAT_SGBRG12), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12), + } }, + { PixelFormat(DRM_FORMAT_SGRBG12), { + .format = PixelFormat(DRM_FORMAT_SGRBG12), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12), + } }, + { PixelFormat(DRM_FORMAT_SRGGB12), { + .format = PixelFormat(DRM_FORMAT_SRGGB12), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12), + } }, + { PixelFormat(DRM_FORMAT_SBGGR12, MIPI_FORMAT_MOD_CSI2_PACKED), { + .format = PixelFormat(DRM_FORMAT_SBGGR12, MIPI_FORMAT_MOD_CSI2_PACKED), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P), + } }, + { PixelFormat(DRM_FORMAT_SGBRG12, MIPI_FORMAT_MOD_CSI2_PACKED), { + .format = PixelFormat(DRM_FORMAT_SGBRG12, MIPI_FORMAT_MOD_CSI2_PACKED), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P), + } }, + { PixelFormat(DRM_FORMAT_SGRBG12, MIPI_FORMAT_MOD_CSI2_PACKED), { + .format = PixelFormat(DRM_FORMAT_SGRBG12, MIPI_FORMAT_MOD_CSI2_PACKED), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P), + } }, + { PixelFormat(DRM_FORMAT_SRGGB12, MIPI_FORMAT_MOD_CSI2_PACKED), { + .format = PixelFormat(DRM_FORMAT_SRGGB12, MIPI_FORMAT_MOD_CSI2_PACKED), + .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P), + } }, + /* Compressed formats. */ { PixelFormat(DRM_FORMAT_MJPEG), { .format = PixelFormat(DRM_FORMAT_MJPEG), diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp index 580c0fc9d983..fd7e2d286f3f 100644 --- a/src/libcamera/v4l2_pixelformat.cpp +++ b/src/libcamera/v4l2_pixelformat.cpp @@ -68,6 +68,36 @@ const std::map vpf2pf{ /* Greyscale formats. */ { V4L2PixelFormat(V4L2_PIX_FMT_GREY), PixelFormat(DRM_FORMAT_R8) }, + /* Bayer formats. */ + { V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8), PixelFormat(DRM_FORMAT_SBGGR8) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8), PixelFormat(DRM_FORMAT_SGBRG8) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8), PixelFormat(DRM_FORMAT_SGRBG8) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8), PixelFormat(DRM_FORMAT_SRGGB8) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10), PixelFormat(DRM_FORMAT_SBGGR10) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10), PixelFormat(DRM_FORMAT_SGBRG10) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10), PixelFormat(DRM_FORMAT_SGRBG10) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10), PixelFormat(DRM_FORMAT_SRGGB10) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10), + PixelFormat(DRM_FORMAT_SBGGR10, MIPI_FORMAT_MOD_CSI2_PACKED) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P), + PixelFormat(DRM_FORMAT_SGBRG10, MIPI_FORMAT_MOD_CSI2_PACKED) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P), + PixelFormat(DRM_FORMAT_SGRBG10, MIPI_FORMAT_MOD_CSI2_PACKED) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P), + PixelFormat(DRM_FORMAT_SRGGB10, MIPI_FORMAT_MOD_CSI2_PACKED) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12), PixelFormat(DRM_FORMAT_SBGGR12) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12), PixelFormat(DRM_FORMAT_SGBRG12) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12), PixelFormat(DRM_FORMAT_SGRBG12) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12), PixelFormat(DRM_FORMAT_SRGGB12) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P), + PixelFormat(DRM_FORMAT_SBGGR12, MIPI_FORMAT_MOD_CSI2_PACKED) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P), + PixelFormat(DRM_FORMAT_SGBRG12, MIPI_FORMAT_MOD_CSI2_PACKED) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P), + PixelFormat(DRM_FORMAT_SGRBG12, MIPI_FORMAT_MOD_CSI2_PACKED) }, + { V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P), + PixelFormat(DRM_FORMAT_SRGGB12, MIPI_FORMAT_MOD_CSI2_PACKED) }, + /* Compressed formats. */ { V4L2PixelFormat(V4L2_PIX_FMT_MJPEG), PixelFormat(DRM_FORMAT_MJPEG) }, }; From patchwork Thu Apr 30 03:07:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 3632 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 83D2261411 for ; Thu, 30 Apr 2020 05:07:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="u+cZ7HEL"; dkim-atps=neutral Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0C9D4503 for ; Thu, 30 Apr 2020 05:07:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1588216050; bh=NgUpLsOv+F0clvwhzzfEWbhyRn1ITcVQjxRceQC1U5s=; h=From:To:Subject:Date:In-Reply-To:References:From; b=u+cZ7HELZ7ygt40D7MU5D95jPEl8b1TRQqZxEUwH7XKzAd7TprGTVsMIKXMkZvs1H Ncr7fF1AxlmQ72Hv8mBigMCR2ANaWGprC07+Y49xOJDqXURksnM3swBEHhp28ntVyu yXC9L93Ye7iZ0L/xjbmSCiBf3SOCge+KvcJt8bHE= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Apr 2020 06:07:23 +0300 Message-Id: <20200430030723.8908-7-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.25.3 In-Reply-To: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> References: <20200430030723.8908-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 6/6] libcamera: formats: Add additional data to PixelFormatInfo X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Apr 2020 03:07:33 -0000 Add three additional fields to PixelFormatInfo to report the number of bits per pixel, the colour encoding, and the data packing. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/libcamera/formats.cpp | 127 ++++++++++++++++++++++++++++++++ src/libcamera/include/formats.h | 9 +++ 2 files changed, 136 insertions(+) diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp index f6f8bc1202c2..331affe9fb25 100644 --- a/src/libcamera/formats.cpp +++ b/src/libcamera/formats.cpp @@ -121,6 +121,45 @@ const std::map> &ImageFormats::data() const * * \var PixelFormatInfo::v4l2Format * \brief The V4L2 pixel format corresponding to the PixelFormat + * + * \var PixelFormatInfo::bitsPerPixel + * \brief The average number of bits per pixel + * + * The number per pixel averages the total number of bits for all colour + * components over the whole image, excluding any padding bits or padding + * pixels. + * + * For formats that store pixels with bit padding within words, only the + * effective bits are taken into account. For instance, 12-bit Bayer data + * stored in two bytes per pixel report 12, not 16, in this field. + * + * Formats that don't have a fixed number of bits per pixel, such as compressed + * formats, report 0 in this field. + * + * \var PixelFormatInfo::colourEncoding + * \brief The colour encoding type + * + * \var PixelFormatInfo::packed + * \brief Tell if multiple pixels are packed in the same bytes + * + * Packed formats are defined as storing data from multiple pixels in the same + * bytes. For instance, 12-bit Bayer data with two pixels stored in three bytes + * is packed, while the same data stored with 4 bits of padding in two bytes + * per pixel is not packed. + */ + +/** + * \enum PixelFormatInfo::ColourEncoding + * \brief The colour encoding type + * + * \var PixelFormatInfo::ColourEncodingRGB + * \brief RGB colour encoding + * + * \var PixelFormatInfo::ColourEncodingYUV + * \brief YUV colour encoding + * + * \var PixelFormatInfo::ColourEncodingRAW + * \brief RAW colour encoding */ namespace { @@ -130,156 +169,244 @@ const std::map pixelFormatInfo{ { PixelFormat(DRM_FORMAT_BGR888), { .format = PixelFormat(DRM_FORMAT_BGR888), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGB24), + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + .packed = false, } }, { PixelFormat(DRM_FORMAT_RGB888), { .format = PixelFormat(DRM_FORMAT_RGB888), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGR24), + .bitsPerPixel = 24, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + .packed = false, } }, { PixelFormat(DRM_FORMAT_ABGR8888), { .format = PixelFormat(DRM_FORMAT_ABGR8888), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_RGBA32), + .bitsPerPixel = 32, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + .packed = false, } }, { PixelFormat(DRM_FORMAT_ARGB8888), { .format = PixelFormat(DRM_FORMAT_ARGB8888), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ABGR32), + .bitsPerPixel = 32, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + .packed = false, } }, { PixelFormat(DRM_FORMAT_BGRA8888), { .format = PixelFormat(DRM_FORMAT_BGRA8888), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_ARGB32), + .bitsPerPixel = 32, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + .packed = false, } }, { PixelFormat(DRM_FORMAT_RGBA8888), { .format = PixelFormat(DRM_FORMAT_RGBA8888), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_BGRA32), + .bitsPerPixel = 32, + .colourEncoding = PixelFormatInfo::ColourEncodingRGB, + .packed = false, } }, /* YUV packed formats. */ { PixelFormat(DRM_FORMAT_YUYV), { .format = PixelFormat(DRM_FORMAT_YUYV), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YUYV), + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + .packed = false, } }, { PixelFormat(DRM_FORMAT_YVYU), { .format = PixelFormat(DRM_FORMAT_YVYU), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_YVYU), + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + .packed = false, } }, { PixelFormat(DRM_FORMAT_UYVY), { .format = PixelFormat(DRM_FORMAT_UYVY), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_UYVY), + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + .packed = false, } }, { PixelFormat(DRM_FORMAT_VYUY), { .format = PixelFormat(DRM_FORMAT_VYUY), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_VYUY), + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + .packed = false, } }, /* YUV planar formats. */ { PixelFormat(DRM_FORMAT_NV16), { .format = PixelFormat(DRM_FORMAT_NV16), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV16), + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + .packed = false, } }, { PixelFormat(DRM_FORMAT_NV61), { .format = PixelFormat(DRM_FORMAT_NV61), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV61), + .bitsPerPixel = 16, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + .packed = false, } }, { PixelFormat(DRM_FORMAT_NV12), { .format = PixelFormat(DRM_FORMAT_NV12), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV12), + .bitsPerPixel = 12, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + .packed = false, } }, { PixelFormat(DRM_FORMAT_NV21), { .format = PixelFormat(DRM_FORMAT_NV21), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_NV21), + .bitsPerPixel = 12, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + .packed = false, } }, /* Greyscale formats. */ { PixelFormat(DRM_FORMAT_R8), { .format = PixelFormat(DRM_FORMAT_R8), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_GREY), + .bitsPerPixel = 8, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + .packed = false, } }, /* Bayer formats. */ { PixelFormat(DRM_FORMAT_SBGGR8), { .format = PixelFormat(DRM_FORMAT_SBGGR8), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8), + .bitsPerPixel = 8, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SGBRG8), { .format = PixelFormat(DRM_FORMAT_SGBRG8), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8), + .bitsPerPixel = 8, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SGRBG8), { .format = PixelFormat(DRM_FORMAT_SGRBG8), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8), + .bitsPerPixel = 8, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SRGGB8), { .format = PixelFormat(DRM_FORMAT_SRGGB8), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8), + .bitsPerPixel = 8, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SBGGR10), { .format = PixelFormat(DRM_FORMAT_SBGGR10), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10), + .bitsPerPixel = 10, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SGBRG10), { .format = PixelFormat(DRM_FORMAT_SGBRG10), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10), + .bitsPerPixel = 10, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SGRBG10), { .format = PixelFormat(DRM_FORMAT_SGRBG10), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10), + .bitsPerPixel = 10, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SRGGB10), { .format = PixelFormat(DRM_FORMAT_SRGGB10), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10), + .bitsPerPixel = 10, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SBGGR10, MIPI_FORMAT_MOD_CSI2_PACKED), { .format = PixelFormat(DRM_FORMAT_SBGGR10, MIPI_FORMAT_MOD_CSI2_PACKED), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P), + .bitsPerPixel = 10, + .packed = true, } }, { PixelFormat(DRM_FORMAT_SGBRG10, MIPI_FORMAT_MOD_CSI2_PACKED), { .format = PixelFormat(DRM_FORMAT_SGBRG10, MIPI_FORMAT_MOD_CSI2_PACKED), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P), + .bitsPerPixel = 10, + .packed = true, } }, { PixelFormat(DRM_FORMAT_SGRBG10, MIPI_FORMAT_MOD_CSI2_PACKED), { .format = PixelFormat(DRM_FORMAT_SGRBG10, MIPI_FORMAT_MOD_CSI2_PACKED), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P), + .bitsPerPixel = 10, + .packed = true, } }, { PixelFormat(DRM_FORMAT_SRGGB10, MIPI_FORMAT_MOD_CSI2_PACKED), { .format = PixelFormat(DRM_FORMAT_SRGGB10, MIPI_FORMAT_MOD_CSI2_PACKED), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P), + .bitsPerPixel = 10, + .packed = true, } }, { PixelFormat(DRM_FORMAT_SBGGR12), { .format = PixelFormat(DRM_FORMAT_SBGGR12), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12), + .bitsPerPixel = 12, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SGBRG12), { .format = PixelFormat(DRM_FORMAT_SGBRG12), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12), + .bitsPerPixel = 12, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SGRBG12), { .format = PixelFormat(DRM_FORMAT_SGRBG12), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12), + .bitsPerPixel = 12, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SRGGB12), { .format = PixelFormat(DRM_FORMAT_SRGGB12), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12), + .bitsPerPixel = 12, + .packed = false, } }, { PixelFormat(DRM_FORMAT_SBGGR12, MIPI_FORMAT_MOD_CSI2_PACKED), { .format = PixelFormat(DRM_FORMAT_SBGGR12, MIPI_FORMAT_MOD_CSI2_PACKED), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P), + .bitsPerPixel = 12, + .packed = true, } }, { PixelFormat(DRM_FORMAT_SGBRG12, MIPI_FORMAT_MOD_CSI2_PACKED), { .format = PixelFormat(DRM_FORMAT_SGBRG12, MIPI_FORMAT_MOD_CSI2_PACKED), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P), + .bitsPerPixel = 12, + .packed = true, } }, { PixelFormat(DRM_FORMAT_SGRBG12, MIPI_FORMAT_MOD_CSI2_PACKED), { .format = PixelFormat(DRM_FORMAT_SGRBG12, MIPI_FORMAT_MOD_CSI2_PACKED), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P), + .bitsPerPixel = 12, + .packed = true, } }, { PixelFormat(DRM_FORMAT_SRGGB12, MIPI_FORMAT_MOD_CSI2_PACKED), { .format = PixelFormat(DRM_FORMAT_SRGGB12, MIPI_FORMAT_MOD_CSI2_PACKED), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P), + .bitsPerPixel = 12, + .packed = true, } }, /* Compressed formats. */ { PixelFormat(DRM_FORMAT_MJPEG), { .format = PixelFormat(DRM_FORMAT_MJPEG), .v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_MJPEG), + .bitsPerPixel = 0, + .colourEncoding = PixelFormatInfo::ColourEncodingYUV, + .packed = false, } }, }; diff --git a/src/libcamera/include/formats.h b/src/libcamera/include/formats.h index 560df07c4451..291a1108aa33 100644 --- a/src/libcamera/include/formats.h +++ b/src/libcamera/include/formats.h @@ -35,6 +35,12 @@ private: class PixelFormatInfo { public: + enum ColourEncoding { + ColourEncodingRGB, + ColourEncodingYUV, + ColourEncodingRAW, + }; + bool isValid() const { return format.isValid(); } static const PixelFormatInfo &info(const PixelFormat &format); @@ -42,6 +48,9 @@ public: /* \todo Add support for non-contiguous memory planes */ PixelFormat format; V4L2PixelFormat v4l2Format; + unsigned int bitsPerPixel; + enum ColourEncoding colourEncoding; + bool packed; }; } /* namespace libcamera */