Skip to content

Commit 95efc3c

Browse files
author
Jacopo Mondi
committed
ipa: mali-c55: Port to use LscAlgorithm
Port the Mali-C55 LSC algorithm to use libIPA LscAlgorithm. As we now need to specify the expected grid size at LscAlgorithm::init() time, only tables of 32x32 are now supported. Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
1 parent d335dc2 commit 95efc3c

3 files changed

Lines changed: 123 additions & 72 deletions

File tree

src/ipa/mali-c55/algorithms/lsc.cpp

Lines changed: 96 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,85 +7,104 @@
77

88
#include "lsc.h"
99

10+
#include <libcamera/base/log.h>
1011
#include <libcamera/base/utils.h>
1112

12-
#include "libcamera/internal/value_node.h"
13-
1413
namespace libcamera {
1514

1615
namespace ipa::mali_c55::algorithms {
1716

1817
LOG_DEFINE_CATEGORY(MaliC55Lsc)
1918

20-
int Lsc::init([[maybe_unused]] IPAContext &context, const ValueNode &tuningData)
19+
/* Gain values in [1, 5] range */
20+
static constexpr unsigned int kMeshScale = 6;
21+
22+
/* Mali-C55 hw supports configurable mesh sizes; we fix it to 32. */
23+
static constexpr unsigned int kMeshSize = 32;
24+
static constexpr unsigned int kGridSize = kMeshSize * kMeshSize;
25+
26+
/* Per-colour component page offsets in the mesh table. */
27+
static constexpr unsigned int kRedOffset = 0;
28+
static constexpr unsigned int kGreenOffset = 1024;
29+
static constexpr unsigned int kBlueOffset = 2048;
30+
31+
/*
32+
* \todo Clarify if Mali-C55 can support up to 4 colour temperatures.
33+
*
34+
* The uAPI only expose MALI_C55_NUM_MESH_SHADING_ELEMENTS (3072) gain elements,
35+
* which correspond to three pages of 1024 (32x32) entries.
36+
*/
37+
static constexpr unsigned int kMaxColourTemperatures = 3;
38+
39+
/*
40+
* The LSC algorithm implementation only supports 32x32 grids. Create a list of
41+
* positions from the grid size.
42+
*/
43+
std::vector<double> Lsc::segmentsToPosition() const
2144
{
22-
if (!tuningData.contains("meshScale")) {
23-
LOG(MaliC55Lsc, Error) << "meshScale missing from tuningData";
24-
return -EINVAL;
25-
}
45+
std::vector<double> positions(kMeshSize);
46+
for (double i = 0.0; i < kMeshSize; ++i)
47+
positions[i] = i / (kMeshSize - 1);
2648

27-
meshScale_ = tuningData["meshScale"].get<uint32_t>(0);
49+
return positions;
50+
}
2851

29-
const ValueNode &sets = tuningData["sets"];
30-
if (!sets.isList()) {
31-
LOG(MaliC55Lsc, Error) << "LSC tables missing or invalid";
32-
return -EINVAL;
33-
}
52+
int Lsc::init(IPAContext &context, const ValueNode &tuningData)
53+
{
54+
gridPos_ = segmentsToPosition();
55+
56+
return lscAlgo_.init(tuningData, context.ctrlMap, {
57+
.keys = { "r", "g", "b" },
58+
.numHSamples = kMeshSize,
59+
.numVSamples = kMeshSize,
60+
.sensorSize = context.sensorInfo.activeAreaSize
61+
});
62+
}
3463

35-
size_t tableSize = 0;
36-
for (const auto &set : sets.asList()) {
37-
uint32_t ct = set["ct"].get<uint32_t>(0);
64+
int Lsc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)
65+
{
66+
int ret = lscAlgo_.configure(context.activeState.lsc, configInfo.analogCrop,
67+
gridPos_, gridPos_);
68+
if (ret)
69+
return ret;
3870

39-
if (!ct) {
40-
LOG(MaliC55Lsc, Error) << "Invalid colour temperature";
41-
return -EINVAL;
42-
}
71+
/* Re-initialize the mesh tables and reserve space for enough entries. */
72+
mesh_ = std::vector<uint32_t>(kGridSize * kMaxColourTemperatures);
73+
colourTemperatures_.clear();
4374

75+
/*
76+
* Get the lsc tables per colour components and populate mesh_ with
77+
* their content.
78+
*/
79+
auto &components = lscAlgo_.getComponents();
80+
for (auto const &[ct, component] : components) {
4481
if (std::count(colourTemperatures_.begin(),
4582
colourTemperatures_.end(), ct)) {
4683
LOG(MaliC55Lsc, Error)
4784
<< "Multiple sets found for colour temperature";
4885
return -EINVAL;
4986
}
5087

51-
std::vector<uint8_t> rTable =
52-
set["r"].get<std::vector<uint8_t>>().value_or(utils::defopt);
53-
std::vector<uint8_t> gTable =
54-
set["g"].get<std::vector<uint8_t>>().value_or(utils::defopt);
55-
std::vector<uint8_t> bTable =
56-
set["b"].get<std::vector<uint8_t>>().value_or(utils::defopt);
88+
const std::vector<uint8_t> &rTable = component.at("r");
89+
const std::vector<uint8_t> &gTable = component.at("g");
90+
const std::vector<uint8_t> &bTable = component.at("b");
5791

58-
/*
59-
* Some validation to do; only 16x16 and 32x32 tables of
60-
* coefficients are acceptable, and all tables across all of the
61-
* sets must be the same size. The first time we encounter a
62-
* table we check that it is an acceptable size and if so make
63-
* sure all other tables are of equal size.
64-
*/
65-
if (!tableSize) {
66-
if (rTable.size() != 256 && rTable.size() != 1024) {
67-
LOG(MaliC55Lsc, Error)
68-
<< "Invalid table size for colour temperature " << ct;
69-
return -EINVAL;
70-
}
71-
tableSize = rTable.size();
72-
}
73-
74-
if (rTable.size() != tableSize ||
75-
gTable.size() != tableSize ||
76-
bTable.size() != tableSize) {
77-
LOG(MaliC55Lsc, Error)
78-
<< "Invalid or mismatched table size for colour temperature " << ct;
79-
return -EINVAL;
80-
}
92+
/* Only 32x32 tables of coefficients are accepted. */
93+
ASSERT(rTable.size() == kGridSize &&
94+
gTable.size() == kGridSize &&
95+
bTable.size() != kGridSize);
8196

82-
if (colourTemperatures_.size() >= 3) {
97+
if (colourTemperatures_.size() >= kMaxColourTemperatures) {
8398
LOG(MaliC55Lsc, Error)
8499
<< "A maximum of 3 colour temperatures are supported";
85100
return -EINVAL;
86101
}
87102

88-
for (unsigned int i = 0; i < tableSize; i++) {
103+
/*
104+
* Create the mesh table entries by assembling up to 3 gains per
105+
* colour temperature in a u32 word.
106+
*/
107+
for (unsigned int i = 0; i < kGridSize; i++) {
89108
mesh_[kRedOffset + i] |=
90109
(rTable[i] << (colourTemperatures_.size() * 8));
91110
mesh_[kGreenOffset + i] |=
@@ -97,35 +116,36 @@ int Lsc::init([[maybe_unused]] IPAContext &context, const ValueNode &tuningData)
97116
colourTemperatures_.push_back(ct);
98117
}
99118

100-
/*
101-
* The mesh has either 16x16 or 32x32 nodes, we tell the driver which it
102-
* is based on the number of values in the tuning data's table.
103-
*/
104-
if (tableSize == 256)
105-
meshSize_ = 15;
106-
else
107-
meshSize_ = 31;
108-
109119
return 0;
110120
}
111121

122+
/**
123+
* \copydoc libcamera::ipa::Algorithm::queueRequest
124+
*/
125+
void Lsc::queueRequest(IPAContext &context, [[maybe_unused]] const uint32_t frame,
126+
IPAFrameContext &frameContext, const ControlList &controls)
127+
{
128+
lscAlgo_.queueRequest(context.activeState.lsc, frameContext.lsc,
129+
controls);
130+
}
131+
112132
void Lsc::fillConfigParamsBlock(MaliC55Params *params) const
113133
{
114134
auto block = params->block<MaliC55Blocks::MeshShadingConfig>();
115135

116136
block->mesh_show = false;
117-
block->mesh_scale = meshScale_;
137+
block->mesh_scale = kMeshScale;
118138
block->mesh_page_r = 0;
119139
block->mesh_page_g = 1;
120140
block->mesh_page_b = 2;
121-
block->mesh_width = meshSize_;
122-
block->mesh_height = meshSize_;
141+
block->mesh_width = kMeshSize - 1;
142+
block->mesh_height = kMeshSize - 1;
123143

124144
std::copy(mesh_.begin(), mesh_.end(), block->mesh);
125145
}
126146

127147
void Lsc::fillSelectionParamsBlock(MaliC55Params *params, uint8_t bank,
128-
uint8_t alpha) const
148+
uint8_t alpha) const
129149
{
130150
auto block = params->block<MaliC55Blocks::MeshShadingSel>();
131151

@@ -198,6 +218,18 @@ void Lsc::prepare(IPAContext &context, [[maybe_unused]] const uint32_t frame,
198218
fillConfigParamsBlock(params);
199219
}
200220

221+
/**
222+
* \copydoc libcamera::ipa::Algorithm::process
223+
*/
224+
void Lsc::process([[maybe_unused]] IPAContext &context,
225+
[[maybe_unused]] const uint32_t frame,
226+
IPAFrameContext &frameContext,
227+
[[maybe_unused]] const mali_c55_stats_buffer *stats,
228+
ControlList &metadata)
229+
{
230+
lscAlgo_.process(frameContext.lsc, metadata);
231+
}
232+
201233
REGISTER_IPA_ALGORITHM(Lsc, "Lsc")
202234

203235
} /* namespace ipa::mali_c55::algorithms */

src/ipa/mali-c55/algorithms/lsc.h

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@
55
* Mali-C55 Lens shading correction algorithm
66
*/
77

8-
#include <map>
8+
#include <vector>
99
#include <tuple>
1010

11+
#include <linux/media/arm/mali-c55-config.h>
12+
13+
#include "libcamera/internal/value_node.h"
14+
15+
#include "libipa/fixedpoint.h"
16+
#include "libipa/lsc.h"
17+
1118
#include "algorithm.h"
19+
#include "ipa_context.h"
20+
#include "params.h"
1221

1322
namespace libcamera {
1423

@@ -21,23 +30,30 @@ class Lsc : public Algorithm
2130
~Lsc() = default;
2231

2332
int init(IPAContext &context, const ValueNode &tuningData) override;
33+
int configure(IPAContext &context, const IPACameraSensorInfo &configInfo) override;
34+
void queueRequest(IPAContext &context, const uint32_t frame,
35+
IPAFrameContext &frameContext,
36+
const ControlList &controls) override;
2437
void prepare(IPAContext &context, const uint32_t frame,
2538
IPAFrameContext &frameContext,
2639
MaliC55Params *params) override;
40+
void process(IPAContext &context, const uint32_t frame,
41+
IPAFrameContext &frameContext,
42+
const mali_c55_stats_buffer *stats,
43+
ControlList &metadata) override;
2744
private:
28-
static constexpr unsigned int kRedOffset = 0;
29-
static constexpr unsigned int kGreenOffset = 1024;
30-
static constexpr unsigned int kBlueOffset = 2048;
31-
45+
std::vector<double> segmentsToPosition() const;
3246
void fillConfigParamsBlock(MaliC55Params *params) const;
3347
void fillSelectionParamsBlock(MaliC55Params *params,
3448
uint8_t bank, uint8_t alpha) const;
3549
std::tuple<uint8_t, uint8_t> findBankAndAlpha(uint32_t ct) const;
3650

37-
std::vector<uint32_t> mesh_ = std::vector<uint32_t>(3072);
3851
std::vector<uint32_t> colourTemperatures_;
39-
uint32_t meshScale_;
40-
uint32_t meshSize_;
52+
std::vector<uint32_t> mesh_;
53+
54+
std::vector<double> gridPos_;
55+
56+
LscAlgorithm<UQ<2, 6>> lscAlgo_;
4157
};
4258

4359
} /* namespace ipa::mali_c55::algorithms */

src/ipa/mali-c55/ipa_context.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "libipa/awb.h"
2020
#include "libipa/ccm.h"
2121
#include "libipa/fixedpoint.h"
22+
#include "libipa/lsc.h"
2223

2324
namespace libcamera {
2425

@@ -60,6 +61,7 @@ struct IPAActiveState {
6061

6162
ipa::awb::ActiveState awb;
6263
ipa::ccm::ActiveState ccm;
64+
ipa::lsc::ActiveState lsc;
6365
};
6466

6567
struct IPAFrameContext : public FrameContext {
@@ -71,6 +73,7 @@ struct IPAFrameContext : public FrameContext {
7173

7274
ipa::awb::FrameContext awb;
7375
ipa::ccm::FrameContext ccm;
76+
ipa::lsc::FrameContext lsc;
7477
};
7578

7679
struct IPAContext {

0 commit comments

Comments
 (0)