[libcamera-devel] [RFC PATCH 2/2] pipeline: rkisp1: Query the driver for formats

Paul Elder paul.elder at ideasonboard.com
Tue Jul 19 14:10:03 CEST 2022


Query the driver for the output formats that it supports, instead of
hardcoding it.

This allows future-proofing for formats that are supported by some but
not all versions of the driver.

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
---
One problem with this patch is that it causes YVU422 to be reported as
supported, but as discussed before, libcamera will try to configure a
non-existent pixelformat to the V4L2 device, as YVU422P does not exist
as a V4L2 format, and there currently is no infrastructure in place to
let libcamera configure YVU422M instead (which would work).

A patch [1] was submitted to fix this (tell libcamera to configure
YVU422M instead of the non-existent YVU422P), but it has been canceled
as a parallel effort is apparently in place [2].

[1] https://patchwork.libcamera.org/patch/16573/
[2] https://patchwork.libcamera.org/patch/16573/#23799

 src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 50 +++++++++----------
 src/libcamera/pipeline/rkisp1/rkisp1_path.h   |  6 ++-
 2 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
index 6f175758..00b5c3ed 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
@@ -20,9 +20,9 @@ namespace libcamera {
 
 LOG_DECLARE_CATEGORY(RkISP1)
 
-RkISP1Path::RkISP1Path(const char *name, const Span<const PixelFormat> &formats,
+RkISP1Path::RkISP1Path(const char *name,
 		       const Size &minResolution, const Size &maxResolution)
-	: name_(name), running_(false), formats_(formats),
+	: name_(name), running_(false),
 	  minResolution_(minResolution), maxResolution_(maxResolution),
 	  link_(nullptr)
 {
@@ -41,6 +41,8 @@ bool RkISP1Path::init(MediaDevice *media)
 	if (video_->open() < 0)
 		return false;
 
+	formats_ = fetchFormats(video_);
+
 	link_ = media->link("rkisp1_isp", 2, resizer, 0);
 	if (!link_)
 		return false;
@@ -48,6 +50,24 @@ bool RkISP1Path::init(MediaDevice *media)
 	return true;
 }
 
+std::vector<PixelFormat> RkISP1Path::fetchFormats(std::unique_ptr<V4L2VideoDevice> &video)
+{
+	V4L2VideoDevice::Formats v4l2Formats = video->formats(0, true);
+	std::vector<PixelFormat> formats;
+
+	for (auto pair : v4l2Formats) {
+		const PixelFormat pixelFormat = pair.first.toPixelFormat();
+		const PixelFormatInfo info = PixelFormatInfo::info(pixelFormat);
+
+		if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
+			continue;
+
+		formats.push_back(pixelFormat);
+	}
+
+	return formats;
+}
+
 StreamConfiguration RkISP1Path::generateConfiguration(const Size &resolution)
 {
 	Size maxResolution = maxResolution_.boundedToAspectRatio(resolution)
@@ -72,6 +92,7 @@ CameraConfiguration::Status RkISP1Path::validate(StreamConfiguration *cfg)
 	const StreamConfiguration reqCfg = *cfg;
 	CameraConfiguration::Status status = CameraConfiguration::Valid;
 
+	/* NV12 is definitely supported, no need to check */
 	if (std::find(formats_.begin(), formats_.end(), cfg->pixelFormat) ==
 	    formats_.end())
 		cfg->pixelFormat = formats::NV12;
@@ -207,39 +228,18 @@ void RkISP1Path::stop()
 namespace {
 constexpr Size RKISP1_RSZ_MP_SRC_MIN{ 32, 16 };
 constexpr Size RKISP1_RSZ_MP_SRC_MAX{ 4416, 3312 };
-constexpr std::array<PixelFormat, 6> RKISP1_RSZ_MP_FORMATS{
-	formats::YUYV,
-	formats::NV16,
-	formats::NV61,
-	formats::NV21,
-	formats::NV12,
-	formats::R8,
-	/* \todo Add support for RAW formats. */
-};
 
 constexpr Size RKISP1_RSZ_SP_SRC_MIN{ 32, 16 };
 constexpr Size RKISP1_RSZ_SP_SRC_MAX{ 1920, 1920 };
-constexpr std::array<PixelFormat, 8> RKISP1_RSZ_SP_FORMATS{
-	formats::YUYV,
-	formats::NV16,
-	formats::NV61,
-	formats::NV21,
-	formats::NV12,
-	formats::R8,
-	formats::RGB565,
-	formats::XRGB8888,
-};
 } /* namespace */
 
 RkISP1MainPath::RkISP1MainPath()
-	: RkISP1Path("main", RKISP1_RSZ_MP_FORMATS,
-		     RKISP1_RSZ_MP_SRC_MIN, RKISP1_RSZ_MP_SRC_MAX)
+	: RkISP1Path("main", RKISP1_RSZ_MP_SRC_MIN, RKISP1_RSZ_MP_SRC_MAX)
 {
 }
 
 RkISP1SelfPath::RkISP1SelfPath()
-	: RkISP1Path("self", RKISP1_RSZ_SP_FORMATS,
-		     RKISP1_RSZ_SP_SRC_MIN, RKISP1_RSZ_SP_SRC_MAX)
+	: RkISP1Path("self", RKISP1_RSZ_SP_SRC_MIN, RKISP1_RSZ_SP_SRC_MAX)
 {
 }
 
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h
index f3f1ae39..77ea632b 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h
+++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h
@@ -30,7 +30,7 @@ struct V4L2SubdeviceFormat;
 class RkISP1Path
 {
 public:
-	RkISP1Path(const char *name, const Span<const PixelFormat> &formats,
+	RkISP1Path(const char *name,
 		   const Size &minResolution, const Size &maxResolution);
 
 	bool init(MediaDevice *media);
@@ -57,12 +57,14 @@ public:
 	Signal<FrameBuffer *> &bufferReady() { return video_->bufferReady; }
 
 private:
+	std::vector<PixelFormat> fetchFormats(std::unique_ptr<V4L2VideoDevice> &video);
+
 	static constexpr unsigned int RKISP1_BUFFER_COUNT = 4;
 
 	const char *name_;
 	bool running_;
 
-	const Span<const PixelFormat> formats_;
+	std::vector<PixelFormat> formats_;
 	const Size minResolution_;
 	const Size maxResolution_;
 
-- 
2.30.2



More information about the libcamera-devel mailing list