diff options
-rw-r--r-- | include/libcamera/pixelformats.h | 25 | ||||
-rw-r--r-- | src/cam/main.cpp | 6 | ||||
-rw-r--r-- | src/libcamera/pipeline/uvcvideo.cpp | 5 | ||||
-rw-r--r-- | src/libcamera/pipeline/vimc.cpp | 2 | ||||
-rw-r--r-- | src/libcamera/pixelformats.cpp | 96 | ||||
-rw-r--r-- | src/libcamera/stream.cpp | 4 | ||||
-rw-r--r-- | src/libcamera/v4l2_videodevice.cpp | 3 | ||||
-rw-r--r-- | src/v4l2/v4l2_camera_proxy.cpp | 2 |
8 files changed, 126 insertions, 17 deletions
diff --git a/include/libcamera/pixelformats.h b/include/libcamera/pixelformats.h index 544363af..eb40e55a 100644 --- a/include/libcamera/pixelformats.h +++ b/include/libcamera/pixelformats.h @@ -7,13 +7,36 @@ #ifndef __LIBCAMERA_PIXEL_FORMATS_H__ #define __LIBCAMERA_PIXEL_FORMATS_H__ +#include <set> #include <stdint.h> +#include <string> #include <linux/drm_fourcc.h> namespace libcamera { -using PixelFormat = uint32_t; +class PixelFormat +{ +public: + PixelFormat(); + PixelFormat(uint32_t fourcc, const std::set<uint64_t> &modifiers = {}); + + bool operator==(const PixelFormat &other) const; + bool operator!=(const PixelFormat &other) const { return !(*this == other); } + bool operator<(const PixelFormat &other) const; + + bool isValid() const { return fourcc_ != 0; } + + operator uint32_t() const { return fourcc_; } + uint32_t fourcc() const { return fourcc_; } + const std::set<uint64_t> &modifiers() const { return modifiers_; } + + std::string toString() const; + +private: + uint32_t fourcc_; + std::set<uint64_t> modifiers_; +}; } /* namespace libcamera */ diff --git a/src/cam/main.cpp b/src/cam/main.cpp index af516f1c..f73e77f3 100644 --- a/src/cam/main.cpp +++ b/src/cam/main.cpp @@ -253,7 +253,7 @@ int CamApp::prepareConfig() /* TODO: Translate 4CC string to ID. */ if (opt.isSet("pixelformat")) - cfg.pixelFormat = opt["pixelformat"]; + cfg.pixelFormat = PixelFormat(opt["pixelformat"]); } } @@ -304,8 +304,8 @@ int CamApp::infoConfiguration() const StreamFormats &formats = cfg.formats(); for (PixelFormat pixelformat : formats.pixelformats()) { - std::cout << " * Pixelformat: 0x" << std::hex - << std::setw(8) << pixelformat << " " + std::cout << " * Pixelformat: " + << pixelformat.toString() << " " << formats.range(pixelformat).toString() << std::endl; diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index 5ff29240..9876d8c9 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -115,8 +115,9 @@ CameraConfiguration::Status UVCCameraConfiguration::validate() if (iter == pixelFormats.end()) { cfg.pixelFormat = pixelFormats.front(); LOG(UVC, Debug) - << "Adjusting pixel format from " << pixelFormat - << " to " << cfg.pixelFormat; + << "Adjusting pixel format from " + << pixelFormat.toString() << " to " + << cfg.pixelFormat.toString(); status = Adjusted; } diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index 82649952..00cb7389 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -105,7 +105,7 @@ private: namespace { -constexpr std::array<PixelFormat, 3> pixelformats{ +static const std::array<PixelFormat, 3> pixelformats{ DRM_FORMAT_RGB888, DRM_FORMAT_BGR888, DRM_FORMAT_BGRA8888, diff --git a/src/libcamera/pixelformats.cpp b/src/libcamera/pixelformats.cpp index c0333540..87557d98 100644 --- a/src/libcamera/pixelformats.cpp +++ b/src/libcamera/pixelformats.cpp @@ -15,14 +15,102 @@ namespace libcamera { /** - * \typedef PixelFormat + * \class PixelFormat * \brief libcamera image pixel format * * The PixelFormat type describes the format of images in the public libcamera - * API. It stores a FourCC value as a 32-bit unsigned integer. The values are - * defined in the Linux kernel DRM/KMS API (see linux/drm_fourcc.h). + * API. It stores a FourCC value as a 32-bit unsigned integer and a set of + * modifiers. The FourCC and modifiers values are defined in the Linux kernel + * DRM/KMS API (see linux/drm_fourcc.h). + */ + +/** + * \brief Construct a PixelFormat with an invalid format + * + * PixelFormat instances constructed with the default constructor are + * invalid, calling the isValid() function returns false. + */ +PixelFormat::PixelFormat() + : fourcc_(0) +{ +} + +/** + * \brief Construct a PixelFormat from a DRM FourCC and a set of modifiers + * \param[in] fourcc A DRM FourCC + * \param[in] modifiers A set of DRM FourCC modifiers + */ +PixelFormat::PixelFormat(uint32_t fourcc, const std::set<uint64_t> &modifiers) + : fourcc_(fourcc), modifiers_(modifiers) +{ +} + +/** + * \brief Compare pixel formats for equality + * \return True if the two pixel formats are equal, false otherwise + */ +bool PixelFormat::operator==(const PixelFormat &other) const +{ + return fourcc_ == other.fourcc() && modifiers_ == other.modifiers_; +} + +/** + * \fn bool PixelFormat::operator!=(const PixelFormat &other) const + * \brief Compare pixel formats for inequality + * \return True if the two pixel formats are not equal, false otherwise + */ + +/** + * \brief Compare pixel formats for smaller than order + * \return True if \a this is smaller than \a other, false otherwise + */ +bool PixelFormat::operator<(const PixelFormat &other) const +{ + if (fourcc_ < other.fourcc_) + return true; + if (fourcc_ > other.fourcc_) + return false; + return modifiers_ < modifiers_; +} + +/** + * \fn bool PixelFormat::isValid() const + * \brief Check if the pixel format is valid + * + * PixelFormat instances constructed with the default constructor are + * invalid. Instances constructed with a FourCC defined in the DRM API + * are valid. The behaviour is undefined otherwise. * - * \todo Add support for format modifiers + * \return True if the pixel format is valid, false otherwise + */ + +/** + * \fn PixelFormat::operator uint32_t() const + * \brief Convert the the pixel format numerical value + * \return The pixel format numerical value + */ + +/** + * \fn PixelFormat::fourcc() const + * \brief Retrieve the pixel format FourCC + * \return DRM FourCC + */ + +/** + * \fn PixelFormat::modifiers() const + * \brief Retrieve the pixel format modifiers + * \return Set of DRM modifiers + */ + +/** + * \brief Assemble and return a string describing the pixel format + * \return A string describing the pixel format */ +std::string PixelFormat::toString() const +{ + char str[11]; + snprintf(str, 11, "0x%08x", fourcc_); + return str; +} } /* namespace libcamera */ diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp index 13789e9e..0716de38 100644 --- a/src/libcamera/stream.cpp +++ b/src/libcamera/stream.cpp @@ -347,9 +347,7 @@ StreamConfiguration::StreamConfiguration(const StreamFormats &formats) */ std::string StreamConfiguration::toString() const { - std::stringstream ss; - ss << size.toString() << "-" << utils::hex(pixelFormat); - return ss.str(); + return size.toString() + "-" + pixelFormat.toString(); } /** diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index ca0d147f..ce67e04c 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -1551,8 +1551,7 @@ uint32_t V4L2VideoDevice::toV4L2Fourcc(PixelFormat pixelFormat, bool multiplanar * class. Until we fix the logger, work around it. */ libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(), LogError).stream() - << "Unsupported V4L2 pixel format " - << utils::hex(pixelFormat); + << "Unsupported V4L2 pixel format " << pixelFormat.toString(); return 0; } diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index e349fbdd..3bc1c1aa 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -533,7 +533,7 @@ struct PixelFormatInfo { namespace { -constexpr std::array<PixelFormatInfo, 13> pixelFormatInfo = {{ +static const std::array<PixelFormatInfo, 13> pixelFormatInfo = {{ /* RGB formats. */ { DRM_FORMAT_RGB888, V4L2_PIX_FMT_BGR24, 1, {{ { 24, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} }, { DRM_FORMAT_BGR888, V4L2_PIX_FMT_RGB24, 1, {{ { 24, 1, 1 }, { 0, 0, 0 }, { 0, 0, 0 } }} }, |