Commit Graph

4849 Commits

Author SHA1 Message Date
van Veen, Stephan
da967ed63d libcamera: controls: Define a new core Hue control
Define a new control to support configuration of Hue adjustments when
supported by the available platform.

Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Signed-off-by: van Veen, Stephan <stephan.vanveen@karlstorz.com>
[Kieran: Rework to define as a rotation in degrees]
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-19 15:06:21 +00:00
Kieran Bingham
52cc91f3f1 ipa: rkisp1: cproc: Report metadata
Presently the colour processing component exposes controls for
brightness, saturation, and contrast to the applications which are
handled and processed accordingly on the ISP.

The implementation lacks reporting the values that are set back to the
application.

Utilise the new Quantised types to provide the values that were applied
to the hardware and report them in the completed request metadata.

Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-19 15:06:21 +00:00
Kieran Bingham
9d1b2b3ba8 ipa: rkisp1: cproc: Convert to use Quantized types
Convert the Brightness, Contrast and Saturation helper functions to a
Quantizer type to support maintaining the data.

While modifying the include blocks of the ipa_context.h, also fix the
include style for libipa components.

Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-19 15:06:21 +00:00
Kieran Bingham
5b4c0c5b8b ipa: libipa: Provide fixed point quantized traits
Extend the new Quantized type infrastructure by providing a
FixedPointQTraits template.

This allows construction of fixed point types with a Quantized storage
that allows easy reading of both the underlying quantized type value and
a floating point representation of that same value.

Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-19 15:06:21 +00:00
Kieran Bingham
cd3149a7fa ipa: libipa: fixedpoint: Fix unsigned usage
The fixedToFloatingPoint does not support unsigned Q types, and
incorrectly sign-extends all values which have the top most bit set in
the quantized values.

Fix this by ensuring that only signed types perform sign extension, and
simplify the calculation for unsigned types.

Convert the storage of the test cases to signed types to correctly
represent their intended purpose, to prevent test failures.

Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-19 15:06:21 +00:00
Kieran Bingham
be64005a8e ipa: libipa: Provide a Quantized data type support
Frequently when handling data in IPA components we must convert and
store user interface values which may be floating point values, and
perform a specific operation or conversion to quantize this to a
hardware value.

This value may be to a fixed point type, or more custom code mappings,
but in either case it is important to contain both the required hardware
value, with its effective quantized value.

Provide a new storage type 'Quantized' which can be defined based on a
set of type specific Traits to perform the conversions between floats
and the underlying hardware type.

Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-19 15:06:21 +00:00
Kieran Bingham
da12b1854f libcamera: software_isp: Fix LIBCAMERA_SOFTISP_MODE log print
When an invalid parameter is specified to LIBCAMERA_SOFTISP_MODE, the
error log has a typo. Fix the typo and reflow the line while here.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-18 16:48:56 +00:00
Kieran Bingham
a1d272d7f1 ipa: simple: Remove duplicate header inclusion
The Awb component already references libcamera/control_ids.h. Remove
the incorrect duplicate inclusion of "control_ids.h".

Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-18 16:48:56 +00:00
Kieran Bingham
dcfe6afb49 ipa: rkisp1: Fix awb algorithm brief
The Awb brief was not updated from when the Bayes AWB was added.

Extend it to account for this.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-18 16:48:56 +00:00
Milan Zamazal
d97d2a58ad libcamera: software_isp: Remove redundant include of time.h
The header file is not used in debayer_cpu.cpp any more.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-18 11:09:51 +00:00
Hans de Goede
7bcc2168bf software_isp: benchmark: Print what is being benchmarked
With the GPU accelerated softISP 2 separate benchmark results are printed,
1 for the generation of the output images on the GPU and a separate one
for generating the statistics on the CPU.

