@@ -20,6 +20,8 @@
namespace libcamera {
+class ColorFilterArray;
+
class V4L2PixelFormat
{
public:
@@ -48,6 +50,7 @@ public:
PixelFormat toPixelFormat(bool warn = true) const;
static const std::vector<V4L2PixelFormat> &
fromPixelFormat(const PixelFormat &pixelFormat);
+ bool toNonGeneric(const ColorFilterArray cfa);
bool isGenericLineBasedMetadata() const;
@@ -14,6 +14,7 @@
#include <libcamera/base/log.h>
+#include <libcamera/color_filter_array.h>
#include <libcamera/formats.h>
#include <libcamera/pixel_format.h>
@@ -245,6 +246,111 @@ const std::map<V4L2PixelFormat, V4L2PixelFormat::Info> vpf2pf{
{ formats::MJPEG, "JPEG JFIF" } },
};
+struct FormatWithCfa {
+ V4L2PixelFormat pixfmt;
+ ColorFilterArray cfa;
+
+ bool operator<(const FormatWithCfa &other) const
+ {
+ return std::tie(pixfmt, cfa.order) <
+ std::tie(other.pixfmt, other.cfa.order);
+ }
+};
+
+const std::map<FormatWithCfa, V4L2PixelFormat> generic2specific {
+ /* 8-bit */
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_8), ColorFilterArray::BGGR },
+ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_8), ColorFilterArray::GBRG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_8), ColorFilterArray::GRBG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_8), ColorFilterArray::RGGB },
+ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8) },
+ /* 10-bit */
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_10), ColorFilterArray::BGGR },
+ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_10), ColorFilterArray::GBRG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_10), ColorFilterArray::GRBG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_10), ColorFilterArray::RGGB },
+ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_10), ColorFilterArray::BGGR },
+ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_10), ColorFilterArray::GBRG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_10), ColorFilterArray::GRBG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_10), ColorFilterArray::RGGB },
+ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P) },
+ /* 12-bit */
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_12), ColorFilterArray::BGGR },
+ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_12), ColorFilterArray::GBRG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_12), ColorFilterArray::GRBG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_12), ColorFilterArray::RGGB },
+ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_12), ColorFilterArray::BGGR },
+ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_12), ColorFilterArray::GBRG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_12), ColorFilterArray::GRBG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_12), ColorFilterArray::RGGB },
+ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P) },
+ /* 14-bit */
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_14), ColorFilterArray::BGGR },
+ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR14) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_14), ColorFilterArray::GBRG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG14) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_14), ColorFilterArray::GRBG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG14) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_14), ColorFilterArray::RGGB },
+ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB14) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_14), ColorFilterArray::BGGR },
+ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR14P) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_14), ColorFilterArray::GBRG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG14P) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_14), ColorFilterArray::GRBG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG14P) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_14), ColorFilterArray::RGGB },
+ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB14P) },
+ /* 16-bit */
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_16), ColorFilterArray::BGGR },
+ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR16) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_16), ColorFilterArray::GBRG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_16), ColorFilterArray::GRBG },
+ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_16), ColorFilterArray::RGGB },
+ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16) },
+ /* Monochrome */
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_8), ColorFilterArray::MONO },
+ V4L2PixelFormat(V4L2_PIX_FMT_GREY) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_10), ColorFilterArray::MONO },
+ V4L2PixelFormat(V4L2_PIX_FMT_Y10) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_10), ColorFilterArray::MONO },
+ V4L2PixelFormat(V4L2_PIX_FMT_Y10P) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_12), ColorFilterArray::MONO },
+ V4L2PixelFormat(V4L2_PIX_FMT_Y12) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_CSI2_12), ColorFilterArray::MONO },
+ V4L2PixelFormat(V4L2_PIX_FMT_Y12P) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_RAW_16), ColorFilterArray::MONO },
+ V4L2PixelFormat(V4L2_PIX_FMT_Y16) },
+ /* IPU3 */
+ { { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_RAW10), ColorFilterArray::BGGR },
+ V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_RAW10), ColorFilterArray::GBRG },
+ V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_RAW10), ColorFilterArray::GRBG },
+ V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10) },
+ { { V4L2PixelFormat(V4L2_PIX_FMT_IPU3_RAW10), ColorFilterArray::RGGB },
+ V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10) },
+};
+
} /* namespace */
/**
@@ -390,6 +496,27 @@ V4L2PixelFormat::fromPixelFormat(const PixelFormat &pixelFormat)
return info.v4l2Formats;
}
+/**
+ * \brief Convert a generic V4L2PixelFormat to a specific one given a color
+ * filter array pattern.
+ * \param[in] cfa Color filter array pattern
+ *
+ * If no specific variant is known for the combination, the format is left
+ * unmodified and false is returned.
+ *
+ * \return True if the format is converted, false otherwise
+ */
+bool V4L2PixelFormat::toNonGeneric(const ColorFilterArray cfa)
+{
+ const auto it = generic2specific.find({*this, cfa});
+ if (it != generic2specific.end()) {
+ *this = it->second;
+ return true;
+ }
+
+ return false;
+}
+
/**
* \brief Test if a V4L2PixelFormat is one of the line based generic metadata
* formats
Many pipelines may not support the generic RAW format fourccs immediately. Add a toNonGeneric() helper that gives the bayer-order specific fourcc value given a PixelFormat and a ColorFilterArray. Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com> --- include/libcamera/internal/v4l2_pixelformat.h | 3 + src/libcamera/v4l2_pixelformat.cpp | 127 ++++++++++++++++++++++++++ 2 files changed, 130 insertions(+)