Commit Graph

4966 Commits

Author SHA1 Message Date
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
Bryan O'Donoghue f520b29fe9 libcamera: software_isp: debayer_egl: Add an eGL Debayer class
Add a class to run the existing glsl debayer shaders on a GBM surface.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Co-developed-by: Robert Mader <robert.mader@collabora.com>
[bod: took scaling and buffer size fixes from Robert]
[bod: took fix for center byte calculation from Hans]
[bod: took formatting fixes from Milan]
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Co-developed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Robert Mader <robert.mader@collabora.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 db09fcd8b6 libcamera: software_isp: Add a Size_ member variable to pass to eGL later
We will be initialising eGL from Debayer::start(). We need a copy of the
size data passed in configure() to tell the fragment shaders the right
output size.

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 7e72e84f3d libcamera: software_isp: Add member variables to track selected input/output pixelFormat
In order to have Debayer::start() tell the eGL shader compilation routine what
the input and output pixel format is, we need to have a copy of the
selected format available. Add variables to the inputConfig and
outputConfig structures to allow tracking of this data for later use.

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
Hans de Goede 5b609e7a44 libcamera: shaders: Fix input sampling when width != stride
When bayer_unpacked.vert is calculating the center and x/yCoord values
stride != width is taken into account for x/yCoord deltas since it is taken
into account by debayer_egl when setting the x part of tex_step uniform.

But it is not taken into account for the center.x which is just directly
copied from textureIn, leading to the input width sampling covering
the entire input stride instead of just covering the input width.

Use the existing and currently unused stride_factor uniform to pass
the width/stride ratio and correct center.x for this. This fixes
the misrendering seen on x86 laptops which is caused by the CSI2 receiver
there requiring a stride which is a multiple of 32 often leading to
stride != width.

Signed-off-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:57 +00:00
Bryan O'Donoghue e4effc1e30 libcamera: shaders: Add support for contrast
Apply contrast after black-level and CCM operations.

Suggested-by: Milan Zamazal <mzamazal@redhat.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
Bryan O'Donoghue 46aac79a44 libcamera: shaders: Add support for Gamma
Add gamma compensation to the debayer shaders after colour correction is
applied.

Similarly only apply the calculated Gamma curve when using the CCM as the
lookup tables already contain the data.

Suggested-by: Milan Zamazal <mzamazal@redhat.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
Bryan O'Donoghue 6029dcf9a6 libcamera: shaders: Add support for black level compensation
Add the ability to apply a int blacklevel subtraction against the
demosaiced data prior to application of colour correction data.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.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: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:57 +00:00
Bryan O'Donoghue 58823cbf68 libcamera: shaders: Extend bayer shaders to support swapping R and B on output
We can easily facilitate swapping R and B on output. Pivot on an
environment define for this purpose.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.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 a4e82c950b libcamera: shaders: Extend debayer shaders to apply CCM gains
Extend Bayer shaders to support application of a passed CCM table.

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 c9954de93d libcamera: shaders: Use highp not mediump for float precision
mediump gives 10 bits of mantissa as the resolution. At higher resolutions
10 bits of accuracy is insufficient - for example at a width of 1928 bytes
we need log2(1928) = ~11 bit resolution.

Switching to highp gives us 23 bits of mantissa giving a sample width
precision of about 2^23 ~ 8,388,608.

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
Milan Zamazal c31d6dba03 libcamera: shaders: Rename bayer_8 to bayer_unpacked
bayer_8.* shaders are now used for all unpacked sensor data formats,
regardless of the pixel bit width.  Let's rename the "8-bit" shaders to
avoid confusion.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
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: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:57 +00:00
Bryan O'Donoghue 76973876b8 qcam: viewfinder_gl: Set no-op Bayer shader values
Populate qcam viewfinder_gl to set default Bayer values so that the
shaders can be used in their original mode without conditional compilation.

Set an identity CCM, identity Black Level and set Gamma and Contrast to
1.0f respectively.

Once this change is made we can use the Bayer shaders in their original
format in qcam with raw streams.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.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: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:57 +00:00
Bryan O'Donoghue 99fd2e669c libcamera: software_isp: egl: Add a eGL base helper class
Introduce an eGL base helper class which provides an eGL context based on a
passed width and height.

The initGLContext function could be overloaded to provide an interface to a
real display.

A set of helper functions is provided to compile and link GLSL shaders.
linkShaderProgram currently compiles vertex/fragment pairs but could be
overloaded or passed a parameter to link a compute shader instead.

Breaking the eGL interface away from debayering - allows to use the eGL
context inside of a dma-buf heap cleanly, reuse that context inside of a
debayer layer and conceivably reuse the context in a multi-stage shader
pass.

Small note the image_attrs[] array doesn't pass checkstyle.py however the
elements of the array are in pairs.

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
[bod: Takes fix from Hans for constructor stride bpp]
[bod: Drops eglClientWaitSync in favour of glFinish Robert/Milan]
Co-developed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Co-developed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Robert Mader <robert.mader@collabora.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 c60b1ce819 libcamera: software_isp: gbm: Add a GBM helper class for GPU surface access
A helper class to interact with GBM. This will allow us to specify the
internal storage format of the GPU when making a texture for the Debayer
vertex/fragment shaders and thus ensure we receive an uncompressed and
untiled output buffer.

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Robert Mader <robert.mader@collabora.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 a1a6253ff9 libcamera: software_isp: debayer: Latch contrastExp not contrast to debayer parameters
Pass contrastExp as calculated in lut to debayer params not the raw
contrast. This way we calculate contrastExp once per frame in lut and pass
the calculated value into the shaders, instead of passing contrast and
calculating contrastExp once per pixel in the shaders.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
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: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-07 17:02:57 +00:00
Barnabás Pőcze c63f2c72cd libcamera: base: log: Add LIBCAMERA_LOG_COLOR env var
Replace the `LIBCAMERA_NO_LOG_COLOR` env variable with another environment
variable that recognizes the "auto", "yes", "no" values. When set to "auto",
the messages are only colored if the standard error is a tty (as determined
by `isatty()`).

"auto" is the default value. This ensures that the ansi escape codes won't
litter the output if the stderr is redirected to a file, `tee`, etc.

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-06 18:05:28 +01:00
Naushir Patuck d9d265cfce pipeline: rpi: Rework internal buffer allocations
In order to clear the V4L2VideoDevice cache, we must call
V4L2VideoDevice::releaseBuffers() when stopping the camera. To do this
without releasing the allocated buffers, we have to rework the internal
buffer allocation logic.

Remove calls to V4L2VideoDevice::importBuffers() and releaseBuffers()
from within the RPi::Stream class. Instead, move these calls to the
PipelineHandlerBase class, where we can call releaseBuffers(), i.e. clear
the V4L2VideoDevice cache unconditionally on stop without de-allocating
the internal buffers.

The code in Stream::clearBuffers() can be then moved into releaseBuffers()
which will actually de-allocate the internal buffers when required.

Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/265
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> # rpi4
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2026-01-06 13:30:20 +01:00
Naushir Patuck 9bb64d2c8e pipeline: rpi: Rename Stream::prepareBuffers to Stream::allocateBuffers
This rename is in preparation for a subsequent change where only
buffer allocations happen in this function.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2026-01-06 13:30:20 +01:00
Hans de Goede 03fc5f6c94 ipa: simple: agc: Make sure activeState.agc expo/again are always initialized
If the first frame of a stream is bad, the IPA will not get called with
frame == 0, leaving activeState.agc expo/again uninitialized. This causes
the agc algorithm to set a very low gain and exposure on the next run
(where it will hit the if (!stats->valid) {} path) resulting in starting
with a black image.

Fix this by using a valid flag instead of checking for frame == 0.

The entire activeState gets cleared to 0 on configure() resetting the new
valid flag.

Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-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-05 14:59:44 +00:00
Vasiliy Doylov 98e5e56150 ipa: simple: fix minimal analog gain init
On most imx sensors the formula seems to be:

