From d60fb232588efe9f9aee001faaab35bf5f46bec1 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 26 Feb 2024 04:50:15 +0200 Subject: libcamera: v4l2_subdevice: Expose media bus format info as internal API The V4L2SubdeviceFormatInfo structure, internal to the v4l2_subdevice.cpp compilation unit, contains information about media bus formats that will be useful in other parts of libcamera. To prepare for this, expose the structure in the v4l2_subdevice.h header and turn it into a class with a similar design as PixelFormatInfo. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- include/libcamera/internal/v4l2_subdevice.h | 13 ++++ src/libcamera/v4l2_subdevice.cpp | 92 +++++++++++++++++++---------- 2 files changed, 75 insertions(+), 30 deletions(-) diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h index 17db311b..a4df9ddf 100644 --- a/include/libcamera/internal/v4l2_subdevice.h +++ b/include/libcamera/internal/v4l2_subdevice.h @@ -29,6 +29,19 @@ namespace libcamera { class MediaDevice; +class MediaBusFormatInfo +{ +public: + bool isValid() const { return code != 0; } + + static const MediaBusFormatInfo &info(uint32_t code); + + const char *name; + uint32_t code; + unsigned int bitsPerPixel; + PixelFormatInfo::ColourEncoding colourEncoding; +}; + struct V4L2SubdeviceCapability final : v4l2_subdev_capability { bool isReadOnly() const { diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 1286e7c3..4918e28e 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -36,28 +36,40 @@ namespace libcamera { LOG_DECLARE_CATEGORY(V4L2) -namespace { - -/* - * \struct MediaBusFormatInfo +/** + * \class MediaBusFormatInfo * \brief Information about media bus formats - * \param name Name of MBUS format - * \param code The media bus format code - * \param bitsPerPixel Bits per pixel - * \param colourEncoding Type of colour encoding + * + * The MediaBusFormatInfo class groups together information describing a media + * bus format. It facilitates handling of media bus formats by providing data + * commonly used in pipeline handlers. + * + * \var MediaBusFormatInfo::name + * \brief The format name as a human-readable string, used as the text + * representation of the format + * + * \var MediaBusFormatInfo::code + * \brief The media bus format code described by this instance (MEDIA_BUS_FMT_*) + * + * \var MediaBusFormatInfo::bitsPerPixel + * \brief The average number of bits per pixel + * + * The number of bits 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 transmit multiple or fractional pixels per sample, the + * value will differ from the bus width. + * + * Formats that don't have a fixed number of bits per pixel, such as compressed + * formats, report 0 in this field. + * + * \var MediaBusFormatInfo::colourEncoding + * \brief The colour encoding type */ -struct MediaBusFormatInfo { - const char *name; - uint32_t code; - unsigned int bitsPerPixel; - PixelFormatInfo::ColourEncoding colourEncoding; -}; -/* - * \var mediaBusFormatInfo - * \brief A map that associates MediaBusFormatInfo struct to V4L2 media - * bus codes - */ +namespace { + const std::map mediaBusFormatInfo{ /* This table is sorted to match the order in linux/media-bus-format.h */ { MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, { @@ -557,6 +569,33 @@ const std::map mediaBusFormatInfo{ } /* namespace */ +/** + * \fn bool MediaBusFormatInfo::isValid() const + * \brief Check if the media bus format info is valid + * \return True if the media bus format info is valid, false otherwise + */ + +/** + * \brief Retrieve information about a media bus format + * \param[in] code The media bus format code + * \return The MediaBusFormatInfo describing the \a code if known, or an invalid + * MediaBusFormatInfo otherwise + */ +const MediaBusFormatInfo &MediaBusFormatInfo::info(uint32_t code) +{ + static const MediaBusFormatInfo invalid{}; + + const auto it = mediaBusFormatInfo.find(code); + if (it == mediaBusFormatInfo.end()) { + LOG(V4L2, Warning) + << "Unsupported media bus format " + << utils::hex(code, 4); + return invalid; + } + + return it->second; +} + /** * \struct V4L2SubdeviceCapability * \brief struct v4l2_subdev_capability object wrapper and helpers @@ -653,14 +692,7 @@ const std::string V4L2SubdeviceFormat::toString() const */ uint8_t V4L2SubdeviceFormat::bitsPerPixel() const { - const auto it = mediaBusFormatInfo.find(mbus_code); - if (it == mediaBusFormatInfo.end()) { - LOG(V4L2, Error) << "No information available for format '" - << *this << "'"; - return 0; - } - - return it->second.bitsPerPixel; + return MediaBusFormatInfo::info(mbus_code).bitsPerPixel; } /** @@ -927,9 +959,9 @@ std::optional V4L2Subdevice::toColorSpace(const v4l2_mbus_framefmt & return std::nullopt; PixelFormatInfo::ColourEncoding colourEncoding; - auto iter = mediaBusFormatInfo.find(format.code); - if (iter != mediaBusFormatInfo.end()) { - colourEncoding = iter->second.colourEncoding; + const MediaBusFormatInfo &info = MediaBusFormatInfo::info(format.code); + if (info.isValid()) { + colourEncoding = info.colourEncoding; } else { LOG(V4L2, Warning) << "Unknown subdev format " -- cgit v1.2.1