feat(users/flokli/ipu6-softisp): init
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>
This commit is contained in:
parent
b38be028d9
commit
af9a8d372b
27 changed files with 5847 additions and 0 deletions
|
|
@ -0,0 +1,354 @@
|
|||
From 3fa62a8e2f34c9794ba67e2565db8fef22938fa4 Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Konovalov <andrey.konovalov@linaro.org>
|
||||
Date: Sun, 22 Oct 2023 17:49:32 +0300
|
||||
Subject: [PATCH 06/25] libcamera: introduce SoftwareIsp class
|
||||
|
||||
Doxygen documentation by Dennis Bonke.
|
||||
|
||||
Co-authored-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>
|
||||
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
|
||||
Tested-by: Pavel Machek <pavel@ucw.cz>
|
||||
---
|
||||
include/libcamera/internal/meson.build | 1 +
|
||||
include/libcamera/internal/software_isp.h | 231 ++++++++++++++++++++++
|
||||
src/libcamera/meson.build | 1 +
|
||||
src/libcamera/software_isp.cpp | 62 ++++++
|
||||
4 files changed, 295 insertions(+)
|
||||
create mode 100644 include/libcamera/internal/software_isp.h
|
||||
create mode 100644 src/libcamera/software_isp.cpp
|
||||
|
||||
diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build
|
||||
index 5807dfd9..1325941d 100644
|
||||
--- a/include/libcamera/internal/meson.build
|
||||
+++ b/include/libcamera/internal/meson.build
|
||||
@@ -40,6 +40,7 @@ libcamera_internal_headers = files([
|
||||
'pub_key.h',
|
||||
'request.h',
|
||||
'shared_mem_object.h',
|
||||
+ 'software_isp.h',
|
||||
'source_paths.h',
|
||||
'sysfs.h',
|
||||
'v4l2_device.h',
|
||||
diff --git a/include/libcamera/internal/software_isp.h b/include/libcamera/internal/software_isp.h
|
||||
new file mode 100644
|
||||
index 00000000..42ff48ec
|
||||
--- /dev/null
|
||||
+++ b/include/libcamera/internal/software_isp.h
|
||||
@@ -0,0 +1,231 @@
|
||||
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
+/*
|
||||
+ * Copyright (C) 2023, Linaro Ltd
|
||||
+ *
|
||||
+ * software_isp.h - Interface for a software implementation of an ISP
|
||||
+ */
|
||||
+
|
||||
+#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/geometry.h>
|
||||
+
|
||||
+#include "libcamera/internal/pipeline_handler.h"
|
||||
+
|
||||
+namespace libcamera {
|
||||
+
|
||||
+class FrameBuffer;
|
||||
+class PixelFormat;
|
||||
+struct StreamConfiguration;
|
||||
+
|
||||
+LOG_DECLARE_CATEGORY(SoftwareIsp)
|
||||
+
|
||||
+/**
|
||||
+ * \brief Base class for the Software ISP.
|
||||
+ *
|
||||
+ * Base class of the SoftwareIsp interface.
|
||||
+ */
|
||||
+class SoftwareIsp
|
||||
+{
|
||||
+public:
|
||||
+ /**
|
||||
+ * \brief Constructor for the SoftwareIsp object.
|
||||
+ * \param[in] pipe The pipeline handler in use.
|
||||
+ * \param[in] sensorControls The sensor controls.
|
||||
+ */
|
||||
+ SoftwareIsp(PipelineHandler *pipe, const ControlInfoMap &sensorControls);
|
||||
+ virtual ~SoftwareIsp();
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Load a configuration from a file.
|
||||
+ * \param[in] filename The file to load from.
|
||||
+ *
|
||||
+ * \return 0 on success.
|
||||
+ */
|
||||
+ virtual int loadConfiguration(const std::string &filename) = 0;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Gets if there is a valid debayer object.
|
||||
+ *
|
||||
+ * \returns true if there is, false otherwise.
|
||||
+ */
|
||||
+ virtual bool isValid() const = 0;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Get the supported output formats.
|
||||
+ * \param[in] input The input format.
|
||||
+ *
|
||||
+ * \return all supported output formats or an empty vector if there are none.
|
||||
+ */
|
||||
+ virtual std::vector<PixelFormat> formats(PixelFormat input) = 0;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Get the supported output sizes for the given input format and size.
|
||||
+ * \param[in] inputFormat The input format.
|
||||
+ * \param[in] inputSize The input size.
|
||||
+ *
|
||||
+ * \return The valid size ranges or an empty range if there are none.
|
||||
+ */
|
||||
+ virtual SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) = 0;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Get the stride and the frame size.
|
||||
+ * \param[in] pixelFormat The output format.
|
||||
+ * \param[in] size The output size.
|
||||
+ *
|
||||
+ * \return a tuple of the stride and the frame size, or a tuple with 0,0 if there is no valid output config.
|
||||
+ */
|
||||
+ virtual std::tuple<unsigned int, unsigned int>
|
||||
+ strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size) = 0;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Configure the SwIspSimple object according to the passed in parameters.
|
||||
+ * \param[in] inputCfg The input configuration.
|
||||
+ * \param[in] outputCfgs The output configurations.
|
||||
+ * \param[in] sensorControls The sensor controls.
|
||||
+ *
|
||||
+ * \return 0 on success, a negative errno on failure.
|
||||
+ */
|
||||
+ virtual int configure(const StreamConfiguration &inputCfg,
|
||||
+ const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs,
|
||||
+ const ControlInfoMap &sensorControls) = 0;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Exports the buffers for use in processing.
|
||||
+ * \param[in] output The number of outputs requested.
|
||||
+ * \param[in] count The number of planes.
|
||||
+ * \param[out] buffers The exported buffers.
|
||||
+ *
|
||||
+ * \return count when successful, a negative return value if an error occurred.
|
||||
+ */
|
||||
+ virtual int exportBuffers(unsigned int output, unsigned int count,
|
||||
+ std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Starts the Software ISP worker.
|
||||
+ *
|
||||
+ * \return 0 on success, any other value indicates an error.
|
||||
+ */
|
||||
+ virtual int start() = 0;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Stops the Software ISP worker.
|
||||
+ */
|
||||
+ virtual void stop() = 0;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Queues buffers for processing.
|
||||
+ * \param[in] input The input framebuffer.
|
||||
+ * \param[in] outputs The output framebuffers.
|
||||
+ *
|
||||
+ * \return 0 on success, a negative errno on failure
|
||||
+ */
|
||||
+ virtual int queueBuffers(FrameBuffer *input,
|
||||
+ const std::map<unsigned int, FrameBuffer *> &outputs) = 0;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Process the statistics gathered.
|
||||
+ * \param[in] sensorControls The sensor controls.
|
||||
+ */
|
||||
+ virtual void processStats(const ControlList &sensorControls) = 0; // rather merge with queueBuffers()?
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Get the signal for when the sensor controls are set.
|
||||
+ *
|
||||
+ * \return The control list of the sensor controls.
|
||||
+ */
|
||||
+ virtual Signal<const ControlList &> &getSignalSetSensorControls() = 0;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Signals that the input buffer is ready.
|
||||
+ */
|
||||
+ Signal<FrameBuffer *> inputBufferReady;
|
||||
+ /**
|
||||
+ * \brief Signals that the output buffer is ready.
|
||||
+ */
|
||||
+ Signal<FrameBuffer *> outputBufferReady;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Signals that the ISP stats are ready.
|
||||
+ *
|
||||
+ * The int parameter isn't actually used.
|
||||
+ */
|
||||
+ Signal<int> ispStatsReady;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * \brief Base class for the Software ISP Factory.
|
||||
+ *
|
||||
+ * Base class of the SoftwareIsp Factory.
|
||||
+ */
|
||||
+class SoftwareIspFactoryBase
|
||||
+{
|
||||
+public:
|
||||
+ SoftwareIspFactoryBase();
|
||||
+ virtual ~SoftwareIspFactoryBase() = default;
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Creates a SoftwareIsp object.
|
||||
+ * \param[in] pipe The pipeline handler in use.
|
||||
+ * \param[in] sensorControls The sensor controls.
|
||||
+ *
|
||||
+ * \return An unique pointer to the created SoftwareIsp object.
|
||||
+ */
|
||||
+ static std::unique_ptr<SoftwareIsp> create(PipelineHandler *pipe,
|
||||
+ const ControlInfoMap &sensorControls);
|
||||
+ /**
|
||||
+ * \brief Gives back a pointer to the factory.
|
||||
+ *
|
||||
+ * \return A static pointer to the factory instance.
|
||||
+ */
|
||||
+ static SoftwareIspFactoryBase *&factory();
|
||||
+
|
||||
+private:
|
||||
+ LIBCAMERA_DISABLE_COPY_AND_MOVE(SoftwareIspFactoryBase)
|
||||
+
|
||||
+ static void registerType(SoftwareIspFactoryBase *factory);
|
||||
+ virtual std::unique_ptr<SoftwareIsp> createInstance(PipelineHandler *pipe,
|
||||
+ const ControlInfoMap &sensorControls) const = 0;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * \brief Implementation for the Software ISP Factory.
|
||||
+ */
|
||||
+template<typename _SoftwareIsp>
|
||||
+class SoftwareIspFactory : public SoftwareIspFactoryBase
|
||||
+{
|
||||
+public:
|
||||
+ SoftwareIspFactory()
|
||||
+ : SoftwareIspFactoryBase()
|
||||
+ {
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * \brief Creates an instance of a SoftwareIsp object.
|
||||
+ * \param[in] pipe The pipeline handler in use.
|
||||
+ * \param[in] sensorControls The sensor controls.
|
||||
+ *
|
||||
+ * \return An unique pointer to the created SoftwareIsp object.
|
||||
+ */
|
||||
+ std::unique_ptr<SoftwareIsp> createInstance(PipelineHandler *pipe,
|
||||
+ const ControlInfoMap &sensorControls) const override
|
||||
+ {
|
||||
+ return std::make_unique<_SoftwareIsp>(pipe, sensorControls);
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+#define REGISTER_SOFTWAREISP(softwareIsp) \
|
||||
+ static SoftwareIspFactory<softwareIsp> global_##softwareIsp##Factory;
|
||||
+
|
||||
+} /* namespace libcamera */
|
||||
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
|
||||
index 3c5e43df..86494663 100644
|
||||
--- a/src/libcamera/meson.build
|
||||
+++ b/src/libcamera/meson.build
|
||||
@@ -41,6 +41,7 @@ libcamera_sources = files([
|
||||
'process.cpp',
|
||||
'pub_key.cpp',
|
||||
'request.cpp',
|
||||
+ 'software_isp.cpp',
|
||||
'source_paths.cpp',
|
||||
'stream.cpp',
|
||||
'sysfs.cpp',
|
||||
diff --git a/src/libcamera/software_isp.cpp b/src/libcamera/software_isp.cpp
|
||||
new file mode 100644
|
||||
index 00000000..2ff97d70
|
||||
--- /dev/null
|
||||
+++ b/src/libcamera/software_isp.cpp
|
||||
@@ -0,0 +1,62 @@
|
||||
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
+/*
|
||||
+ * Copyright (C) 2023, Linaro Ltd
|
||||
+ *
|
||||
+ * software_isp.cpp - Interface for a software implementation of an ISP
|
||||
+ */
|
||||
+
|
||||
+#include "libcamera/internal/software_isp.h"
|
||||
+
|
||||
+#include <libcamera/base/log.h>
|
||||
+
|
||||
+namespace libcamera {
|
||||
+
|
||||
+LOG_DEFINE_CATEGORY(SoftwareIsp)
|
||||
+
|
||||
+SoftwareIsp::SoftwareIsp([[maybe_unused]] PipelineHandler *pipe,
|
||||
+ [[maybe_unused]] const ControlInfoMap &sensorControls)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+SoftwareIsp::~SoftwareIsp()
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+/* SoftwareIspFactoryBase */
|
||||
+
|
||||
+SoftwareIspFactoryBase::SoftwareIspFactoryBase()
|
||||
+{
|
||||
+ registerType(this);
|
||||
+}
|
||||
+
|
||||
+void SoftwareIspFactoryBase::registerType(SoftwareIspFactoryBase *factory)
|
||||
+{
|
||||
+ SoftwareIspFactoryBase *®istered =
|
||||
+ SoftwareIspFactoryBase::factory();
|
||||
+
|
||||
+ ASSERT(!registered && factory);
|
||||
+ registered = factory;
|
||||
+}
|
||||
+
|
||||
+SoftwareIspFactoryBase *&SoftwareIspFactoryBase::factory()
|
||||
+{
|
||||
+ static SoftwareIspFactoryBase *factory;
|
||||
+ return factory;
|
||||
+}
|
||||
+
|
||||
+std::unique_ptr<SoftwareIsp>
|
||||
+SoftwareIspFactoryBase::create(PipelineHandler *pipe,
|
||||
+ const ControlInfoMap &sensorControls)
|
||||
+{
|
||||
+ SoftwareIspFactoryBase *factory = SoftwareIspFactoryBase::factory();
|
||||
+ if (!factory)
|
||||
+ return nullptr;
|
||||
+
|
||||
+ std::unique_ptr<SoftwareIsp> swIsp = factory->createInstance(pipe, sensorControls);
|
||||
+ if (swIsp->isValid())
|
||||
+ return swIsp;
|
||||
+
|
||||
+ return nullptr;
|
||||
+}
|
||||
+
|
||||
+} /* namespace libcamera */
|
||||
--
|
||||
2.43.0
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue