@@ -38,6 +38,7 @@ libcamera_internal_headers = files([
'process.h',
'pub_key.h',
'request.h',
+ 'software_isp.h',
'source_paths.h',
'sysfs.h',
'v4l2_device.h',
new file mode 100644
@@ -0,0 +1,106 @@
+/* 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/signal.h>
+
+#include <libcamera/geometry.h>
+
+#include "libcamera/internal/pipeline_handler.h"
+
+namespace libcamera {
+
+class FrameBuffer;
+class PixelFormat;
+struct StreamConfiguration;
+
+class SoftwareIsp
+{
+public:
+ SoftwareIsp(PipelineHandler *pipe, const ControlInfoMap &sensorControls);
+ virtual ~SoftwareIsp();
+
+ virtual int loadConfiguration(const std::string &filename) = 0;
+
+ virtual bool isValid() const = 0;
+
+ virtual std::vector<PixelFormat> formats(PixelFormat input) = 0;
+ virtual SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) = 0;
+
+ virtual std::tuple<unsigned int, unsigned int>
+ strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size) = 0;
+
+ virtual int configure(const StreamConfiguration &inputCfg,
+ const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs) = 0;
+ virtual int exportBuffers(unsigned int output, unsigned int count,
+ std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;
+
+ virtual int start() = 0;
+ virtual void stop() = 0;
+
+ virtual int queueBuffers(FrameBuffer *input,
+ const std::map<unsigned int, FrameBuffer *> &outputs) = 0;
+
+ virtual void processStats(const ControlList &sensorControls) = 0; // rather merge with queueBuffers()?
+
+ virtual Signal<const ControlList &> &getSignalSetSensorControls() = 0;
+
+ Signal<FrameBuffer *> inputBufferReady;
+ Signal<FrameBuffer *> outputBufferReady;
+
+ /* The int parameter isn't actually used */
+ Signal<int> ispStatsReady;
+};
+
+class SoftwareIspFactoryBase
+{
+public:
+ SoftwareIspFactoryBase();
+ virtual ~SoftwareIspFactoryBase() = default;
+
+ static std::unique_ptr<SoftwareIsp> create(PipelineHandler *pipe,
+ const ControlInfoMap &sensorControls);
+ 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;
+};
+
+template<typename _SoftwareIsp>
+class SoftwareIspFactory : public SoftwareIspFactoryBase
+{
+public:
+ SoftwareIspFactory()
+ : SoftwareIspFactoryBase()
+ {
+ }
+
+ 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 */
@@ -40,6 +40,7 @@ libcamera_sources = files([
'process.cpp',
'pub_key.cpp',
'request.cpp',
+ 'software_isp.cpp',
'source_paths.cpp',
'stream.cpp',
'sysfs.cpp',
new file mode 100644
@@ -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 */
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> --- include/libcamera/internal/meson.build | 1 + include/libcamera/internal/software_isp.h | 106 ++++++++++++++++++++++ src/libcamera/meson.build | 1 + src/libcamera/software_isp.cpp | 62 +++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 include/libcamera/internal/software_isp.h create mode 100644 src/libcamera/software_isp.cpp