ipa: ipu3: Calculate line duration from IPACameraSensorInfo

Squash \todo by calculating line duration from IPACameraSensorInfo,
now passed in, to IPU3Agc::initialise().

Since line duration is now calculated from real values, store it as a
private member in IPU3Agc class. As a further step, replace the
associated global constant, kMaxExposureTime, with a private IPU3Agc
class member as well, and assign its value correspondingly in
IPU3Agc::initialise(), similar to previous precedence.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Tested-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
This commit is contained in:
Umang Jain 2021-06-08 13:12:23 +05:30
parent 1e5cee7017
commit 384a53d3cd
3 changed files with 20 additions and 13 deletions

View file

@ -174,7 +174,7 @@ void IPAIPU3::configure(const IPAConfigInfo &configInfo)
awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_); awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
agcAlgo_ = std::make_unique<IPU3Agc>(); agcAlgo_ = std::make_unique<IPU3Agc>();
agcAlgo_->initialise(bdsGrid_); agcAlgo_->initialise(bdsGrid_, configInfo.sensorInfo);
} }
void IPAIPU3::mapBuffers(const std::vector<IPABuffer> &buffers) void IPAIPU3::mapBuffers(const std::vector<IPABuffer> &buffers)

View file

@ -11,6 +11,8 @@
#include <cmath> #include <cmath>
#include <numeric> #include <numeric>
#include <libcamera/ipa/core_ipa_interface.h>
#include "libcamera/internal/log.h" #include "libcamera/internal/log.h"
#include "libipa/histogram.h" #include "libipa/histogram.h"
@ -39,11 +41,6 @@ static constexpr uint32_t kMaxGain = kMaxISO / 100;
static constexpr uint32_t kMinExposure = 1; static constexpr uint32_t kMinExposure = 1;
static constexpr uint32_t kMaxExposure = 1976; static constexpr uint32_t kMaxExposure = 1976;
/* \todo those should be got from IPACameraSensorInfo ! */
/* line duration in microseconds */
static constexpr double kLineDuration = 16.8;
static constexpr double kMaxExposureTime = kMaxExposure * kLineDuration;
/* Histogram constants */ /* Histogram constants */
static constexpr uint32_t knumHistogramBins = 256; static constexpr uint32_t knumHistogramBins = 256;
static constexpr double kEvGainTarget = 0.5; static constexpr double kEvGainTarget = 0.5;
@ -54,14 +51,19 @@ static constexpr uint8_t kCellSize = 8;
IPU3Agc::IPU3Agc() IPU3Agc::IPU3Agc()
: frameCount_(0), lastFrame_(0), converged_(false), : frameCount_(0), lastFrame_(0), converged_(false),
updateControls_(false), iqMean_(0.0), gamma_(1.0), updateControls_(false), iqMean_(0.0), gamma_(1.0),
lineDuration_(0.0), maxExposureTime_(0.0),
prevExposure_(0.0), prevExposureNoDg_(0.0), prevExposure_(0.0), prevExposureNoDg_(0.0),
currentExposure_(0.0), currentExposureNoDg_(0.0) currentExposure_(0.0), currentExposureNoDg_(0.0)
{ {
} }
void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid) void IPU3Agc::initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo)
{ {
aeGrid_ = bdsGrid; aeGrid_ = bdsGrid;
/* line duration in microseconds */
lineDuration_ = sensorInfo.lineLength * 1000000ULL / static_cast<double>(sensorInfo.pixelRate);
maxExposureTime_ = kMaxExposure * lineDuration_;
} }
void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats) void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats)
@ -160,13 +162,13 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain)
double newGain = kEvGainTarget * knumHistogramBins / iqMean_; double newGain = kEvGainTarget * knumHistogramBins / iqMean_;
/* extracted from Rpi::Agc::computeTargetExposure */ /* extracted from Rpi::Agc::computeTargetExposure */
double currentShutter = exposure * kLineDuration; double currentShutter = exposure * lineDuration_;
currentExposureNoDg_ = currentShutter * gain; currentExposureNoDg_ = currentShutter * gain;
LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_ LOG(IPU3Agc, Debug) << "Actual total exposure " << currentExposureNoDg_
<< " Shutter speed " << currentShutter << " Shutter speed " << currentShutter
<< " Gain " << gain; << " Gain " << gain;
currentExposure_ = currentExposureNoDg_ * newGain; currentExposure_ = currentExposureNoDg_ * newGain;
double maxTotalExposure = kMaxExposureTime * kMaxGain; double maxTotalExposure = maxExposureTime_ * kMaxGain;
currentExposure_ = std::min(currentExposure_, maxTotalExposure); currentExposure_ = std::min(currentExposure_, maxTotalExposure);
LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_; LOG(IPU3Agc, Debug) << "Target total exposure " << currentExposure_;
@ -174,18 +176,18 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, uint32_t &gain)
filterExposure(); filterExposure();
double newExposure = 0.0; double newExposure = 0.0;
if (currentShutter < kMaxExposureTime) { if (currentShutter < maxExposureTime_) {
exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure); exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / currentExposureNoDg_), kMinExposure, kMaxExposure);
newExposure = currentExposure_ / exposure; newExposure = currentExposure_ / exposure;
gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain); gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / newExposure), kMinGain, kMaxGain);
updateControls_ = true; updateControls_ = true;
} else if (currentShutter >= kMaxExposureTime) { } else if (currentShutter >= maxExposureTime_) {
gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain); gain = std::clamp(static_cast<uint32_t>(gain * currentExposure_ / currentExposureNoDg_), kMinGain, kMaxGain);
newExposure = currentExposure_ / gain; newExposure = currentExposure_ / gain;
exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure); exposure = std::clamp(static_cast<uint32_t>(exposure * currentExposure_ / newExposure), kMinExposure, kMaxExposure);
updateControls_ = true; updateControls_ = true;
} }
LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * kLineDuration << " and gain " << gain; LOG(IPU3Agc, Debug) << "Adjust exposure " << exposure * lineDuration_ << " and gain " << gain;
} }
lastFrame_ = frameCount_; lastFrame_ = frameCount_;
} }

View file

@ -18,6 +18,8 @@
namespace libcamera { namespace libcamera {
class IPACameraSensorInfo;
namespace ipa::ipu3 { namespace ipa::ipu3 {
class IPU3Agc : public Algorithm class IPU3Agc : public Algorithm
@ -26,7 +28,7 @@ public:
IPU3Agc(); IPU3Agc();
~IPU3Agc() = default; ~IPU3Agc() = default;
void initialise(struct ipu3_uapi_grid_config &bdsGrid); void initialise(struct ipu3_uapi_grid_config &bdsGrid, const IPACameraSensorInfo &sensorInfo);
void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, uint32_t &gain); void process(const ipu3_uapi_stats_3a *stats, uint32_t &exposure, uint32_t &gain);
bool converged() { return converged_; } bool converged() { return converged_; }
bool updateControls() { return updateControls_; } bool updateControls() { return updateControls_; }
@ -49,6 +51,9 @@ private:
double iqMean_; double iqMean_;
double gamma_; double gamma_;
double lineDuration_;
double maxExposureTime_;
double prevExposure_; double prevExposure_;
double prevExposureNoDg_; double prevExposureNoDg_;
double currentExposure_; double currentExposure_;