[{"id":17912,"web_url":"https://patchwork.libcamera.org/comment/17912/","msgid":"<CAHW6GY+MTWkp0fCyUjDNkB4uK6KCL-mHD-78GP5ugLXFqeSheA@mail.gmail.com>","date":"2021-06-29T13:22:25","subject":"Re: [libcamera-devel] [PATCH v1 7/7] ipa: ipu3: Implement a new AGC\n\talgorithm","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/people/42/","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"content":"Hi Jean-Michel\n\nThanks for your work - very happy to see our code being useful elsewhere!\n\nOne minor thing - would it be ok to include a Raspberry Pi copyright\nalongside the IdeasonBoard one?\n\nThanks!\nDavid\n\n\nOn Mon, 28 Jun 2021 at 21:23, Jean-Michel Hautbois <\njeanmichel.hautbois@ideasonboard.com> wrote:\n\n> This one comes from RPi for most if it, except that we are not\n> exchanging any metadata between algorithms for now.\n> When process() is called, the current analogue gain and shutter time are\n> calculated. The AWB stats from IPU3 are then parsed to generate new\n> statistics dedicated to AGC. This new grid is used to estimate the\n> luminance and each region is weighted. A default centered metering is\n> used as is should be the most used one.\n>\n> After calculating weighted regions, analogue gain and shutter time are\n> divided up and the values are then sent back to the IPAIPU3.\n>\n> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n> ---\n>  src/ipa/ipu3/ipu3_agc.cpp | 276 ++++++++++++++++++++++++--------------\n>  src/ipa/ipu3/ipu3_agc.h   |  23 +++-\n>  2 files changed, 196 insertions(+), 103 deletions(-)\n>\n> diff --git a/src/ipa/ipu3/ipu3_agc.cpp b/src/ipa/ipu3/ipu3_agc.cpp\n> index 042d67fa..0d421404 100644\n> --- a/src/ipa/ipu3/ipu3_agc.cpp\n> +++ b/src/ipa/ipu3/ipu3_agc.cpp\n> @@ -27,37 +27,19 @@ namespace ipa::ipu3 {\n>\n>  LOG_DEFINE_CATEGORY(IPU3Agc)\n>\n> -/* Number of frames to wait before calculating stats on minimum exposure\n> */\n> -static constexpr uint32_t kInitialFrameMinAECount = 4;\n> -/* Number of frames to wait between new gain/exposure estimations */\n> -static constexpr uint32_t kFrameSkipCount = 6;\n> -\n> -/* Maximum ISO value for analogue gain */\n> -static constexpr uint32_t kMinISO = 100;\n> -static constexpr uint32_t kMaxISO = 1500;\n> -\n> -/* Maximum analogue gain value\n> - * \\todo grab it from a camera helper */\n> -static constexpr uint32_t kMinGain = kMinISO / 100;\n> -static constexpr uint32_t kMaxGain = kMaxISO / 100;\n> -\n> -/* \\todo use calculated value based on sensor */\n> -static constexpr uint32_t kMinExposure = 1;\n> -static constexpr uint32_t kMaxExposure = 1976;\n> -\n>  /* Histogram constants */\n>  static constexpr uint32_t knumHistogramBins = 256;\n> -static constexpr double kEvGainTarget = 0.5;\n>\n> -/* A cell is 8 bytes and contains averages for RGB values and saturation\n> ratio */\n> -static constexpr uint8_t kCellSize = 8;\n> +/* seems to be a 8-bit pipeline */\n> +static constexpr uint8_t kPipelineBits = 8;\n>\n>  IPU3Agc::IPU3Agc()\n>         : frameCount_(0), lastFrame_(0), converged_(false),\n>           updateControls_(false), iqMean_(0.0), gamma_(1.0),\n>           lineDuration_(0s), maxExposureTime_(0s),\n>           prevExposure_(0s), prevExposureNoDg_(0s),\n> -         currentExposure_(0s), currentExposureNoDg_(0s)\n> +         currentExposure_(0s), currentExposureNoDg_(0s),\n> +         currentShutter_(1.0s), currentAnalogueGain_(1.0)\n>  {\n>  }\n>\n> @@ -83,55 +65,79 @@ void IPU3Agc::initialise(struct ipu3_uapi_grid_config\n> &bdsGrid, const IPAConfigI\n>         }\n>         minGain_ = std::max(itGain->second.min().get<int32_t>(), 1);\n>         maxGain_ = itGain->second.max().get<int32_t>();\n> +\n> +       /* \\todo: those values need to be extracted from a configuration\n> file */\n> +       shutterConstraints_.push_back(100us);\n> +       shutterConstraints_.push_back(10ms);\n> +       shutterConstraints_.push_back(33ms);\n> +       gainConstraints_.push_back(1.0);\n> +       gainConstraints_.push_back(4.0);\n> +       gainConstraints_.push_back(16.0);\n> +\n> +       fixedShutter_ = 0s;\n> +       fixedAnalogueGain_ = 0.0;\n>  }\n>\n> -void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats)\n> +/* Translate the IPU3 statistics into the default statistics region array\n> */\n> +void IPU3Agc::generateStats(const ipu3_uapi_stats_3a *stats)\n>  {\n> -       const struct ipu3_uapi_grid_config statsAeGrid =\n> stats->stats_4a_config.awb_config.grid;\n> -       Rectangle aeRegion = { statsAeGrid.x_start,\n> -                              statsAeGrid.y_start,\n> -                              static_cast<unsigned int>(statsAeGrid.x_end\n> - statsAeGrid.x_start) + 1,\n> -                              static_cast<unsigned int>(statsAeGrid.y_end\n> - statsAeGrid.y_start) + 1 };\n> -       Point topleft = aeRegion.topLeft();\n> -       int topleftX = topleft.x >> aeGrid_.block_width_log2;\n> -       int topleftY = topleft.y >> aeGrid_.block_height_log2;\n> -\n> -       /* Align to the grid cell width and height */\n> -       uint32_t startX = topleftX << aeGrid_.block_width_log2;\n> -       uint32_t startY = topleftY * aeGrid_.width <<\n> aeGrid_.block_width_log2;\n> -       uint32_t endX = (startX + (aeRegion.size().width >>\n> aeGrid_.block_width_log2)) << aeGrid_.block_width_log2;\n> -       uint32_t i, j;\n> -       uint32_t count = 0;\n> -\n> +       uint32_t regionWidth = round(aeGrid_.width /\n> static_cast<double>(kAgcStatsSizeX));\n> +       uint32_t regionHeight = round(aeGrid_.height /\n> static_cast<double>(kAgcStatsSizeY));\n>         uint32_t hist[knumHistogramBins] = { 0 };\n> -       for (j = topleftY;\n> -            j < topleftY + (aeRegion.size().height >>\n> aeGrid_.block_height_log2);\n> -            j++) {\n> -               for (i = startX + startY; i < endX + startY; i +=\n> kCellSize) {\n> -                       /*\n> -                        * The grid width (and maybe height) is not\n> reliable.\n> -                        * We observed a bit shift which makes the value\n> 160 to be 32 in the stats grid.\n> -                        * Use the one passed at init time.\n> -                        */\n> -                       if (stats->awb_raw_buffer.meta_data[i + 4 + j *\n> aeGrid_.width] == 0) {\n> -                               uint8_t Gr =\n> stats->awb_raw_buffer.meta_data[i + 0 + j * aeGrid_.width];\n> -                               uint8_t Gb =\n> stats->awb_raw_buffer.meta_data[i + 3 + j * aeGrid_.width];\n> -                               hist[(Gr + Gb) / 2]++;\n> -                               count++;\n> +\n> +       LOG(IPU3Agc, Debug) << \"[\" << (int)aeGrid_.width << \"x\" <<\n> (int)aeGrid_.height << \"] regions\"\n> +                           << \" scaled to [\" << regionWidth << \"x\" <<\n> regionHeight << \"] AGC stats\";\n> +\n> +       /*\n> +        * Generate a (kAgcStatsSizeX x kAgcStatsSizeY) array from the\n> IPU3 grid which is\n> +        * (aeGrid_.width x aeGrid_.height).\n> +        */\n> +       for (unsigned int j = 0; j < kAgcStatsSizeY * regionHeight; j++) {\n> +               for (unsigned int i = 0; i < kAgcStatsSizeX * regionWidth;\n> i++) {\n> +                       uint32_t cellPosition = j * aeGrid_.width + i;\n> +                       uint32_t cellX = (cellPosition / regionWidth) %\n> kAgcStatsSizeX;\n> +                       uint32_t cellY = ((cellPosition / aeGrid_.width) /\n> regionHeight) % kAgcStatsSizeY;\n> +\n> +                       uint32_t agcRegionPosition =\n> kAgcStatsRegions[cellY * kAgcStatsSizeX + cellX];\n> +                       weights_[agcRegionPosition] =\n> kCenteredWeights[agcRegionPosition];\n> +                       cellPosition *= sizeof(Ipu3AwbCell);\n> +\n> +                       /* Cast the initial IPU3 structure to simplify the\n> reading */\n> +                       Ipu3AwbCell *currentCell =\n> reinterpret_cast<Ipu3AwbCell *>(const_cast<uint8_t\n> *>(&stats->awb_raw_buffer.meta_data[cellPosition]));\n> +                       if (currentCell->satRatio == 0) {\n> +                               /* The cell is not saturated, use the\n> current cell */\n> +                               agcStats_[agcRegionPosition].counted++;\n> +                               uint32_t greenValue =\n> currentCell->greenRedAvg + currentCell->greenBlueAvg;\n> +                               hist[greenValue / 2]++;\n> +                               agcStats_[agcRegionPosition].gSum +=\n> greenValue / 2;\n> +                               agcStats_[agcRegionPosition].rSum +=\n> currentCell->redAvg;\n> +                               agcStats_[agcRegionPosition].bSum +=\n> currentCell->blueAvg;\n>                         }\n>                 }\n>         }\n>\n> -       /* Limit the gamma effect for now */\n> -       gamma_ = 1.1;\n> -\n>         /* Estimate the quantile mean of the top 2% of the histogram */\n>         iqMean_ = Histogram(Span<uint32_t>(hist)).interQuantileMean(0.98,\n> 1.0);\n>  }\n>\n> +void IPU3Agc::clearStats()\n> +{\n> +       for (unsigned int i = 0; i < kNumAgcWeightedZones; i++) {\n> +               agcStats_[i].bSum = 0;\n> +               agcStats_[i].rSum = 0;\n> +               agcStats_[i].gSum = 0;\n> +               agcStats_[i].counted = 0;\n> +               agcStats_[i].uncounted = 0;\n> +       }\n> +\n> +       awb_.blueGain = 1.0;\n> +       awb_.greenGain = 1.0;\n> +       awb_.redGain = 1.0;\n> +}\n> +\n>  void IPU3Agc::filterExposure()\n>  {\n> -       double speed = 0.2;\n> +       double speed = 0.08;\n>         if (prevExposure_ == 0s) {\n>                 /* DG stands for digital gain.*/\n>                 prevExposure_ = currentExposure_;\n> @@ -156,65 +162,131 @@ void IPU3Agc::filterExposure()\n>          * total exposure, as there might not be enough digital gain\n> available\n>          * in the ISP to hide it (which will cause nasty oscillation).\n>          */\n> -       double fastReduceThreshold = 0.4;\n> +       double fastReduceThreshold = 0.3;\n>         if (prevExposureNoDg_ <\n>             prevExposure_ * fastReduceThreshold)\n>                 prevExposureNoDg_ = prevExposure_ * fastReduceThreshold;\n>         LOG(IPU3Agc, Debug) << \"After filtering, total_exposure \" <<\n> prevExposure_;\n>  }\n>\n> -void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain)\n> +double IPU3Agc::computeInitialY(IspStatsRegion regions[], AwbStatus const\n> &awb,\n> +                               double weights[], double gain)\n>  {\n> -       updateControls_ = false;\n> +       /* Note how the calculation below means that equal weights give you\n> +        * \"average\" metering (i.e. all pixels equally important). */\n> +       double redSum = 0, greenSum = 0, blueSum = 0, pixelSum = 0;\n> +       for (unsigned int i = 0; i < kNumAgcWeightedZones; i++) {\n> +               double counted = regions[i].counted;\n> +               double rSum = std::min(regions[i].rSum * gain, ((1 <<\n> kPipelineBits) - 1) * counted);\n> +               double gSum = std::min(regions[i].gSum * gain, ((1 <<\n> kPipelineBits) - 1) * counted);\n> +               double bSum = std::min(regions[i].bSum * gain, ((1 <<\n> kPipelineBits) - 1) * counted);\n> +               redSum += rSum * weights[i];\n> +               greenSum += gSum * weights[i];\n> +               blueSum += bSum * weights[i];\n> +               pixelSum += counted * weights[i];\n> +       }\n> +       if (pixelSum == 0.0) {\n> +               LOG(IPU3Agc, Warning) << \"computeInitialY: pixel_sum is\n> zero\";\n> +               return 0;\n> +       }\n> +       double Y_sum = redSum * awb.redGain * .299 +\n> +                      greenSum * awb.greenGain * .587 +\n> +                      blueSum * awb.blueGain * .114;\n>\n> -       /* Algorithm initialization should wait for first valid frames */\n> -       /* \\todo - have a number of frames given by DelayedControls ?\n> -        * - implement a function for IIR */\n> -       if ((frameCount_ < kInitialFrameMinAECount) || (frameCount_ -\n> lastFrame_ < kFrameSkipCount))\n> -               return;\n> +       return Y_sum / pixelSum / (1 << kPipelineBits);\n> +}\n>\n> -       /* Are we correctly exposed ? */\n> -       if (std::abs(iqMean_ - kEvGainTarget * knumHistogramBins) <= 1) {\n> -               LOG(IPU3Agc, Debug) << \"!!! Good exposure with iqMean = \"\n> << iqMean_;\n> -               converged_ = true;\n> -       } else {\n> -               double newGain = kEvGainTarget * knumHistogramBins /\n> iqMean_;\n> -\n> -               /* extracted from Rpi::Agc::computeTargetExposure */\n> -               libcamera::utils::Duration currentShutter = exposure *\n> lineDuration_;\n> -               currentExposureNoDg_ = currentShutter * gain;\n> -               LOG(IPU3Agc, Debug) << \"Actual total exposure \" <<\n> currentExposureNoDg_\n> -                                   << \" Shutter speed \" << currentShutter\n> -                                   << \" Gain \" << gain;\n> -               currentExposure_ = currentExposureNoDg_ * newGain;\n> -               libcamera::utils::Duration maxTotalExposure =\n> maxExposureTime_ * kMaxGain;\n> -               currentExposure_ = std::min(currentExposure_,\n> maxTotalExposure);\n> -               LOG(IPU3Agc, Debug) << \"Target total exposure \" <<\n> currentExposure_;\n> -\n> -               /* \\todo: estimate if we need to desaturate */\n> -               filterExposure();\n> -\n> -               libcamera::utils::Duration newExposure = 0.0s;\n> -               if (currentShutter < maxExposureTime_) {\n> -                       exposure =\n> std::clamp(static_cast<uint32_t>(exposure * currentExposure_ /\n> currentExposureNoDg_), kMinExposure, kMaxExposure);\n> -                       newExposure = currentExposure_ / exposure;\n> -                       gain = std::clamp(static_cast<uint32_t>(gain *\n> currentExposure_ / newExposure), kMinGain, kMaxGain);\n> -                       updateControls_ = true;\n> -               } else if (currentShutter >= maxExposureTime_) {\n> -                       gain = std::clamp(static_cast<uint32_t>(gain *\n> currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain);\n> -                       newExposure = currentExposure_ / gain;\n> -                       exposure =\n> std::clamp(static_cast<uint32_t>(exposure * currentExposure_ /\n> newExposure), kMinExposure, kMaxExposure);\n> -                       updateControls_ = true;\n> +void IPU3Agc::computeTargetExposure(double gain)\n> +{\n> +       currentExposure_ = currentExposureNoDg_ * gain;\n> +       /* \\todo: have a list of shutter speeds */\n> +       Duration maxShutterSpeed = shutterConstraints_.back();\n> +       Duration maxTotalExposure = maxShutterSpeed *\n> gainConstraints_.back();\n> +\n> +       currentExposure_ = std::min(currentExposure_, maxTotalExposure);\n> +       LOG(IPU3Agc, Debug) << \"Target total_exposure \" <<\n> currentExposure_;\n> +}\n> +\n> +void IPU3Agc::divideUpExposure()\n> +{\n> +       Duration exposureValue = prevExposure_;\n> +       Duration shutterTime;\n> +       double analogueGain;\n> +       shutterTime = shutterConstraints_[0];\n> +       shutterTime = std::min(shutterTime, shutterConstraints_.back());\n> +       analogueGain = gainConstraints_[0];\n> +\n> +       if (shutterTime * analogueGain < exposureValue) {\n> +               for (unsigned int stage = 1;\n> +                    stage < gainConstraints_.size(); stage++) {\n> +                       if (fixedShutter_ == 0s) {\n> +                               Duration stageShutter =\n> +\n>  std::min(shutterConstraints_[stage], shutterConstraints_.back());\n> +                               if (stageShutter * analogueGain >=\n> +                                   exposureValue) {\n> +                                       shutterTime =\n> +                                               exposureValue /\n> analogueGain;\n> +                                       break;\n> +                               }\n> +                               shutterTime = stageShutter;\n> +                       }\n> +                       if (fixedAnalogueGain_ == 0.0) {\n> +                               if (gainConstraints_[stage] * shutterTime\n> >= exposureValue) {\n> +                                       analogueGain = exposureValue /\n> shutterTime;\n> +                                       break;\n> +                               }\n> +                               analogueGain = gainConstraints_[stage];\n> +                       }\n>                 }\n> -               LOG(IPU3Agc, Debug) << \"Adjust exposure \" << exposure *\n> lineDuration_ << \" and gain \" << gain;\n>         }\n> -       lastFrame_ = frameCount_;\n> +       LOG(IPU3Agc, Debug) << \"Divided up shutter and gain are \" <<\n> shutterTime << \" and \"\n> +                           << analogueGain;\n> +\n> +       /* \\todo: flickering avoidance ? */\n> +       filteredShutter_ = shutterTime;\n> +       filteredAnalogueGain_ = analogueGain;\n> +}\n> +\n> +void IPU3Agc::computeGain(double &currentGain)\n> +{\n> +       currentGain = 1.0;\n> +       /* \\todo: the target Y needs to be grabbed from a configuration */\n> +       double targetY = 0.162;\n> +       for (int i = 0; i < 8; i++) {\n> +               double initialY = computeInitialY(agcStats_, awb_,\n> weights_, currentGain);\n> +               double extra_gain = std::min(10.0, targetY / (initialY +\n> .001));\n> +\n> +               currentGain *= extra_gain;\n> +               LOG(IPU3Agc, Debug) << \"Initial Y \" << initialY << \"\n> target \" << targetY\n> +                                   << \" gives gain \" << currentGain;\n> +               if (extra_gain < 1.01)\n> +                       break;\n> +       }\n> +\n> +       double newGain = 128 / iqMean_;\n> +       LOG(IPU3Agc, Debug) << \"gain: \" << currentGain << \" new gain: \" <<\n> newGain;\n>  }\n>\n> -void IPU3Agc::process(const ipu3_uapi_stats_3a *stats, uint32_t\n> &exposure, double &gain)\n> +void IPU3Agc::process(const ipu3_uapi_stats_3a *stats, uint32_t\n> &exposure, double &analogueGain)\n>  {\n> -       processBrightness(stats);\n> -       lockExposureGain(exposure, gain);\n> +       ASSERT(stats->stats_3a_status.awb_en);\n> +       clearStats();\n> +       generateStats(stats);\n> +       currentShutter_ = exposure * lineDuration_;\n> +       /* \\todo: the gain needs to be calculated based on sensor\n> informations */\n> +       currentAnalogueGain_ = analogueGain;\n> +       currentExposureNoDg_ = currentShutter_ * currentAnalogueGain_;\n> +\n> +       double currentGain = 1;\n> +       computeGain(currentGain);\n> +       computeTargetExposure(currentGain);\n> +       filterExposure();\n> +       divideUpExposure();\n> +\n> +       exposure = filteredShutter_ / lineDuration_;\n> +       analogueGain = filteredAnalogueGain_;\n> +\n> +       updateControls_ = true;\n>         frameCount_++;\n>  }\n>\n> diff --git a/src/ipa/ipu3/ipu3_agc.h b/src/ipa/ipu3/ipu3_agc.h\n> index ce43c534..f1b1157b 100644\n> --- a/src/ipa/ipu3/ipu3_agc.h\n> +++ b/src/ipa/ipu3/ipu3_agc.h\n> @@ -35,8 +35,8 @@ public:\n>         IPU3Agc();\n>         ~IPU3Agc() = default;\n>\n> -       void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure,\n> double &gain);\n>         void initialise(struct ipu3_uapi_grid_config &bdsGrid, const\n> IPAConfigInfo &configInfo);\n> +       void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure,\n> double &analogueGain);\n>         bool converged() { return converged_; }\n>         bool updateControls() { return updateControls_; }\n>         /* \\todo Use a metadata exchange between IPAs */\n> @@ -46,6 +46,17 @@ private:\n>         void processBrightness(const ipu3_uapi_stats_3a *stats);\n>         void filterExposure();\n>         void lockExposureGain(uint32_t &exposure, double &gain);\n> +       void generateStats(const ipu3_uapi_stats_3a *stats);\n> +       void clearStats();\n> +       void generateZones(std::vector<RGB> &zones);\n> +       double computeInitialY(IspStatsRegion regions[], AwbStatus const\n> &awb, double weights[], double gain);\n> +       void computeTargetExposure(double currentGain);\n> +       void divideUpExposure();\n> +       void computeGain(double &currentGain);\n> +\n> +       AwbStatus awb_;\n> +       double weights_[kNumAgcWeightedZones];\n> +       IspStatsRegion agcStats_[kNumAgcWeightedZones];\n>\n>         struct ipu3_uapi_grid_config aeGrid_;\n>         ControlInfoMap ctrls_;\n> @@ -72,6 +83,16 @@ private:\n>         Duration prevExposureNoDg_;\n>         Duration currentExposure_;\n>         Duration currentExposureNoDg_;\n> +\n> +       Duration currentShutter_;\n> +       std::vector<Duration> shutterConstraints_;\n> +       Duration fixedShutter_;\n> +       Duration filteredShutter_;\n> +\n> +       double currentAnalogueGain_;\n> +       std::vector<double> gainConstraints_;\n> +       double fixedAnalogueGain_;\n> +       double filteredAnalogueGain_;\n>  };\n>\n>  } /* namespace ipa::ipu3 */\n> --\n> 2.30.2\n>\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 229D8C3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 29 Jun 2021 13:22:38 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7B767684EC;\n\tTue, 29 Jun 2021 15:22:37 +0200 (CEST)","from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com\n\t[IPv6:2a00:1450:4864:20::42b])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 43C09684CB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 29 Jun 2021 15:22:36 +0200 (CEST)","by mail-wr1-x42b.google.com with SMTP id i94so25853312wri.4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 29 Jun 2021 06:22:36 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"NGTxd7os\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=gSuaYru/aoMrQ8pqbyZyiLOU+UKigC2r3whn3RHV8d0=;\n\tb=NGTxd7os1dCo2GMe4hATuyXlbfyTOhUnb6jEXCv4zdIF0jBY+ETXH+5HyvdVtyHD4u\n\tjYzbh4w1XvjEWwhrSOqg77YIrvxwG3YVwX1lu9/UD5R8QS+4MDuDJQ6fWvqfhoRfwnpU\n\tRQ7mTMKFN1+bsi/p3JGrxs12RKZd9WfYGb5dm5qm0BW/Z7GhLr99ET2O3BiC+W3zxRZZ\n\tCUeDUKkI2auNXrACP03MniERXVVGeoJNxKl75NjTth+b0cQYA7GM1JJkjfVct2+R2JkV\n\tgEQqHZ8hY5f4VzTmssbIWOLOk8i2uO2iRyBlix9ce2Ag/UH/rkck6egPM1QSFtzFd6wO\n\tNz8g==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=gSuaYru/aoMrQ8pqbyZyiLOU+UKigC2r3whn3RHV8d0=;\n\tb=Mjd8ZpoarFxDfmNzkwDMPc1b3HfEYMiLq1N8r0yK3t9oujlVfcs5ql47fcKub7dThY\n\tCgWy8bJY+7hGCQHkQcz40MN05do7oEe8639D+p2LBMUnwmQHVjmWb8gzi79sZl9olO+t\n\tIPGXcmoXNuQM/33FgtQ5eh62K5fMQjBQ1heT92cTva0h+5pIsXfgyzFp/BMvmf8o8QLv\n\t3b/jBw+7glnLZjIa5b3QLb4kAPS4w2xoJA2mQHNXyE0QpJjZCVWtuWlMWlVp235TsXtY\n\tUGl9aP6YmSY1qcylcQozIK9T/bhY1PQnRDPKgM0YGkUPZrfikPfd7GW1br2muf79/Mn0\n\t1U3A==","X-Gm-Message-State":"AOAM53340qutkWivLlAw/w/X7cvPTgAuXkh3KcHTiRYtb29R8xl4YaxA\n\t7s7vYnfVSL3N1e2qdrzbAimxkOP9xLGd+u5AV7aqDw==","X-Google-Smtp-Source":"ABdhPJyDwIKoadbB9jljbhGvaC1OY7RUiiX7gb1/sE/42xfG1ZlRBhbpxeXwI/dqXS4TsfTtqYvlFyz5drhvfvgxBnc=","X-Received":"by 2002:a5d:4dd2:: with SMTP id\n\tf18mr33113995wru.86.1624972955844; \n\tTue, 29 Jun 2021 06:22:35 -0700 (PDT)","MIME-Version":"1.0","References":"<20210628202255.138874-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20210628202255.138874-8-jeanmichel.hautbois@ideasonboard.com>","In-Reply-To":"<20210628202255.138874-8-jeanmichel.hautbois@ideasonboard.com>","From":"David Plowman <david.plowman@raspberrypi.com>","Date":"Tue, 29 Jun 2021 14:22:25 +0100","Message-ID":"<CAHW6GY+MTWkp0fCyUjDNkB4uK6KCL-mHD-78GP5ugLXFqeSheA@mail.gmail.com>","To":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"000000000000cd930105c5e77f53\"","Subject":"Re: [libcamera-devel] [PATCH v1 7/7] ipa: ipu3: Implement a new AGC\n\talgorithm","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":17915,"web_url":"https://patchwork.libcamera.org/comment/17915/","msgid":"<YNsmTZxQ0ktVEoD7@pendragon.ideasonboard.com>","date":"2021-06-29T13:55:25","subject":"Re: [libcamera-devel] [PATCH v1 7/7] ipa: ipu3: Implement a new AGC\n\talgorithm","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi David,\n\nOn Tue, Jun 29, 2021 at 02:22:25PM +0100, David Plowman wrote:\n> Hi Jean-Michel\n> \n> Thanks for your work - very happy to see our code being useful elsewhere!\n> \n> One minor thing - would it be ok to include a Raspberry Pi copyright\n> alongside the IdeasonBoard one?\n\nI haven't looked at the code yet, but if a substantial part of it comes\nfrom the RPi implementation, it should certainly mention appropriate\nauthorship and copyright information. In the kernel, we often mention it\nas follows:\n\n * Based on the implementation from the Raspberry Pi IPA,\n * Copyright (C) 2019-2021, Raspberry Pi (Trading) Ltd.\n\nWould that be fine with you ?\n\n> On Mon, 28 Jun 2021 at 21:23, Jean-Michel Hautboiswrote:\n> \n> > This one comes from RPi for most if it, except that we are not\n> > exchanging any metadata between algorithms for now.\n> > When process() is called, the current analogue gain and shutter time are\n> > calculated. The AWB stats from IPU3 are then parsed to generate new\n> > statistics dedicated to AGC. This new grid is used to estimate the\n> > luminance and each region is weighted. A default centered metering is\n> > used as is should be the most used one.\n> >\n> > After calculating weighted regions, analogue gain and shutter time are\n> > divided up and the values are then sent back to the IPAIPU3.\n> >\n> > Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n> > ---\n> >  src/ipa/ipu3/ipu3_agc.cpp | 276 ++++++++++++++++++++++++--------------\n> >  src/ipa/ipu3/ipu3_agc.h   |  23 +++-\n> >  2 files changed, 196 insertions(+), 103 deletions(-)","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id AE961C321F\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 29 Jun 2021 13:55:29 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6A839684D2;\n\tTue, 29 Jun 2021 15:55:29 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0846F684CB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 29 Jun 2021 15:55:28 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8E30F4AD;\n\tTue, 29 Jun 2021 15:55:27 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"L0e1ju1a\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1624974927;\n\tbh=L0Kh3LKMNYrVnbcF+D7LgFIGRiuHeg207PUXBZAvK6I=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=L0e1ju1abg1Gplw2bfgvJCDA28c0jDsnEOgjJ9HTZ7b0EcG1AJ03jzc9zZmnspfPn\n\t2lVE7lpOwC3YLDy0BX282prwSxyNCVqBKRY9HVKLDHfdp+Lleb4spRQiSPLi0rOrmh\n\tAUpkY3b4gghhh4PSCXRhTZwBtP21VoU/ud9gCcME=","Date":"Tue, 29 Jun 2021 16:55:25 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"David Plowman <david.plowman@raspberrypi.com>","Message-ID":"<YNsmTZxQ0ktVEoD7@pendragon.ideasonboard.com>","References":"<20210628202255.138874-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20210628202255.138874-8-jeanmichel.hautbois@ideasonboard.com>\n\t<CAHW6GY+MTWkp0fCyUjDNkB4uK6KCL-mHD-78GP5ugLXFqeSheA@mail.gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<CAHW6GY+MTWkp0fCyUjDNkB4uK6KCL-mHD-78GP5ugLXFqeSheA@mail.gmail.com>","Subject":"Re: [libcamera-devel] [PATCH v1 7/7] ipa: ipu3: Implement a new AGC\n\talgorithm","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":17916,"web_url":"https://patchwork.libcamera.org/comment/17916/","msgid":"<CAHW6GYJVTNP0y1wMod0yzicnHDvOfQ50RW9Rxrn6Gg2fU59gAQ@mail.gmail.com>","date":"2021-06-29T14:03:48","subject":"Re: [libcamera-devel] [PATCH v1 7/7] ipa: ipu3: Implement a new AGC\n\talgorithm","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/people/42/","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"content":"HI Laurent\n\nYes, I think that would be fine.\n\nThanks\nDavid\n\nOn Tue, 29 Jun 2021 at 14:55, Laurent Pinchart <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> Hi David,\n>\n> On Tue, Jun 29, 2021 at 02:22:25PM +0100, David Plowman wrote:\n> > Hi Jean-Michel\n> >\n> > Thanks for your work - very happy to see our code being useful elsewhere!\n> >\n> > One minor thing - would it be ok to include a Raspberry Pi copyright\n> > alongside the IdeasonBoard one?\n>\n> I haven't looked at the code yet, but if a substantial part of it comes\n> from the RPi implementation, it should certainly mention appropriate\n> authorship and copyright information. In the kernel, we often mention it\n> as follows:\n>\n>  * Based on the implementation from the Raspberry Pi IPA,\n>  * Copyright (C) 2019-2021, Raspberry Pi (Trading) Ltd.\n>\n> Would that be fine with you ?\n>\n> > On Mon, 28 Jun 2021 at 21:23, Jean-Michel Hautboiswrote:\n> >\n> > > This one comes from RPi for most if it, except that we are not\n> > > exchanging any metadata between algorithms for now.\n> > > When process() is called, the current analogue gain and shutter time\n> are\n> > > calculated. The AWB stats from IPU3 are then parsed to generate new\n> > > statistics dedicated to AGC. This new grid is used to estimate the\n> > > luminance and each region is weighted. A default centered metering is\n> > > used as is should be the most used one.\n> > >\n> > > After calculating weighted regions, analogue gain and shutter time are\n> > > divided up and the values are then sent back to the IPAIPU3.\n> > >\n> > > Signed-off-by: Jean-Michel Hautbois <\n> jeanmichel.hautbois@ideasonboard.com>\n> > > ---\n> > >  src/ipa/ipu3/ipu3_agc.cpp | 276 ++++++++++++++++++++++++--------------\n> > >  src/ipa/ipu3/ipu3_agc.h   |  23 +++-\n> > >  2 files changed, 196 insertions(+), 103 deletions(-)\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 0914CC3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 29 Jun 2021 14:04:02 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5E919684D2;\n\tTue, 29 Jun 2021 16:04:01 +0200 (CEST)","from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com\n\t[IPv6:2a00:1450:4864:20::32f])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0EAD3684CB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 29 Jun 2021 16:04:00 +0200 (CEST)","by mail-wm1-x32f.google.com with SMTP id\n\tm9-20020a05600c3b09b02901f246b43bbeso506431wms.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 29 Jun 2021 07:04:00 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"bKp2RNQ2\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=/Tr2YHwO5yVimBBpZ5Dp45iZaL2LhIISi5kM4c4onVI=;\n\tb=bKp2RNQ209cpx4ekNiH1bPqpne6BXAX3XdPQWHHJAVInMJBhFTB3doVGzwOSghs3ry\n\t9KPeG9c2x3kIQKW3TUvdXg7hbj+bXPgEawk9R9nw/qGSXoL9A4vWDQOTOQRuUWVF4Ati\n\tbdJ460f4i7jikpqtTMLPZrAIT2VZRw/hQEAJzmWWesswLvJm6jmz+gvReRYZQZ6sZN/l\n\tOlBC6U1BmkPgr9uiMZfO53SxKqMDJeJHq2sBm8qwKop+GDDKvoqpJKISsucyDvrMt49v\n\tJs3SjpoYI0JOr3sQgRtqQV3XhFPkSuxWNWF3d5RNZ7WYt6elOAZlJIV+xAKwzZdoQCQg\n\tmIdA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=/Tr2YHwO5yVimBBpZ5Dp45iZaL2LhIISi5kM4c4onVI=;\n\tb=Ua9Lwzx4gwKjUeAoT8qgC1A+cEKwS0duixxrlTII8S+ikFM1sPv5FNcIi8SacjrkIs\n\tkvGDcb9gtS0lfHajOfzBgwrXbTVGsVWBfXTQkHEIXGfOtK7/tJFJxpRrz7qTXDWUs/4q\n\t5tS+KZ+z3oRGBUbKLYa9qv5nKGbUr6tSzxlPvXjrhcOivTMf/svvLd/0FPD2b+RQQmCO\n\tHTChjCCvfiMdTA+iTSJD63216wvMt/y+aa3F1yfBlI0o/GfKNcEc7B9Vqh9GiyIuPIwc\n\tYgB/EFsZBnDChHOO0lUntmarBLLhfWZD1QE1BrZ1+9N7qJk7Rjzf20K24Wk8B2MlpXa/\n\t6qew==","X-Gm-Message-State":"AOAM533V4TOkIwhU/b1bq6dT11DgIGgDiFMEZIzrhww7HQ1jqZvWyyzd\n\taPthHKxMatRfIXxcVwLrb7jTC7Aw0wHeAofDjg6nDQ==","X-Google-Smtp-Source":"ABdhPJzMoZsCx2QGraP7I+RMMk0SWwmg2BNqCQHpRz6zDPtDUwo7I49jhwDy9gNFQgm7sD+QTckqrHRt/OK2x2qtZio=","X-Received":"by 2002:a05:600c:17c3:: with SMTP id\n\ty3mr6790017wmo.40.1624975439617; \n\tTue, 29 Jun 2021 07:03:59 -0700 (PDT)","MIME-Version":"1.0","References":"<20210628202255.138874-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20210628202255.138874-8-jeanmichel.hautbois@ideasonboard.com>\n\t<CAHW6GY+MTWkp0fCyUjDNkB4uK6KCL-mHD-78GP5ugLXFqeSheA@mail.gmail.com>\n\t<YNsmTZxQ0ktVEoD7@pendragon.ideasonboard.com>","In-Reply-To":"<YNsmTZxQ0ktVEoD7@pendragon.ideasonboard.com>","From":"David Plowman <david.plowman@raspberrypi.com>","Date":"Tue, 29 Jun 2021 15:03:48 +0100","Message-ID":"<CAHW6GYJVTNP0y1wMod0yzicnHDvOfQ50RW9Rxrn6Gg2fU59gAQ@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"000000000000d8f01705c5e813f0\"","Subject":"Re: [libcamera-devel] [PATCH v1 7/7] ipa: ipu3: Implement a new AGC\n\talgorithm","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":17920,"web_url":"https://patchwork.libcamera.org/comment/17920/","msgid":"<0163d851-1a9c-721e-0688-8d0fc3c2a7fc@ideasonboard.com>","date":"2021-06-29T15:34:29","subject":"Re: [libcamera-devel] [PATCH v1 7/7] ipa: ipu3: Implement a new AGC\n\talgorithm","submitter":{"id":75,"url":"https://patchwork.libcamera.org/api/people/75/","name":"Jean-Michel Hautbois","email":"jeanmichel.hautbois@ideasonboard.com"},"content":"Hi David !\n\nOn 29/06/2021 16:03, David Plowman wrote:\n> HI Laurent\n> \n> Yes, I think that would be fine.\n> \n> Thanks\n> David\n> \n> On Tue, 29 Jun 2021 at 14:55, Laurent Pinchart\n> <laurent.pinchart@ideasonboard.com\n> <mailto:laurent.pinchart@ideasonboard.com>> wrote:\n> \n>     Hi David,\n> \n>     On Tue, Jun 29, 2021 at 02:22:25PM +0100, David Plowman wrote:\n>     > Hi Jean-Michel\n>     >\n>     > Thanks for your work - very happy to see our code being useful\n>     elsewhere!\n>     >\n>     > One minor thing - would it be ok to include a Raspberry Pi copyright\n>     > alongside the IdeasonBoard one?\n> \n>     I haven't looked at the code yet, but if a substantial part of it comes\n>     from the RPi implementation, it should certainly mention appropriate\n>     authorship and copyright information. In the kernel, we often mention it\n>     as follows:\n> \n>      * Based on the implementation from the Raspberry Pi IPA,\n>      * Copyright (C) 2019-2021, Raspberry Pi (Trading) Ltd.\n> \n\nI missed it, I wanted to do it !\nDone on my -v2 ;-)\nThe implementation is a lot from RPi, but with small differences, if you\nhave comments, please shot :-).\n\n>     Would that be fine with you ?\n> \n>     > On Mon, 28 Jun 2021 at 21:23, Jean-Michel Hautboiswrote:\n>     >\n>     > > This one comes from RPi for most if it, except that we are not\n>     > > exchanging any metadata between algorithms for now.\n>     > > When process() is called, the current analogue gain and shutter\n>     time are\n>     > > calculated. The AWB stats from IPU3 are then parsed to generate new\n>     > > statistics dedicated to AGC. This new grid is used to estimate the\n>     > > luminance and each region is weighted. A default centered\n>     metering is\n>     > > used as is should be the most used one.\n>     > >\n>     > > After calculating weighted regions, analogue gain and shutter\n>     time are\n>     > > divided up and the values are then sent back to the IPAIPU3.\n>     > >\n>     > > Signed-off-by: Jean-Michel Hautbois\n>     <jeanmichel.hautbois@ideasonboard.com\n>     <mailto:jeanmichel.hautbois@ideasonboard.com>>\n>     > > ---\n>     > >  src/ipa/ipu3/ipu3_agc.cpp | 276\n>     ++++++++++++++++++++++++--------------\n>     > >  src/ipa/ipu3/ipu3_agc.h   |  23 +++-\n>     > >  2 files changed, 196 insertions(+), 103 deletions(-)\n> \n>     -- \n>     Regards,\n> \n>     Laurent Pinchart\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 00770C3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 29 Jun 2021 15:34:33 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 59A42684E9;\n\tTue, 29 Jun 2021 17:34:33 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 135DB684CB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 29 Jun 2021 17:34:32 +0200 (CEST)","from tatooine.ideasonboard.com (unknown\n\t[IPv6:2a01:e0a:169:7140:d4ff:199e:6bde:2ea6])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 925D54AD;\n\tTue, 29 Jun 2021 17:34:31 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"erZj7HV/\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1624980871;\n\tbh=DrtHfMAQXm85JktHd8ZYT8GVJDA/69e9L+HFo1ka5Co=;\n\th=Subject:To:Cc:References:From:Date:In-Reply-To:From;\n\tb=erZj7HV/zO3vD1GcfGngGzgJHdfSwtBzJNxMvpI2IrL5WIGX+jUGKIeBGQB+O72ly\n\ta6hHa7RsUviU85lPdbs7BTDQaiWsCkhtmdhaT04iXgy4IPP1SzPHKWheESLTWAFphr\n\tHSe7f/3qMXXhQm9HSocaQXhLOB10s9b4tlknGuBs=","To":"David Plowman <david.plowman@raspberrypi.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20210628202255.138874-1-jeanmichel.hautbois@ideasonboard.com>\n\t<20210628202255.138874-8-jeanmichel.hautbois@ideasonboard.com>\n\t<CAHW6GY+MTWkp0fCyUjDNkB4uK6KCL-mHD-78GP5ugLXFqeSheA@mail.gmail.com>\n\t<YNsmTZxQ0ktVEoD7@pendragon.ideasonboard.com>\n\t<CAHW6GYJVTNP0y1wMod0yzicnHDvOfQ50RW9Rxrn6Gg2fU59gAQ@mail.gmail.com>","From":"Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>","Message-ID":"<0163d851-1a9c-721e-0688-8d0fc3c2a7fc@ideasonboard.com>","Date":"Tue, 29 Jun 2021 17:34:29 +0200","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.11.0","MIME-Version":"1.0","In-Reply-To":"<CAHW6GYJVTNP0y1wMod0yzicnHDvOfQ50RW9Rxrn6Gg2fU59gAQ@mail.gmail.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH v1 7/7] ipa: ipu3: Implement a new AGC\n\talgorithm","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]