diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2022-10-21 23:47:31 +0300 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2022-11-25 10:52:06 +0200 |
commit | 947b8627f9a27e2966c05443f1d2af5561efdb64 (patch) | |
tree | eaf21c280663c7f7e1df7e3b3b2fc184c510d919 | |
parent | 81e7689bb168a74c0822846729d992128da97322 (diff) |
ipa: rkisp1: Support raw capture in IPA operations
The RkISP1 can capture raw frames by bypassing the ISP. In that mode,
the ISP will not produce statistics nor consume parameters. Most
algorithms will thus be unable to run, with one exception: the AGC will
still be able to configure the sensor exposure time and analog gain in
manual mode.
To prepare for this, add the ability to disable algorithms for the
duration of the capture session based on the camera configuration.
Individual algorithms report whether they support raw formats at
construction time, and the IPA module disables algorithms in configure()
based on the stream configurations.
Disabled algorithms are skipped during the capture session in the
processStatsBuffer() operation. As the ISP doesn't produce statistics,
don't try to access the stats buffer. There is no need for similar logic
in fillParamsBuffer() as that operation won't be called for raw capture.
All algorithms report not supporting raw capture by default. Raw support
in AGC will be added separately.
The feature is implemented in the RkISP1 module without any support from
libipa at this point to avoid designing a generic API based on a single
user. This may be changed in the future.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
-rw-r--r-- | src/ipa/rkisp1/algorithms/algorithm.h | 12 | ||||
-rw-r--r-- | src/ipa/rkisp1/ipa_context.cpp | 5 | ||||
-rw-r--r-- | src/ipa/rkisp1/ipa_context.h | 2 | ||||
-rw-r--r-- | src/ipa/rkisp1/rkisp1.cpp | 40 |
4 files changed, 52 insertions, 7 deletions
diff --git a/src/ipa/rkisp1/algorithms/algorithm.h b/src/ipa/rkisp1/algorithms/algorithm.h index c3212cff..9454c9a1 100644 --- a/src/ipa/rkisp1/algorithms/algorithm.h +++ b/src/ipa/rkisp1/algorithms/algorithm.h @@ -15,7 +15,17 @@ namespace libcamera { namespace ipa::rkisp1 { -using Algorithm = libcamera::ipa::Algorithm<Module>; +class Algorithm : public libcamera::ipa::Algorithm<Module> +{ +public: + Algorithm() + : disabled_(false), supportsRaw_(false) + { + } + + bool disabled_; + bool supportsRaw_; +}; } /* namespace ipa::rkisp1 */ diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp index 7a987497..9bbf3684 100644 --- a/src/ipa/rkisp1/ipa_context.cpp +++ b/src/ipa/rkisp1/ipa_context.cpp @@ -90,6 +90,11 @@ namespace libcamera::ipa::rkisp1 { */ /** + * \var IPASessionConfiguration::raw + * \brief Indicates if the camera is configured to capture raw frames + */ + +/** * \struct IPAActiveState * \brief Active state for algorithms * diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h index bb60ab9e..3e47ac66 100644 --- a/src/ipa/rkisp1/ipa_context.h +++ b/src/ipa/rkisp1/ipa_context.h @@ -48,6 +48,8 @@ struct IPASessionConfiguration { struct { rkisp1_cif_isp_version revision; } hw; + + bool raw; }; struct IPAActiveState { diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 4658aa31..dd551c7b 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -24,6 +24,7 @@ #include <libcamera/ipa/rkisp1_ipa_interface.h> #include <libcamera/request.h> +#include "libcamera/internal/formats.h" #include "libcamera/internal/mapped_framebuffer.h" #include "libcamera/internal/yaml_parser.h" @@ -206,7 +207,7 @@ void IPARkISP1::stop() } int IPARkISP1::configure(const IPAConfigInfo &ipaConfig, - [[maybe_unused]] const std::map<uint32_t, IPAStream> &streamConfig, + const std::map<uint32_t, IPAStream> &streamConfig, ControlInfoMap *ipaControls) { sensorControls_ = ipaConfig.sensorControls; @@ -254,7 +255,21 @@ int IPARkISP1::configure(const IPAConfigInfo &ipaConfig, context_.configuration.sensor.minAnalogueGain = camHelper_->gain(minGain); context_.configuration.sensor.maxAnalogueGain = camHelper_->gain(maxGain); - for (auto const &algo : algorithms()) { + context_.configuration.raw = std::any_of(streamConfig.begin(), streamConfig.end(), + [](auto &cfg) -> bool { + PixelFormat pixelFormat{ cfg.second.pixelFormat }; + const PixelFormatInfo &format = PixelFormatInfo::info(pixelFormat); + return format.colourEncoding == PixelFormatInfo::ColourEncodingRAW; + }); + + for (auto const &a : algorithms()) { + Algorithm *algo = static_cast<Algorithm *>(a.get()); + + /* Disable algorithms that don't support raw formats. */ + algo->disabled_ = context_.configuration.raw && !algo->supportsRaw_; + if (algo->disabled_) + continue; + int ret = algo->configure(context_, info); if (ret) return ret; @@ -297,8 +312,12 @@ void IPARkISP1::queueRequest(const uint32_t frame, const ControlList &controls) { IPAFrameContext &frameContext = context_.frameContexts.alloc(frame); - for (auto const &algo : algorithms()) + for (auto const &a : algorithms()) { + Algorithm *algo = static_cast<Algorithm *>(a.get()); + if (algo->disabled_) + continue; algo->queueRequest(context_, frame, frameContext, controls); + } } void IPARkISP1::fillParamsBuffer(const uint32_t frame, const uint32_t bufferId) @@ -323,8 +342,13 @@ void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId { IPAFrameContext &frameContext = context_.frameContexts.get(frame); - const rkisp1_stat_buffer *stats = - reinterpret_cast<rkisp1_stat_buffer *>( + /* + * In raw capture mode, the ISP is bypassed and no statistics buffer is + * provided. + */ + const rkisp1_stat_buffer *stats = nullptr; + if (!context_.configuration.raw) + stats = reinterpret_cast<rkisp1_stat_buffer *>( mappedBuffers_.at(bufferId).planes()[0].data()); frameContext.sensor.exposure = @@ -334,8 +358,12 @@ void IPARkISP1::processStatsBuffer(const uint32_t frame, const uint32_t bufferId ControlList metadata(controls::controls); - for (auto const &algo : algorithms()) + for (auto const &a : algorithms()) { + Algorithm *algo = static_cast<Algorithm *>(a.get()); + if (algo->disabled_) + continue; algo->process(context_, frame, frameContext, stats, metadata); + } setControls(frame); |