about summary refs log tree commit diff
path: root/users/flokli/ipu6-softisp/libcamera/0010-libcamera-introduce-SoftwareIsp.patch
diff options
context:
space:
mode:
Diffstat (limited to 'users/flokli/ipu6-softisp/libcamera/0010-libcamera-introduce-SoftwareIsp.patch')
-rw-r--r--users/flokli/ipu6-softisp/libcamera/0010-libcamera-introduce-SoftwareIsp.patch507
1 files changed, 0 insertions, 507 deletions
diff --git a/users/flokli/ipu6-softisp/libcamera/0010-libcamera-introduce-SoftwareIsp.patch b/users/flokli/ipu6-softisp/libcamera/0010-libcamera-introduce-SoftwareIsp.patch
deleted file mode 100644
index 9f2d66c2f8b6..000000000000
--- a/users/flokli/ipu6-softisp/libcamera/0010-libcamera-introduce-SoftwareIsp.patch
+++ /dev/null
@@ -1,507 +0,0 @@
-From ad41ea12fe4b8ca0ace20781c775a63ed0d66f4c Mon Sep 17 00:00:00 2001
-From: Andrey Konovalov <andrey.konovalov@linaro.org>
-Date: Mon, 11 Mar 2024 15:15:14 +0100
-Subject: [PATCH 10/21] libcamera: introduce SoftwareIsp
-
-Doxygen documentation by Dennis Bonke.
-
-Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
-Tested-by: Pavel Machek <pavel@ucw.cz>
-Reviewed-by: Pavel Machek <pavel@ucw.cz>
-Co-developed-by: Dennis Bonke <admin@dennisbonke.com>
-Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
-Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- .../internal/software_isp/meson.build         |   1 +
- .../internal/software_isp/software_isp.h      |  98 +++++
- src/libcamera/software_isp/meson.build        |   1 +
- src/libcamera/software_isp/software_isp.cpp   | 349 ++++++++++++++++++
- 4 files changed, 449 insertions(+)
- create mode 100644 include/libcamera/internal/software_isp/software_isp.h
- create mode 100644 src/libcamera/software_isp/software_isp.cpp
-
-diff --git a/include/libcamera/internal/software_isp/meson.build b/include/libcamera/internal/software_isp/meson.build
-index a620e16d..508ddddc 100644
---- a/include/libcamera/internal/software_isp/meson.build
-+++ b/include/libcamera/internal/software_isp/meson.build
-@@ -2,5 +2,6 @@
- 
- libcamera_internal_headers += files([
-     'debayer_params.h',
-+    'software_isp.h',
-     'swisp_stats.h',
- ])
-diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h
-new file mode 100644
-index 00000000..8d25e979
---- /dev/null
-+++ b/include/libcamera/internal/software_isp/software_isp.h
-@@ -0,0 +1,98 @@
-+/* SPDX-License-Identifier: LGPL-2.1-or-later */
-+/*
-+ * Copyright (C) 2023, Linaro Ltd
-+ *
-+ * software_isp.h - Simple software ISP implementation
-+ */
-+
-+#pragma once
-+
-+#include <functional>
-+#include <initializer_list>
-+#include <map>
-+#include <memory>
-+#include <string>
-+#include <tuple>
-+#include <vector>
-+
-+#include <libcamera/base/class.h>
-+#include <libcamera/base/log.h>
-+#include <libcamera/base/signal.h>
-+#include <libcamera/base/thread.h>
-+
-+#include <libcamera/geometry.h>
-+#include <libcamera/pixel_format.h>
-+
-+#include <libcamera/ipa/soft_ipa_interface.h>
-+#include <libcamera/ipa/soft_ipa_proxy.h>
-+
-+#include "libcamera/internal/dma_heaps.h"
-+#include "libcamera/internal/pipeline_handler.h"
-+#include "libcamera/internal/shared_mem_object.h"
-+#include "libcamera/internal/software_isp/debayer_params.h"
-+
-+namespace libcamera {
-+
-+class DebayerCpu;
-+class FrameBuffer;
-+class PixelFormat;
-+struct StreamConfiguration;
-+
-+LOG_DECLARE_CATEGORY(SoftwareIsp)
-+
-+class SoftwareIsp
-+{
-+public:
-+	SoftwareIsp(PipelineHandler *pipe, const ControlInfoMap &sensorControls);
-+	~SoftwareIsp();
-+
-+	int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; }
-+
-+	bool isValid() const;
-+
-+	std::vector<PixelFormat> formats(PixelFormat input);
-+
-+	SizeRange sizes(PixelFormat inputFormat, const Size &inputSize);
-+
-+	std::tuple<unsigned int, unsigned int>
-+	strideAndFrameSize(const PixelFormat &outputFormat, const Size &size);
-+
-+	int configure(const StreamConfiguration &inputCfg,
-+		      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs,
-+		      const ControlInfoMap &sensorControls);
-+
-+	int exportBuffers(unsigned int output, unsigned int count,
-+			  std::vector<std::unique_ptr<FrameBuffer>> *buffers);
-+
-+	void processStats(const ControlList &sensorControls);
-+
-+	int start();
-+	void stop();
-+
-+	int queueBuffers(FrameBuffer *input,
-+			 const std::map<unsigned int, FrameBuffer *> &outputs);
-+
-+	void process(FrameBuffer *input, FrameBuffer *output);
-+
-+	Signal<FrameBuffer *> inputBufferReady;
-+	Signal<FrameBuffer *> outputBufferReady;
-+	Signal<int> ispStatsReady;
-+	Signal<const ControlList &> setSensorControls;
-+
-+private:
-+	void saveIspParams(int dummy);
-+	void setSensorCtrls(const ControlList &sensorControls);
-+	void statsReady(int dummy);
-+	void inputReady(FrameBuffer *input);
-+	void outputReady(FrameBuffer *output);
-+
-+	std::unique_ptr<DebayerCpu> debayer_;
-+	Thread ispWorkerThread_;
-+	SharedMemObject<DebayerParams> sharedParams_;
-+	DebayerParams debayerParams_;
-+	DmaHeap dmaHeap_;
-+
-+	std::unique_ptr<ipa::soft::IPAProxySoft> ipa_;
-+};
-+
-+} /* namespace libcamera */
-diff --git a/src/libcamera/software_isp/meson.build b/src/libcamera/software_isp/meson.build
-index 71b46539..e9266e54 100644
---- a/src/libcamera/software_isp/meson.build
-+++ b/src/libcamera/software_isp/meson.build
-@@ -10,5 +10,6 @@ endif
- libcamera_sources += files([
-     'debayer.cpp',
-     'debayer_cpu.cpp',
-+    'software_isp.cpp',
-     'swstats_cpu.cpp',
- ])
-diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
-new file mode 100644
-index 00000000..388b4496
---- /dev/null
-+++ b/src/libcamera/software_isp/software_isp.cpp
-@@ -0,0 +1,349 @@
-+/* SPDX-License-Identifier: LGPL-2.1-or-later */
-+/*
-+ * Copyright (C) 2023, Linaro Ltd
-+ *
-+ * software_isp.cpp - Simple software ISP implementation
-+ */
-+
-+#include "libcamera/internal/software_isp/software_isp.h"
-+
-+#include <sys/mman.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+
-+#include <libcamera/formats.h>
-+#include <libcamera/stream.h>
-+
-+#include "libcamera/internal/bayer_format.h"
-+#include "libcamera/internal/framebuffer.h"
-+#include "libcamera/internal/ipa_manager.h"
-+#include "libcamera/internal/mapped_framebuffer.h"
-+
-+#include "debayer_cpu.h"
-+
-+/**
-+ * \file software_isp.cpp
-+ * \brief Simple software ISP implementation
-+ */
-+
-+namespace libcamera {
-+
-+LOG_DEFINE_CATEGORY(SoftwareIsp)
-+
-+/**
-+ * \class SoftwareIsp
-+ * \brief Class for the Software ISP
-+ */
-+
-+/**
-+ * \var SoftwareIsp::inputBufferReady
-+ * \brief A signal emitted when the input frame buffer completes
-+ */
-+
-+/**
-+ * \var SoftwareIsp::outputBufferReady
-+ * \brief A signal emitted when the output frame buffer completes
-+ */
-+
-+/**
-+ * \var SoftwareIsp::ispStatsReady
-+ * \brief A signal emitted when the statistics for IPA are ready
-+ *
-+ * The int parameter isn't actually used.
-+ */
-+
-+/**
-+ * \var SoftwareIsp::setSensorControls
-+ * \brief A signal emitted when the values to write to the sensor controls are ready
-+ */
-+
-+/**
-+ * \brief Constructs SoftwareIsp object
-+ * \param[in] pipe The pipeline handler in use
-+ * \param[in] sensorControls ControlInfoMap describing the controls supported by the sensor
-+ */
-+SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const ControlInfoMap &sensorControls)
-+	: debayer_(nullptr),
-+	  debayerParams_{ DebayerParams::kGain10, DebayerParams::kGain10, DebayerParams::kGain10, 0.5f },
-+	  dmaHeap_(DmaHeap::DmaHeapFlag::Cma | DmaHeap::DmaHeapFlag::System)
-+{
-+	if (!dmaHeap_.isValid()) {
-+		LOG(SoftwareIsp, Error) << "Failed to create DmaHeap object";
-+		return;
-+	}
-+
-+	sharedParams_ = SharedMemObject<DebayerParams>("softIsp_params");
-+	if (!sharedParams_) {
-+		LOG(SoftwareIsp, Error) << "Failed to create shared memory for parameters";
-+		return;
-+	}
-+
-+	auto stats = std::make_unique<SwStatsCpu>();
-+	if (!stats->isValid()) {
-+		LOG(SoftwareIsp, Error) << "Failed to create SwStatsCpu object";
-+		return;
-+	}
-+	stats->statsReady.connect(this, &SoftwareIsp::statsReady);
-+
-+	debayer_ = std::make_unique<DebayerCpu>(std::move(stats));
-+	debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady);
-+	debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady);
-+
-+	ipa_ = IPAManager::createIPA<ipa::soft::IPAProxySoft>(pipe, 0, 0);
-+	if (!ipa_) {
-+		LOG(SoftwareIsp, Error)
-+			<< "Creating IPA for software ISP failed";
-+		debayer_.reset();
-+		return;
-+	}
-+
-+	int ret = ipa_->init(IPASettings{ "No cfg file", "No sensor model" },
-+			     debayer_->getStatsFD(),
-+			     sharedParams_.fd(),
-+			     sensorControls);
-+	if (ret) {
-+		LOG(SoftwareIsp, Error) << "IPA init failed";
-+		debayer_.reset();
-+		return;
-+	}
-+
-+	ipa_->setIspParams.connect(this, &SoftwareIsp::saveIspParams);
-+	ipa_->setSensorControls.connect(this, &SoftwareIsp::setSensorCtrls);
-+
-+	debayer_->moveToThread(&ispWorkerThread_);
-+}
-+
-+SoftwareIsp::~SoftwareIsp()
-+{
-+	/* make sure to destroy the DebayerCpu before the ispWorkerThread_ is gone */
-+	debayer_.reset();
-+}
-+
-+/**
-+ * \fn int SoftwareIsp::loadConfiguration([[maybe_unused]] const std::string &filename)
-+ * \brief Load a configuration from a file
-+ * \param[in] filename The file to load the configuration data from
-+ *
-+ * Currently is a stub doing nothing and always returning "success".
-+ *
-+ * \return 0 on success
-+ */
-+
-+/**
-+ * \brief Process the statistics gathered
-+ * \param[in] sensorControls The sensor controls
-+ *
-+ * Requests the IPA to calculate new parameters for ISP and new control
-+ * values for the sensor.
-+ */
-+void SoftwareIsp::processStats(const ControlList &sensorControls)
-+{
-+	ASSERT(ipa_);
-+	ipa_->processStats(sensorControls);
-+}
-+
-+/**
-+ * \brief Check the validity of Software Isp object
-+ * \return True if Software Isp is valid, false otherwise
-+ */
-+bool SoftwareIsp::isValid() const
-+{
-+	return !!debayer_;
-+}
-+
-+/**
-+  * \brief Get the output formats supported for the given input format
-+  * \param[in] inputFormat The input format
-+  * \return All the supported output formats or an empty vector if there are none
-+  */
-+std::vector<PixelFormat> SoftwareIsp::formats(PixelFormat inputFormat)
-+{
-+	ASSERT(debayer_ != nullptr);
-+
-+	return debayer_->formats(inputFormat);
-+}
-+
-+/**
-+ * \brief Get the supported output sizes for the given input format and size
-+ * \param[in] inputFormat The input format
-+ * \param[in] inputSize The input frame size
-+ * \return The valid size range or an empty range if there are none
-+ */
-+SizeRange SoftwareIsp::sizes(PixelFormat inputFormat, const Size &inputSize)
-+{
-+	ASSERT(debayer_ != nullptr);
-+
-+	return debayer_->sizes(inputFormat, inputSize);
-+}
-+
-+/**
-+ * Get the output stride and the frame size in bytes for the given output format and size
-+ * \param[in] outputFormat The output format
-+ * \param[in] size The output size (width and height in pixels)
-+ * \return A tuple of the stride and the frame size in bytes, or a tuple of 0,0
-+ * if there is no valid output config
-+ */
-+std::tuple<unsigned int, unsigned int>
-+SoftwareIsp::strideAndFrameSize(const PixelFormat &outputFormat, const Size &size)
-+{
-+	ASSERT(debayer_ != nullptr);
-+
-+	return debayer_->strideAndFrameSize(outputFormat, size);
-+}
-+
-+/**
-+ * \brief Configure the SoftwareIsp object according to the passed in parameters
-+ * \param[in] inputCfg The input configuration
-+ * \param[in] outputCfgs The output configurations
-+ * \param[in] sensorControls ControlInfoMap of the controls supported by the sensor
-+ * \return 0 on success, a negative errno on failure
-+ */
-+int SoftwareIsp::configure(const StreamConfiguration &inputCfg,
-+			   const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs,
-+			   const ControlInfoMap &sensorControls)
-+{
-+	ASSERT(ipa_ != nullptr && debayer_ != nullptr);
-+
-+	int ret = ipa_->configure(sensorControls);
-+	if (ret < 0)
-+		return ret;
-+
-+	return debayer_->configure(inputCfg, outputCfgs);
-+}
-+
-+/**
-+ * \brief Export the buffers from the Software ISP
-+ * \param[in] output Output stream index exporting the buffers
-+ * \param[in] count Number of buffers to allocate
-+ * \param[out] buffers Vector to store the allocated buffers
-+ * \return The number of allocated buffers on success or a negative error code
-+ * otherwise
-+ */
-+int SoftwareIsp::exportBuffers(unsigned int output, unsigned int count,
-+			       std::vector<std::unique_ptr<FrameBuffer>> *buffers)
-+{
-+	ASSERT(debayer_ != nullptr);
-+
-+	/* single output for now */
-+	if (output >= 1)
-+		return -EINVAL;
-+
-+	for (unsigned int i = 0; i < count; i++) {
-+		const std::string name = "frame-" + std::to_string(i);
-+		const size_t frameSize = debayer_->frameSize();
-+
-+		FrameBuffer::Plane outPlane;
-+		outPlane.fd = SharedFD(dmaHeap_.alloc(name.c_str(), frameSize));
-+		if (!outPlane.fd.isValid()) {
-+			LOG(SoftwareIsp, Error)
-+				<< "failed to allocate a dma_buf";
-+			return -ENOMEM;
-+		}
-+		outPlane.offset = 0;
-+		outPlane.length = frameSize;
-+
-+		std::vector<FrameBuffer::Plane> planes{ outPlane };
-+		buffers->emplace_back(std::make_unique<FrameBuffer>(std::move(planes)));
-+	}
-+
-+	return count;
-+}
-+
-+/**
-+ * \brief Queue buffers to Software ISP
-+ * \param[in] input The input framebuffer
-+ * \param[in] outputs The container holding the output stream indexes and
-+ * their respective frame buffer outputs
-+ * \return 0 on success, a negative errno on failure
-+ */
-+int SoftwareIsp::queueBuffers(FrameBuffer *input,
-+			      const std::map<unsigned int, FrameBuffer *> &outputs)
-+{
-+	unsigned int mask = 0;
-+
-+	/*
-+	 * Validate the outputs as a sanity check: at least one output is
-+	 * required, all outputs must reference a valid stream and no two
-+	 * outputs can reference the same stream.
-+	 */
-+	if (outputs.empty())
-+		return -EINVAL;
-+
-+	for (auto [index, buffer] : outputs) {
-+		if (!buffer)
-+			return -EINVAL;
-+		if (index >= 1) /* only single stream atm */
-+			return -EINVAL;
-+		if (mask & (1 << index))
-+			return -EINVAL;
-+
-+		mask |= 1 << index;
-+	}
-+
-+	process(input, outputs.at(0));
-+
-+	return 0;
-+}
-+
-+/**
-+ * \brief Starts the Software ISP streaming operation
-+ * \return 0 on success, any other value indicates an error
-+ */
-+int SoftwareIsp::start()
-+{
-+	int ret = ipa_->start();
-+	if (ret)
-+		return ret;
-+
-+	ispWorkerThread_.start();
-+	return 0;
-+}
-+
-+/**
-+ * \brief Stops the Software ISP streaming operation
-+ */
-+void SoftwareIsp::stop()
-+{
-+	ispWorkerThread_.exit();
-+	ispWorkerThread_.wait();
-+
-+	ipa_->stop();
-+}
-+
-+/**
-+ * \brief Passes the input framebuffer to the ISP worker to process
-+ * \param[in] input The input framebuffer
-+ * \param[out] output The framebuffer to write the processed frame to
-+ */
-+void SoftwareIsp::process(FrameBuffer *input, FrameBuffer *output)
-+{
-+	debayer_->invokeMethod(&DebayerCpu::process,
-+			       ConnectionTypeQueued, input, output, debayerParams_);
-+}
-+
-+void SoftwareIsp::saveIspParams([[maybe_unused]] int dummy)
-+{
-+	debayerParams_ = *sharedParams_;
-+}
-+
-+void SoftwareIsp::setSensorCtrls(const ControlList &sensorControls)
-+{
-+	setSensorControls.emit(sensorControls);
-+}
-+
-+void SoftwareIsp::statsReady(int dummy)
-+{
-+	ispStatsReady.emit(dummy);
-+}
-+
-+void SoftwareIsp::inputReady(FrameBuffer *input)
-+{
-+	inputBufferReady.emit(input);
-+}
-+
-+void SoftwareIsp::outputReady(FrameBuffer *output)
-+{
-+	outputBufferReady.emit(output);
-+}
-+
-+} /* namespace libcamera */
--- 
-2.43.2
-