[libcamera-devel] [PATCH] Remove limitation that camera and display must match

Eric Curtin ecurtin at redhat.com
Fri Feb 4 12:12:54 CET 2022


There is a limitation that requires input and output
to be pixel for pixel identical in terms of height
and width. Remove this limitation to enable more
hardware that doesn't match. Centralize the image.

Signed-off-by: Eric Curtin <ecurtin at redhat.com>
---
 src/cam/kms_sink.cpp | 27 +++++++++------------------
 src/cam/kms_sink.h   |  2 ++
 2 files changed, 11 insertions(+), 18 deletions(-)

diff --git a/src/cam/kms_sink.cpp b/src/cam/kms_sink.cpp
index 973cd370..159b9355 100644
--- a/src/cam/kms_sink.cpp
+++ b/src/cam/kms_sink.cpp
@@ -113,24 +113,15 @@ int KMSSink::configure(const libcamera::CameraConfiguration &config)
 	const libcamera::StreamConfiguration &cfg = config.at(0);
 
 	const std::vector<DRM::Mode> &modes = connector_->modes();
-	const auto iter = std::find_if(modes.begin(), modes.end(),
-				       [&](const DRM::Mode &mode) {
-					       return mode.hdisplay == cfg.size.width &&
-						      mode.vdisplay == cfg.size.height;
-				       });
-	if (iter == modes.end()) {
-		std::cerr
-			<< "No mode matching " << cfg.size.toString()
-			<< std::endl;
-		return -EINVAL;
-	}
 
 	int ret = configurePipeline(cfg.pixelFormat);
 	if (ret < 0)
 		return ret;
 
-	mode_ = &*iter;
+	mode_ = &modes[0];
 	size_ = cfg.size;
+	x_ = (mode_->hdisplay - size_.width) / 2;
+	y_ = (mode_->vdisplay - size_.height) / 2;
 	stride_ = cfg.stride;
 
 	return 0;
@@ -297,12 +288,12 @@ bool KMSSink::processRequest(libcamera::Request *camRequest)
 		drmRequest->addProperty(plane_, "CRTC_ID", crtc_->id());
 		drmRequest->addProperty(plane_, "SRC_X", 0 << 16);
 		drmRequest->addProperty(plane_, "SRC_Y", 0 << 16);
-		drmRequest->addProperty(plane_, "SRC_W", mode_->hdisplay << 16);
-		drmRequest->addProperty(plane_, "SRC_H", mode_->vdisplay << 16);
-		drmRequest->addProperty(plane_, "CRTC_X", 0);
-		drmRequest->addProperty(plane_, "CRTC_Y", 0);
-		drmRequest->addProperty(plane_, "CRTC_W", mode_->hdisplay);
-		drmRequest->addProperty(plane_, "CRTC_H", mode_->vdisplay);
+		drmRequest->addProperty(plane_, "SRC_W", size_.width << 16);
+		drmRequest->addProperty(plane_, "SRC_H", size_.height << 16);
+		drmRequest->addProperty(plane_, "CRTC_X", x_);
+		drmRequest->addProperty(plane_, "CRTC_Y", y_);
+		drmRequest->addProperty(plane_, "CRTC_W", size_.width);
+		drmRequest->addProperty(plane_, "CRTC_H", size_.height);
 
 		flags |= DRM::AtomicRequest::FlagAllowModeset;
 	}
diff --git a/src/cam/kms_sink.h b/src/cam/kms_sink.h
index 4a0a872c..1b08e887 100644
--- a/src/cam/kms_sink.h
+++ b/src/cam/kms_sink.h
@@ -61,6 +61,8 @@ private:
 	libcamera::PixelFormat format_;
 	libcamera::Size size_;
 	unsigned int stride_;
+	unsigned int x_;  // Where to start drawing camera output
+	unsigned int y_;  // Where to start drawing camera output
 
 	std::map<libcamera::FrameBuffer *, std::unique_ptr<DRM::FrameBuffer>> buffers_;
 
-- 
2.34.1



More information about the libcamera-devel mailing list