[libcamera-devel] [PATCH v4 06/10] ipa: rkisp1: Add AF algorithm basing on AfHillClimbing
Jacopo Mondi
jacopo.mondi at ideasonboard.com
Tue Mar 21 15:49:05 CET 2023
Hi Daniel
On Tue, Mar 14, 2023 at 03:48:30PM +0100, Daniel Semkowicz wrote:
> Add contrast based auto focus implementation for rkisp1 platform using
> the common AfHillClimbing algorithm.
>
> Rockchip ISP AF block allows calculation of sharpness and luminance
> in up to three user defined windows. If no windows are set, there are
> some default settings applied for the first window and exposed through
> the driver. For each frame, use the sharpness value calculated for this
> default window and feed the hill climbing algorithm with them. Then set
> the lens position to value calculated by the algorithm.
>
> Signed-off-by: Daniel Semkowicz <dse at thaumatec.com>
> ---
> src/ipa/rkisp1/algorithms/af.cpp | 107 ++++++++++++++++++++++++++
> src/ipa/rkisp1/algorithms/af.h | 39 ++++++++++
> src/ipa/rkisp1/algorithms/meson.build | 1 +
> src/ipa/rkisp1/ipa_context.cpp | 13 ++++
> src/ipa/rkisp1/ipa_context.h | 5 ++
> 5 files changed, 165 insertions(+)
> create mode 100644 src/ipa/rkisp1/algorithms/af.cpp
> create mode 100644 src/ipa/rkisp1/algorithms/af.h
>
> diff --git a/src/ipa/rkisp1/algorithms/af.cpp b/src/ipa/rkisp1/algorithms/af.cpp
> new file mode 100644
> index 00000000..abf5d91f
> --- /dev/null
> +++ b/src/ipa/rkisp1/algorithms/af.cpp
> @@ -0,0 +1,107 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2023, Theobroma Systems
> + *
> + * af.cpp - RkISP1 AF hill climbing based control algorithm
> + */
> +
> +#include "af.h"
> +
> +/**
> + * \file af.h
> + */
> +
> +namespace libcamera::ipa::rkisp1::algorithms {
> +
> +/**
> + * \class Af
> + * \brief AF contrast based hill climbing control algorithm for RkISP platforms
> + *
> + * Auto focus algorithm for RkISP platforms, basing on the common contrast based
s/basing/based
s/common constrast based/common
> + * hill climbing auto focus implementation
> + * (libcamera::ipa::common::algorithms::AfHillClimbing).
> + *
> + * This is the platform layer of the algorithm.
> + *
> + * Tuning file parameters:
> + * - **wait-frames-lens:** Number of frames that should be skipped when lens
> + * position is changed. Lens movement takes some time and statistics measured
> + * during the lens movement are unstable. Currently there is no way to know
> + * when lens movement finished and this is a workaround for this. Wait a fixed
> + * amount of time on each movement. This parameter should be set according
> + * to the worst case - the number of frames it takes to move lens between
> + * limit positions.
I would add a
\todo Model the lens delay as number of frames required for
the lens position to stabilize in the CameraLens class
> + */
> +
> +LOG_DEFINE_CATEGORY(RkISP1Af)
> +
> +/**
> + * \copydoc libcamera::ipa::Algorithm::init
> + */
> +int Af::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData)
> +{
> + waitFramesLens_ = tuningData["wait-frames-lens"].get<uint32_t>(1);
> +
> + LOG(RkISP1Af, Debug) << "waitFramesLens_: " << waitFramesLens_;
> +
> + return af.init(tuningData);
> +}
> +
> +/**
> + * \copydoc libcamera::ipa::Algorithm::configure
> + */
> +int Af::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
> +{
> + const auto &lensConfig = context.configuration.lens;
> +
> + af.configure(lensConfig.minFocusPosition, lensConfig.maxFocusPosition,
> + configInfo.outputSize);
> +
> + /*
> + * Lens position is unknown at the startup, so initialize
> + * the current position to something out of range.
> + */
Check comments along the series
> + context.activeState.af.lensPosition = lensConfig.maxFocusPosition + 1;
> +
> + return 0;
> +}
> +
> +/**
> + * \copydoc libcamera::ipa::Algorithm::queueRequest
> + */
> +void Af::queueRequest([[maybe_unused]] IPAContext &context,
> + [[maybe_unused]] const uint32_t frame,
> + [[maybe_unused]] IPAFrameContext &frameContext,
> + const ControlList &controls)
> +{
> + af.queueRequest(controls);
> +}
> +
> +/**
> + * \copydoc libcamera::ipa::Algorithm::process
> + */
> +void Af::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
> + [[maybe_unused]] IPAFrameContext &frameContext,
> + const rkisp1_stat_buffer *stats,
> + [[maybe_unused]] ControlList &metadata)
> +{
> + uint32_t sharpness = stats->params.af.window[0].sum;
> + uint32_t luminance = stats->params.af.window[0].lum;
> +
> + LOG(RkISP1Af, Debug)
> + << "lensPosition: " << context.activeState.af.lensPosition
> + << ", Sharpness: " << sharpness
> + << ", Luminance: " << luminance;
> +
> + int32_t newLensPosition = af.process(sharpness);
> +
> + if (newLensPosition != context.activeState.af.lensPosition) {
> + context.activeState.af.lensPosition = newLensPosition;
> + context.activeState.af.applyLensCtrls = true;
> + af.setFramesToSkip(waitFramesLens_);
> + }
> +}
> +
> +REGISTER_IPA_ALGORITHM(Af, "Af")
> +
> +} /* namespace libcamera::ipa::rkisp1::algorithms */
> diff --git a/src/ipa/rkisp1/algorithms/af.h b/src/ipa/rkisp1/algorithms/af.h
> new file mode 100644
> index 00000000..85de0a64
> --- /dev/null
> +++ b/src/ipa/rkisp1/algorithms/af.h
> @@ -0,0 +1,39 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2023, Theobroma Systems
> + *
> + * af.h - RkISP1 AF hill climbing based control algorithm
> + */
> +
> +#pragma once
> +
> +#include <linux/rkisp1-config.h>
> +
> +#include "libipa/algorithms/af_hill_climbing.h"
> +
> +#include "algorithm.h"
> +
> +namespace libcamera::ipa::rkisp1::algorithms {
> +
> +class Af : public Algorithm
> +{
> +public:
> + int init(IPAContext &context, const YamlObject &tuningData) override;
> + int configure(IPAContext &context,
> + const IPACameraSensorInfo &configInfo) override;
> + void queueRequest(IPAContext &context, const uint32_t frame,
> + IPAFrameContext &frameContext,
> + const ControlList &controls) override;
> + void process(IPAContext &context, const uint32_t frame,
> + IPAFrameContext &frameContext,
> + const rkisp1_stat_buffer *stats,
> + ControlList &metadata) override;
> +
> +private:
> + ipa::common::algorithms::AfHillClimbing af;
> +
> + /* Wait number of frames after changing lens position */
> + uint32_t waitFramesLens_;
> +};
> +
> +} /* namespace libcamera::ipa::rkisp1::algorithms */
> diff --git a/src/ipa/rkisp1/algorithms/meson.build b/src/ipa/rkisp1/algorithms/meson.build
> index 93a48329..ab7e44f3 100644
> --- a/src/ipa/rkisp1/algorithms/meson.build
> +++ b/src/ipa/rkisp1/algorithms/meson.build
> @@ -1,6 +1,7 @@
> # SPDX-License-Identifier: CC0-1.0
>
> rkisp1_ipa_algorithms = files([
> + 'af.cpp',
> 'agc.cpp',
> 'awb.cpp',
> 'blc.cpp',
> diff --git a/src/ipa/rkisp1/ipa_context.cpp b/src/ipa/rkisp1/ipa_context.cpp
> index 401c098f..5c5f80c7 100644
> --- a/src/ipa/rkisp1/ipa_context.cpp
> +++ b/src/ipa/rkisp1/ipa_context.cpp
> @@ -134,6 +134,19 @@ namespace libcamera::ipa::rkisp1 {
> * member may be read by any algorithm, but shall only be written by its owner.
> */
>
> +/**
> + * \var IPAActiveState::af
> + * \brief State for the Automatic Focus Control algorithm
> + *
> + * \var IPAActiveState::af.lensPosition
> + * \brief Lens position calculated by the AF algorithm
> + *
> + * \var IPAActiveState::af.applyLensCtrls
> + * \brief Whether the lens position should be applied
> + *
> + * If true, IPA should send new controls to the PH to set new lens position.
> + */
> +
> /**
> * \var IPAActiveState::agc
> * \brief State for the Automatic Gain Control algorithm
> diff --git a/src/ipa/rkisp1/ipa_context.h b/src/ipa/rkisp1/ipa_context.h
> index bfb6e1b7..2c2eec3b 100644
> --- a/src/ipa/rkisp1/ipa_context.h
> +++ b/src/ipa/rkisp1/ipa_context.h
> @@ -58,6 +58,11 @@ struct IPASessionConfiguration {
> };
>
> struct IPAActiveState {
> + struct {
> + int32_t lensPosition;
> + bool applyLensCtrls;
> + } af;
> +
> struct {
> struct {
> uint32_t exposure;
> --
> 2.39.2
>
More information about the libcamera-devel
mailing list