Commit Graph

6031 Commits

Author SHA1 Message Date
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
Kieran Bingham
aa2a0812e6 apps: qcam: Disable -Wsfinae-incomplete
GCC-16 has updated the warnings enabled and now includes
-Wsfinae-incomplete triggering breakage in the included headers from
Qt6:

/usr/include/qt6/QtCore/qregularexpression.h:31:21: error: defining ‘QRegularExpression’, which previously failed to be complete in a SFINAE context [-Werror=sfinae-incomplete=]

This is a Qt header issue outside of libcamera’s control. Disable the
warning for qcam to restore buildability with newer GCC versions.

Link: https://qt-project.atlassian.net/browse/QTBUG-143470
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-01-28 13:35:49 +00:00
Milan Zamazal
07240afa12 libcamera: simple: Fix black level offsets in AWB
The black level offset subtracted in AWB is wrong.  It assumes that the
stats contain sums of the individual colour pixels.  But they actually
contain sums of the colour channels of larger "superpixels" consisting
of the individual colour pixels.  Each of the RGB colour values and the
computed luminosity (a histogram entry) are added once to the stats per
such a superpixel.  This means the offset computed from the black level
and the number of pixels should be used as it is, not divided.

The patch fixes the subtracted offset.  Since the evaluation is the same
for all the three colours now, the individual class variables are
replaced with a single RGB variable.

Fixes: 4e13c6f55b ("Honor black level in AWB")
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Robert Mader <robert.mader@collabora.com>
Tested-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 12:08:21 +00:00
Peter Bailey
10e4e5ba1e ipa: rpi: pisp: vc4: Update tuning files for new AWB
Update the tuning files to include the new AWB algorithm. It is
enabled by setting "enabled" to true for the AWB algorithm that you
want, and the same field to false for the one you don't want. Note
that you may enable only one of the two algorithms!

The AWB models themselves are not included with libcamera. They will
be supplied from the Raspberry Pi software repositories.

Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 09:14:55 +00:00
Peter Bailey
7214950ffe ipa: rpi: controller: Ignore algorithms that are not enabled
Algorithms may now contain an "enabled" field which can be set to
false to disable it and prevent it from being loaded. If not present,
algorithms are treated as enabled by default for backwards
compatability.

We additionally prevent duplicate versions of the same algorithm type
(such as AWB) from loading, and flag an error. This will prevent
undefined behaviour if (for example) two distinct AWB algorithms are
trying to run simultaneously.

Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 09:14:55 +00:00
Peter Bailey
045bfb1b8f ipa: rpi: controller: awb: Add Neural Network AWB
Add an AWB algorithm which uses neural networks.

Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 09:14:55 +00:00
Peter Bailey
6d38984436 ipa: rpi: controller: awb: Separate Bayesian AWB into AwbBayes
Move parts of the AWB algorithm specific to the Bayesian algorithm into a
new class. This will make it easier to add new AWB algorithms in the future.

Signed-off-by: Peter Bailey <peter.bailey@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-28 09:14:55 +00:00
Barnabás Pőcze
9b477c114b libcamera: v4l2_subdevice: Avoid unnecessary copy
There is no reason make a copy of the name, so don't do it,
and instead use a reference.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
2026-01-27 15:53:25 +01:00
Barnabás Pőcze
ddef786eee libcamera: v4l2_subdevice: Avoid reconstructing the std::regex object
Make the `std::regex` object have static lifetime to avoid
reconstructing it on every call.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
2026-01-27 15:53:22 +01:00
Barnabás Pőcze
330c390e6f libcamera: v4l2_subdevice: Remove unnecessary variable
`model` is not used, so remove it.

