summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libcamera/formats.cpp126
-rw-r--r--src/libcamera/include/formats.h15
-rw-r--r--src/libcamera/v4l2_pixelformat.cpp75
3 files changed, 144 insertions, 72 deletions
diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp
index 5f6552a4..4a351020 100644
--- a/src/libcamera/formats.cpp
+++ b/src/libcamera/formats.cpp
@@ -9,6 +9,8 @@
#include <errno.h>
+#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<unsigned int, std::vector<SizeRange>> &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<PixelFormat, PixelFormatInfo> 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 f43bc8c0..560df07c 100644
--- a/src/libcamera/include/formats.h
+++ b/src/libcamera/include/formats.h
@@ -12,6 +12,9 @@
#include <vector>
#include <libcamera/geometry.h>
+#include <libcamera/pixelformats.h>
+
+#include "v4l2_pixelformat.h"
namespace libcamera {
@@ -29,6 +32,18 @@ private:
std::map<unsigned int, std::vector<SizeRange>> 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 e1c96b98..580c0fc9 100644
--- a/src/libcamera/v4l2_pixelformat.cpp
+++ b/src/libcamera/v4l2_pixelformat.cpp
@@ -16,6 +16,7 @@
#include <libcamera/pixelformats.h>
+#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<PixelFormat, PixelFormatInfo> 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<V4L2PixelFormat, PixelFormat> 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;
}