about summary refs log tree commit diff
path: root/users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch
diff options
context:
space:
mode:
authorFlorian Klink <flokli@flokli.de>2024-01-30T09·43+0200
committerflokli <flokli@flokli.de>2024-01-30T09·54+0000
commitaf9a8d372b24710bf7fc27c8e81244e1ca6d1658 (patch)
treedf8bee03b202ec5081b9bd7e7b5d7b6ecdd28e1b /users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch
parentb38be028d96ce107439f3323026270228a871a13 (diff)
feat(users/flokli/ipu6-softisp): init r/7454
This code adds support for the ipu6 webcams via libcamera, based on the work in
https://copr.fedorainfracloud.org/coprs/jwrdegoede/ipu6-softisp/.

It's supposed to be included in your NixOS configuration imports.

Change-Id: Ifb71999ad61161fa23506b97cb449f73fb1270e3
Reviewed-on: https://cl.tvl.fyi/c/depot/+/10709
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
Autosubmit: flokli <flokli@flokli.de>
Diffstat (limited to 'users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch')
-rw-r--r--users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch243
1 files changed, 243 insertions, 0 deletions
diff --git a/users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch b/users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch
new file mode 100644
index 000000000000..f639a3b74c93
--- /dev/null
+++ b/users/flokli/ipu6-softisp/libcamera/0015-libcamera-pipeline-simple-enable-use-of-Soft-ISP-and.patch
@@ -0,0 +1,243 @@
+From ad61052d9aea1f1af6aaef9ce7e5d447c595187c Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andrey.konovalov@linaro.org>
+Date: Tue, 12 Dec 2023 02:02:37 +0300
+Subject: [PATCH 15/25] libcamera: pipeline: simple: enable use of Soft ISP and
+ Soft IPA
+
+To enable the Simple Soft ISP and Soft IPA for simple pipeline handler
+configure the build with:
+  -Dpipelines=simple/simple -Dipas=simple/simple
+
+If the pipeline uses Converter, Soft ISP and Soft IPA aren't
+available.
+
+Configuring the build with just:
+  -Dpipelines=simple
+makes it to work like before - Soft ISP and Soft IPA aren't used.
+
+Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
+Tested-by: Pavel Machek <pavel@ucw.cz>
+---
+ src/libcamera/pipeline/simple/simple.cpp | 111 ++++++++++++++++++-----
+ 1 file changed, 89 insertions(+), 22 deletions(-)
+
+diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
+index fa298746..c76510c2 100644
+--- a/src/libcamera/pipeline/simple/simple.cpp
++++ b/src/libcamera/pipeline/simple/simple.cpp
+@@ -34,6 +34,7 @@
+ #include "libcamera/internal/device_enumerator.h"
+ #include "libcamera/internal/media_device.h"
+ #include "libcamera/internal/pipeline_handler.h"
++#include "libcamera/internal/software_isp.h"
+ #include "libcamera/internal/v4l2_subdevice.h"
+ #include "libcamera/internal/v4l2_videodevice.h"
+ 
+@@ -274,6 +275,7 @@ public:
+ 	bool useConversion_;
+ 
+ 	std::unique_ptr<Converter> converter_;
++	std::unique_ptr<SoftwareIsp> swIsp_;
+ 
+ private:
+ 	void tryPipeline(unsigned int code, const Size &size);
+@@ -281,6 +283,9 @@ private:
+ 
+ 	void conversionInputDone(FrameBuffer *buffer);
+ 	void conversionOutputDone(FrameBuffer *buffer);
++
++	void ispStatsReady(int dummy);
++	void setSensorControls(const ControlList &sensorControls);
+ };
+ 
+ class SimpleCameraConfiguration : public CameraConfiguration
+@@ -509,6 +514,25 @@ int SimpleCameraData::init()
+ 		}
+ 	}
+ 
++	/*
++	 * Create SoftwareIsp unconditionally if no converter is used
++	 * - to be revisited
++	 */
++	if (!converter_) {
++		swIsp_ = SoftwareIspFactoryBase::create(pipe, sensor_->controls());
++		if (!swIsp_) {
++			LOG(SimplePipeline, Warning)
++				<< "Failed to create software ISP, disabling software debayering";
++			swIsp_.reset();
++		} else {
++			swIsp_->inputBufferReady.connect(this, &SimpleCameraData::conversionInputDone);
++			swIsp_->outputBufferReady.connect(this, &SimpleCameraData::conversionOutputDone);
++			swIsp_->ispStatsReady.connect(this, &SimpleCameraData::ispStatsReady);
++
++			swIsp_->getSignalSetSensorControls().connect(this, &SimpleCameraData::setSensorControls);
++		}
++	}
++
+ 	video_ = pipe->video(entities_.back().entity);
+ 	ASSERT(video_);
+ 
+@@ -599,12 +623,20 @@ void SimpleCameraData::tryPipeline(unsigned int code, const Size &size)
+ 		config.captureFormat = pixelFormat;
+ 		config.captureSize = format.size;
+ 
+-		if (!converter_) {
+-			config.outputFormats = { pixelFormat };
+-			config.outputSizes = config.captureSize;
+-		} else {
++		if (converter_) {
+ 			config.outputFormats = converter_->formats(pixelFormat);
+ 			config.outputSizes = converter_->sizes(format.size);
++		} else if (swIsp_) {
++			config.outputFormats = swIsp_->formats(pixelFormat);
++			config.outputSizes = swIsp_->sizes(pixelFormat, format.size);
++			if (config.outputFormats.empty()) {
++				/* Do not use swIsp for unsupported pixelFormat's */
++				config.outputFormats = { pixelFormat };
++				config.outputSizes = config.captureSize;
++			}
++		} else {
++			config.outputFormats = { pixelFormat };
++			config.outputSizes = config.captureSize;
+ 		}
+ 
+ 		configs_.push_back(config);
+@@ -750,9 +782,9 @@ void SimpleCameraData::bufferReady(FrameBuffer *buffer)
+ 		}
+ 
+ 		/*
+-		 * The converter is in use. Requeue the internal buffer for
+-		 * capture (unless the stream is being stopped), and complete
+-		 * the request with all the user-facing buffers.
++		 * The converter or Software ISP is in use. Requeue the internal
++		 * buffer for capture (unless the stream is being stopped), and
++		 * complete the request with all the user-facing buffers.
+ 		 */
+ 		if (buffer->metadata().status != FrameMetadata::FrameCancelled)
+ 			video_->queueBuffer(buffer);
+@@ -798,9 +830,9 @@ void SimpleCameraData::bufferReady(FrameBuffer *buffer)
+ 					buffer->metadata().timestamp);
+ 
+ 	/*
+-	 * Queue the captured and the request buffer to the converter if format
+-	 * conversion is needed. If there's no queued request, just requeue the
+-	 * captured buffer for capture.
++	 * Queue the captured and the request buffer to the converter or Software
++	 * ISP if format conversion is needed. If there's no queued request, just
++	 * requeue the captured buffer for capture.
+ 	 */
+ 	if (useConversion_) {
+ 		if (conversionQueue_.empty()) {
+@@ -808,7 +840,11 @@ void SimpleCameraData::bufferReady(FrameBuffer *buffer)
+ 			return;
+ 		}
+ 
+-		converter_->queueBuffers(buffer, conversionQueue_.front());
++		if (converter_)
++			converter_->queueBuffers(buffer, conversionQueue_.front());
++		else
++			swIsp_->queueBuffers(buffer, conversionQueue_.front());
++
+ 		conversionQueue_.pop();
+ 		return;
+ 	}
+@@ -834,6 +870,18 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)
+ 		pipe->completeRequest(request);
+ }
+ 
++void SimpleCameraData::ispStatsReady([[maybe_unused]] int dummy)
++{
++	swIsp_->processStats(sensor_->getControls({ V4L2_CID_ANALOGUE_GAIN,
++						    V4L2_CID_EXPOSURE }));
++}
++
++void SimpleCameraData::setSensorControls(const ControlList &sensorControls)
++{
++	ControlList ctrls(sensorControls);
++	sensor_->setControls(&ctrls);
++}
++
+ /* Retrieve all source pads connected to a sink pad through active routes. */
+ std::vector<const MediaPad *> SimpleCameraData::routedSourcePads(MediaPad *sink)
+ {
+@@ -1016,8 +1064,10 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate()
+ 		/* Set the stride, frameSize and bufferCount. */
+ 		if (needConversion_) {
+ 			std::tie(cfg.stride, cfg.frameSize) =
+-				data_->converter_->strideAndFrameSize(cfg.pixelFormat,
+-								      cfg.size);
++				(data_->converter_) ? data_->converter_->strideAndFrameSize(cfg.pixelFormat,
++											    cfg.size)
++						    : data_->swIsp_->strideAndFrameSize(cfg.pixelFormat,
++											cfg.size);
+ 			if (cfg.stride == 0)
+ 				return Invalid;
+ 		} else {
+@@ -1180,7 +1230,9 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)
+ 	inputCfg.stride = captureFormat.planes[0].bpl;
+ 	inputCfg.bufferCount = kNumInternalBuffers;
+ 
+-	return data->converter_->configure(inputCfg, outputCfgs);
++	return (data->converter_) ? data->converter_->configure(inputCfg, outputCfgs)
++				  : data->swIsp_->configure(inputCfg, outputCfgs,
++							    data->sensor_->controls());
+ }
+ 
+ int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream,
+@@ -1194,8 +1246,10 @@ int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream,
+ 	 * whether the converter is used or not.
+ 	 */
+ 	if (data->useConversion_)
+-		return data->converter_->exportBuffers(data->streamIndex(stream),
+-						       count, buffers);
++		return (data->converter_) ? data->converter_->exportBuffers(data->streamIndex(stream),
++									    count, buffers)
++					  : data->swIsp_->exportBuffers(data->streamIndex(stream),
++									count, buffers);
+ 	else
+ 		return data->video_->exportBuffers(count, buffers);
+ }
+@@ -1240,10 +1294,18 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL
+ 	}
+ 
+ 	if (data->useConversion_) {
+-		ret = data->converter_->start();
+-		if (ret < 0) {
+-			stop(camera);
+-			return ret;
++		if (data->converter_) {
++			ret = data->converter_->start();
++			if (ret < 0) {
++				stop(camera);
++				return ret;
++			}
++		} else if (data->swIsp_) {
++			ret = data->swIsp_->start();
++			if (ret < 0) {
++				stop(camera);
++				return ret;
++			}
+ 		}
+ 
+ 		/* Queue all internal buffers for capture. */
+@@ -1259,8 +1321,13 @@ void SimplePipelineHandler::stopDevice(Camera *camera)
+ 	SimpleCameraData *data = cameraData(camera);
+ 	V4L2VideoDevice *video = data->video_;
+ 
+-	if (data->useConversion_)
+-		data->converter_->stop();
++	if (data->useConversion_) {
++		if (data->converter_)
++			data->converter_->stop();
++		else if (data->swIsp_) {
++			data->swIsp_->stop();
++		}
++	}
+ 
+ 	video->streamOff();
+ 	video->releaseBuffers();
+-- 
+2.43.0
+