Fixes: 5d2aad02e8 ("libcamera: add model() for retrieving model name in V4L2Subdevice")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2026-01-27 15:53:18 +01:00
Jacopo Mondi
ad2d317a0c ipa: ipu3: Retain Camera::controls() after ipa->configure()
Similar to what commit acfd602767 ("ipa: rkisp1: Fix algorithm controls
vanish after configure") did for the RkISP1 IPA, replace the usage of
unordered_map::merge() at updateControls() time with
unordered_map::insert().

As unordered_map::merge moves items from the source map, it deletes
controls registered at algorithms initialization time in the
ipaContext.ctrlMap. As at configure() time updateControls() is called
again and the list of Camera controls is refreshed, the controls
registered at algorithms initialization time are lost.

Fixes: 87353f2bba ("ipa: ipu3: Derive ipu3::algorithms::Agc from AgcMeanLuminance")
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-23 17:40:15 +01:00
Jacopo Mondi
202e330789 ipa: mali-c55: Retain Camera::controls() after ipa->configure()
Similar to what commit acfd602767 ("ipa: rkisp1: Fix algorithm controls
vanish after configure") did for the RkISP1 IPA, replace the usage of
unordered_map::merge() at updateControls() time with
unordered_map::insert().

As unordered_map::merge moves items from the source map, it deletes
controls registered at algorithms initialization time in the
ipaContext.ctrlMap. As at configure() time updateControls() is called
again and the list of Camera controls is refreshed, the controls
registered at algorithms initialization time are lost.

Fixes: fe989ee514 ("ipa: mali-c55: Add Mali-C55 ISP IPA module")
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-23 17:39:29 +01:00
Barnabás Pőcze
9e6fcab87c libcamera: pipeline: virtual: Don't use span iterator as pointer
Pointer to the contiguous data of a container is to be retrieved
using the `data()` member function. Using `begin()` in contexts
that require pointers is not correct as the iterator may be
something entirely different. So use `data()` where applicable.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
2026-01-23 16:49:03 +01:00
Naushir Patuck
b9b53845fe v4l2: v4l2_camera_proxy: Fix for getting default FrameDurationLimits
The default values for controls::FrameDurationLimits is now an array but
the v4l2 proxy is fetching it as a scalar value, causing a runtime
error. Fix this by templating the getter with the correct
Span<const int64_t, 2> type.

This fix also requires the RPi initial default value for FrameDurationLimits
to be specified as a Span<const int64_t, 2>.

As a drive-by, remove the hard-coded 33ms min and 120ms max frame
duration values in the initial defaults, and use the defaultMinFrameDuration
and defaultMaxFrameDuration const values. This change is inconsequential
to runtime operation as these always get overridden on the first camera
configure call.

Fixes: 4e9be7d11b ("ipa: ipu3, mali-c55, rkisp1, rpi: Fix reporting non-scalar controls")
Closes: https://github.com/raspberrypi/libcamera/issues/321
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2026-01-23 16:07:56 +01:00
Barnabás Pőcze
71f0280709 libcamera: base: utils: join(): Don't use const_iterator directly
For example, `std::span` does not have a `const_iterator` typedef before
C++23, so compilation fails. Simply use `auto`. The `const` qualifier on
`items` should already ensure, that such an iterator will be be used that
the container deems appropriate for "const" access.

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-01-23 12:02:36 +01:00
Robert Mader
7350d6cc5d Revert "libcamera: software_isp: gbm: Add a GBM helper class for GPU surface access"
GBM is not used any more - remove the helper class.

This reverts commit c60b1ce819.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sm8250/rb5, x1e/Dell Insprion14p
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-01-21 12:05:00 +00:00
Robert Mader
a5e01866ae egl: Add workaround for Mesa <= 22.2
Older Mesa versions with EGL headers missing the change from
https://github.com/KhronosGroup/EGL-Registry/pull/130
pull in Xlib headers, causing build issues.

This notably happens on the Debian 11 CI image, which until now does not
build the shared EGL code due to missing GBM dependencies. That will
change in the following commit, thus include a workaround.

Suggested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Signed-off-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-21 12:05:00 +00:00
Robert Mader
0c2ed9ebf9 egl: Use the Mesa surfaceless platform instead of GBM
Mesa surfaceless platform appears to be a better fit for the use-case at hand:
1. Like GBM it is Mesa specific, so no change in supported setups is
   expected. If ever required, a fallback to the generic device platform
   could be added on top.
2. It leaves the complexity of selecting a renderer device to the
   driver, reducing code and dependencies.
3. It allows to use llvmpipe / software drivers without dri device,
   which can be useful on CI or debugging (with LIBGL_ALWAYS_SOFTWARE=1).

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sm8250/rb5, x1e/Dell Insprion14p
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com> # TI AM69
Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> # ThinkPad X1 Yoga Gen 7 + ov2740
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-21 12:05:00 +00:00
Robert Mader
4a5ebcf675 libcamera: simple: Enable SoftISP for imx7-csi
Since commit "libcamera: simple: Make raw streams working" apps that rely
on raw streams - such as Millipixels - can work with the SoftISP being
enabled. Thus let's enable the later by default.

Tested on a Librem5.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-20 17:31:40 +00:00
Barnabás Pőcze
2318a2863b libcamera: base: log: Inline LOG() into ASSERT()
Avoid the conditional logic in the expansion of `LOG()` inside `ASSERT()` by
directly calling `_log(...)` with the appropriate parameters.

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-20 14:03:02 +01:00
Barnabás Pőcze
75c963146e libcamera: base: log: Remove LogInvalid check
A `LogMessage` instance cannot be moved or copied, so a severity of
`LogInvalid` is only possible if the message was constructed with that
log level explicitly. However, being a completely internal type, this
does not occur. So remove the check. And even if it does, it's probably
still better to print the message than to drop it silently.

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-20 14:03:02 +01:00
Barnabás Pőcze
140dd0de85 libcamera: base: log: Do not check severity before printing
Now that the severity of the log message and the category is compared in
the expansion of the `LOG()` macro, there is no need to do it again in the
destructor.

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-20 14:03:02 +01:00
Barnabás Pőcze
7d5321ac52 libcamera: base: log: Do not instantiate disabled LogMessages
At the moment every `LOG()` macro invocation results in a `LogMessage` being
created, the message serialized into an `std::stringstream`. Only in the
destructor is it actually checked whether the given `LogCategory` enables
the given log level.

This is not too efficient, it would be better to skip the log message
construction and all the `operator<<()` invocations if the message will
just be discarded.

This could be easily done if the `LOG()` macro accepted its arguments like a
traditional function as in that case an appropriate `if` statement can be
injected in a do-while loop. However, that is not the case, the `LOG()` macro
should effectively "return" a stream.

It is not possible inject an `if` statement directly as that would
lead to issues:

  if (...)
    LOG(...)
  else
   ...

The `else` would bind the to the `if` in the `LOG()` macro. This is
diagnosed by `-Wdangling-else`.

An alternative approach would be to use a `for` loop and force a single
iteration using a boolean flag or similar. This is entirely doable but
I think the implemented approach is easier to understand.

This change implements the early log level checking using a `switch` statement
as this avoids the dangling else related issues. One small issue arises
because having a boolean controlling expression is diagnosed by clang
(`-Wswitch-bool`); the result is cast to `int` to avoid the warning.

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-20 14:03:02 +01:00
Barnabás Pőcze
95bf04298e treewide: Remove libcamera::LOG(...) occurrences
When a class inherits from `Loggable`, it will have a protected `_log()`
function and that will be used instead of the global `_log()` function in the
expansion of the `LOG()` macro. However, if such a class has static member
functions, then simply writing `LOG()` will not work because name lookup will
find the non-static member function and not the global function, resulting in
a compiler error because the non-static member cannot be invoked without an
object, and there is no object in a static member function.

This can be avoided by using `using libcamera::_log;`, thereby bringing the
global declaration into the current scope.

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-01-20 14:02:44 +01:00
Robert Mader
6725ea8edd egl: Print GLES version
It might come in handy to know whether 2.0 or e.g. 3.2 is used.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # Thinkpad X1 Carbon G13 IPU7 ov08x40
Tested-by: Milan Zamazal <mzamazal@redhat.com> # TI AM69
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-19 10:25:53 +00:00
Robert Mader
07335cbeb1 egl: Remove duplicated logging of EGL version
The line below already prints it.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # Thinkpad X1 Carbon G13 IPU7 ov08x40
Tested-by: Milan Zamazal <mzamazal@redhat.com> # TI AM69
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-19 10:25:49 +00:00
Robert Mader
22b15ff683 egl: Remove bpp variable
It's unused and, in one case, was set wrongly.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # Thinkpad X1 Carbon G13 IPU7 ov08x40
Tested-by: Milan Zamazal <mzamazal@redhat.com> # TI AM69
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-19 10:25:44 +00:00
Robert Mader
7c1527cd44 egl: Remove unused functions
They are left-overs from older iterations of the GPU-ISP.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # Thinkpad X1 Carbon G13 IPU7 ov08x40
Tested-by: Milan Zamazal <mzamazal@redhat.com> # TI AM69
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-19 10:25:05 +00:00
Khem Raj
ab9c943971 meson: Do not force libc++ when using clang
Currently the meson scripts force the use of libc++ when using clang
as the compiler. This behaviour cannot be overridden by the user, and
it is suboptimal as it means that a clang build cannot reliably use
system qt, gtest, etc since those might use libstdc++.

To fix that, simply do not force the use of any particular standard
library, and detect the currently used one based on predefined macros.
This is exactly what meson does internally, although the result is
not readily available for meson scripts[0][1]; so the test needs
to be largely replicated.

[0]: 675b47b069
[1]: https://stackoverflow.com/a/31658120

Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/226
Signed-off-by: Khem Raj <raj.khem@gmail.com>
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-01-16 09:33:09 +01:00
Barnabás Pőcze
65db93f8f4 gstreamer: Be prepared when queueing request
The moment execution enters `Camera::queueRequest()`, an application must be
prepared to receive the corresponding `requestCompleted` signal. However,
the gstreamer element is currently not prepared: it queues the request,
takes a lock, then inserts into a list.

If the request completion handler acquires the lock right after queueing the
request, then it will not find the expected object in the list. Even potentially
encountering an empty list, running into undefined behaviour when trying
to pop the first element from it.

Fix that by queueing the request while the lock is held.

Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/238
Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/306
Fixes: 06bd05bece ("gstreamer: Use dedicated lock for request queues")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Acked-by: Umang Jain <uajain@igalia.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-15 10:12:18 +01:00
Barnabás Pőcze
fa22b4ffef libcamera: base: event_dispatcher_poll: Dispatch POLLPRI first
When `poll()` returns multiple events for a given file descriptor, while there
is no general rule that requires it, for the use cases of libcamera, it is
better to service priority events first. So dispatch those first, and not last.

For example, a V4L2 capture device might be a source of V4L2 events (e.g. frame
start) as well as a source of dequeue-able buffers. In such cases, given the
appropriate scheduling, it is possible with the current event dispatch order
that dequeueing the buffer happens before processing the corresponding frame
start event. Such occurrence will most likely trip up any internal state machine.

The above is suspected to contribute to [0], however, that is not confirmed.

[0]: https://gitlab.freedesktop.org/camera/libcamera/-/issues/267

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2026-01-14 12:30:11 +01:00
Barnabás Pőcze
993496ba35 Documentation: guides: pipeline-handler: Refresh
Update the guide to be compatible with the current version of
libcamera, as well as sync the code snippets with [0].

Apart from libcamera related changes, `meson build` is replaced with
`meson setup build`, and direct `ninja` calls are replaced with
`meson compile -C build`. And update the code block languages where
appropriate.

[0]: https://git.libcamera.org/libcamera/vivid.git

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-13 15:33:43 +01:00
Paul Elder
5e59969dbb libcamera: control_serializer: Remove unnecessary allocation
In between versions of the patch "libcamera: control_serializer: Add
array info to serialized ControlValue", ipa_control_value_entry was
changed to be members of ipa_control_info_entry as opposed to being
serialized at the same level. The binarySize/entriesSize computation was
not updated, however, leaving some extra memory allocated for the
serialized form of ControlInfoMap.

Fix this by removing the extra size for 3 * ipa_control_value_entry.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2026-01-08 11:00:10 +09:00
Bryan O'Donoghue
aaa48bb276 libcamera: software_isp: Add a gpuisp todo list
List the series of things to do in GPU ISP in perceived order of
difficulty.

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen 6 (arm64) ov02c10 + X1c gen 12 ov08x40
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:58 +00:00
Bryan O'Donoghue
2cf92d00c2 libcamera: software_isp: debayer_egl: Make gpuisp default softisp mode
In some cases the GPU can deliver 15x performance in Debayer with the
CCM on, reference hardware Qualcomm RB5 with IMX512 sensor.

Given this large performance difference it makes sense to make GPUISP
the default for the Software ISP.

If LIBCAMERA_SOFTISP_MODE is omitted gpu will be the default. If
libcamera is compiled without gpuisp support, CPU Debayer will be used.

It is still possible to select CPU mode with LIBCAMERA_SOFISP_MODE=cpu.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen 6 (arm64) ov02c10 + X1c gen 12 ov08x40
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:58 +00:00
Bryan O'Donoghue
a350ad5467 libcamera: software_isp: Switch on default CCM at 65k
Switch on the uncalibrated CCM @ 65k colour temperature. This will become
the default for SoftISP where we have swtiched to GPUISP as default.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen 6 (arm64) ov02c10 + X1c gen 12 ov08x40
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:58 +00:00
Bryan O'Donoghue
852ffae2a0 libcamera: software_isp: lut: Change default Gamma to 1.0/2.2
Change the default softisp Gamma from 0.5 to 1.0/2.2.

Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen 6 (arm64) ov02c10 + X1c gen 12 ov08x40
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:58 +00:00
Bryan O'Donoghue
43180e12ba libcamera: software_isp: lut: Skip calculation lookup tables if gpuIspEnabled is true
On my reference platform Qualcomm RB5 sm8520 the qcam application CPU
occupancy drops from ~100% to about 95% of a single core so this one change
sheds aprox 5% CPU usage.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen 6 (arm64) ov02c10 + X1c gen 12 ov08x40
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:57 +00:00
Bryan O'Donoghue
fe9e143702 ipa: simple: Add a flag to indicate gpuIspEnabled
Flag gpuIspEnabled in the simple IPA context. This flag will allow to
selectively avoid some calculations or to generate a default CCM.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen 6 (arm64) ov02c10 + X1c gen 12 ov08x40
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:57 +00:00
Bryan O'Donoghue
a92cc12fb5 libcamera: software_isp: debayer_egl: Make DebayerEGL an environment option
If GPUISP support is available make it so an environment variable can
switch it on.

Given we don't have full feature parity with CPUISP just yet on pixel
format output, we should default to CPUISP mode giving the user the option
to switch on GPUISP by setting LIBCAMERA_SOFTISP_MODE=gpu

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen 6 (arm64) ov02c10 + X1c gen 12 ov08x40
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:57 +00:00
Milan Zamazal
999d446475 libcamera: software_isp: GPU support for unpacked 10/12-bit formats
The GPU processing supports 8-bit sensor formats and 10/12-bit packed
formats.  Support for 10/12-bit unpacked formats is missing, let's add
it.

10/12-bit unpacked formats use two adjacent bytes to store the value.
This means the 8-bit shaders can be used if we can modify them for
additional support of 16-bit addressing.  This requires the following
modifications:

- Using GL_RG (two bytes per pixel) instead of GL_LUMINANCE (one byte
  per pixel) as the texture format for the given input formats.

- Setting the texture width to the number of pixels rather than the
  number of bytes.

- Making the definition of `fetch' macro variable, according to the
  pixel format.

- Using only `fetch' for accessing the texture.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen 6 (arm64) ov02c10 + X1c gen 12 ov08x40
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:57 +00:00
Bryan O'Donoghue
6a478459f3 libcamera: software_isp: debayer_cpu: Make getInputConfig and getOutputConfig static
Make getInputConfig and getOutputConfig static so as to allow for
interrogation of the supported pixel formats prior to object instantiation.
Do this so as to allow the higher level logic make an informed choice
between CPU and GPU ISP based on which pixel formats are supported.

Currently CPU ISP supports more diverse input and output schemes.

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # ThinkPad T14s gen 6 (arm64) ov02c10 + X1c gen 12 ov08x40
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:57 +00:00