ipa: ipu3: Move IPU3 agc into algorithms
Now that the interface is properly used by the AGC class, move it into ipa::ipu3::algorithms and let the loops do the calls. As we need to exchange the exposure_ and gain_ by passing them through the FrameContext, use the calculated values in setControls() function to ease the reading. Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
b145ae4242
commit
93802f600c
5 changed files with 28 additions and 32 deletions
|
@ -5,7 +5,7 @@
|
||||||
* ipu3_agc.cpp - AGC/AEC control algorithm
|
* ipu3_agc.cpp - AGC/AEC control algorithm
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ipu3_agc.h"
|
#include "agc.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
@ -21,7 +21,7 @@ namespace libcamera {
|
||||||
|
|
||||||
using namespace std::literals::chrono_literals;
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
namespace ipa::ipu3 {
|
namespace ipa::ipu3::algorithms {
|
||||||
|
|
||||||
LOG_DEFINE_CATEGORY(IPU3Agc)
|
LOG_DEFINE_CATEGORY(IPU3Agc)
|
||||||
|
|
||||||
|
@ -50,14 +50,14 @@ static constexpr double kEvGainTarget = 0.5;
|
||||||
/* A cell is 8 bytes and contains averages for RGB values and saturation ratio */
|
/* A cell is 8 bytes and contains averages for RGB values and saturation ratio */
|
||||||
static constexpr uint8_t kCellSize = 8;
|
static constexpr uint8_t kCellSize = 8;
|
||||||
|
|
||||||
IPU3Agc::IPU3Agc()
|
Agc::Agc()
|
||||||
: frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s),
|
: frameCount_(0), lastFrame_(0), iqMean_(0.0), lineDuration_(0s),
|
||||||
maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s),
|
maxExposureTime_(0s), prevExposure_(0s), prevExposureNoDg_(0s),
|
||||||
currentExposure_(0s), currentExposureNoDg_(0s)
|
currentExposure_(0s), currentExposureNoDg_(0s)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int IPU3Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo)
|
int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo)
|
||||||
{
|
{
|
||||||
aeGrid_ = context.configuration.grid.bdsGrid;
|
aeGrid_ = context.configuration.grid.bdsGrid;
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ int IPU3Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats)
|
void Agc::processBrightness(const ipu3_uapi_stats_3a *stats)
|
||||||
{
|
{
|
||||||
const struct ipu3_uapi_grid_config statsAeGrid = stats->stats_4a_config.awb_config.grid;
|
const struct ipu3_uapi_grid_config statsAeGrid = stats->stats_4a_config.awb_config.grid;
|
||||||
Rectangle aeRegion = { statsAeGrid.x_start,
|
Rectangle aeRegion = { statsAeGrid.x_start,
|
||||||
|
@ -109,7 +109,7 @@ void IPU3Agc::processBrightness(const ipu3_uapi_stats_3a *stats)
|
||||||
iqMean_ = Histogram(Span<uint32_t>(hist)).interQuantileMean(0.98, 1.0);
|
iqMean_ = Histogram(Span<uint32_t>(hist)).interQuantileMean(0.98, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPU3Agc::filterExposure()
|
void Agc::filterExposure()
|
||||||
{
|
{
|
||||||
double speed = 0.2;
|
double speed = 0.2;
|
||||||
if (prevExposure_ == 0s) {
|
if (prevExposure_ == 0s) {
|
||||||
|
@ -143,7 +143,7 @@ void IPU3Agc::filterExposure()
|
||||||
LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << prevExposure_;
|
LOG(IPU3Agc, Debug) << "After filtering, total_exposure " << prevExposure_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain)
|
void Agc::lockExposureGain(uint32_t &exposure, double &gain)
|
||||||
{
|
{
|
||||||
/* Algorithm initialization should wait for first valid frames */
|
/* Algorithm initialization should wait for first valid frames */
|
||||||
/* \todo - have a number of frames given by DelayedControls ?
|
/* \todo - have a number of frames given by DelayedControls ?
|
||||||
|
@ -186,7 +186,7 @@ void IPU3Agc::lockExposureGain(uint32_t &exposure, double &gain)
|
||||||
lastFrame_ = frameCount_;
|
lastFrame_ = frameCount_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPU3Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)
|
void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)
|
||||||
{
|
{
|
||||||
uint32_t &exposure = context.frameContext.agc.exposure;
|
uint32_t &exposure = context.frameContext.agc.exposure;
|
||||||
double &gain = context.frameContext.agc.gain;
|
double &gain = context.frameContext.agc.gain;
|
||||||
|
@ -195,6 +195,6 @@ void IPU3Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)
|
||||||
frameCount_++;
|
frameCount_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace ipa::ipu3 */
|
} /* namespace ipa::ipu3::algorithms */
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
|
@ -2,10 +2,10 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2021, Ideas On Board
|
* Copyright (C) 2021, Ideas On Board
|
||||||
*
|
*
|
||||||
* ipu3_agc.h - IPU3 AGC/AEC control algorithm
|
* agc.h - IPU3 AGC/AEC control algorithm
|
||||||
*/
|
*/
|
||||||
#ifndef __LIBCAMERA_IPU3_AGC_H__
|
#ifndef __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__
|
||||||
#define __LIBCAMERA_IPU3_AGC_H__
|
#define __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__
|
||||||
|
|
||||||
#include <linux/intel-ipu3.h>
|
#include <linux/intel-ipu3.h>
|
||||||
|
|
||||||
|
@ -13,21 +13,21 @@
|
||||||
|
|
||||||
#include <libcamera/geometry.h>
|
#include <libcamera/geometry.h>
|
||||||
|
|
||||||
#include "algorithms/algorithm.h"
|
#include "algorithm.h"
|
||||||
|
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
|
|
||||||
struct IPACameraSensorInfo;
|
struct IPACameraSensorInfo;
|
||||||
|
|
||||||
namespace ipa::ipu3 {
|
namespace ipa::ipu3::algorithms {
|
||||||
|
|
||||||
using utils::Duration;
|
using utils::Duration;
|
||||||
|
|
||||||
class IPU3Agc : public Algorithm
|
class Agc : public Algorithm
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IPU3Agc();
|
Agc();
|
||||||
~IPU3Agc() = default;
|
~Agc() = default;
|
||||||
|
|
||||||
int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
|
int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
|
||||||
void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;
|
void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;
|
||||||
|
@ -53,8 +53,8 @@ private:
|
||||||
Duration currentExposureNoDg_;
|
Duration currentExposureNoDg_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ipa::ipu3 */
|
} /* namespace ipa::ipu3::algorithms */
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
||||||
#endif /* __LIBCAMERA_IPU3_AGC_H__ */
|
#endif /* __LIBCAMERA_IPU3_ALGORITHMS_AGC_H__ */
|
|
@ -1,6 +1,7 @@
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
ipu3_ipa_algorithms = files([
|
ipu3_ipa_algorithms = files([
|
||||||
|
'agc.cpp',
|
||||||
'algorithm.cpp',
|
'algorithm.cpp',
|
||||||
'awb.cpp',
|
'awb.cpp',
|
||||||
'tone_mapping.cpp',
|
'tone_mapping.cpp',
|
||||||
|
|
|
@ -29,10 +29,10 @@
|
||||||
|
|
||||||
#include "libcamera/internal/mapped_framebuffer.h"
|
#include "libcamera/internal/mapped_framebuffer.h"
|
||||||
|
|
||||||
|
#include "algorithms/agc.h"
|
||||||
#include "algorithms/algorithm.h"
|
#include "algorithms/algorithm.h"
|
||||||
#include "algorithms/awb.h"
|
#include "algorithms/awb.h"
|
||||||
#include "algorithms/tone_mapping.h"
|
#include "algorithms/tone_mapping.h"
|
||||||
#include "ipu3_agc.h"
|
|
||||||
#include "libipa/camera_sensor_helper.h"
|
#include "libipa/camera_sensor_helper.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,8 +187,6 @@ private:
|
||||||
uint32_t minGain_;
|
uint32_t minGain_;
|
||||||
uint32_t maxGain_;
|
uint32_t maxGain_;
|
||||||
|
|
||||||
/* Interface to the AEC/AGC algorithm */
|
|
||||||
std::unique_ptr<IPU3Agc> agcAlgo_;
|
|
||||||
/* Interface to the Camera Helper */
|
/* Interface to the Camera Helper */
|
||||||
std::unique_ptr<CameraSensorHelper> camHelper_;
|
std::unique_ptr<CameraSensorHelper> camHelper_;
|
||||||
|
|
||||||
|
@ -268,6 +266,7 @@ int IPAIPU3::init(const IPASettings &settings,
|
||||||
*ipaControls = ControlInfoMap(std::move(controls), controls::controls);
|
*ipaControls = ControlInfoMap(std::move(controls), controls::controls);
|
||||||
|
|
||||||
/* Construct our Algorithms */
|
/* Construct our Algorithms */
|
||||||
|
algorithms_.push_back(std::make_unique<algorithms::Agc>());
|
||||||
algorithms_.push_back(std::make_unique<algorithms::Awb>());
|
algorithms_.push_back(std::make_unique<algorithms::Awb>());
|
||||||
algorithms_.push_back(std::make_unique<algorithms::ToneMapping>());
|
algorithms_.push_back(std::make_unique<algorithms::ToneMapping>());
|
||||||
|
|
||||||
|
@ -386,9 +385,6 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
agcAlgo_ = std::make_unique<IPU3Agc>();
|
|
||||||
agcAlgo_->configure(context_, configInfo);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,15 +472,12 @@ void IPAIPU3::parseStatistics(unsigned int frame,
|
||||||
{
|
{
|
||||||
ControlList ctrls(controls::controls);
|
ControlList ctrls(controls::controls);
|
||||||
|
|
||||||
for (auto const &algo : algorithms_)
|
|
||||||
algo->process(context_, stats);
|
|
||||||
|
|
||||||
/* \todo These fields should not be written by the IPAIPU3 layer */
|
/* \todo These fields should not be written by the IPAIPU3 layer */
|
||||||
context_.frameContext.agc.gain = camHelper_->gain(gain_);
|
context_.frameContext.agc.gain = camHelper_->gain(gain_);
|
||||||
context_.frameContext.agc.exposure = exposure_;
|
context_.frameContext.agc.exposure = exposure_;
|
||||||
agcAlgo_->process(context_, stats);
|
|
||||||
exposure_ = context_.frameContext.agc.exposure;
|
for (auto const &algo : algorithms_)
|
||||||
gain_ = camHelper_->gainCode(context_.frameContext.agc.gain);
|
algo->process(context_, stats);
|
||||||
|
|
||||||
setControls(frame);
|
setControls(frame);
|
||||||
|
|
||||||
|
@ -505,6 +498,9 @@ void IPAIPU3::setControls(unsigned int frame)
|
||||||
IPU3Action op;
|
IPU3Action op;
|
||||||
op.op = ActionSetSensorControls;
|
op.op = ActionSetSensorControls;
|
||||||
|
|
||||||
|
exposure_ = context_.frameContext.agc.exposure;
|
||||||
|
gain_ = camHelper_->gainCode(context_.frameContext.agc.gain);
|
||||||
|
|
||||||
ControlList ctrls(ctrls_);
|
ControlList ctrls(ctrls_);
|
||||||
ctrls.set(V4L2_CID_EXPOSURE, static_cast<int32_t>(exposure_));
|
ctrls.set(V4L2_CID_EXPOSURE, static_cast<int32_t>(exposure_));
|
||||||
ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast<int32_t>(gain_));
|
ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast<int32_t>(gain_));
|
||||||
|
|
|
@ -6,7 +6,6 @@ ipa_name = 'ipa_ipu3'
|
||||||
|
|
||||||
ipu3_ipa_sources = files([
|
ipu3_ipa_sources = files([
|
||||||
'ipu3.cpp',
|
'ipu3.cpp',
|
||||||
'ipu3_agc.cpp',
|
|
||||||
])
|
])
|
||||||
|
|
||||||
ipu3_ipa_sources += ipu3_ipa_algorithms
|
ipu3_ipa_sources += ipu3_ipa_algorithms
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue