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 <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Laurent Pinchart 2024-02-26 04:50:15 +02:00
parent 1a1cf4a2c1
commit d60fb23258
2 changed files with 76 additions and 31 deletions

View file

@ -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
{

View file

@ -36,28 +36,40 @@ namespace libcamera {
LOG_DECLARE_CATEGORY(V4L2)
/**
* \class MediaBusFormatInfo
* \brief Information about media bus formats
*
* 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
*/
namespace {
/*
* \struct 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
*/
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
*/
const std::map<uint32_t, MediaBusFormatInfo> 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<uint32_t, MediaBusFormatInfo> 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<ColorSpace> 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 "