again_float = 512.0 / (512.0 - again_ctrl_value)

So the minimum again of 0 makes sense and actually translates to a gain of 1.0.
And the max gain of 400 leads to 512.0 / 112.0 = 4.57 which is about typical for
a maximum again. Since a minimum again value of 0 is actually normal, the special
handling of againMin == 0 is undesirable and this is actually causing problems
on these IMX sensors. again10 correctly gets set to 0 which is less than the
adjusted againMin which causes the AGC code to not work properly.

Fix this by dropping the special handling of againMin == 0.

Signed-off-by: Vasiliy Doylov <nekocwd@mainlining.org>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2026-01-05 14:49:06 +00:00
Barnabás Pőcze 2861817f09 libcamera: camera_manager: CameraManager::version(): Add threadsafe ref
Use the `\threadsafe` alias to refer to the thread safety documentation
page instead of just formatting the word as italic.

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>
2025-12-19 11:35:43 +01:00
Barnabás Pőcze 4c4a333c88 apps: lc-compliance: Commit camera configuration last
Save the result of `Camera::generateConfiguration()` in a local variable,
and only commit it to the member variable `config_` if it passes all checks.
This removes the need for explicit `config_.reset()` calls in error paths,
hence making things simpler.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-12-18 16:47:35 +01:00
Jacopo Mondi 7c847b1159 apps: cam: Do not override Request::controls()
The ControlList associated with a Request are created with
the libcamera::controls::controls id map.

The cam application, when parsing controls from a script
assigns to the Request's control list a newly created one, which is
initialized without a valid idmap or info map.

This causes IPA that run in isolated mode to fail, as the IPC
serialization/deserialization code requires all ControlList to have
a valid idmap or info map associated.

Instead of overwriting the Request::controls() list, merge it with
the one created by cam when parsing the capture script.

Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/295
Fixes: 568865a6c1 ("cam: Use script parser to set controls")
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>
2025-12-16 15:02:54 +01:00
Jacopo Mondi 310cd8bc07 libcamera: camera: Ensure a request's controls are valid
The list of controls part of a Request is initialized with the
ControlInfoMap of the Camera the Request is created from.

Applications can re-assign the controls list in a Request
which could cause issues during serialization.

Validate that the ControlList in a Request is valid when
the Request is queued to the Camera by inspecting the
ControlInfoMap pointer.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2025-12-16 15:02:54 +01:00
Jacopo Mondi b7ed763f0d libcamera: request: Make controls_ a class instance
The controls_ member variable is a pointer, for no specific reason.
Make it an instance and simplify the class constructor and destructor.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-12-16 15:02:54 +01:00
Jacopo Mondi 06d16fd805 libcamera: request: Make metadata_ a class instance
The metadata_ member variable is a pointer, for no specific reason.
Make it an instance and simplify the class constructor and destructor.

Suggested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-12-16 15:02:54 +01:00
Jacopo Mondi dce2ef36f2 libcamera: request: Move metadata_ to Private
Address a long standing \todo item that suggested to implement a
read-only interface for the Request::metadata() accessor and deflect to
the internal implementation for the read-write accessor used by pipeline
handlers.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Acked-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-12-16 15:02:53 +01:00
Jacopo Mondi a8b8485aca libcamera: request: Create control list with Camera info map
The control lists associated with a Request is created with the global
libcamera::controls::controls id map.

This is fine as the idmap/info map used to contruct a ControlList are not
used for any control validation purposes by the libcamera code.

However creating a ControlList with the camera ControlInfoMap has two
advantages:

1) The idmap can be extracted from the info map, but not the other way
   around
2) The control list is constructed with a valid map of info to the
   controls it can actually supports, instead of the global map of
   libcamera controls

