mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-26 01:55:51 +03:00
ipa: ipu3: Introduce modular algorithm
Implement a new modular framework for algorithms with a common context structure that is passed to each algorithm through a common API. This patch: - removes all the local references from IPAIPU3 and uses IPAContext - implements the list of pointers and the loop at configure call on each algorithm - loops in fillParams on each prepare() call on the algorithm list - loops in prepareStats on each process() call on the algorithm list 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
b3a2882b36
commit
96dfda8e4b
2 changed files with 52 additions and 13 deletions
|
@ -10,11 +10,17 @@
|
||||||
|
|
||||||
#include <linux/intel-ipu3.h>
|
#include <linux/intel-ipu3.h>
|
||||||
|
|
||||||
|
#include <libcamera/geometry.h>
|
||||||
|
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
|
|
||||||
namespace ipa::ipu3 {
|
namespace ipa::ipu3 {
|
||||||
|
|
||||||
struct IPASessionConfiguration {
|
struct IPASessionConfiguration {
|
||||||
|
struct {
|
||||||
|
ipu3_uapi_grid_config bdsGrid;
|
||||||
|
Size bdsOutputSize;
|
||||||
|
} grid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IPAFrameContext {
|
struct IPAFrameContext {
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include "libcamera/internal/mapped_framebuffer.h"
|
#include "libcamera/internal/mapped_framebuffer.h"
|
||||||
|
|
||||||
|
#include "algorithms/algorithm.h"
|
||||||
#include "ipu3_agc.h"
|
#include "ipu3_agc.h"
|
||||||
#include "ipu3_awb.h"
|
#include "ipu3_awb.h"
|
||||||
#include "libipa/camera_sensor_helper.h"
|
#include "libipa/camera_sensor_helper.h"
|
||||||
|
@ -79,6 +80,17 @@
|
||||||
* are run. This needs to be turned into real per-frame data storage.
|
* are run. This needs to be turned into real per-frame data storage.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \struct IPASessionConfiguration::grid
|
||||||
|
* \brief Grid configuration of the IPA
|
||||||
|
*
|
||||||
|
* \var IPASessionConfiguration::grid::bdsGrid
|
||||||
|
* \brief Bayer Down Scaler grid plane config used by the kernel
|
||||||
|
*
|
||||||
|
* \var IPASessionConfiguration::grid::bdsOutputSize
|
||||||
|
* \brief BDS output size configured by the pipeline handler
|
||||||
|
*/
|
||||||
|
|
||||||
static constexpr uint32_t kMaxCellWidthPerSet = 160;
|
static constexpr uint32_t kMaxCellWidthPerSet = 160;
|
||||||
static constexpr uint32_t kMaxCellHeightPerSet = 56;
|
static constexpr uint32_t kMaxCellHeightPerSet = 56;
|
||||||
|
|
||||||
|
@ -137,10 +149,12 @@ private:
|
||||||
/* Interface to the Camera Helper */
|
/* Interface to the Camera Helper */
|
||||||
std::unique_ptr<CameraSensorHelper> camHelper_;
|
std::unique_ptr<CameraSensorHelper> camHelper_;
|
||||||
|
|
||||||
/* Local parameter storage */
|
/* Maintain the algorithms used by the IPA */
|
||||||
struct ipu3_uapi_params params_;
|
std::list<std::unique_ptr<ipa::ipu3::Algorithm>> algorithms_;
|
||||||
|
|
||||||
struct ipu3_uapi_grid_config bdsGrid_;
|
/* Local parameter storage */
|
||||||
|
struct IPAContext context_;
|
||||||
|
struct ipu3_uapi_params params_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -237,7 +251,9 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)
|
||||||
uint32_t minError = std::numeric_limits<uint32_t>::max();
|
uint32_t minError = std::numeric_limits<uint32_t>::max();
|
||||||
Size best;
|
Size best;
|
||||||
Size bestLog2;
|
Size bestLog2;
|
||||||
bdsGrid_ = {};
|
|
||||||
|
/* Set the BDS output size in the IPAConfiguration structure */
|
||||||
|
context_.configuration.grid.bdsOutputSize = bdsOutputSize;
|
||||||
|
|
||||||
for (uint32_t widthShift = 3; widthShift <= 7; ++widthShift) {
|
for (uint32_t widthShift = 3; widthShift <= 7; ++widthShift) {
|
||||||
uint32_t width = std::min(kMaxCellWidthPerSet,
|
uint32_t width = std::min(kMaxCellWidthPerSet,
|
||||||
|
@ -261,14 +277,17 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bdsGrid_.width = best.width >> bestLog2.width;
|
struct ipu3_uapi_grid_config &bdsGrid = context_.configuration.grid.bdsGrid;
|
||||||
bdsGrid_.block_width_log2 = bestLog2.width;
|
bdsGrid.x_start = 0;
|
||||||
bdsGrid_.height = best.height >> bestLog2.height;
|
bdsGrid.y_start = 0;
|
||||||
bdsGrid_.block_height_log2 = bestLog2.height;
|
bdsGrid.width = best.width >> bestLog2.width;
|
||||||
|
bdsGrid.block_width_log2 = bestLog2.width;
|
||||||
|
bdsGrid.height = best.height >> bestLog2.height;
|
||||||
|
bdsGrid.block_height_log2 = bestLog2.height;
|
||||||
|
|
||||||
LOG(IPAIPU3, Debug) << "Best grid found is: ("
|
LOG(IPAIPU3, Debug) << "Best grid found is: ("
|
||||||
<< (int)bdsGrid_.width << " << " << (int)bdsGrid_.block_width_log2 << ") x ("
|
<< (int)bdsGrid.width << " << " << (int)bdsGrid.block_width_log2 << ") x ("
|
||||||
<< (int)bdsGrid_.height << " << " << (int)bdsGrid_.block_height_log2 << ")";
|
<< (int)bdsGrid.height << " << " << (int)bdsGrid.block_height_log2 << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
int IPAIPU3::configure(const IPAConfigInfo &configInfo)
|
int IPAIPU3::configure(const IPAConfigInfo &configInfo)
|
||||||
|
@ -310,15 +329,23 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo)
|
||||||
|
|
||||||
defVBlank_ = itVBlank->second.def().get<int32_t>();
|
defVBlank_ = itVBlank->second.def().get<int32_t>();
|
||||||
|
|
||||||
|
/* Clean context and IPU3 parameters at configuration */
|
||||||
params_ = {};
|
params_ = {};
|
||||||
|
context_ = {};
|
||||||
|
|
||||||
calculateBdsGrid(configInfo.bdsOutputSize);
|
calculateBdsGrid(configInfo.bdsOutputSize);
|
||||||
|
|
||||||
awbAlgo_ = std::make_unique<IPU3Awb>();
|
for (auto const &algo : algorithms_) {
|
||||||
awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
|
int ret = algo->configure(context_, configInfo);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
awbAlgo_ = std::make_unique<IPU3Awb>();
|
||||||
|
awbAlgo_->initialise(params_, context_.configuration.grid.bdsOutputSize,
|
||||||
|
context_.configuration.grid.bdsGrid);
|
||||||
agcAlgo_ = std::make_unique<IPU3Agc>();
|
agcAlgo_ = std::make_unique<IPU3Agc>();
|
||||||
agcAlgo_->initialise(bdsGrid_, sensorInfo_);
|
agcAlgo_->initialise(context_.configuration.grid.bdsGrid, sensorInfo_);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -392,6 +419,9 @@ void IPAIPU3::processControls([[maybe_unused]] unsigned int frame,
|
||||||
|
|
||||||
void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params)
|
void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params)
|
||||||
{
|
{
|
||||||
|
for (auto const &algo : algorithms_)
|
||||||
|
algo->prepare(context_, ¶ms_);
|
||||||
|
|
||||||
if (agcAlgo_->updateControls())
|
if (agcAlgo_->updateControls())
|
||||||
awbAlgo_->updateWbParameters(params_, agcAlgo_->gamma());
|
awbAlgo_->updateWbParameters(params_, agcAlgo_->gamma());
|
||||||
|
|
||||||
|
@ -409,6 +439,9 @@ void IPAIPU3::parseStatistics(unsigned int frame,
|
||||||
{
|
{
|
||||||
ControlList ctrls(controls::controls);
|
ControlList ctrls(controls::controls);
|
||||||
|
|
||||||
|
for (auto const &algo : algorithms_)
|
||||||
|
algo->process(context_, stats);
|
||||||
|
|
||||||
double gain = camHelper_->gain(gain_);
|
double gain = camHelper_->gain(gain_);
|
||||||
agcAlgo_->process(stats, exposure_, gain);
|
agcAlgo_->process(stats, exposure_, gain);
|
||||||
gain_ = camHelper_->gainCode(gain);
|
gain_ = camHelper_->gainCode(gain);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue