[libcamera-devel] [PATCH] SQUASH: ipa: ipu3: af: Auto focus for dw9719 Surface Go2 VCM

Kieran Bingham kieran.bingham at ideasonboard.com
Tue Mar 15 15:50:42 CET 2022


Quoting Kieran Bingham (2022-03-15 14:13:18)
> These changes are expected to be squashed into the AF implementation.
> 
> The changes here include:
> - Correct alignment of documentation *'s
> - Normalise return value documentation
> - Fix spelling of /afEstemateVariance/afEstimateVariance/
> - Expand documentation of Af::afEstimateVariance
> 
> With these, for Kate's patch:
> 
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> 
> I have a few more potential changes, but they can be handled as patches
> on top and reviewed independently.
> 
> Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> ---
>  src/ipa/ipu3/algorithms/af.cpp | 76 +++++++++++++++++++++++-----------
>  1 file changed, 52 insertions(+), 24 deletions(-)
> 
> diff --git a/src/ipa/ipu3/algorithms/af.cpp b/src/ipa/ipu3/algorithms/af.cpp
> index 17055c043200..541b200bcc61 100644
> --- a/src/ipa/ipu3/algorithms/af.cpp
> +++ b/src/ipa/ipu3/algorithms/af.cpp
> @@ -33,25 +33,25 @@
>   * \var kAfMinGridWidth
>   * \brief the minimum width of AF grid.
>   * The minimum grid horizontal dimensions.
> -*/
> + */
>  
>  /**
>   * \var kAfMinGridHeight
>   * \brief the minimum height of AF grid.
>   * The minimum grid vertical dimensions.
> -*/
> + */
>  
>  /**
>   * \var kAfMaxGridWidth
>   * \brief the maximum width of AF grid.
>   * The maximum grid horizontal dimensions.
> -*/
> + */
>  
>  /**
>   * \var kAfMaxGridHeight
>   * \brief The maximum height of AF grid.
>   * The maximum grid vertical dimensions.
> -*/
> + */
>  
>  /**
>   * \var kAfMinGridBlockWidth
> @@ -127,6 +127,7 @@ static struct ipu3_uapi_af_filter_config afFilterConfigDefault = {
>  /**
>   * \class Af
>   * \brief An auto-focus algorithm based on IPU3 statistics
> + *
>   * This algorithm is used to determine the position of the lens to make a
>   * focused image. The IPU3 AF processing block computes the statistics that
>   * are composed by two types of filtered value and stores in a AF buffer.
> @@ -158,7 +159,7 @@ void Af::prepare(IPAContext &context, ipu3_uapi_params *params)
>   * \brief Configure the Af given a configInfo
>   * \param[in] context The shared IPA context
>   * \param[in] configInfo The IPA configuration data
> - * \return 0
> + * \return 0 on success, a negative error code otherwise
>   */
>  int Af::configure(IPAContext &context, const IPAConfigInfo &configInfo)
>  {
> @@ -195,7 +196,9 @@ int Af::configure(IPAContext &context, const IPAConfigInfo &configInfo)
>  
>  /**
>   * \brief AF coarse scan
> + *
>   * Find a near focused image using a coarse step. The step is determined by coarseSearchStep.
> + *
>   * \param[in] context The shared IPA context
>   */
>  void Af::afCoarseScan(IPAContext &context)
> @@ -220,7 +223,9 @@ void Af::afCoarseScan(IPAContext &context)
>  
>  /**
>   * \brief AF fine scan
> + *
>   * Find an optimum lens position with moving 1 step for each search.
> + *
>   * \param[in] context The shared IPA context
>   */
>  void Af::afFineScan(IPAContext &context)
> @@ -239,7 +244,9 @@ void Af::afFineScan(IPAContext &context)
>  
>  /**
>   * \brief AF reset
> + *
>   * Reset all the parameters to start over the AF process.
> + *
>   * \param[in] context The shared IPA context
>   */
>  void Af::afReset(IPAContext &context)
> @@ -260,11 +267,13 @@ void Af::afReset(IPAContext &context)
>  
>  /**
>   * \brief AF variance comparison.
> - * It always picks the largest variance to replace the previous one. The image
> - * with a larger variance also indicates it is a clearer image than previous
> - * one. If it finds the negative sign of derivative, it returns immediately.
>   * \param[in] context The IPA context
>   * \param min_step The VCM movement step.
> + *
> + * We always pick the largest variance to replace the previous one. The image
> + * with a larger variance also indicates it is a clearer image than previous
> + * one. If we find a negative derivative, we return immediately.
> + *
>   * \return True, if it finds a AF value.
>   */
>  bool Af::afScan(IPAContext &context, int min_step)
> @@ -278,7 +287,7 @@ bool Af::afScan(IPAContext &context, int min_step)
>                  * Find the maximum of the variance by estimating its
>                  * derivative. If the direction changes, it means we have
>                  * passed a maximum one step before.
> -               */
> +                */
>                 if ((currentVariance_ - context.frameContext.af.maxVariance) >=
>                     -(context.frameContext.af.maxVariance * 0.1)) {
>                         /*
> @@ -313,8 +322,7 @@ bool Af::afScan(IPAContext &context, int min_step)
>  
>  /**
>   * \brief Determine the frame to be ignored.
> - * \return Return true the frame is ignored.
> - * \return Return false the frame should be processed.
> + * \return Return True if the frame should be ignored, false otherwise
>   */
>  bool Af::afNeedIgnoreFrame()
>  {
> @@ -334,9 +342,22 @@ void Af::afIgnoreFrameReset()
>  }
>  
>  /**
> - * \brief Estemate variance
> + * \brief Estimate variance
> + * \param y_item The AF filter data set from the IPU3 statistics buffer
> + * \param len The quantity of table item entries which are valid to process
> + * \param isY1 Selects between filter Y1 or Y2 to calculate the variance
> + *
> + * Calculate the mean of the data set provided by \a y_item, and then calculate
> + * the variance of that data set from the mean.
> + *
> + * The operation can work on one of two sets of values contained within the
> + * y_item data set supplied by the IPU3. The two data sets are the results of
> + * both the Y1 and Y2 filters which are used to support coarse (Y1) and fine
> + * (Y2) calculations of the contrast.
> + *
> + * \return The variance of the values in the data set \a y_item selected by \a isY1
>   */
> -double Af::afEstemateVariance(y_table_item_t *y_item, uint32_t len,
> +double Af::afEstimateVariance(y_table_item_t *y_item, uint32_t len,

Of course, there is also the corresponding update to the class
definition in the header for this change.
--
Kieran

>                               bool isY1)
>  {
>         uint32_t z = 0;
> @@ -363,21 +384,25 @@ double Af::afEstemateVariance(y_table_item_t *y_item, uint32_t len,
>  
>  /**
>   * \brief Determine out-of-focus situation.
> + * \param context The IPA context.
> + *
>   * Out-of-focus means that the variance change rate for a focused and a new
>   * variance is greater than a threshold.
> - * \param context The IPA context.
> - * \return If it is out-of-focus, return true.
> - * \return If is is focused, return false.
> + *
> + * \return True if the variance threshold is crossed indicating lost focus,
> + *         false otherwise.
>   */
>  bool Af::afIsOutOfFocus(IPAContext context)
>  {
>         const uint32_t diff_var = std::abs(currentVariance_ -
>                                            context.frameContext.af.maxVariance);
>         const double var_ratio = diff_var / context.frameContext.af.maxVariance;
> +
>         LOG(IPU3Af, Debug) << "Variance change rate: "
>                            << var_ratio
>                            << " Current VCM step: "
>                            << context.frameContext.af.focus;
> +
>         if (var_ratio > kMaxChange)
>                 return true;
>         else
> @@ -386,16 +411,19 @@ bool Af::afIsOutOfFocus(IPAContext context)
>  
>  /**
>   * \brief Determine the max contrast image and lens position.
> - * Ideally, a clear image also has a raletively higher contrast. So, every
> - * images for each focus step should be tested to find a optimal focus step.
> + * \param[in] context The IPA context.
> + * \param[in] stats The statistic buffer of IPU3.
> + *
> + * Ideally, a clear image also has a relatively higher contrast. So, every
> + * image for each focus step should be tested to find an optimal focus step.
> + *
>   * The Hill Climbing Algorithm[1] is used to find the maximum variance of the
> - * AF statistic which is the AF output of IPU3. The focus step is increased
> + * AF statistics which is the AF output of IPU3. The focus step is increased
>   * then the variance of the AF statistic is estimated. If it finds the negative
> - * derivative which means we just passed the peak, the best focus is found.
> + * derivative we have just passed the peak, and we infer that the best focus is
> + * found.
>   *
>   * [1] Hill Climbing Algorithm, https://en.wikipedia.org/wiki/Hill_climbing
> - * \param[in] context The IPA context.
> - * \param[in] stats The statistic buffer of IPU3.
>   */
>  void Af::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)
>  {
> @@ -415,9 +443,9 @@ void Af::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)
>          * For fine: y2 results are used.
>          */
>         if (coarseCompleted_)
> -               currentVariance_ = afEstemateVariance(y_item, afRawBufferLen, false);
> +               currentVariance_ = afEstimateVariance(y_item, afRawBufferLen, false);
>         else
> -               currentVariance_ = afEstemateVariance(y_item, afRawBufferLen, true);
> +               currentVariance_ = afEstimateVariance(y_item, afRawBufferLen, true);
>  
>         if (!context.frameContext.af.stable) {
>                 afCoarseScan(context);
> -- 
> 2.32.0
>


More information about the libcamera-devel mailing list