Initialize the ControlList part of a Request with the Camera control
info map, as the association between a Request and a Camera is permanent
and valid for the whole lifetime of a Request.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-12-16 15:02:53 +01:00
Jacopo Mondi 99e35cc9ec ipa: mali-c55: Introduce MaliC55Params
Implement MaliC55Params to derive from V4L2Params and use the new
helpers in the Mali C55 IPA algorithms implementation.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Tested-by: Antoine Bouyer <antoine.bouyer@nxp.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-16 15:02:53 +01:00
Jacopo Mondi bd7b54876d ipa: libipa: Introduce V4L2Params
The existing RkISP1Params helper class allows the RkISP1 IPA to handle
both the extensible parameters format and the legacy fixed-size format.

With the introduction of v4l2-isp.h in the Linux kernel the part of
the RkISP1Params helper class that handles extensible parameters can
be generalized so that other IPA modules can use the same helpers
to populate a parameters buffer compatible with v4l2-isp.h.

Generalize the RkISP1Params class to a new libipa component named
V4L2Params and derive the existing RkISP1Params from it, leaving
in the RkISP1-specific implementation the handling of the legacy format.

Deriving RkISP1Params from V4L2Params requires changing the size
associated to each block to include the size of v4l2_params_block_header
in the ipa:rkisp1::kBlockTypeInfo map as the V4L2Params::block()
implementation doesn't account for that as RkIS1Params::block()
implementation did.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Tested-by: Antoine Bouyer <antoine.bouyer@nxp.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-16 15:02:53 +01:00
Jacopo Mondi 907cd64a17 ipa: mali-c55: Update header file and adjust IPA
Update Mali C55 header file to the version merged in Linux v6.19-rc1 at
revision 08a99369f44e ("media: uapi: Add parameters structs to
mali-c55-config.h") with applied on top the in-review patch:
https://lore.kernel.org/all/20251215-mali-c55-header-update-for-v6-19-rc1-v1-3-69f56dee3c71@ideasonboard.com/

Adjust the IPA module to use the new header version which uses the
v4l2-isp framework.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Tested-by: Antoine Bouyer <antoine.bouyer@nxp.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-12-16 15:02:52 +01:00
Barnabás Pőcze 2b266a4ab2 libcamera: device_enumerator_udev: Handle duplicate devices
It is possible that same device is processed multiple times, leading to
multiple `MediaDevice`s being instantiated, mostly likely leading to
a fatal error:

  Trying to register a camera with a duplicated ID xyzw...

There is a time window after the `udev_monitor` has been created in `init()`
and the first (and only) enumeration done in `enumerate()`. If e.g. a UVC
camera is connected in this time frame, then it is possible that it will be
processed both by the `udevNotify()` and the initial `enumerate()`, leading
to the fatal error. This can be reproduced as follows:

  1. $ gdb --args cam -m
  2. (gdb) break libcamera::DeviceEnumeratorUdev::enumerate
  3. (gdb) run
  4. when the breakpoint is hit, connect a usb camera
  5. (gdb) continue
  6. observe fatal error

To address this, keep track of the devnums of all devices reported by
udev, and reject devices with already known devnums. This ensures that
the same device won't be reported multiple times (assuming that udev
reports "add" / "remove" events in the correct order).

Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/293
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: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-12-16 10:49:27 +01:00
Michael Olbrich c6a8808eba ipa: rpi: remove executable bits from data files
These are just data files. Like all other files in the same directory,
they should not be executable. So change the mode to match.

Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-16 09:43:45 +00:00
Kieran Bingham e4a4eb0a94 ipa: simple: awb: Fix ColourGains reported
The AWB gains reported in the metadata are currently scaled against the
maximum gain, but in fact the gain itself is already stored as a
floating point gain value.

Remove the incorrect scaling and report the gains directly.

Fixes: a0b97475b1 ("ipa: simple: Report the ColourGains in metadata")
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-16 09:43:44 +00:00
Barnabás Pőcze f0499ecfc2 utils: gen-shader-headers: Fix subproject build
Meson already takes care of passing the proper absolute or relative
paths to commands. There is no need do more path manipulation.

So simplify the script by using the paths as-is. This also fixes the
path manipulation issue that prevented libcamera from building as a
subproject.

