From d2d27a85933e34b52fd16d39b6b10b7d9ada5fb9 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Wed, 4 Aug 2021 14:52:46 +0100 Subject: ipa: ipu3: Introduce modular algorithms Provide a modular IPU3 specific algorithm, and frame context structure so that algorithms can be built for the IPU3 in a component based structure. Signed-off-by: Kieran Bingham --- src/ipa/ipu3/algorithms/algorithm.h | 30 +++++++++++++++++++ src/ipa/ipu3/algorithms/meson.build | 4 +++ src/ipa/ipu3/ipa_context.h | 30 +++++++++++++++++++ src/ipa/ipu3/ipu3.cpp | 57 ++++++++++++++++++++++++++++++++++++- src/ipa/ipu3/meson.build | 4 +++ 5 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/ipa/ipu3/algorithms/algorithm.h create mode 100644 src/ipa/ipu3/algorithms/meson.build create mode 100644 src/ipa/ipu3/ipa_context.h diff --git a/src/ipa/ipu3/algorithms/algorithm.h b/src/ipa/ipu3/algorithms/algorithm.h new file mode 100644 index 00000000..cbeb6d64 --- /dev/null +++ b/src/ipa/ipu3/algorithms/algorithm.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Ideas On Board + * + * algorithm.h - IPU3 control algorithm interface + */ +#ifndef __LIBCAMERA_IPA_IPU3_ALGORITHM_H__ +#define __LIBCAMERA_IPA_IPU3_ALGORITHM_H__ + +#include + +namespace libcamera { + +namespace ipa::ipu3 { + +class Algorithm +{ +public: + virtual ~Algorithm(); + + virtual int initialise(IPAContext *context); + virtual int configure(IPAContext *context); + virtual void process(IPAContext *context); +}; + +} /* namespace ipa::ipu3 */ + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_IPA_IPU3_ALGORITHM_H__ */ diff --git a/src/ipa/ipu3/algorithms/meson.build b/src/ipa/ipu3/algorithms/meson.build new file mode 100644 index 00000000..67148333 --- /dev/null +++ b/src/ipa/ipu3/algorithms/meson.build @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: CC0-1.0 + +ipu3_ipa_algorithms = files([ +]) diff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h new file mode 100644 index 00000000..6cf85524 --- /dev/null +++ b/src/ipa/ipu3/ipa_context.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Ideas On Board + * + * ipu3_ipa_context.h - IPU3 IPA Context + * + * Context information shared between the algorithms + */ +#ifndef __LIBCAMERA_IPU3_IPA_CONTEXT_H__ +#define __LIBCAMERA_IPU3_IPA_CONTEXT_H__ + +#include + +namespace libcamera { + +namespace ipa::ipu3 { + +struct IPAContext { + /* Input statistics from the previous frame */ + const ipu3_uapi_stats_3a *stats; + + /* Output Parameters which will be written to the hardware */ + ipu3_uapi_params *params; +}; + +} /* namespace ipa::ipu3 */ + +} /* namespace libcamera*/ + +#endif /* __LIBCAMERA_IPU3_IPA_CONTEXT_H__ */ diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 71698d36..d37cdda7 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -22,6 +22,9 @@ #include "libcamera/internal/framebuffer.h" +#include "algorithms/algorithm.h" +#include "ipa_context.h" + #include "ipu3_agc.h" #include "ipu3_awb.h" #include "libipa/camera_sensor_helper.h" @@ -51,6 +54,10 @@ public: private: void processControls(unsigned int frame, const ControlList &controls); void fillParams(unsigned int frame, ipu3_uapi_params *params); + + int initialiseAlgorithms(); + int configureAlgorithms(); + void processAlgorithms(const ipu3_uapi_stats_3a *stats); void parseStatistics(unsigned int frame, int64_t frameTimestamp, const ipu3_uapi_stats_3a *stats); @@ -80,10 +87,13 @@ private: /* Interface to the Camera Helper */ std::unique_ptr camHelper_; + /* Maintain the algorithms used by the IPA */ + std::list algorithms_; + /* Local parameter storage */ struct ipu3_uapi_params params_; - struct ipu3_uapi_grid_config bdsGrid_; + struct IPAContext context_; }; int IPAIPU3::init(const IPASettings &settings) @@ -94,6 +104,14 @@ int IPAIPU3::init(const IPASettings &settings) return -ENODEV; } + /* + * This may require better linking, or it could simply be moved into the + * context structure entirely. (Moving it makes more sense) + */ + context_.params = ¶ms_; + + initialiseAlgorithms(); + return 0; } @@ -197,6 +215,8 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo) calculateBdsGrid(configInfo.bdsOutputSize); + configureAlgorithms(); + awbAlgo_ = std::make_unique(); awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_); @@ -286,12 +306,47 @@ void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params) queueFrameAction.emit(frame, op); } +int IPAIPU3::initialiseAlgorithms() +{ + for (Algorithm &algo : algorithms_) { + int ret = algo.initialise(&context_); + if (ret) + return ret; + } + + return 0; +} + +int IPAIPU3::configureAlgorithms() +{ + for (Algorithm &algo : algorithms_) { + int ret = algo.configure(&context_); + if (ret) + return ret; + } + + return 0; +} + +void IPAIPU3::processAlgorithms(const ipu3_uapi_stats_3a *stats) +{ + /* It might be better to pass the stats in as a parameter to process() ? */ + context_.stats = stats; + + for (Algorithm &algo : algorithms_) { + algo.process(&context_); + } +} + void IPAIPU3::parseStatistics(unsigned int frame, [[maybe_unused]] int64_t frameTimestamp, [[maybe_unused]] const ipu3_uapi_stats_3a *stats) { ControlList ctrls(controls::controls); + /* Run the process for each algorithm on the stats */ + processAlgorithms(stats); + double gain = camHelper_->gain(gain_); agcAlgo_->process(stats, exposure_, gain); gain_ = camHelper_->gainCode(gain); diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build index b6364190..fcb27d68 100644 --- a/src/ipa/ipu3/meson.build +++ b/src/ipa/ipu3/meson.build @@ -1,5 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 +subdir('algorithms') + ipa_name = 'ipa_ipu3' ipu3_ipa_sources = files([ @@ -8,6 +10,8 @@ ipu3_ipa_sources = files([ 'ipu3_awb.cpp', ]) +ipu3_ipa_sources += ipu3_ipa_algorithms + mod = shared_module(ipa_name, [ipu3_ipa_sources, libcamera_generated_ipa_headers], name_prefix : '', -- cgit v1.2.1