[libcamera-devel] [PATCH v2 2/4] libcamera: pipeline: vimc: Set media bus formats for sensor and debayer

Niklas Söderlund niklas.soderlund at ragnatech.se
Wed Aug 7 22:49:13 CEST 2019


Linux commit 85ab1aa1fac17bcd ("media: vimc: deb: fix default sink bayer
format") which is part of v5.2 changes the default media bus format for
the debayer subdevices. This leads to a -EPIPE error when trying to use
the raw capture video device nodes.

Fix this by modifying the camera exposed by vimc to only support bayer
formarts. This allows the pipeline to function both before and after the
upstream change. As a consequence of this change the media bus format of
the subdevices involved needs to be set to avoid a misconfigured media
pipeline. Once upstream is sorted out none bayer formats should be
re-enabled on the vimc pipeline.

Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
---
 src/libcamera/pipeline/vimc.cpp | 54 ++++++++++++++++++++++++++++-----
 test/camera/buffer_import.cpp   |  6 ++--
 2 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index 3d6808222a8a2c5d..4dc514638da3746d 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -10,6 +10,8 @@
 #include <iomanip>
 #include <tuple>
 
+#include <linux/media-bus-format.h>
+
 #include <libcamera/camera.h>
 #include <libcamera/controls.h>
 #include <libcamera/ipa/ipa_interface.h>
@@ -25,6 +27,7 @@
 #include "pipeline_handler.h"
 #include "utils.h"
 #include "v4l2_controls.h"
+#include "v4l2_subdevice.h"
 #include "v4l2_videodevice.h"
 
 namespace libcamera {
@@ -35,13 +38,15 @@ class VimcCameraData : public CameraData
 {
 public:
 	VimcCameraData(PipelineHandler *pipe)
-		: CameraData(pipe), video_(nullptr), sensor_(nullptr)
+		: CameraData(pipe), video_(nullptr), debayer_(nullptr),
+		  sensor_(nullptr)
 	{
 	}
 
 	~VimcCameraData()
 	{
 		delete sensor_;
+		delete debayer_;
 		delete video_;
 	}
 
@@ -49,6 +54,7 @@ public:
 	void bufferReady(Buffer *buffer);
 
 	V4L2VideoDevice *video_;
+	V4L2Subdevice *debayer_;
 	CameraSensor *sensor_;
 	Stream stream_;
 };
@@ -101,10 +107,11 @@ VimcCameraConfiguration::VimcCameraConfiguration()
 
 CameraConfiguration::Status VimcCameraConfiguration::validate()
 {
-	static const std::array<unsigned int, 3> formats{
-		V4L2_PIX_FMT_BGR24,
-		V4L2_PIX_FMT_RGB24,
-		V4L2_PIX_FMT_ARGB32,
+	static const std::array<unsigned int, 4> formats{
+		V4L2_PIX_FMT_SBGGR8,
+		V4L2_PIX_FMT_SGBRG8,
+		V4L2_PIX_FMT_SGRBG8,
+		V4L2_PIX_FMT_SRGGB8,
 	};
 
 	Status status = Valid;
@@ -123,8 +130,8 @@ CameraConfiguration::Status VimcCameraConfiguration::validate()
 	/* Adjust the pixel format. */
 	if (std::find(formats.begin(), formats.end(), cfg.pixelFormat) ==
 	    formats.end()) {
-		LOG(VIMC, Debug) << "Adjusting format to RGB24";
-		cfg.pixelFormat = V4L2_PIX_FMT_RGB24;
+		LOG(VIMC, Debug) << "Adjusting format to SBGGR8";
+		cfg.pixelFormat = V4L2_PIX_FMT_SBGGR8;
 		status = Adjusted;
 	}
 
@@ -159,7 +166,7 @@ CameraConfiguration *PipelineHandlerVimc::generateConfiguration(Camera *camera,
 		return config;
 
 	StreamConfiguration cfg{};
-	cfg.pixelFormat = V4L2_PIX_FMT_RGB24;
+	cfg.pixelFormat = V4L2_PIX_FMT_SBGGR8;
 	cfg.size = { 640, 480 };
 	cfg.bufferCount = 4;
 
@@ -176,6 +183,33 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config)
 	StreamConfiguration &cfg = config->at(0);
 	int ret;
 
+	V4L2SubdeviceFormat subformat = {};
+	subformat.size = cfg.size;
+	switch (cfg.pixelFormat) {
+	case V4L2_PIX_FMT_SBGGR8:
+		subformat.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8;
+		break;
+	case V4L2_PIX_FMT_SGBRG8:
+		subformat.mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8;
+		break;
+	case V4L2_PIX_FMT_SGRBG8:
+		subformat.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8;
+		break;
+	case V4L2_PIX_FMT_SRGGB8:
+		subformat.mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = data->sensor_->setFormat(&subformat);
+	if (ret)
+		return ret;
+
+	ret = data->debayer_->setFormat(0, &subformat);
+	if (ret)
+		return ret;
+
 	V4L2DeviceFormat format = {};
 	format.fourcc = cfg.pixelFormat;
 	format.size = cfg.size;
@@ -340,6 +374,10 @@ int VimcCameraData::init(MediaDevice *media)
 	if (video_->open())
 		return -ENODEV;
 
+	debayer_ = new V4L2Subdevice(media->getEntityByName("Debayer B"));
+	if (debayer_->open())
+		return -ENODEV;
+
 	video_->bufferReady.connect(this, &VimcCameraData::bufferReady);
 
 	sensor_ = new CameraSensor(media->getEntityByName("Sensor B"));
diff --git a/test/camera/buffer_import.cpp b/test/camera/buffer_import.cpp
index 400d02b350c1aa8f..2c29267f22d1ba27 100644
--- a/test/camera/buffer_import.cpp
+++ b/test/camera/buffer_import.cpp
@@ -74,10 +74,10 @@ public:
 
 		format_.size.width = 640;
 		format_.size.height = 480;
-		format_.fourcc = V4L2_PIX_FMT_RGB24;
+		format_.fourcc = V4L2_PIX_FMT_SBGGR8;
 		format_.planesCount = 1;
-		format_.planes[0].size = 640 * 480 * 3;
-		format_.planes[0].bpl = 640 * 3;
+		format_.planes[0].size = 640 * 480;
+		format_.planes[0].bpl = 640;
 
 		if (video_->setFormat(&format_)) {
 			cleanup();
-- 
2.22.0



More information about the libcamera-devel mailing list