Fixes: 19371dee41 ("utils: gen-shader-headers: Add a utility to generate headers from shaders")
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>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-15 17:33:11 +00:00
Julien Vuillaumier 34c5cf2480 gstreamer: Add raw support to libcamerasrc stream-role property
The current definition of the stream-role property of libcamerasrc
element does not allow for the Raw (0) value to be assigned.
That property is used to query the pipeline handlers through
generateConfiguration(roles) to retrieve the formats exposed to
the user. Not being able to specify the raw stream-role, bayer
formats are not reported so can not be used for caps negotiation.

Adding value stream-role=raw enables usage of bayer GStreamer pipelines
like:

`gst-launch-1.0 libcamerasrc camera-name=<name> src::stream-role=raw !
    video/x-bayer, format=bggr16le ! ...`

Signed-off-by: Julien Vuillaumier <julien.vuillaumier@nxp.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-15 17:05:30 +00:00
Milan Zamazal 6293fa3308 libcamera: simple: Make raw streams working
When a raw stream is requested, whether alone or together with a
processed stream, its buffers must be handled outside the software ISP
machinery.  They serve as output buffers, even when a processed stream
is produced.  But when both processed and raw streams are requested, the
buffer can be completed only after the processing is finished, to make
sure it's untouched by the application as long as the processing runs.

At most one raw stream and at most one processed stream are supported
and can be combined.  An example of producing both raw and processed
files using `cam' application:

  cam -c1 -C100 -Ffile# \
    -s role=viewfinder,width=1920,height=1080,pixelformat=RGB888 \
    -s role=raw,width=3280,height=2464,pixelformat=SRGGB8

Note the difference in viewfinder and raw stream sizes due to the fact
that debayering requires enlarging the image width, which enforces
selecting a larger sensor resolution in this case.

In order to track whether a raw stream is requested and which one it is,
SimpleCameraData::rawStream_ member variable is introduced.

This is the final step to make raw streams working.

Reviewed-by: Umang Jain <uajain@igalia.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-13 11:29:43 +00:00
Milan Zamazal 3991f02209 libcamera: simple: Require metadata only when software ISP is used
If software ISP is enabled then metadata is required in the simple
pipeline.  But this doesn't apply if the software ISP is not actually
used, for example when only a raw stream is produced.  Then the pipeline
waits for metadata that never comes.

This patch fixes the problem by requiring metadata only when software
ISP is used.

Reviewed-by: Umang Jain <uajain@igalia.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-13 11:29:43 +00:00
Milan Zamazal a19f725695 libcamera: simple: Set the number of software ISP streams to 2
When software ISP is enabled, we want to be able to provide a raw stream
in addition to the processed stream.  For this purpose, we need two
streams.  If only the processed stream is requested, it doesn't harm to
allocate two.

The number of streams is determined as a camera property in the pipeline
matching.  To be able to produce both raw and processed output, two
streams must be provided.  The actual number of streams needed (one or
two) is determined only in SimplePipelineHandler::validate().

In theory, software ISP could produce multiple processed streams but
this is out of scope of this patch series.  Hence two streams are
sufficient at the moment.

When software ISP is not enabled, the camera won't be able to produce
multiple streams (assuming there's no hardware converter) and only
single stream should be allocated as before.  The simple pipeline
handler assumes there's a linear pipeline from the camera sensor to a
video capture device, and only supports a single stream.  Branches in
the hardware pipeline that would allow capturing multiple streams from
the same camera sensor are not supported.  We have no plan to change
that, as a device that can produce multiple streams will likely be
better supported by a dedicated pipeline handler.

Reviewed-by: Umang Jain <uajain@igalia.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-13 11:29:43 +00:00
Milan Zamazal e9252384f5 libcamera: simple: Don't enforce conversion with an added raw stream
When a raw stream is requested, either alone or together with a
processed stream, it can be produced without conversion.  Let's amend
the corresponding check on the number of configurations, so that the
mere presence of a raw stream doesn't enforce conversion.

Reviewed-by: Umang Jain <uajain@igalia.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-13 11:29:43 +00:00
Milan Zamazal 7b068dda96 libcamera: simple: Validate raw stream configurations
SimpleCameraConfiguration::validate() looks for the best configuration.
As part of enabling raw stream support, the method must consider raw
streams in addition to the processed streams.

Raw streams are adjusted from the capture format and size.

Configuration validation computes the maximum size of all the requested
streams and compares it to the output sizes.  When e.g. only a raw
stream is requested then this may result in an invalid adjustment of its
size.  This is because the output sizes are computed for processed
streams and may be smaller than capture sizes.  If a raw stream with the
capture size is requested, it may then be wrongly adjusted to a larger
size because the output sizes, which are irrelevant for raw streams
anyway, are smaller than the requested capture size.  The problem is
resolved by tracking raw and processed streams maximum sizes separately
and comparing raw stream sizes against capture rather than output sizes.

Note that with both processed and raw streams, the requested sizes must
be mutually matching, including resizing due to debayer requirements.
For example, the following `cam' setup is valid for imx219

  cam -s role=viewfinder,width=1920,height=1080 \
      -s role=raw,width=3280,height=2464

