[libcamera-devel] [PATCH v2 06/18] libcamera: introduce SoftwareIsp class
Jacopo Mondi
jacopo.mondi at ideasonboard.com
Wed Jan 31 12:56:41 CET 2024
Hi Andrey, a few drive-by comments
On Sat, Jan 13, 2024 at 03:22:06PM +0100, Hans de Goede via libcamera-devel wrote:
> From: Andrey Konovalov <andrey.konovalov at linaro.org>
>
> Doxygen documentation by Dennis Bonke.
>
> Co-authored-by: Dennis Bonke <admin at dennisbonke.com>
> Signed-off-by: Dennis Bonke <admin at dennisbonke.com>
> Signed-off-by: Andrey Konovalov <andrey.konovalov at linaro.org>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> Tested-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org> # sc8280xp Lenovo x13s
> Tested-by: Pavel Machek <pavel at 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)
Do you need it here ? (this applies to the log.h inclusion)
> +
> +/**
> + * \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;
ControlInfoMap should be forward declared ? (as well as ControlList
below, so you could possibily include controls.h)
> +
> + /**
> + * \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;
Let's review the interface once seen in ation ;)
So far it seems it could be realized by extending the existing
Converter interface, we'll see..
> +};
> +
> +/**
> + * \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
>
More information about the libcamera-devel
mailing list