Message ID | 20240113142218.28063-14-hdegoede@redhat.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
Hi 2024. január 13., szombat 15:22 keltezéssel, Hans de Goede via libcamera-devel írta: > From: Andrey Konovalov <andrey.konovalov@linaro.org> > > The implementation of SoftwareIsp handles creation of Soft IPA > and interactions with it, so that the pipeline handler wouldn't > need to care about the Soft IPA. > > Doxygen documentation by Dennis Bonke. > > Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> > Co-authored-by: Dennis Bonke <admin@dennisbonke.com> > Signed-off-by: Dennis Bonke <admin@dennisbonke.com> > Co-authored-by: Hans de Goede <hdegoede@redhat.com> > 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> > --- > .../internal/software_isp/meson.build | 1 + > .../internal/software_isp/swisp_simple.h | 163 ++++++++++++ > src/libcamera/software_isp/meson.build | 19 ++ > src/libcamera/software_isp/swisp_simple.cpp | 238 ++++++++++++++++++ > 4 files changed, 421 insertions(+) > create mode 100644 include/libcamera/internal/software_isp/swisp_simple.h > create mode 100644 src/libcamera/software_isp/swisp_simple.cpp > > diff --git a/include/libcamera/internal/software_isp/meson.build b/include/libcamera/internal/software_isp/meson.build > index b5a0d737..cf21ace5 100644 > --- a/include/libcamera/internal/software_isp/meson.build > +++ b/include/libcamera/internal/software_isp/meson.build > @@ -4,6 +4,7 @@ libcamera_internal_headers += files([ > 'debayer.h', > 'debayer_cpu.h', > 'debayer_params.h', > + 'swisp_simple.h', > 'swisp_stats.h', > 'swstats.h', > 'swstats_cpu.h', > diff --git a/include/libcamera/internal/software_isp/swisp_simple.h b/include/libcamera/internal/software_isp/swisp_simple.h > new file mode 100644 > index 00000000..87613c23 > --- /dev/null > +++ b/include/libcamera/internal/software_isp/swisp_simple.h > @@ -0,0 +1,163 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2023, Linaro Ltd > + * > + * swisp_simple.h - Simple software ISP implementation > + */ > + > +#pragma once > + > +#include <libcamera/base/log.h> > +#include <libcamera/base/thread.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/software_isp.h" > +#include "libcamera/internal/software_isp/debayer_cpu.h" > + > +namespace libcamera { > + > +/** > + * \brief Class for the Simple Software ISP. > + * > + * Implementation of the SoftwareIsp interface. > + */ > +class SwIspSimple : public SoftwareIsp > +{ > +public: > + /** > + * \brief Constructor for the SwIspSimple object. > + * > + * \param[in] pipe The pipeline handler in use. > + * \param[in] sensorControls The sensor controls. > + */ > + SwIspSimple(PipelineHandler *pipe, const ControlInfoMap &sensorControls); > + ~SwIspSimple() {} ~SwIspSimple() = default; > + > + /** > + * \brief Load a configuration from a file. > + * \param[in] filename The file to load from. > + * > + * \return 0 on success. > + */ > + int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; } > + > + /** > + * \brief Gets if there is a valid debayer object. > + * > + * \returns true if there is, false otherwise. > + */ > + bool isValid() const; > + > + /** > + * \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. > + */ > + std::vector<PixelFormat> formats(PixelFormat input); > + > + /** > + * \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. > + */ > + SizeRange sizes(PixelFormat inputFormat, const Size &inputSize); > + > + /** > + * \brief Get the stride and the frame size. > + * \param[in] outputFormat 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. > + */ > + std::tuple<unsigned int, unsigned int> > + strideAndFrameSize(const PixelFormat &outputFormat, const Size &size); > + > + /** > + * \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. > + */ > + int configure(const StreamConfiguration &inputCfg, > + const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs, > + const ControlInfoMap &sensorControls); > + > + /** > + * \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. > + */ > + int exportBuffers(unsigned int output, unsigned int count, > + std::vector<std::unique_ptr<FrameBuffer>> *buffers); > + > + /** > + * \brief Process the statistics gathered. > + * \param[in] sensorControls The sensor controls. > + */ > + void processStats(const ControlList &sensorControls); > + > + /** > + * \brief Starts the Software ISP worker. > + * > + * \return 0 on success, any other value indicates an error. > + */ > + int start(); > + > + /** > + * \brief Stops the Software ISP worker. > + */ > + void stop(); > + > + /** > + * \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 > + */ > + int queueBuffers(FrameBuffer *input, > + const std::map<unsigned int, FrameBuffer *> &outputs); > + > + /** > + * \brief Get the signal for when the sensor controls are set. > + * > + * \return The control list of the sensor controls. > + */ > + Signal<const ControlList &> &getSignalSetSensorControls(); > + > + /** > + * \brief Process the input framebuffer. > + * \param[in] input The input framebuffer. > + * \param[out] output The output framebuffer. > + */ > + void process(FrameBuffer *input, FrameBuffer *output); > + > +private: > + void saveIspParams(int dummy); > + 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 6d7a44d7..9464f2fd 100644 > --- a/src/libcamera/software_isp/meson.build > +++ b/src/libcamera/software_isp/meson.build > @@ -6,3 +6,22 @@ libcamera_sources += files([ > 'swstats.cpp', > 'swstats_cpu.cpp', > ]) > + > +# Software ISP is enabled for 'simple' pipeline handler. > +# The 'pipelines' option value should be > +# 'simple/<Software ISP implementation>' e.g.: > +# -Dpipelines=simple/simple > +# The source file should be named swisp_<Software ISP implementation>.cpp, > +# e.g. 'swisp_simple.cpp'. > + > +foreach pipeline : pipelines > + pipeline = pipeline.split('/') > + if pipeline.length() == 2 and pipeline[0] == 'simple' > + libcamera_sources += files([ > + 'swisp_' + pipeline[1] + '.cpp', > + ]) > + # the 'break' below can be removed if/when multiple > + # Software ISP implementations are allowed in single build > + break > + endif > +endforeach > diff --git a/src/libcamera/software_isp/swisp_simple.cpp b/src/libcamera/software_isp/swisp_simple.cpp > new file mode 100644 > index 00000000..0884166e > --- /dev/null > +++ b/src/libcamera/software_isp/swisp_simple.cpp > @@ -0,0 +1,238 @@ > +/* SPDX-License-Identifier: LGPL-2.1-or-later */ > +/* > + * Copyright (C) 2023, Linaro Ltd > + * > + * swisp_simple.cpp - Simple software ISP implementation > + */ > + > +#include "libcamera/internal/software_isp/swisp_simple.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" > + > +namespace libcamera { > + > +SwIspSimple::SwIspSimple(PipelineHandler *pipe, const ControlInfoMap &sensorControls) > + : SoftwareIsp(pipe, sensorControls), debayer_(nullptr), debayerParams_{ 256, 256, 256, 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_.fd().isValid()) { > + LOG(SoftwareIsp, Error) << "Failed to create shared memory for parameters"; > + return; > + } > + > + std::unique_ptr<SwStatsCpu> stats; > + > + stats = std::make_unique<SwStatsCpu>(); You can just say auto stats = std::make_unique<SwStatsCpu>(); > + if (!stats) { std::make_unique should never return nullptr. > + LOG(SoftwareIsp, Error) << "Failed to create SwStatsCpu object"; > + return; > + } > + > + stats->statsReady.connect(this, &SwIspSimple::statsReady); > + > + debayer_ = std::make_unique<DebayerCpu>(std::move(stats)); > + if (!debayer_) { Same here. > + LOG(SoftwareIsp, Error) << "Failed to create DebayerCpu object"; > + return; > + } > + > + debayer_->inputBufferReady.connect(this, &SwIspSimple::inputReady); > + debayer_->outputBufferReady.connect(this, &SwIspSimple::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, &SwIspSimple::saveIspParams); > + > + debayer_->moveToThread(&ispWorkerThread_); > +} > [...] Regards, Barnabás Pőcze
diff --git a/include/libcamera/internal/software_isp/meson.build b/include/libcamera/internal/software_isp/meson.build index b5a0d737..cf21ace5 100644 --- a/include/libcamera/internal/software_isp/meson.build +++ b/include/libcamera/internal/software_isp/meson.build @@ -4,6 +4,7 @@ libcamera_internal_headers += files([ 'debayer.h', 'debayer_cpu.h', 'debayer_params.h', + 'swisp_simple.h', 'swisp_stats.h', 'swstats.h', 'swstats_cpu.h', diff --git a/include/libcamera/internal/software_isp/swisp_simple.h b/include/libcamera/internal/software_isp/swisp_simple.h new file mode 100644 index 00000000..87613c23 --- /dev/null +++ b/include/libcamera/internal/software_isp/swisp_simple.h @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Linaro Ltd + * + * swisp_simple.h - Simple software ISP implementation + */ + +#pragma once + +#include <libcamera/base/log.h> +#include <libcamera/base/thread.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/software_isp.h" +#include "libcamera/internal/software_isp/debayer_cpu.h" + +namespace libcamera { + +/** + * \brief Class for the Simple Software ISP. + * + * Implementation of the SoftwareIsp interface. + */ +class SwIspSimple : public SoftwareIsp +{ +public: + /** + * \brief Constructor for the SwIspSimple object. + * + * \param[in] pipe The pipeline handler in use. + * \param[in] sensorControls The sensor controls. + */ + SwIspSimple(PipelineHandler *pipe, const ControlInfoMap &sensorControls); + ~SwIspSimple() {} + + /** + * \brief Load a configuration from a file. + * \param[in] filename The file to load from. + * + * \return 0 on success. + */ + int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; } + + /** + * \brief Gets if there is a valid debayer object. + * + * \returns true if there is, false otherwise. + */ + bool isValid() const; + + /** + * \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. + */ + std::vector<PixelFormat> formats(PixelFormat input); + + /** + * \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. + */ + SizeRange sizes(PixelFormat inputFormat, const Size &inputSize); + + /** + * \brief Get the stride and the frame size. + * \param[in] outputFormat 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. + */ + std::tuple<unsigned int, unsigned int> + strideAndFrameSize(const PixelFormat &outputFormat, const Size &size); + + /** + * \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. + */ + int configure(const StreamConfiguration &inputCfg, + const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs, + const ControlInfoMap &sensorControls); + + /** + * \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. + */ + int exportBuffers(unsigned int output, unsigned int count, + std::vector<std::unique_ptr<FrameBuffer>> *buffers); + + /** + * \brief Process the statistics gathered. + * \param[in] sensorControls The sensor controls. + */ + void processStats(const ControlList &sensorControls); + + /** + * \brief Starts the Software ISP worker. + * + * \return 0 on success, any other value indicates an error. + */ + int start(); + + /** + * \brief Stops the Software ISP worker. + */ + void stop(); + + /** + * \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 + */ + int queueBuffers(FrameBuffer *input, + const std::map<unsigned int, FrameBuffer *> &outputs); + + /** + * \brief Get the signal for when the sensor controls are set. + * + * \return The control list of the sensor controls. + */ + Signal<const ControlList &> &getSignalSetSensorControls(); + + /** + * \brief Process the input framebuffer. + * \param[in] input The input framebuffer. + * \param[out] output The output framebuffer. + */ + void process(FrameBuffer *input, FrameBuffer *output); + +private: + void saveIspParams(int dummy); + 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 6d7a44d7..9464f2fd 100644 --- a/src/libcamera/software_isp/meson.build +++ b/src/libcamera/software_isp/meson.build @@ -6,3 +6,22 @@ libcamera_sources += files([ 'swstats.cpp', 'swstats_cpu.cpp', ]) + +# Software ISP is enabled for 'simple' pipeline handler. +# The 'pipelines' option value should be +# 'simple/<Software ISP implementation>' e.g.: +# -Dpipelines=simple/simple +# The source file should be named swisp_<Software ISP implementation>.cpp, +# e.g. 'swisp_simple.cpp'. + +foreach pipeline : pipelines + pipeline = pipeline.split('/') + if pipeline.length() == 2 and pipeline[0] == 'simple' + libcamera_sources += files([ + 'swisp_' + pipeline[1] + '.cpp', + ]) + # the 'break' below can be removed if/when multiple + # Software ISP implementations are allowed in single build + break + endif +endforeach diff --git a/src/libcamera/software_isp/swisp_simple.cpp b/src/libcamera/software_isp/swisp_simple.cpp new file mode 100644 index 00000000..0884166e --- /dev/null +++ b/src/libcamera/software_isp/swisp_simple.cpp @@ -0,0 +1,238 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2023, Linaro Ltd + * + * swisp_simple.cpp - Simple software ISP implementation + */ + +#include "libcamera/internal/software_isp/swisp_simple.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" + +namespace libcamera { + +SwIspSimple::SwIspSimple(PipelineHandler *pipe, const ControlInfoMap &sensorControls) + : SoftwareIsp(pipe, sensorControls), debayer_(nullptr), debayerParams_{ 256, 256, 256, 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_.fd().isValid()) { + LOG(SoftwareIsp, Error) << "Failed to create shared memory for parameters"; + return; + } + + std::unique_ptr<SwStatsCpu> stats; + + stats = std::make_unique<SwStatsCpu>(); + if (!stats) { + LOG(SoftwareIsp, Error) << "Failed to create SwStatsCpu object"; + return; + } + + stats->statsReady.connect(this, &SwIspSimple::statsReady); + + debayer_ = std::make_unique<DebayerCpu>(std::move(stats)); + if (!debayer_) { + LOG(SoftwareIsp, Error) << "Failed to create DebayerCpu object"; + return; + } + + debayer_->inputBufferReady.connect(this, &SwIspSimple::inputReady); + debayer_->outputBufferReady.connect(this, &SwIspSimple::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, &SwIspSimple::saveIspParams); + + debayer_->moveToThread(&ispWorkerThread_); +} + +void SwIspSimple::processStats(const ControlList &sensorControls) +{ + ASSERT(ipa_); + ipa_->processStats(sensorControls); +} + +Signal<const ControlList &> &SwIspSimple::getSignalSetSensorControls() +{ + ASSERT(ipa_); + return ipa_->setSensorControls; +} + +bool SwIspSimple::isValid() const +{ + return !!debayer_; +} + +std::vector<PixelFormat> SwIspSimple::formats(PixelFormat inputFormat) +{ + ASSERT(debayer_ != nullptr); + + return debayer_->formats(inputFormat); +} + +SizeRange SwIspSimple::sizes(PixelFormat inputFormat, const Size &inputSize) +{ + ASSERT(debayer_ != nullptr); + + return debayer_->sizes(inputFormat, inputSize); +} + +std::tuple<unsigned int, unsigned int> +SwIspSimple::strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) +{ + ASSERT(debayer_ != nullptr); + + return debayer_->strideAndFrameSize(outputFormat, size); +} + +int SwIspSimple::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); +} + +int SwIspSimple::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; +} + +int SwIspSimple::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; +} + +int SwIspSimple::start() +{ + int ret = ipa_->start(); + if (ret) + return ret; + + ispWorkerThread_.start(); + return 0; +} + +void SwIspSimple::stop() +{ + ispWorkerThread_.exit(); + ispWorkerThread_.wait(); + + ipa_->stop(); +} + +void SwIspSimple::process(FrameBuffer *input, FrameBuffer *output) +{ + debayer_->invokeMethod(&DebayerCpu::process, + ConnectionTypeQueued, input, output, debayerParams_); +} + +void SwIspSimple::saveIspParams([[maybe_unused]] int dummy) +{ + debayerParams_ = *sharedParams_; +} + +void SwIspSimple::statsReady(int dummy) +{ + ispStatsReady.emit(dummy); +} + +void SwIspSimple::inputReady(FrameBuffer *input) +{ + inputBufferReady.emit(input); +} + +void SwIspSimple::outputReady(FrameBuffer *output) +{ + outputBufferReady.emit(output); +} + +REGISTER_SOFTWAREISP(SwIspSimple) + +} /* namespace libcamera */