rather than

  cam -s role=viewfinder,width=1920,height=1080 \
      -s role=raw,width=1920,height=1080

due to the resolution of 1924x1080 actually selected for debayering to
1920x1080.  If the resolutions don't match mutually or don't match the
available sizes, validation adjusts them.

Setting up the right configurations is still not enough to make the raw
streams working.  Buffer handling must be changed in the simple
pipeline, which is addressed in followup patches.

Co-developed-by: Umang Jain <uajain@igalia.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <uajain@igalia.com>
Signed-off-by: Umang Jain <uajain@igalia.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-13 11:29:43 +00:00
Milan Zamazal b98f3ee039 libcamera: simple: Handle processed and raw formats separately
Let's handle both processed and/or raw output configurations.  In
addition to the already handled processed formats and sizes, this patch
adds handling of raw formats and sizes, which correspond to the capture
formats and sizes.

When creating stream configurations, raw or processed formats are
selected according to the requested stream roles.

This is another preparatory patch without making raw outputs working.

Reviewed-by: Umang Jain <uajain@igalia.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-13 11:29:17 +00:00
Milan Zamazal 2d9b647e56 libcamera: simple: Exclude raw configurations from output conversions
In order to support raw streams, we need to add raw formats to software
ISP configurations.  In this preparatory patch, the raw formats are
excluded from output configurations for conversions.

Reviewed-by: Umang Jain <uajain@igalia.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-13 11:29:17 +00:00
Bryan O'Donoghue 5f51e2e545 libcamera: software_isp: lut: Make contrast available in debayer params
Provide the contrast used in IPA to Bayer parameters. Similar to the
calculated Gamma value we will pass this value into the debayer fragment
shader for further consumption.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-12 23:32:53 +00:00
Bryan O'Donoghue 5bfb96661f libcamera: software_isp: lut: Make gamma from lut.cpp available in debayer params
Provide the gamma used in IPA to Bayer parameters. We will pass Gamma into
the shader via a uniform and can then tweak that value from outside at
will.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-12 23:32:53 +00:00
Bryan O'Donoghue 724a29e3cd libcamera: software_isp: blacklevel: Make black level available in debayer params
Populate black level gain in blacklevel::prepare(). A copy is made of the gain
value in the DebayerParams structure.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-12 23:32:53 +00:00
Bryan O'Donoghue 3d7ef342b7 libcamera: software_isp: lut: Make CCM available in debayer params
Provide the CCM calculated in LUT to the debayer params structure for
consumption in the debayer shaders.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-12 23:32:52 +00:00
Bryan O'Donoghue 0640f5ac11 libcamera: software_isp: debayer: Make the debayer_ object of type class Debayer not DebayerCpu
Make the type of object Debayer not DebayerCpu thus allowing us to assign
the object to either DebayerCpu or DebayerEGL.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-12-12 23:32:52 +00:00