Add a new name argument to the Benchmark class descriptor and print this
out when printing the benchmark result.

Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-18 10:48:52 +00:00
Hans de Goede
f0a79dd68b software_isp: benchmark: Add missing _ postfix to measure data member
All class data members should have a _ postifx, add the missing _ postfix
to the Benchmark::measure_ data member.

Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-18 10:48:52 +00:00
Stefan Klug
1dcf9957a4 libcamera: converter: converter_dw100_vertexmap: Fix dewarp parameter p2 handling
The lens dewarp implementation done in commit 1784e08be3 ("libcamera:
dw100_vertexmap: Implement parametric dewarping") handles the dewarp
parameter p2 incorrectly because it uses the already dewarped x value as
input for the calculation of the y value. Fix that by using separate
variables for the output value. Do so for x and y to keep the code
symmetric even if it is only strictly required for y.

Fixes: 1784e08be3 ("libcamera: dw100_vertexmap: Implement parametric dewarping")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-11 14:06:20 +01:00
Barnabás Pőcze
78b9890a0f libcamera: software_isp: debayer: Take DebayerParams by ref
When calling `Debayer::process()` from `SoftwareIsp::process()`, the
`DebayerParams` object is copied multiple times:

  (1) call of `BoundMethodMember<...>::activate()`
      inside `Object::invokeMethod()`
  (2) constructor of `BoundMethodArgs<...>`
      inside `BoundMethodMember<...>::activate()`
  (3) call of `BoundMethodMember<...>::invoke()`
      inside `BoundMethodArgs::invokePack()`
  (4) call of the actual pointer to member function
      inside `BoundMethodMember::invoke()`

While compilers might avoid one or two of the above copies, this is still
not ideal. By making `Debayer::process()` take the parameter object by
const lvalue reference, only the copy in the `BoundMethodArgs` constructor
remains. So do that.

Before:
	[0:12:51.133836595] [12424] DEBUG SoftwareIsp software_isp.cpp:399 params=0x7d0a691f57d0
	copy from 0x7d0a691f57d0 into 0x7baa65f2bf30
	copy from 0x7baa65f2bf30 into 0x7c6a69209758
	copy from 0x7c6a69209758 into 0x7baa63223930
	copy from 0x7baa63223930 into 0x7baa63223a70
	[0:12:51.134559602] [12426] DEBUG eGL debayer_egl.cpp:538 params=0x7baa63223a70
	771.099877 (30.06 fps) cam0-stream0 seq: 000031 bytesused: 8666112

After:
	[0:13:42.861691943] [12543] DEBUG SoftwareIsp software_isp.cpp:399 params=0x7cfaad5f57d0
	copy from 0x7cfaad5f57d0 into 0x7c5aad609758
	[0:13:42.862453917] [12545] DEBUG eGL debayer_egl.cpp:538 params=0x7c5aad609758
	822.827388 (30.02 fps) cam0-stream0 seq: 000031 bytesused: 8666112

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
2026-02-09 09:14:24 +01:00
Barnabás Pőcze
c6c5a8bc5b meson: Add libdw option to control libdw dependency
Previously it was not possible to disable libdw usage if it was
detected. Fix that by adding a meson feature option.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-02-06 09:57:56 +01:00
Milan Zamazal
bb2e6d0833 libcamera: ipa: simple: Fix multiplication order in Awb
The matrix multiplication in Awb is swapped: the gains should be applied
after combinedMatrix, i.e. on the left side.  The mistake happened when
`ccm' was replaced with combinedMatrix and gainMatrix multiplication was
moved to Awb.  While CCM must be applied after gains, the gains must be
applied after the combined matrix, which no longer corresponds to CCM in
Awb.

Since there is currently no algorithm modifying combinedMatrix before
Awb, combinedMatrix is an identity matrix there and the wrong order
doesn't influence the output at the moment.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2026-02-06 00:39:33 +02:00
Barnabás Pőcze
79c31f0707 libcamera: base: utils: Fix namespace of operator<< for Duration
In order for ADL to find the function, it must be in the namespace of any of
its arguments. Previously, however, that was not the case, and it has only
really worked by accident and could be easily made to fail by introducing
other `operator<<` overloads.

For example, a user of this function in `libcamera::ipa` would no longer
compile after introducing an `operator<<` into the `libcamera::ipa`
namespace as that would essentially hide this overload, and without ADL
it would not be found.

So move the function into the `utils` namespace.

Fixes: 5055ca747c ("libcamera: utils: Add helper class for std::chrono::duration")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2026-01-28 18:26:28 +01:00
Barnabás Pőcze
f7417c38e4 ipa: rpi: Fix printing of utils::Duration
`utils::Duration` derives from `std::chrono::duration<...>`, but multiplying
it yields an `std::chrono::duration<...>`, not `Duration`. chrono duration
types only have `operator<<` in C++20 or later, so this usage should not
compile. It only did so because the `operator<<` for `Duration` was in
the `libcamera` namespace and `Duration` has an implicit constructor from
any chrono duration type.

This will cease to work when that operator is moved into the `utils` namespace
for ADL purposes. So fix it by making the cast to `Duration` explicit.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2026-01-28 18:26:28 +01:00
Barnabás Pőcze
461e7d3d73 libcamera: base: utils: Simplify operator<< for Duration
There is no real need for a function template. It is not defined in a
header file, so it has limited availability, and there exists only a
single instantion.

So convert it to use `std::ostream` directly, like most `operator<<`
in the code base.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2026-01-28 18:26:28 +01:00
Laurent Pinchart
67fd7d720b libcamera: yaml_parser: Fix uninitialized variable warning
gcc 14.3.0, cross-compiling from amd64 to arm64, warns about a possibly
uninitialized variable in YamlObject::Getter<>::get():

In file included from ../../include/libcamera/internal/yaml_parser.h:12,
                 from ../../src/libcamera/yaml_parser.cpp:8:
In constructor ‘constexpr std::_Optional_payload_base<_Tp>::_Storage<_Up, <anonymous> >::_Storage(std::in_place_t, _Args&& ...) [with _Args = {unsigned char}; _Up = unsigned char; bool <anonymous> = true; _Tp = unsigned char]’,
    inlined from ‘constexpr std::_Optional_payload_base<_Tp>::_Optional_payload_base(std::in_place_t, _Args&& ...) [with _Args = {unsigned char}; _Tp = unsigned char]’ at include/c++/14.3.0/optional:122:4,
    inlined from ‘constexpr std::_Optional_payload<unsigned char, true, true, true>::_Optional_payload(std::in_place_t, _Args&& ...) [with _Args = {unsigned char}][inherited from std::_Optional_payload_base<unsigned char>]’ at include/c++/14.3.0/optional:337:42,
    inlined from ‘constexpr std::_Optional_base<_Tp, true, true>::_Optional_base(std::in_place_t, _Args&& ...) [with _Args = {unsigned char}; typename std::enable_if<is_constructible_v<_Tp, _Args ...>, bool>::type <anonymous> = false; _Tp = unsigned char]’ at include/c++/14.3.0/optional:648:4,
    inlined from ‘constexpr std::optional<_Tp>::optional(_Up&&) [with _Up = unsigned char; typename std::enable_if<__and_v<std::__not_<std::is_same<std::optional<_Tp>, typename std::remove_cv<typename std::remove_reference<_Up>::type>::type> >, std::__not_<std::is_same<std::in_place_t, typename std::remove_cv<typename std::remove_reference<_Up>::type>::type> >, std::is_constructible<_T1, _U1>, std::is_convertible<_Iter, _Iterator> >, bool>::type <anonymous> = true; _Tp = unsigned char]’ at include/c++/14.3.0/optional:747:47,
    inlined from ‘std::optional<_Tp> libcamera::YamlObject::Getter<T, typename std::enable_if<(((((is_same_v<signed char, T> || is_same_v<unsigned char, T>) || is_same_v<short int, T>) || is_same_v<short unsigned int, T>) || is_same_v<int, T>) || is_same_v<unsigned int, T>), void>::type>::get(const libcamera::YamlObject&) const [with T = unsigned char]’ at ../../src/libcamera/yaml_parser.cpp:172:10:
include/c++/14.3.0/optional:210:15: error: ‘value’ may be used uninitialized [-Werror=maybe-uninitialized]
  210 |             : _M_value(std::forward<_Args>(__args)...)
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/libcamera/yaml_parser.cpp: In member function ‘std::optional<_Tp> libcamera::YamlObject::Getter<T, typename std::enable_if<(((((is_same_v<signed char, T> || is_same_v<unsigned char, T>) || is_same_v<short int, T>) || is_same_v<short unsigned int, T>) || is_same_v<int, T>) || is_same_v<unsigned int, T>), void>::type>::get(const libcamera::YamlObject&) const [with T = unsigned char]’:
../../src/libcamera/yaml_parser.cpp:165:19: note: ‘value’ was declared here
  165 |                 T value;
      |                   ^~~~~

This appears to be a false positive, as the std::from_chars() function
should set value when it returns without an error. Commit bb1d216113
("libcamera: base: log: Fix uninitialized variable warning") fixed a
similar warning with gcc 13.3.0.

The warning is easy to work around by initializing the variable, and
doing so shouldn't be too costly as the type T is restricted to being an
integer. Fix the build by doing so.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2026-01-28 18:47:15 +02:00
Stefan Klug
186e5cf9ac ipa: rkisp1: Implement LensShadingCorrectionEnable control
Implement the LensShadingCorrectionEnable control for rkisp1.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
1355e29f31 libcamera: control_ids: Introduce LensShadingCorrectionEnable
Introduce a LensShadingCorrectionEnable control to enable and disable
LSC. This is useful to assess the working and quality of the lens
shading correction at runtime.

While at it drop the reference to the tuning file in the description of
the LensDewarpEnable control, as that information doesn't belong to the
controls.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
e8054c758c ipa: rkisp1: lsc: Resample polynomial lens shading tables at configure time
The lens shading correction is always applied based on the sensor crop
bounds. This leads to incorrect lens shading correction for analog crops
that do not cover the whole sensor.

To fix that, we need to adapt the lens shading table for the selected
analog crop at configure time. Introduce an abstract ShadingDescriptor
class that holds the lens shading information that can then be sampled
at configure time for a specific crop rectangle.

Resampling for a specific crop is only implemented for polynomial lsc
data. For tabular data, a warning is logged and the unmodified table is
returned. This matches the current functionality for tabular data and is
a huge improvement for polynomial data.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
d59081c2e2 ipa: rkisp1: lsc: Pass crop rectangle as parameter
In preparation for the upcoming rework, pass the crop rectangle as
parameter to samplePolynomial(). This patch contains no functional
change.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Rui Wang <rui.wang@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
d474a5aa8a ipa: rkisp1: lsc: Pass sampling positions into samplePolynomial
There is no need to recalculate the sampling positions over and over.
Pass them as parameter into the sampling function. The vectors are still
kept inside the loop as this is also a preparatory change for the
upcoming refactoring.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
ee1d93d8aa ipa: libipa: interpolator: Drop key quantization
The quantization of the interpolation key was only used by the LSC
algorithm. There it lead to difficult to read code was removed. As there
is no remaining user of it, drop it from the Interpolator class.

While at it, cleanup the includes.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
3bfc71345f ipa: rkisp1: lsc: Handle quantization locally
The quantization functionality in the Interpolator type hinders in
writing nice code. Don't use it and implement the functionality directly
in the algorithm.

While at it, reduce the threshold to half of the quantization step size,
otherwise it might happen that we skip a full quantization step. Rename
the kColourTemperatureChangeThreshhold to kColourTemperatureQuantization
to better express the usecase.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
098fc4eeed ipa: rkisp1: lsc: Move local types into anonymous namespace
Move all local helpers into an anonymous namespace and drop a static
modifier that is no longer needed.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
55fb540f4e ipa: rksip1: lsc: Move function definitions out of class
Move the function definitions out of the related classes. This was noted
in review after the series was already merged. After trying it out I
must admit that it really improves readability and reduces the
indentation level by one.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Rui Wang <rui.wang@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
f8e054989a ipa: rkisp1: lsc: Rename res to samples
Rename res to samples to better describe the intent. This was noted in
review after the series was merged.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Rui Wang <rui.wang@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
05be45a839 ipa: rkisp1: lsc: Rename res to ret
Rename res to ret as that is used in libcamera for return codes.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Rui Wang <rui.wang@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
2d33d786af ipa: rkisp1: lsc: Rename res to positions
Rename the res variable to positions which better describes the intent.
This was commented in review after being merged.

While at it, improve the documentation a bit.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Rui Wang <rui.wang@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
f1854d356b ipa: rkisp1: lsc: Replace assert with ASSERT
Replace assert() by ASSERT() and drop a set of unnecessary curly braces.
Those were noticed in the former review but after the series was
applied. Fix them now.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Rui Wang <rui.wang@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
71c2e858d8 ipa: rkisp1: lsc: Drop unused function declaration
The interpolateTable() function is not implemented anywhere. Drop the
declaration.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Stefan Klug
c9b0ad95d7 ipa: rkisp1: lsc: Drop unused member variable
The Components::ct member is not used anywhere. Drop it.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Rui Wang <rui.wang@ideasonboard.com>
2026-01-28 17:10:01 +01:00
Milan Zamazal
60f150bf87 libcamera: ipa: simple: Disable Ccm algorithm by default again
The default CCM in uncalibrated.yaml is just an identity transformation
and has been enabled by default only to always provide a correction
matrix to GPU ISP.  It slows down CPU ISP when CCM is not used.

Now, when a default correction matrix is always provided to GPU ISP, we
can disable the Ccm algorithm in uncalibrated.yaml again.  The check for
ccmEnabled in GPU ISP is no longer needed and it must be removed in
order not to fail when Ccm algorithm is not enabled.  ccmEnabled flag is
still needed in CPU ISP where the processing differs based on whether
CCM is present or not.

Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Robert Mader <robert.mader@collabora.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:34 +00:00
Milan Zamazal
3ffaa4c0e2 libcamera: ipa: simple: Remove Lut algorithm
The Lut algorithm is not really an algorithm.  Moreover, algorithms may
be enabled or disabled but with Lut disabled, nothing will work.

Let's move the construction of lookup tables to CPU debayering, where it
is used.  The implied and related changes are:

- DebayerParams is changed to contain the real params rather than lookup
  tables.
- contrastExp parameter introduced by GPU ISP is used for CPU ISP too.
- The params must be initialised so that debayering gets meaningful
  parameter values even when some algorithms are disabled.
- combinedMatrix must be put to params everywhere where it is modified.
- Matrix changes needn't be tracked in the algorithms any more.
- CPU debayering must watch for changes of the corresponding parameters
  to update the lookup tables when and only when needed.
- Swapping red and blue is integrated into lookup table constructions.
- gpuIspEnabled flags are removed as they are not needed any more.

Reviewed-by: Robert Mader <robert.mader@collabora.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:34 +00:00
Milan Zamazal
c43aeaade0 libcamera: ipa: simple: Set contrast metadata unconditionally
Let's do the same with contrast as with other metadata.

Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Robert Mader <robert.mader@collabora.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:34 +00:00
Milan Zamazal
43a2ff5c2f libcamera: ipa: simple: Use symbolic constants for adjust defaults
The adjust algorithm already uses a symbolic constant for gamma.  Let's
introduce similar constants for contrast and saturation to prevent
copying the numeric defaults to multiple places.

Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Robert Mader <robert.mader@collabora.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:33 +00:00
Milan Zamazal
14d340a27b libcamera: ipa: simple: Use float type for adjustment controls
control_ids.h defines the contrast type as float, let's use the same in
simple IPA, instead of double.  Saturation and gamma already use float,
except for the knobs initializers, let's use float for the knobs too.

Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Robert Mader <robert.mader@collabora.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:33 +00:00
Milan Zamazal
da0926bc4b libcamera: ipa: simple: Apply gain matrix in awb
Now, when we have a combined matrix, we can apply AWB gains to it
directly in awb.cpp.

Reviewed-by: Robert Mader <robert.mader@collabora.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:33 +00:00
Milan Zamazal
0f01a68086 libcamera: ipa: simple: Make gamma adjustable
The gamma value is fixed in software ISP.  Let's make it adjustable,
similarly to contrast and saturation, and report it in metadata.

Reviewed-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:33 +00:00
Milan Zamazal
e8e2bd39f9 libcamera: ipa: simple: Move contrast settings to adjust.cpp
Let's move the contrast settings from lut.cpp to adjust.cpp, where they
belong, similarly to saturation.

Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Robert Mader <robert.mader@collabora.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:33 +00:00
Milan Zamazal
d92f5f5402 libcamera: ipa: simple: Separate saturation from CCM
Saturation adjustments are implemented using matrix operations.  They
are currently applied to the colour correction matrix.  Let's move them
to a newly introduced separate "Adjust" algorithm.

This separation has the following advantages:

- It allows disabling general colour adjustments algorithms without
  disabling the CCM algorithm.

- It keeps the CCM separated from other corrections.

- It's generally cleaner.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Robert Mader <robert.mader@collabora.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:32 +00:00
Milan Zamazal
82ed6c19c2 libcamera: ipa: simple: Initialise the general correction matrix
The combined matrix must be reset to the initial value before each frame
is prepared.  This must be done outside algorithms because any of the
algorithms may be disabled while the matrix must be always initialised.

Let's initialise the combined matrix to the identity matrix (which keeps
the pixel values unchanged) in software ISP just before calling
`prepare' on the algorithms.

Matrix updates can no longer be skipped in ccm.cpp, otherwise the CCM
won't be applied if there is no temperature or saturation change.  We
explicitly track whether the CCM has been set up completely rather than
relying on the frame number, to avoid missing the initialisation in case
the first frame is skipped due to some error.

Reviewed-by: Robert Mader <robert.mader@collabora.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:32 +00:00
Milan Zamazal
5f3cdafe0f libcamera: ipa: simple: Introduce a general correction matrix
Let's introduce IPAActiveState::combinedMatrix that is separate from
IPAActiveState::ccm and represents the overall correction matrix, not
only the sensor colour correction matrix.

IPAActiveState::ccm still includes everything; this is changed in the
followup patch.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:32 +00:00
Milan Zamazal
a7a0852662 libcamera: ipa: simple: Rename "ccm" identifiers not specific to CCM
Let's rename the identifiers that are related to general colour
corrections applied by matrix operations, rather than directly to the
sensor colour correction matrix.

Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Robert Mader <robert.mader@collabora.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:20:27 +00:00
Milan Zamazal
77942a3bd0 libcamera: ipa: simple: Generalize tracking matrix changes
IPAActiveState::ccm stores the colour correction matrix (CCM) and
whether it has been changed.  The change flag is later used when
recomputing or not the lookup tables.

But the CCM may include other corrections than just the sensor colour
correction, for example white balance and saturation adjustments.  These
things should be separated and IPAActiveState::ccm should represent just
the CCM itself.

As the first step towards that cleanup, let's separate the change flag
from the CCM.  And wrap the only remaining member of
IPAActiveState::ccm.

Also, let's reset the separated change flag in the lookup tables; it'll
be no longer tied to just CCM handling.

This patch doesn't change actual behaviour and it still reports the
combined matrix as CCM in metadata.  This is addressed in the followup
patches.

Reviewed-by: Bryan O'Donoghue <bod.linux@nxsw.ie>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:19:51 +00:00
Milan Zamazal
3dbe06a15f libcamera: ipa: simple: Unwrap IPAFrameContext::ccm
The struct has only one member and there is no immediate need to add
more.  Let's use the member directly, to make things a bit simpler.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:19:51 +00:00
Milan Zamazal
7a8a3b6340 libcamera: ipa: simple: Remove an unused include from awb.cpp
<algorithm> is not used any more.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 15:19:51 +00:00