Compare commits

...

927 commits

Author SHA1 Message Date
Laurent Pinchart
afd9890b7b libcamera: delayed_controls: Inherit from Object class
A second use-after-free bug related to signals staying connected after
the receiver DelayedControls instance gets deleted has been found, this
time in the simple pipeline handler. Fix the issue once and for all by
making the DelayedControls class inherit from Object. This will
disconnect signals automatically upon deletion of the receiver.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Tested-by: Isaac Scott <isaac.scott@ideasonboard.com>
Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-11 12:25:46 +01:00
Umang Jain
fb72083975 camera: Fix spell error
Correct 'CameraConfigutation' spell error to 'CameraConfiguration'.

Signed-off-by: Umang Jain <uajain@igalia.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-08 14:10:14 +01:00
Naushir Patuck
29a88d85b7 libcamera: controls: Use nanoseconds units for FrameWallClock
Use nanoseconds for the FrameWallClock control to match the units for
other timestamp controls, including SensorTimestamp.

Update the RPi pipeline handlers to match the new nanoseconds units when
converting from SensorTimestamp to FrameWallClock.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-08 11:18:58 +01:00
Naushir Patuck
a437212753 libcamera: controls: Remove hyphenation in control description text
Remove the hyphenation in "micro-seconds" in the description for the
ExposureTime control to match the rest of the document.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-08 11:18:47 +01:00
Nick Hollinghurst
e6fb24ffdb ipa: rpi: Fix bug in AfState reporting
A previous change introduced a bug in which it reported AfStateIdle
when idle in Auto mode, when it should continue to report the most
recent AF cycle's outcome (AfStateFocused or AfStateFailed).

Also fix the Pause method so it won't reset state to AfStateIdle
when paused in Continuous AF mode (to match documented behaviour).

Fixes: ea5f451c56 ("ipa: rpi: controller: AutoFocus bidirectional scanning")
Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Tested-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-08 11:18:17 +01:00
Harvey Yang
525325440b V4L2VideoDevice: Call FrameBuffer::Private::cancel() in streamOff()
At the moment `V4L2VideoDevice::streamOff()` sets
`FrameBuffer::Private`'s metadata directly, while that's equivalent to
calling `FrameBuffer::Private::cancel()`. To ease code tracing, this
patch replace the manual modification with the function call.

Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <uajain@igalia.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-08 11:18:12 +01:00
Christian Rauch
17eed522e8 subprojects: libpisp: Update to 1.2.1
Update the libpisp wrap to use the latest 1.2.1 release which silences
an 'unused-parameter' warning.

Bug: https://github.com/raspberrypi/libpisp/pull/43
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Christian Rauch <Rauch.Christian@gmx.de>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-07-08 13:05:54 +03:00
Nick Hollinghurst
619da07f73 ipa: rpi: Update IMX708 camera tuning files for AutoFocus changes
Explicitly add new parameters: "retrigger_ratio", "retrigger_delay",
"check_for_ir". Tweak other parameters to suit algorithm changes.
(Though existing tuning files should still work acceptably.)

Add AfSpeedFast parameters for the Raspberry Pi V3 standard lens.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-03 10:24:33 +01:00
Nick Hollinghurst
ea5f451c56 ipa: rpi: controller: AutoFocus bidirectional scanning
To reduce unnecessary lens movements, allow the CDAF-based
search procedure to start from either end of the range;
or if not near an end, from the current lens position.

This sometimes requires a second coarse scan, if the first
one started in the middle and did not find peak contrast.

Shorten the fine scan from 5 steps to 3 steps; allow fine scan
to be omitted altogether when "step_fine": 0 in the tuning file.

Move updateLensPosition() out of startProgrammedScan() to avoid
calling it more than once per iteration.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-03 10:24:32 +01:00
Nick Hollinghurst
686f88707c ipa: rpi: controller: Autofocus to use AWB statistics; re-trigger
Analyse AWB statistics: used both for scene change detection
and to detect IR lighting (when a flag is set in the tuning file).

Option to suppress PDAF altogether when IR lighting is detected.

Rather than being based solely on PDAF "dropout", allow a scan to
be (re-)triggered whenever the scene changes and then stabilizes,
based on contrast and average RGB statistics within the AF window.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-03 10:24:32 +01:00
Nick Hollinghurst
3d44987bc6 ipa: rpi: controller: AutoFocus tweak earlyTerminationByPhase()
Increase threshold for ETBP, from "confEpsilon" to "confThresh".
Correct sign test to take account of pdafGain sign (typically -ve).
Reduce allowed extrapolation range, but relax the check in the
case of Continuous AF, when we go back into the PDAF closed loop.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-03 10:24:32 +01:00
Nick Hollinghurst
429a5ab48f ipa: rpi: controller: Autofocus CAF/PDAF stability tweak
When in Continuous AF mode using PDAF, only move the lens when
phase has had the same sign for at least 4 frames. This reduces
lens wobble in e.g. noisy conditions.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-03 10:24:32 +01:00
Nick Hollinghurst
0fa2b05a86 ipa: rpi: controller: AutoFocus weighting tweak
In getPhase(), stop using different weights for sumWc and sumWcp.
This should improve linearity e.g. in earlyTerminationByPhase().
Phases are slightly larger but confidence values slightly reduced.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-03 10:24:32 +01:00
Nick Hollinghurst
a283287fbf ipa: rpi: controller: Improve findPeak() function in AF algorithm
Improve quadratic peak fitting in findPeak(). The old approximation
was good but only valid when points were equally spaced and the
MAX was not at one end of the series.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-03 10:24:32 +01:00
Nick Hollinghurst
30114cadd8 ipa: rpi: Defer initialising AF LensPosition ControlInfo and value
This fixes two small bugs:

We previously populated LensPosition's ControlInfo with hard-coded
values, ignoring the tuning file. Now we query the AfAlgorithm to
get limits (over all AF ranges) and default (for AfRangeNormal).

We previously sent a default position to the lens driver, even when
a user-specified starting position would follow. Defer doing this,
to reduce unnecessary lens movement at startup (for some drivers).

Bug: https://bugs.libcamera.org/show_bug.cgi?id=258
Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-07-03 10:24:26 +01:00
Barnabás Pőcze
6b5cc1c92a libcamera: pipeline: uvcvideo: Handle controls during startup
Process the control list passed to `Camera::start()`, and set
the V4L2 controls accordingly.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <uajain@igalia.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-07-02 10:26:41 +02:00
Naushir Patuck
5f94209b1d pipeline: rpi: Fix for enumerating the media graphs
When there are multiple entities between the sensor and CFE device (e.g.
a serialiser and deserialiser or multiple mux devices), the media graph
enumeration would work incorrectly and report that the frontend entity
was not found. This is because the found flag was stored locally in a
boolean and got lost in the recursion.

Fix this by explicitly tracking and returning the frontend found flag
through the return value of enumerateVideoDevices(). This ensures the
flag does not get lost through nested recursion.

This flag can also be used to fail a camera registration if the frontend
is not found.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Umang Jain <uajain@igalia.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-07-01 02:10:34 +03:00
Barnabás Pőcze
35ee8752b7 libcamera: pipeline: uvcvideo: Silently ignore AeEnable
The `AeEnable` control is handled in `Camera::queueRequest()` but it
still reaches the pipeline handler because a single element cannot be
removed from a `ControlList`. So ignore it silently.

Fixes: ffcecda4d5 ("libcamera: pipeline: uvcvideo: Report new AeEnable control as available")
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: Paul Elder <paul.elder@ideasonboard.com>
2025-06-30 14:46:19 +02:00
Umang Jain
e9528306f2 camera_sensor: Expand on computeTransform() documentation
The description for computeTransform() when the desired orientation
cannot be achieved, can be expanded a further bit, to clearly report
that orientation will be adjusted to native camera sensor mounting
rotation.

Signed-off-by: Umang Jain <uajain@igalia.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-06-26 16:20:53 +03:00
Barnabás Pőcze
a29c53f6a6 meson: Use libyaml wrap file from wrapdb
Use the libyaml wrap file from the meson wrapdb instead of
creating the wrap file manually and using the cmake module.
This provides better integration with meson, such as the
`force_fallback_for` built-in option.

This is also needed because the upstream CMakeLists.txt is
out of date, failing with a sufficiently new cmake version:

    CMake Error at CMakeLists.txt:2 (cmake_minimum_required):
    Compatibility with CMake < 3.5 has been removed from CMake.

The above is nonetheless addressed by https://github.com/yaml/libyaml/pull/314,
but the project seems a bit inactive at the moment.

The wrap file was added using `meson wrap install libyaml`,
and it can be updated using `meson wrap update libyaml`.

`default_library=static` is used to match the behaviour of the
previously used cmake build. `werror=false` needs to be set
because libyaml does not compile without warnings, and that
would abort the build process otherwise.

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>
2025-06-26 14:01:19 +02:00
Kieran Bingham
5f4d2ac935 libcamera: controls: Revert incorrect SPDX removal
In commit 6a09deaf7d ("controls: Add FrameWallClock control") the
existing SPDX was accidentally removed, likely from a rebase operation
at some point.

Unfortunately as this patch had already collected Reviewed-by tags, the
surruptious removal wasn't noticed until after it was merged.

Re-insert the existing SPDX and copyright banner as the header to the
control definitions file.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-26 12:59:03 +01:00
Stefan Klug
0dfb052fbd libcamera: base: Fix log level parsing when multiple categories are
listed

For a list of log levels like LIBCAMERA_LOG_LEVELS="CatA:0,CatB:1" only
the severity of the last entry is correctly parsed.

Due to the change of level to a string_view in 24c2caa1c1 ("libcamera:
base: log: Use `std::string_view` to avoid some copies") the level is no
longer necessarily null terminated as it is a view on the original data.

Replace the check for a terminating null by a check for the end position
to fix the issue.

Fixes: 24c2caa1c1 ("libcamera: base: log: Use `std::string_view` to avoid some copies")
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>
2025-06-23 16:40:43 +02:00
Stefan Klug
8ea3ef083f libcamera: test: Add a failing test for the log level parser
Log level parsing doesn't always work as expected.  Add a failing test
for that.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-23 16:39:47 +02:00
Laurent Pinchart
c19047dfdf gstreamer: Use std::exchange() instead of g_steal_pointer()
g_steal_pointer) only preserves the type since glib 2.68, requiring
casts. Use std::exchange() instead.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2025-06-23 02:30:47 +03:00
Laurent Pinchart
02a3b436c4 ipa: rkisp1: Move Sharpness control creation to Filter algorithm
The Sharpness control is used solely by the Filter algorithm. Create it
there, to avoid exposing it to applications when the algorithm is
disabled.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-06-23 02:30:47 +03:00
David Plowman
1537da7442 pipeline: rpi: Add wallclock timestamp support
A ClockRecovery object is added for derived classes to use, and
wallclock timestamps are copied into the request metadata for
applications.

Wallclock timestamps are derived corresponding to the sensor
timestamp, and made available to the base pipeline handler class and
to IPAs, for both vc4 and pisp platforms.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-19 11:12:26 +01:00
David Plowman
1d1ba78b45 controls: Add camera synchronisation controls for Raspberry Pi
New controls are added to control the camera "sync" algorithm, which
allows different cameras to synchronise their frames. For the time
being, the controls are Raspberry Pi specific, though this is expected
to change in future.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-19 11:12:26 +01:00
David Plowman
2a4e347dfe libcamera: Add ClockRecovery class to generate wallclock timestamps
The ClockRecovery class takes pairs of timestamps from two different
clocks, and models the second ("output") clock from the first ("input")
clock.

We can use it, in particular, to get a good wallclock estimate for a
frame's SensorTimestamp.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-19 11:12:26 +01:00
David Plowman
6a09deaf7d controls: Add FrameWallClock control
Add a FrameWallClock control that reports the same moment as the
frame's SensorTimestamp, but in wallclock units.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-19 11:12:26 +01:00
Hou Qi
4a277906a4 gstreamer: Fix libcamerasrc responding latency before setting caps
Whenever a downstream element queries latency, libcamerasrc will always reply,
even though it has not yet determined the latency.

However some downstream elements (e.g. glvideomixer/aggregator) will query the
latency before libcamerasrc sets the caps. When these elements get the latency,
they will start the caps negotiation. Since libcamerasrc has not yet determined
caps, invalid negotiation is performed and workflow is disrupted.

So, set latency to 'GST_CLOCK_TIME_NONE' during initialization, and reply to the
query after libcamerasrc confirms the latency. At this time, libcamerasrc has also
completed caps negotiation and downstream elements work fine.

In addition, every time the src pad task stops, we reset the latency to
GST_CLOCK_TIME_NONE to ensure that when next time task starts, the downstream
elements can generate out buffers after receiving the effective latency.

Signed-off-by: Hou Qi <qi.hou@nxp.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-19 01:50:38 +01:00
Barnabás Pőcze
b4c92a61bf ipa: rpi: Initialize enum controls with a list of values
This is how uvcvideo and rkisp1 do it. See ee918b370a
("ipa: rkisp1: agc: Initialize enum controls with a list of values")
for the motivation. In summary, having a list of values is used as a sign
that the control is an enum in multiple places (e.g. `cam`, `camshark`).

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-06-17 10:59:12 +02:00
Laurent Pinchart
b3ff75d758 gstreamer: Replace NULL with nullptr
Usage of NULL has slowly crept in the libcamerasrc sources. Replace it
with nullptr.

Reported-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
2025-06-17 01:01:31 +03:00
Laurent Pinchart
a8f90517e0 gstreamer: Drop incorrect unref on caps
The caps object passeed to the gst_libcamera_create_video_pool()
function is managed as a g_autoptr() in the caller. The function doesn't
acquire any new reference, so it shouldn't call gst_caps_unref(). Fix
it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
2025-06-17 01:01:29 +03:00
Laurent Pinchart
772b06bd8c gstreamer: Fix leak of GstQuery and GstBufferPool in error path
The gst_libcamera_create_video_pool() function leaks a GstQuery instance
and a GstBufferPool instance in an error path. Fix the leaks with
g_autoptr().

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2025-06-17 01:01:26 +03:00
Laurent Pinchart
f7c4fcd301 gstreamer: Rename variable in gst_libcamera_create_video_pool()
Now that the code is isolated in a function, the video_pool variable in
gst_libcamera_create_video_pool() can be renamed to pool without
clashing with another local variable. Do so to reduce line length.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
2025-06-17 01:01:23 +03:00
Laurent Pinchart
613202b809 gstreamer: Reduce indentation in gst_libcamera_create_video_pool()
Now that video pool creation is handled by a dedicated function, the
logic can be simplified by returning early instead of nesting scopes. Do
so to decrease indentation and improve readability, and document the
implementation of the function with comments.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
2025-06-17 01:01:20 +03:00
Laurent Pinchart
3b68207789 gstreamer: Factor out video pool creation
The gst_libcamera_src_negotiate() function uses 5 indentation levels,
causing long lines. Move video pool creation to a separate function to
increase readability.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
2025-06-17 01:01:17 +03:00
Laurent Pinchart
04e7823eb2 gstreamer: Document improvements when updating minimum GStreamer version
A const_cast<> was recently added to fix a compilation issue with older
GStreamer versions. Add a comment to indicate it can be removed when
bumping the minimum GStreamer version requirement. While at it, also
document a possible future improvement in the same function, and wrap
long lines.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
2025-06-17 01:01:14 +03:00
Antoine Bouyer
d3f3b95b64 pipeline: imx8-isi: Dynamically compute crossbar subdevice's first source.
So far, imx8-isi pipeline supports _symetrical_ crossbar, with same
amount of sink and source pads.

But for some other imx SoCs, such as i.MX8QM or i.MX95, crossbar is not
symetric anymore.

Since each crossbar source is already captured as a pipes_ vector entry,
we use pipes_ vector's size to compute 1st source index.

  "1st source index" = "total number of crossbar pads" - pipes_.count()

Signed-off-by: Antoine Bouyer <antoine.bouyer@nxp.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-06-17 00:44:05 +03:00
Antoine Bouyer
5621ac27a2 pipeline: imx8-isi: Fix match returned value in error case
The match() function returns a boolean type, while it could return int
in case of error when opening the capture file.

Fixes: 0ec982d210 ("libcamera: pipeline: Add IMX8 ISI pipeline")
Signed-off-by: Antoine Bouyer <antoine.bouyer@nxp.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>
2025-06-17 00:19:54 +03:00
Antoine Bouyer
5c8de8a08e pipeline: imx8-isi: Cosmetic changes
Change indentation to pass checkstyle script.

Fixes: 680cde6005 ("libcamera: imx8-isi: Split Bayer/YUV config generation")
Signed-off-by: Antoine Bouyer <antoine.bouyer@nxp.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-06-17 00:19:53 +03:00
Barnabás Pőcze
b544ce1c19 apps: common: image: Fix assertion
`plane` must be strictly less than the vector's size,
it cannot be equal to it.

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-06-16 10:57:54 +02:00
Naushir Patuck
8d2cd0b5b8 ipa: rpi: Rename dropFrameCount_ to invalidCount_
Rename dropFrameCount_ to invalidCount_ to better reflect its use as
frames are no longer dropped by the pipeline handler.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-12 17:26:55 +01:00
Naushir Patuck
a402f9ebc1 pipeline: rpi: Remove ispOutputCount_ and ispOutputTotal_
With the drop frame logic removed from the pipeline handler, these
member variables and not used, so remove them.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-12 17:26:55 +01:00
Naushir Patuck
98d144fef3 pipeline: rpi: Remove disable_startup_frame_drops config option
With the previous change to not drop frames in the pipeline handler,
the "disable_startup_frame_drops" pipeline config option is not used.
Remove it, and throw a warning if the option is present in the YAML
config file.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-12 17:26:55 +01:00
Naushir Patuck
6cf9c4d34f pipeline: ipa: rpi: Split RPiCameraData::dropFrameCount_
Split the pipeline handler drop frame tracking into startup frames and
invalid frames, as reported by the IPA.

Remove the drop buffer handling logic in the pipeline handler. Now all
image buffers are returned out with the appropriate FrameStatus set
for startup or invalid frames.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-12 17:26:54 +01:00
Naushir Patuck
b114c155a7 ipa: rpi: Replace dropFrameCount in the IPA -> PH interface
Replace the dropFrameCount parameter returned from ipa::start() to the
pipeline handler by startupFrameCount and invalidFrameCount. The former
counts the number of frames required for AWB/AGC to converge, and the
latter counts the number of invalid frames produced by the sensor when
starting up.

In the pipeline handler, use the sum of these 2 values to replicate the
existing dropFrameCount behaviour.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-12 17:26:54 +01:00
Naushir Patuck
c50eb1f04a libcamera: framebuffer: Add FrameMetadata::Status::FrameStartup
Add a new status enum, FrameStartup, used to denote that even though
the frame has been successfully captured, the IQ parameters set by the
IPA will cause the frame to be unusable and applications are advised to
not consume this frame. An example of this would be on a cold-start of
the 3A algorithms, and there will be large oscillations to converge to
a stable state quickly.

Additional, update the definition of the FrameError state to cover the
usage when the sensor is known to produce a number of invalid/error
frames after stream-on.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-12 17:26:54 +01:00
Barnabás Pőcze
8d168f3348 libcamera: process: Ensure that file descriptors are nonnegative
Return `-EINVAL` from `Process::start()` if any of the file descriptors
are negative as those most likely signal some kind of issue such as
missed error checking.

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-06-09 15:26:11 +02:00
Barnabás Pőcze
fae2b506d7 libcamera: process: Return error if already running
Returning 0 when a running process is already managed can be confusing
since the parameters might be completely different, causing the caller
to mistakenly assume that the program it specified has been started.

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-06-09 15:25:59 +02:00
Barnabás Pőcze
0a591eaf8c libcamera: process: Misc. cleanup around execv()
Firstly, get the number of arguments first, and use that to determine the
size of the allocation instead of retrieving it twice.

Secondly, use `const_cast` instead of a C-style cast when calling `execv()`.

Third, use `size_t` to match the type of `args.size()`.

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-06-09 15:25:22 +02:00
Barnabás Pőcze
081554db34 libcamera: process: Disable copy/move
A `Process` object has address identity because a pointer to it is
stored inside the `ProcessManager`. However, copy/move special
methods are still generated by the compiler. So disable them to
avoid potential issues and confusion.

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-06-09 15:25:18 +02:00
Barnabás Pőcze
633063e099 android: camera_device: Do not pass nullptr to Request::addBuffer()
The default argument already takes care of passing no fence to
`addBuffer()`, so there is no reason to specify `nullptr` explicitly.

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>
2025-06-04 09:31:23 +02:00
Kieran Bingham
290d3f82e3 libcamera v0.5.1
The abi-compliance checker reports 100% compatibility in this release.
As such the SONAME is maintained at 0.5.

 Binary compatibility: 100%
 Source compatibility: 100%
 Total binary compatibility problems: 0, warnings: 0
 Total source compatibility problems: 0, warnings: 0

This release brings 93 commits with a large proportion of fixes and
cleanup againt earlier releases. Improvements have been made to the
Raspberry Pi Camera Tuning Tools, and the geometry, matrix and vector
class helpers have been expanded for greater reuse throughout the
project.

Notably for packagers - IPA modules now have their own subdirectory
which should prevent undesirable surrupticious error messages that would
occur if packagers choose to install the V4L2 adaptation layer in the
same folder as the IPA modules.

The RKISP1 can now adapt to more complex input pipelines, including
FPGAs and multiplexors, which has been beneficial for users on the
i.MX8MP, and the IPA algorithms for i.MX8MP and RKISP1 continue to get
improvements.

The software ISP has a new Saturation control (available when the CCM is
enabled).

The Documentation and pipeline handler writers guide has been
re-reviewed and cleaned up.

On the application and test side, lc-compliance now includes
multi-stream tests, and cam has extended support for display formats and
now prevents issues on non-display GPUs when rendering direct to DRM.

Contributors:

    36  Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
    15  Stefan Klug <stefan.klug@ideasonboard.com>
     5  David Plowman <david.plowman@raspberrypi.com>
     5  Kieran Bingham <kieran.bingham@ideasonboard.com>
     5  Laurent Pinchart <laurent.pinchart@ideasonboard.com>
     4  Milan Zamazal <mzamazal@redhat.com>
     4  Quentin Schulz <quentin.schulz@cherry.de>
     3  Daniel Scally <dan.scally@ideasonboard.com>
     3  Paul Elder <paul.elder@ideasonboard.com>
     2  Hou Qi <qi.hou@nxp.com>
     2  Julien Vuillaumier <julien.vuillaumier@nxp.com>
     2  Naushir Patuck <naush@raspberrypi.com>
     2  Niklas Söderlund <niklas.soderlund@ragnatech.se>
     2  Pavel Machek <pavel@ucw.cz>
     1  Benjamin Mugnier <benjamin.mugnier@foss.st.com>
     1  Nícolas F. R. A. Prado <nfraprado@collabora.com>
     1  Sven Püschel <s.pueschel@pengutronix.de>

 108 files changed, 3359 insertions(+), 528 deletions(-)

Integration overview:

The following commits in this release relate to either a bug fix or an
improvement to an existing commit.

 - meson: Do not automatically build documentation if sphinx-build-3 is found
   - Fixes: aba567338b ("Documentation: Move all dependencies into features")
 - Revert "libcamera: rkisp1: Eliminate hard-coded resizer limits"
   - Fixes: 761545407c ("pipeline: rkisp1: Filter out sensor sizes not supported by the pipeline")
 - pipeline: rkisp1: Fix vblank delay
   - Fixes: f72c76eb6e ("rkisp1: Honor the FrameDurationLimits control")
 - utils: raspberrypi: ctt: Fix NaNs in lens shading tables
   - Bug: https://github.com/raspberrypi/libcamera/issues/254
 - utils: raspberrypi: ctt: Fix NaNs in chromatic aberration tables
   - Bug: https://github.com/raspberrypi/libcamera/issues/254
 - utils: raspberrypi: ctt: Fix integer division error calculating LSC cell size
   - Bug: https://github.com/raspberrypi/libcamera/issues/260
 - apps: qcam: Push the viewfinder role to vector
   - Fixes: ee2b011b65 ("apps: cam: Try raw role if default viewfinder role fails")
 - ipa: Move IPA installations to a subdir
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=268
 - ipa: rkisp1: algorithms: awb: Fix wrong colour temperature reporting
   - Fixes: b60bd37b1a ("ipa: rkisp1: Move calculation of RGB means into own function")
 - ipa: rkisp1: ccm/lsc: Fix CCM/LSC based on manual color temperature
   - Fixes: 0230880954 ("ipa: rkisp1: awb: Implement ColourTemperature control")
 - libcamera: controls: Fix `ControlInfoMap::count(unsigned int)`
   - Fixes: 76b9923e55 ("libcamera: controls: Avoid exception in ControlInfoMap count() and find()")
 - apps: cam: capture_script: Disallow arrays of strings
   - Fixes: b35f04b3c1 ("cam: capture_script: Support parsing array controls")
 - libcamera: matrix: Fix compilation error in inverse() function
   - Fixes: 6287ceff5a ("libcamera: matrix: Add inverse() function")
 - ipa: rpi: controller: rpi: Fix colour gain typo in AGC
   - Fixes: 29892f1c56 ("ipa: libipa: colour: Use the RGB class to model RGB values")

And the following updates have been made in this release, grouped by category:

core:
 - meson: Make the default value of "documentation" feature explicit
 - meson: Do not automatically build documentation if sphinx-build-3 is found
 - libcamera: request: Avoid double map lookup
 - utils: rkisp1: gen-csc-table: Support printing CCM in decimal
 - libcamera: ipa_module: Avoid unnecessary copy when getting signature
 - libcamera: controls: Disallow arrays of arrays
 - libcamera: media_device: Add helper to return matching entities
 - libcamera: internal: Add MediaPipeline helper
 - libcamera: stream: Add color space to configuration string representation
 - README.rst: remove unnecessary dependency for qcam
 - libcamera: v4l2_videodevice: Log buffer count on allocation error
 - libcamera: matrix: Replace SFINAE with static_asserts
 - libcamera: matrix: Make most functions constexpr
 - libcamera: matrix: Add a Span based constructor
 - libcamera: vector: Add a Span based constructor
 - libcamera: matrix: Add inverse() function
 - libcamera: matrix: Extend multiplication operator to heterogenous types
 - libcamera: vector: Extend matrix multiplication operator to heterogenous types
 - libcamera: controls: Fix `ControlInfoMap::count(unsigned int)`
 - utils: codegen: Make users depend on `controls.py` in meson
 - libcamera: matrix: Fix compilation error in inverse() function
 - libcamera: sensor: Fix the gain delay for IMX283
 - treewide: Do not use `*NameValueMap` for known values
 - utils: codegen: ipc: Use `any()` instead of `len([]) > 0`
 - utils: codegen: ipc: Remove `namespace` argument
 - utils: codegen: ipc: Add `deserializer()` function
 - utils: codegen: ipc: Log error code when remote call fails
 - utils: codegen: ipc: Simplify `return` statements
 - libcamera: ipa_data_serializer: Remove some vector `reserve()` calls
 - libcamera: mali-c55: Remove tpgCodes_
 - libcamera: mali-c55: Remove tpgSizes_ member from MaliC55CameraData
 - libcamera: process: Use _exit in child process
 - libcamera: process: Pass stderr and reserve stdin and stdout fds
 - guides: pipeline-handler: Update name of pipeline handler stop function
 - libcamera: mali-c55: Fix error paths in ::init()

pipeline:
 - libcamera: software_isp: Add a clarification comment to AWB
 - libcamera: pipeline: uvcvideo: Expose `Gamma` control
 - libcamera: software_isp: Fix CCM multiplication
 - libcamera: pipeline: virtual: Fix typo in log message
 - libcamera: pipeline: imx8-isi: Remove unused variable
 - pipeline: rkisp1: Fix vblank delay
 - libcamera: pipeline: rkisp1: Convert to use MediaPipeline
 - libcamera: pipeline: uvcvideo: Report new AeEnable control as available
 - ipu3: cio2: Remove unused function definition
 - libcamera: software_isp: Add saturation control
 - Revert "libcamera: rkisp1: Eliminate hard-coded resizer limits"

apps:
 - apps: lc-compliance: Support multiple streams in helpers
 - apps: lc-compliance: Add multi-stream tests
 - apps: cam: capture_script: Simplify bool array parsing
 - gstreamer: Fixate colorimetry field during caps negotiation
 - apps: cam: Try raw role if default viewfinder role fails
 - apps: qcam: Push the viewfinder role to vector
 - py: Set `PYTHONPATH` in devenv
 - apps: cam: sdl_texture: Take list of buffers in span
 - apps: cam: sdl_texture: Drop `&rect_` from `SDL_Update{NV,}Texture()` call
 - apps: cam: sdl_texture: Add `SDLTexture1Plane`
 - apps: cam: sdl_sink: Support more single-plane formats
 - gstreamer: Add GstVideoMeta support
 - apps: cam: capture_script: Disallow arrays of strings
 - apps: cam: Skip non-display GPUs

ipa:
 - utils: ipc: Do not duplicate signals in proxy object
 - utils: ipc: Do not define variables in signal handler up front
 - ipa: rpi: common: Avoid warnings when AeEnable control is used
 - ipa: rpi: awb: Remove "fast" parameter
 - ipa: Move IPA installations to a subdir
 - ipa: rkisp1: awb: Declare ControlInfo in AWB
 - ipa: rkisp1: awb: Ignore empty AWB statistics
 - ipa: rkisp1: Refactor automatic/manual structure in IPAActiveState
 - ipa: rkisp1: algorithms: awb: Fix wrong colour temperature reporting
 - ipa: rkisp1: ccm/lsc: Fix CCM/LSC based on manual color temperature
 - ipa: rkisp1: Implement manual ColourCorrectionMatrix control
 - libipa: awb: Make result of gainsFromColourTemp optional
 - ipa: rkisp1: Damp color temperature regulation
 - ipa: rkisp1: awb: Take the CCM into account for the AWB gains calculation
 - ipa: rkisp1: awb: Avoid division by zero
 - ipa: rpi: controller: rpi: Fix colour gain typo in AGC
 - ipa: rpi: Add tuning for IMX283
 - ipa: rpi: Prevent segfault if AGC algorithm is absent

tuning:
 - utils: raspberrypi: ctt: Fix NaNs in lens shading tables
 - utils: raspberrypi: ctt: Fix NaNs in chromatic aberration tables
 - utils: raspberrypi: ctt: Fix integer division error calculating LSC cell size

documentation:
 - Documentation: guides: pipeline-handler: Fix camera creation
 - Documentation: guides: pipeline-handler: Fix property list file name
 - Documentation: guides: pipeline-handler: Fix configuration creation
 - Documentation: guides: pipeline-handler: Fix `Camera::create()` link
 - Documentation: guides: pipeline-handler: Simplify format collection
 - Documentation: guides: pipeline-handler: Query pixel formats once
 - Documentation: guides: application-developer: Remove unnecessary argument
 - Documentation: Fix `INCLUDE_PATH` doxygen configuration option
 - doc: Mention right meson version
 - doc: document libtiff dependency for cam

test:
 - test: Add minimal test for Matrix
 - lc-compliance: Move camera setup to CameraHolder class

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-01 23:57:29 +01:00
Barnabás Pőcze
a8bc540653 Documentation: Fix INCLUDE_PATH doxygen configuration option
libcamera header files should be included using the `libcamera/...` prefix.
However, `INCLUDE_PATH` is currently set to `@TOP_SRCDIR@/include/libcamera`
meaning that doxygen, when encountering `libcamera/x.h`, will try to open
`@TOP_SRCDIR@/include/libcamera/libcamera/x.h`, which is not the correct
path.

Fix that by using `@TOP_{BUILD,SRC}DIR@/include`. This removes the extra
`libcamera` component from the path and adds the corresponding directory
from the build directory as well since that is an implicit include
directory added by meson.

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>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-01 23:11:54 +01:00
Milan Zamazal
59ac34b728 libcamera: software_isp: Add saturation control
Saturation control is added on top of the colour correction matrix.  A
method of saturation adjustment that can be fully integrated into the
colour correction matrix is used.  The control is available only if Ccm
algorithm is enabled.

The control uses 0.0-2.0 value range, with 1.0 being unmodified
saturation, 0.0 full desaturation and 2.0 quite saturated.

The saturation is adjusted by converting to Y'CbCr colour space,
applying the saturation value on the colour axes, and converting back to
RGB.  ITU-R BT.601 conversion is used to convert between the colour
spaces, for no particular reason.

The colour correction matrix is applied before gamma and the given
matrix is suitable for such a case.  Alternatively, the transformation
used in libcamera rpi ccm.cpp could be used.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-01 23:08:01 +01:00
Daniel Scally
e342f050c2 libcamera: mali-c55: Fix error paths in ::init()
In the MaliC55CameraData::init() function there are two places that
return values they shouldn't; the ret variable is returned after
checking a pointer is not null instead of an explicit -ENODEV and later
the boolean value false is returned on failure instead of the error
value returned by V4L2Subdevice::open() - fix both problems.

Signed-off-by: Daniel Scally <dan.scally@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-06-01 22:53:47 +01:00
Niklas Söderlund
fabee6055f guides: pipeline-handler: Update name of pipeline handler stop function
Since commit f6b6f15b54 ("libcamera: pipeline: Introduce
stopDevice()") the stop function needed to be implemented by pipeline
handlers was renamed to stopDevice().

Update the pipeline handler writers guide to match this.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jai Luthra <jai.luthra@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-01 22:41:32 +01:00
Niklas Söderlund
4b5856533a ipu3: cio2: Remove unused function definition
The private function cio2BufferReady is defined but not implemented or
used, remove it for the class definition.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-06-01 22:30:49 +01:00
Milan Zamazal
663ab2ee8e apps: cam: Skip non-display GPUs
Device::openCard() in the cam DRM helpers looks for a /dev/dri/card*
device that can be opened and that doesn't fail when asked about
DRM_CAP_DUMB_BUFFER capability (regardless whether the capability is
supported by the device).

There can be matching devices that are not display devices.  This can
lead to selection of such a device and inability to use KMS output with
the `cam' application.  The ultimate goal is to display something on the
device and later the KMS sink will fail if there is no connector
attached to the device (although it can actually fail earlier, when
trying to set DRM_CLIENT_CAP_ATOMIC capability if this is not
supported).

Let's avoid selecting devices without connectors, CRTCs or encoders.
The added check makes the original check for DRM_CAP_DUMB_BUFFER API
most likely unnecessary, let's remove it.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Mattijs Korpershoek <mkorpershoek@kernel.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-05-30 12:26:53 +03:00
Benjamin Mugnier
1ee330c058 ipa: rpi: Prevent segfault if AGC algorithm is absent
Even without AGC definition in the tuning file, the application would
still dereference agc unconditionally, leading to a segmentation fault
if AGC is absent.
This is relevant for sensors already providing AGC/AEC by themselves.
Check if AGC is present prior to setting maximum exposure time.

Signed-off-by: Benjamin Mugnier <benjamin.mugnier@foss.st.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> # RPi4 + imx708_wide
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-29 15:00:09 +01:00
Julien Vuillaumier
5b7c83d8cc libcamera: process: Pass stderr and reserve stdin and stdout fds
When a child process is started from Process::start(), the file
descriptors inherited from the parent process are closed, except
the ones explicitly listed in the fds[] argument.

One issue is that the file descriptors for stdin, stdout and stderr
being closed, the subsequent file descriptors created by the child
process will reuse the values 0, 1 and 2 that are now available.
Thus, usage of printf(), assert() or alike may direct its output
to the new resource bound to one of these reused file descriptors.
The other issue is that the child process can no longer log on
the console because stderr has been closed.

To address the 2 issues, Process:start() is amended as below:
- Child process inherits from parent's stderr fd in order to share
the same logging descriptor
- Child process stdin, stdout and stderr fds are bound to /dev/null
if not inherited from parent. That is to prevent those descriptors
to be reused for any other resource, that could be corrupted by
the presence of printf(), assert() or alike.

Signed-off-by: Julien Vuillaumier <julien.vuillaumier@nxp.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-29 12:30:12 +01:00
Julien Vuillaumier
32905fdd0b libcamera: process: Use _exit in child process
Use _exit() in child process in case of execv() error. That is to
avoid interfering with the parent process as exit() may call its
atexit() handlers and flush its io buffers.

Signed-off-by: Julien Vuillaumier <julien.vuillaumier@nxp.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-29 12:30:12 +01:00
Daniel Scally
f58077f073 libcamera: mali-c55: Remove tpgSizes_ member from MaliC55CameraData
The tpgSizes_ vector is only used within the initTPGData() function.
Drop it and use a local variable instead.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-05-29 11:56:23 +01:00
Daniel Scally
b55943714f libcamera: mali-c55: Remove tpgCodes_
MaliC55CameraData stores a vector of the TPG's mbus codes (if the
camera in question is a TPG). This is never used - remove it.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-05-29 11:56:23 +01:00
Barnabás Pőcze
4709f8442b libcamera: ipa_data_serializer: Remove some vector reserve() calls
`appendPOD()` does a single insertion, so if only a single `appendPOD()`
will be called on a vector before returning, then calling `reserve()`
is not that useful, so remove it.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-05-27 11:10:23 +02:00
Barnabás Pőcze
e633d85be9 utils: codegen: ipc: Simplify return statements
Returning an expression of type `void` from a function returning `void`
is legal, so do not handle those cases specially.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-05-27 11:10:23 +02:00
Barnabás Pőcze
4adefc100d utils: codegen: ipc: Log error code when remote call fails
The error code can be useful in diagnosing the underlying issue,
so log that as well, not just the existence of the issue.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-05-27 11:10:23 +02:00
Barnabás Pőcze
d58ccabab7 utils: codegen: ipc: Add deserializer() function
Add `deserializer()` in `serializer.tmpl` to have a single function
that generates all the necessary functions into the template specialization
like `serializer()`. This also avoids the duplication of some
conditional logic.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-05-27 11:10:23 +02:00
Barnabás Pőcze
0a1539a4f1 utils: codegen: ipc: Remove namespace argument
The `serializer()`, `deserializer_{fd,no_fd,simple}()` functions
take a string argument named "namespace", but they do not use it.
So remove the argument.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-05-27 11:10:23 +02:00
Barnabás Pőcze
d4ef160b1a utils: codegen: ipc: Use any() instead of len([]) > 0
Use `any()` with a generator expression instead of constructing
a list and checking its length.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-05-27 11:10:23 +02:00
Barnabás Pőcze
eecb270085 treewide: Do not use *NameValueMap for known values
When the value is known, do not look it up via the control's `NameValueMap`,
instead, just refer to the value directly.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-05-27 09:42:46 +02:00
Naushir Patuck
aca8b701ac libcamera: sensor: Fix the gain delay for IMX283
The IMX283 uses a gain delay of 1 instead of the current value of 2 as
defined in the sensor properties. Fix it.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-23 11:52:31 +01:00
Naushir Patuck
eb9bb35d80 ipa: rpi: Add tuning for IMX283
Add calibrated tuning for the IMX283 sensor for pisp. Update the vc4
tuning file to match the new calibration.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Paul Elder <paul.elder@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-23 11:49:20 +01:00
David Plowman
ad5326c926 ipa: rpi: controller: rpi: Fix colour gain typo in AGC
A simple typo crept in where the red gain had been re-typed rather
than using the correct green gain. In particular, this was causing
very dark images for sensors that use large red gains, such as the
IMX477 outdoors.

Fixes: 29892f1c56 ("ipa: libipa: colour: Use the RGB class to model RGB values")
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Tested-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-05-23 09:44:57 +02:00
Laurent Pinchart
516f365670 libcamera: matrix: Fix compilation error in inverse() function
Some gcc versions report uninitialized variable usage:

In member function ‘constexpr T& libcamera::Span<T, 4294967295>::operator[](size_type) const [with T = unsigned int]’,
    inlined from ‘void libcamera::matrixInvert(Span<const T>, Span<T, 4294967295>, unsigned int, Span<T, 4294967295>, Span<unsigned int>)::MatrixAccessor::swap(unsigned int, unsigned int) [with T = float]’ at ../../src/libcamera/matrix.cpp:194:13,
    inlined from ‘bool libcamera::matrixInvert(Span<const T>, Span<T, 4294967295>, unsigned int, Span<T, 4294967295>, Span<unsigned int>) [with T = float]’ at ../../src/libcamera/matrix.cpp:255:14:
../../include/libcamera/base/span.h:362:76: error: ‘row’ may be used uninitialized [-Werror=maybe-uninitialized]
  362 |         constexpr reference operator[](size_type idx) const { return data()[idx]; }
      |                                                                      ~~~~~~^
../../src/libcamera/matrix.cpp: In function ‘bool libcamera::matrixInvert(Span<const T>, Span<T, 4294967295>, unsigned int, Span<T, 4294967295>, Span<unsigned int>) [with T = float]’:
../../src/libcamera/matrix.cpp:232:30: note: ‘row’ was declared here
  232 |                 unsigned int row;
      |                              ^~~

This is a false positive. Fix it by initializing the variable when
declaring it.

Fixes: 6287ceff5a ("libcamera: matrix: Add inverse() function")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com>
2025-05-22 19:04:15 +02:00
Barnabás Pőcze
d997e97512 utils: codegen: Make users depend on controls.py in meson
Currently, modifying `controls.py` does not make those build targets dirty
that use a script that includes it (e.g. `gen-controls.py`) because meson
has no knowledge of this dependency. Add `depend_files` to each
`custom_target()` invocation to fix this.

Ideally it would be possible to attach this dependency to `gen_controls`,
`gen_gst_controls`, etc. objects themselves, so that repetition is
avoided, but this does not seem possible at the moment.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-22 13:16:07 +02:00
Barnabás Pőcze
702af1a1d0 apps: cam: capture_script: Disallow arrays of strings
The current `ControlValue` mechanism does not support arrays
of strings, the assignment in the removed snippet will in fact
trigger an assertion failure in `ControlValue::set()` because
`sizeof(std::string) != ControlValueSize[ControlTypeString]`.

Fixes: b35f04b3c1 ("cam: capture_script: Support parsing array controls")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-22 13:16:07 +02:00
Barnabás Pőcze
ffcecda4d5 libcamera: pipeline: uvcvideo: Report new AeEnable control as available
The `AeEnable` control is handled by the `Camera` class directly, but it
still has to be added because `ControlInfoMap`s are not easily modifiable.

See 338ba00e7a ("ipa: rkisp1: agc: Report new AeEnable control as available")
for more details and a similar change in rkisp1.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-22 12:34:54 +02:00
Barnabás Pőcze
efdbe39698 libcamera: controls: Fix ControlInfoMap::count(unsigned int)
The two overloads of `find()` and `at()` have the same behaviour
regardless of the argument type: `unsigned int` or `const ControlId *`.
However, `count()` is not so because `count(unsigned int)` only checks
the `ControlIdMap`, and it does not check if the given id is actually
present in the map storing the `ControlInfo` objects.

So `count()` returns 1 for every control id that is present in the
associated `ControlIdMap` regardless of whether there is an actual
entry for the `ControlId` associated with the given numeric id.

Fix that by simply using `find()` to determine the return value.

Fixes: 76b9923e55 ("libcamera: controls: Avoid exception in ControlInfoMap count() and find()")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-22 11:22:34 +02:00
Stefan Klug
969df3db31 ipa: rkisp1: awb: Avoid division by zero
As the gains can also be specified manually, the regulation can run into
numeric instabilities by dividing by near zero. Mitigate that by
applying a small minium value.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 11:20:08 +02:00
Stefan Klug
7991293cec ipa: rkisp1: awb: Take the CCM into account for the AWB gains calculation
The AWB measurements are taken after the CCM. This can be seen by
enabling debug logging on AWB, disabling AWB (stats will still be
processed) and manually chaning the CCM.

This means that the estimated colour temperature and the corresponding
CCM also lead to changed rgbMeans which in turn leads to oscillations.
Fix that by applying the inverse transform on the rgbMeans.

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>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 11:20:08 +02:00
Stefan Klug
71b680c863 ipa: rkisp1: Damp color temperature regulation
Damp the regulation of the color temperature with the same factor as the
gains.  Not damping the color temperature leads to visible flicker, as
the CCM changes too much.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 11:20:08 +02:00
Stefan Klug
c699d26573 libipa: awb: Make result of gainsFromColourTemp optional
In the grey world AWB case, if no colour gains are contained in the
tuning file, the colour gains get reset to 1 when the colour temperature
is set manually. This is unexpected and undesirable. Allow the
gainsFromColourTemp() function to return a std::nullopt to handle that
case.

While at it, remove an unnecessary import from rkisp1/algorithms/awb.h.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 11:20:08 +02:00
Stefan Klug
66e9604684 ipa: rkisp1: Implement manual ColourCorrectionMatrix control
Add a manual ColourCorrectionMatrix control. This was already discussed
while implementing manual colour temperature but was never implemented.
The control allows to manually specify the CCM when AwbEnable is false.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 11:20:07 +02:00
Stefan Klug
f1ac420eb1 ipa: rkisp1: ccm/lsc: Fix CCM/LSC based on manual color temperature
In RkISP1Awb::process(), the color temperature in the active state is
updated every time new statistics are available.  The CCM/LSC algorithms
use that value in prepare() to update the CCM/LSC. This is not correct
if the color temperature was specified manually and leads to visible
flicker even when AwbEnable is set to false.

To fix that, track the auto and manual color temperature separately in
active state. In Awb::prepare() the current frame context is updated
with the corresponding value from active state. Change the algorithms to
fetch the color temperature from the frame context instead of the active
state in prepare().

Fixes: 0230880954 ("ipa: rkisp1: awb: Implement ColourTemperature control")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-05-20 11:16:36 +02:00
Stefan Klug
3fcc6b06c3 ipa: rkisp1: algorithms: awb: Fix wrong colour temperature reporting
In commit b60bd37b1a ("ipa: rkisp1: Move calculation of RGB means into
own function") the output of the current measured colour temperature as
metadata was incorrectly added. Remove it.

Fixes: b60bd37b1a ("ipa: rkisp1: Move calculation of RGB means into own function")
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>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 09:59:23 +02:00
Stefan Klug
5010b65a08 ipa: rkisp1: Refactor automatic/manual structure in IPAActiveState
Swap gains and automatic/manual in the IPAActiveState structure. This is
in preparation to adding another member, which is easier in the new
structure. The patch contains no functional changes.

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>
2025-05-20 09:58:56 +02:00
Laurent Pinchart
1e67b96fb0 libcamera: vector: Extend matrix multiplication operator to heterogenous types
It is useful to multiply matrices and vectors of heterogeneous types, for
instance float and double. Extend the multiplication operator to support
this, avoiding the need to convert one of the operations. The type of the
returned vector is selected automatically to avoid loosing precision.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 09:49:09 +02:00
Laurent Pinchart
754798b664 libcamera: matrix: Extend multiplication operator to heterogenous types
It is useful to multiply matrices of heterogneous types, for instance
float and double. Extend the multiplication operator to support this,
avoiding the need to convert one of the matrices. The type of the
returned matrix is selected automatically to avoid loosing precision.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 09:49:09 +02:00
Stefan Klug
dacbcc7d77 test: Add minimal test for Matrix
Add a few tests for the Matrix class. This is not full fledged but at
least a starter.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 09:49:01 +02:00
Stefan Klug
6287ceff5a libcamera: matrix: Add inverse() function
For calculations in upcoming algorithm patches, the inverse of a matrix
is required. Add an implementation of the inverse() function for square
matrices.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 09:46:12 +02:00
Stefan Klug
bcba580546 libcamera: vector: Add a Span based constructor
When one wants to create a Vector from existing data, currently the only
way is via std::array. Add a Span based constructor to allow creation
from std::vectors and alike.

While at it, replace the manual loop with std::copy.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 09:46:12 +02:00
Stefan Klug
aca9042abd libcamera: matrix: Add a Span based constructor
When one wants to create a Matrix from existing data, currently the only
way is via std::array. Add a Span based constructor to allow creation
from vectors and alike.

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>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 09:46:11 +02:00
Stefan Klug
5234e4936f libcamera: matrix: Make most functions constexpr
By zero-initializing the data_ member we can make most functions
constexpr which will come in handy in upcoming patches. Note that this
is due to C++17. In C++20 we will be able to leave data_ uninitialized
for constexpr.  The Matrix(std::array) version of the constructor can
not be constexpr because std::copy only became constexpr in C++20.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-20 09:46:11 +02:00
Stefan Klug
1d8a6db31c libcamera: matrix: Replace SFINAE with static_asserts
SFINAE is difficult to read and not needed in these cases. Replace it
with static_asserts. The idea came from [1] where it is stated:

"The use of enable_if seems misguided to me. SFINAE is useful for the
situation where we consider multiple candidates for something (overloads
or class template specializations) and try to choose the correct one,
without causing compilation to fail."

[1]: https://stackoverflow.com/questions/62109526/c-friend-template-that-use-sfinae

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2025-05-20 09:46:11 +02:00
Stefan Klug
0069b9ceb1 ipa: rkisp1: awb: Ignore empty AWB statistics
When the AWB engine doesn't find a valid pixel because all pixels lie
outside the configured colour range it returns an AWB measurement value
of 255, 255, 255. This leaves the regulation in an unrecoverable state
noticeable by a completely green image. Fix that by skipping the AWB
calculation in case there were no valid pixels.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-19 15:35:47 +02:00
Hou Qi
848a3017b8 gstreamer: Add GstVideoMeta support
GStreamer video-info calculated stride and offset may differ from
those used by the camera.

For stride and offset mismatch, this patch adds video meta to buffer
if downstream supports VideoMeta through allocation query. Otherwise,
create a internal VideoPool using the caps, and copy video frame to
this system memory.

Signed-off-by: Hou Qi <qi.hou@nxp.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-19 09:28:19 +01:00
Barnabás Pőcze
e5442c3150 apps: cam: sdl_sink: Support more single-plane formats
With the newly introduced `SDLTexture1Plane` it is easy to handle
any single-plane format that has an SDL equivalent. So use it for
more YUV and RGB formats.

The mapping of RGB formats is not entirely straightforward because
`SDL_PIXELFORMAT_ZZZ...888...` defines a format where the order of
the components is endian dependent, while libcamera's `ZZZ...888...`
formats are derived from the matching DRM formats, and the RGB formats
in question are defined to be little-endian there. So the
endian-independent `SDL_PIXELFORMAT_{ZZZ24,ZZZZ32}` are used.

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-05-15 17:41:36 +02:00
Barnabás Pőcze
b24cd12293 apps: cam: sdl_texture: Add SDLTexture1Plane
`SDLTextureYUYV` uses `SDL_PIXELFORMAT_YUY2`, which is a single plane
format. To support other single plane formats, replace `SDLTextureYUYV`
with `SDLTexture1Plane` that can be instantiated with an arbitrary SDL
pixel format and that uses `SDL_UpdateTexture()` to update the texture
using exactly a single plane.

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-05-15 17:41:36 +02:00
Barnabás Pőcze
41b0997114 apps: cam: sdl_texture: Drop &rect_ from SDL_Update{NV,}Texture() call
If the entire texture is to be updated, there is no need to specify
the target area explicitly.

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-05-15 17:41:36 +02:00
Barnabás Pőcze
02f60006cf apps: cam: sdl_texture: Take list of buffers in span
A non-owning span is sufficient, so use that instead of a vector.

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>
2025-05-15 17:41:36 +02:00
Nícolas F. R. A. Prado
f3a12332f6 lc-compliance: Move camera setup to CameraHolder class
Different base classes can be used for different setups on tests, but
all of them will need to setup the camera for the test. To reuse that
code, move it to a separate CameraHolder class that is inherited by test
classes.

Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
2025-05-13 20:17:19 +02:00
Paul Elder
d01342f1dc ipa: rkisp1: awb: Declare ControlInfo in AWB
The ControlInfo information for AwbEnable and ColourGains are declared
and exposed in the top-level IPA. These should instead be exposed by the
AWB part of the IPA, as it doesn't make sense to support these controls
when AWB is disabled, for example.

Move the declaration of these controls out of the top-level IPA and into
AWB.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-05-13 11:57:24 +02:00
Kieran Bingham
37dccb4584 ipa: Move IPA installations to a subdir
IPAs are expected to live within a directory that is searched by the
IPAManager.  If other non-IPA so files are installed in the same
location, then the user may be presented with an error message reporting
that the module could not be parsed.

Move IPA modules to an ipa specific subdirectory to ensure we only parse
.so files that are expected to be IPA modules at load time.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=268
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
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>
2025-05-12 16:13:06 +02:00
Barnabás Pőcze
54aeb0447c py: Set PYTHONPATH in devenv
If the python bindings are built, then set the `PYTHONPATH` environmental
variable in the meson devenv accordingly to make it easy to use.

  $ meson devenv -C build
  [libcamera] $ echo $PYTHONPATH
  /libcamera/build/src/py
  [libcamera] $ python
  Python 3.13.3 (main, Apr  9 2025, 07:44:25) [GCC 14.2.1 20250207] on linux
  Type "help", "copyright", "credits" or "license" for more information.
  >>> import libcamera
  >>> cm = libcamera.CameraManager.singleton()
  [...]
  [129:52:33.293860558] [4133380]  INFO Camera camera_manager.cpp:326 libcamera v0.5.0+169-7dbe74b5-dirty (2025-05-01)
  [...]

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-12 09:21:14 +02:00
Sven Püschel
fabfdd8559 libcamera: v4l2_videodevice: Log buffer count on allocation error
Log the actual and requested buffers count in case of a V4L2 buffers
allocation error, when the requested buffers count could not be
allocated.

Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
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>
2025-05-09 15:39:17 +02:00
Kieran Bingham
a799415017 apps: qcam: Push the viewfinder role to vector
In commit ee2b011b65 ("apps: cam: Try raw role if default viewfinder
role fails"), the viewfinder role is specified as the default if no role
is yet chosen.

This was unfortunately added by directly accessing the vector rather
than extending the size when the vector is empty. Fix the code to push
the default viewfinder role on to the back of the vector, increasing the
size appropriately.

Fixes: ee2b011b65 ("apps: cam: Try raw role if default viewfinder role fails")
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-08 10:51:11 +02:00
David Plowman
e0405b171e utils: raspberrypi: ctt: Fix integer division error calculating LSC cell size
The cell sizes must be cast to integers as the parameters that
were passed in may be floats.

Bug: https://github.com/raspberrypi/libcamera/issues/260
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Fixes: 36ba0e5515 ("utils: raspberrypi: ctt: Fix NaNs in lens shading tables")
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-08 10:51:10 +02:00
Barnabás Pőcze
2f62701e9e Documentation: guides: application-developer: Remove unnecessary argument
`required: true` is the default for meson's `dependency()` function.

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>
2025-05-05 09:20:39 +02:00
Barnabás Pőcze
1200775986 Documentation: guides: pipeline-handler: Query pixel formats once
There is no reason to create an entire new copy of the same thing,
so use the already existing `formats` object.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-02 17:25:30 +02:00
Barnabás Pőcze
b03992e66f Documentation: guides: pipeline-handler: Simplify format collection
I believe a simple range based for loop is easier to understand
here than `std::transform()`. Furthermore, using a for loop enables
the easy filtering of invalid pixel formats.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-02 17:25:30 +02:00
Barnabás Pőcze
f83bab529c Documentation: guides: pipeline-handler: Fix Camera::create() link
Since 6b4771d460 ("libcamera: camera: Hide Camera::create() from the public API")
`Camera::create()` is documented in the internal documentation.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-02 17:25:30 +02:00
Barnabás Pőcze
28d2d4f43c Documentation: guides: pipeline-handler: Fix configuration creation
`PipelineHandler::generateConfiguration()` returns a `std::unique_ptr`.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-02 17:25:30 +02:00
Barnabás Pőcze
dd2ddea8bf Documentation: guides: pipeline-handler: Fix property list file name
It is `property_ids_core.yaml`.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-02 17:25:30 +02:00
Barnabás Pőcze
8e10804413 Documentation: guides: pipeline-handler: Fix camera creation
1. The unique_ptr containing the private data must be passed to
`Camera::create()`.

2. `registerCamera()` needs only the pointer to the `Camera`

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-02 17:25:30 +02:00
Quentin Schulz
ab508f2b55 README.rst: remove unnecessary dependency for qcam
The introducing commit (dff416a84b ("README: Add missing package for
Qt5 tools"); for Qt 5 originally) stated that without the dependency we
would get the following messages:

	Program /usr/lib/x86_64-linux-gnu/qt5/bin/lrelease found: NO
	Program lrelease-qt5 found: NO
	Program lrelease found: NO found  but need: '== 5.14.2'

That was the case for qt5 and is still true for qt6 but this actually
is neither breaking the build nor is it doing anything to the outcome
of the build (for both qt5 and qt6) as qcam is bit to bit identical
with and without that package.

Therefore, let's not mislead users to install an unnecessary package.

Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-01 16:48:48 +01:00
Barnabás Pőcze
92ed6140ee ipa: rpi: awb: Remove "fast" parameter
The "fast" parameter has not been used since it first appeared in the
source code. And not only is it not used, but its retrieval from
the configuration since c1597f9896 ("ipa: raspberrypi: Use YamlParser
to replace dependency on boost") has been incorrect. So remove it.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
2025-04-30 14:36:06 +02:00
David Plowman
e4677362a1 ipa: rpi: common: Avoid warnings when AeEnable control is used
The AeEnable control is now just a wrapper that is converted to
ExposureTimeMode and AnalogueGainMode controls instead. Therefore, it
should simply be ignored when we encounter it, without the need for
any warnings.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-29 16:14:49 +01:00
David Plowman
17e41b2a3a utils: raspberrypi: ctt: Fix NaNs in chromatic aberration tables
NaNs can appear if no black dots can be found and analysed in a
particular region of the calibration image. There needs to be at least
one such dot in every 8x8 cell covering the image.

This is now detected, and an error message issued. No CAC tables are
generated, so CAC is disabled.

Bug: https://github.com/raspberrypi/libcamera/issues/254
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-29 16:14:48 +01:00
David Plowman
36ba0e5515 utils: raspberrypi: ctt: Fix NaNs in lens shading tables
The problem occurs when the calculation could lead to a final row (or
column) of grid squares with no pixels in them (and hence, NaNs).

One specific case is a Pi 5 with an image width (or height) of 1364,
so that's 682 Bayer quads. To give 32 grid squares it was calculating
22 quads per cell. However, 31 * 22 = 682 leaving nothing in the final
column.

The fix is to do a rounding-down division by the number of cells minus
one, rather than a rounding-up division by the number of cells. This
turns the corner case from one where the final row/column has no
pixels to one where we don't quite cover the full image, which is how
we have to handle these cases.

Bug: https://github.com/raspberrypi/libcamera/issues/254
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-29 16:14:48 +01:00
Laurent Pinchart
9b50d3c23d libcamera: stream: Add color space to configuration string representation
Extend the string representation of StreamConfiguration, as returned by
the toString() and operator<<() functions, with color space information.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2025-04-29 17:32:19 +03:00
Kieran Bingham
8751369c5b libcamera: pipeline: rkisp1: Convert to use MediaPipeline
Use the new MediaPipeline to manage and identify all sensors connected
to complex pipelines that can connect to the CSI2 receiver before the
ISP.

This can include chained multiplexors that supply multiple cameras, so
make use of the MediaDevice::locateEntities to search for all cameras
and construct a pipeline for each.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Acked-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-04-29 02:45:21 +09:00
Kieran Bingham
f1721c2f9f libcamera: internal: Add MediaPipeline helper
Provide a MediaPipeline class to help identifing and managing pipelines across
a MediaDevice graph.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-04-29 02:45:21 +09:00
Kieran Bingham
0785f5f99a libcamera: media_device: Add helper to return matching entities
Provide a helper on the MediaDevice to return a list of all
available entities which match a given function in the graph.

As a drive by, also fix a whitespace error in the documentation of
MediaDevice::setupLink.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-04-29 01:20:50 +09:00
Paul Elder
ee2b011b65 apps: cam: Try raw role if default viewfinder role fails
cam currently defaults to the viewfinder role when no role is specified.
This means that on platforms that only support the raw role (such as a
raw sensor with no softISP on a simple pipeline platform),
generateConfiguration() would return nullptr and cam would bail out.

At least this is what is supposed to happen based on the little
documentation that we have written regarding generateConfiguration(),
specifically in the application writer's guide, which is probably the
most influential piece of documentation:

  The ``Camera::generateConfiguration()`` function accepts a list of
  desired roles and generates a ``CameraConfiguration`` with the best
  stream parameters configuration for each of the requested roles. If the
  camera can handle the requested roles, it returns an initialized
  ``CameraConfiguration`` and a null pointer if it can't.

Currently the simple pipeline handler will return a raw configuration
anyway (if it only supports raw) even if a non-raw role was requested.
Thus cam receives a raw configuration instead of a nullptr when no role
is specified and viewfinder is requested.

However, in the near future, support for raw streams with softISP on the
simple pipeline handler will be merged. This will notably change the
behavior of the simple pipeline handler to return nullptr if a non-raw
role was requested on a platform that only supports raw. This is proper
behavior according to documentation, but changes cam's behavior as it
used to capture fine with no parameters but will no longer be able to.

Technically this is an issue with the roles API, as we are mixing
roles in the sense of "configuration hints" (eg. viewfinder vs recording
vs still capture) with roles in the sense of "platform capabilities"
(raw vs everything else). In the long term the proper solution is to
rework the roles API.

In the meantime, fix cam so that it will try the raw role if the default
viewfinder role returns no configuration. cam is an app that is capable
of using the raw stream, so this is appropriate behavior. If roles are
specified, then do not retry, as in this situation the user knows what
streams they can use and what they want.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2025-04-29 00:57:54 +09:00
Barnabás Pőcze
72c3deffbb libcamera: controls: Disallow arrays of arrays
Arrays of arrays, even arrays of strings, are not supported by
the current `ControlValue` mechanism, so disable them for now
to trigger compile time errors if attempts are made to use them.

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-04-25 18:06:05 +02:00
Hou Qi
3569fed7af gstreamer: Fixate colorimetry field during caps negotiation
When libcamerasrc is negotiating with downstream element, it first
extracts colorimetry field from downstream supported caps, then set
this colorimetry to its stream configuration and propagates the
colorimetry downstream.

Currently libamerasrc only considers the case there is one colorimetry
in colorimetry field of downstream caps. But the issue is that
downstream caps may report a list of supported colorimetry, which
causes libcamerasrc to set unknown colorimetry to stream configuration
and negotiate fail with downstream element.

In order to fix the issue, need to fixate colorimetry field before
getting colorimetry string.

Signed-off-by: Hou Qi <qi.hou@nxp.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-23 13:50:53 +01:00
Barnabás Pőcze
e1818265ae utils: ipc: Do not define variables in signal handler up front
Defining the variables at the beginning of the function forces the types
to be default constructible, which may not be desirable; furthermore, it
also forces the move/copy assignment operator to be used when the
deserialized value is retrieved.

Having `T val = f()` has the advantage of benefitting from potential RVO
as well as not requiring `T` to be default constructible, so generate
code in that form by calling `deserialize_call()` with `declare=true`.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-22 20:52:42 +02:00
Barnabás Pőcze
f31da7272e libcamera: ipa_module: Avoid unnecessary copy when getting signature
The `signature()` getter can just return a reference to the private vector
member variable, and let the caller make a copy if needed. Since the
return type is const qualified, this was likely the original intention.

Signed-off-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>
2025-04-22 14:49:10 +02:00
Paul Elder
86c45c8fdf pipeline: rkisp1: Fix vblank delay
The vblank delay for delayed controls was incorrectly hardcoded to 1.
Get it from the camera sensor properties instead.

Fixes: f72c76eb6e ("rkisp1: Honor the FrameDurationLimits control")
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-22 20:18:11 +09:00
Quentin Schulz
6e24360d3f Revert "libcamera: rkisp1: Eliminate hard-coded resizer limits"
This reverts commit e85c7ddd38.

Linux kernel predating 6.4 (specifically commit 7cfb35d3a800 ("media:
rkisp1: Implement ENUM_FRAMESIZES") do not have the ioctl in rkisp1
driver required to dynamically query the resizer limits.

Because of that, maxResolution and minResolution are both {0, 0}
(default value for Size objects) which means filterSensorResolution()
will create an entry for the sensor in sensorSizesMap_ but because the
sensor resolution cannot fit inside the min and max resolution of the
rkisp1, no size is put into this entry in sensorSizesMap_.
On the next call to filterSensorResolution(),
sensorSizesMap_.find(sensor) will return the entry but when attempting
to call back() on iter->second, it'll trigger an assert because the size
array is empty.

Linux kernel 6.1 is supported until December 2027, so it seems premature
to get rid of those hard-coded resizer limits before this happens.

Let's restore the hard-coded resizer limits as fallbacks, actual limits
are still queried from the driver on recent enough kernels.

Fixes: 761545407c ("pipeline: rkisp1: Filter out sensor sizes not supported by the pipeline")
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-22 13:24:01 +03:00
Barnabás Pőcze
5b73d25967 utils: ipc: Do not duplicate signals in proxy object
The specific proxy type (see `module_ipa_proxy.h.tmpl`) inherits `IPAProxy`,
the specific interface type, and `Object`. The interface type already
provides public definitions of the necessary `Signal<>` objects (see
`module_ipa_interface.h.tmpl`), so do not duplicate them.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-21 16:33:40 +02:00
Barnabás Pőcze
3e4de5f54e apps: cam: capture_script: Simplify bool array parsing
`std::vector<bool>` is a specialization that implements a dynamic
bit vector, therefore it is not suitable to provide storage for
an array of `bool`. Hence a statically sized array is used when
parsing an array of boolean values.

Instead, use the array overload of `std::make_unique` since the
size is known beforehand.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-04-21 16:24:16 +02:00
Barnabás Pőcze
83543f08d5 libcamera: pipeline: imx8-isi: Remove unused variable
The `mbusCodes` variable in `ISICameraConfiguration::validateRaw()`
has been unused since

  87fed43253 ("libcamera: imx8-isi: Break out RAW format selection"),

so remove it.

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-04-21 16:15:21 +02:00
Barnabás Pőcze
ee92b5211c libcamera: pipeline: virtual: Fix typo in log message
pass -> parse

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-04-21 16:05:43 +02:00
Laurent Pinchart
5d1380f7df utils: rkisp1: gen-csc-table: Support printing CCM in decimal
Add an option to the gen-csc-table.py script to output the CCM matrix in
decimal format instead of hexadecimal. This makes no functional
difference, but is useful to adapt to different coding styles.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-17 14:50:44 +03:00
Pavel Machek
50d143ad1d doc: document libtiff dependency for cam
DNG writing is useful when working with bayer data, but libtiff is
needed for that.

Signed-off-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
[Kieran: Updated text to match other entries]
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-15 18:52:31 +01:00
Milan Zamazal
026ed62739 libcamera: software_isp: Fix CCM multiplication
A colour correction matrix (CCM) is applied like this to an RGB pixel
vector P:

  CCM * P

White balance must be applied before CCM.  If CCM is used, software ISP
makes a combined matrix by multiplying the CCM by a white balance gains
CCM-like matrix (WBG).  The multiplication should be as follows to do it
in the correct order:

  CCM * (WBG * P) = (CCM * WBG) * P

The multiplication order in Lut software ISP algorithm is reversed,
resulting in colour casts.  Let's fix the order.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-15 18:47:17 +01:00
Barnabás Pőcze
78d9f7bb75 libcamera: pipeline: uvcvideo: Expose Gamma control
Commit 294ead848c ("libcamera: Add gamma control id")
introduced the "Gamma" control, so expose it for UVC
cameras as well using the `V4L2_CID_GAMMA` control.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-15 13:07:21 +02:00
Barnabás Pőcze
5553efc6b1 libcamera: request: Avoid double map lookup
Use `try_emplace()` that more or less combines `find()` and `operator[]`
in one function.

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-04-15 12:11:40 +02:00
Barnabás Pőcze
7fd317adf0 apps: lc-compliance: Add multi-stream tests
Rename the `SingleStream` test to `SimpleCapture`, and extend it
to support using multiple roles. And instantiate another test suite
from the `SimpleCapture` test that tests multiple streams in one
capture session.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-04-15 09:54:18 +02:00
Barnabás Pőcze
13cca98046 apps: lc-compliance: Support multiple streams in helpers
Prepare to add a test suite for capture operations with multiple
streams.

Modify the Capture helper class to support multiple roles and streams
in the configure() and capture() operations. The buffer count
of each stream is asserted to be the same.

Multi-stream support will be added in next patches.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-04-15 09:54:18 +02:00
Pavel Machek
886f877dd3 doc: Mention right meson version
Documentation says 0.60, but in fact 0.63 is required.

Signed-off-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-14 22:07:31 +03:00
Quentin Schulz
ae2b6cb3ca meson: Do not automatically build documentation if sphinx-build-3 is found
Commit aba567338b ("Documentation: Move all dependencies into
features") did an incomplete migration of the documentation boolean
option into a documentation feature.

If sphinx-build-3 binary is found on the host system, the documentation
is built, regardless of the value of the feature option.

This makes sure that sphinx-build-3 presence is only checked if the
documentation feature is not disabled (which is the default, as it's
"auto" by default).

This is essential for reproducibility for build systems where
sphinx-build-3 may or may not be present when libcamera is built, and
also to declutter the generated package if documentation isn't desired.

Fixes: aba567338b ("Documentation: Move all dependencies into features")
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Quentin Schulz <quentin.schulz@cherry.de>
Tested-by: Quentin Schulz <quentin.schulz@cherry.de>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-14 22:07:17 +03:00
Quentin Schulz
eea723ad72 meson: Make the default value of "documentation" feature explicit
The meson documentation on the feature build options isn't clear if a
missing "value" is legal and if it is, what its default value is ([1]).

Therefore, let's make it explicit by using what is experimentally the
default: auto.

[1] https://mesonbuild.com/Build-options.html#features

Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-14 22:07:11 +03:00
Milan Zamazal
21088e605c libcamera: software_isp: Add a clarification comment to AWB
The computed AWB gains are applied when constructing LUT tables rather
than in awb.cpp itself.  This can look confusing when reading awb.cpp,
let's add a clarifying comment.

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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-10 00:09:40 +03:00
Kieran Bingham
058f589ae3 libcamera v0.5.0
The abi-compliance-checker reports there are both ABI and API changes in this
release:

  Binary compatibility: 99%
  Source compatibility: 99.5%
  Total binary compatibility problems: 5, warnings: 1
  Total source compatibility problems: 6, warnings: 1

Substantially less than the previous release, and ultimately quite minor but
unfortunately there nonetheless and so the SONAME is updated to 0.5
accordingly. I do not anticipate anything there that cannot be solved for
applications without just a recompile. I had hoped to get a longer run for 0.4
series...

A full and detailed ABI report for those interested can always be generated
between any two versions with the internal tooling:

 "./utils/abi-compat.sh v0.4.0 v0.5.0"

Integration overview:

This release brings in 201 commits with a huge list of fixes and code clean up
which I'm very happy to see, including interesting fixes to the AGC and AWB
handling in libipa.

In regards to new features, libcamera-0.5 has aptly now got the core Raspberry
Pi 5 support merged!. There are still patches that are currently maintained by
Raspberry Pi for additional features, and while the transition to upstream
API's continue, but I think we're all happy to see this support getting in
directly, and Raspberry Pi continue to lead the way in upstream camera
development. I look forward to the kernel API's for streams being fully
utilised by the PiSP platform for upstream camera metadata handling. This
upcoming work is also supported by the CameraSensor factory and CameraSensorRaw
support that is now also merged in this release.

Further more in the platform support, the software_isp continues to be
developed and is now able to measure colour temperature, which will bring in
improvements for AWB, and a CCM can be applied while peforming debayering (at a
CPU cost) which will allow us to finally apply color tuning for sensors on
devices that need to fall back to the software ISP.

New sensor support seems fairly short in this release, with the IMX415 being
the prominent addition.

In libipa, and algorithm developments, along with many fixes and improvements
there is a substantial new feature that the Baysian AWB algorithm from
Raspberry Pi can now also be used on all libipa supported IPA modules, and has
shown good impovements for the RkISP1 supported devices.

There is minimal changes to the application support side, but it is notable
that now the Y444 format has been mapped to be usable by the gstreamer src
element. lc-compliance has seen some progress which I hope will bring this to
being a more central part of the test infrastructure.

The following commits in this release relate to either a bug fix or an
improvement to an existing commit.

 - DmaBufAllocator: Make DmaSyncer non-copyable
   - Fixes: 39482d59fe ("DmaBufAllocator: Add Dma Buffer synchronization function & helper class")
 - utils: codegen: controls.py: Fix missing direction error message
   - Fixes: 39fe4ad968 ("utils: codegen: controls.py: Parse direction information")
 - Thread: Fix setThreadAffinity race condition in start
   - Fixes: 4d9db06d66 ("libcamera: add method to set thread affinity")
 - meson: Don't override pipeline list when `auto` is selected
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=247
 - DmaBufAllocator: Avoid syncing with an invalid file descriptor
   - Fixes: 545046a41e ("DmaBufAllocator: Make DmaSyncer non-copyable")
 - controls: Introduce AEGC-related controls
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=42
 - Documentation: guides: application-developer: Fix variable shadowing
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=252
 - libcamera: pipeline: virtual: Fill buffer's metadata
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=245
 - ipa: rkisp1: agc: Fix build on debian 11 (gcc-9)
   - Fixes: ee918b370a ("ipa: rkisp1: agc: Initialize enum controls with a list of values")
 - ipa: rpi: Apply default ControlInfo values for sensor controls
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=253
 - ipa: rpi: Fix incorrect cast for ExposureTime ControlInfo
   - Fixes: bea2db5e61 ("ipa: rpi: Apply default ControlInfo values for sensor controls")
 - ipa: rkisp1: algorithms: agc: Fix whitespace
   - Fixes: 0e0e32b189 ("ipa: rkisp1: algorithms: agc: Check for correct stats type")
 - libcamera: pipeline: Fix LIBCAMERA_<NAME>_TUNING_FILE handling
   - Fixes: f5da05ed03 ("libcamera: pipeline: Move tuning file override handling to IPAProxy")
 - ipa: rkisp1: algorithms: awb: Fix AWB means vector order in RGB mode
   - Fixes: 29892f1c56 ("ipa: libipa: colour: Use the RGB class to model RGB values")
 - libipa: awb: Fix non-virtual destructor warning in AwbStats
   - Fixes: 6f663990a0 ("libipa: Add AWB algorithm base class")
 - ipa: rkisp1: Allow exposure time to be shorter than minimum frame duration limit
   - Fixes: f72c76eb6e ("rkisp1: Honor the FrameDurationLimits control")
 - ipa: libipa: Fix bug in ExposureModeHelper that leads to oscillations in AEGC
   - Fixes: 34c9ab6282 ("ipa: libipa: Add ExposureModeHelper")
 - libcamera: software_isp: Emit ispStatsReady only if IPA is running
   - Reported-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
 - libcamera: base: log: Fix uninitialized variable warning
   - Fixes: 8fa119e0b5 ("libcamera: base: log: Use `std::from_chars()`")
 - libcamera: media_object: Fix unnecessary copy
   - Fixes: 9490c664b5 ("libcamera: Add members to MediaEntity to support ancillary entities")
 - ipa: rkisp1: agc: Fix metering modes
   - Fixes: 4c5152843a ("ipa: rkisp1: Derive rkisp1::algorithms::Agc from AgcMeanLuminance")
 - libcamera: software_isp: Reset stored exposure in black level
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=259
 - libcamera: pipeline: uvcvideo: Fix `ExposureTimeMode` control setup
   - Fixes: bad8d591f8 ("libcamera: uvcvideo: Register ExposureTimeMode control")
 - libcamera: pipeline: uvcvideo: Fix `ExposureTimeMode` control setting
   - Fixes: bad8d591f8 ("libcamera: uvcvideo: Register ExposureTimeMode control")
 - ipa: simple: Initialize ccmEnabled to false
   - Fixes: ac30686556 ("libcamera: software_isp: Track whether CCM is enabled")
 - gstreamer: Use `Control<>` objects when setting controls
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=261
 - gstreamer: Restore `AeEnable` control
   - Fixes: 187f2d537b ("gstreamer: Generate the new AEGC controls")
 - pipeline: rpi: Fix potential empty optional read
   - Fixes: 6c71ee1f15 ("pipeline: raspberrypi: Introduce PipelineHandlerBase class")

And the following updates have been made in this release, grouped by category:

core:
 - libcamera: virtual: Avoid some copies
 - libcamera: virtual: Query number of planes correctly
 - libcamera: virtual: Speed up test pattern animation
 - libcamera: camera_sensor_properties: Add delays for imx415
 - include: linux: Update headers for line-based embedded data support
 - include: linux: videodev2: Add generic line based pixel formats
 - libcamera: v4l2_subdevice: Add new metadata formats
 - libcamera: v4l2_videodevice: Update to the new kernel metadata API
 - libcamera: Add CameraSensor implementation for raw V4L2 sensors
 - libcamera: camera_sensor: Add support for embedded data
 - libcamera: base: Remove custom __nodiscard attribute
 - libcamera: Add missing <stdint.h> include to dma_buf_allocator.h
 - libcamera: include: Include missing stdint.h header
 - utils: codegen: controls.py: Fix missing direction error message
 - meson: Convert `v4l2` into a feature option
 - meson: Don't override pipeline list when `auto` is selected
 - libcamera: pipeline_handler: Enable silent configuration file lookup
 - libcamera: virtual: Install configuration file
 - libcamera: v4l2_subdevice: Work around false positive warning
 - libcamera: uvcvideo: Register ExposureTimeMode control
 - libcamera: camera: Pre-process AeEnable control
 - libcamera: base: object,thread: Disable copy/move
 - libcamera: matrix: Add read-only accessor to internal data
 - libcamera: log: Match whole category in LIBCAMERA_LOG_LEVELS
 - libcamera: Copy Vector class files from libipa
 - libcamera: Adapt Vector class to new location
 - libcamera: request: addBuffer(): Do fence check earlier
 - libcamera: Drop spurious colon after doxygen \todo directive
 - meson: Enable the -Wnon-virtual-dtor compiler option
 - libcamera: formatting: Avoid spaces in for loops without expression
 - libcamera: base: log: Remove move constructor
 - libcamera: base: log: Use `std::from_chars()`
 - libcamera: base: log: Remove `LogMessage::init()`
 - libcamera: base: log: Make `LogCategory::severity_` atomic
 - libcamera: base: log: Use `std::string_view` to avoid some copies
 - libcamera: base: log: Pass dynamic prefix through
 - libcamera: base: log: Protect log categories with lock
 - libcamera: base: log: Avoid manual `LogCategory` deletion
 - libcamera: meson: Fix libyuv detection
 - libcamera: base: thread: Support dispatching for a specific receiver
 - libcamera: base: log: Fix uninitialized variable warning
 - libcamera: base: signal: Drop pre-C++17 support
 - meson: Add libpisp.wrap
 - libcamera: media_object: Fix unnecessary copy
 - libcamera: ipa_manager: Store `IPAModule`s in `std::unique_ptr`
 - libcamera: base: mutex: Remove unnecessary constructors
 - libcamera: media_device: Ignore `lockf()` return value
 - libcamera: v4l2_videodevice: `lastUsedCounter_` need not be atomic
 - libcamera: camera: Ensure correct id maps are always set
 - libcamera: base: span: Explicitly default copy assignment
 - libcamera: controls: Check size of enum
 - libcamera: camera_manager: Do not emit signals while holding lock
 - libcamera: camera_manager: Simplify camera lookup
 - libcamera: camera_manager: Take camera id in `std::string_view`
 - libcamera: base: object: Forward arguments when invoking
 - libcamera: base: bound_method: Simplify `invokePack()`
 - libcamera: v4l2_device: add frame start event helpers
 - DmaBufAllocator: Make DmaSyncer non-copyable
 - Thread: Fix setThreadAffinity race condition in start
 - DmaBufAllocator: Avoid syncing with an invalid file descriptor
 - controls: Introduce AEGC-related controls
 - controls: Remove AeLocked
 - controls: Redefine AeEnable

ipa:
 - ipa: rpi: Add cam_helper for imx415
 - ipa: rpi: Add vc4 tuning files for imx415
 - ipa: rpi: Use r-value references in the set()/setLocked() functions
 - ipa: rpi: Add erase()/eraseLocked() to RPiController::Metadata
 - ipa: rpi: Add a HW property to determine if the data buffer is strided
 - ipa: rpi: Provide the camera helper with the hardware configuration
 - ipa: raspberry: Port to the new AEGC controls
 - ipa: rkisp1: Port to the new AEGC controls
 - ipa: rkisp1: agc: Report new AeEnable control as available
 - ipa: raspberry: Report new AeEnable control as available
 - ipa: libipa: lux: Fix indentation
 - ipa: rkisp1: agc: Initialize enum controls with a list of values
 - ipa: rkisp1: agc: Fix build on debian 11 (gcc-9)
 - ipa: rpi: Apply default ControlInfo values for sensor controls
 - ipa: Use Vector class from libcamera
 - libipa: Drop Vector class
 - ipa: rpi: Fix incorrect cast for ExposureTime ControlInfo
 - ipa: rkisp1: algorithms: agc: Fix whitespace
 - libipa: interpolator: Add accessor to internal data
 - libipa: pwl: Add clear() function
 - libipa: Add AWB algorithm base class
 - libipa: awb: Add helper functions for AWB mode support
 - libipa: Add grey world AWB algorithm
 - ipa: rkisp1: Move calculation of RGB means into own function
 - ipa: rkisp1: Use grey world algorithm from libipa
 - libipa: Add bayesian AWB algorithm
 - ipa: rkisp1: Add support for bayes AWB algorithm from libipa
 - ipa: rkisp1: awb: Apply gains based on default colour temperature on start
 - libipa: lux: Normalize referenceY to 1
 - libipa: awb_bayes: Add logging of value limits
 - libipa: awb_bayes: Remove overly verbose log messages
 - libipa: awb_bayes: Change the probabilities from log space to linear space
 - libipa: awb: Sort class member documentation according to header order
 - libipa: awb: Capitalize AWB
 - libipa: awb: Follow function names with '()' in doxygen documentation
 - libipa: awb: Standardize spelling on 'grey' world
 - libipa: awb: Replace reference to pipeline handle with IPA module
 - libipa: awb: Pass lux value to calculateAwb() as unsigned int
 - ipa: rkisp1: awb: Fix wrong indentation in comment
 - libipa: awb: Rename AwbStats::getRGBMeans() to rgbMeans()
 - libipa: awb: Tidy up includes
 - libipa: awb_grey: Minor comment fixes
 - ipa: rkisp1: awb: Don't calculate RGB means if stats are missing
 - ipa: rkisp1: awb: Capitalize AWB
 - ipa: rkisp1: algorithms: awb: Fix AWB means vector order in RGB mode
 - libipa: awb: Fix non-virtual destructor warning in AwbStats
 - ipa: rkisp1: Initialise AGC from FrameDurationLimits controls
 - ipa: rkisp1: Alias lineDuration
 - ipa: rkisp1: Allow exposure time to be shorter than minimum frame duration limit
 - ipa: libipa: Fix bug in ExposureModeHelper that leads to oscillations in AEGC
 - utils: ipc: Only dispatch messages for proxy when stopping thread
 - ipa: rpi: Add support for Raspberry Pi 5
 - ipa: simple: lut: Fix include path
 - ipa: rkisp1: agc: Fix metering modes
 - ipa: rkisp1: agc: Set measurement window to full frame
 - ipa: rkisp1: Add debug log for the sensor controls being set
 - ipa: libipa: agc_mean_luminance: Error out when effectiveExposureValue is zero
 - ipa: rksip1: Remove setControls(0) to reduce startup oscillations
 - ipa: simple: softisp: Extend to pass metadata
 - ipa: simple: Report the ColourGains in metadata
 - ipa: simple: Report black levels in metadata
 - ipa: simple: Report contrast in metadata
 - ipa: simple: Report exposure in metadata
 - ipa: simple: Initialize ccmEnabled to false
 - libipa: histogram: Fix quantile() calculation for fractional results
 - libipa: histogram: Fix interQuantileMean() for small ranges

apps:
 - gstreamer: allocator: gst_libcamera_allocator_new(): Recognize errors
 - gstreamer: allocator: gst_libcamera_allocator_new(): Fix memory leak
 - gstreamer: Generate the new AEGC controls
 - apps: ppm_writer: Add a missing include
 - apps: ppm_writer: Return EIO on I/O errors
 - gstreamer: Fix scaler-crop property get
 - apps: common: event_loop: Take callbacks by rvalue ref
 - apps: common: event_loop: Disable copy/move
 - apps: common: event_loop: Use `std::deque` instead of `std::list`
 - apps: common: event_loop: Use single event source for deferred calls
 - apps: common: event_loop: Remove unused type alias
 - apps: lc-compliance: Initialize `CameraManager` pointer in `Environment`
 - apps: lc-compliance: Put tests into anonymous namespace
 - apps: lc-compliance: Optimize `std::shared_ptr` usage
 - apps: lc-compliance: Remove redundant getter call
 - apps: lc-compliance: Don't allocate `FrameBufferAllocator` dynamically
 - apps: lc-compliance: Use `std::vector` for argument array
 - apps: lc-compliance: Use array instead of `std::vector`
 - apps: lc-compliance: Add message to `GTEST_SKIP()`
 - apps: lc-compliance: Merge `CaptureBalanced` and `CaptureUnbalanced`
 - gstreamer: Add Y444 format support to the YUV list
 - apps: cam: Fix include order
 - apps: qcam: Simplify `PixelFormat` search
 - apps: cam: Highlight default enumerator
 - gstreamer: Use `Control<>` objects when setting controls
 - gstreamer: Restore `AeEnable` control

pipeline:
 - libcamera: pipeline: virtual: Demote config file error message to debug
 - libcamera: pipeline: Move tuning file override handling to IPAProxy
 - libcamera: software_isp: Move a non-loop condition out of the loop
 - libcamera: software_isp: Handle signals in the proper thread
 - libcamera: pipeline: virtual: Simplify error return
 - libcamera: pipeline: virtual: Fill buffer's metadata
 - libcamera: pipeline: virtual: Set `FrameError` on error
 - libcamera: pipeline: Fix LIBCAMERA_<NAME>_TUNING_FILE handling
 - rkisp1: Honor the FrameDurationLimits control
 - libcamera: software_isp: Emit ispStatsReady only if IPA is running
 - libcamera: software_isp: Handle queued output buffers on stop
 - libcamera: software_isp: Handle queued input buffers on stop
 - libcamera: software_isp: Dispatch messages on stop
 - pipeline: rpi: Add new stream flags for PiSP
 - pipeline: rpi: Add support for Raspberry Pi 5
 - libcamera: software_isp: Determine color temperature
 - libcamera: software_isp: Use RGB type to represent gains
 - libcamera: software_isp: Store color temperature to metadata
 - libcamera: software_isp: lut: Remove maybe_unused on a used argument
 - libcamera: software_isp: Use common code to store debayered pixels
 - libcamera: software_isp: Use a macro to assign debayering methods
 - libcamera: software_isp: Add CCM algorithm
 - libcamera: software_isp: Add an example CCM to uncalibrated.yaml
 - libcamera: software_isp: Track whether CCM is enabled
 - libcamera: software_isp: Apply CCM in debayering
 - pipeline: rpi: pisp: Fix uninitialized variable warning
 - libcamera: software_isp: Track frames and requests
 - libcamera: software_isp: Reset stored exposure in black level
 - libcamera: pipeline: uvcvideo: Fix `ExposureTimeMode` control setup
 - libcamera: pipeline: uvcvideo: Fix `ExposureTimeMode` control setting
 - pipeline: rpi: Fix potential empty optional read
 - pipeline: simple: Connect/disconnect frameStart signal at start/stop time
 - pipeline: simple: Enable frame start events
 - pipeline: simple: Create DelayedControls instance once only
 - pipeline: simple: Reset delayedCtrls at start

documentation:
 - Documentation: design: ae: Document the design for AE controls
 - Documentation: guides: application-developer: Fix variable shadowing
 - Revert "README.rst: Report py dependencies"

test:
 - test: ipa_data_serialization: Use DebugMetadataEnable
 - test: threads: Use `pthread_testcancel()`
 - test: ipa: libipa: Add histogram tests
 - test: ipa: libipa: histogram: Add tests for quantile() returning a fraction
 - test: ipa: libipa: histogram: Add tests for small inter quantile mean ranges

tuning:
 - libtuning: module: awb: Add bayes AWB support
 - libtuning: Add module for lux calibration
 - utils: tuning: rkisp1: Add lux module

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-03 14:38:25 +01:00
Stefan Klug
80ac19a507 libipa: histogram: Fix interQuantileMean() for small ranges
The interQuantileMean() is supposed to return a weighted mean value
between two quantiles. This works for fine histograms, but fails for
coarse histograms and small quantile ranges because the weight is always
taken from the lower border of the bin.

Fix that by rewriting the algorithm to calculate a lower and upper bound
for every (partial) bin that goes into the mean calculation and weight
the bins by the middle of these bounds.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-03 12:36:07 +02:00
Stefan Klug
3b9c432920 test: ipa: libipa: histogram: Add tests for small inter quantile mean ranges
Add tests for small inter quantile mean ranges. As these cases fail at
the moment, mark the test as should_fail.

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>
2025-04-03 12:36:07 +02:00
Stefan Klug
8936e81e3f libipa: histogram: Fix quantile() calculation for fractional results
The calculation of the frac variable is based solely on integers and
therefore results in the fractional part being either 0 or 1.

In the original code from RaspberryPi this is mitigated by casting the
nominator to a double. This works for most cases, but fails when q is
very small because of the quantization introduced by item being an
integer.

Fix both issues by doing the full calculation in double and remove the
should_fail tag.

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>
2025-04-03 12:36:07 +02:00
Stefan Klug
781e2f4d0c test: ipa: libipa: histogram: Add tests for quantile() returning a fraction
Add tests for quantile() returning a fractional value. These cases will
get fixed in the next commit. Therefore mark the test as should_fail.

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>
2025-04-03 12:36:07 +02:00
Stefan Klug
1a17a6aac7 test: ipa: libipa: Add histogram tests
Add some basic tests for the histogram class.

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>
2025-04-03 12:36:07 +02:00
Stanislaw Gruszka
18792b81cb pipeline: simple: Reset delayedCtrls at start
Similar like in other pipelines (IPU3, rpi) avoid using stale
values of DelayedControls class when the same camera is started
second time.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Co-developed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-03 10:28:30 +01:00
Laurent Pinchart
8a79800089 pipeline: simple: Create DelayedControls instance once only
The DelayedControls instance for the camera sensor is created in
SimplePipelineHandler::configure(). Constant deletion and reconstruction
of a new object is unnecessary, as the control delays are an intrinsic
property of the sensor and are known at initialization time. Move the
DelayedControls creation to the SimpleCameraData class constructor.

Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com> # v6
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-03 10:28:29 +01:00
Stanislaw Gruszka
183bab1643 pipeline: simple: Enable frame start events
The simple pipeline handler uses frame start events to apply sensor
controls through the DelayedControls class. The setSensorControls()
function applies the controls directly, which would result in controls
being applied twice, if it wasn't for the fact that the pipeline handler
forgot to enable the frame start events in the first place. Those two
issues cancel each other, but cause controls to always be applied
directly.

Fix the issue by only applying controls directly in setSensorControls()
if no frame start event emitter is available, and by enabling the frame
start events in startDevice() otherwise. Disable them in stopDevice()
for symmetry.

Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com> # v6
Co-developed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Co-developed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-03 10:28:24 +01:00
Stanislaw Gruszka
2f7bece17b pipeline: simple: Connect/disconnect frameStart signal at start/stop time
The frameStart signal from the frame start emitter is connected in the
configure() function, and is never disconnected. This means that each
time the camera is configured a new connection is made, causing the
DelayedControls::applyControls() to be called multiple times. Fix it by
connecting and disconnecting the signal when starting and stopping the
camera.

Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com> # v6
Co-developed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Co-developed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-03 09:36:11 +01:00
Stanislaw Gruszka
b2eccef711 libcamera: v4l2_device: add frame start event helpers
Add helper to check if frame start event are supported by subdevice.
Since kernel does not have interface to query supported events
use subscribe interface.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # v3
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> # v5
Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-03 09:36:11 +01:00
Barnabás Pőcze
a2a7f4fc2d pipeline: rpi: Fix potential empty optional read
If `!target`, then `*target` is undefined behaviour, so check if the optional
is empty when printing the error message. Simplify the check as well.

Fixes: 6c71ee1f15 ("pipeline: raspberrypi: Introduce PipelineHandlerBase class")
Fixes: 841ef2b4bb ("pipeline: rpi: Add support for Raspberry Pi 5")
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>
2025-04-02 19:37:38 +02:00
Barnabás Pőcze
61d93434f5 gstreamer: Restore AeEnable control
Commit "gstreamer: Generate the new AEGC controls" removed the
`AeEnable` control from gen-gst-controls.py. However, the patch
set it was part of did not end up removing the `AeEnable`
control after all. So restore it for gstreamer users.

See 85cb179f28 ("controls: Redefine AeEnable").

Fixes: 187f2d537b ("gstreamer: Generate the new AEGC controls")
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-04-02 17:41:14 +02:00
Barnabás Pőcze
66fc6d2656 gstreamer: Use Control<> objects when setting controls
`g_value_get_boolean()` returns `gboolean`, which is actually `int`. Thus

  // ControlValue x;
  auto val = g_value_get_boolean(...);
  x.set(val);

will cause `ControlValue::set<int, ...>(const int&)` to be called, which
will save the value as `ControlTypeInteger32`, not `ControlTypeBoolean`.

Then, if something tries to retrieve the boolean value, it will run into an
assertion failure:

  Assertion `type_ == details::control_type<std::remove_cv_t<T>>::value' failed.

in `ControlValue::set()`.

Fix this by using the appropriately typed `Control<>` object when setting
the value in the `ControlList` as this ensures that the value will be
converted to the actual type of the control.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=261
Fixes: 27cece6653 ("gstreamer: Generate controls from control_ids_*.yaml files")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-02 17:14:54 +02:00
Stanislaw Gruszka
7cd8818da8 ipa: simple: Initialize ccmEnabled to false
ccmEnabled variable is not initialized by default, which results in
usage of CCM when the algorithm itself is not enabled and configured.

The bug manifests itself as seldom reproducible corrupted video stream.
Fix by initialize ccmEnabled member where it is declared.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Fixes: ac30686556 ("libcamera: software_isp: Track whether CCM is enabled")
Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-02 09:35:52 +01:00
Barnabás Pőcze
8b2533d0ac libcamera: pipeline: uvcvideo: Fix ExposureTimeMode control setting
The mapping in `UVCCameraData::processControl()` is not entirely correct
because the control value is retrieved as a `bool` instead of `int32_t`.
Additionally, the available modes are not taken into account.

Retrieve the control value with the right type, `int32_t`, check if the
requested mode is available, and if so, set the appropriate V4L2 control
value selected by `addControl()` earlier.

Fixes: bad8d591f8 ("libcamera: uvcvideo: Register ExposureTimeMode control")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-04-01 16:13:00 +02:00
Barnabás Pőcze
799982b646 libcamera: pipeline: uvcvideo: Fix ExposureTimeMode control setup
`ControlInfo(Span<const int32_t>{...})` calls the incorrect constructor
of `ControlInfo`. The intended constructor to be called is
`ControlInfo(Span<const ControlValue>, ...)` however that is not called
because a span of `const int32_t` is passed. Instead, the constructor
`ControlInfo(const ControlValue &min, const ControlValue &max, ...)`
will be called.

Furthermore, since `values.back()` is used, only the last element of
the array is actually set.

To fix this, convert the array to contain `ControlValue` objects and use
a separate variable to keep track of which element to set next.

For each of `ExposureTimeMode{Auto,Manual}` save the V4L2 control value
that is to be used when the libcamera control is set.

Fixes: bad8d591f8 ("libcamera: uvcvideo: Register ExposureTimeMode control")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-04-01 16:13:00 +02:00
Barnabás Pőcze
5646307b71 libcamera: base: bound_method: Simplify invokePack()
Use `if constexpr` instead of SFINAE to handle return values of type `void`.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-01 13:57:45 +02:00
Barnabás Pőcze
7dd548f678 libcamera: base: object: Forward arguments when invoking
Use `std::forward()` to forward the received arguments to enable the
potential use of move constructors instead of copy constructors.

Commit 0eacde623b ("libcamera: object: Avoid argument copies in invokeMethod()")
added the forwarding references to `invokeMethod()` but it did not add the
appropriate `std::forward()` calls, so copying could still take place
even if not necessary.

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>
2025-04-01 12:58:45 +02:00
Barnabás Pőcze
37283b68ea libcamera: camera_manager: Take camera id in std::string_view
Do not force the caller to have an `std::string` object as a
simple string view is sufficient to do the lookup.

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-04-01 12:08:24 +02:00
Barnabás Pőcze
056ebf0b6e libcamera: camera_manager: Simplify camera lookup
`std::find()` works just fine because `std::shared_ptr` has
`operator==()` with the expected semantics.

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>
2025-04-01 11:42:00 +02:00
Milan Zamazal
ceea066fa2 libcamera: software_isp: Reset stored exposure in black level
Automatic black level setting in software ISP updates the determined
black level value when exposure or gain change.  It stores the last
exposure and gain values to detect the change.

BlackLevel::configure() resets the stored black level value but not the
exposure and gain values.  This can prevent updating the black value and
cause bad image output, e.g. after suspending and resuming a camera, if
exposure and gain remain unchanged.

Let's store exposure and gain in IPAActiveState.  Although the values
are not supposed to be used outside BlackLevel class, storing them in
the context has the advantage of their automatic reset together with the
other context contents and having them in `blc' struct indicates their
relationship to the black value computation.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=259
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-01 10:47:39 +03:00
Milan Zamazal
485a807dcb ipa: simple: Report exposure in metadata
Report exposure and gain in metadata.

This is more complicated than it could be expected because the exposure
value should be in microseconds but it's handled using V4L2_CID_EXPOSURE
control, which doesn't specify the unit, see
https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/control.html.
So the unit conversion is done in the way rkisp1 IPA uses.

This requires getting and passing IPACameraSensorInfo around.  To avoid
naming confusion and to improve consistency with rkisp1 IPA,
sensorCtrlInfoMap parameter is renamed to sensorControls.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-03-28 02:09:16 +02:00
Milan Zamazal
1375b07ede ipa: simple: Report contrast in metadata
Provide the requested contrast value, if any, in the metadata to add to
the completed requests.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-03-28 02:09:15 +02:00
Kieran Bingham
8a4c2682be ipa: simple: Report black levels in metadata
Provide the determined black level values in the metadata
to add to the completed requests.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-03-28 02:09:15 +02:00
Kieran Bingham
a0b97475b1 ipa: simple: Report the ColourGains in metadata
Provide the determined colour gains back into the metadata
to add to completed requests.

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>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-03-28 02:09:14 +02:00
Kieran Bingham
fb99081586 ipa: simple: softisp: Extend to pass metadata
Extend the Simple IPA IPC to support returning a metadata ControlList
when the process call has completed.

A new signal from the IPA is introduced to report the metadata,
similarly to what the hardware pipelines do.

Merge the metadata reported by the ISP into any completing request to
provide to the application.  Completion of a request is delayed until
this is done; this doesn't apply to canceled requests.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-03-28 02:09:13 +02:00
Milan Zamazal
4e343af7df libcamera: software_isp: Track frames and requests
Hardware pipelines track requests and other information related to
particular frames.  This hasn't been needed in software ISP so far.  But
in order to be able to track metadata corresponding to a given frame,
frame-request tracking mechanism starts being useful.  This patch
introduces the basic tracking structure, actual metadata handling is
added in the following patch.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-03-28 02:09:13 +02:00
Stefan Klug
4adf0e0b1c ipa: rksip1: Remove setControls(0) to reduce startup oscillations
The call to setControls(0) is counter productive. At start() time, no
requests were queued and no stats were received. So setControls(0)
accesses a zeroed frame context and in turn sends 0 as gain, exposure
and vblank to the pipeline handler and DelayedControls. This leads to
strong oscillations on every start of the camera.

A proper fix for handling the startup controls still needs to be done
and was already started in [1] and [2].

From a DelayedControls point of view the call to setControls(0) is also
unnecessary as DelayedControls treat frame 0 as already being queued in
after initialization.

So it is safe to just remove it and the removal fixes the zero
effectiveExposureValue discussed in the previous patch for rkisp1.

[1]: https://patchwork.libcamera.org/patch/21708/
[2]: https://patchwork.libcamera.org/patch/22445/

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>
2025-03-26 17:16:39 +01:00
Stefan Klug
03bae6b924 ipa: libipa: agc_mean_luminance: Error out when effectiveExposureValue is zero
In a proper system it never happens that the effectiveExposureValue
drops to zero. If that still happens due to a bug outside of
agc_mean_luminance, the calculated gain goes towards infinity but the
newExposureValue is still 0 because it is the result of multiplying the
effectiveExposureTime with the gain, leading to wild oscillations.

Catch that condition, print an error message and set the new effective
exposure value to an arbitrary 10ms.

Note that in any case the underlying problem must be fixed. The
important change is the added error message to be able to detect such a
situation.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-03-26 17:16:39 +01:00
Stefan Klug
94e94c6e8d ipa: rkisp1: Add debug log for the sensor controls being set
In the algorithm code a lot of information is logged in debug log level,
but there is no place where the values sent to the sensor get logged.
Add such a log message.

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>
2025-03-26 17:16:39 +01:00
Laurent Pinchart
bb3b8f0fec pipeline: rpi: pisp: Fix uninitialized variable warning
gcc 13.3.0 from buildroot 2024.11.1 complains about an uninitialized
variable. This is a false positive as the cfe_ array can't be empty.
Nonetheless, it breaks builds, so initialize the variable to work around
the issue.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-26 13:41:17 +02:00
Stefan Klug
2c66de06a0 ipa: rkisp1: agc: Set measurement window to full frame
With the availability of metering modes and the corresponding weights,
there is a flexible way of defining the area that gets taken into
account when AEGC is calculated. There is no need to reduce that window
to an arbitrary region anymore. If need arises we can make this
parameter user configurable or add a control for it.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-26 12:31:11 +01:00
Stefan Klug
0539e88679 ipa: rkisp1: agc: Fix metering modes
The weights for a given metering mode are applied to the histogram data
inside the histogram statistics block. The AE statistics do not contain
any weights. Therefore the weights are honored when AgcMeanLuminance
calculates the upper or lower constraints, but ignored in the
calculation of the frame luminance. Fix that by manually applying the
weights in the luminance calculation.

Fixes: 4c5152843a ("ipa: rkisp1: Derive rkisp1::algorithms::Agc from AgcMeanLuminance")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-26 12:31:10 +01:00
Milan Zamazal
e2b4000dc9 libcamera: software_isp: Apply CCM in debayering
This patch applies color correction matrix (CCM) in debayering if the
CCM is specified.  Not using CCM must still be supported for performance
reasons.

The CCM is applied as follows:

  [r1 g1 b1]   [r]
  [r2 g2 b2] * [g]
  [r3 g3 b3]   [b]

The CCM matrix (the left side of the multiplication) is constant during
single frame processing, while the input pixel (the right side) changes.
Because each of the color channels is only 8-bit in software ISP, we can
make 9 lookup tables with 256 input values for multiplications of each
of the r_i, g_i, b_i values.  This way we don't have to multiply each
pixel, we can use table lookups and additions instead.  Gamma (which is
non-linear and thus cannot be a part of the 9 lookup tables values) is
applied on the final values rounded to integers using another lookup
table.

Because the changing part is the pixel value with three color elements,
only three dynamic table lookups are needed.  We use three lookup tables
to represent the multiplied matrix values, each of the tables
corresponding to the given matrix column and pixel color.

We use int16_t to store the precomputed multiplications.  This seems to
be noticeably (>10%) faster than `float' for the price of slightly less
accuracy and it covers the range of values that sane CCMs produce.  The
selection and structure of data is performance critical, for example
using bytes would add significant (>10%) speedup but would be too short
to cover the value range.

The color lookup tables can be represented either as unions,
accommodating tables for both the CCM and non-CCM cases, or as separate
tables for each of the cases, leaving the tables for the other case
unused.  The latter is selected as a matter of preference.

The tables are copied (as before), which is not elegant but also not a
big problem.  There are patches posted that use shared buffers for
parameters passing in software ISP (see software ISP TODO #5) and they
can be adjusted for the new parameter format.

Color gains from white balance are supposed not to be a part of the
specified CCM.  They are applied on it using matrix multiplication,
which is simple and in correspondence with future additions in the form
of matrix multiplication, like saturation adjustment.

With this patch, the reported per-frame slowdown when applying CCM is
about 45% on Debix Model A and about 75% on TI AM69 SK.

Using std::clamp in debayering adds some performance penalty (a few
percent).  The clamping is necessary to eliminate out of range values
possibly produced by the CCM.  If it could be avoided by adjusting the
precomputed tables some way then performance could be improved a bit.

Signed-off-by: Milan Zamazal <mzamazal@redhat.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-03-26 10:45:01 +00:00
Milan Zamazal
ac30686556 libcamera: software_isp: Track whether CCM is enabled
Applying color correction matrix (CCM) in software ISP is optional due
to performance reasons.  CCM is applied if and only if `Ccm' algorithm
is present in the tuning file.

Software ISP debayering is a performance critical piece of code and we
do not want to use dynamic conditionals there.  Therefore we pass
information about CCM application to debayering configuration and let it
select the right versions of debayering functions using templates.  This
is a trick similar to the previously used one for adding or not adding
an alpha channel to the output.

Debayering gets this information but it ignores it in this patch.
Actual processing with CCM is added in the followup patch.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.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>
2025-03-26 10:45:01 +00:00
Milan Zamazal
0c53fe5f2f libcamera: software_isp: Add an example CCM to uncalibrated.yaml
For performance reasons, color correction matrix (CCM) is not applied by
default in software ISP.  But let's add a commented out example how to
define it to the default tuning file.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-26 10:45:01 +00:00
Milan Zamazal
38ec74fb40 libcamera: software_isp: Add CCM algorithm
This patch adds color correction matrix (CCM) algorithm to software ISP.
It is based on the corresponding algorithm in rkisp1.

The primary difference against hardware pipelines is that applying the
CCM is optional.  Applying CCM causes a significant slowdown, time
needed to process a frame raises by 40-90% on tested platforms.  If CCM
is really needed, it can be applied, if not, it's better to stick
without it.  This can be configured by presence or omission of Ccm
algorithm in the tuning file.

CCM is changed only if the determined temperature changes by at least
100 K (an arbitrarily selected value), to avoid recomputing the matrices
and lookup tables all the time.

Since the CCM is float, rather than double, to use the same type as in
the rkisp1 pipeline, the type of color gains is changed from double to
float.

The outputs of the algorithm are not used yet, they will be enabled in
followup patches.

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: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-26 10:45:01 +00:00
Milan Zamazal
23dfd69081 libcamera: software_isp: Use a macro to assign debayering methods
Assignments of the debayering methods to be used is a repetitive pattern
that can be (arguably) better expressed by using a macro.  This removes
some duplication and also makes easier to introduce more complex
assignment patterns.  This will be useful once color correction matrix
support is added.

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: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-26 10:45:01 +00:00
Milan Zamazal
f1955a0058 libcamera: software_isp: Use common code to store debayered pixels
The debayering macros use the same pattern, let's extract it to a common
macro.  This reduces code duplication a bit now and it'll make changes
of debayering easier when color correction matrix is introduced.

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: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-26 10:45:01 +00:00
Milan Zamazal
148ac13043 libcamera: software_isp: lut: Remove maybe_unused on a used argument
`params' argument of Lut::prepare is actually used, let's remove
maybe_unused from it.

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: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-26 10:45:01 +00:00
Milan Zamazal
7d4b4a1a79 libcamera: software_isp: Store color temperature to metadata
Image color temperature is a piece of information that should be
reported in metadata, let's put it there.

Metadata is currently not reported in simple pipeline but we should make
at least newly added information ready to be reported.

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: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-26 10:45:01 +00:00
Milan Zamazal
94e849bcf7 libcamera: software_isp: Use RGB type to represent gains
Rather than using a custom struct to represent RGB values, let's use the
corresponding type and its facilities.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.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>
2025-03-26 10:45:01 +00:00
Milan Zamazal
84f82c6b3c libcamera: software_isp: Determine color temperature
The AWB algorithm has data to determine color temperature of the image.
Let's compute the temperature from it and store it into the context.
This piece of information is currently unused but it will be needed in a
followup patch introducing support for color correction matrix.

Let's store the white balance related information under `awb' subsection
of the active state, as the hardware pipelines do.

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: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-26 10:45:01 +00:00
Barnabás Pőcze
d505bd5360 libcamera: camera_manager: Do not emit signals while holding lock
Both `CameraManager::Private::{add,remove}Camera()` emit the
`camera{Added,Removed}` signals, respectively, while holding the
lock protecting the list of cameras.

This is problematic because if a callback tries to call `cameras()`,
then the same (non-recursive) lock would be locked again.

Furthermore, there is no real need to hold the lock while user code
is running, so release the lock as soon as possible.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-25 12:54:50 +01:00
Barnabás Pőcze
b3272f7827 libcamera: controls: Check size of enum
Only enums whose sizes match that of `int32_t` can be directly
supported. Otherwise the expected size and the real size would
disagree, leading to an assertion failure in `ControlValue::set()`.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-25 12:41:17 +01:00
Barnabás Pőcze
a17df1be5e libcamera: base: span: Explicitly default copy assignment
The `dynamic_extent` specialization is currently not trivially copyable
unlike its standard counterpart, `std::span`. This is because the copy
assignment operator is user-defined. Explicitly default it just like
it is done in the main template definition.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-25 12:21:21 +01:00
Barnabás Pőcze
22dcaeacd0 libcamera: camera: Ensure correct id maps are always set
`Camera::Private::properties_` is a default constructed `ControlList`,
therefore it does not have an associated `ControlIdMap`. `controlInfo_`
is in a similar situation.

Extend the `Camera::Private` constructor to initialize the control id map
of both properly.

Multiple pipeline handlers copy the sensor's property list and
set that as camera properties, and since the `CameraSensor{Legacy,Raw}`
classes set the proper id map, the camera properties will have it too.

However, some pipelines, e.g. `uvcvideo` or `virtual`, do not do so,
and thus there will be no id map set. To fix this, extend the
`Camera::Private` constructor to set `properties::properties`.

As for `controlInfo_`, all pipeline handlers overwrite it during
camera initialization (and thus it will have the correct id map),
but still initialize the id map so that it is set at all times.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-21 18:28:28 +01:00
Barnabás Pőcze
12931e304a ipa: simple: lut: Fix include path
Use the proper path to include `libcamera/control_ids.h`.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-21 17:53:46 +01:00
Barnabás Pőcze
ce333ad0d2 test: threads: Use pthread_testcancel()
`pthread_testcancel()` is a guaranteed cancellation point,
specifically for testing if cancellation has been requested,
so use it.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-21 17:35:41 +01:00
Barnabás Pőcze
1df8091e63 libcamera: v4l2_videodevice: lastUsedCounter_ need not be atomic
The `V4L2BufferCache` type is not thread-safe. Its `lastUsedCounter_`
member is not used in contexts where its atomicity would matter.
So it does not need to be have an atomic type.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-21 16:56:58 +01:00
Barnabás Pőcze
90208694c8 apps: cam: Highlight default enumerator
Print "[default]" after the default enumerator when listing controls.

Example:

  $ cam -c 1 --list-controls
  [...]
  Control: [inout] libcamera::ExposureTimeMode:
    - ExposureTimeModeAuto (0) [default]
    - ExposureTimeModeManual (1)

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-21 16:40:50 +01:00
Barnabás Pőcze
fbb67a73c4 libcamera: media_device: Ignore lockf() return value
When `_FORTIFY_SOURCE` is enabled, the `lockf()` function might be marked
with the `warn_unused_result` attribute, leading to compilation failure.
Fix that by explicitly ignoring the return value.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-21 16:26:35 +01:00
Barnabás Pőcze
bb7f702b48 apps: qcam: Simplify PixelFormat search
Since `PixelFormat` has `operator==()`, `std::find()` can be used
directly, so do that to simplify.

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>
2025-03-21 16:09:39 +01:00
Barnabás Pőcze
314ecb5400 libcamera: base: mutex: Remove unnecessary constructors
The compiler defined default constructor works perfectly fine.

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>
2025-03-21 15:56:27 +01:00
Barnabás Pőcze
d716200d2b libcamera: ipa_manager: Store IPAModules in std::unique_ptr
Express the ownership more clearly by using a smart pointer type.

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>
2025-03-21 15:43:41 +01:00
Barnabás Pőcze
4a5ad4e9b0 libcamera: media_object: Fix unnecessary copy
`MediaEntity::ancillaryEntities()` can just return a const lvalue
reference to the underlying array, a copy need not be made. That
was likely the original intention.

Fixes: 9490c664b5 ("libcamera: Add members to MediaEntity to support ancillary entities")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-03-21 14:46:44 +01:00
Laurent Pinchart
330cd1c560 apps: cam: Fix include order
Several .cpp files in the cam application don't include their
corresponding header first, as usually done by libcamera to ensure that
headers are self-contained. Reorder headers to fix it. This shows
through a compilation error that file_sink.h is missing
libcamera/controls.h, fix it as well.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-03-20 16:03:27 +02:00
Naushir Patuck
841ef2b4bb pipeline: rpi: Add support for Raspberry Pi 5
Add the Raspberry Pi 5 ISP (PiSP) pipeline handler to libcamera. To
include this pipeline handler in the build, set the following meson
option:

meson configure -Dpipelines=rpi/pisp

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-20 12:03:28 +00:00
Naushir Patuck
332b04ce20 pipeline: rpi: Add new stream flags for PiSP
Add the following new stream flags:

Needs16bitEndianSwap - Indicates that a 16-bit endian swap needs to be
performed on the framebuffer in software.

Needs14bitUnpack - Indicates that a CSI-2 14-bit unpacking (to 16-bits)
needs to be performed on the framebuffer in software.

These are to workaround hardware restrictions in the CFE hardware that
will be supported in a future commit.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-20 12:03:28 +00:00
Naushir Patuck
dccdf87af3 ipa: rpi: Add support for Raspberry Pi 5
Add the Raspberry Pi 5 ISP (PiSP) IPA to libcamera. To include this IPA
in the build, set the following meson option:

meson configure -Dipas=rpi/pisp

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-20 12:03:28 +00:00
Naushir Patuck
e9807f5b6a meson: Add libpisp.wrap
Add a new subpoject wrap file for the libpisp library located at
https://github.com/raspberrypi/libpisp

The libpisp library is used to configure the Raspberry Pi 5 Frontend
and Backend ISP components.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-20 12:00:03 +00:00
Antoine Bouyer
06269e9584 gstreamer: Add Y444 format support to the YUV list
'imx8-isi' pipeline provides support for 'YUV444' PixelFormat with YUV
streams, but it cannot be played with gstreamer adapter whereas
gstreamer's video format 'Y444' value suggests that it also supports
this format.

To add support of Planar 4:4:4 YUV format in gstreamer adapter, this patch
maps 'Y444' gstreamer video format with 'YUV444' libcamera PixelFormat.

Then below command example can be used to capture a stream with imx8-isi
pipeline:

  gst-launch-1.0 \
      libcamerasrc camera-name=<your_camera_name> ! \
      video/x-raw, format=Y444, width=1280, height=800 ! \
      queue ! \
      filesink location=/tmp/output

Signed-off-by: Antoine Bouyer <antoine.bouyer@nxp.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-19 08:59:47 +00:00
Jacopo Mondi
39419ce431 Revert "README.rst: Report py dependencies"
This reverts commit 36753f5cbb.

Commit 36753f5cbb ("README.rst: Report py dependencies")
duplicated the entries for the Python bindings dependencies,
and does not list libpython3-dev which is still a requirement.

Revert it.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-03-04 18:02:14 +01:00
Laurent Pinchart
5e6872740d libcamera: base: signal: Drop pre-C++17 support
The libcamera public API requires C++17, drop support for older
standards.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-03 14:53:35 +02:00
Laurent Pinchart
bb1d216113 libcamera: base: log: Fix uninitialized variable warning
gcc 13.3.0, cross-compiling from amd64 to arm64, warns about a possibly
uninitialized variable in Logger::parseLogLevel():

src/libcamera/base/log.cpp: In static member function ‘static libcamera::LogSeverity libcamera::Logger::parseLogLevel(std::string_view)’:
../../src/libcamera/base/log.cpp:694:55: error: ‘severity’ may be used uninitialized [-Werror=maybe-uninitialized]
  694 |                 if (ec != std::errc() || *end != '\0' || severity > LogFatal)
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
src/libcamera/base/log.cpp:690:22: note: ‘severity’ was declared here
  690 |         unsigned int severity;
      |                      ^~~~~~~~

This appears to be a false positive, as the std::from_chars() function
should set severity value when it returns without an error. Still, the
warning is easy to solve, so fix it by initializing the severity
variable.

Fixes: 8fa119e0b5 ("libcamera: base: log: Use `std::from_chars()`")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-03 14:52:59 +02:00
Milan Zamazal
c0a58b9798 utils: ipc: Only dispatch messages for proxy when stopping thread
When stopping the proxy thread, all messages of InvokeMessage type
posted to the pipeline handler thread are dispatched, to ensure that all
signals emitted from the proxy thread and queued for delivery to the
proxy are delivered synchronously. This unnecessarily delivers queued
signals for other objects in the pipeline handler thread, possibly
delaying processing of higher priority events.

Improve the implementation by limiting synchronous delivery to messages
posted for the proxy.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-01 23:10:05 +00:00
Milan Zamazal
86ffaf936d libcamera: software_isp: Dispatch messages on stop
There may be pending messages in SoftwareIsp message queue when
SoftwareIsp stops.  The call to IPAProxySoft::stop() will dispatch them
before SoftwareIsp::stop() finishes.  But this is dependent on
IPAProxySoft::stop() implementation, let's break this dependency and
dispatch messages to SoftwareIsp explicitly in SoftwareIsp::stop().

This also allows dropping `running_' flag.  Since the SoftwareIsp
messages get processed and invoke IPA calls before the IPA proxy is set
to ProxyStopping state and the SoftwareIsp worker thread is no longer
running, it's guaranteed that no new messages come to SoftwareIsp and
attempt to call the stopped IPA proxy.

Signed-off-by: Milan Zamazal <mzamazal@redhat.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-03-01 23:10:05 +00:00
Milan Zamazal
72a890e11a libcamera: base: thread: Support dispatching for a specific receiver
The Thread::dispatchMessage() function supports filtering messages based
on their type. It can be useful to also dispatch only messages posted
for a specific receiver. Add an optional receiver argument to the
dispatchMessage() function to do so. When set to null (the default
value), the behaviour of the function is not changed.

This facility is actually used in followup patches.

Signed-off-by: Milan Zamazal <mzamazal@redhat.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-03-01 23:10:05 +00:00
Milan Zamazal
cd32e069ec libcamera: software_isp: Handle queued input buffers on stop
When SoftwareIsp stops, input and output buffers queued to it may not
yet be fully processed.  They will be eventually returned but stop means
stop, there should be no processing related actions invoked afterwards.

Let's stop forwarding processed input buffers from SoftwareIsp slots
when SoftwareIsp is stopped.  Let's track the queued input buffers and
return them back for capture in SoftwareIsp::stop().

The returned input buffers are marked as cancelled.  This is not
necessary at the moment but it gives the pipeline handlers chance to
deal with this if they need to.

Signed-off-by: Milan Zamazal <mzamazal@redhat.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-03-01 23:09:56 +00:00
Milan Zamazal
ba4715ffed libcamera: software_isp: Handle queued output buffers on stop
When SoftwareIsp stops, input and output buffers queued to it may not
yet be fully processed.  They will be eventually returned but stop means
stop, there should be no processing related actions invoked afterwards.

Let's stop forwarding processed output buffers from the SoftwareIsp
slots once SoftwareIsp is stopped.  Let's track the queued output
buffers and mark those still pending as cancelled in SoftwareIsp::stop
and return them to the pipeline handler.

Dealing with input buffers is addressed in a separate patch.

Signed-off-by: Milan Zamazal <mzamazal@redhat.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-03-01 23:07:15 +00:00
Milan Zamazal
b72d789475 libcamera: software_isp: Emit ispStatsReady only if IPA is running
Software ISP runs debayering in a separate thread and debayering may
emit statsReady when software ISP (including the IPA) is being stopped.
The signal waits in a queue and gets invoked later, resulting in an
assertion error when attempting to invoke a method on the stopped IPA:

  FATAL default soft_ipa_proxy.cpp:456 assertion
  "state_ == ProxyRunning" failed in processStatsThread()

Let's prevent this problem by forwarding the ISP stats signal from
software ISP only when the IPA is running.  To track this,
SoftwareISP::running_ variable is introduced.

Making processing of the other signals in SoftwareISP more robust is
addressed in the followup patches.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reported-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.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-03-01 23:06:12 +00:00
Dylan Aïssi
1ea124c7a3 libcamera: meson: Fix libyuv detection
We already fall back to a subproject to support the libyuv package when
it can not be discovered through the usual dependency() mechanism.

Unfortunately libyuv may be packaged without any corresponding
pkg-config support as can be seen at [0], so further extend the
dependency search by using an explicit cxx.find_library() call.

[0] https://packages.debian.org/bookworm/amd64/libyuv-dev/filelist

Signed-off-by: Dylan Aïssi <dylan.aissi@collabora.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-03-01 22:36:24 +00:00
Stefan Klug
eb550486c7 ipa: libipa: Fix bug in ExposureModeHelper that leads to oscillations in AEGC
The ExposureModeHelper::splitExposures() runs through the configured
stages to find the best gain/exposure time pair. It first raises the
exposure time until it reaches the limit of the current stage. Then it
raises the gain until that also reaches the limit of the current stage.
After that it continues with the next stage until a match is found.

Due to a slight mistake in the initial code, the second step doesn't
work as expected because the exposure time gets divided by the gain of
the current stage, effectively leading to a jump of the gain value from
the maximum gain of the last stage to the maximum gain of the current
stage instead of gradually increasing the gain value.

Depending on the tuning file this leads to very visible oscillations and
jumps in the brightness.

Fix by clamping the exposure time in the second step to the maximum
exposure time of the current stage.

While at it, add two comments for easier understanding.

Fixes: 34c9ab6282 ("ipa: libipa: Add ExposureModeHelper")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-28 10:00:51 +01:00
Stefan Klug
d748bdc66d ipa: rkisp1: Allow exposure time to be shorter than minimum frame duration limit
The minimum FrameDurationLimit also limits the min exposure time and
results in overly bright AE regulation. Remove the limit on the minimum
exposure time as the vertical blanking ensures the minimum frame
duration limit.

Fixes: f72c76eb6e ("rkisp1: Honor the FrameDurationLimits control")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 20:59:56 +01:00
Barnabás Pőcze
74c0e8cbf1 apps: lc-compliance: Merge CaptureBalanced and CaptureUnbalanced
The above two classes have very similar implementations, in fact, the
only essential difference is how many requests are queued. `CaptureBalanced`
queues a predetermined number of requests, while `CaptureUnbalanced`
queues requests without limit.

This can be addressed by introducing a "capture" and a "queue" limit
into the `Capture` class, which determine at most how many requests
can be queued, and how many request completions are expected before
stopping.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 17:31:04 +01:00
Barnabás Pőcze
995bb7e507 apps: lc-compliance: Add message to GTEST_SKIP()
Just like other gtest macros, `GTEST_SKIP()` returns an object
to which a formatted message can be added using the usual `<<`
stream operator. So use it instead of printing to `std::cout`.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-27 17:31:04 +01:00
Barnabás Pőcze
6fd3ac82b5 apps: lc-compliance: Use array instead of std::vector
There is no reason to use `std::vector` for this static data,
a simple array will do fine.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-27 17:31:04 +01:00
Barnabás Pőcze
5c3eb98374 apps: lc-compliance: Use std::vector for argument array
Just use an `std::vector` to store the arguments passed to
`InitGoogleTest()`. This removes the need for the map and
the separate `argc` variable used for size-keeping.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-02-27 17:31:04 +01:00
Barnabás Pőcze
1f02966f3f apps: lc-compliance: Don't allocate FrameBufferAllocator dynamically
There is no reason to do so.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-27 17:31:04 +01:00
Barnabás Pőcze
d8645b5f67 apps: lc-compliance: Remove redundant getter call
Smart pointers overload `operator->()`, no reason to use `get()`.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-27 17:31:04 +01:00
Barnabás Pőcze
d338fe9336 apps: lc-compliance: Optimize std::shared_ptr usage
Avoid unnecessary copies and try to move construct `std::shared_ptr`
whenever possible.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-27 17:31:04 +01:00
Barnabás Pőcze
6719ae34cc apps: lc-compliance: Put tests into anonymous namespace
There is no reason for these symbols to be global.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-27 17:31:04 +01:00
Barnabás Pőcze
8c6d0106d0 apps: lc-compliance: Initialize CameraManager pointer in Environment
Do not leave it unitialized.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-27 17:31:04 +01:00
Barnabás Pőcze
3939c316f0 apps: common: event_loop: Remove unused type alias
The type alias `duration` is not used anywhere, so remove it.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 17:29:28 +01:00
Barnabás Pőcze
234eb60546 apps: common: event_loop: Use single event source for deferred calls
Instead of calling `event_base_once()` every time a deferred call
is added to the loop, create an event source at construction, and
simply trigger that when a new deferred call is scheduled.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 17:29:28 +01:00
Barnabás Pőcze
54055dd0c2 apps: common: event_loop: Use std::deque instead of std::list
Deque has fast pop_front and push_back operations while making
fewer allocations for the same number of elements as an `std::list`.
So use an `std::deque` for storing the deferred calls of the loop.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-27 17:29:28 +01:00
Barnabás Pőcze
a0f4092c6c apps: common: event_loop: Disable copy/move
The compiler generated functions are not appropriate, so
delete the copy/move constructor/assignment to avoid
potential issues.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 17:29:28 +01:00
Barnabás Pőcze
b1b99f4d66 apps: common: event_loop: Take callbacks by rvalue ref
Using a const lvalue reference to `std::function<>` is not ideal
because it forces a copy to happen. Use an rvalue reference and
`std::move()` to avoid that.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-27 17:29:28 +01:00
Barnabás Pőcze
0fc00eacdb libcamera: base: log: Avoid manual LogCategory deletion
Wrap the `LogCategory` pointers in `std::unique_ptr` to avoid
the need for manual deletion in the destructor.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 11:30:23 +01:00
Barnabás Pőcze
9ac914c634 libcamera: base: log: Protect log categories with lock
Log categories may be added from any thread, so it is important to
synchronize access to the `Logger::categories_` list between its two
users: category creation (by LogCategory::create(), which calls
Logger::findCategory() and Logger::registerCategory()); and log level
setting (by Logger::logSetLevel()).

The LogCategory::create() function uses a mutex to serialize category
creation, but Logger::logSetLevel() can access `Logger::categories_`
concurrently without any protection. To fix the issue, move the mutex to
the Logger class, and use it to protect all accesses to the categories
list. This requires moving all the logic of LogCategory::create() to a
new Logger::findOrCreateCategory() function that combines both
Logger::findCategory() and Logger::registerCategory() in order to make
the two operations exacute atomically.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-02-27 11:30:23 +01:00
Barnabás Pőcze
aca8457d34 libcamera: base: log: Pass dynamic prefix through
Use move construction to essentially pass through the string
returned by `Loggable::logPrefix()` to avoid an unnecessary copy.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 11:30:23 +01:00
Barnabás Pőcze
24c2caa1c1 libcamera: base: log: Use std::string_view to avoid some copies
Use `std::string_view` to avoid some largely unnecessary copies, and
to make string comparisong potentially faster by eliminating repeated
`strlen()` calls.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 11:30:23 +01:00
Barnabás Pőcze
16bcc5a3e4 libcamera: base: log: Make LogCategory::severity_ atomic
The severity of a log category may be changed from a different thread,
so it is important to ensure that the reads and writes happen atomically.
Using `std::memory_order_relaxed` should not introduce any synchronization
overhead, it should only guarantee that the operation itself is atomic.

Secondly, inline `LogCategory::setSeverity()`, as it is merely an
assignment, so going through a DSO call is a big pessimization.
`LogCategory` is not part of the public API, so this change has
no external effects.

Thirdly, assert that the atomic variable is lock free so as to ensure
it won't silently fall back to libatomic (or similar) on any platform.
If this assertion fails, this needs to be revisited.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 11:30:23 +01:00
Barnabás Pőcze
5d0af9840b libcamera: base: log: Remove LogMessage::init()
It is a short function that can be merged into the constructor with
essentially no change in observable behaviour, so do that.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 11:30:23 +01:00
Barnabás Pőcze
8fa119e0b5 libcamera: base: log: Use std::from_chars()
Use the `std::from_chars()` function from `<charconv>` to
parse the integral log level instead of `strtoul` as it
provides an easier to use interface and better type safety.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 11:30:23 +01:00
Barnabás Pőcze
d40250e03b libcamera: base: log: Remove move constructor
C++17 guarantees move and copy elision in certain cases,
such as when returning a prvalue of the same type as the
return type of the function.

This is what the `_log()` functions do, thus there is no need
for the move constructor, so remove it. Furthermore, do not
just remove the implementation, but instead delete it as well.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-02-27 11:30:23 +01:00
Paul Elder
f72c76eb6e rkisp1: Honor the FrameDurationLimits control
Add support to rkisp1 for controlling the framerate via the
FrameDurationLimits control.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-02-26 15:07:44 +09:00
Kieran Bingham
2abfcac1c3 ipa: rkisp1: Alias lineDuration
The configured line duration of the sensor is used frequently throughout
the AGC implementation.

It's available in the IPA context through the rather long:
  context.configuration.sensor.lineDuration

Take a copy of the lineDuration early in the call and replace the two
current usages of the reference with the shorter copy to manage line
length and ease readibility.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-26 15:07:44 +09:00
Kieran Bingham
443ac36e12 ipa: rkisp1: Initialise AGC from FrameDurationLimits controls
The IPA calculates and reports the FrameDurationLimits to applications
by configuring the ControlInfo accordingly during
IPARkISP1::updateControls()

We later need to know these limits during Agc::configure() for
initialising the ActiveState of the AGC implementation with the limits.

Store the FrameDurationLimits ControlInfo in the ControlInfoMap which is
now present in the IPAContext so that it is commonly available for the
AGC algorithm, removing the 'todo' accordingly.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-26 15:07:43 +09:00
Milan Zamazal
33ce463a46 libcamera: formatting: Avoid spaces in for loops without expression
The clang formatter removes spaces in places of empty expressions in for
loops.  For example, it changes

  for (init; condition; )

to

  for (init; condition;)

libcamera currently uses both the styles and we should use only one of
them for consistency.  Since there is apparently no option to override
the formatter behavior (see
https://clang.llvm.org/docs/ClangFormatStyleOptions.html), let's remove
the extra spaces to make the formatter happy.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-02-26 02:27:18 +02:00
Laurent Pinchart
4849a84a9b meson: Enable the -Wnon-virtual-dtor compiler option
A base class with virtual functions and a non-virtual public destructor
is prone to undefined behaviourif deleted from a pointer to the base.
Enable the -Wnon-virtual-dtor warning to report those issues.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-26 02:27:16 +02:00
Laurent Pinchart
005d19a73f libipa: awb: Fix non-virtual destructor warning in AwbStats
The AwbStats structure has virtual functions but a publicly accessible
non-virtual destructors. This can cause undefined behaviour if deleting
a derived class instance through a pointer to the base AwbStats class.

The problem is theoretical only as no code in libcamera is expected to
perform such deletion, but compilers can't know that and will emit a
warning if the -Wnon-virtual-dtor option is enabled.

Fixing this can be done by declaring a virtual public destructor in the
AwbStats class. A more efficient alternative is to declare a protected
non-virtual destructor, ensuring that instances can't be deleted through
a pointer to the base class. Do so, and mark the derived RkISP1AwbStats
as final to avoid the same warning.

Fixes: 6f663990a0 ("libipa: Add AWB algorithm base class")
Reported-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com>
2025-02-26 02:27:09 +02:00
Stefan Klug
d4545edb38 ipa: rkisp1: algorithms: awb: Fix AWB means vector order in RGB mode
Fix the order of the rgbMeans vector that got broken accidentally
during refactoring.  As there is currently no way to enable rgb mode at
runtime it went unnoticed.

Fixes: 29892f1c56 ("ipa: libipa: colour: Use the RGB class to model RGB values")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-02-24 23:26:08 +02:00
Laurent Pinchart
25dcdf2998 libcamera: Drop spurious colon after doxygen \todo directive
The doxygen \todo directive doesn't need to be followed by a colon. Drop
it. While at it, turn one 'todo:' into '\todo'.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:36:21 +02:00
Laurent Pinchart
7222171340 ipa: rkisp1: awb: Capitalize AWB
AWB is an abbreviation, capitalize it in comments and log messages for
consistency.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:36:19 +02:00
Laurent Pinchart
1bb4d3712d ipa: rkisp1: awb: Don't calculate RGB means if stats are missing
When statistics are missing we can't meaningfully calculate the RGB
means. Move their calculation after checking if stats are available.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:36:15 +02:00
Laurent Pinchart
127bc20965 libipa: awb_grey: Minor comment fixes
Fix the top-level file description to mention the file contains an AWB
grey world implementation, not a base class, and fix a grammar mistake
in a documentation block.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:22:41 +02:00
Laurent Pinchart
643af7f2e7 libipa: awb: Tidy up includes
Drop unneeded headers and add missing ones.

The yaml_parser.h header is dropped from awb_grey.h as the classes it
provides are only used in virtual functions defined by the base class,
so any required definitions are guaranteed to be available already.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:22:39 +02:00
Laurent Pinchart
afd87c342c libipa: awb: Rename AwbStats::getRGBMeans() to rgbMeans()
The convention in libcamera is not to prefix getters with a 'get'
prefix. Rename the AwbStats::getRGBMeans() function accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:22:38 +02:00
Laurent Pinchart
080cb47e9f ipa: rkisp1: awb: Fix wrong indentation in comment
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:22:36 +02:00
Laurent Pinchart
6981a5169b libipa: awb: Pass lux value to calculateAwb() as unsigned int
The lux value can never be negative. Pass it as an unsigned int.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:22:30 +02:00
Laurent Pinchart
1a948d5457 libipa: awb: Replace reference to pipeline handle with IPA module
The AwbStats documentation incorrectly references pipeline handlers when
it means IPA modules. Fix it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:22:29 +02:00
Laurent Pinchart
ef5a162b34 libipa: awb: Standardize spelling on 'grey' world
All locations but one spell 'grey' instead of 'gray'. Fix the outlier.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:22:27 +02:00
Laurent Pinchart
7115b81310 libipa: awb: Follow function names with '()' in doxygen documentation
Function names are followed by parentheses in doxygen documentation
blocks as convention in libcamera. Add missing parentheses in the
AwbAlgorithm documentation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:22:25 +02:00
Laurent Pinchart
704a3aa5d0 libipa: awb: Capitalize AWB
AWB is an abbreviation, capitalize it in comments and log messages for
consistency.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:22:22 +02:00
Laurent Pinchart
7199a0c39d libipa: awb: Sort class member documentation according to header order
Sort the documentation of the class members in the same order as the
member declaration in the class definition, as is customary in
libcamera.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-24 18:22:18 +02:00
Stefan Klug
d476f8358b libipa: awb_bayes: Change the probabilities from log space to linear space
The original code used to specify the probabilities in log space and
scaled for the RaspberryPi hardware with 192 AWB measurement points.
This is reasonable as the whole algorithm makes use of unitless numbers
to prefer some colour temperatures based on a lux level. These numbers
are then hand tuned with the specific device in mind.

This has two shortcomings:

1. The linear interpolation of PWLs in log space is mathematically
   incorrect. The outcome might still be ok, as both spaces (log and
linear) are monotonic, but it is still not "right".

2. Having unitless numbers gets more error prone when we try to
   harmonize the behavior over multiple platforms.

Change the algorithm to interpret the numbers as being in linear space.
This makes the interpolation mathematically correct at the expense of a
few log operations.

To account for that change, update the numbers in the tuning example
file with the linear counterparts scaled to one AWB zone measurement.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:51:10 +01:00
Stefan Klug
d98f3512ec libipa: awb_bayes: Remove overly verbose log messages
Logging every search step is too verbose even with debug messages
enabled and it hides the more important messages (min max values of
errors and likelihoods). Remove the debug messages in a separate commit,
so that it can easily be reverted if needed.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:51:10 +01:00
Stefan Klug
c2059585f3 libipa: awb_bayes: Add logging of value limits
When tuning the AWB algorithm it is more helpful to get a feeling for
the value ranges than to get verbose output of every single step. Add a
small utility class to track the limits and log them.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:51:10 +01:00
Stefan Klug
ce9d547aff libipa: lux: Normalize referenceY to 1
By normalizing the referenceY value to 1 (which is the usual range for
Y) in the tuning file, the bins_ value is no longer needed. Remove it.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:51:10 +01:00
Stefan Klug
92bb16b68e utils: tuning: rkisp1: Add lux module
Now that the lux module is available, add it to the rkisp1 tuner.

While at it, sort the imports correctly.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:51:10 +01:00
Stefan Klug
a783a90dec libtuning: Add module for lux calibration
For the lux algorithm, reference values get calculated based on a tuning
image taken at a known lux level. The reference data contains the mean Y
of the image, lux level, exposure time, gain and aperture. This module
calculates these values for insertion into the tuning file.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:51:09 +01:00
Stefan Klug
bab4db2d6d ipa: rkisp1: awb: Apply gains based on default colour temperature on start
The colour gains are initialized with a default value of 1. Improve that
by querying the auto white balance algorithm for the gains for a default
colour temperature. This is still not based on measurements, but it is
still better than the current implementation. If the algorithm doesn't
implement mapping from colour temperature to gains, it will internally
fallback to 1.0.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:51:09 +01:00
Stefan Klug
7a4012ec79 ipa: rkisp1: Add support for bayes AWB algorithm from libipa
Now that libipa contains a bayes AWB algorithm, add it as supported
algorithm to the rkisp1 ipa.

The decision between the grey world algorithm and the bayesian is done
based on the "algorithm" property of the "Awb" algorithm in the tuning
file. If the lux value in the frameContext is set by the Lux algorithm
it is taken into account. If the lux value is 0 the prior likelihood
estimation gets ignored in the AWB calculations.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:51:09 +01:00
Stefan Klug
f45eb6bd9d libipa: Add bayesian AWB algorithm
The bayesian AWB algorithm is an AWB algorithm that takes prior
probabilities for a given light source dependent on the current lux
level into account.

The biggest improvement compared to the grey world model comes from the
search of the ideal white point on the CT curve. The algorithm walks the
CT curve to minimize the colour error for a given statistics. After the
minimium is found it additionally tries to search the area around that
spot and also off the curve. So even without defined prior probabilities
this algorithm provides much better results than the grey world
algorithm.

The logic for this code was taken from the RaspberryPi implementation.
The logic was only minimally adjusted for usage with the rkisp1 and a
few things were left out (see doxygen doc for the AwbBayes class). The
code is refactored to better fit the libcamera code style and to make
use of the syntactic sugar provided by the Interpolator and Vector
classes.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:51:09 +01:00
Stefan Klug
60d60c1367 libtuning: module: awb: Add bayes AWB support
To support the bayesian AWB algorithm in libtuning, the necessary data
needs to be collected and written to the tuning file.

Extend libtuning to calculate and output that additional data.

Prior probabilities and AwbModes are manually specified and not
calculated in the tuning process. Add sample values from the RaspberryPi
tuning files to the example config file.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-02-21 17:35:03 +01:00
Stefan Klug
deb3f05137 ipa: rkisp1: Use grey world algorithm from libipa
Now that libipa contains a grey world algorithm, use that.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:35:03 +01:00
Stefan Klug
b60bd37b1a ipa: rkisp1: Move calculation of RGB means into own function
Move the calculation of the RGB means into an own function for better
code clarity. This commit doesn't contain any functional changes.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:35:03 +01:00
Stefan Klug
7ea83d5f7b libipa: Add grey world AWB algorithm
Add the grey world algorithm that is currently used in rkisp1 to libipa.
No changes in functionality were made.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-21 17:35:03 +01:00
Stefan Klug
d19ae2a228 libipa: awb: Add helper functions for AWB mode support
The AWB modes are specified in the libcamera core controls. It is
therefore quite likely that every AWB algorithm will implement them. Add
helper functions for parsing and storing the configured modes in the
AwbAlgorithm base class.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:35:03 +01:00
Stefan Klug
6f663990a0 libipa: Add AWB algorithm base class
Add a class to provide a generic interface for auto white balance
algorithms. Concrete AWB algorithms are expected to subclass the
AwbAlgorithm class to implement their functionality.

IPAs are expected to subclass the AwbStats class and implement the
necessary functions to give the algorithm access to the hardware
specific statistics data.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-21 17:35:03 +01:00
Stefan Klug
3acacb089d libipa: pwl: Add clear() function
Sometimes it is necessary to clear a pwl. Add a function for that.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:35:03 +01:00
Stefan Klug
3c653f3f65 libipa: interpolator: Add accessor to internal data
The only way to access the internal data of an Interpolator is through
the getInterpolated() method. Sometimes it is necessary to to access the
internal data directly to iterate over it. Add an accessor for that.

While at it, remove a line break from the doxygen documentation for
interpolate() so that doxygen is able to correctly match the function.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-21 17:35:02 +01:00
Stefan Klug
a7d7bc03e5 libcamera: pipeline: Fix LIBCAMERA_<NAME>_TUNING_FILE handling
In f5da05ed03 ("libcamera: pipeline: Move tuning file override
handling to IPAProxy") a incorrect comparison slipped through. That
broke the handling of LIBCAMERA_<NAME>_TUNING_FILE. Fix that.

Fixes: f5da05ed03 ("libcamera: pipeline: Move tuning file override handling to IPAProxy")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-02-21 17:34:12 +01:00
Barnabás Pőcze
32cc6717d2 libcamera: request: addBuffer(): Do fence check earlier
Check if the buffer has a fence before making any modifications because
otherwise it is possible for `Request::addBuffer()` to return an error code
while at the same time the buffer - for all intents and purposes - is added
to the request.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
2025-02-17 18:16:41 +01:00
Nerijus Bendžiūnas
892e85e4e3 gstreamer: Fix scaler-crop property get
Fix a copy/paste/replace typo. Without this fix, the last element (4th)
is always zero.

Signed-off-by: Nerijus Bendžiūnas <nerijus.bendziunas@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-02-17 18:59:22 +02:00
Laurent Pinchart
9834402f81 ipa: rkisp1: algorithms: agc: Fix whitespace
Drop trailing whitespace introduced by mistake.

Fixes: 0e0e32b189 ("ipa: rkisp1: algorithms: agc: Check for correct stats type")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-02-13 21:39:41 +02:00
Naushir Patuck
2e8b6fd217 ipa: rpi: Fix incorrect cast for ExposureTime ControlInfo
controls::ExposureTime is of type ControlTypeInteger32, but the
default ControlInfoMap casts a value to int64_t causing incorrect
initialisation of the associated ControlInfo.

Fix this by casting correctly to int32_t.

Fixes: bea2db5e61 ("ipa: rpi: Apply default ControlInfo values for sensor controls")
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-02-13 10:41:45 +00:00
Stefan Klug
fa93d40035 libipa: Drop Vector class
The Vector class from libipa is not used anymore. Drop it.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-02-12 14:26:27 +01:00
Stefan Klug
82cf918b5b ipa: Use Vector class from libcamera
Now that there is a Vector class in libcamera, use that one.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2025-02-12 14:26:27 +01:00
Stefan Klug
cfd94e5f85 libcamera: Adapt Vector class to new location
Change the namespace of the Vector class from libipa to libcamera and
add it to the build.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-02-12 14:26:27 +01:00
Stefan Klug
e506b45822 libcamera: Copy Vector class files from libipa
Prepare the move of the Vector class from libipa to libcamera by copying
the relevant files into the corresponding libcamera directories. The
files are copied without modification.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-02-12 14:26:27 +01:00
Naushir Patuck
bea2db5e61 ipa: rpi: Apply default ControlInfo values for sensor controls
The existing IPA initialisation code did not set default values for
some sensor related controls. This caused a crash using libcamerify
when the it was trying to access the default value for
controls::FrameDurationLimits as part of a recent change.

Ensure controls::FrameDurationLimits, controls::AnalogueGain and
controls::ExposureTime advertise default values along with the existing
min/max values. The default is set to the defaults defined in the IPA
set during initialisation.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=253
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-02-12 10:34:28 +00:00
Stefan Klug
f63f4d71d4 ipa: rkisp1: agc: Fix build on debian 11 (gcc-9)
In the CI on debian 11 (gcc 9.3.0 and gcc 10.2.1) compilation fails
because the compiler incorrectly selects the

explicit ControlInfo(std::set<bool> values, bool def)

version of the ControlInfo constructor. This behavior was not
reproducible using gcc 9.5.0 and 10.5.0. So it seems newer versions of
gcc already contain a fix. Fix the CI build by explicitly passing a
ControlValue as second argument to the constructor.

Fixes: ee918b370a ("ipa: rkisp1: agc: Initialize enum controls with a list of values")
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>
2025-02-11 23:08:38 +01:00
Stefan Klug
ee918b370a ipa: rkisp1: agc: Initialize enum controls with a list of values
The controls ExposureTimeMode and AnalogueGainMode are shown in camshark
as normal int entries instead of enum popups. The reason is that
ControlInfos for these controls are constructed using min/max instead of
a list of valid ControlValues. Camshark (and cam) uses the values()
vector to deduce if the control is an enum or not. It might be debatable
if this is the correct check, but all other ControlInfos for enum
controls in libcamera are initialized using a list.

Modify the construction of the ControlInfos to use the Span based
constructor to fix that issue.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-11 13:20:28 +01:00
Stefan Klug
9b1f609e5b libcamera: log: Match whole category in LIBCAMERA_LOG_LEVELS
A LIBCAMERA_LOG_LEVELS value of "RkISP1:0" also applies to RkISP1Ccm and
RkISP1Awb. This behavior is unexpected as it automatically enables all
algorithm log categories when the intent is only to increase the log
level of the upper category. Fix that replacing the manual matching code
with fnmatch. This has the side effect that more wildcards ("?" and
"[...]") are supported which is acceptable but won't be advertised.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-02-06 15:25:52 +01:00
Laurent Pinchart
7e5d811842 libcamera: matrix: Add read-only accessor to internal data
Add a data() function to the Matrix class to access the internal data.
This is useful for code that needs to use the matrix contents as a
linear array, as shown by the RkISP1::Ccm::process() function that needs
to copy the matrix data to a local variable. Simplify that function by
using the new accessor.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2025-02-04 21:27:54 +02:00
Barnabás Pőcze
7fdfe648a4 libcamera: pipeline: virtual: Set FrameError on error
Do not cancel, simply set the buffer's status to `FrameError`
to notify the user about the error condition.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-04 18:32:23 +01:00
Barnabás Pőcze
98cf9eb533 libcamera: pipeline: virtual: Fill buffer's metadata
Fill the `FrameMetadata` object of the `FrameBuffer`s because it
should not be left uninitialized as users expect to be able to
access it and find reasonable data there.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=245
Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-04 18:32:23 +01:00
Barnabás Pőcze
9c29274382 libcamera: pipeline: virtual: Simplify error return
Just return an `std::unique_ptr` constructed from an empty
initializer instead of doing a `reset()` on the existing
`config` variable and returning that. This is simpler.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-04 18:32:23 +01:00
Barnabás Pőcze
9a7fce1b51 libcamera: base: object,thread: Disable copy/move
Objects of type `Object` and `Thread` have address identities, so they
should not be just moved/copied. And the special member functions
generated by the compiler do not do the right thing. So delete them.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-02-04 18:18:50 +01:00
Barnabás Pőcze
2ae569dad2 Documentation: guides: application-developer: Fix variable shadowing
The mentioned commit mistakenly introduced a new variable for storing
the camera instead of just assigining to the global variable defined
earlier in the tutorial. Fix that by making it an assignment.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=252
Fixes: e77a275110 ("treewide: Query list of cameras just once")
Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-02-04 17:53:50 +01:00
Milan Zamazal
9bc8b6a573 libcamera: software_isp: Handle signals in the proper thread
inputBufferReady ready signal in the simple pipeline is handled in the
pipeline handler thread.  outputBufferReady and ispStatsReady signals
should be handled there too.

Rather than relying on the user of the SoftwareIsp instance, let
SoftwareIsp inherits Object.  SoftwareIsp serves as a signal proxy, the
signals above are emitted from signal handlers.  This means that if
SoftwareIsp inherits Object then the slots are invoked in SoftwareIsp
thread.  Which is the camera manager thread because the SoftwareIsp
instance is created there.

Signed-off-by: Milan Zamazal <mzamazal@redhat.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-02-01 10:09:46 +00:00
Milan Zamazal
8aef7b4dfb apps: ppm_writer: Return EIO on I/O errors
EINVAL should be returned only when the requested format is unsupported.
On errors when writing the data, let's return EIO, which is the closest
description of the situation when we don't inspect it more.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-27 00:06:11 +02:00
Milan Zamazal
8072518ca9 apps: ppm_writer: Add a missing include
<errno.h> should be included in the ppm writer, as the source of the
error code constants used there.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-27 00:05:56 +02:00
Milan Zamazal
818b737146 libcamera: software_isp: Move a non-loop condition out of the loop
The check for the number of outputs is done in a loop over the outputs.
It should be moved out of the loop as it's not loop specific and is just
repeated there.

This is a cosmetic change not changing any functionality.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-27 00:05:32 +02:00
Laurent Pinchart
f5da05ed03 libcamera: pipeline: Move tuning file override handling to IPAProxy
The rkisp1 and rpi pipeline handlers duplicate code to handle the
LIBCAMERA_RKISP1_TUNING_FILE and LIBCAMERA_RPI_TUNING_FILE environment
variables that override tuning file selection. Move the common code to
IPAProxy::configurationFile() to avoid the duplication, and make the
feature available to all pipeline handlers with the same behaviour.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-01-24 22:41:36 +02:00
Laurent Pinchart
3e753e2273 ipa: libipa: lux: Fix indentation
Indentation in a doxygen comment is wrong, fix it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-01-24 22:07:17 +02:00
Paul Elder
fdc01dc3e0 ipa: raspberry: Report new AeEnable control as available
Even though the new AeEnable control internally switches on and off the
sub-controls (ExposureTimeMode and AnalogueGainMode), it still needs to
be declared as available. Report this control as available in the
rpi IPA.

Support for the control does not need to be added as it is handled by
the Camera class. It does not need to be handled in metadata either as
the new version of AeEnable is not returned in metadata.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 21:36:41 +02:00
Paul Elder
338ba00e7a ipa: rkisp1: agc: Report new AeEnable control as available
Even though the new AeEnable control internally switches on and off the
sub-controls (ExposureTimeMode and AnalogueGainMode), it still needs to
be declared as available. Report this control as available in the
rkisp1 IPA.

Support for the control does not need to be added as it is handled by
the Camera class. It does not need to be handled in metadata either as
the new version of AeEnable is not returned in metadata.

Signed-off-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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 21:36:40 +02:00
Paul Elder
7abd413905 libcamera: camera: Pre-process AeEnable control
Handle the AeEnable under the hood in the Camera class, such that
AeEnable activates ExposureTimeMode and AnalogueGain together. This
allows applications the convenience of setting auto/manual mode of all
of the AE-related controls, as well as protecting applications against a
nasty behavior change if an aperture control is added in the future.
This also moves common handling code out of the IPA.

While we also want to inject AeEnable in Camera::controls() so that IPAs
don't have to report it, it is technically difficult at the moment as
ControlInfoMaps are not easily modifiable.

Signed-off-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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 21:36:40 +02:00
Paul Elder
85cb179f28 controls: Redefine AeEnable
In the redesign of the AE-related controls, the AeEnable control was
intended to be removed in favor of more specific sub-controls for
analogue gain and exposure time. However this will cause problems if
aperture sub-controls are introduced, and an application from a
pre-aperture era uses a camera that supports aperture.

If there is no AeEnable control, then a pre-aperture era application
might set analogue gain and exposure time to manual, while aperture
silently stays auto since that's the default mode. Thus aperture would
be uncontrollable by the application.

With an AeEnable control, then a pre-aperture era application can set
AeEnable to manual, and under the hood all three of analogue gain and
exposure time and aperture will be set to manual. The application won't
be able to set the manual aperture, however.

Although the above scenario is expected to be rare, the scenario with an
AeEnable control seems less detrimental. With an AeEnable control at
least the aperture would be static at a reasonably usable value, whereas
without an AeEnable the aperture would be more-or-less uncontrolable and
could go to extreme values as the AEGC algorithm tries to compensate for
the manual analogue gain and exposure time values.

Thus we redefine the AeEnable control, available only as a control and
not in metadata. It will be preprocessed by the Camera class so that the
relevant sub-controls are set. No pipline handler nor IPA shall act on
the AeEnable control. The IPA still has to report the control as
available, however.

Signed-off-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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 21:36:40 +02:00
Jacopo Mondi
a533bd004b controls: Remove AeLocked
Now that the codebase has been ported to use the new AEGC controls
remove the definition of AeLocked. AeEnable is not be removed as it will
be redefined.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 21:36:40 +02:00
Paul Elder
187f2d537b gstreamer: Generate the new AEGC controls
Since AeEnable will be replaced with ExposureTimeMode and
AnalogueGainMode so that the two can be set between auto/manual
independently, update the gstreamer control ids generation to conform
with this.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Nicolas Nicolas <nicolas.dufresne@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 21:36:40 +02:00
Paul Elder
3d23f325fd ipa: rkisp1: Port to the new AEGC controls
The newly introduced controls to drive the AEGC algorithm allow
controlling the computation of the exposure time and analogue gain
separately.

Augument the RkISP1 AEGC implementation to handle the exposure and gain
controls separately using the new controls.

Signed-off-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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 21:36:40 +02:00
Jacopo Mondi
c45a2682c3 ipa: raspberry: Port to the new AEGC controls
The newly introduced controls to drive the AEGC algorithm allow to
control the computation of the exposure time and analogue gain
separately.

The RPi AEGC implementation already computes the shutter and gain values
separately but does not expose separate functions to control them.

Augment the AgcAlgorithm interface to allow pausing/resuming the shutter
and gain automatic computations separately and plumb them to the newly
introduced controls.

Add safety checks to ignore ExposureTime and AnalogueGain values if the
algorithms are not paused, and report the correct AeState value by
checking if both algorithms have been paused or if they have converged.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 20:59:42 +02:00
Jacopo Mondi
72b2c9dddf test: ipa_data_serialization: Use DebugMetadataEnable
Replace the deprecated AeEnable control with DebugMetadataEnable
in ipa_data_serialization test. We use DebugMetadataEnable instead of
one of the controls replacing AeEnable as they are not boolean controls.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 19:38:21 +02:00
Jacopo Mondi
bad8d591f8 libcamera: uvcvideo: Register ExposureTimeMode control
Port the UVC pipeline handler to use the new ExposureTimeMode control
when processing Camera controls in place of the AeEnable control.

The V4L2_CID_EXPOSURE_AUTO control allows 4 possible values, which
map to ExposureTimeModeAuto and ExposureTimeModeManual.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 19:38:20 +02:00
Paul Elder
128220a139 Documentation: design: ae: Document the design for AE controls
Document the design and rationale for the AE-related controls.
Also add documentation for the controls.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 19:38:14 +02:00
Paul Elder
3becdbcbe8 controls: Introduce AEGC-related controls
Introduce the AeState, ExposureTimeMode and AnalogueGainMode controls
to model the AEGC algorithm block.

The three controls allow applications to select the exposure time and
analogue gain computation calculation mode (auto vs manual)
independently from one another, while the AeState control reports the
global state for the AEGC algorithm.

The new controls are meant to replace the existing AeEnable and AeLocked
controls, which are momentarily kept not to break compilation of
platforms making use of them.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=42
Bug: https://bugs.libcamera.org/show_bug.cgi?id=43
Bug: https://bugs.libcamera.org/show_bug.cgi?id=47
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-20 19:38:10 +02:00
Laurent Pinchart
b01918978c libcamera: v4l2_subdevice: Work around false positive warning
gcc 13.3.0, as provided by buildroot 2024.11.1, chokes when compiling
v4l2_subdevice.cpp with ASan enabled, due to the usage of the C++
standard library regex header:

In file included from /host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/functional:59,
                 from ../../include/libcamera/base/utils.h:12,
                 from ../../include/libcamera/base/log.h:15,
                 from ../../include/libcamera/internal/v4l2_subdevice.h:20,
                 from ../../src/libcamera/v4l2_subdevice.cpp:8:
In constructor ‘std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes ...)>&&) [with _Res = bool; _ArgTypes = {char}]’,
    inlined from ‘std::__detail::_State<_Char_type>::_State(std::__detail::_State<_Char_type>&&) [with _Char_type = char]’ at /host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/regex_automaton.h:149:4,
    inlined from ‘std::__detail::_StateIdT std::__detail::_NFA<_TraitsT>::_M_insert_subexpr_begin() [with _TraitsT = std::__cxx11::regex_traits<char>]’ at /host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/regex_automaton.h:281:24:
/host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/std_function.h:405:42: error: ‘*(std::function<bool(char)>*)((char*)&__tmp + offsetof(std::__detail::_StateT, std::__detail::_State<char>::<unnamed>.std::__detail::_State_base::<unnamed>)).std::function<bool(char)>::_M_invoker’ may be used uninitialized [-Werror=maybe-uninitialized]
  405 |       : _Function_base(), _M_invoker(__x._M_invoker)
      |                                      ~~~~^~~~~~~~~~
In file included from /host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/regex:65,
                 from ../../src/libcamera/v4l2_subdevice.cpp:11:
/host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/regex_automaton.h: In member function ‘std::__detail::_StateIdT std::__detail::_NFA<_TraitsT>::_M_insert_subexpr_begin() [with _TraitsT = std::__cxx11::regex_traits<char>]’:
/host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/regex_automaton.h:279:17: note: ‘__tmp’ declared here
  279 |         _StateT __tmp(_S_opcode_subexpr_begin);
      |                 ^~~~~
In member function ‘bool std::_Function_base::_M_empty() const’,
    inlined from ‘std::function<_Res(_ArgTypes ...)>::operator bool() const [with _Res = bool; _ArgTypes = {char}]’ at /host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/std_function.h:574:25,
    inlined from ‘std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes ...)>&&) [with _Res = bool; _ArgTypes = {char}]’ at /host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/std_function.h:407:6,
    inlined from ‘std::__detail::_State<_Char_type>::_State(std::__detail::_State<_Char_type>&&) [with _Char_type = char]’ at /host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/regex_automaton.h:149:4,
    inlined from ‘std::__detail::_StateIdT std::__detail::_NFA<_TraitsT>::_M_insert_subexpr_begin() [with _TraitsT = std::__cxx11::regex_traits<char>]’ at /host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/regex_automaton.h:281:24:
/host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/std_function.h:247:37: error: ‘*(const std::_Function_base*)((char*)&__tmp + offsetof(std::__detail::_StateT, std::__detail::_State<char>::<unnamed>.std::__detail::_State_base::<unnamed>)).std::_Function_base::_M_manager’ may be used uninitialized [-Werror=maybe-uninitialized]
  247 |     bool _M_empty() const { return !_M_manager; }
      |                                     ^~~~~~~~~~
/host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/regex_automaton.h: In member function ‘std::__detail::_StateIdT std::__detail::_NFA<_TraitsT>::_M_insert_subexpr_begin() [with _TraitsT = std::__cxx11:
/host/aarch64-buildroot-linux-gnu/include/c++/13.3.0/bits/regex_automaton.h:279:17: note: ‘__tmp’ declared here
  279 |         _StateT __tmp(_S_opcode_subexpr_begin);
      |                 ^~~~~

This is a false positive that previously occurred with gcc 12.1.0 and
was fixed in 12.2 (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562),
and it seems to have now reappeared. The bug report indicates that the
probability of such false positives increase when using sanitizers. As
this isn't caught by CI, which compiles libcamera with gcc 13.3.0, the
chance that such compilation failures will appear in environments
without a clear pattern is relatively high. Work around the problem by
disabling the warning around the inclusiong of the regex header.

If the regex header needs to be included in other source files, creating
a wrapped in libcamera-base may be a cleaner alternative.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-01-20 19:38:05 +02:00
Harvey Yang
4dad8ece72 DmaBufAllocator: Avoid syncing with an invalid file descriptor
As DmaSyncer disables the copy c'tor, the move c'tor will be used
instead. This leaves some DmaSyncers with invalid SharedFDs. They should
avoid syncing with invalid file descriptors in the d'tor.

Fixes: 545046a41e ("DmaBufAllocator: Make DmaSyncer non-copyable")
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Tested-by: Milan Zamazal <mzamazal@redhat.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>
2025-01-14 22:17:33 +00:00
Barnabás Pőcze
8b35ce4753 libcamera: virtual: Install configuration file
Install the example configuration file of the virtual pipeline
handler as it serves documentation purposes, and to make the
virtual pipeline handler easily usable in CI.

Nonetheless, the file is installed with the ".example" suffix
so that it will not be used by default, to avoid cluttering
the camera lists of users whose distributions decide to
enable the virtual pipeline handler.

The file is installed in the proper location for convenience:
  (1) is is easier to use it in the CI;
  (2) users need not browse documentation to determine where
      they should place the file.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-14 16:50:55 +02:00
Laurent Pinchart
6841ea8d36 libcamera: pipeline: virtual: Demote config file error message to debug
The virtual pipeline handler prints an error message when its
configuration file can't be opened. Not providing a configuration file
is the default method to disable virtual cameras, so this error is
confusing for users. Replace it with a debug message when the
configuration file is not found, and keep an error message when it
exists but can't be opened.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Julien Vuillaumier <julien.vuillaumier@nxp.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-14 16:38:09 +02:00
Laurent Pinchart
31a7378c87 libcamera: pipeline_handler: Enable silent configuration file lookup
The PipelineHandler::configurationFile() function prints an error
message when no configuration file is found. It can be useful for
pipeline handlers to silence the lookup operation and handle errors
themselves. Add a silent parameter to the function to enable this.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Julien Vuillaumier <julien.vuillaumier@nxp.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-14 16:38:04 +02:00
Barnabás Pőcze
2ae7b2ff74 meson: Don't override pipeline list when auto is selected
Consider `pipelines=auto,virtual`. Previously that would select
everything that `auto` would, but not actually enable the `virtual`
pipeline handler because the `pipelines` list was reset.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=247
Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-10 12:53:18 +01:00
Barnabás Pőcze
a945532314 meson: Convert v4l2 into a feature option
The v4l2 compatibility layer does not have external dependencies,
the usual benefits of a feature option do not apply. The main
motivation behind this change is making use of the `auto_features`
meson option that can change all feature options set to "auto"
by default to the desired value.

This can be useful for two reasons: (1) using auto_features=disabled
and then building up the list of features that are desired in the
particular build; (2) using auto_features=enabled to achieve
(usually) more testing and compilation coverage.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-10 12:35:10 +01:00
Barnabás Pőcze
ac611e80d2 gstreamer: allocator: gst_libcamera_allocator_new(): Fix memory leak
If `FrameBufferAllocator::allocate()` causes the construction to be
aborted, the allocated `GstLibcameraAllocator` will not be
deallocated properly. Use `g_autoptr()` to address this.

`g_steal_pointer()` could only be used in glib 2.68 or later because
earlier it evaluates to a pointer-to-void in C++, which would necessitate
a `static_cast`.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
2025-01-10 12:14:27 +01:00
Barnabás Pőcze
fd6e41b9fb gstreamer: allocator: gst_libcamera_allocator_new(): Recognize errors
`FrameBufferAllocator::allocate()` might return a negative error code,
but currently this is handled the same way as success. So instead
of continuing, abort the construction of the allocator object.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
2025-01-10 12:14:27 +01:00
Harvey Yang
d49a84a4f3 Thread: Fix setThreadAffinity race condition in start
Previously we call Thread::setThreadAffinityInternal in
Thread::startThread. The purpose was to avoid the main workload being
run on incorrect CPUs. This leads to a race condition of setting
`Thread::thread_` in `Thread::start()` and accessing
`Thread::setThreadAffinityInternal` though.

This patch moves the call after the construction of std::thread to avoid
the race condition. The downside is that the first tasks, if any, upon
starting a thread might be run on incorrect CPUs.

Fixes: 4d9db06d66 ("libcamera: add method to set thread affinity")
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-09 23:18:56 +02:00
Paul Elder
8d50577c0f utils: codegen: controls.py: Fix missing direction error message
The error message for missing direction field prints the direction value
(usually 'None') instead of the name of the field 'direction'. Fix this.

Fixes: 39fe4ad968 ("utils: codegen: controls.py: Parse direction information")
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-09 14:12:50 -06:00
Laurent Pinchart
de44514b25 libcamera: include: Include missing stdint.h header
Many libcamera headers that use standard C integer types do not include
stdint.h. Fix the omission.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-09 15:11:17 +02:00
Sergei Trofimovich
91de550243 libcamera: Add missing <stdint.h> include to dma_buf_allocator.h
Without the change the build fails on upcoming `gcc-15` as:

    In file included from ../src/libcamera/dma_buf_allocator.cpp:9:
    ../include/libcamera/internal/dma_buf_allocator.h:66:19: error: 'uint64_t' has not been declared
       66 |         void sync(uint64_t step);
          |                   ^~~~~~~~

Signed-off-by: Sergei Trofimovich <slyich@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-09 03:34:13 +02:00
Mattijs Korpershoek
5d444bbd51 libcamera: base: Remove custom __nodiscard attribute
__nodiscard was introduced for compatibility with C++14.
In C++17, there is an official attribute: [[nodiscard]].
Moreover, some libc implementations (like bionic) already define the
__nodiscard macro [1].

Since:
- libcamera builds with cpp_std=c++17
- [[nodiscard]] is already used in the android HAL (exif)

We should replace all usage __nodiscard of by [[nodiscard]] for
consistency.

Do the replacement and remove the no longer used compiler.h.

[1] 3254860

Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.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-01-08 15:26:30 +00:00
Laurent Pinchart
3feb4df755 libcamera: camera_sensor: Add support for embedded data
Some sensors support producing and transmitting embedded data over a
stream separate from the image stream. Add support for this feature in
the CameraSensor interface, and implement it for the CameraSensorRaw
class. The CameraSensorLegacy uses the default stub implementation, as
the corresponding kernel drivers don't support embedded data.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 14:30:33 +01:00
Laurent Pinchart
a09c7f212c libcamera: Add CameraSensor implementation for raw V4L2 sensors
Add a new CameraSensorRaw implementation of the CameraSensor interface
tailored to devices that implement the new V4L2 raw camera sensors API.

This new class duplicates code from the CameraSensorLegacy class. The
two classes will be refactored to share code.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 14:30:25 +01:00
Laurent Pinchart
99b54c2c55 libcamera: v4l2_videodevice: Update to the new kernel metadata API
With support for metadata in the streams API, the v4l2_meta_format
structure has been extended with width, height and bytesperline fields.

Support them in the V4L2VideoDevice getFormat() and setFormat()
functions is the video device is meta capture device and if the
pixel format is one of the generic line-based metadata formats.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 14:28:35 +01:00
Laurent Pinchart
accee0fe1e libcamera: v4l2_subdevice: Add new metadata formats
Support the newly introduced V4L2 media bus formats for metadata. This
includes generic metadata formats, and two sensor-specific embedded data
formats.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 14:28:35 +01:00
Jacopo Mondi
57d13c2c63 include: linux: videodev2: Add generic line based pixel formats
Add the definition for the generic line based pixelformats.

The formats has been added in upstream Linux by commit
1d9215233958 ("media: uapi: v4l: Add generic 8-bit metadata format
definitions") which got merged in Linux v6.10.

The formats however are not yet available to userspace, as they
have been made only available to the kernel by commit
d69c8429ea80 ("media: uapi: v4l: Don't expose generic metadata formats
to userspace") to let the line-based metadata support stabilize before
allowing applications to use it.

With the forthcoming completion of the line-based metadata upstreaming
manually add the generic line based pixel format to prepare libcamera
to support them.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 14:28:35 +01:00
Jacopo Mondi
052a9ff245 include: linux: Update headers for line-based embedded data support
Update the kernel headers with the definition of two device-specific
line-based metadata formats, and with the definition of the
MEDIA_PAD_FL_INTERNAL and V4L2_SUBDEV_ROUTE_FL_IMMUTABLE flags.

The new definitions will allow to support handling line-based
metadata streams exposed by the sensor driver through an
internal sink pad.

While the changes have not yet been collected in the official
linux-media tree, they're available in the 'metadata' branch of
https://git.linuxtv.org/sailus/media_tree.git, at revision:
f9bbbd9a696d ("media: Documentation: Add binning and sub-sampling
controls")

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 14:28:35 +01:00
Naushir Patuck
18c9ff46ef ipa: rpi: Provide the camera helper with the hardware configuration
Add a CamHelper::setHwConfig() helper used by the IPA to set the
hardware configuration in use by the pipeline. This will be needed by
the IMX500 camera helper in a future commit to determine if the
metadata buffer is strided.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 12:30:58 +00:00
Naushir Patuck
cd3dfa1f03 ipa: rpi: Add a HW property to determine if the data buffer is strided
This property (dataBufferStrided) indicates if the CSI-2 hardware writes
to the embedded/metadata buffer directly, or if it treats the buffer
like an image buffer and strides the metadata lines.

Unicam writes this buffer strided, while the PiSP Frontend writes to it
directly. This information will be relevant to data parsers in the
helpers where the data is structured in lines.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 12:30:58 +00:00
Naushir Patuck
a45de8e81b ipa: rpi: Add erase()/eraseLocked() to RPiController::Metadata
These functions erase a key/value pair from the metadata object.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 12:30:58 +00:00
Naushir Patuck
031a57bcd2 ipa: rpi: Use r-value references in the set()/setLocked() functions
Use an r-value reference in set() and setLocked(), allowing more
efficient metadata handling with std::forward and std::move if needed.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 12:30:58 +00:00
Dave Stevenson
2d4660b51a ipa: rpi: Add vc4 tuning files for imx415
Basic tuning done by David Plowman using a Waveshare SKU 28524
"IMX415-98 IR-CUT Camera" module.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 10:00:35 +00:00
Dave Stevenson
07be807dc7 ipa: rpi: Add cam_helper for imx415
As another Starvis sensor, it is near identical to imx290/327.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 10:00:28 +00:00
Dave Stevenson
549916fead libcamera: camera_sensor_properties: Add delays for imx415
Believed correct based on imx290.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-08 10:00:08 +00:00
Harvey Yang
545046a41e DmaBufAllocator: Make DmaSyncer non-copyable
As DmaSyncer does sync start/end in the c'tor/d'tor, copying a DmaSyncer
instance would trigger sync end earlier than expected. This patch makes
it non-copyable to avoid the issue.

Fixes: 39482d59fe ("DmaBufAllocator: Add Dma Buffer synchronization function & helper class")
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
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>
2025-01-07 09:46:34 +00:00
Barnabás Pőcze
4f9d8a6301 libcamera: virtual: Speed up test pattern animation
After the initial generation, when a frame is requested,
the test pattern generator rotates the image left by 1 column.

The current approach has two shortcomings:
  (1) it allocates a temporary buffer to hold one column;
  (2) it swaps two columns at a time.

The test patterns are simple ARGB images, in row-major order,
so doing (2) works against memory prefetching. This can be
addressed by doing the rotation one row at a time as that way
the image is addressed in a purely linear fashion. Doing so also
eliminates the need for a dynamically allocated temporary buffer,
as the required buffer now only needs to hold one sample,
which is 4 bytes in this case.

In an optimized build, this results in about a 2x increase in the
number of frames per second as reported by `cam`. In an unoptimized,
ASAN and UBSAN intrumented build, the difference is even bigger,
which is useful for running lc-compliance in CI in a reasonable time.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-06 10:18:44 +01:00
Barnabás Pőcze
fe33e727f2 libcamera: virtual: Query number of planes correctly
`PixelFormatInfo::planes.size()` always returns 3 since `planes` is
an array, but that is not the number of planes of the pixel format.
Use the `numPlanes()` getter instead.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-06 10:18:44 +01:00
Barnabás Pőcze
277a28691c libcamera: virtual: Avoid some copies
There is no reason make copies, these functions return
const lvalue references, access the data through those.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-01-06 10:18:44 +01:00
Kieran Bingham
35ed4b9129 libcamera v0.4.0
The abi-compliance-checker reports that there is both ABI and API breakage in
this release.

  Binary compatibility: 91.2%
  Source compatibility: 98.9%
  Total binary compatibility problems: 69, warnings: 0
  Total source compatibility problems: 9, warnings: 0

This is not too surprising as this was the reason for the extra delay holding
up this release, and as such this release bumps the SONAME to 0.4 accordingly.

The majority of the ABI breakages are around the public API for Control
handling and definitions, which have caused underlying identifiers to be
changed, and the reuqired storage for controls has increased.

I hope that grouping the expected ABI and API breakages and delaying this
release will allow a longer stability on the 0.4 series but as we are
developing rapidly this can not be guaranteed, though we aim to minimise
disruption to distributions and applications whereever possible.

This release brings in 253 commits, with substantial development on image
control and tuning features for IPA and Pipeline handlers supporting libipa, as
well as integrating libipa support for IPA handling on the ARM Mali-C55 ISP.

A new 'Virtual Pipeline Handler' has been introduced to support more testing in
CI and virtual environments.

Gstreamer has had some interesting development to rework expressing the full
control set from libcamera using auto generation from the full control
descriptors.

A key and notable change in this release too is that the softISP is now moving
towards utilising the libipa implementaitons which will enable future tuning
and image control capabilities, and should also support future development on a
GPU-ISP implementation for GPU-accelerated handling. I do believe this work may
have introduced an oscillation regression in the AEGC which will need to be
investigated and fixed in the near future, but I don't want to hold up
progressing the ABI updates at this stage.

The i.MX8MP can now make full use of the DW100 Dewarp Engine for full rotation
and digital zoom capabilities.

Raspberry Pi systems now have improved support for the OV7251, IMX462, and
IMX327 Sensors, and libipa platforms can now make use of the GalaxyCore gc05a2
and gc08a3 Image sensors.

The following commits in this release relate to either a bug fix or an
improvement to an existing commit.

 - ipa: rpi: Use std::abs()
   - Reported-by: Maarten Lankhorst <dev@lankhorst.se>
 - libcamera: rkisp1: Clamp stream configuration to ISP limit on raw path
   - Fixes: 761545407c ("pipeline: rkisp1: Filter out sensor sizes not supported by the pipeline")
 - libcamera: rkisp1: Rectify SensorConfiguration check
   - Fixes: 047d647452 ("libcamera: rkisp1: Integrate SensorConfiguration support")
 - libcamera: controls: Add missing size to control_type<Point>
   - Fixes: 200d535ca8 ("libcamera: controls: Add ControlTypePoint")
 - pycamera: Add missing code for ControlTypePoint
   - Fixes: 200d535ca8 ("libcamera: controls: Add ControlTypePoint")
 - libcamera: software_isp: Clear IPA context on configure and stop
   - Fixes: 04d171e6b2 ("libcamera: software_isp: Call Algorithm::queueRequest")
 - utils: checkstyle.py: Centralize dependency handling for checkers
   - Fixes: 8ffaf376bb ("utils: checkstyle: Add a python formatter")
 - test: py: Fix log level restore in SimpleTestMethods()
   - Fixes: 06cb7130c4 ("py: Add unittests.py")
 - v4l2: v4l2_camera_proxy: Fix VIDIOC_[GS]_PARM support
   - Fixes: 5456e02d3f ("v4l2: Support setting frame rate in the V4L2 Adaptation layer")
 - gstreamer: Remove auto-focus-mode property from device provider
   - Fixes: 5a142438b0 ("gstreamer: Add enable_auto_focus option to the GStreamer plugin")
 - libcamera: software_isp: Clean up pending requests on stop
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=234
 - ipa: rpi: awb: Disable CT search bias for Grey World AWB
   - Fixes: ea8fd63d93 ("ipa: rpi: awb: Add a bias to the AWB search")
 - meson: Don't unnecessarily fallback to libyuv wrap
   - Fixes: eeaa7de21b ("libcamera: pipeline: Add test pattern for VirtualPipelineHandler")
 - libcamera: Don't copy `StreamConfiguration` when iterating
   - Fixes: 4217c9f1aa ("libcamera: camera: Zero streams before validate()")
 - libcamera: software_isp: Actually apply black level from tuning data
   - Fixes: 41e3d61c74 ("libcamera: software_isp: Clear IPA context on configure and stop")
 - gstreamer: keep same transfer with that in negotiated caps
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=150
 - pipeline: rkisp1: Fix scope of dewarper stop() exit action
   - Fixes: 12b553d691 ("libcamera: rkisp1: Plumb the dw100 dewarper as V4L2M2M converter")
 - pipeline: rkisp1: Limit sensor size to max resolution
   - Fixes: 761545407c ("pipeline: rkisp1: Filter out sensor sizes not supported by the pipeline")

And the following updates have been made in this release, grouped by category:

core:
 - utils: abi-compat: Disable python build
 - utils: abi-compat: sort meson options
 - libcamera: controls: Add enum names and values map to ControlId
 - libcamera: controls: Add array information to ControlId
 - libcamera: v4l2_videodevice: Add getSelection() function
 - libcamera: controls: Handle enum values without a cast
 - libcamera: Replace usage of lroundf() with std::lround()
 - libcamera: Replace last users of math.h
 - libcamera: geometry: Clarify Rectangle's top-left corner
 - libcamera: geometry: Add two-point Rectangle constructor
 - libcamera: controls: Add ControlTypePoint
 - libcamera: control_ids_draft: Add face detection controls
 - libcamera: android: Add face detection control support
 - libcamera: yaml_parser: Take string keys in `std::string_view`
 - libcamera: camera: Fix CameraConfiguration spelling error
 - libcamera: MappedFrameBuffer: Fix typo in comment formatting
 - libcamera: controls: Add missing size to control_type<Point>
 - libcamera: tracepoints: Fix copyright year for reproducible builds
 - libcamera: controls: Add vendor information to ControlId
 - libcamera: converter: Add interface for feature flags
 - libcamera: converter: Add interface to support cropping capability
 - libcamera: formats: Change bytesPerGroup of RGB565 and RGB565_BE from 3 to 2
 - utils: checkstyle.py: Factor out common code to new CheckerBase class
 - utils: checkstyle.py: Turn check() into a class method for all checkers
 - utils: checkstyle.py: Print issues using __str__
 - utils: checkstyle.py: Centralize dependency handling for checkers
 - libcamera: camera_sensor: Introduce CameraSensorFactory
 - libcamera: camera_sensor: Create abstract base class
 - libcamera: camera_sensor: Sort factories by priority
 - libcamera: pipeline_handler: Provide cancelRequest
 - libcamera: simple: Track requests in conversionQueue_
 - libcamera: Rationalize IPA and handlers names
 - libcamera: Add debug control space
 - libcamera: Add a DebugMetadata helper
 - utils: Add script to generate control_ids_debug.yaml
 - libcamera: yaml_parser: Use std::from_chars()
 - libcamera: add DmaBufAllocator::exportBuffers()
 - libcamera: Remove PipelineHandler Fatal check of non-empty MediaDevices
 - libcamera: virtual: Add VirtualPipelineHandler
 - libcamera: virtual: Add ImageFrameGenerator
 - libcamera: virtual: Read config and register cameras based on the config
 - meson: Don't unnecessarily fallback to libyuv wrap
 - libcamera: Rename "shutter speed" to "exposure time"
 - libcamera: camera_sensor_properties: Add sensor control delays
 - libcamera: pipelines: Draw control delays from CameraSensor properties
 - libcamera: Don't copy `StreamConfiguration` when iterating
 - treewide: Avoid some copies in range-based for loops
 - libcamera: v4l2_videodevice: Clarify V4L2M2MDevice
 - libcamera: Extend u32 control type
 - libcamera: Extend u16 control type
 - libcamera: add method to set thread affinity
 - libcamera: Copy Matrix class from libipa to libcamera
 - libcamera: internal: Move Matrix class into libcamera namespace
 - libcamera: internal: matrix: Replace vector with array in constructor
 - libcamera: internal: Add Matrix class to build
 - libcamera: mali-c55: Limit max size to sensor resolution
 - libcamera: mali-c55: Limit ISP input size
 - libcamera: mali-c55: Init camera properties
 - libcamera: mali-c55: Simplify bufferReady()
 - libcamera: mali-c55: Remove MaliC55CameraData::mbusCodes()
 - libcamera: mali-c55: Add stride and size to rawConfig
 - libcamera: v4l2-subdevice: Add Mali C55 media bus formats
 - libcamera: bayer_format: Add 20-bit bayer formats
 - libcamera: mali-c55: Propagate CSI-2 format to ISP
 - libcamera: mali-c55: Correct input/output format representation
 - libcamera: mali-c55: Enable links between resizer and video node
 - libcamera: mali-c55: Enable usage of scaler
 - libcamera: mali-c55: implement support for ScalerCrop
 - libcamera: yaml_parser: Output more details when parsing fails
 - libcamera: yaml_parser: Include stdlib.h instead of cstdlib
 - libcamera: utils: StringSplitter: Inline some trivial methods
 - libcamera: utils: StringSplitter: Add `operator==`
 - libcamera: stream: Add operator<<(StreamConfiguration)
 - libcamera: yaml_parser: Improve efficiency of string empty check
 - libcamera: geometry: Add Rectangle::transformedBetween()
 - libcamera: converter_v4l2_m2m: Add missing override specifier
 - libcamera: converter_v4l2_m2m: Refactor get crop bounds code
 - libcamera: converter: Add function to query crop bounds
 - libcamera: converter: Add function to check if a stream was configured
 - libcamera: converter: Add functions to adjust config
 - libcamera: camera: Add a const version of the pipe() function
 - libcamera: camera_sensor: Add parameter to limit returned sensor size
 - libcamera: camera_sensor_properties: Add ov7251 and ov9281
 - libcamera: rpi: Draw sensor delays from CameraSensorProperties
 - include: linux: Add mali-c55-config.h
 - include: linux: Add Mali-C55 Stats and Params V4L2 format
 - libcamera: mali-c55: Acquire and plumb in 3a params and stats
 - libcamera: controls: Populate direction field in control definitions
 - utils: codegen: controls.py: Parse direction information
 - libcamera: controls: Add support for querying direction information
 - libcamera: controls: Update the ColourTemperature control to be writable
 - utils: gen-debug-controls: Output direction flag
 - hooks: pre-push: Verify that co-authors have a SoB line
 - gitignore: Add venv directory to gitignore
 - CameraManager: Ensure we cleanup on failure
 - Add .editorconfig file
 - DmaBufAllocator: Add Dma Buffer synchronization function & helper class

apps:
 - apps: cam: Print control enum values more nicely
 - py: Add bindings for ControlId enum name
 - apps: cam: Print control array sizes
 - apps: Replace HAVE_DNG with HAVE_TIFF
 - apps: cam: Print an error when outputting DNG and DNG support is missing
 - pycamera: Add missing code for ControlTypePoint
 - apps: cam: Print control vendor information when listing controls
 - py: Add bindings for ControlId vendor information
 - qcam: Automatically select the camera if only one is available
 - gstreamer: Implement caps negotiation for video/x-bayer
 - v4l2: v4l2_camera_proxy: Fix VIDIOC_[GS]_PARM support
 - gstreamer: Remove auto-focus-mode property from device provider
 - gstreamer: Remove auto-focus-mode property from libcamerasrc
 - gstreamer: Generate controls from control_ids_*.yaml files
 - py: Add bindings for ControlId array information
 - qcam: Use pointer when choosing camera
 - gstreamer: keep same transfer with that in negotiated caps
 - apps: cam: Print control direction information

pipeline:
 - libcamera: software_isp: Remove superfluous includes
 - libcamera: software_isp: Move BlackLevel to libcamera::ipa::soft
 - libcamera: software_isp: Define skeletons for IPA refactoring
 - libcamera: software_isp: Let IPASoftSimple inherit Module
 - libcamera: software_isp: Make stats frame and buffer aware
 - libcamera: software_isp: Remove final dots in debayer.cpp docstrings
 - libcamera: software_isp: Track and pass frame ids
 - libcamera: software_isp: Create algorithms
 - libcamera: software_isp: Call Algorithm::configure
 - libcamera: software_isp: Call Algorithm::queueRequest
 - libcamera: software_isp: Call Algorithm::prepare
 - libcamera: software_isp: Call Algorithm::process
 - libcamera: software_isp: Move black level to an algorithm module
 - libcamera: software_isp: Move color handling to an algorithm module
 - libcamera: software_isp: Use floating point for color parameters
 - libcamera: software_isp: Use DelayedControls
 - libcamera: software_isp: Move exposure+gain to an algorithm module
 - libcamera: software_isp: Update black level only on exposure changes
 - pipeline: simple: Increase buffer count to four
 - libcamera: rkisp1: Eliminate hard-coded resizer limits
 - pipeline: rkisp1: Filter out sensor sizes not supported by the pipeline
 - libcamera: software_isp: Improve wording in a comment
 - libcamera: rkisp1: Integrate SensorConfiguration support
 - libcamera: rkisp1: Clamp stream configuration to ISP limit on raw path
 - libcamera: rkisp1: Use const reference for sensor configuration
 - libcamera: rkisp1: Rectify SensorConfiguration check
 - libcamera: rkisp1: Maintain alphabetical order of forward declarations
 - libcamera: software_isp: Clear IPA context on configure and stop
 - libcamera: software_isp: Get black level from the camera helper
 - libcamera: software_isp: Black level from tuning file
 - libcamera: pipeline: rkisp1: Fix typo in todo task
 - libcamera: rkisp1: Prepare for additional camera controls
 - libcamera: rkisp1: Plumb the dw100 dewarper as V4L2M2M converter
 - pipeline: rpi: Remove CameraData::scalerCrop_
 - pipeline: rpi: Pass crop rectangle as a parameter to platformSetIspCrop()
 - pipeline: rpi: Introduce CameraData::CropParams
 - pipeline: rpi: Track which ISP output is configured for a stream
 - pipeline: rpi: Pass ISP output index into platformSetIspCrop()
 - pipeline: rpi: Handler controls::rpi::ScalerCrops
 - libcamera: rkisp1: Create main buffer pool out of if(!isRaw)
 - libcamera: software_isp: Clean up pending requests on stop
 - libcamera: pipeline: Add test pattern for VirtualPipelineHandler
 - libcamera: software_isp: Refactor SoftwareIsp to use DmaBufAllocator::exportBuffers
 - libcamera: software_isp: Initialize exposure+gain before agc calculations
 - libcamera: software_isp: Remove unused IPAActiveState fields
 - libcamera: software_isp: Actually apply black level from tuning data
 - rkisp1: Use Matrix class from libcamera
 - libcamera: software_isp: Add support for contrast control
 - libcamera: software_isp: Add contrast control
 - pipeline: rkisp1: Fix scope of dewarper stop() exit action
 - pipeline: rkisp1: Keep aspect ratio on imx8mp
 - pipeline: rkisp1: Split inputCrop and outputCrop
 - pipeline: rkisp1: Reorder sensorInfo collection code
 - pipeline: rkisp1: Query dewarper crop bounds if no stream configured
 - pipeline: rkisp1: Fix ScalerCrop to be in sensor coordinates
 - pipeline: rkisp1: Add ScalerMaximumCrop property
 - pipeline: rkisp1: Refactor path validation
 - pipeline: rkisp1: Enable the dewarper unconditionally
 - pipeline: rkisp1: make RkISP1CameraConfiguration a friend of the pipeline handler
 - pipeline: rkisp1: Fix config validation when dewarper is used
 - pipeline: rkisp1: Limit sensor size to max resolution
 - debayer_cpu: Replace syncing DMABUFs with DmaSyncer
 - include: media-bus-formats: Add Mali-C55 mbus codes
 - mali-c55: Plumb the IPA module in

ipa:
 - ipa: rpi: Use std::abs()
 - ipa: rpi: Replace last users of math.h
 - ipa: rpi: awb: Add a const for the default colour temperature
 - ipa: rpi: awb: Add a bias to the AWB search
 - ipa: rkisp1: algorithms: agc: Check for correct stats type
 - ipa: rkisp1: algorithms: awb: Check for correct stats type
 - ipa: rpi: Add tuning files for OV7251
 - ipa: libipa: Fix ExposureModeHelper function name in documentation
 - ipa: rkisp1: Add constructor to the ipa context
 - ipa: rkisp1: Add debug metadata support to the rkisp1
 - ipa: libipa: Add data accessor to Histogram
 - ipa: libipa: Add colour helpers
 - ipa: ipu3: Use centralised libipa helpers
 - ipa: rkisp1: Use centralised libipa helpers
 - ipa: rpi: Use centralised libipa helpers
 - ipa: rpi: awb: Disable CT search bias for Grey World AWB
 - libipa: FCQueue: Make sure FrameContext#0 is initialized
 - libcamera: libipa: camera_sensor: Provide helper and properties for Sony IMX462
 - ipa: rpi: cam_helper: Add Sony IMX327
 - ipa: raspberrypi: Add tuning file for IMX462 sensor
 - ipa: raspberrypi: Add tuning file for IMX327 sensor
 - libcamera: libipa: camera_sensor_helper: add IMX290 black level
 - ipa: libipa: vector: Add mutable x(), y() and z() accessors
 - ipa: libipa: vector: Add r(), g() and b() accessors
 - ipa: libipa: vector: Add scalar constructor
 - ipa: libipa: vector: Rename the dot product operator*() to dot()
 - ipa: libipa: vector: Generalize arithmetic operators
 - ipa: libipa: vector: Add missing binary arithemtic operators
 - ipa: libipa: vector: Add compound assignment operators
 - ipa: libipa: vector: Add element-wise min() and max() functions
 - ipa: libipa: vector: Add sum() function
 - ipa: ipu3: awb: Replace Awb::RGB class with ipa::RGB
 - ipa: libipa: colour: Use the RGB class to model RGB values
 - ipa: libipa: colour: Use Vector and Matrix for linear algebra
 - ipa: rkisp1: awb: Use RGB class to store colour gains
 - ipa: rkisp1: awb: Use Vector and Matrix for linear algebra
 - ipa: rkisp1: awb: Expand comment
 - libcamera: libipa: camera_sensor: Add GalaxyCore gc05a2 sensor properties
 - libcamera: libipa: camera_sensor: Add GalaxyCore gc08a3 sensor properties
 - ipa: rpi: Rename Matrix to Matrix3x3
 - ipa: rpi: ccm: Replace local matrix implementation with the libcamera one
 - libipa: Use Matrix class from libcamera
 - libipa: Drop Matrix class
 - libipa: agc_mean_luminance: Rename yaml key from exposure-time to exposureTime
 - ipa: software_isp: Add constructor to the IPA context
 - ipa: ipu3: Add constructor to the IPA context
 - libcamera: libipa: camera_sensor_helper: Use `variant` instead of `union`
 - ipa: rpi: Fix wrong frame integration difference value for OV9281
 - ipa: rpi: cam_helper: imx708: Correct the frame integration diff value
 - libipa: Centralise Fixed / Floating point convertors
 - ipa: mali-c55: Add Mali-C55 ISP IPA module
 - ipa: mali-c55: Add Agc algorithm
 - ipa: mali-c55: Add BLC Algorithm
 - ipa: mali-c55: Add AWB Algorithm
 - ipa: mali-c55: Add Lens Shading Correction algorithm
 - ipa: mali-c55: Add IMX415 tuning data file
 - ipa: rkisp1: awb: Load white balance gains from tuning file
 - ipa: rkisp1: awb: Implement ColourTemperature control
 - ipa: rpi: awb: Make it possible to set the colour temperature directly
 - ipa: libipa: Add Lux helper
 - ipa: rkisp1: Add Lux algorithm module
 - controls: rpi: Add a vendor rpi::ScalerCrops control

documentation:
 - Documentation: guides: Fix FileSink source link

test:
 - test: py: Fix log level restore in SimpleTestMethods()
 - test: py: Replace environment array with environment object
 - test: py: LD_PRELOAD the C++ standard library when using ASan
 - test: libipa: Add Vector class test
 - test: span: Use intended variable

tuning:
 - utils: tuning: libtuning: Fix tuning for non RGGB RAWs
 - libtuning: Use logging framework in ctt_awb.awb()
 - libtuning: Remove the Cam object from ctt_awb.awb()
 - libtuning: Fix access to color member in ctt_awb.awb()
 - libtuning: Add initial AWB module
 - utils: tuning: rkisp1: Replace static AWB with new AWB module

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-23 20:18:23 +00:00
Stefan Klug
fa2e8621f5 utils: gen-debug-controls: Output direction flag
The yaml definitions for controls now require a direction attribute
which is not auto generated by gen-debug-controls.py. Fix that.

Signed-off-by: Stefan Klug <stefan.klug@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>
2024-12-23 11:16:08 +00:00
Paul Elder
344064a111 ipa: rkisp1: Add Lux algorithm module
Add a lux algorithm module to rkisp1 IPA for estimating the lux level of
an image. This is reported in metadata, as well as saved in the frame
context so that other algorithms (mainly AGC) can use its value. It does
not set any controls.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
2024-12-23 17:38:40 +09:00
Paul Elder
bd077a11ee ipa: libipa: Add Lux helper
Add a Lux helper to libipa that does the estimation of the lux level
given gain, exposure, and luminance histogram. The helper also
handles reading the reference values from the tuning file. These are
expected to be common operations of lux algorithm modules in IPAs, and
is modeled/copied from Raspberry Pi.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
2024-12-23 17:37:34 +09:00
David Plowman
e378309251 ipa: rpi: awb: Make it possible to set the colour temperature directly
ColourTemperature is now exported as a writable control so that
applications can set it directly. The AWB algorithm class now requires
a method to be provided to perform this operation. The method should
clamp the passed value to the calibrated range known to the algorithm.

The default range is set very wide to cover all conceivable future AWB
calibrations. It will always be clamped before use.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Tested-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-12-20 17:22:42 +01:00
Stefan Klug
6efbe35de5 utils: tuning: rkisp1: Replace static AWB with new AWB module
The rkisp1 tuner used a static module to insert the AWB algorithm into
the tuning file. Replace that with the new AWB module.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-20 17:22:42 +01:00
Stefan Klug
b1ec488f1b libtuning: Add initial AWB module
This AWB module uses the awb function from Raspberry Pi to calculate the
needed white balance gains per colour temperature. It stores these gains
in the tuning file.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-20 17:22:42 +01:00
Stefan Klug
731cc02e79 libtuning: Fix access to color member in ctt_awb.awb()
The color temperature member of the image object was named "col" in the
past. Now it is named "color" (which is still not very expressive).
There are still a few unspotted accesses to the col member. Fix them to
access the color member.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-20 17:22:42 +01:00
Stefan Klug
83e186a094 libtuning: Remove the Cam object from ctt_awb.awb()
Replace the Cam object with a list parameter to be able to call the
ctt_awb.awb() function from libtuning code.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-20 17:22:42 +01:00
Stefan Klug
3077f951c1 libtuning: Use logging framework in ctt_awb.awb()
To be able to use the awb function copied from the Raspberry Pi tuning
scripts in the libtuning code, we need to remove the Cam object. Use the
logging framework to replace all accesses to Cam.log.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-20 17:22:42 +01:00
Stefan Klug
0230880954 ipa: rkisp1: awb: Implement ColourTemperature control
There are many use-cases (tuning-validation, working in static
environments) where a manual ColourTemperature control is helpful.
Implement that by interpolating and applying the white balance gains
from the tuning file according to the requested colour temperature. If
colour gains are provided on the same request, they take precedence.
Store the colour temperature used for a given frame in the frame context
and report that in metadata.

Note that in the automatic case, the colour gains are still based on the
gray world model and the CT curve from the tuning file get ignored.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-20 17:22:42 +01:00
Stefan Klug
886e0328c3 ipa: rkisp1: awb: Load white balance gains from tuning file
For the implementation of a manual colour temperature setting, it is
necessary to read predefined colour gains per colour temperature from
the tuning file. Implement this in a backwards compatible way. If no
gains are contained in the tuning file, loading just continues as
before.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-20 17:22:42 +01:00
Stefan Klug
4d2618fb10 libcamera: controls: Update the ColourTemperature control to be writable
For manual control it is helpful to be able to specify a fixed colour
temperature. It also provides an easy way to apply the temperature
specific CCMs and colour gains that are contained in the tuning files.

Document this and update the control dependencies.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-20 17:22:42 +01:00
Stefan Klug
24e00be9f3 utils: tuning: libtuning: Fix tuning for non RGGB RAWs
Tuning fails for raw images that don't have the channels ordered in
RGGB.  In 19dc8c28f6 ("utils: tuning: libtuning: Implement the core of
libtuning") the channels of the image were reordered to RGGB
unconditionally in _read_image_dng(). That change was not applied to the
ctt_awb code, so that the channels were reordered twice. Fix by removing
the double ordering.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Tested-by: Isaac Scott <isaac.scott@ideasonboard.com>
Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-18 17:20:32 +01:00
Paul Elder
936a099eca apps: cam: Print control direction information
Now that there is support for retrieving the allowed directions of a
control, print this information when listing controls.

Sample output:
$ cam --list-controls -c 2
Using camera Virtual0 as cam0
Control: [inout] draft::FaceDetectMode:
  - FaceDetectModeOff (0)
Control: [inout] libcamera::FrameDurationLimits: [16666..33333]
   Size: 2

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-18 17:27:22 +09:00
Paul Elder
34d7b4776b libcamera: controls: Add support for querying direction information
Add support to ControlId for querying direction information. This allows
applications to query whether a ControlId is meant for being set in
controls or to be returned in metadata or both. This also has a side
effect of properly encoding this information, as previously it was only
mentioned losely and inconsistently in the control id definition.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-18 17:27:01 +09:00
Paul Elder
39fe4ad968 utils: codegen: controls.py: Parse direction information
In preparation for adding support for querying direction information
from controls, parse the direction information from control ID
definitions. This can later be plugged in directly to the IPA code
generators simply by using ctrl.direction.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-12-18 17:26:52 +09:00
Paul Elder
9bd9d25a82 libcamera: controls: Populate direction field in control definitions
In preparation for adding support for querying direction information
from controls, populate the corresponding field in the control ID
defintions.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-12-18 17:26:40 +09:00
Daniel Scally
ef7c767a0f ipa: mali-c55: Add IMX415 tuning data file
Add a tuning data file for the IMX415 camera sensor. The black level
offset data is drawn from the camera sensor's datasheet. The lens
shading tables are generated through the libtuning LSC modules.

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Nayden Kanchev <nayden.kanchev@arm.com>
Co-developed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-17 22:35:59 +00:00
Daniel Scally
96b1ae03c3 ipa: mali-c55: Add Lens Shading Correction algorithm
Add a lens shading correction algorithm to the mali-c55 IPA. This
algorithm parses tables from Yaml in a easy to follow format before
munging them into Arm's interleaved mesh to be copied to the ISP.
A colour temperature estimate from the AGC statistics is used to
select the appropriate table to apply; this can be some interpolation
of two tables, in which case the colour temperature estimate is also
used to derive the coefficient that does the blending.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Nayden Kanchev <nayden.kanchev@arm.com>
Co-developed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-17 22:35:59 +00:00
Daniel Scally
2f95217917 ipa: mali-c55: Add AWB Algorithm
Add a simple grey-world auto white balance algorithm to the mali-c55
IPA.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Nayden Kanchev <nayden.kanchev@arm.com>
Co-developed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-17 22:35:59 +00:00
Jacopo Mondi
fbea6a4c02 ipa: mali-c55: Add BLC Algorithm
Add a Black Level Correction algorithm.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Acked-by: Nayden Kanchev  <nayden.kanchev@arm.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-17 22:35:59 +00:00
Daniel Scally
e8cae247e8 ipa: mali-c55: Add Agc algorithm
Add a new algorithm and associated infrastructure for Agc. The
tuning files for uncalibrated sensors is extended to enable the
algorithm.

Acked-by: Nayden Kanchev <nayden.kanchev@arm.com>
Co-developed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-17 22:35:59 +00:00
Jacopo Mondi
93a33e7a0f mali-c55: Plumb the IPA module in
Plumb the Pipeline-IPA loop in.

Load the IPA module at camera creation time and create the loop between
the pipeline and the IPA.

When a new Request is queued the IPA is asked to prepare the parameters
buffer, once ready it notifies the pipeline which queues the parameters
to the ISP along with a buffer for statistics and frames,

Once statistics are ready they get passed to the IPA which upates its
settings for the next frame.

Driveby fix an error message in the Pipeline Handler's ::freeBuffers()
function which reported a problem with the wrong video device in an
error path.

Acked-by: Nayden Kanchev  <nayden.kanchev@arm.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-17 22:35:59 +00:00
Daniel Scally
fe989ee514 ipa: mali-c55: Add Mali-C55 ISP IPA module
Add a barebones IPA module for the Mali-C55 ISP. In this initial
implementation pretty much only buffer plumbing is implemented.

Acked-by: Nayden Kanchev  <nayden.kanchev@arm.com>
Co-developed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-17 22:35:58 +00:00
Daniel Scally
10ccab9db9 libcamera: mali-c55: Acquire and plumb in 3a params and stats
Acquire the mali-c55 3a stats and parameters video devices during
::match() and plumb them in.

For this commit we simply allocate and release buffers for the
statistics and parameters. Statistics buffers are queue and dequeued
from the stats video device but their contents are for now untouched.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Nayden Kanchev  <nayden.kanchev@arm.com>
Co-developed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-17 22:35:58 +00:00
Daniel Scally
52b19407f0 include: linux: Add Mali-C55 Stats and Params V4L2 format
Add the new format describing the Mali C55's Statistics and Parameters
to videodev2. These come from the v8 of the C55 kernel driver series
[1]. Once the kernel driver is merged we can replace these temporary
manual additions with updates to the scripts that merge in the
kernel headers.

[1] https://lore.kernel.org/linux-media/20241106100534.768400-1-dan.scally@ideasonboard.com/

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Nayden Kanchev  <nayden.kanchev@arm.com>
Co-developed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-17 22:35:58 +00:00
Daniel Scally
6c61299518 include: linux: Add mali-c55-config.h
Add the header file describing the Mali C55's 3A statistics and
parameters structures so that they can be used by the new IPA module.

The header has been taken from the v6 of the patchset for the Mali
C55 ISP driver submitted to linux-media, found at the link below:

https://lore.kernel.org/linux-media/20240709132906.3198927-1-dan.scally@ideasonboard.com/

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Nayden Kanchev  <nayden.kanchev@arm.com>
Co-developed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-17 22:35:58 +00:00
Daniel Scally
3dd5725a84 libipa: Centralise Fixed / Floating point convertors
The rkisp1 IPA has some utility functions to convert between fixed
and floating point numbers. Move those to libipa so they're available
for use in other IPA modules too.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-17 22:35:58 +00:00
Daniel Scally
e4178d7943 libcamera: rpi: Draw sensor delays from CameraSensorProperties
Now that we have camera sensor control application delay values in
the CameraSensorProperties class, remove the duplicated definitions
in the RPi IPA's CameraSensorHelpers and update the pipeline handler
to use the values from CameraSensorProperties.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-17 22:35:58 +00:00
Daniel Scally
fb02bbf7d9 libcamera: camera_sensor_properties: Add ov7251 and ov9281
Add entries for the OmniVision OV7251 and OV9281 sensors. The control
delay values are drawn from the Raspberry Pi CameraSensorHelper class
for these sensors - the pixel sizes from the datasheets. Both sensors
are monochrome and do not have test pattern settings that correspond
to defined control values.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-17 22:02:59 +00:00
Stefan Klug
62959e1f89 pipeline: rkisp1: Limit sensor size to max resolution
In RkISPPath::validate() the sensor sizes are correctly filtered to the
ones supported by the ISP. But later in RkISPPipeline::configure() the
configured stream size is passed to sensor->getFormat() and the
CameraSensor class chooses the best sensor format for the requested
stream size. This can result in a sensor format that is too big for the
ISP. Fix that by supplying the maximum resolution supported by the ISP
to setFormat().

Fixes: 761545407c ("pipeline: rkisp1: Filter out sensor sizes not supported by the pipeline")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-12-17 11:19:36 +01:00
Stefan Klug
60e94a0d99 libcamera: camera_sensor: Add parameter to limit returned sensor size
The getFormat function takes the aspect ratio and the area of the
requested size into account when choosing the best sensor size. In case
the sensor is connected to an rkisp1 the maximum supported frame size of
the ISP is another constraining factor for the selection of the best
format. Add a maxSize parameter to support such a constraint.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 11:19:36 +01:00
Stefan Klug
041377839b pipeline: rkisp1: Fix config validation when dewarper is used
When the dewarper is used, config->validate() needs to take the
restrictions of the dewarper into account. Add the corresponding checks.

As the useDewarper_ variable is now accessed earlier in
PipelineHandlerRkISP1::configure(), ensure it gets set early enough.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 11:19:36 +01:00
Stefan Klug
d4487f690f pipeline: rkisp1: make RkISP1CameraConfiguration a friend of the pipeline handler
For the validate() implementation, the RkISP1CameraConfiguration needs
access to dewarper related members of the PipelineHandlerRkISP1 object.
Allow this access by adding const versions of the pipe accessors and
making RkISP1CameraConfiguration a friend of PipelineHandlerRkISP1.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-12-17 11:19:36 +01:00
Stefan Klug
437ca585df libcamera: camera: Add a const version of the pipe() function
Allow access to the pipeline handler on a const instance of
Camera::Private.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-12-17 11:19:36 +01:00
Stefan Klug
fd71913d70 pipeline: rkisp1: Enable the dewarper unconditionally
In configure() and in the future in generateConfiguration() the
calculated stream sizes and crop rectangles depend on the dewarper being
available or not. It is therefore not possible to disable the dewarper
later if configuration fails. Error out in that case.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 11:19:36 +01:00
Stefan Klug
f0e12b0fc8 pipeline: rkisp1: Refactor path validation
Refactor validation code to prepare for extensions in the upcoming
patches. Code duplication is reduced by moving parts of the validation
logic into a lambda function. This patch does not include any functional
changes.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-12-17 11:19:36 +01:00
Jacopo Mondi
0ce20a8cd5 libcamera: converter: Add functions to adjust config
Add to the Converter interface two functions used by pipeline handlers
to validate and adjust the converter input and output configurations
by specifying the desired alignment for the adjustment.

Add the adjustInputSize() and adjustOutputSize() functions that allows
to adjust the converter input/output sizes with the desired alignment.

Add a validateOutput() function meant to be used by the pipeline
handler implementations of validate(). The function adjusts a
StreamConfiguration to a valid configuration produced by the Converter.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-12-17 11:19:36 +01:00
Stefan Klug
a631af61af pipeline: rkisp1: Add ScalerMaximumCrop property
The ScalerMaximumCrop property holds the biggest allowed ScalerCrop
value. Add it to the rkisp1.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 10:33:14 +01:00
Stefan Klug
2a4bebd427 pipeline: rkisp1: Fix ScalerCrop to be in sensor coordinates
ScalerCrop is specified as being in sensor coordinates. The current
dewarper implementation on the imx8mp handles ScalerCrop in dewarper
coordinates. This leads to unexpected results and an unusable ScalerCrop
control in camshark. Fix that by transforming back and forth between
sensor coordinates and dewarper coordinates.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 10:33:14 +01:00
Stefan Klug
c4a523582a pipeline: rkisp1: Query dewarper crop bounds if no stream configured
Query the crop bounds on the dewarper instead of the stream in case the
camera was not yet configured when updateControls() gets called. This
provides sane defaults for the controls.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 10:33:14 +01:00
Stefan Klug
06346821be libcamera: converter: Add function to check if a stream was configured
Add a isConfigured() function to be able to check if a given stream was
configured in the converter. This is useful in pipelines to either query
device or stream specific crop bounds depending on whether the stream is
configured or not.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-12-17 10:33:14 +01:00
Stefan Klug
9abc05fae9 libcamera: converter: Add function to query crop bounds
The inputCropBounds_ member of the V4L2M2MConverter::Stream class is
only initialized after a V4L2M2MConverter::configure() call, when the
streams are initialized.

However, the converter has crop limits that do not depend on the
configured Streams, and which are currently not accessible from the
class interface.

Add a new inputCropBounds() function to the V4L2M2MConverter class
that allows to retrieve the converter crop limits before any stream
is configured.

This is particularly useful for pipelines to initialize controls and
properties and to implement validation before the Camera gets
configured.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 10:33:14 +01:00
Stefan Klug
d6c21e237e libcamera: converter_v4l2_m2m: Refactor get crop bounds code
In an upcoming patch it is necessary to get the crop bounds on the
converter itself. The V4L2M2MConverter contains code that is very
similar to the get crop bounds code in the V4L2M2MStream. Merge these
code blocks into a static function to be used from both classes.  This
patch contains no functional changes.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-12-17 10:33:14 +01:00
Stefan Klug
366dad2536 libcamera: converter_v4l2_m2m: Add missing override specifier
In preparation for adding new functions and overrides to the
V4L2M2MDevice class, add an override specifier to all overridden
functions in the class. This prevents -Winconsistent-missing-override
warnings.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-12-17 10:33:14 +01:00
Stefan Klug
60bb16695e pipeline: rkisp1: Reorder sensorInfo collection code
The sensorInfo (specifically the crop rectangle of the selected sensor
mode) is collected to be passed to the IPA later. In an upcoming patch
that data will also be needed for correct ScalerCrop handling. Move the
collection of the sensorInfo before the dewarper configuration step and
refactor the code a bit.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 10:31:44 +01:00
Stefan Klug
169b65ce16 pipeline: rkisp1: Split inputCrop and outputCrop
One Rectangle instance is used to calculate the inputCrop and the
outputCrop of the ISP in the rkisp1 pipeline. Split that into two
distinct variables, because both values will be needed in the upcoming
patches. This patch does not contain any functional changes.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 10:31:44 +01:00
Stefan Klug
ec097d63ef libcamera: geometry: Add Rectangle::transformedBetween()
Handling cropping and scaling within a complicated pipeline involves
transformations of rectangles between different coordinate systems. For
example the full input of the dewarper (0,0)/1920x1080 might correspond
to the rectangle (0, 243)/2592x1458 in sensor coordinates (of a
2592x1944 sensor). Add a function that allows the transformation of a
rectangle defined in one reference frame (dewarper) into the coordinates
of a second reference frame (sensor).

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 10:31:44 +01:00
Stefan Klug
db9b6f8e23 pipeline: rkisp1: Keep aspect ratio on imx8mp
In the current code, the input stage of the image resizer is used to
apply a crop to keep the aspect ratio in cases where the requested
output aspect ratio differs from the one of the selected sensor mode. On
the imx8mp the resizer hardware is not capable of cropping (for
reference see also rkisp1-resizer.c:rkisp1_rsz_set_sink_crop() in the
linux kernel v6.10).

Therefore apply the necessary cropping on the output of the ISP (on the
image stabilization block). The cropping code on the image resizer
doesn't need modifications as the requested crop gets ignored by the
kernel.

While at it, remove a todo comment that is no longer needed.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 10:31:44 +01:00
Stefan Klug
479e8c851c pipeline: rkisp1: Fix scope of dewarper stop() exit action
Move the definition of the dewarper stop() action into the scope were
the corresponding start() happens.

Fixes: 12b553d691 ("libcamera: rkisp1: Plumb the dw100 dewarper as V4L2M2M converter")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-12-17 10:31:44 +01:00
Hou Qi
e9a876acc6 gstreamer: keep same transfer with that in negotiated caps
The conversions back and forth between GStreamer colorimetry and
libcamera color space are not invariant for the bt601 colorimetry.
The reason is that Rec709 transfer function defined in GStreamer
as GST_VIDEO_TRANSFER_BT709 (5), is to be replaced by its alias
GST_VIDEO_TRANSFER_BT601 (16) only for the case of bt601 (aka 2:4:16:4)
colorimetry - see [1].

Currently the composition of the GStreamer/libcamera conversions:
colorimetry_from_colorspace (colorspace_from_colorimetry (bt601))
returns 2:4:5:4 instead of the expected 2:4:16:4 (bt601). This
causes negotiation error when the downstream element explicitly
expects bt601 colorimetry.

Minimal example to reproduce the issue is with a pipeline handler
that do not set the optional color space in the stream configuration,
for instance vimc or imx8-isi:
export LIBCAMERA_PIPELINES_MATCH_LIST="vimc,imx8-isi"
gst-launch-1.0 -v libcamerasrc ! video/x-raw,colorimetry=bt601 ! fakesink

Above pipeline fails to start. This change memorizes downstream required
transfer function when mapped libcamera transfer is Rec709 in
gst_libcamera_configure_stream_from_caps(), and restores the transfer
function in gst_libcamera_stream_formats_to_caps().

[1] https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/724

Bug: https://bugs.libcamera.org/show_bug.cgi?id=150
Signed-off-by: Hou Qi <qi.hou@nxp.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-16 15:12:50 +02:00
Laurent Pinchart
a7aab7da8a libcamera: yaml_parser: Improve efficiency of string empty check
Comparing a std::string to an empty string literal is more complex than
using the std::string::empty() function. Improve the code efficiency by
replacing the former with the latter.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-16 14:26:45 +02:00
David Plowman
8e15010b7d ipa: rpi: cam_helper: imx708: Correct the frame integration diff value
This is the minimum permitted difference between the frame length and
coarse exposure (both measured in lines). The correct value, taken
from the datasheet, is 48.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-12 10:36:40 +00:00
Jacopo Mondi
88456ab55a libcamera: stream: Add operator<<(StreamConfiguration)
The StreamConfiguration class only implements toString() but doesn't
offer an overload of operator<<() which is more convenient to use.

Add an overload for operator<<(StreamConfiguration) and re-implement
StreamConfiguration::toString() on top of it.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-11 15:39:05 +01:00
Naushir Patuck
229667606e ipa: rpi: Fix wrong frame integration difference value for OV9281
The frameIntegrationDiff value should be 25, otherwise we see invalid
frames when integration times are set to large values.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
2024-12-09 14:01:21 +01:00
Barnabás Pőcze
65dd707f74 libcamera: libipa: camera_sensor_helper: Use variant instead of union
Use an `std::variant` to store the analogue gain instead of a bare union + tag.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-09 13:52:39 +01:00
Milan Zamazal
3930b94021 libcamera: software_isp: Add contrast control
This patch introduces support for applying runtime controls to software
ISP.  It enables the contrast control as the first control that can be
used.

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>
2024-12-06 12:34:48 +00:00
Milan Zamazal
9135aacff1 libcamera: software_isp: Add support for contrast control
Software ISP is currently fully automatic and doesn't allow image
modifications by explicitly set control values.  The user has no means
to make the image looking better.

This patch introduces support for contrast control, which can improve
e.g. a flat looking image.  Based on the provided contrast value, it
applies a simple S-curve modification to the image.

The contrast algorithm just handles the provided values, while the
S-curve is applied in the gamma algorithm on the computed gamma curve
whenever the contrast value changes.  Since the algorithm is applied
only on the lookup table already present, its overhead is negligible.

The contrast value range is 0..2 and corresponds to the whole range from
a completely flat contrast to an infinite contrast, 1.0 being the normal
value.  This makes the user visible range intuitive and easy to use in
GUI sliders, while complying with Contrast control definition.  There is
no unified range in the hardware pipelines, for example rkisp1 uses
0..1.993 range while rpi uses 0..10 range.

This is a preparation patch without actually providing the control
itself, which is done in the following patch.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-06 12:34:48 +00:00
Milan Zamazal
c11e536ed2 ipa: ipu3: Add constructor to the IPA context
Let's have a constructor that takes just the non-default argument,
without the need to specify the defaults.

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>
2024-12-06 12:34:48 +00:00
Milan Zamazal
d2234560f8 ipa: software_isp: Add constructor to the IPA context
Let's have a constructor that takes just the non-default argument,
without the need to specify the defaults.

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>
2024-12-06 12:34:48 +00:00
Barnabás Pőcze
737fb452fc libcamera: utils: StringSplitter: Add operator==
If `cpp_debugstl` is enabled in the build configuration, then
libstdc++ will try to use `==` on operators in certain cases
to carry out extra checks. This leads to build failures because
`StringSplitter::iterator` has no `operator==`.

Implement `operator==`, and express `operator!=` in terms of it.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-05 22:29:57 +02:00
Barnabás Pőcze
f1bc9edb46 libcamera: utils: StringSplitter: Inline some trivial methods
Inline some of the more trivial methods so that they can
be inlined by the compiler.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-05 22:29:57 +02:00
Barnabás Pőcze
b5fd7631e6 test: span: Use intended variable
It appears that the original intention was to use it in these
particular constructor tests: the variable is otherwise unused,
and `Span<const int>{ v }` is already tested.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-05 22:29:57 +02:00
Milan Zamazal
8f7155ddfb libcamera: yaml_parser: Include stdlib.h instead of cstdlib
checkstyle.py will complain about cstdlib include, let's use stdlib.h
instead.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-05 22:29:57 +02:00
Stefan Klug
fa0013c953 libcamera: yaml_parser: Output more details when parsing fails
On malformed yaml files, the yaml parser only errors out without giving
details on the error that happened. Fix that by providing a more detailed
error message.

Output old:

ERROR YamlParser yaml_parser.cpp:886 Failed to parse YAML content from /root/imx283.yaml

Output new:

ERROR YamlParser yaml_parser.cpp:627 /root/imx283.yaml:72:8 could not find expected ':' while scanning a simple key
ERROR YamlParser yaml_parser.cpp:886 Failed to parse YAML content from /root/imx283.yaml

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>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-05 22:29:57 +02:00
Stefan Klug
9fc86dc02a libipa: agc_mean_luminance: Rename yaml key from exposure-time to exposureTime
In d0478c41f4 ("libcamera: Rename "shutter speed" to "exposure time"")
the tuning file entry "shutter" was renamed to "exposure-time". As the
tuning files use camel cased key names, change "exposure-time" to
"exposureTime" for consistency. It doesn't break our users setups as
there are no tuning files using that entry in the wild (at least
officially).

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-04 17:09:26 +01:00
Jacopo Mondi
cf0c56f7e0 libcamera: mali-c55: implement support for ScalerCrop
Implement support for the ScalerCrop control that allows to apply a
digital zoom to the captured streams.

Initialize the camera controls at camera registration time and update
them at configure time as the sensor's analogue crop size might change
depending on the desired Camera configuration.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Jacopo Mondi
d5c61dfdef libcamera: mali-c55: Enable usage of scaler
The Mali C55 ISP has a resizing pipeline that allows to crop and scale
images.

So far the mali-c55 pipeline has only supported cropping without using
the scaling functionalities.

Now that the kernel has gained support for the scaling operations, make
the libcamera pipeline use it by combining it with a first cropping step
to align the input and output images FOV ratio, and then scale to the
desired output size.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Daniel Scally
0ce849ab38 libcamera: mali-c55: Enable links between resizer and video node
The mali-c55 driver now expects links to video devices to be enabled
in order for those devices to be streamed from / to. Enable the media
link between the resizers and their associated video device to fulfil
the requirement.

Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Daniel Scally
6925d043f8 libcamera: mali-c55: Correct input/output format representation
At present we configure raw streams by looping through the pixel
formats we support and finding one with an associated media bus
format code that the sensor can produce. In the new representation
of raw data from the kernel driver this will not work - the sensor
could produce 8, 10, 12, 14 or 16 bit data and the ISP will force
it to RAW16, which is the only actually supported output.

To fix the issue move to simply finding a pixel format with a bayer
order that matches that of the media bus format produced by the
sensor. If the sensor can produce multiple formats with the same
bayer order use the one with the largest bitdepth.

Finally, remove the claim to support RAW formats of less than 16 bits.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Jacopo Mondi
4607866bbe libcamera: mali-c55: Propagate CSI-2 format to ISP
The latest version of the Mali C55 driver has changed the format
accepted by the ISP sink pad to be the 20-bit wide.

The CSI-2 receiver handles the format expansion internally by
propagating the sensor produced format from its sink to the 20-bit
expanded version on its source pad.

Instead of re-applying the sensor format to the CSI-2 receiver source
pad (which is now an invalid operation) read from there the format
propagated by the driver internally and further propagate it to the ISP
subdevice.

Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Daniel Scally
673c785de1 libcamera: bayer_format: Add 20-bit bayer formats
Add support for the 20-bit bayer formats to libcamera's BayerFormat class.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Jacopo Mondi
9bda95ab7e libcamera: v4l2-subdevice: Add Mali C55 media bus formats
Add support in the mediaBusFormatInfo map in the v4l2-subdevice.c file
for the media bus formats used by the Mali C55 ISP.

Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Jacopo Mondi
2dddbf5fb0 include: media-bus-formats: Add Mali-C55 mbus codes
Add media bus codes introduced by the Mali C55 ISP support to describe
the 20-bit input formats supported by the ISP. This manual addition is
a temporary measure until the kernel driver changes are merged, from
which point this will be managed through the usual merge of the upstream
kernel headers.

Add the following formats

- MEDIA_BUS_FMT_RGB202020_1X60

  for processed input formats
  https://lore.kernel.org/linux-media/20241106100534.768400-2-dan.scally@ideasonboard.com/

- MEDIA_BUS_FMT_SBGGR20_1X20
  MEDIA_BUS_FMT_SGBRG20_1X20
  MEDIA_BUS_FMT_SGRBG20_1X20
  MEDIA_BUS_FMT_SRGGB20_1X20

  for the RAW bayer input format
  https://lore.kernel.org/linux-media/20241106100534.768400-3-dan.scally@ideasonboard.com/

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Daniel Scally
9b68a14bfd libcamera: mali-c55: Add stride and size to rawConfig
Complete the RAW StreamConfiguration by populating the frame stride and
the frame size.

Set the minimum required alignment to 4 bytes as the Mali C55 ISP output
expands RAW output to 16 bits and a RAW Bayer macro-pixel requires
two samples to be complete.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Daniel Scally
313bebc492 libcamera: mali-c55: Remove MaliC55CameraData::mbusCodes()
The MaliC55CameraData::mbusCodes() function is unused. Remove it.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Daniel Scally
dac4ffe58f libcamera: mali-c55: Simplify bufferReady()
The PipelineHandler::completeBuffer() base class function returns
a boolean to indicate if there still are pending buffers in the
Request.

Simplify the bufferReady() function in the Mali-C55 pipeline handler
using the completeBuffer() return value.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Daniel Scally
3ed4e65f45 libcamera: mali-c55: Init camera properties
Initialise the camera properties using the CameraSensor properties.

Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Jacopo Mondi
0caaf7498d libcamera: mali-c55: Limit ISP input size
The Mali-C55 ISP has a minimum input size limit of 640x480.

Filter out resolutions smaller than this when selecting the
sensor format. While at it, rename 'maxYuvSize' to a more
appropriate 'minSensorSize'.

Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Jacopo Mondi
a10fcffcca libcamera: mali-c55: Limit max size to sensor resolution
The Mali C55 ISP cannot upscale. The maximum allowed output size
is the sensor's resolution.

For RAW streams this is already handled in adjustRawSizes(), while
for processed streams the maximum allowed resolution was wrongly
set to the ISP maximum output size (8192x8192).

Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-12-04 13:54:16 +00:00
Stefan Klug
db3999897a libipa: Drop Matrix class
There are no users of the libipa::Matrix class anymore. Drop it.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-03 17:47:15 +01:00
Stefan Klug
9048d135b5 rkisp1: Use Matrix class from libcamera
Use the Matrix class from libcamera/internal in the rkisp IPA so that
the libipa one can be dropped later.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-03 17:47:15 +01:00
Stefan Klug
460a955618 libipa: Use Matrix class from libcamera
Use the Matrix class from libcamera/internal in libipa so that the one
from libipa can be dropped later.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-03 17:47:15 +01:00
Stefan Klug
0c43b77759 ipa: rpi: ccm: Replace local matrix implementation with the libcamera one
The RaspberryPi IPA contains a private Matrix3x3 class inside the ccm
algorithm. Replace it with the Matrix class available in
libcamera/internal.

While at it, mark the matrices RGB2Y and Y2RGB as static const.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Naushir Patuck <naush@raspberrypi.com>
2024-12-03 17:47:15 +01:00
Stefan Klug
5b7f89d9b8 libcamera: internal: Add Matrix class to build
Add the new Matrix class to the build.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-03 17:47:15 +01:00
Stefan Klug
80f21e78a6 libcamera: internal: matrix: Replace vector with array in constructor
The Matrix constructor that takes a std::vector is meant and only used
to initialize a Matrix from an initializer list. Using a std::vector is
problematic for two reasons. First, it requires constructing a vector,
copying the data from the initializer list, which is an expensive
operation. Then, the vector size can't be verified at compile time,
making the constructor unsafe.

The first issue could be solved by replacing the vector with a
std::initializer_list or a Span. The second issue would require checking
the initializer list size with a static assertion, or restricting usage
of the constructor to fixed-extent spans. Unfortunately, even if the
size of initializer lists is always known at compile time, the
std::initializer_list::size() function is a compile-time constant only
for constant initializer lists. Using a span would work better, but
construction of a fixed extent span from an initializer list must be
explicit, making the API cumbersome.

We can solve all those issues by passing an std::array to the
constructor. Construction of an array from an initializer list can be
implicit and doesn't involve a copy, and the array size is a template
parameter and therefore guaranteed to be a compile-time constant.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-03 17:47:15 +01:00
Stefan Klug
056a0fe0ab libcamera: internal: Move Matrix class into libcamera namespace
The Matrix class no longer lives inside lipipa. Move it into the
libcamera namespace to account for that.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-03 17:47:15 +01:00
Stefan Klug
9d61c09462 libcamera: Copy Matrix class from libipa to libcamera
In preparation to moving the matrix implementation from libipa to
libcamera copy the corresponding files to the new location. The files
are copied without modification to make upcoming integration changes
easier to see. The new files are not included in the build and therefore
have no negative side effects on the build.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-03 17:47:15 +01:00
Stefan Klug
6f3b07e649 ipa: rpi: Rename Matrix to Matrix3x3
The upcoming patches will introduce a Matrix class into
libcamera/internal. That name clashes with the Matrix class from the
RaspberryPi ccm implementation. Rename the rpi version to Matrix3x3 to
prevent the name clash. Matrix3x3 will be replaced by the generic
implementation later.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-03 17:47:14 +01:00
Milan Zamazal
2a9b0b34f8 libcamera: software_isp: Actually apply black level from tuning data
The black level obtained from the tuning file in software ISP is
retrieved in init (because this is the standard algorithm method with
access to tuning data) and stored into context.  But the context gets
reset in configure and the black level is lost and never applied.

Let's store the black level from the tuning file into an algorithm
instance variable and put it into the context only later in configure.
This is similar to what rkisp1 IPA does with the values obtained from
the tuning file.

Fixes: 41e3d61c74 ("libcamera: software_isp: Clear IPA context on configure and stop")
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-03 14:30:18 +00:00
Stanislaw Gruszka
a43ea7ff70 qcam: Use pointer when choosing camera
In order to remove redundant camera ID lookups and comparisons switch
to pointer-based checks when choosing and switching cameras.

Co-developed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-29 22:13:20 +00:00
Stanislaw Gruszka
1a2be886c0 libcamera: software_isp: Remove unused IPAActiveState fields
Now agc struct in IPAActiveState is not used any longer. If there
will be need to have this struct, this patch can be reverted.

Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.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>
2024-11-29 22:13:15 +00:00
Stanislaw Gruszka
bb1aa92eb9 libcamera: software_isp: Initialize exposure+gain before agc calculations
On my setup, since commit fb8ad13d ("libcamera: software_isp: Move exposure+gain
to an algorithm module"), at start camera output stays very dark for dozen
of seconds, and then later slowly gets to normal. This is because existing
sensor exposure+gain settings are not used at start. We save initial
values in frameContext but in the agc algorithm we use IPA context.

Fix the problem by using in frameContext sensor values, since we already
use those in blc algorithm and change exposure type to int32_t to
unnecessary castings.

Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-29 22:13:15 +00:00
Harvey Yang
8e0e6886f7 libcamera: libipa: camera_sensor: Add GalaxyCore gc08a3 sensor properties
Provide the GalaxyCore gc08a3 camera sensor properties and registration
with libipa for the gain code helpers.

Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org>
Co-developed-by: Xing Gu <xinggu@chromium.org>
Signed-off-by: Xing Gu <xinggu@chromium.org>
Co-developed-by: Yudhistira Erlandinata <yerlandinata@chromium.org>
Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-29 16:24:48 +00:00
Harvey Yang
4076201873 libcamera: libipa: camera_sensor: Add GalaxyCore gc05a2 sensor properties
Provide the GalaxyCore gc05a2 camera sensor properties and registration
with libipa for the gain code helpers.

Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org>
Co-developed-by: Xing Gu <xinggu@chromium.org>
Signed-off-by: Xing Gu <xinggu@chromium.org>
Co-developed-by: Yudhistira Erlandinata <yerlandinata@chromium.org>
Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-29 16:24:48 +00:00
Han-Lin Chen
4d9db06d66 libcamera: add method to set thread affinity
Add method to set thread affinity to Thread class.

Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-28 17:50:55 +00:00
Yudhistira Erlandinata
d711a4c015 libcamera: Extend u16 control type
V4L2 Controls support a wide variety of types not yet supported by the
ControlValue type system.

Extend the libcamera ControlValue types to support an explicit 16 bit
unsigned integer type, and map that to the corresponding
V4L2_CTRL_TYPE_U16 type within the v4l2_device support class.

It's used on some camera metadata that is of length 16-bits,
for example JPEG metadata headers.

Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-28 17:46:50 +00:00
Yudhistira Erlandinata
86902b39d7 libcamera: Extend u32 control type
V4L2 Controls support a wide variety of types not yet supported by the
ControlValue type system.

Extend the libcamera ControlValue types to support an explicit 32 bit
unsigned integer type, and map that to the corresponding
V4L2_CTRL_TYPE_U32 type within the v4l2_device support class.

Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-28 17:46:50 +00:00
Harvey Yang
1197fff482 debayer_cpu: Replace syncing DMABUFs with DmaSyncer
As there's an existing helper class DmaSyncer that makes synchronizing
DMABUFs more easily, this patch removes the self-defined function and
reuse DmaSyncer.

Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-28 16:44:08 +00:00
Harvey Yang
39482d59fe DmaBufAllocator: Add Dma Buffer synchronization function & helper class
To synchronize CPU access with mmap and hardware access on DMA buffers,
using `DMA_BUF_IOCTL_SYNC` is required. This patch adds a function and
a helper class to allow users to sync buffers more easily.

Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-28 16:44:08 +00:00
Jacopo Mondi
562b6335d9 libcamera: v4l2_videodevice: Clarify V4L2M2MDevice
The documentation seems to suggest that to create a new M2M
execution context it is expected users to call V4L2M2MDevice::open()
multiple times on the same video device path.

It is instead expected that multiple instances of the class are
created, one for each required execution context.

Clarify it in the documentation of the V4L2M2MDevice class.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-28 17:17:40 +01:00
Barnabás Pőcze
493f198e94 treewide: Avoid some copies in range-based for loops
Most of these have been found by the `performance-for-range-copy`
check of `clang-tidy`.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-27 16:20:51 +02:00
Barnabás Pőcze
4e557e544b libcamera: Don't copy StreamConfiguration when iterating
A copy is made in the range-based for loop, and thus all modifications
done in the for loop body are lost, and not actually applied to
the object in the container.

Fix that by taking a reference in the range-based for loop.

Fixes: 4217c9f1aa ("libcamera: camera: Zero streams before validate()")
Fixes: 613d540267 ("pipeline: raspberrypi: Fix handling of colour spaces")
Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-27 16:18:45 +02:00
Daniel Scally
5d4b7e4b5b libcamera: pipelines: Draw control delays from CameraSensor properties
Rather than hard coding default delays for control values in the
pipeline handlers, pick up the ones defined in the CameraSensor
properties.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-11-27 10:52:12 +00:00
Daniel Scally
ca64f0514a libcamera: camera_sensor_properties: Add sensor control delays
Add properties covering the sensor control application delays to both
the static CameraSensorProperties definitions. The values used are
taken from Raspberry Pi's CamHelper class definitions. Where no more
specific values are known the delay struct is defined as empty and
defaults supplied through the getter function.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-11-27 10:52:12 +00:00
Laurent Pinchart
f5db849732 ipa: rkisp1: awb: Expand comment
The RGB to YCbCr conversion matrix mentioned in a comment, coming from
the hardware documentation, does not match any of the canonical matrices
specified by any standard. While researching where the values came from,
it became apparent they are likely Bt.601 limited range coefficients
rounded to 6 bits of decimal precision. Record this in comments.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:20 +02:00
Laurent Pinchart
be22d4aa77 ipa: rkisp1: awb: Use Vector and Matrix for linear algebra
Replace the manual vector and matrix calculations with usage of the
Vector and Matrix classes. This simplifies the code and improves
readability.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:20 +02:00
Laurent Pinchart
01919308e9 ipa: rkisp1: awb: Use RGB class to store colour gains
Replace the manual storage of gains in the IPA active state and frame
context with usage of the RGB class. This simplifies the code thanks to
usage of the arithmetic functions provided by the RGB class.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:20 +02:00
Laurent Pinchart
16c15c428d ipa: libipa: colour: Use Vector and Matrix for linear algebra
Replace the manual vector and matrix calculations with usage of the
Vector and Matrix classes. This simplifies the code and improves
readability.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:20 +02:00
Laurent Pinchart
29892f1c56 ipa: libipa: colour: Use the RGB class to model RGB values
The rec601LuminanceFromRGB() and estimateCCT() functions take RGB
triplets as three variables. Replace them with instances of the RGB
class and adapt the users accordingly. Only variables passed directly to
these functions are converted to RGB instances, further conversion of
IPA modules to the RGB class will be performed separately.

While at it, fix a typo in the documentation of the estimateCCT()
function.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:20 +02:00
Laurent Pinchart
cb3e3095d6 ipa: ipu3: awb: Replace Awb::RGB class with ipa::RGB
Now that libipa has a generic RGB class, replaces the local
implementation from the IPU3 AWB algorithm.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:20 +02:00
Laurent Pinchart
4251193c35 test: libipa: Add Vector class test
Add a unit test to exercize the API of the ipa::Vector class.

The test binary being called 'vector', implicit includes cause the
binary to be picked by '#include <vector>', causing builds to fail. Set
implicit_include_directories to false to avoid this, as done in commit
6cd8491258 ("test: Don't add current build directory to include
path").

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:19 +02:00
Laurent Pinchart
5ad6b3b1bb ipa: libipa: vector: Add sum() function
Add a function to calculate the sum of a vector. It will be useful for
algorithms.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:19 +02:00
Laurent Pinchart
2a29a2a6a1 ipa: libipa: vector: Add element-wise min() and max() functions
Add functions to calculate the element-wise minimum and maximum of two
vectors or of a vector and a scalar. This will be used in algorithm
implementations.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:19 +02:00
Laurent Pinchart
69544f5b7b ipa: libipa: vector: Add compound assignment operators
Extend the Vector class with compound assignment operators that match
the binary arithmetic operators.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:19 +02:00
Laurent Pinchart
f0d73c8758 ipa: libipa: vector: Add missing binary arithemtic operators
The Vector class defines multiple element-wise arithmetic operators
between vectors or between a vector and a scalar. A few variants are
missing. Add them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:19 +02:00
Laurent Pinchart
49e961ca35 ipa: libipa: vector: Generalize arithmetic operators
Instead of hand-coding all arithmetic operators, implement them based on
a generic apply() function that takes an operator-specific binary
operators. This will simplify adding missing arithmetic operators.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:19 +02:00
Laurent Pinchart
dd624b3fff ipa: libipa: vector: Rename the dot product operator*() to dot()
The Vector class defines a set of arithmetic operators between two
vectors or a vector and a scalar. All the operators perform element-wise
operations, except for the operator*() that computes the dot product.
This is inconsistent and confusing. Replace the operator with a dot()
function.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:19 +02:00
Laurent Pinchart
b68d898909 ipa: libipa: vector: Add scalar constructor
The default constructor leaves the vector data uninitialized. Add a
constructor to fill the vector with copies of a scalar value, and fix
the documentation of the default constructor.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:19 +02:00
Laurent Pinchart
bc10ffca97 ipa: libipa: vector: Add r(), g() and b() accessors
The Vector class can be useful to represent RGB pixel values. Add r(),
g() and b() accessors, similar to x(), y() and z(), along with an RGB
type that aliases Vector<T, 3>.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:18 +02:00
Laurent Pinchart
6089b5bc94 ipa: libipa: vector: Add mutable x(), y() and z() accessors
The x(), y() and z() functions of the Vector class are convenience
accessors for the first, second and third element of the vector
respectively, meant to improve readability of class users when a vector
represents coordinates in 1D, 2D or 3D space. Those accessors are
limited to immutable access to the vector elements, as they return a
copy. Extend the API with mutable accessors.

The immutable accessors are modified to return a reference to the vector
elements instead of a copy for consistency. As they are inline
functions, this should make no difference in terms of performance as the
compiler can perform the same optimizations in their case.

While at it, reorder functions to declare operators before other member
functions, to be consistent with the usual coding style.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26 19:05:18 +02:00
Laurent Pinchart
d0478c41f4 libcamera: Rename "shutter speed" to "exposure time"
The terms "shutter" and "shutter speed" are used through libcamera to
mean "exposure time". This is confusing, both due to "speed" being used
as "time" while it should be the inverse (i.e. a maximum speed should
correspond to the minimum time), and due to "shutter speed" and
"exposure time" being used in different places with the same meaning.

To improve clarity of the code base and the documentation, use "exposure
time" consistently to replace "shutter speed".

This rename highlighted another vocabulary issue in libcamera. The
ExposureModeHelper::splitExposure() function used to document that it
splits "exposure time into shutter time and gain". It has been reworded
to "split exposure into exposure time and gain". That is not entirely
satisfactory, as "exposure" has a defined meaning in photography (see
https://en.wikipedia.org/wiki/Exposure_(photography)) that is not
expressed as a duration. This issue if left to be addressed separately.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-26 19:05:17 +02:00
Laurent Pinchart
e5f8d40bad meson: Don't unnecessarily fallback to libyuv wrap
Before commit eeaa7de21b ("libcamera: pipeline: Add test pattern for
VirtualPipelineHandler") the libyuv dependency was only needed for the
Android adaptation layer. As libyuv isn't packaged by most distribution,
meson fell back to using a meson wrap if the Android adaptation layer
was enabled and the library wasn't found.

With commit eeaa7de21b, libyuv is also used by the virtual pipeline
handler, and the meson wrap fallback handling got centralized and became
unconditional, so the wrap is downloaded even if the components
depending on libyuv are all disabled. This causes unnecessary downloads
at setup time, which can be problematic on build systems without an
internet connection.

Fix this by making the wrap fallback conditional on the components that
use libyuv.

Fixes: eeaa7de21b ("libcamera: pipeline: Add test pattern for VirtualPipelineHandler")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-26 19:05:17 +02:00
Paul Elder
ea7f6faefe py: Add bindings for ControlId array information
Add python bindings for querying whether or not a ControlId is an array
type, and the size.

Example usage:
>>> cid
libcamera.ControlId(28, FrameDurationLimits[2], ControlType.Integer64)
>>> cid.isArray
True
>>> cid.size
2

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-25 22:28:26 +09:00
Geoffrey Van Landeghem
357dbc9f0e libcamera: libipa: camera_sensor_helper: add IMX290 black level
Report the default sensor black level reported by the datasheet.
Note that IMX327 and IMX462 depend on the IMX290 CameraSensorHelper.
That's fine since those sensors report the same defaults for the
black level as the Sony IMX290.

Signed-off-by: Geoffrey Van Landeghem <geoffrey.vl@gmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-11-25 11:40:51 +01:00
Geoffrey Van Landeghem
b45ff9ff3c ipa: raspberrypi: Add tuning file for IMX327 sensor
Add a default tuning file for Sony IMX327 sensor. This tuning file
is a copy of the IMX290 and is added to make the IMX327 sensor
just work without hassle. Note the extra description field to
clarify this is just an interim tuning file untill someone
provides a proper one.

Signed-off-by: Geoffrey Van Landeghem <geoffrey.vl@gmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-11-25 11:40:47 +01:00
Geoffrey Van Landeghem
99a871439b ipa: raspberrypi: Add tuning file for IMX462 sensor
Add a default tuning file for Sony IMX462 sensor. This tuning file
is a copy of the IMX290 and is added to make the IMX462 sensor
just work without hassle. Note the extra description field to
clarify this is just an interim tuning file untill someone
provides a proper one.

Signed-off-by: Geoffrey Van Landeghem <geoffrey.vl@gmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-11-25 11:40:43 +01:00
Geoffrey Van Landeghem
a49052d976 ipa: rpi: cam_helper: Add Sony IMX327
The IMX327 sensor is largely compatible with the already supported
Sony IMX290 so we can reuse the same helpers for the analogue gain
conversion functions.

Signed-off-by: Geoffrey Van Landeghem <geoffrey.vl@gmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-11-25 11:40:40 +01:00
Geoffrey Van Landeghem
8655ba6ffb libcamera: libipa: camera_sensor: Provide helper and properties for Sony IMX462
The sensor is largely compatible with the already supported
Sony IMX290 so we can reuse the same helpers for the analogue
gain conversion functions.

Signed-off-by: Geoffrey Van Landeghem <geoffrey.vl@gmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-11-25 11:40:36 +01:00
Jacopo Mondi
e07ac56066 libipa: FCQueue: Make sure FrameContext#0 is initialized
Some IPA modules, like the RkISP1 one, call FCQueue::get(0) at
IPA::start() time, before any frame context has been allocated with
FCQueue::alloc() called at queueRequest() time.

The FCQueue implementation aims to detect when a FrameContext is get()
before it is alloc()-ated, Warns about it, and initializes the
FrameContext before returning it.

In case of frame#0, a get() preceding an alloc() call is not detected
as the "frame == frameContext.frame" test returns success, as
FrameContexts are zeroed by default.

As a result, the first returned FrameContext is not initialized.

Explicitly test for frame#0 to make sure the FrameContext is initialized
if get(0) is called before alloc(0). To avoid re-initializing a frame
context, in case alloc() has been called correctly before get(),
introduce an "initialised" state variable that tracks the FrameContext
initialisation state.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-11-25 11:14:52 +01:00
Harvey Yang
9a5f91c78a libcamera: software_isp: Refactor SoftwareIsp to use DmaBufAllocator::exportBuffers
As the helper function DmaBufAllocator::exportBuffers is added, we can
avoid some code duplication in SoftwareIsp as well.

Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-20 10:47:27 +00:00
Harvey Yang
2716a95852 libcamera: virtual: Read config and register cameras based on the config
This patch introduces the configuration file for Virtual Pipeline
Handler. The config file is written in yaml, and the format is
documented in `README.md`.

The config file will define the camera with IDs, supported formats and
image sources, etc. In the default config file, only Test Patterns are
used. Developers can use real images loading if desired.

Signed-off-by: Konami Shu <konamiz@google.com>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Co-developed-by: Yunke Cao <yunkec@chromium.org>
Signed-off-by: Yunke Cao <yunkec@chromium.org>
Co-developed-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-20 10:47:27 +00:00
Harvey Yang
61195be6c8 libcamera: virtual: Add ImageFrameGenerator
Besides TestPatternGenerator, this patch adds ImageFrameGenerator that
loads real images (jpg / jpeg for now) as the source and generates
scaled frames.

Signed-off-by: Konami Shu <konamiz@google.com>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Co-developed-by: Yunke Cao <yunkec@chromium.org>
Signed-off-by: Yunke Cao <yunkec@chromium.org>
Co-developed-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-20 10:47:27 +00:00
Harvey Yang
eeaa7de21b libcamera: pipeline: Add test pattern for VirtualPipelineHandler
Add a test pattern generator class hierarchy for the Virtual
pipeline handler.

Implement two types of test patterns: color bars and diagonal lines
generator and use them in the Virtual pipeline handler.

A shifting mechanism is enabled. For each frame, the image is shifted to
the left by 1 pixel. It drops FPS though.

Add a dependency for libyuv to the build system to generate images
in NV12 format from the test pattern.

Signed-off-by: Konami Shu <konamiz@google.com>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Co-developed-by: Yunke Cao <yunkec@chromium.org>
Signed-off-by: Yunke Cao <yunkec@chromium.org>
Co-developed-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-20 10:47:27 +00:00
Harvey Yang
3a884ebfe4 libcamera: virtual: Add VirtualPipelineHandler
Add VirtualPipelineHandler for more unit tests and verfiy libcamera
infrastructure works on devices without using hardware cameras.

Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-20 10:47:27 +00:00
Harvey Yang
670bbf3dc2 libcamera: Remove PipelineHandler Fatal check of non-empty MediaDevices
The Fatal check of having at least one MediaDevice was to prevent
pipeline handler implementations searching and owning media devices with
custom conventions, instead of using the base function
|acquireMediaDevice|. It also has the assumption that there's at least
one media device to make a camera work.

Now that the assumption will be broken by the virtual pipeline handler
added in the following patches, and developers should be aware of the
available functions in the base class to handle media devices, the Fatal
check is no longer needed.

Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
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>
2024-11-20 10:47:27 +00:00
Harvey Yang
168488275a libcamera: add DmaBufAllocator::exportBuffers()
Add a helper function exportBuffers in DmaBufAllocator to make it easier
to use.

It'll be used in Virtual Pipeline Handler and SoftwareIsp.

Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-20 10:47:27 +00:00
Robert Mader
83c5ad0fac Add .editorconfig file
To make contributing to libcamera more fun, see
https://editorconfig.org/

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-19 23:57:09 +00:00
Naushir Patuck
934bbfce24 ipa: rpi: awb: Disable CT search bias for Grey World AWB
If grey world AWB is setup in the tuning file, the CT curve will either
be missing or invalid. Disable biasing the statistics for the search in
such cases.

Fixes: ea8fd63d93 ("ipa: rpi: awb: Add a bias to the AWB search")
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-19 11:00:14 +00:00
Daniel Scally
d5217b1602 ipa: rpi: Use centralised libipa helpers
Use the centralised libipa helpers rather than open coding common
functions.

Signed-off-by: Daniel Scally <dan.scally@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>
2024-11-18 15:48:25 +00:00
Daniel Scally
1cc6d926ac ipa: rkisp1: Use centralised libipa helpers
Use the centralised libipa helpers instead of open-coding common
functions.

Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-18 15:48:25 +00:00
Daniel Scally
edfe10997b ipa: ipu3: Use centralised libipa helpers
Use the centralised libipa helpers instead of open coding common
functions.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-18 15:48:25 +00:00
Daniel Scally
b1439c87d1 ipa: libipa: Add colour helpers
We start to have some functions relating to colour that are
effectively identical crop up across the IPA modules. Add a file
allowing those to be centralised within libipa so that a single
implementation can be used in all of the IPAs.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-18 15:48:25 +00:00
Laurent Pinchart
5c71df927d libcamera: yaml_parser: Use std::from_chars()
std::from_chars(), introduced in C++17, is a fast, locale-independent
string-to-arithmetic conversion function. The C++ standard library
provides overloads for all integer types, making it a prime candidate to
replace the manual handling of integer sizes in the YamlParser string to
integer conversion.

Compared to std::strtol(), std::from_chars() doesn't recognize the '0x'
prefix or '+' prefix, and doesn't ignore leading white space. As the
YamlParser doesn't require those features, std::from_chars() can be used
safely, reducing the amount of code.

C++17 also requires the standard C++ library to provide overloads for
floating-point types, but libc++ does not implement those. The float and
bool implementations of YamlParser::Getter::get() are therefore kept
as-is.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-13 15:38:18 +02:00
Stefan Klug
6d9baefca8 ipa: libipa: Add data accessor to Histogram
For debugging purposes it is helpful to access the internal data of the
histogram.  Add an accessor for that.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-13 11:47:06 +01:00
Stefan Klug
f328b61f66 ipa: rkisp1: Add debug metadata support to the rkisp1
Add a DebugMetadata helper to the context and add the corresponding
plumbing.  This is all that is needed to support debug metadata in an
IPA.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-13 11:47:06 +01:00
Stefan Klug
87431d1cff ipa: rkisp1: Add constructor to the ipa context
Initialization using the initializer list is cumbersome and requires
modifications to the list whenever the context is modified. Fix that by
adding a proper constructor to the context.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-13 11:47:06 +01:00
Stefan Klug
f7121716db utils: Add script to generate control_ids_debug.yaml
For flexible debugging it is helpful to minimize the roundtrip time.
This script parses the source tree and looks for usages of

set<type>(controls::debug::Something,

and adds (or removes) the controls as necessary from the yaml
description. It is meant to be used during development to ease the
creation of the correct yaml entries.

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>
2024-11-13 11:47:06 +01:00
Stefan Klug
d0e30e0ffc libcamera: Add a DebugMetadata helper
Debug metadata often occurs in places where the metadata control list is
not available e.g. in queueRequest() or processStatsBuffer() or even in
a class far away from the metadata handling code. It is therefore
difficult to add debug metadata without adding lots of boilerplate
code. This can be mitigated by recording the metadata and forwarding it
to the metadata control list when it becomes available. To solve the
issue of code that is far away from the metadata context, add a chaining
mechanism to allow loose coupling at runtime.

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>
2024-11-13 11:47:06 +01:00
Stefan Klug
af0ca816b8 libcamera: Add debug control space
Add a new 'debug' controls namespace for the upcoming implementation of
debug metadata. While at it, sort the entries alphabetically.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-13 11:47:06 +01:00
Kieran Bingham
dcb90f13cf CameraManager: Ensure we cleanup on failure
If the CameraManager fails to initialise at startup during
CameraManager::Private::init(), then the run() function will prepare the
thread for operations, but the thread will immediately close without
executing any cleanup.

This can leave instantiated objects such as the EventNotifier registered
by the udev enumerator constructed in a thread which no longer exists.
The destructor of those objects can then fire an assertion that they are
being executed from an incorrect thread while performing their cleanup.

Ensure that the failure path does not result in reporting thread
ownership assertions by performing cleanup correctly on the
CameraManager thread before it closes.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-11 14:18:02 +00:00
Jacopo Mondi
8fceb6ab1d libcamera: Rationalize IPA and handlers names
The names used by the IPA interface and the names used for buffer
completions handlers in libcamera clash in the use of the term "buffer".

For example video device buffer completion handler is called
"bufferReady" and the IPA event to ask the IPA to compute parameters are
called "fillParamsBuffers". This makes it hard to recognize which
function handles video device completion signals and which ones handle
the IPA interface events.

Rationalize the naming scheme in the IPA interface function and events
and the signal handlers in the pipelines,  according to the
following table. Remove the name "buffer" from the IPA interface events
and events handler and reserve it for the buffer completion handlers.
Rename the IPA interface events and function to use the 'params' and
'stats' names as well.

IPA Interface:

- fillParamsBuffer -> computeParams   [FUNCTION]
- processStatsBuffer -> processStats  [FUNCTION]
- paramFilled -> paramsComputed       [EVENT]

Pipeline handler:

- bufferReady -> videoBufferReady     [BUFFER HANDLER]
- paramReady -> paramBufferReady      [BUFFER HANDLER]
- statReady -> statBufferReady        [BUFFER HANDLER]
- paramFilled -> paramsComputed       [IPA EVENT HANDLER]

Cosmetic change only, no functional changes intended.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-11 14:34:57 +01:00
Milan Zamazal
2cbf863f3f libcamera: software_isp: Clean up pending requests on stop
PipelineHandler::stop() calls stopDevice() method to perform pipeline
specific cleanup and then completes waiting requests.  If any queued
requests remain, an assertion error is raised.

Software ISP stores request buffers in
SimpleCameraData::conversionQueue_ and queues them as V4L2 signals
bufferReady.  stopDevice() cleanup forgets to clean up the buffers and
their requests from conversionQueue_, possibly resulting in the
assertion error.  This patch fixes the omission.

The problem wasn't very visible when
SimplePipelineHandler::kNumInternalBuffers (the number of buffers
allocated in V4L2) was equal to the number of buffers exported from
software ISP.  But when the number of the exported buffers was increased
by one in commit abe2ec64f9, the assertion
error started pop up in some environments.  Increasing the number of the
buffers much more, e.g. to 9, makes the problem very reproducible.

Each pipeline uses its own mechanism to track the requests to clean up
and it can't be excluded that similar omissions are present in other
places.  But there is no obvious way to make a common cleanup for all
the pipelines (except for doing it instead of raising the assertion
error, which is probably undesirable, in order not to hide incomplete
pipeline specific cleanups).

Bug: https://bugs.libcamera.org/show_bug.cgi?id=234
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-08 03:45:52 +02:00
Milan Zamazal
2cc52d6835 libcamera: simple: Track requests in conversionQueue_
Simple pipeline retrieves the requests to complete from the
conversionQueue_.  This patch stores the requests in conversionQueue_
explicitly.  This explicit tracking is supposed to be preferred to
implicit retrieval and it simplifies the completion code a bit here and
in the followup patch that adds request cleanup on stop.

The change as implemented assumes that all the buffers in each of the
conversionQueue_ elements point to the same request, the one specified.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-08 03:45:49 +02:00
Milan Zamazal
fe68cd0d7d libcamera: pipeline_handler: Provide cancelRequest
Let's extract the two occurrences of canceling a request to a common
helper.  This is especially useful for the followup patch, which needs
to cancel a request from outside.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-08 03:45:36 +02:00
Jacopo Mondi
e1d45a17f7 libcamera: rkisp1: Create main buffer pool out of if(!isRaw)
The "useDewarper_" class variable is set to true during configure
only if the configuration is !isRaw.

The main path buffer pool creation can thus be moved out of the
if (!isRaw) block at allocateBuffers() time.

Cosmetic change that will make it easier to create a buffer pool
for the main and self paths unconditionally in future.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2024-11-05 18:14:06 +01:00
Laurent Pinchart
5cb45181d7 libcamera: camera_sensor: Sort factories by priority
In order to support a default implementation for camera sensors when no
better implementation matches, libcamera needs to try "specialized"
implementations first and pick the default last. Make this possible by
adding a priority value for factories. Newly registered factories are
inserted in the factories list sorted by descending priority, and the
default factory uses a negative priority to be inserted as the last
element.

This mechanism may be a bit overkill in the sense that there is no
expected use cases for priorities other than trying the default last,
but the implementation is simple and easy to understand.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-11-05 18:07:42 +01:00
Laurent Pinchart
aee7f8207e libcamera: camera_sensor: Create abstract base class
With a camera sensor factory in place, the next step is to create an
abstract base class that all camera sensors implement, providing a
uniform API to pipeline handler. Turn all public functions of the
CameraSensor class into pure virtual functions, and move the
implementation to the CameraSensorLegacy class.

Part of the code is likely worth keeping as common helpers in a base
class. However, to follow the principle of not designing helpers with a
single user, this commit moves the whole implementation. Common helpers
will be introduced later, along with other CameraSensor subclasses.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-11-05 18:07:42 +01:00
Jacopo Mondi
6ba23735b9 libcamera: camera_sensor: Introduce CameraSensorFactory
Introduce a factory to create CameraSensor derived classes instances by
inspecting the sensor media entity name and provide a convenience macro
to register specialized sensor handlers.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-05 18:07:42 +01:00
Jaslo Ziska
27cece6653 gstreamer: Generate controls from control_ids_*.yaml files
This commit implements gstreamer controls for the libcamera element by
generating the controls from the control_ids_*.yaml files using a new
gen-gst-controls.py script. The appropriate meson files are also changed
to automatically run the script when building.

The gen-gst-controls.py script works similar to the gen-controls.py
script by parsing the control_ids_*.yaml files and generating C++ code
for each exposed control.
For the controls to be used as gstreamer properties the type for each
control needs to be translated to the appropriate glib type and a
GEnumValue is generated for each enum control. Then a
g_object_install_property(), _get_property() and _set_property()
function is generated for each control.
The vendor controls get prefixed with "$vendor-" in the final gstreamer
property name.

The C++ code generated by the gen-gst-controls.py script is written into
the template gstlibcamerasrc-controls.cpp.in file. The matching
gstlibcamerasrc-controls.h header defines the GstCameraControls class
which handles the installation of the gstreamer properties as well as
keeping track of the control values and setting and getting the
controls. The content of these functions is generated in the Python
script.

Finally the libcamerasrc element itself is edited to make use of the new
GstCameraControls class. The way this works is by defining a PROP_LAST
enum variant which is passed to the installProperties() function so the
properties are defined with the appropriate offset. When getting or
setting a property PROP_LAST is subtracted from the requested property
to translate the control back into a libcamera::controls:: enum
variant.

Signed-off-by: Jaslo Ziska <jaslo@ziska.de>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-05 16:28:09 +00:00
Jaslo Ziska
aebc8742b0 gstreamer: Remove auto-focus-mode property from libcamerasrc
In preparation for generic support of all libcamera controls, remove the
manual handling of the auto-focus-mode property from the libcamerasrc
element.

Signed-off-by: Jaslo Ziska <jaslo@ziska.de>
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>
2024-11-05 16:28:09 +00:00
Jaslo Ziska
327b0d16a1 gstreamer: Remove auto-focus-mode property from device provider
The device provider is not supposed to have control properties, remove
the auto-focus-mode property which was introduced by accident.

Fixes: 5a142438b0 ("gstreamer: Add enable_auto_focus option to the GStreamer plugin")
Signed-off-by: Jaslo Ziska <jaslo@ziska.de>
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>
2024-11-05 16:28:09 +00:00
Laurent Pinchart
77438775b3 v4l2: v4l2_camera_proxy: Fix VIDIOC_[GS]_PARM support
v4l2-compliance reports an error due to VIDIOC_S_PARM being supported
without VIDIOC_G_PARM. Fix it by implementing VIDIOC_G_PARM. To satisfy
all compliance tests, VIDIOC_S_PARM also needs to be updated to properly
zero reserved fields.

Fixes: 5456e02d3f ("v4l2: Support setting frame rate in the V4L2 Adaptation layer")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-11-05 15:29:22 +02:00
Laurent Pinchart
f326eb4bf2 test: py: LD_PRELOAD the C++ standard library when using ASan
When the ASan runtime is linked using --as-needed, its dependency on the
C++ standard library is stripped. This results to a failure to properly
handled exceptions when a C++ dynamically loaded .so is used, as in the
Python unit tests that load the libcamera Python module:

AddressSanitizer: CHECK failed: asan_interceptors.cpp:335 "((__interception::real___cxa_throw)) != (0)" (0x0, 0x0) (tid=32679)
    #0 0x7fa2f32e6c19 in CheckUnwind /var/tmp/portage/sys-devel/gcc-13.3.1_p20241025/work/gcc-13-20241025/libsanitizer/asan/asan_rtl.cpp:69
    #1 0x7fa2f330c9fd in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /var/tmp/portage/sys-devel/gcc-13.3.1_p20241025/work/gcc-13-20241025/libsanitizer/sanitizer_common/sanitizer_termination.cpp:86
    #2 0x7fa2f3247824 in __interceptor___cxa_throw /var/tmp/portage/sys-devel/gcc-13.3.1_p20241025/work/gcc-13-20241025/libsanitizer/asan/asan_interceptors.cpp:335
    #3 0x7fa2f3247824 in __interceptor___cxa_throw /var/tmp/portage/sys-devel/gcc-13.3.1_p20241025/work/gcc-13-20241025/libsanitizer/asan/asan_interceptors.cpp:334
    #4 0x7fa2efb6da8b in operator() ../../src/py/libcamera/py_main.cpp:157
[...]

The issue has been reported in [1] and so far remains unfixed. Work
around it by preloading the C++ standard library.

[1] https://github.com/google/sanitizers/issues/934

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-05 15:29:04 +02:00
Laurent Pinchart
b3eba17213 test: py: Replace environment array with environment object
The environment for pyunittests is stored in an array. Meson provides an
environment object, which makes handling of multi-value environment
variables easier and increases code clarity. Switch to using the
environment object.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-05 15:28:33 +02:00
Laurent Pinchart
876730d805 test: py: Fix log level restore in SimpleTestMethods()
The SimpleTestMethods() function tests that incorrect calls to the
Camera.acquire() method raise an exception. Before doing so, it sets the
log level for the Camera category to FATAL, in order to avoid showing
misleading errors in the test log, and then restores the log level to
ERROR after running the test. ERROR is however not the default log
level. Restore the log level to INFO instead, in order to avoid losing
log messages in subsequent tests.

Fixes: 06cb7130c4 ("py: Add unittests.py")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
2024-11-05 15:28:13 +02:00
Laurent Pinchart
7ff6fd9774 utils: checkstyle.py: Centralize dependency handling for checkers
The checkstyle.py script depends on external tools. Those dependencies
are handled in different ways in different parts of the code. Centralize
the management of checker-specific dependencies to simplify the checkers
and output more consistent error messages.

This fixes a crash in the Pep8Formatter class when the autopep8
dependency is not found.

Fixes: 8ffaf376bb ("utils: checkstyle: Add a python formatter")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-05 03:50:12 +02:00
Laurent Pinchart
5722438754 utils: checkstyle.py: Print issues using __str__
CommitIssue and StyleIssue classes have different string
representations, which are handled by type-specific print() calls in the
code that handles the issues. This requires the user to know which type
of issue it is dealing with. Simplify that by moving the string
representation logic to a __str__() method.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-05 03:50:12 +02:00
Laurent Pinchart
b488a862df utils: checkstyle.py: Turn check() into a class method for all checkers
The check() method of StyleChecker subclasses are instance methods,
while CommitChecker subclasses use class methods. This makes unified
handling of checkers more complicated. Turn the StyleChecker check()
method into a class method, passing it the contents to be checked
directly.

While at it, fix two style issues reported by checkstyle.py.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-05 03:50:11 +02:00
Laurent Pinchart
5f7bcd93fd utils: checkstyle.py: Factor out common code to new CheckerBase class
The CommitChecker, StyleChecker and Formatter classes duplicate code.
Create a new CheckerBase class to factor out common code.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-05 03:50:11 +02:00
Johannes Kirchmair
f028b09b7b gstreamer: Implement caps negotiation for video/x-bayer
The parsing of video/x-bayer sources from string makes it possible to
use cameras providing e.g SGRBG8 streams via gst-launch.

Like:
gst-launch-1.0 libcamerasrc camera-name=<cam> ! video/x-bayer,format=grbg

Without this change the gstreamer plugin complains about "Unsupported
media type: video/x-bayer".

Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Johannes Kirchmair <johannes.kirchmair@skidata.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-04 15:35:04 +00:00
Naushir Patuck
58598f4dde pipeline: rpi: Handler controls::rpi::ScalerCrops
Handle multiple scaler crops being set through the rpi::ScalerCrops
control. We now populate the cropParams_ map in the loop where we handle
the output stream configuration items. The key of this map is the index
of the stream configuration structure set by the application. This will
also be the same index used to specify the crop rectangles through the
ScalerCrops control.

CameraData::applyScalerCrop() has been adapted to look at either
controls::ScalerCrop or controls::rpi::ScalerCrops. The latter takes
priority over the former. If only controls::ScalerCrop is provided, the
pipeline handler will apply the same scaler crop to all output streams.

Finally return all crops through the same ScalerCrops control via
request metadata. The first configure stream's crop rectangle is also
returned via the ScalerCrop control in the request metadata.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-04 17:23:57 +02:00
Naushir Patuck
7154247b86 pipeline: rpi: Pass ISP output index into platformSetIspCrop()
At this point, the index is unused, but will be in a future commit where
we can set different crops on each ISP output.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-04 17:23:56 +02:00
Naushir Patuck
d6a1d9596b pipeline: rpi: Track which ISP output is configured for a stream
Add a ispIndex field to CropParams that is used to track
which ISP output (0/1) will be used for a given stream during
configuration.

Tracking this information is required for an upcoming change where crop
rectangles can be specified for each configured stream. Currently, the
value is fixed to 0.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-04 17:23:56 +02:00
Naushir Patuck
81afca4078 pipeline: rpi: Introduce CameraData::CropParams
In preparation for assigning separate crop windows for each stream, add
a new CropParams structure that stores the existing ispCrop_ and
ispMinCropSize_ as fields. Use a new std::map to store a CropParams
structure where the map key is the index of the stream configuration in
the CameraConfiguration vector.

At preset, only a single CropParams structure will be set at key == 0 to
preserve the existing crop handling logic.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-04 17:23:55 +02:00
Naushir Patuck
6bb278c20c pipeline: rpi: Pass crop rectangle as a parameter to platformSetIspCrop()
This will be required when we program separate crop values to each ISP
output in a future commit.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-04 17:23:54 +02:00
Naushir Patuck
fb23268105 pipeline: rpi: Remove CameraData::scalerCrop_
Do not cache the scalerCrop_ parameter. The cached value is used to
update the request metadata, but since this is not an expensive
operation (and can only occur once per frame), caching it is of limited
value.

This will simplify logic in a future commit where we can specify a
crop per-output stream.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-04 17:23:54 +02:00
Naushir Patuck
dbcf6123a0 controls: rpi: Add a vendor rpi::ScalerCrops control
Add a vendor control rpi::ScalerCrops that is analogous to the current
core::ScalerCrop, but can apply a different crop to each configured
stream.

This control takes a span of Rectangle structures - the order of
rectangles must match the order of streams configured by the application.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-04 17:23:53 +02:00
Hou Qi
ff069d87e2 libcamera: formats: Change bytesPerGroup of RGB565 and RGB565_BE from 3 to 2
The RGB565 and RGB565_BE formats incorrectly specify a wrong value
of 3 bytes per group of pixels, when they actually use 2. Fix them.

Signed-off-by: Hou Qi <qi.hou@nxp.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-10-28 18:43:02 +02:00
Laurent Pinchart
19617424db ipa: libipa: Fix ExposureModeHelper function name in documentation
Previous iterations of the ExposureModeHelper class had a
setShutterGainLimits() function, which got renamed to setLimits(). The
documentation still uses the old name. Fix it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-10-28 18:34:52 +02:00
Stanislaw Gruszka
80a7ccd3ad qcam: Automatically select the camera if only one is available
When only a single camera is available, showing the camera selection
dialog is unnecessary. It's better to automatically select the available
camera without prompting the user for input.

Co-developed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-10-25 01:13:32 +03:00
Umang Jain
12b553d691 libcamera: rkisp1: Plumb the dw100 dewarper as V4L2M2M converter
Plumb the dw100 dewarper as a V4L2M2M converter in the rkisp1 pipeline
handler. If the dewarper is found, it is instantiated and buffers are
exported from it, instead of RkISP1Path. Internal buffers are allocated
for the RkISP1Path in case where dewarper is going to be used.

The RKISP1 pipeline handler now supports scaler crop control through
the converter. Register the ScalerCrop control for the cameras created
in the RKISP1 pipeline handler.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-10-24 14:04:31 +05:30
Umang Jain
485f92ac06 libcamera: rkisp1: Prepare for additional camera controls
Currently the rkisp1 pipeline handler only registers controls that are
related to the IPA. This patch prepares the rkisp1 pipeline-handler to
register camera controls which are not related to the IPA.

Hence, introduce an additional ControlInfoMap for IPA controls. These
controls will be merged together with the controls in the pipeline
handler (introduced subsequently) as part of updateControls() and
together will be registered during the registration of the camera.
This is similar to what IPU3 pipeline handler handles its controls.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-10-24 14:04:31 +05:30
Umang Jain
1b0b90a332 libcamera: converter: Add interface to support cropping capability
If the converter has cropping capability on its input, the interface
should support it by providing appropriate virtual functions. Provide
Feature::InputCrop in Feature enumeration for the same.

Provide virtual setInputCrop() and inputCropBounds() interfaces so that
the converter can implement its own cropping functionality.

The V4L2M2MConverter implements these interfaces of the Converter
interface. Not all V4L2M2M converters will have cropping ability
on its input, hence it needs to be discovered at construction time.
If the capability to crop is identified successfully, the cropping
bounds are determined during configure() time.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-10-24 14:04:31 +05:30
Umang Jain
7fad22efae libcamera: converter: Add interface for feature flags
This patch intends to extend the converter interface to have feature
flags, which enables each converter to expose the set of features
it supports.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-10-24 14:04:31 +05:30
Dave Stevenson
994588fb75 ipa: rpi: Add tuning files for OV7251
OV7251 is a mono VGA global shutter sensor that has a mainline
driver and works with libcamera.
Add the supporting files for it. The tuning is copied from OV9281.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-21 11:51:41 +01:00
Paul Elder
79893cc00f py: Add bindings for ControlId vendor information
Add python bindings for quering vendor information from a ControlId.
While at it, update __repr__ so that it also prints the vendor.

Example usage:
>>> cid
libcamera.ControlId(20, libcamera.Saturation, ControlType.Float)
>>> cid.vendor
'libcamera'

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-10-21 00:23:07 +03:00
Paul Elder
b777d8272a apps: cam: Print control vendor information when listing controls
Now that the vendor of the control can be queried, print it in
--list-controls.

Example output:
$ cam -c 1 --list-controls
Using camera platform/vimc.0 Sensor B as cam0
Control: libcamera::Brightness: [-1.000000..1.000000]
Control: libcamera::Contrast: [0.000000..2.000000]
Control: libcamera::Saturation: [0.000000..2.000000]

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-10-21 00:23:03 +03:00
Paul Elder
aafa406edd libcamera: controls: Add vendor information to ControlId
Add vendor/namespace information to ControlId, so that the vendor can be
queried from it. This is expected to be used by applications either
simply to display the vendor or for it to be used for grouping in a
UI.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-10-21 00:22:56 +03:00
Kieran Bingham
f0325383cd libcamera: pipeline: rkisp1: Fix typo in todo task
The delay values should be managed correctly. Not the dealys.

Correct accordingly.

Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-19 00:11:28 +01:00
Milan Zamazal
7cbd05dc01 libcamera: software_isp: Black level from tuning file
This patch allows obtaining a black level from a tuning file in addition
to the camera sensor helper.  If both of them define a black level, the
one from the tuning file takes precedence.

The use cases are:

- A user wants to use a different black level, for whatever reason.

- There is a sensor without known gains but with a known black level.
  Because a camera sensor helper cannot be defined without specifying
  gains, the only way to specify the black level is using the tuning
  file.  Software ISP uses its fallback gain handling in such a case.

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>
2024-10-18 23:02:08 +01:00
Milan Zamazal
7bbe26bbc4 libcamera: software_isp: Get black level from the camera helper
The black level in software ISP is unconditionally guessed from the
obtained frames.  CameraSensorHelper optionally provides the black level
from camera specifications now.  Let's use the value if available.

If the black level is not available from the given CameraSensorHelper
instance, it's still determined on the fly.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Robert Mader <robert.mader@collabora.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-18 23:02:08 +01:00
Robert Mader
41e3d61c74 libcamera: software_isp: Clear IPA context on configure and stop
Like the hardware pipelines do. Not clearing frameContexts otherwise can
trigger asserts like "Frame context for ... has been overwritten by ..."
when switching between cameras using the swISP, e.g. on phones.

Clearing the configuration and active state will become more important
with upcoming changes such as getting the black level from the camera
helper.

Fixes: 04d171e6b2 ("libcamera: software_isp: Call Algorithm::queueRequest")
Signed-off-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-18 23:02:08 +01:00
Bernhard M. Wiedemann
ae51d30468 libcamera: tracepoints: Fix copyright year for reproducible builds
The tracepoints.h file is generated from the tracepoints.h.in template
by the gen-tp-header.py script. The template contains a {{year}}
placeholder for the copyright year, which the script fills with the
current year. This breaks reproducible builds with at least the openSUSE
debugsource package.

As the gen-tp-header.py script doesn't add any copyrightable contents to
the tracepoints.h file, fix this by replacing the {{year}} placeholder
with the year of the last copyright-worthy change to tracepoints.h.in.

Signed-off-by: Bernhard M. Wiedemann <bwiedemann@suse.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-10-18 23:39:11 +03:00
Stefan Klug
2460049b67 pycamera: Add missing code for ControlTypePoint
In the python bindings ControlTypePoint is not handled in the
corresponding conversion functions. Add that.

While at it, sort the listings in the same order as the enum in
controls.h.

Fixes: 200d535ca8 ("libcamera: controls: Add ControlTypePoint")
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>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-18 17:17:07 +01:00
Stefan Klug
ed3f3f6aa6 libcamera: controls: Add missing size to control_type<Point>
The size member is missing in control_type<Point>. This did not do any
harm because the only control using the Point type was an array control.
As soon as a control-id with a non-array Point control gets defined, the
compile fails with:

error: size is not a member of libcamera::details::control_type<libcamera::Point>

Fixes: 200d535ca8 ("libcamera: controls: Add ControlTypePoint")
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>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-18 17:17:07 +01:00
Stefan Klug
4c131dfa5c ipa: rkisp1: algorithms: awb: Check for correct stats type
Sometimes the ISP produces statistics only with a subset of statistic
types being valid. It doesn't happen normally, but was observed in the
wild. Check for the RKISP1_CIF_ISP_STAT_AWB bit to prevent using invalid
or outdated data. As it doesn't happen regularly add an error message to
get notified when it happens.

For simpler code structure, the ColourTemperature metadata entry gets
written unconditionally and overwritten later if needed.

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>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-18 17:17:07 +01:00
Stefan Klug
0e0e32b189 ipa: rkisp1: algorithms: agc: Check for correct stats type
Sometimes the ISP produces statistics only with a subset of statistic
types being valid. It doesn't happen normally, but was observed in the
wild. Check for the RKISP1_CIF_ISP_STAT_AUTOEXP bit to prevent using
invalid or outdated data. As it doesn't happen regularly add an error
message to get notified when it happens.

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>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-18 17:17:07 +01:00
Paul Elder
c8d261608a libcamera: MappedFrameBuffer: Fix typo in comment formatting
Fix typo in comment block formatting.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-18 08:37:13 +01:00
Umang Jain
3299f84de7 libcamera: rkisp1: Maintain alphabetical order of forward declarations
Alphabetical order of Forward declarations should be maintained hence,
'class V4L2Subdevice' should come after 'class SensorConfiguration'.
Fix it.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-10-15 10:31:52 +05:30
Umang Jain
a2be725d26 libcamera: rkisp1: Rectify SensorConfiguration check
The 'found' flag was mistakenly understood that a compatible sensor
format has been found when a sensor configuration is passed in. However,
'found' related to the stream configuration's pixelformat, whether it is
supported by the RkISP1Path video node or not. It does not relate to the
sensor format, hence the check:

	if (sensorConfig && !found)

doesn't make sense.

Rectify the above check with:

	if (sensorConfig && !rawFormat.isValid())

to ensure a sensor format compatible with sensor configuration has been
set to rawFormat.

Fixes: 047d647452 ("libcamera: rkisp1: Integrate SensorConfiguration support")
Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-10-15 10:31:47 +05:30
Umang Jain
326e0aa834 libcamera: rkisp1: Use const reference for sensor configuration
User-provided sensor configuration is never meant to be altered,
hence pass SensorConfiguration by `const` reference in
RkISP1Path::validate().

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-10-15 10:31:44 +05:30
Stefan Klug
302e7e60b1 gitignore: Add venv directory to gitignore
The python venv module is the standard way of creating virtual python
environments. 'venv' is a commonly used name for the corresponding
directory. For example in the tuning docs we propose to execute 'python
-m venv venv' to setup a local virtual environment.  During development
I often have these scattered around in the source tree and they show up
as untracked files in git. Add venv to .gitignore to prevent that.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-09 14:36:47 +02:00
Umang Jain
3d0ca251e1 libcamera: rkisp1: Clamp stream configuration to ISP limit on raw path
Commit 761545407c ("pipeline: rkisp1: Filter out sensor sizes not
supported by the pipeline") introduced a mechanism to determine maximum
supported sensor resolution and filter out resolutions that cannot be
supported by the ISP.

However, it missed to update the raw stream configuration path, where
it should have clamped the raw stream configuration size to the maximum
sensor supported resolution.

This patch fixes the above issue and can be confirmed with IMX283
on i.MX8MP:

From:
($) cam -c1 -srole=raw,width=5472,height=3072
INFO Camera camera.cpp:1197 configuring streams: (0) 5472x3648-SRGGB12
ERROR RkISP1 rkisp1_path.cpp:425 Unable to configure capture in 5472x3648-SRGGB12
Failed to configure camera
Failed to start camera session

To:
($) cam -c1 -srole=raw,width=5472,height=3072
INFO Camera camera.cpp:1197 configuring streams: (0) 4096x3072-SRGGB12
cam0: Capture until user interrupts by SIGINT
536.082380 (0.00 fps) cam0-stream0 seq: 000000 bytesused: 25165824
536.182378 (10.00 fps) cam0-stream0 seq: 000001 bytesused: 25165824
536.282375 (10.00 fps) cam0-stream0 seq: 000002 bytesused: 25165824
...

Fixes: 761545407c ("pipeline: rkisp1: Filter out sensor sizes not supported by the pipeline")
Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-10-09 16:40:31 +05:30
Umang Jain
047d647452 libcamera: rkisp1: Integrate SensorConfiguration support
Integrate the RkISP1 pipeline handler to support sensor configuration
provided by applications through CameraConfiguration::sensorConfig.

The SensorConfiguration must be validated on both RkISP1Path (mainPath
and selfPath), so the parameters of RkISP1Path::validate() have been
updated to include sensorConfig.

The camera configuration will be marked as invalid when the sensor
configuration is supplied, if:
- Invalid sensor configuration (SensorConfiguration::isValid())
- Bit depth not supported by RkISP1 pipeline
- Sensor configuration output size is larger than maximum supported
  sensor's size on RkISP1 pipeline
- No matching sensor configuration output size supplied by the sensor

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Tested-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-10-09 16:40:23 +05:30
Laurent Pinchart
fc761ffe49 hooks: pre-push: Verify that co-authors have a SoB line
The Co-developed-by tag must be followed by a corresponding SoB line.
Enforce this rule in the git pre-push hook.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-08 18:06:30 +03:00
Umang Jain
b20dfa95d2 Documentation: guides: Fix FileSink source link
Fix the 'class FileSink' source link which got broken due to
commit 84ad104499 ("Move test applications to src/apps/").

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-10-08 19:17:05 +05:30
Naushir Patuck
ea8fd63d93 ipa: rpi: awb: Add a bias to the AWB search
In the case of an AWB search failure, the current algorithm logic will
return a point on the CT curve closest to where the search finisned.
This can be quite undesirable. Instead, add some bias params to the AWB
algorithm which will direct the search to a set CT value in the case
where statistics become unreliable causing the search to fail.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-08 09:54:04 +01:00
Naushir Patuck
692d0d66ac ipa: rpi: awb: Add a const for the default colour temperature
A default CT of 4500K is used in a couple of places. Add a constexpr
value for the default CT value and use it instead.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-08 09:54:04 +01:00
Umang Jain
3513db6cc6 libcamera: camera: Fix CameraConfiguration spelling error
The documentation of CameraConfiguration::validate() has one
misspelled "CameraConfiguration". Fix it.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-10-08 11:22:27 +05:30
Milan Zamazal
a7d573df53 libcamera: software_isp: Improve wording in a comment
A minor wording improvement suggested on refactoring review.

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>
2024-10-03 14:44:03 +01:00
Barnabás Pőcze
e879a86979 libcamera: yaml_parser: Take string keys in std::string_view
In many cases a static string literal is used as key. Thus
having the argument type be `const std::string&` is suboptimal
since an `std::string` object needs to be constructed before
the call.

C++17 introduced `std::string_view`, using which the call
can be done with less overhead, as the `std::string_view`
is non-owning and may be passed in registers entirely.

So make `YamlObject::{contains,operator[]}` take the string keys
in `std::string_view`s.

Unfortunately, that is not sufficient yet, because `std::map::find()`
takes an reference to `const key_type`, which would be `const std::string&`
in the case of `YamlParser`. However, with a transparent comparator
such as `std::less<>` `std::map::find()` is able to accept any
object as the argument, and it forwards it to the comparator.

So make `YamlParser::dictionary_` use `std::less<>` as the comparator
to enable the use of `std::map::find()` with any type of argument.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-10-03 01:36:29 +03:00
Harvey Yang
3088e14e81 libcamera: android: Add face detection control support
Allow Android HAL adapter to pass the face detection metadata control to
the pipeline and also send face detection metadata to the camera client
if the pipeline generates it.

Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
2024-10-01 21:02:37 +02:00
Yudhistira Erlandinata
dada914339 libcamera: control_ids_draft: Add face detection controls
Add FaceDetectMode, FaceDetectFaceRectangles, FaceDetectFaceScores,
and FaceDetectFaceLandmark. Also add ControlTypePoint for supporting
FaceDetectFaceLandmark.

Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>
Co-developed-by: Becker Hsieh <beckerh@chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
2024-10-01 21:02:12 +02:00
Yudhistira Erlandinata
200d535ca8 libcamera: controls: Add ControlTypePoint
Add a control_type<> specialization for libcamera::Point to allow
storing data of that type in a ControlValue instance.

The new control type will be used by controls introduced in the
next patches.

Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>
Co-developed-by: Becker Hsieh <beckerh@chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-10-01 21:01:49 +02:00
Yudhistira Erlandinata
724bbf7d25 libcamera: geometry: Add two-point Rectangle constructor
Add a constructor to the Rectangle class that accepts two points.

The constructed Rectangle spans all the space between the two given
points.

Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org>
Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
2024-10-01 21:01:25 +02:00
Jacopo Mondi
2f621920ea libcamera: geometry: Clarify Rectangle's top-left corner
The libcamera::Rectangle class allows defining rectangles regardless of
the orientation of the reference system where a rectangle is used in.

This implies that, depending on the reference system in use, the
rectangle's top-left corner, as defined by libcamera, doesn't correspond
to the visual top-left position.

         ^
         |
         |      -------------------
         |      ^                 | h
         |      |                 |
        y|      o---->-------------
         |               w
          ------------------------------->
         (0,0)  x

         (0,0)  x
           ------------------------------>
          |              w
         y|     o---->-------------
          |     |                 | h
          |     v                 |
          |     -------------------
          |
          V

Clarify that a Rectangle's top-left corner corresponds to the point
with the smaller x and y coordinates and that the horizontal and
vertical dimensions are obtained by positive increments along the
corresponding axes.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
2024-10-01 20:56:40 +02:00
Laurent Pinchart
8d22064082 libcamera: Replace last users of math.h
As described in the coding style document, libcamera favours <cmath>
over <math.h>. Replace the last few occurrences of the latter with the
former and adapt the code accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2024-09-30 10:56:49 +03:00
Laurent Pinchart
09c291192c ipa: rpi: Replace last users of math.h
As described in the coding style document, libcamera favours <cmath>
over <math.h>. Replace the last few occurrences of the latter with the
former in the Raspberry Pi IPA and adapt the code accordingly. In some
cases, the <math.h> include is simply dropped as it isn't needed.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2024-09-30 10:56:49 +03:00
Laurent Pinchart
fa2dfd55cc libcamera: Replace usage of lroundf() with std::lround()
As explained in the coding style document, usage of std::lround() is
preferred over lroundf() as it picks the correct function based on
the argument type. Replace calls to lroundf() with std::lround() through
libcamera.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-09-30 10:56:48 +03:00
Laurent Pinchart
8b378a5606 ipa: rpi: Use std::abs()
As explained in the coding style document, usage of std::abs() is
preferred over abs() or fabs() as it picks the correct function based on
the argument type. Replace calls to abs() and fabs() with std::abs() in
the Raspberry Pi algorithms.

This fixes a reported warning from clang:

../src/ipa/rpi/controller/rpi/awb.cpp:508:6: error: using integer absolute value function 'abs' when argument is of floating point type [-Werror,-Wabsolute-value]
        if (abs(denominator) > eps) {
            ^
../src/ipa/rpi/controller/rpi/awb.cpp:508:6: note: use function 'std::abs' instead
        if (abs(denominator) > eps) {
            ^~~
            std::abs

Reported-by: Maarten Lankhorst <dev@lankhorst.se>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-30 10:56:48 +03:00
Laurent Pinchart
e6da224926 libcamera: controls: Handle enum values without a cast
When constructing a ControlValue from an enum value, an explicit cast to
int32_t is needed as we use int32_t as the underlying type for all
enumerated controls. This makes users of ControlValue more complex. To
simplify them, specialize the control_type template for enum types, to
support construction of ControlValue directly without a cast.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-30 10:56:48 +03:00
Laurent Pinchart
4cb3380f4d libcamera: v4l2_videodevice: Add getSelection() function
The V4L2VideoDevice class implements setSelection() but not
getSelection(). The latter is useful for instance to query crop bounds.
Implement the function.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-09-30 10:56:48 +03:00
Laurent Pinchart
b2538c80b9 apps: cam: Print an error when outputting DNG and DNG support is missing
When DNG support is missing, the cam application ignores the .dng suffix
of the file pattern and writes raw binary data instead, without
notifying the user. This leads to confusion. Fix it by printing an error
message.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-09-30 10:56:48 +03:00
Laurent Pinchart
2e47324860 apps: Replace HAVE_DNG with HAVE_TIFF
Support for DNG capture is conditioned by the availability of libtiff,
which is indicated by the HAVE_TIFF macro set by meson. The dng_writer.h
header then defines HAVE_DNG, which is used in a couple of places to
conditionally compile DNG-related code. Most of the other locations
where conditional compilation is required use HAVE_TIFF.

Using both HAVE_TIFF and HAVE_DNG is confusing. HAVE_DNG would be a
better name, but as the macro is defined in dng_writer.h, it would
require all files that need to test for DNG support to include that
header. Failure to include it (directly or indirectly) would result in
the code covered by the macro to be silently disabled.

To avoid the confusion, standardize on using HAVE_TIFF everywhere and
drop HAVE_DNG.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-09-30 10:56:48 +03:00
Umang Jain
761545407c pipeline: rkisp1: Filter out sensor sizes not supported by the pipeline
It is possible that the maximum sensor size (returned by
CameraSensor::resolution()) is not supported by the pipeline. In such
cases, a filter function is required to filter out resolutions of the
camera sensor, which cannot be supported by the pipeline.

Introduce the filter function filterSensorResolution() in RkISP1Path
class and use it for validate() and generateConfiguration(). The
maximum sensor resolution is picked from that filtered set of
resolutions instead of CameraSensor::resolution().

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-09-30 13:05:56 +05:30
Umang Jain
e85c7ddd38 libcamera: rkisp1: Eliminate hard-coded resizer limits
The minResolution_ and maxResolution_ limits are dynamically queried
in populateFormats() from the RkISP1Path video node. Therefore,
initializing these limits with the resizer limits in the constructor is
unnecessary.

This change allows us to remove the hard-coded max/min resolution limits
of the resizer from RkISP1Path, simplifying its constructor further.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
2024-09-28 11:09:32 +05:30
Robert Mader
abe2ec64f9 pipeline: simple: Increase buffer count to four
Which is not only what many other pipeline handlers use, but also a good
lower limit when dealing with DRM and similar APIs. Even Mesas EGL and
Vulkan WSI implementations use for the reason outlined in mesa commit
992a2dbba80aba35efe83202e1013bd6143f0dba:
> When the compositor is directly scanning out from the application's buffer it
> may end up holding on to three buffers. These are the one that is is currently
> scanning out from, one that has been given to DRM as the next buffer to flip
> to, and one that has been attached and will be given to DRM as soon as the
> previous flip completes. When we attach a fourth buffer to the compositor it
> should replace that third buffer so we should get a release event immediately
> after that. This patch therefore also changes the number of buffer slots to 4
> so that we can accomodate that situation.

Given the popularity of this buffer number the bump should be unlikely
to cause problems. At the same time it may help with performance or
even work around glitches.

The previous number was introduced in commit
a8964c28c8 without mentioning a specific
reason against the change at hand.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 16:40:15 +01:00
Milan Zamazal
6c0aefdaf9 libcamera: software_isp: Update black level only on exposure changes
The black level is likely to get updated, if ever, only after exposure
or gain changes.  Don't compute its possible updates if exposure and
gain are unchanged.

It's probably not worth trying to implement something more
sophisticated.  Better to spend the effort on supporting tuning files.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
fb8ad13dc3 libcamera: software_isp: Move exposure+gain to an algorithm module
This is the last step to fully convert software ISP to Algorithm-based
processing.

The newly introduced frameContext.sensor parameters are set, and the
updated code moved, before calling Algorithm::process() to have the
values up-to-date in stats processing.

Resolves software ISP TODO #10.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
54fb3bba81 libcamera: software_isp: Use DelayedControls
Use the standard libcamera mechanism to report the "current" controls
rather than delaying updates by counting from the last update.

A problem is that with software ISP we cannot be sure about the sensor
delay.  The original implementation simply skips exposure updates for 2
frames, which should be enough in most cases.  After this change, we
assume the delay being exactly 2 frames, which may or may not be correct
and may work with outdated values if the delay is shorter.

According to Kieran, the wrong parts are also wrong on the
IPU3/RKISP1/Mali pipelines and only RPi have this correct.  We need to
fix this, by correctly specifying the gains in the libipa camera sensor
helpers.  The sooner the better because this change could introduce a
risk of increasing oscillations.

This patch also prepares moving exposure+gain to an algorithm module
where the original delay mechanism would be a (possibly unnecessary)
complication.

Resolves software ISP TODO #11 + #12.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
8c84efa486 libcamera: software_isp: Use floating point for color parameters
It's more natural to represent color gains as floating point numbers
rather than using a particular pixel-related representation.

double is used rather than float because it's a more common floating
point type in libcamera algorithms.  Otherwise there is no obvious
reason to select one over the other here.

The constructed color tables still use integer representation for
efficiency.

Black level still uses pixel (integer) values, for consistency with
other libcamera parts.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
7fab2062d8 libcamera: software_isp: Move color handling to an algorithm module
After black level handling has been moved to an algorithm module, white
balance and the construction of color tables can be moved to algorithm
modules too.

This time, the moved code is split between stats processing and
parameter construction methods.  It is also split to two algorithm
modules:

- White balance computation.

- Gamma table computation and color lookup tables construction.  While
  this applies the color gains computed by the white balance algorithm,
  it is not directly related to white balance.  And we may want to
  modify the color lookup tables in future according to other parameters
  than just gamma and white balance gains.

Gamma table computation and color lookup tables construction could be
split to separate algorithms too.  But there is no big need for that now
so they are kept together for simplicity.

This is the only part of the software ISP algorithms that sets the
parameters so emitting setIspParams can be moved to prepare() method.

A more natural representation of the gains (and black level) would be
floating point numbers.  This is not done here in order to minimize
changes in code movements.  It will be addressed in a followup patch.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
079d5f30ef libcamera: software_isp: Move black level to an algorithm module
The black level determination, already present as a separate class, can
be moved to the prepared Algorithm processing structure.  It is the
first of the current software ISP algorithms that is called in the stats
processing sequence, which means it is also the first one that should be
moved to the new structure.  Stats processing starts with calling
Algorithm-based processing so the call order of the algorithms is
retained.

Movement of this algorithm is relatively straightforward because all it
does is processing stats.

The comment about getting black level from the tuning files is dropped.
The black level will be taken from CameraSensorHelper if available and
that will be implemented in one of the followup patches.

Black level is now recomputed on each stats processing.  In a future
patch, after DelayedControls are used, this will be changed to recompute
the black level only after exposure/gain changes.

The black level depends on the sensor used, the computed value can be
reused in a followup capture sessions with the same sensor.  Thus it is
sufficient to (re)set the initial value in BlackLevel::init.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
9e7437d5c3 libcamera: software_isp: Call Algorithm::process
This patch adds Algorithm::process call for the defined algorithms.
This is preparation only since there are currently no Algorithm based
algorithms defined.

As software ISP currently doesn't produce any metadata, a dummy and
unused metadata instance is created to satisfy Algorithm::process API.
This should be changed in future.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
2dc696be21 libcamera: software_isp: Call Algorithm::prepare
This patch adds Algorithm::prepare call for the defined algorithms.
This is preparation only since there are currently no Algorithm based
algorithms defined.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
04d171e6b2 libcamera: software_isp: Call Algorithm::queueRequest
This patch adds Algorithm::queueRequest call for the defined algorithms.
As there are currently no control knobs in software ISP nor the
corresponding queueRequest call chain, the patch also introduces the
queueRequest methods and calls from the pipeline to the IPA.

This is preparation only since there are currently no Algorithm based
algorithms defined and no current software ISP algorithms support
control knobs.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
ecbc05c4c5 libcamera: software_isp: Call Algorithm::configure
This patch adds Algorithm::configure call for the defined algorithms.
This is preparation only since there are currently no Algorithm based
algorithms defined.

A part of this change is passing IPAConfigInfo instead of ControlInfoMap
to configure() calls as this is what Algorithm::configure expects.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
97f9961e1b libcamera: software_isp: Create algorithms
We are ready to introduce algorithms now.  First, let's create
algorithms.  The algorithms are not called yet, calls to them will be
added in followup patches.

The maximum number of contexts is set to the same value as in hardware
pipelines.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
f06c344bd5 libcamera: software_isp: Track and pass frame ids
A previous preparation patch implemented passing frame ids to stats
processing but without actual meaningful frame id value passed there.
This patch extends that by actually providing the frame id and passing
it through to the stats processor.

The frame id is taken from the request sequence number, the same as in
hardware pipelines.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
e334227dcc libcamera: software_isp: Remove final dots in debayer.cpp docstrings
The policy and the style checker require that \brief, \param and \return
texts don't finish with a dot.  This needs to be fixed in debayer.cpp.
Also leading spaces in a \return statement are removed from there.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
c64f2f197a libcamera: software_isp: Make stats frame and buffer aware
This patch adds frame and bufferId arguments to stats related calls.
Although the parameters are currently unused, because frame ids are not
tracked and used and the stats buffer is passed around directly rather
than being referred by its id, they bring the internal APIs closer to
their counterparts in hardware pipelines.

It serves as a preparation for followup patches that will introduce:

- Frame number tracking in order to switch to DelayedControls
  (software ISP TODO #11 + #12).
- A ring buffer for stats in order to improve passing the stats
  (software ISP TODO #2).

Frame and buffer ids are unrelated for the given purposes but since they
are passed together at the same places, the change is implemented as a
single patch rather than two, basically the same, patches.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
0cc74c492a libcamera: software_isp: Let IPASoftSimple inherit Module
The Module class is a base class for all IPA modules.
In addition, implement logPrefix() of the module for the softIPA.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
cca55c83f5 libcamera: software_isp: Define skeletons for IPA refactoring
Software ISP image processing algorithms are currently defined in a
simplified way, different from other libcamera pipelines.  This is not
good for several reasons:

- It makes the software ISP code harder to understand due to its
  different structuring.
- Adding more algorithms may make the code harder to understand
  generally.
- Mass libcamera code changes may not be easily applicable to software
  ISP.
- Algorithm sharing with other pipelines is not easily possible.

This patch introduces basic software ISP IPA skeletons structured
similarly to the other pipelines.  The newly added files are currently
not used or compiled and the general skeleton structures don't contain
anything particular.  It is just a preparation step for a larger
refactoring and the code will be actually used and extended as needed in
followup patches.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
306b0f952f libcamera: software_isp: Move BlackLevel to libcamera::ipa::soft
IPA modules use custom namespaces for all their internal components to
avoid namespace clashes. The simple IPA module for the software ISP uses
libcamera::ipa::soft for this purpose. It however defines an internal
class named BlackLevel in the root of the libcamera namespace, making it
prone to clashes. Move it to the ipa::soft namespace along with the rest
of the code.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Milan Zamazal
b28037e6ee libcamera: software_isp: Remove superfluous includes
Remove unused libcamera internal headers bayer_format.h, framebuffer.h
and mapped_frameBuffer.h.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-27 15:01:57 +01:00
Paul Elder
f2088eb91f apps: cam: Print control array sizes
Now that controls can be queried for array information, print it in
--list-controls when applicable.

Example output (with dummy controls added to vimc):

$ cam -c 1 --list-controls
Using camera platform/vimc.0 Sensor B as cam0
Control: ColourGains: [1.000000..4.000000]
   Size: 2
Control: Brightness: [-1.000000..1.000000]
Control: AfWindows: [(0, 0)/1x1..(0, 0)/100x100]
   Size: n
Control: Contrast: [0.000000..2.000000]
Control: Saturation: [0.000000..2.000000]

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-25 23:56:50 +03:00
Paul Elder
ab67fdd210 libcamera: controls: Add array information to ControlId
Add to ControlId information on whether or not it is an array control,
and the size of the control if it is an array control.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-25 23:56:47 +03:00
Paul Elder
505e49b76e py: Add bindings for ControlId enum name
Add python bindings for querying enum value names from a ControlId.

Example usage:
>>> cid
libcamera.ControlId(16, AwbMode, ControlType.Integer32)
>>> cid.enumerators()
{0: 'AwbAuto', 1: 'AwbIncandescent', 2: 'AwbTungsten', 3: 'AwbFluorescent', 4: 'AwbIndoor', 5: 'AwbDaylight', 6: 'AwbCloudy', 7: 'AwbCustom'}
>>> cinfo
libcamera.ControlInfo([2..5])
>>> cinfo.values
[2, 3, 5]
>>> [cid.enumerators()[v] for v in cinfo.values]
['AwbTungsten', 'AwbFluorescent', 'AwbDaylight']

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-25 23:54:42 +03:00
Paul Elder
ab48009a81 apps: cam: Print control enum values more nicely
Now that enum names can be obtained from ControlId, use that information
to print out the list of supported enum values in --list-controls.

Example output (with a dummy AwbMode ControlInfo added to vimc):

$ cam -c 1 --list-controls
Using camera platform/vimc.0 Sensor B as cam0
Control: AwbMode:
  - AwbTungsten (2)
  - AwbFluorescent (3)
  - AwbDaylight (5)
Control: Brightness: [-1.000000..1.000000]
Control: Contrast: [0.000000..2.000000]
Control: Saturation: [0.000000..2.000000]

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-25 23:54:14 +03:00
Paul Elder
9bbccb97fa libcamera: controls: Add enum names and values map to ControlId
Add to ControlId information about the names and values of enum, in the
event that the ControlId is an enum type. This allows applications to
query the ControlId for the names of the enum values, so that they can
be displayed on a UI, for example. Without this, it was necessary to use
macros of NameOfControlNameValueMap, which is difficult to use and is
very inflexible.

There already exists a map from name -> value in generated code. Reuse
this and pass it to the ControlId constructor, which in turn generates
the reverse map. The reverse map is then exposed to applications.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-25 23:53:44 +03:00
Kieran Bingham
44b49af7a0 utils: abi-compat: sort meson options
Sort the options passed to meson setup alphabetically when performing a
slimline libcamera build.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-25 10:36:40 +01:00
Kieran Bingham
9155d79f4d utils: abi-compat: Disable python build
While building the core libcamera library for ABI compatibility checks,
the pycamera python bindings may get built if the required dependencies
are found.

The ABI compatibility checks do not validate or verify the Python API -
so remove this from the intermediate build steps.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-25 10:36:37 +01:00
Kieran Bingham
8bcec68734 libcamera v0.3.2
abi-compliance-checker reports 100% binary and source compatibility,
so this release does not change the SONAME.

  Binary compatibility: 100%
  Source compatibility: 100%
  Total binary compatibility problems: 0, warnings: 0
  Total source compatibility problems: 0, warnings: 0

bugs:

The following commits in this release relate to either a bug fix or
improvement to existing commit.

 - meson: Enable simple pipeline handler on all platforms by default
   - Fixes: 06e0d8508e ("libcamera: pipeline: simple: Enable intel-ipu6 with Soft ISP")
 - libcamera: udev: Catch udev notification errors
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=230
 - libcamera: Drop remaining file names from header comment blocks
   - Fixes: 829acb3ab0 ("libcamera: Drop file name from header comment blocks in templates")
 - Documentation: Fix link to introduction on mainpage.dox
   - Fixes: 860a3e3031 ("Documentation: Rework docs.rst into introduction.rst")
 - Documentation: Fix links from API references to guides
   - Fixes: e938861781 ("Documentation: Improve doxygen main page")
 - pipeline: uvcvideo: Implement acquireDevice() + releaseDevice()
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=168

And the following updates have been made in this release, grouped by
category:

core:
 - libcamera: Avoid variable-length arrays
 - meson: Enable simple pipeline handler on all platforms by default
 - libcamera: base: Add MemFd helper class
 - libcamera: base: memfd: Handle uClibc compatibility with function wrapper
 - libcamera: shared_mem_object: Prevent memfd from shrinking or growing
 - libcamera: simple: Log a missing sensor in a better way
 - libcamera: ipa_proxy: Unify configurationFile argument name
 - libcamera: ipa_proxy: Report a missing configuration as a warning
 - libcamera: Remove spaces at end of lines
 - meson: Drop gcc 8 support
 - utils: checkstyle.py: Warn when no valid Signed-off-by line is found
 - libcamera: Drop path prefix from Doxygen file directive
 - libcamera: Make all internal headers visible to Doxygen
 - libcamera: Unify Doxygen file directive prefix for formats.h
 - libcamera: Mark internal parts of public classes with \internal
 - libcamera: Hide *::Private classes with __DOXYGEN_PUBLIC__
 - libcamera: Split public and internal source arrays
 - libcamera: Add version.h to public headers
 - libcamera: Drop libcamera_generated_ipa_headers from sources
 - libcamera: Move IPA headers to the libcamera_private dependency
 - libcamera: Consolidate all IPA headers in libcamera_ipa_headers
 - libcamera: Add missing headers to libcamera_internal_headers
 - libcamera: Consolidate tracepoint header in libcamera_internal_headers
 - libcamera: Don't add libcamera_public_headers to libcamera_public_sources
 - utils: checkstyle.py: Add author property to Commit class
 - utils: checkstyle.py: Validate SoB trailer against author
 - utils: checkstyle.py: Fix trailer parsing for commits with changelogs
 - libcamera: ipa_manager: Remove singleton requirement
 - libcamera: udev: Catch udev notification errors
 - libcamera: Add missing <stdint.h> include to base/file.h
 - libcamera: Add missing <stdint.h> include to internal/yaml_parser.h
 - libcamera: Fix header grouping
 - libcamera: formats: Adding Support for Y12P
 - utils: checkstyle.py: Rework commit message parsing
 - utils: checkstyle.py: Skip title and trailers checkers for pre-commit
 - utils: checkstyle.py: Add __repr__ method to Commit class
 - libcamera: simple: Fix a typo in a doc string
 - libcamera: camera: Hide Camera::create() from the public API
 - meson: Store controls and properties YAML files in variables
 - meson: Fix mismatch in controls and properties generated file names
 - libcamera: Drop remaining file names from header comment blocks
 - meson: Move all code generation scripts to utils/codegen/
 - meson: utils: Provide environment for Python scripts
 - utils: codegen: gen-header.sh: Generate libcamera.h based on meson.build
 - utils: codegen: gen-controls.py: Convert to jinja2 templates
 - utils: codegen: gen-controls.py: Move helper classes to separate file
 - libcamera: controls: Improve formatting of control descriptions in YAML
 - libcamera: pipeline_handler: Fix unlocking media devices too early
 - libcamera: pipeline_handler: Call releaseDevice() before unlocking media devices
 - libcamera: controls: Fix example for ExposureValue
 - utils: update-kernel-headers: Support relative path to kernel git tree
 - include: linux: Update headers for rkisp1 extensible parameters
 - libcamera: camera: Use invokeMethod() for pipe_->acquire() and pipe_->release()
 - libcamera: uvcvideo: Fix includes
 - libcamera: v4l2: Remove unused includes
 - libcamera: v4l2: Fix an include placement
 - libcamera: v4l2: Fix indirect include
 - libcamera: libcamera: Remove unused includes
 - libcamera: libcamera: Add missing includes
 - libcamera: libcamera: Formatting improvements
 - libcamera: includes: Add missing includes
 - libcamera: includes: Remove unused includes
 - libcamera: includes: Formatting improvements
 - utils: checkstyle: Add a python formatter
 - utils: checkstyle: Remove style checker for python pep8
 - libcamera: utils: Add ScopeExitActions class
 - libcamera: v4l2_videodevice: Improve readability
 - libcamera: media_object: Add MediaPad string representations
 - libcamera: media_object: Add MediaLink string representations
 - libcamera: media_device: Use MediaLink string helper
 - libcamera: yaml-parser: Add additional tests
 - libcamera: yaml-parser: Add failing test for unexpected behavior
 - libcamera: yaml-parser: Differentiate between empty and empty string
 - Document additional environmental variables

pipeline:
 - libcamera: software_isp: Remove file seal TODO item
 - libcamera: software_isp: Replace malloc() with std::vector<>
 - pipeline: rkisp1: Use the extensible parameters format
 - pipeline_handler: Add acquireDevice() function to mirror releaseDevice()
 - pipeline: uvcvideo: Implement acquireDevice() + releaseDevice()
 - libcamera: ipu3: Remove unused includes
 - libcamera: ipu3: Replace wrong include
 - libcamera: ipu3: Formatting improvements
 - libcamera: rkisp1: Remove unused includes
 - libcamera: rkisp1: Formatting improvements
 - pipeline: rkisp1: Use ScopeExitActions to simplify error handling in start
 - libcamera: pipeline: simple: Fix typos in match routing comment
 - pipeline: simple: Remove media member variable
 - libcamera: pipeline: simple: Use MediaLink string helper
 - libcamera: debayer_cpu: Sync DMABUFs

ipa:
 - ipa: libipa: camera_sensor_helper: Reference blackLevel() in documentation
 - ipa: libipa: Add missing CameraSensorHelper fn label in docs
 - ipa: rkisp1: Pass parameters buffer format to IPA module
 - ipa: rkisp1: Pass parameters buffer size to pipeline handler
 - ipa: rkisp1: Add ISP parameters abstraction class
 - ipa: rkisp1: Use the new ISP parameters abstraction
 - ipa: rkisp1: params: Add companding blocks
 - ipa: rkisp1: Add compand feature flag to ipa context
 - ipa: rkisp1: blc: Add support for BLS in compand
 - libcamera: libipa: Remove unused includes
 - libcamera: ipa: Remove unused includes
 - utils: ipc: Include <string> in generated headers where needed
 - libcamera: ipa: Drop unneded includes from ipa_interface.h
 - ipa: rpi: agc: Ignore stable region when exposure/gain set manually
 - ipa: rpi: Adding IMX283 support
 - libcamera: libipa: camera_sensor: Add IMX283 black level
 - ipa: libipa: Add generic Interpolator class
 - ipa: rkisp1: Use generic Interpolator class
 - ipa: rkisp1: Remove MatrixInterpolator
 - ipa: rkisp1: Use interpolator in lsc
 - ipa: rkisp1: Move loader functions into helper class
 - ipa: libipa: Add lsc polynomial class
 - ipa: rkisp1: Add sensor info to context
 - ipa: rkisp1: Add polynomial LSC loader
 - libcamera: libipa: camera_sensor: Add Sony IMX214 sensor properties

apps:
 - gstreamer: Fix width and height range handling
 - apps: qcam: Disable -Wextra-semi
 - gstreamer: Fix missing "greater than" symbol in author string
 - py: cam: Convert to PyQt6
 - py: gen-py-controls: Use Control class
 - py: gen-py-controls: Convert to jinja2 templates
 - v4l2: Support setting frame rate in the V4L2 Adaptation layer
 - qcam: Decrease minimum width of selector dialog
 - qcam: Drop Qt version checks
 - qcam: viewfinder_qt: Draw the letterbox background black
 - qcam: viewfinder_gl: Fix binding of vertex buffer and shader program
 - qcam: viewfinder_gl: Drop duplicate glClearColor()
 - qcam: viewfinder_gl: Render image centered in letterbox

documentation:
 - Documentation: Add Thread safety page
 - Documentation: Split doxygen_input in public and internal inputs
 - Documentation: Split public/private documentation
 - Documentation: Improve doxygen main page
 - Documentation: Add documentation-contents.rst
 - Documentation: Alphabetise the Documentation toctree
 - Documentation: Synchronise camera stack details
 - Documentation: Breakout docs.rst
 - Documentation: Remove libcamera architecture from introduction.rst
 - Documentation: Rework docs.rst into introduction.rst
 - Documentation: Rework index.rst
 - Documentation: Add internal-api-html placeholder
 - Documentation: Reformat documentation_contents.rst
 - Documentation: Rename "API" section to "API Reference"
 - Documentation: Drop local table of contents from introduction
 - Documentation: Rename "Documentation" section to "Introduction"
 - Documentation: Fix link to introduction on mainpage.dox
 - Documentation: Fix links from API references to guides

tuning:
 - utils: tuning: rkisp1: Clean up tuner construction
 - utils: tuning: Change Tuner.add() to accept a list of modules

test:
 - tests: Add a missing iostream include
 - test: ipa: libipa: Add tets for Interpolator

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-24 14:30:57 +01:00
André Apitzsch
642dbafe64 libcamera: libipa: camera_sensor: Add Sony IMX214 sensor properties
Provide the Sony IMX214 camera sensor properties and registration with
libipa for the gain code helpers.

Signed-off-by: André Apitzsch <git@apitzsch.eu>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-23 15:51:24 +01:00
Stefan Klug
0c72c6b4cf ipa: rkisp1: Add polynomial LSC loader
Add a loader that is capable of loading polynomial coefficients from the
tuning files. The polynomial is sampled at load time to reduce the
computational overhead at runtime.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-23 16:42:45 +02:00
Stefan Klug
830340615a ipa: rkisp1: Add sensor info to context
For the LSC algorithm to dynamically calculate the LSC tables based on
the sensor size and the crop rectangle it needs access to that data.
Provide access to it by adding the sensorInfo object to the context.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-09-23 16:42:45 +02:00
Stefan Klug
eb6edfb69e ipa: libipa: Add lsc polynomial class
Add a basic class to represent polynomials as specified in the DNG spec
for vignetting correction.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-23 16:42:45 +02:00
Stefan Klug
b9d4fc82d9 ipa: rkisp1: Move loader functions into helper class
In preparation for supporting polynomial LSC data, move the current
loader into its own helper class.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-09-23 16:42:45 +02:00
Stefan Klug
a6adaa7283 ipa: rkisp1: Use interpolator in lsc
Now, that the generic interpolator is available, use it to do the
interpolation of the lens shading tables. This makes the algorithm
easier to read and remove some duplicate code.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-09-23 16:42:45 +02:00
Stefan Klug
79aa7ecd1a ipa: rkisp1: Remove MatrixInterpolator
The MatrixInterpolator is no longer used. Remove it.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-09-23 16:42:45 +02:00
Stefan Klug
91e6491fa0 ipa: rkisp1: Use generic Interpolator class
Replace all occurrences of the MatrixInterpolator with the generic one.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-09-23 16:42:45 +02:00
Stefan Klug
8ccb04a168 test: ipa: libipa: Add tets for Interpolator
Add tests for the Interpolator class.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-09-23 16:42:45 +02:00
Stefan Klug
2e936455ae ipa: libipa: Add generic Interpolator class
The MatrixInterpolator is great for interpolation of matrices for
different color temperatures. It has however one limitation - it can
only handle matrices. For LSC it would be great to interpolate the LSC
tables (or even polynomials) using the same approach. Add a generic
Interpolator class based on the existing MatrixInterpolator. This class
can be adapted to any other type using partial template specialization.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-09-23 16:42:45 +02:00
Stefan Klug
6b67094cd2 libcamera: yaml-parser: Differentiate between empty and empty string
When accessing a nonexistent key on a dict the YamlObject returns an
empty element. This element can happily be cast to a string which is
unexpected. For example the following statement:

yamlDict["nonexistent"].get<string>("default")

is expected to return "default" but actually returns "". Fix this by
introducing an empty type to distinguish between an empty YamlObject and
a YamlObject of type value containing an empty string. For completeness
add an isEmpty() function and an explicit cast to bool to be able to
test for that type.

Extend the tests accordingly.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-09-23 13:03:35 +02:00
Stefan Klug
f623f3ed64 libcamera: yaml-parser: Add failing test for unexpected behavior
When accessing a nonexistent key on a dict the YamlObject returns an
empty element. This element can happily be cast to a string. This is
unexpected. For example the following statement:

yamlDict["nonexistent"].get<string>("default")

is expected to return "default" but actually returns "". Add a (failing)
testcase for that behavior.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-09-23 13:03:35 +02:00
Stefan Klug
f2842258d1 libcamera: yaml-parser: Add additional tests
Add additional tests in preparation for upcoming modifications on the
yaml parser. These tests handle the case where the yaml file contains
empty items in dictionaries or lists. E.g.:

dict:
  key_with_value: value
  key_without_value:

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-09-23 13:03:35 +02:00
Robert Mader
cbfe04f77c libcamera: debayer_cpu: Sync DMABUFs
Using `DMA_BUF_IOCTL_SYNC` is required for DMABUFs in order to ensure
correct output. Not doing so currently results in occasional tearing
and/or backlashes in GL/VK clients that use the buffers directly for
rendering.

An alternative approach to have the sync code in `MappedFrameBuffer` was
considered but rejected for now, in order to allow clients more
flexibility.

While the new helper is added to an annoymous namespace, add
timeDiff to the same namespace and remove the static definition as a
drive by.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com> # Debix
Tested-by: Hans de Goede <hdegoede@redhat.com> # IPU6 + ov2740
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s + OV5675
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-20 21:09:26 +01:00
Kieran Bingham
66c9b157e9 libcamera: pipeline: simple: Use MediaLink string helper
Replace the open-coded implementation of a link representation
with the operator<< overload string representation to simplify
the code and unify appearance of reporting MediaLinks.

Signed-off-by: Kieran Bingham <kieran.bingham@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>
2024-09-12 12:01:29 +02:00
Kieran Bingham
4035f5754e libcamera: media_device: Use MediaLink string helper
Replace the two open-coded implementations of a link representation
with the operator<< overload string representation to simplify
the code and unify appearance of reporting MediaLinks.

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>
2024-09-12 12:01:29 +02:00
Kieran Bingham
a783562a34 libcamera: media_object: Add MediaLink string representations
Various parts of libcamera print the representation of a MediaLink by
inline joining the parts to make a string representation.

This repeated use case can be supported with a common helper to print
the MediaLink in a common manner using the existing toString() and
operator<< overload style to make it easier to report on MediaLink
types.

This implementation will report in the following style:

  'imx283 1-001a'[0] -> 'video-mux'[0]

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>
2024-09-12 12:01:29 +02:00
Kieran Bingham
6837607ca3 libcamera: media_object: Add MediaPad string representations
Facilitate easy representations of a MediaPad object by preparing
it as a string and supporting output streams.

A MediaPad will be report in the following style:

  'imx283 1-001a'[0]

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>
2024-09-12 12:01:29 +02:00
Paul Elder
d900ec990d pipeline: simple: Remove media member variable
There is no need for the simple pipeline handler to save the media
device. Remove it.

Signed-off-by: Paul Elder <paul.elder@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>
2024-09-12 11:12:28 +02:00
Stefan Klug
33a49ce4a2 libcamera: v4l2_videodevice: Improve readability
The handling for the sequence number validation within
V4L2VideoDevice::dequeueBuffer makes use of a std::optional, which can
be used as a boolean in conditional statements. This has the impact in
this use case that it can be mis-read to be interpretting the value for
firstFrame_ which is assigned as the buf.sequence.

Remove this potential for confusion by making it clear that the first
frame handling is only performed when firstFrame_ does not have a value
assigned.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
[Kieran: Rework commit message]
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-12 11:12:28 +02:00
Kieran Bingham
75fc944738 libcamera: pipeline: simple: Fix typos in match routing comment
Fix a small typo in the comment regarding the default routing
table configuration.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-12 11:12:28 +02:00
Kieran Bingham
935f6ff267 libcamera: libipa: camera_sensor: Add IMX283 black level
Report the default sensor black level reported by the datasheet.

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>
2024-09-12 11:12:28 +02:00
will whang
69b702d183 ipa: rpi: Adding IMX283 support
Add support for the IMX283 sensor for the VC4 target.

Signed-off-by: will whang <will@willwhang.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-12 11:12:28 +02:00
Laurent Pinchart
e6441ec4f4 qcam: viewfinder_gl: Render image centered in letterbox
Mimic the letterbox behaviour of the Qt viewfinder by rendering the
image centered. This is done by adding a projection matrix to the vertex
shader to scale the rendered rectangle.

Another option would have been to keep using glViewport() (which would
have needed to be moved to paintGL(), as Qt resets the viewport to span
the full widget before calling). Hidpi displays would then need special
handling of the device pixel ratio, which is done automatically by Qt
when it sets the default viewport. Using a projection matrix avoids this
complication.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-11 18:24:51 +03:00
Laurent Pinchart
583901a714 qcam: viewfinder_gl: Drop duplicate glClearColor()
There's no need to call glClearColor() twice before drawing any GL
content. Drop the first call. This doesn't introduce any functional
change.

While at it, pass floats instead of doubles to glClearColor(), as
required by the function.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-11 18:24:51 +03:00
Laurent Pinchart
33a0b14e0a qcam: viewfinder_gl: Fix binding of vertex buffer and shader program
Starting in Qt 6.7.0, vertex buffers and shader programs are unbound
just before calling QOpenGLWidget::paintGL(). This breaks rendering in
the GL viewfinder in two ways.

First, we bind the vertex buffer only once at initialization time. There
is therefore no vertex buffer mapped at rendering time, preventing both
the vertex shader from having access to the vertex and texture
coordinates.

Then, we bind the shader program only when rendering the first frame.
There is thus no shader program bound for all subsequent frames,
breaking rendering.

Fix this by binding the vertex buffer where needed, when setting
attribute buffers for the shader program, and binding the shader program
for every frame.

As we use a single vertex buffer, we could bind it at the beginning of
paintGL() and keep it bound indefinitely. That would however fail to
clearly indicate in the source code where the vertex buffer is needed,
making the code more difficult to understand as it would rely on
implicit assumptions. Release the vertex buffer explicitly when we don't
need it anymore to avoid this.

While at it, fix a coding style violation by adding missing curly
brackets.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-11 18:24:51 +03:00
Laurent Pinchart
2e2aa40799 qcam: viewfinder_qt: Draw the letterbox background black
When the widget's aspect ratio doesn't match the camera aspect ratio,
the viewfinder is rendered letter-boxed. The side rectangles are not
painted by the viewfinder, and Qt thus renders the parent widget
background to fill that space.

To make it black, we have two options:

- The simplest option is to set the widget's autoFillBackground property
  to true. This causes Qt to paint the whole widget with its background
  colour before calling paintEvent(). As the camera image typically
  covers most (if not all) of the viewfinder widget, this is less
  efficient.

- The more complicated option is to paint the letterbox rectangles
  manually. We can additionally set the widget's WA_OpaquePaintEvent
  attribute to instruct Qt to skip painting the parent widget. This
  reduces CPU usage by about 1% (and may reduce GPU usage as well).

Note that the WA_OpaquePaintEvent attribute has to be disabled when we
render the stopped icon, as the icon has a transparent background.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-11 18:24:50 +03:00
Laurent Pinchart
e5fd3bea77 qcam: Drop Qt version checks
The Qt version checks to support different minor Qt5 versions are not
needed anymore, now that we switched to Qt6. Drop them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Neal Gompa <neal@gompa.dev>
2024-09-11 18:24:01 +03:00
Luca Weiss
13645ab0ab qcam: Decrease minimum width of selector dialog
On phone screens the default width is too wide, so the OK button cannot
be clicked.

Fix this by decreasing the minimum size of the dialog so it fits nicely.

Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-11 18:23:59 +03:00
Nejc Galof
5456e02d3f v4l2: Support setting frame rate in the V4L2 Adaptation layer
The V4L2 adaptation layer can already support streaming with components
such as OpenCV, however it is not accepting, or handling any requests to
configure the frame rate.

In V4L2 the frame rate is set by configuring the timeperframe component
of the v4l2_streamparm structure through the VIDIOC_S_PARM ioctl.

Extend the V4L2 compatibility layer to accept the VIDIOC_S_PARM ioctls
and provide an interface for setting controls on the V4L2Camera class to
set the requested rate when starting the camera.

Signed-off-by: Nejc Galof <galof.nejc@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
2024-09-10 22:17:28 +02:00
David Plowman
5c5bc85082 ipa: rpi: agc: Ignore stable region when exposure/gain set manually
When a user is taking control of exposure and gain, setting them
manually, we set the AGC "stable region" to zero. This means that any
user changes, however small, will be applied, and they won't be
regarded as "too small to bother with".

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-09 15:13:43 +01:00
Laurent Pinchart
f75b8dd26f pipeline: rkisp1: Use ScopeExitActions to simplify error handling in start
Error handling in the PipelineHandlerRkISP1::start() function is
cumbersome. Simplify it using the utils::ScopeExitActions class.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Xavier Roumegue <xavier.roumegue@oss.nxp.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2024-09-05 16:12:41 +03:00
Laurent Pinchart
481fc69e7c libcamera: utils: Add ScopeExitActions class
The ScopeExitActions class is a simple object that performs
user-provided actions upon destruction. It is meant to simplify cleanup
tasks in error handling paths.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Xavier Roumegue <xavier.roumegue@oss.nxp.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2024-09-05 16:12:35 +03:00
Stefan Klug
8161018b9b utils: checkstyle: Remove style checker for python pep8
The issues detected and fixed by autopep8 are the same as the ones
detected by pycodestyle. As the formatter runs unconditionally we can
remove the checker.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-04 17:22:59 +02:00
Stefan Klug
8ffaf376bb utils: checkstyle: Add a python formatter
Reporting style issues on python files is great, automatically fixing
them is even better. Add a call to autopep8 for python files. This fixes
the same issues as the ones reported by pycodestyle.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-04 17:22:36 +02:00
Laurent Pinchart
b318101ada libcamera: ipa: Drop unneded includes from ipa_interface.h
The ipa_interface.h file includes a number of headers that are not
directly used. Remove them, and add them to the source files that
include ipa_interface.h as required.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-09-03 15:25:55 +03:00
Laurent Pinchart
0e333755ff utils: ipc: Include <string> in generated headers where needed
Depending on the types used in the IPA interface, generated headers may
use the std::string class. Include <string> when needed.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-09-03 15:25:45 +03:00
Milan Zamazal
ac1c57fcf5 libcamera: includes: Formatting improvements
The LSP autoformatter doesn't like some of the current formatting, let's
make it happier.  Note that not all of its suggestions were accepted
because readability is preferred and adjusting .clang-format may not be
easy or possible.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 22:46:32 +03:00
Milan Zamazal
e2cace52d5 libcamera: includes: Remove unused includes
The includes that are not used can be removed.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 22:44:38 +03:00
Milan Zamazal
308f0ccf04 libcamera: includes: Add missing includes
Let's add direct includes for classes currently included indirectly,
through other header files.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 22:37:55 +03:00
Milan Zamazal
6d0bf44c32 libcamera: libcamera: Formatting improvements
The LSP autoformatter doesn't like some of the current formatting, let's
make it happier.  Note that not all of its suggestions were accepted
because readability is preferred and adjusting .clang-format may not be
easy or possible.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 22:34:37 +03:00
Milan Zamazal
61a1d1694c libcamera: libcamera: Add missing includes
Let's add direct includes for classes currently included indirectly,
through other header files.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 22:31:50 +03:00
Milan Zamazal
d3aa432305 libcamera: libcamera: Remove unused includes
The includes that are not used can be removed.  Additionally, add some
directly used includes not listed.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 22:01:40 +03:00
Milan Zamazal
fd7fc9cca5 libcamera: ipa: Remove unused includes
The includes that are not used can be removed.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 21:55:41 +03:00
Milan Zamazal
132ba5ea8a libcamera: v4l2: Fix indirect include
Use the direct include of V4L2PixelFormat.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 21:54:50 +03:00
Milan Zamazal
89da2f4736 libcamera: v4l2: Fix an include placement
Put the inclusion of geometry.h to the right place.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 21:54:33 +03:00
Milan Zamazal
802073e79f libcamera: v4l2: Remove unused includes
The includes that are not used can be removed.  Also, some directly used
includes not listed are added.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 21:54:18 +03:00
Milan Zamazal
a1f597478d libcamera: uvcvideo: Fix includes
The includes that are not used can be removed and there are also
directly used includes not listed.  Let's fix both.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 21:52:38 +03:00
Milan Zamazal
552777c0dc libcamera: libipa: Remove unused includes
The includes that are not used can be removed.  And two identified
missing includes (directly used but available only through other
includes) are added.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 21:50:55 +03:00
Milan Zamazal
682a3f1f73 libcamera: rkisp1: Formatting improvements
The LSP autoformatter doesn't like some of the current formatting, let's
make it happier.  Note that not all of its suggestions were accepted
because readability is preferred and adjusting .clang-format may not be
easy or possible.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 21:49:16 +03:00
Milan Zamazal
e4c6eb95a9 libcamera: rkisp1: Remove unused includes
The includes that are not used can be removed.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 21:36:04 +03:00
Milan Zamazal
759b0731d2 libcamera: ipu3: Formatting improvements
The LSP autoformatter doesn't like some of the current formatting, let's
make it happier.  Note that not all of its suggestions were accepted
because readability is preferred and adjusting .clang-format may not be
easy or possible.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 21:34:14 +03:00
Milan Zamazal
c9eb4a71f1 libcamera: ipu3: Replace wrong include
v4l2_videodevice.h is not used but logging is imported through it.
Remove the unused include and include log.h instead.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 21:32:10 +03:00
Milan Zamazal
3140785918 libcamera: ipu3: Remove unused includes
The includes that are not used can be removed.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 18:57:55 +03:00
Milan Zamazal
6a2b6628ce tests: Add a missing iostream include
generated_serializer_test.cpp uses iostream without including it,
relying on imports from another included header.  Let's include iostream
there.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-09-02 18:57:55 +03:00
Hans de Goede
7a36d05795 pipeline: uvcvideo: Implement acquireDevice() + releaseDevice()
The uvcvideo pipeline handler always keeps the uvcvideo /dev/video# node
for a pipeline open after enumerating the camera.

This is a problem for uvcvideo, as keeping the /dev/video# node open
stops the underlying USB device and the USB bus controller from being
able to enter runtime-suspend causing significant unnecessary
power-usage.

Implement acquireDevice() + releaseDevice(), openening /dev/video# on
acquire and closing it on release to fix this.

And make validate do a local video_->open() + close() around validate()
when not open yet, to keep validate() working on unacquired cameras.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=168
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-30 15:17:27 +03:00
Hans de Goede
11e396bf9f libcamera: camera: Use invokeMethod() for pipe_->acquire() and pipe_->release()
The uvcvideo driver needs to open / close its /dev/video# node from
pipe_->acquireDevices() / pipe_->releaseDevices().

V4L2VideoDevice::open() creates an EventNotifier and this notifier needs
to be created from the CameraManager thread.

Use invokeMethod() for pipe_->acquire() and pipe_->release() so that the
EventNotifiers are created from the CameraManager thread context.

Running pipe_->acquire() and pipe_->release() from the CameraManager
thread context serializes all calls to them. Drop PipelineHandler::lock_
this now is no longer necessary and update the "\context" part of the
documentation for acquire[Device]() and release[Device]() to match.

Note the delayed opening of /dev/video# is a special case because the
kernel uvcvideo driver powers on the USB device as soon as /dev/video#
is opened. This behavior should *not* be copied by other pipeline
handlers.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-30 15:15:39 +03:00
Hans de Goede
c05e45ac77 pipeline_handler: Add acquireDevice() function to mirror releaseDevice()
libcamera always keeps all /dev/video# and /dev/v4l2_subdev# nodes for a
pipeline open after enumerating the camera.

This is a problem for the uvcvideo pipeline handler. Keeping /dev/video#
open stops the UVC USB device from being able to enter runtime-suspend
causing significant unnecessary power-usage.

Add a stub acquireDevice() function to the PipelineHandler class which
pipeline handlers can override.

The uvcvideo pipeline handler will use this to delay opening /dev/video#
until the device is acquired. This is a special case because the kernel
uvcvideo driver powers on the USB device as soon as /dev/video# is
opened. This behavior should *not* be copied by other pipeline handlers.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-30 15:15:06 +03:00
Paul Elder
9020c2eec9 ipa: rkisp1: blc: Add support for BLS in compand
Extend the RkISP1 BLC algorithm to use the ISP 'companding' block for
versions of the ISP (such as the one on the i.MX8MP) that lack the
dedicated BLS block but implement BLS as part of the companding block.

As access to the companding block requires the extensible parameters
format, disable BLC when using the legacy parameters format on i.MX8MP
to avoid crashes at runtime with older kernels.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-08-27 12:29:08 +03:00
Paul Elder
39e4e04f3a ipa: rkisp1: Add compand feature flag to ipa context
Add a compand feature flag to the hardware settings section of the IPA
context, so that we can act accordingly for black level subtraction, and
to pave the way to skipping companding appropriately when support for it
is added.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-08-27 12:29:07 +03:00
Laurent Pinchart
974dccd45b ipa: rkisp1: params: Add companding blocks
Extend the RkISP1 parameters helper with support for the new companding
blocks.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-27 12:29:04 +03:00
Jacopo Mondi
b43a06d124 pipeline: rkisp1: Use the extensible parameters format
Now that the IPA module supports the extensible parameters format,
switch to it when available. If the kernel driver doesn't support the
new format, setFormat() will adjust paramFormat to the legacy format,
which will be passed to the IPA module, preserving backward
compatibility.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-27 12:29:02 +03:00
Laurent Pinchart
9861678f23 ipa: rkisp1: Use the new ISP parameters abstraction
Use the new ISP parameters abstraction class RkISP1Params to access the
ISP parameters in the IPA algorithms. The class replaces the pointer to
the rkisp1_params_cfg structure passed to the algorithms' prepare()
function, and is used to access individual parameters blocks.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-08-27 12:28:57 +03:00
Laurent Pinchart
9cacf4e420 ipa: rkisp1: Add ISP parameters abstraction class
Individual algorithms of the rkisp1 IPA module access their
corresponding ISP parameters through the top-level structure
rkisp1_params_cfg. This will not work anymore with the new parameters
format. In order to ease the transition to the new format, abstract the
ISP parameters in a new RkISP1Params class that offers the same
interface regardless of the format.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-08-27 12:28:52 +03:00
Jacopo Mondi
e70cda4238 ipa: rkisp1: Pass parameters buffer size to pipeline handler
The ISP parameters buffer currently has a fixed payload size, which is
hardcoded in the pipeline handler. To prepare for support of the
extensible parameters format that has a variable payload size, pass the
size from the IPA module to the pipeline handler explicitly. Keep the
size hardcoded to sizeof(struct rkisp1_params_cfg) for now, this will be
udpated later.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-27 12:28:51 +03:00
Laurent Pinchart
db15711692 ipa: rkisp1: Pass parameters buffer format to IPA module
The rkisp1 driver supports two formats for the ISP parameters buffer,
the legacy fixed format and the new extensible format. In preparation of
support for the new format, pass the parameters buffer format from the
pipeline handler to the IPA module and store it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-27 12:28:47 +03:00
Jacopo Mondi
798daf9eb0 include: linux: Update headers for rkisp1 extensible parameters
Update the kernel headers with the definitions for the rkisp1 extensible
parameters format.

The headers have been generated from the most recent linux-media stage
tree master branch, at commit a043ea54bbb9 ("Merge tag
'next-media-rkisp1-20240814' of
git://git.kernel.org/pub/scm/linux/kernel/git/pinchartl/linux.git").

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Paul Elder <paul.elder@ideasonboard.com>
Acked-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-08-27 12:28:42 +03:00
Laurent Pinchart
67b87ccb87 utils: update-kernel-headers: Support relative path to kernel git tree
When given a relative path to the kernel git tree,
update-kernel-headers.sh fails to execute the headers_install.sh script
from the kernel sources. Fix it by turning the kernel directory into an
absolute path.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-08-27 12:16:10 +03:00
Daniel Scally
874b63d5cb Documentation: Fix links from API references to guides
The links on the API reference mainpage to guides within the main
libcamera documentation work built locally, but not through the
website. As the website's more important make them work with the
website paths as a temporary solution until a better one is devised.

Fixes: e938861781 ("Documentation: Improve doxygen main page")
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-25 04:35:10 +03:00
Daniel Scally
8c1b29072e Documentation: Fix link to introduction on mainpage.dox
With the removal of guides/introduction.rst the link on the API
reference landing page no longer works. Point it to the documents
introduction page instead.

Fixes: 860a3e3031 ("Documentation: Rework docs.rst into introduction.rst")
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-25 04:34:59 +03:00
Fang Hui
87fd05c663 libcamera: controls: Fix example for ExposureValue
EV = [-2, -1, 0.5, 0, 0.5, 1, 2]
should change to
EV = [-2, -1, -0.5, 0, 0.5, 1, 2]

Signed-off-by: Fang Hui <hui.fang@nxp.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-25 04:34:13 +03:00
Hans de Goede
3186a0eb54 libcamera: pipeline_handler: Call releaseDevice() before unlocking media devices
It is better / more logical to call releaseDevice() before unlocking the
devices. At the moment the only pipeline handler implementing
releaseDevice() is the rpi pipeline handler which releases buffers from
its releaseDevice() implementation.

Releasing buffers before unlocking the media devices is ok to do
and arguably it is better to release the buffers before unlocking.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-25 03:27:17 +03:00
Hans de Goede
a3fb0b3d0a libcamera: pipeline_handler: Fix unlocking media devices too early
PipelineHandler::acquire() only locks the media devices when the first
camera is acquired. If a second camera of a pipeline is acquired only
useCount_ is increased and nothing else is done.

When releasing cameras PipelineHandler::release() should only unlock
the media devices when the last camera is released. But the old code
unlocked on every release().

Fix PipelineHandler::release() to only release the media devices when
the last camera is released.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-25 03:06:06 +03:00
Laurent Pinchart
fc7250f0b3 Documentation: Rename "Documentation" section to "Introduction"
The introduction.rst file contains the introduction to the libcamera
documentation. Rename the section from "Documentation" to
"Introduction".

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-21 12:22:31 +03:00
Laurent Pinchart
c0bd24dc8f Documentation: Drop local table of contents from introduction
The local table of contents from the introduction page doesn't provide
much navigation value as the page is short. It also stands out, as no
other page has a local table of contents. Drop it, we will reintroduce
local tables of contents more globally if needed later.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-21 12:22:29 +03:00
Laurent Pinchart
fb45232fe5 Documentation: Rename "API" section to "API Reference"
"API" as a section name is as informative as it is long, that is to say,
not very. Rename it to "API Reference" for improved clarity.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-21 12:22:17 +03:00
Daniel Scally
119277b8ce Documentation: Reformat documentation_contents.rst
Now that documentation_contents.rst serves as a navbar for the docs
pages on the website, reformat it to present the links in a more
logical order. The list is split into three sections for Users,
Developers and System Integrators, with a slight break between
each section and a header above the links.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-21 03:11:57 +03:00
Daniel Scally
be2182d239 Documentation: Add internal-api-html placeholder
Mimicking the existing api-html placeholder, add a placeholder for the
internal version of the Doxygen generated API documentation so that the
website can generate hyperlinks to it properly.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-21 03:11:36 +03:00
Daniel Scally
69d11d29a2 Documentation: Rework index.rst
index.rst is the page that becomes index.html, but currently just has
some blurb. Although this page will only be seen if viewing the docs
as built from the libcamera tree it'd be better if it were more of an
introductory page. Include the content of docs.rst to improve it. As
we're no longer including the content from README.rst the labels that
enabled that can be dropped.

With this change whether viewing the documentation as built in the
libcamera tree or on the Docs page of the website, the landing content
will be the same.

The CSS for the documentation's theme currently hides the toctree from
the generated body in html, as it's already displayed on every page via
the theme's CSS. This change reorders the page such that the CSS that
hides the toctree no longer works - update the CSS to retain the
current behaviour.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-21 01:35:49 +03:00
Daniel Scally
860a3e3031 Documentation: Rework docs.rst into introduction.rst
docs.rst is the landing page for the documentation from the libcamera
website, but isn't particularly introductory. Move much of the content
from guides/introduction.rst to docs.rst, which will serve as the new
introductory page. Remove guides/introduction.rst.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-21 01:35:44 +03:00
Daniel Scally
3fe819eecf Documentation: Remove libcamera architecture from introduction.rst
The libcamera Architecture section of the introduction is largely a
duplicate of the section broken out from docs.rst. Remove it from the
introduction.rst file and consolidate anything that wasn't duplicated
into libcamera_architecture.rst and feature_requirements.rst. Take the
opportunity to also expand the list of Platform Support which is now a
bit out of date.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-21 01:35:39 +03:00
Daniel Scally
c01dfb3650 Documentation: Breakout docs.rst
In preparation for including more of the Documentation for libcamera
on the website, break out the libcamera Architecture and Feature
Requirements sections of docs.rst file into separate files for each
section. Add all of the new files to documentation-contents.rst so
they're included on the website too.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-21 01:35:36 +03:00
Daniel Scally
83800ba709 Documentation: Synchronise camera stack details
There are two near-duplicate instances of the camera stack details
in the Documentation, in docs.rst and guides/introduction.rst. Remove
them from guides/introduction.rst, with the exception of the
explanations of the V4L2 Compatibility Layer and the Android HAL
which are moved to the Camera Stack section in docs.rst. The Docs
page already had its own separate version of those details but they
are distinct and seemingly out of date - remove them.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-21 01:35:34 +03:00
Daniel Scally
b6c521c569 Documentation: Alphabetise the Documentation toctree
With the exception of the initial group of four links, alphabetise
the pages in the Documentation toctree so adding new ones can be
done in a defined order.

Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-21 01:35:30 +03:00
Daniel Scally
182bdadd0f Documentation: Add documentation-contents.rst
Add a new .rst file referencing the documentation contents. This file
is then included in each documentation page so that we can enhance
the Documentation pages on the libcamera website using it. As we do
not want the appearance of the libcamera in-tree Documentation to
change just yet, disable the new class using the sphinx theme's CSS.

To facilitate easier distinguishing between "normal" and
documentation pages on the website we want to add a "documentation"
class to the content of all such pages. Since this new file will be
included on each documentation page it is convenient to add the new
directive here - do so. As the website uses different CSS to
libcamera, move the contents on docs.rst a little so that the
directive at the end of the contents block applies correctly.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-21 01:35:24 +03:00
Laurent Pinchart
ce690bd9d7 libcamera: controls: Improve formatting of control descriptions in YAML
The control descriptions from YAML files are extracted to generate
Doxygen documentation blocks for the controls, which are then compiled
to HTML. The extraction script uses the first line of the description
as the Doxygen \brief, and preserves blank lines to keep paragraphs.

The control descriptions in the YAML files have however not all been
written with this in mind. Many description elements are not formatted
as block string scalars, in the first place, so blank lines are lost
when parsing YAML. Furthermore, they often start with a long initial
paragraph, making the \brief description very long.

Improve the documentation formatting by marking all multiline
descriptions as block string scalars, and try to provide a short
one-line first paragraph to be used as a \brief. While at it, reflow the
documentation to the 80 columns limit.

The draft controls are left as-is, as they should evolve to non-draft
controls eventually (and ideally sooner than later).

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-16 00:50:53 +03:00
Laurent Pinchart
39f01e9185 py: gen-py-controls: Convert to jinja2 templates
Jinja2 templates help separate the logic related to the template from
the generation of the data. The python code becomes much clearer as a
result.

As an added bonus, we can use a single template file for both controls
and properties.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Acked-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-16 00:28:32 +03:00
Laurent Pinchart
5c1cb5e5bc py: gen-py-controls: Use Control class
Replace manual extraction of data from YAML with the Control helper
class. This centralizes YAML parsing and avoids manual mistakes.

In order to import the controls module, add the utils/codegen/ directory
to the PYTHONPATH through the Python build environment.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-16 00:28:32 +03:00
Laurent Pinchart
6a96113107 utils: codegen: gen-controls.py: Move helper classes to separate file
The ControlEnum and Control helper classes defined in gen-controls.py
are useful for other generator scripts. Move them to a separate file to
make it possible to share them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-16 00:28:32 +03:00
Laurent Pinchart
dc067c4bce utils: codegen: gen-controls.py: Convert to jinja2 templates
Jinja2 templates help separate the logic related to the template from
the generation of the data. The python code becomes much clearer as a
result.

As an added bonus, we can use a single template file for both controls
and properties.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-16 00:27:54 +03:00
Laurent Pinchart
48f9660acd utils: codegen: gen-header.sh: Generate libcamera.h based on meson.build
The libcamera.h header is a top-level library header that contains every
other libcamera header. It is currently generated by listing the files
in include/libcamera/ and dropping the .in suffix from template files.
This assumes a 1:1 mapping between generated header file names and the
name of their templates.

Drop that assumption and base the libcamera.h generation on the
libcamera public headers listed in meson.build. This makes the
libcamera.h header generation more future-proof.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-16 00:00:28 +03:00
Laurent Pinchart
a5f12d2eb3 meson: utils: Provide environment for Python scripts
Python scripts run as part of the build process need to take a few
actions specific to the environment in which they operate. One of those
is disabling the Python bytecode cache, to avoid writing .pyc files to
the source tree. This is done manually in the IPC generate.py and
parser.py scripts.

The current implementation is not ideal because it hardcodes in the
scripts information related to the environment in which they operate. As
those scripts are part of libcamera this is more of a theoretical issue
than a practical one. A second issue is that future Python scripts will
need to duplicate similar mechanisms, resulting in a higher maintenance
burden.

Address the issue with a different approach, by creating a meson
environment for the Python scripts, and passing it to the
custom_target() functions. The environment only disables the bytecode
cache for now.

The diffstat shows an increase in code size. This is expected to be
offset by usage of the environment for more Python scripts, as well as
support of more variables in the environment.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-16 00:00:23 +03:00
Laurent Pinchart
50c92cc7e2 meson: Move all code generation scripts to utils/codegen/
We have multiple code generation scripts in utils/, mixed with other
miscellaneous utilities, as well as a larger code base based on mojom in
utils/ipc/. To make code sharing easier between the generator scripts,
without creating a mess in the utils/ directory, move all the code
generation code to utils/codegen/.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-15 23:59:08 +03:00
Laurent Pinchart
d3bf27180e libcamera: Drop remaining file names from header comment blocks
Commit 829acb3ab0 ("libcamera: Drop file name from header comment
blocks in templates") dropped file names from header comment blocks in
templates, but forgot the control and property .cpp templates. Fix it.

Fixes: 829acb3ab0 ("libcamera: Drop file name from header comment blocks in templates")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-15 04:44:27 +03:00
Laurent Pinchart
cbffcbe362 meson: Fix mismatch in controls and properties generated file names
The header for controls and properties are generated from the
control_ids.h.in and property_ids.h.in templates respectively, and the
generated files are named control_ids.h and property_ids.h.

For sources, the templates are named control_ids.cpp.in and
property_ids.cpp.in, but the output files are named controls_ids.cpp and
properties_ids.cpp. This discrepancy causes confusion. Fix it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-15 04:44:20 +03:00
Laurent Pinchart
b8d318ebeb meson: Store controls and properties YAML files in variables
When generating control headers, the YAML files to be used are
determined dynamically based on the selected pipeline handlers. As part
of this process, the build system populates an array of meson File
objects used as an input for the control headers generation custom
target, as well as an array of file names (as strings). The file names
array is later used to generate the control source files for the
libcamera core, as well as the source code for controls support in the
Python bindings.

Both of the source code generators manually turn the array of file names
into File objects. This duplicates code and reduces readability. A third
similar implementation has also been proposed to generate control
support sources in the GStreamer element, making the issue worse.

To simplify this, store File objects instead of file names in the
controls_files array. As the meson configuration summary doesn't support
File objects, create a separate controls_files_names to store the file
names for that sole purpose.

The exact same process occurs for properties, address them the same way.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-15 04:44:09 +03:00
Stefan Klug
53108b6ff1 utils: tuning: Change Tuner.add() to accept a list of modules
Change the first parameter of Tuner.add() to accept either a list of
modules or a single module. This allows more compact code and is in sync
with Tuner.set_output_order().

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-14 16:22:07 +02:00
Stefan Klug
1dfedac794 utils: tuning: rkisp1: Clean up tuner construction
The instances of the static modules need to be passed to
tuner.set_output_order() instead of the class.  This is the reason for
the intermediate variables. To keep the code tidy, apply the same
pattern to the other modules.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-08-14 11:37:14 +02:00
Laurent Pinchart
6b4771d460 libcamera: camera: Hide Camera::create() from the public API
The Camera::create() function is internal. Hide it from the public API
documentation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-14 04:17:45 +03:00
Daniel Scally
e938861781 Documentation: Improve doxygen main page
The "Main Page" of the doxygen generated API reference is currently
totally empty. Expand it with some introductory text along with links
to the developer's guide, application developer's guide and the
pipeline and IPA module writer's guides.

Provide an easy link to switch between the reduced public reference
pages and the more complete internal ones.

Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-14 04:17:45 +03:00
Daniel Scally
7dc38adcb5 Documentation: Split public/private documentation
The API reference pages generated by Doxygen are comprehensive, but
therefore quite overwhelming for application developers who will
likely never need to use the majority of the library's objects. To
reduce the complexity of the documentation, split it into two runs of
doxygen.

The first run of doxygen is for the public API. We pass a specific list
of source files to parse, which is built from the arrays of public
headers and sources in meson build files. This ensures that we only
generate the documentation for code from those files.

A custom Python script is needed to add the list of input files to
Doxyfile, as several of the objects included in the header and source
array are custom_tgt objects, which can't be handled as strings to
populate a variable in the configuration data.

The headers defining the Extensible and Object classes (class.h and
object.h respectively), as well as the corresponding source files, are
excluded from the public API documentation despite being referenced in
the meson public headers and sources arrays. This is due to the fact
that public API classes inherit from Extensible and Object, making the
Extensible and Object classes part of the public ABI. Those two base
classes are however implementation details and must not be accessed
directly by application code.

The second run of doxygen is for the internal API. This contains
documentation for all of the library's objects as it currently does.
This set will now be output into build/Documentation/internal-api-html.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Co-developed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-14 04:17:40 +03:00
Laurent Pinchart
7304442774 Documentation: Split doxygen_input in public and internal inputs
To prepare for splitting the API documentation in public and internal
documents, split the doxygen_input list in the public and internal
counterparts.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-14 04:11:38 +03:00
Daniel Scally
f57e9fa6dd Documentation: Add Thread safety page
Move the section of the Thread support page dealing with thread safety
to a dedicated .dox file at Documentation/. This is done to support the
splitting of the Documentation into a public and internal version. With
a separate page, references can be made to thread safety without having
to include the Thread class in the doxygen run. Some sections of the new
page are still specific to internal implementations and so are hidden
with the \internal flag and an internal section which is conditionally
included. For now, hardcode it to be included in the Doxyfile.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-14 03:57:47 +03:00
Tomi Valkeinen
15a51caae8 py: cam: Convert to PyQt6
Qt5 is now end of life. The libcamera 'qcam' application has removed
support for Qt5, and updated to Qt6.

Update the python 'cam' application accordingly to Qt6.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-12 20:25:20 +03:00
Milan Zamazal
7c6b960a8e libcamera: simple: Fix a typo in a doc string
Rectify incorrect phrase in the sentence -- s/their share/they share/.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-12 15:45:07 +03:00
Milan Zamazal
ea7d766807 ipa: libipa: Add missing CameraSensorHelper fn label in docs
The constructor reference was missing, causing the constructor
documentation to appear in blackLevel() documentation.

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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-12 15:44:23 +03:00
Laurent Pinchart
2d5cea862d utils: checkstyle.py: Add __repr__ method to Commit class
When debugging issues with the Commit class, a __repr__ method proved to
be useful to quickly print all the parsed information about a commit. To
avoid reimplementing the method over and over again in the future, add
it to the class, even if it is not actually used.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-12 15:44:23 +03:00
Laurent Pinchart
35f045f978 utils: checkstyle.py: Skip title and trailers checkers for pre-commit
When running checkstyle.py in a pre-commit hook, there is either no
commit message at all (when committing staged changes as a new commit),
or the commit message comes from a previous commit being amended. In
either case, there's no new commit message yet, and thus nothing to
validate for the title and trailers checkers. The trailers checker, in
particular, will always flag an error, making all commits fail.

To fix that, just skip the two checkers during pre-commit.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-12 15:44:22 +03:00
Laurent Pinchart
eeb435bbda utils: checkstyle.py: Rework commit message parsing
When parsing commit messages, the Commit class tries to optimize the
process by invoking git-show once only, extracting both the commit
author, title and modified files in one go. As a result, the derived
Amendment class needs to implement the commit parsing separately, as the
modified files need to be extracted differently for amendments (and the
commit ID also needs to be retrieved differently). Furthermore, because
of the list of named files, extracting the trailers needs to invoke
git-show separately.

Improve the situation by reworking the commit message parsing in three
steps. In the first step, use git-show to extract the commit ID, author,
title and body. In the second step, invoke git-interpret-trailers to
extract the trailers from the body that was previously extracted. The
third and final step extracts the list of modified files, using
different methods for regular commits and amendments.

This allows sharing code for the first two steps between the Commit and
Amendment classes, making the code simpler. The Commit class still
invokes git three times, while the Amendment class runs it three times
instead of four, improving performance slightly.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-12 15:44:17 +03:00
will whang
f87bf964fc libcamera: formats: Adding Support for Y12P
Add support for a 12-bit Mono format named formats::R12_CSI2P.

This format is added to support the IMX585 mono sensor, which uses the
MEDIA_BUS_FMT_Y12_1X12 media bus format.

Signed-off-by: will whang <will@willwhang.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-12 14:57:35 +03:00
Laurent Pinchart
4363266322 libcamera: Fix header grouping
The libcamera coding style groups the C and C++ standard library headers
in a single group. Fix the few offenders in the source tree.

While at it, add a missing blank line between header groups in a
separate location.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-12 14:57:35 +03:00
Sergei Trofimovich
b6369e7df2 libcamera: Add missing <stdint.h> include to internal/yaml_parser.h
Without the change the build fails on upcoming `gcc-15` as:

    In file included from ../src/libcamera/yaml_parser.cpp:8:
    ../include/libcamera/internal/yaml_parser.h:183:41: error: 'uint8_t' was not declared in this scope
      183 |                          std::is_same_v<uint8_t, T> ||
          |                                         ^~~~~~~

Signed-off-by: Sergei Trofimovich <slyich@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-12 14:57:35 +03:00
Sergei Trofimovich
d021d29822 libcamera: Add missing <stdint.h> include to base/file.h
Without the change the build fails on upcoming `gcc-15` as:

    In file included from ../src/libcamera/base/file.cpp:8:
    ../include/libcamera/base/file.h:62:33: error: 'uint8_t' was not declared in this scope
       62 |         ssize_t read(const Span<uint8_t> &data);
          |                                 ^~~~~~~

Signed-off-by: Sergei Trofimovich <slyich@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-08-12 14:57:35 +03:00
Kieran Bingham
62760bd260 libcamera: udev: Catch udev notification errors
The udev_monitor_receive_device() can return NULL on an error as
detailed in the man pages for the function.

The udevNotify() handler in the DeviceEnumeratorUdev directly uses the
return value of udev_monitor_receive_device() in successive calls to
process the event without having first checked the udev_device.

Ensure we identify, and handle events where the udev_device can not be
returned successfully.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=230
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-08 15:09:52 +01:00
Laurent Pinchart
1045522af9 libcamera: ipa_manager: Remove singleton requirement
The IPAManager class implements a singleton pattern due to the need of
accessing the instance in a static member function. The function now
takes a pointer to a PipelineHandler, which we can use to access the
CameraManager, and from there, the IPAManager.

Add accessors to the internal API to expose the CameraManager from the
PipelineHandler, and the IPAManager from the CameraManager. This
requires allocating the IPAManager dynamically to avoid a loop in
includes. Use those accessors to replace the IPAManager singleton.

Update the IPA interface unit test to instantiate a CameraManager
instead of an IPAManager and ProcessManager, to reflect the new way that
the IPAManager is accessed.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 18:58:55 +03:00
Laurent Pinchart
6f1df8d606 utils: checkstyle.py: Fix trailer parsing for commits with changelogs
Trailers are extracted from commits using the '(trailers:*)' formatting
specifier. git ignores dividers when doing so, as if the --no-divider
options was passed to git-interpret-trailers. This prevents trailers
from being located when the patch contains a local changelog.

There is unfortuantely no 'no-no-divider' option to the trailers format
specifier. Fix the issue by extracting trailers with
git-interpret-trailers, that gives better control of the parsing.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 18:58:54 +03:00
Jaslo Ziska
82c5ea24b0 gstreamer: Fix missing "greater than" symbol in author string
Signed-off-by: Jaslo Ziska <jaslo@ziska.de>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-08-07 18:58:52 +03:00
Laurent Pinchart
93506de63a utils: checkstyle.py: Validate SoB trailer against author
The TrailersChecker enforces the presence of a Signed-off-by tag in the
trailer, but doesn't verify that the tag matches the commit's author.
Add that verification, as required by the libcamera contribution
process.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 18:38:45 +03:00
Laurent Pinchart
fd130ef21b utils: checkstyle.py: Add author property to Commit class
Extend the Commit class with an author property, retrieved from the
commit. It will be used to extend checkers.

While at it, drop the unneeded .strip() call when retrieving the title
for amendment commits. The call got carried over from code that
initially needed it to strip the new line character, but that need
disappeard with usage of .splitlines().

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 18:38:44 +03:00
Laurent Pinchart
ff0613a6e5 libcamera: Don't add libcamera_public_headers to libcamera_public_sources
Now that libcamera_internal_sources is separate from
libcamera_internal_headers, perform the same split for
libcamera_public_sources and libcamera_public_headers to ensure
consistency of the build system variables.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:23 +03:00
Laurent Pinchart
6865649730 libcamera: Consolidate tracepoint header in libcamera_internal_headers
The libcamera_tracepoint_header variable stores the tracepoints.h header
custom target, for the sole purpose of being listed as a source of the
libcamera shared library, through the libcamera_internal_sources
variable.

Add the tracepoints.h header to libcamera_internal_headers instead of
libcamera_internal_sources, and list libcamera_internal_headers as a
source of the shared library, alongside libcamera_internal_sources. This
makes libcamera_internal_sources contain sources only, improving clarity
of the build system variables.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:22 +03:00
Laurent Pinchart
4736ec509d libcamera: Add missing headers to libcamera_internal_headers
The ipa_data_serializer.h and ipc_pipe.h headers are missing from
libcamera_internal_headers. Add them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:21 +03:00
Laurent Pinchart
186d75b10c libcamera: Consolidate all IPA headers in libcamera_ipa_headers
The IPA headers are listed in two different meson variables, one for
generated headers, and one for the other headers. There's no real reason
for this split, consolidate all of them in the libcamera_ipa_headers
variable.

While at it, don't add the IPA headers to the libcamera_internal_sources
variable, but list libcamera_ipa_headers in the sources for the shared
library. This moves the libcamera_internal_sources variable towards
holding source files, not header files, to improve clarity of the build
system.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:20 +03:00
Laurent Pinchart
29316a6693 libcamera: Move IPA headers to the libcamera_private dependency
The IPA headers are listed in the libcamera_public and libcamera_private
dependency objects, with the generated headers part of the private
dependency object and the non-generated headers part of the public
dependency object. As neither set of IPA headers are part of the public
API, list them both in the libcamera_private dependency object.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:19 +03:00
Laurent Pinchart
058cb9f4cc libcamera: Drop libcamera_generated_ipa_headers from sources
The libcamera_generated_ipa_headers variable, containing the list of
generated IPA headers, is listed in the sources of IPA modules, as well
as IPA tests. This was done to ensure that the modules and tests get
rebuilt when the generate IPA headers change. However, the dependency is
already handled through the libcamera_private dependency object,
specified for all those modules and tests. There's no need to list the
IPA generated headers as sources. Drop them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:17 +03:00
Laurent Pinchart
29455194d6 libcamera: Add version.h to public headers
The generated version.h header is part of the public headers, but is
missing from the libcamera_public_headers variable. Add it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:15 +03:00
Daniel Scally
88e5bf8279 libcamera: Split public and internal source arrays
Meson array variables hold lists of libcamera's source files. To help
facilitate the splitting of Doxygen generated documentation into
distinct public and internal versions, split those arrays to separate
public and internal variables.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Co-developed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:08 +03:00
Laurent Pinchart
ff26e21339 libcamera: Hide *::Private classes with __DOXYGEN_PUBLIC__
The *::Private classes are part of the internal API, as their name
implies. They are defined in internal headers, but implemented in the
same source file as their public counterparts. This will cause Doxygen
to complain about missing class definition when splitting the public and
internal API documents, as the internal headers won't be parsed by
Doxygen for the public API documentation.

Marking the classes with \internal isn't enough. The directive prevents
the documentation block from being included in the output, but this
occurs at the generation stage, after the documentation blocks are
parsed. Fix this by completely hidding the implementation of the
*::Private classes from Doxygen using preprocessor conditional
compilation. To do so, introduce a new macro, __DOXYGEN_PUBLIC__, that
will be defined for the public API documentation only.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:07 +03:00
Laurent Pinchart
697bcf5b10 libcamera: Mark internal parts of public classes with \internal
The libcamera public API exposes classes that have parts considered
internal. They inherit the Extensible class, and their internal parts
are split into a Private class. Those classes are defined in public API
headers, and their Private counterparts are defined in internal headers
sharing a common file name (in a different directory). Both headers are
documented in the same source file.

For instance, include/libcamera/camera.h contains the public API of the
Camera class, and include/libcamera/internal/camera.h its internal
counterpart. Both are documented in src/libcamera/camera.cpp.

As the internal headers are not part of the public API, they need to be
hidden from the future public API builds. To prepare for doing so, mark
them with the \internal Doxygen directive. Hardcode the Doxygen
INTERNAL_DOCS option to YES to include the internal API. This will be
changed later for the public API documentation build.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:06 +03:00
Laurent Pinchart
b783a9e6ee libcamera: Unify Doxygen file directive prefix for formats.h
libcamera has two formats.h headers, an internal one in
include/libcamera/internal/, and a public one generated at build time.
The convention is to prefix the internal header name with
libcamera/internal/ in the Doxygen file directive, but formats.cpp only
uses internal/ as a prefix. Unify it with the rest of the code base.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:04 +03:00
Laurent Pinchart
d0ef1b9451 libcamera: Make all internal headers visible to Doxygen
Two classes that have both public and internal headers, namely Camera
and Request, make only their public header visible to Doxygen through a
file directive. Fix them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:03 +03:00
Laurent Pinchart
a458eb1adf libcamera: Drop path prefix from Doxygen file directive
The Doxygen directive only requires qualifying header file names with a
path to differentiate between multiple header files with the same name.
Most file directives that refer to unambiguous files do not have a
libcamera/ and/or internal/ path prefix, but a few do, most likely due
to copy&paste. Drop the prefix in those few files for consistency.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-07 17:57:01 +03:00
Laurent Pinchart
8af95d6854 utils: checkstyle.py: Warn when no valid Signed-off-by line is found
All commits to libcamera must include a Signed-off-by line, and that
rule is enforced through git hooks and CI. This however doesn't prevent
patches from being submitted without an SoB tag, as noticed multiple
times in the past. Extend the checkstyle.py trailer checker to issue a
warning when the SoB line is missing to try and improve the situation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-05 19:37:29 +03:00
Laurent Pinchart
57396a0e3f libcamera: software_isp: Replace malloc() with std::vector<>
libcamera is implemented in C++, use std::vector<> to manage the
dynamically allocated line buffers instead of malloc() and free(). This
simplifies the code and improves memory safety by ensuring no allocation
will be leaked.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
2024-08-05 19:29:03 +03:00
Laurent Pinchart
46275401e6 ipa: libipa: camera_sensor_helper: Reference blackLevel() in documentation
The documentation for the blackLevel_ member is very terse. Reference
the more complete documentation of the sibling blackLevel() member
function to provide more information.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-05 19:28:56 +03:00
Laurent Pinchart
9f513439b6 meson: Drop gcc 8 support
The libcamera CI has retired gcc 8 testing with the end of life of
Debian Buster at the end of June 2024. As gcc 8 isn't tested anymore, we
can't guarantee it will keep building libcamera correctly. Drop its
support. If anyone still has a compelling use case for gcc 8 support for
libcamera, we will investigate how to restore it in CI.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-05 18:26:36 +03:00
Laurent Pinchart
0bb8afc9ac libcamera: Remove spaces at end of lines
Spaces at end of lines have cropped up in a few places in libcamera.
Remove them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-05 18:25:53 +03:00
Pablo Pita
19bbca3c0b Document additional environmental variables
* LIBCAMERA_IPA_PROXY_PATH: path to access a proxy IPA
* LIBCAMERA_RPI_TUNING_FILE: used to pass tuning configuration data for the raspberry pi

Signed-off-by: Pablo Pita <pablo.pita@gmail.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-08-01 15:13:13 +01:00
Milan Zamazal
6c17996879 libcamera: ipa_proxy: Report a missing configuration as a warning
When the configuration file for an IPA module is missing, it is reported
as an error in the log, for example:

  ERROR IPAProxy ipa_proxy.cpp:149 Configuration file 'imx219.yaml' not found for IPA module 'simple'

This is misleading because several pipelines use uncalibrated.yaml in
such a case and can continue working.  And in case of software ISP,
there is currently no other configuration file so the error is always
reported.

On the other hand, in some other cases the presence of the configuration
file is required and it is an error if it is missing.

Let's introduce a new optional argument to IPAProxy::configurationFile
that specifies a fallback file if the requested file is not found.  If
the primary requested file is not found and a non-empty fallback file is
specified then a warning is logged and the fallback file is looked up.
If neither the fallback file can be found then only then an error is
logged and the method returns an empty string.  This change has also the
benefit of putting the common fallback file ("uncalibrated.yaml")
pattern to a single place.

Signed-off-by: Milan Zamazal <mzamazal@redhat.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>
2024-08-01 08:50:36 +01:00
Milan Zamazal
58f83d70eb libcamera: ipa_proxy: Unify configurationFile argument name
The argument name is different in the declaration and the definition.
Let's use the same one in both, namely `name'.

Signed-off-by: Milan Zamazal <mzamazal@redhat.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>
2024-08-01 08:50:36 +01:00
Milan Zamazal
06674004fb libcamera: simple: Log a missing sensor in a better way
SimplePipelineHandler::match may be called several times for different
pipeline configurations.  Not all of these calls must succeed.  For
example, for TI AM69 board with a single camera attached, the following
error is reported in the log even when libcamera works fine:

  ERROR SimplePipeline simple.cpp:1558 No sensor found

This is because a sensor is found for /dev/media0 but not for
/dev/media1.  The error is harmless in such a case and only confuses
users who may think no camera is detected at all.  Let's change the
error to info and add the device node to the message to indicate the
error is specific to the given media only.  It's up to the callers to
report a fatal error condition if libcamera cannot work due to no
matching pipeline configuration.

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>
2024-08-01 08:50:36 +01:00
Laurent Pinchart
a3ddf56a00 libcamera: software_isp: Remove file seal TODO item
The file seal TODO item has been addressed. Remove it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2024-08-01 01:22:14 +03:00
Laurent Pinchart
efc7a85bc0 libcamera: shared_mem_object: Prevent memfd from shrinking or growing
The memfd underlying the SharedMem object must not shrink, or memory
corruption will happen. Prevent this by setting the shrink seal on the
file. As there's no valid use case for growing the memory either, set
the grow seal as well.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2024-08-01 01:22:14 +03:00
Laurent Pinchart
93d9751945 libcamera: base: memfd: Handle uClibc compatibility with function wrapper
uClibc doesn't provide memfd_create(), which led libcamera to open-code
the call using syscall(). Sprinkling the code with #ifdef's isn't the
most readable option, so improve it by providing a local implementation
of memfd_create(), and call the function unconditionally from
MemFd::create(). This makes the main code path more readable.

Suggested-by: Nicolas Dufresne <nicolas@ndufresne.ca>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
2024-08-01 01:21:59 +03:00
Laurent Pinchart
a7a589df15 libcamera: base: Add MemFd helper class
libcamera creates memfds in two locations already, duplicating some
code. Move the code to a new MemFd helper class.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2024-08-01 01:20:10 +03:00
Laurent Pinchart
98b0176839 meson: Enable simple pipeline handler on all platforms by default
The simple pipeline handler is enabled by default on arm platforms only,
as it used to support arm SoCs only. Now that support for the IPU6 has
been added to the pipeline handler, it should be enabled on x86
platforms as well. Fix it.

Fixes: 06e0d8508e ("libcamera: pipeline: simple: Enable intel-ipu6 with Soft ISP")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2024-07-31 12:26:21 +03:00
Laurent Pinchart
7f33dfc100 libcamera: Avoid variable-length arrays
Unlike in C where they have been standardized since C99, variable-length
arrays in C++ are an extension supported by gcc and clang. Clang started
warning about this with -Wall in version 18:

src/libcamera/ipc_unixsocket.cpp:250:11: error: variable length arrays in C++ are a Clang extension [-Werror,-Wvla-cxx-extension]
  250 |         char buf[CMSG_SPACE(num * sizeof(uint32_t))];
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

One simple option is to disable the warning. However, usage of VLAs in
C++ is discouraged by some, usually due to security reasons, based on
the rationale that developers are often unaware of unintentional use of
VLAs and how they may affect the security of the code when the array
size is not properly validated.

This rationale may sound dubious, as the most commonly proposed fix is
to replace VLAs with vectors (or just arrays dynamically allocated with
new() wrapped in unique pointers), without adding any size validation.
This will not produce much better results. However, keeping the VLA
warning and converting the code to dynamic allocation may still be
slightly better, as it can prompt developers to notice VLAs and check if
size validation is required.

For these reasons, convert all VLAs to std::vector. Most of the VLAs
don't need extra size validation, as the size is bound through different
constraints (e.g. image width for line buffers). An arguable exception
may be the buffers in IPCUnixSocket::sendData() and
IPCUnixSocket::recvData() as the number of fds is not bound-checked
locally, but we will run out of file descriptors before we could
overflow the buffer size calculation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Acked-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-07-31 01:22:13 +03:00
Laurent Pinchart
d5cbf69a7f apps: qcam: Disable -Wextra-semi
The Qt 6 qkeysequence.h header has an extra semicolon. This causes a
build failure with clang:

/usr/include/qt6/QtGui/qkeysequence.h:139:26: error: extra ';' after member function definition [-Werror,-Wextra-semi]
  139 |     Q_ENUM(SequenceMatch);
      |                          ^

We can't fix the issue, so ignore the warning in qcam.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-07-30 14:21:21 +03:00
Hou Qi
c9152bad5c gstreamer: Fix width and height range handling
This changes is fixing critical error message
"gst_value_set_int_range_step: assertion 'start < end' failed" observed
when building GStreamer caps from a stream configuration whose size
range holds a single size.

GStreamer range step definition requires distinct min and max values
definitions, otherwise above error message is output.

libcamera SizeRange instance may return a single size leading to
identical min and max values. Add a conditional check where the min and
max of the range are distinct during iterating the supported sizes for
each pixelformat.

To prevent appending structures that are already expressed with this
update, gst_caps_merge_structure() is used in place of
gst_caps_append_structure().

Signed-off-by: Hou Qi <qi.hou@nxp.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-26 10:15:31 +01:00
Kieran Bingham
9c40320763 libcamera v0.3.1
The abi-compliance checker reports 100% binary and source compatibility,
so this release does not change the SONAME.

  Binary compatibility: 100%
  Source compatibility: 100%
  Total binary compatibility problems: 0, warnings: 0
  Total source compatibility problems: 0, warnings: 0

The following commits in this release relate to either a bug fix or
improvement to existing commit.

- ipa: rpi: Make monoSensor() accessor const
  - Fixes: 2031e2f290 ("ipa: rpi: Add accessor function for monoSensor_")
- libcamera: dma_buf_allocator: Create memfd with CLOEXEC
  - Fixes: ea4baaacc3 ("libcamera: DmaBufAllocator: Support allocating from /dev/udmabuf")
- libcamera: dma_buf_allocator: Work around lack of memfd_create() in uClibc
  - Fixes: ea4baaacc3 ("libcamera: DmaBufAllocator: Support allocating from /dev/udmabuf")
- libcamera: dma_buf_allocator: Work around lack of file seals in uClibc
  - Fixes: ea4baaacc3 ("libcamera: DmaBufAllocator: Support allocating from /dev/udmabuf")
- test: ipa: rkisp1: utils: Fix floating and fixed point conversion test
  - Fixes: 9d152e9c66 ("ipa: rkisp1: Add a helper to convert floating-point to fixed-point")
- ipa: rkisp1: Fix algorithm controls vanish after configure
  - Fixes: 4c5152843a ("ipa: rkisp1: Derive rkisp1::algorithms::Agc from AgcMeanLuminance")
- pipeline: rpi: Don't validate configuration in generateConfiguration()
  - Bug: https://github.com/raspberrypi/libcamera/issues/138
- ipa: rkisp1: agc: Fix initialization without metering modes
  - Fixes: 35233938ee ("ipa: rkisp1: agc: Read histogram weights from tuning file")
- v4l2: v4l2_compat: Fix redirect from `__open(at)64_2()`
  - Fixes: 1023107b64 ("v4l2: v4l2_compat: Intercept open64, openat64, and mmap64")
- ipa: rkisp1: blc: Drop [[maybe_unused]] attribute
  - Fixes: 50c28e1351 ("ipa: rkisp1: blc: Query black levels from camera sensor helper")
- ipa: rkisp1: ccm: Fix ccm metadata output
  - Fixes: cbfdfa42ca ("ipa: rkisp1: algorithms: Add crosstalk algorithm")
- gstreamer: pool: Replace GstAtomicQueue with deque and mutex
  - Bug: https://bugs.libcamera.org/show_bug.cgi?id=201
- gstreamer: allocator: Ensure camera manager stay alive
  - Bug: https://bugs.libcamera.org/show_bug.cgi?id=211

And the following updates have been made in this release, grouped by
category:

core:
 - treewide: Query list of cameras just once
 - libcamera: yaml_parser: Avoid double lookup in `operator[]`
 - utils: checkstyle.py: Refactor IncludeChecker
 - utils: checkstyle.py: Extend IncludeChecker to cover math.h
 - utils: checkstyle.py: Add a check for hex values
 - utils: checkstyle.py: Show location of coding style issue within line
 - update-kernel-headers: Add linux/udmabuf.h to headers to sync
 - include: linux: Update kernel headers to version v6.10-rc1
 - libcamera: v4l2_subdevice: Update to the new kernel routing API
 - libcamera: Rename DmaHeap class to DmaBufAllocator
 - libcamera: DmaBufAllocator: Support allocating from /dev/udmabuf
 - libcamera: dma_buf_allocator: Create memfd with CLOEXEC
 - libcamera: dma_buf_allocator: Work around lack of memfd_create() in uClibc
 - libcamera: dma_buf_allocator: Work around lack of file seals in uClibc
 - libcamera: Add gamma control id
 - clang-format: Make Qt includes matching case sensitive
 - meson: Group libipa and libipa_includes in a dependency object
 - libcamera: controls: Add missing period at end of Gamma description
 - libcamera: yaml_parser: Make default value templated in `get()`
 - libcamera: yaml_parser: Drop std::enable_if_t guards for get() function
 - libcamera: yaml_parser: Delegate YamlObject::get() to helper structure
 - libcamera: yaml_parser: Add support for float types
 - libcamera: base: log: Declare log categories when defining them
 - meson: Enable warnings to flag missing declarations
 - libcamera: Fix maybe-uninitialized error
 - converter: converter_v4l2_m2m: Rectify streams sanity check
 - converter: converter_v4l2_m2m: Rename private Stream class
 - libcamera: converter: Replace usage of stream index by Stream pointer
 - libcamera: base: utils: Implement hex() for 8-bit and 16-bit values
 - libcamera: v4l2_videodevice: Use bufferType_ in [get|try|set]Format()
 - utils: gen-version: Use posix compliant date

-----------------------------------------------------------------------------
ipa:
 - ipa: rpi: Make monoSensor() accessor const
 - ipa: rkisp1: Add a helper to convert floating-point to fixed-point
 - ipa: rpi: Disable StatsOutputEnable control by default
 - ipa: rkisp1: Fix algorithm controls vanish after configure
 - ipa: rkisp1: Add GammaOutCorrection algorithm
 - ipa: libipa: Add Vector class
 - ipa: libipa: Copy pwl from rpi, and clean it up to match libcamera
 - ipa: rpi: controller: Use libipa's Pwl class
 - ipa: rkisp1: goc: Fix typographical issues in documentation.
 - ipa: rkisp1: goc: Drop incorrect [[maybe_unused]]
 - ipa: rkisp1: goc: Use copydoc
 - ipa: rkisp1: goc: Mark default gamma table as static constexpr
 - ipa: rkisp1: goc: Avoid use of auto for short type
 - libcamera: libipa: camera_sensor: Define AR0521 helper functions inline
 - ipa: rkisp1: cproc: Use anonymous namespace to limit symbol visibility
 - ipa: rkisp1: cproc: Merge identical functions
 - ipa: rkisp1: cproc: Drop incorrect [[maybe_unused]]
 - ipa: rkisp1: agc: Read histogram weights from tuning file
 - ipa: rkisp1: agc: Plumb mode-selection and frame duration controls
 - ipa: libipa: vector: Specialize YamlObject getter
 - ipa: libipa: vector: Drop readYaml() function
 - ipa: libipa: pwl: Suffix \param with direction
 - ipa: libipa: pwl: Make the empty() function inline
 - ipa: libipa: pwl: Add a size() function
 - ipa: libipa: pwl: Add a constructor that moves a Point vector
 - ipa: libipa: pwl: Specialize YamlObject getter
 - ipa: libipa: Add Matrix class
 - ipa: libipa: Add MatrixInterpolator class
 - ipa: rkisp1: algorithms: Add crosstalk algorithm
 - ipa: libipa: vector: Add matrix-vector multiplication
 - ipa: rkisp1: agc: Fix initialization without metering modes
 - ipa: libipa: agc_mean_luminance: Fix enumerator names
 - ipa: libipa: agc_mean_luminance: Include missing header
 - ipa: rkisp1: Document all AGC parameters in IPAActiveState
 - ipa: rkisp1: Document all AGC parameters in IPAFrameContext
 - ipa: rkisp1: agc: Make size argument to computeHistogramPredivider const
 - ipa: rkisp1: agc: Don't update histogram parameters unnecessarily
 - ipa: rkisp1: agc: Simplify predivider calculation
 - ipa: rkisp1: agc: Use mode from frame context to calculate new EV
 - ipa: rkisp1: agc: Rename maxShutterSpeed to maxFrameDuration
 - ipa: rkisp1: agc: Correctly clamp maximum shutter speed
 - ipa: rkisp1: agc: Move AeEnable control to the AGC algorithm
 - ipa: rpi: controller: Replace Pwl::readYaml() with YamlObject::get()
 - ipa: libipa: pwl: Drop readYaml() function
 - ipa: rkisp1: agc: Rename frame context update variable to updateMetering
 - ipa: libipa: matrix: Fix incorrect symbol namespace
 - ipa: ipa_interface: Declare ipaCreate() in libcamera namespace
 - ipa: rpi: Define local functions in anonymous namespace
 - ipa: libipa: Add black levels to camera sensor helper
 - ipa: rkisp1: Move camHelper into IPAContext
 - ipa: rkisp1: blc: Query black levels from camera sensor helper
 - ipa: rkisp1: blc: Report sensor black levels in metadata
 - ipa: rkisp1: data: Update tuning files for imx219 and imx258
 - ipa: rkisp1: Move ov4689 and ov5640 black levels into sensor helpers
 - ipa: rkisp1: blc: Drop [[maybe_unused]] attribute
 - ipa: rkisp1: Install all tuning files
 - libipa: camera_sensor_helper: Add OV5675 black level
 - ipa: rkisp1: awb: Clamp gains to machine limits
 - ipa: rkisp1: awb: Unconditionally fill metadata
 - ipa: rkisp1: ccm: Fix ccm metadata output
 - ipa: rkisp1: ccm: Ensure metadata contains valid ccm
 - libcamera: libipa: camera_sensor: Add onsemi AR0144 sensor properties
 - ipa rkisp1: Remove temperatureK from FrameContext

-----------------------------------------------------------------------------
apps:
 - android: camera_capabilities: Fix GCC 14 warning
 - v4l2: v4l2_compat: Fix redirect from `__open(at)64_2()`
 - v4l2: v4l2_compat: Move `open*()` flag check into function
 - py: libcamera: Move function declarations to common header
 - v4l2: v4l2_compat: Include missing headers
 - v4l2: v4l2_compat: Selectively disable -Wmissing-declarations
 - apps: Define local functions in anonymous namespace
 - apps: common: dng_writer: Workaround for "Unknown tag 33421" error
 - apps: common: dng_writer: Support RAW16 formats
 - apps: common: dng_writer: Rename packing functions
 - apps: common: dng_writer: Add thumbnail scanline function for Raw
 - apps: common: dng_writer: Support RAW10 and RAW12 format
 - apps: common: dng_writer: Fix thumbnail generation on BE machines
 - apps: common: dng_writer: Fix RAW10 and RAW12 packing on BE machines
 - qcam: viewfinder_qt: Maintain aspect ratio
 - apps: qcam: Port to Qt 6
 - gstreamer: pool: Replace GstAtomicQueue with deque and mutex
 - gstreamer: allocator: Ensure camera manager stay alive
 - v4l2: v4l2_compat: Fix ioctl() prototype with musl C library
 - gst: Add child proxy support to libcamerasrc
 - gst: Document libcamerasrc multi stream usage

-----------------------------------------------------------------------------
test:
 - test: ipa: rkisp1-utils: Fix capitalization of hex numbers
 - test: camera: Increase timeout for vimc capture tests
 - test: fence: Turn class member variable into local variable
 - test: fence: Fix race condition
 - test: fence: Increase timeout for fence test
 - test: v4l2_videodevice: Increase timeout for vimc capture tests
 - test: ipa: rkisp1-utils: Fix coding style for template arguments
 - test: ipa: rkisp1: utils: Fix floating and fixed point conversion test
 - test: ipc: unixsocket: Define local function in anonymous namespace
 - test: gstreamer: Include missing sanitizer/asan_interface.h header
 - test: utils: Extend utils::hex() test to 8-bit and 16-bit values
 - test: gstreamer: Test memory lifetime

-----------------------------------------------------------------------------
pipeline:
 - libcamera: software_isp: Use a specific integer type for black level
 - libcamera: software_isp: Honor black level in AWB
 - libcamera: software_isp: Move color mappings out of debayering
 - libcamera: software_isp: Remove DebayerParams::kGain10
 - libcamera: software_isp: Remove TODO about internal representation
 - pipeline: vimc: Don't hardcode scaling factor with recent kernels
 - libcamera: software_isp: Allow using dma-buffers from /dev/udmabuf
 - libcamera: software_isp: Fix includes ordering in simple.cpp
 - pipeline: rkisp1: cproc: Fix default value handling
 - pipeline: rpi: Don't validate configuration in generateConfiguration()
 - libcamera: debayer_cpu: Add 32bits/aligned output formats
 - libcamera: software_isp: Drop unnecessary sanity check
 - libcamera: pipeline: simple: Enable intel-ipu6 with Soft ISP
 - libcamera: pipeline: simple: Enable Soft ISP for TI CSI-RX

-----------------------------------------------------------------------------
tuning:
 - utils: raspberrypi: ctt: Adapt tuning tool for both VC4 and PiSP
 - utils: raspberrypi: ctt: Added CAC support to the CTT
 - utils: raspberrypi: ctt: Changed CTT handling of VC4 and PiSP
 - utils: raspberrypi: ctt: Update tuning tool for HDR
 - utils: raspberrypi: ctt: Add option to convert between vc4/pisp targets
 - utils: raspberrypi: ctt: Add a maximum gain parameter for LSC
 - utils: libtuning: modules: Add skeletal AGC module
 - utils: tuning: rkisp1: Add skeletal AGC to the rkisp1 tuning script
 - utils: libtuning: Correct GBRG Image parsing
 - libtuning: Backport improvements in MacBeth search reliability
 - libtuning: Fix reference image
 - libtuning: Copy files from raspberrypi
 - libtuning: Copy visualize_macbeth_chart from raspberry pi
 - utils: tuning: Add requirements file and update readme
 - libtuning: Fix imports
 - libtuning: Migrate prints to python logging framework
 - libtuning: Fix visualize_macbeth_chart()
 - libtuning: Improve filename parsing
 - libtuning: Implement a minimal yaml parser
 - libtuning: Reactivate macbeth locator
 - libtuning: Be a bit more verbose
 - libtuning: lsc: rkisp1: Clip lsc values to valid range
 - libtuning: Use the color member of the Image class
 - libtuning: Remove need for Cam object from ccm
 - libtuning: modules: Add initial CCM module
 - libtuning: Handle cases, where no lsc tuning images are present
 - libtuning: Only warn if processing returns None
 - libtuning: Add static module
 - tuning: rkisp1: Add some static modules
 - libtuning: lsc: rkisp1: Do not calculate ratios to green
 - libtuning: lsc: Prevent negative values
 - libtuning: agc: rkisp1: Increase y-target

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-25 13:49:12 +01:00
Nicolas Dufresne
b7225c887a gst: Document libcamerasrc multi stream usage
This adds documentation and an example using gst-launch-1.0.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-25 12:11:48 +01:00
Nicolas Dufresne
a1549129d3 gst: Add child proxy support to libcamerasrc
The child proxy interface is needed in order to allow setting
properties on pad using parse launch syntax.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-25 12:11:48 +01:00
Laurent Pinchart
74513c3987 libcamera: libipa: camera_sensor: Add onsemi AR0144 sensor properties
Provide the onsemi AR0144 camera sensor properties and registration with
libipa for the gain code helpers.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-25 11:57:33 +01:00
Laurent Pinchart
83b3141178 v4l2: v4l2_compat: Fix ioctl() prototype with musl C library
The musl C library, as well as the POSIX standard, define the ioctl()
function's request argument as an int. glibc and uclibc, on the other
hand, define it as an unsigned long.

This difference between the function prototype and the implementation in
the V4L2 adaptation layer causes a compilation error with musl. Fix it
by detecting the function prototype and declaring the libcamera ioctl()
handler accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-25 11:57:15 +01:00
Nicolas Dufresne
0c9862d6e3 gstreamer: allocator: Ensure camera manager stay alive
Without the camera manager, it is not possible to cleanly delete the
FrameBufferAllocator object. Keep the camera manager alive until all the
memory object have been released.

A shared_ptr to the CameraManager is introduced which is itself stored
as a plain pointer and allocated and released explicitly. When more
than one C++ member is required, this can be refactored to use a new C++
class, but the struct _GstLibcameraAllocator is allocated and freed by
glib, so it does not have automatic destruction presently.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=211
[Kieran: Update test framework to remove expected test fail]
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.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>
2024-07-25 11:44:32 +01:00
Nicolas Dufresne
d267fd6d89 test: gstreamer: Test memory lifetime
Test that everything works fine if a buffer outlives the pipeline.

[Kieran: Update test path with comments and clarify test case]
Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-25 11:44:05 +01:00
Zach DeCook
a61241eb8b utils: gen-version: Use posix compliant date
The version string of libcamera is presently appended with a date/time
argument in the case of a dirty tree to show further detail of when it
was built. This string is generated with the iso-8601 parameter to
'date' and produces a date string in the form:
"2024-06-17T22:15:30+01:00"

Strict posix shells or implementations of 'date' which may be optimised
for size such as the one provided by busybox or Alpine Linux may not
support the '--iso-8601' flag.

To support builds on those platforms, use a direct POSIX-compliant
date-format string instead matching as closely as possible to the
iso-8601 definition.

An exact match is not possible with those restrictions so 'date
%Y-%m-%dT%H:%M:%S%Z' is used which produces 2024-06-17T22:15:30BST.

The use of the human readable timezone identifier provides a friendlier
output for the string than a timezone offset at the expense of being
less sortable in the exceptionally low risk and unlikely event of two
custom builds being compared at the same time of different timezones.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Zach DeCook <zachdecook@librem.one>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-25 09:57:54 +01:00
Nicolas Dufresne
04f1f20337 gstreamer: pool: Replace GstAtomicQueue with deque and mutex
The GstAtomicQueue only supports 2 threads, one pushing, and one
popping. We pop and push on error cases and we may have multiple threads
downstream returning buffer (using tee), which breaks this assumption.

On top of which, the release function, that notifies when the queue goes
from empty to not-empty relies on a racy empty check. The downstream
thread that does this check is effectively concurrent with our thread
calling acquire().

Fix this by replacing the GstAtomicQueue with a std::deque, and protect
access to that using the object lock.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=201
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-25 09:54:56 +01:00
Stefan Klug
01132257b9 ipa: rkisp1: ccm: Ensure metadata contains valid ccm
When the colour temperature does not change between frames, the ccm
inside the frame context is not updated and the metadata contains
invalid data. Fix that by caching the ccm inside the active state.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
[Kieran: Remove spurious [[maybe_unused]] addition]
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-24 15:37:04 +01:00
Stefan Klug
c7d7e7ec4a ipa: rkisp1: ccm: Fix ccm metadata output
Only the first three entries of the matrix were set. Fix that.

Fixes: cbfdfa42ca ("ipa: rkisp1: algorithms: Add crosstalk algorithm")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-24 15:36:02 +01:00
Stefan Klug
29ce7b96ea ipa: rkisp1: awb: Unconditionally fill metadata
When the colour temperature estimation gets skipped, the metadata isn't
populated. Fix that by filling the metadata early in the function.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-24 15:36:01 +01:00
Stefan Klug
e9aea086b5 ipa rkisp1: Remove temperatureK from FrameContext
The frame context is used to store data used for processing that frame.
It is later used to either act as input for other algorithms or to fill
the metadata.  For the colour temperature this is not needed, as the
meatadata shall not contain the value that was active when the image was
processed, but the value that was calculated based on the statistics for
that image. This is no functional change.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-24 15:36:01 +01:00
Stefan Klug
7b8094d6fc ipa: rkisp1: awb: Clamp gains to machine limits
When the color gains are set manually it is possible to specify a
gain that wrapped the hardware limits. It would also be possible to
further tune the floating point limits, but that is an error prone
approach. So the limits are imposed on the integers, just before writing
to the hardware. This noticeably reduces some oscillations in the awb
regulation.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-24 15:34:14 +01:00
Daniel Semkowicz
7ee9ef451d libipa: camera_sensor_helper: Add OV5675 black level
Add black level value for OV5675 camera sensor.
According to datasheet, default value is 0x10, 10 bits width.
However, Linux kernel driver initializes black level target value
to 0x40. Set the value to the same as in kernel driver, but scaled
to 16 bits.

Signed-off-by: Daniel Semkowicz <dse@thaumatec.com>
Reviewed-by: Quentin Schulz <quentin.schulz@cherry.de>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-24 15:28:54 +01:00
Neal Gompa
71aa3ceec3 apps: qcam: Port to Qt 6
Open source Qt 5 has been effectively end of life since the release
of Qt 6, and Qt 6 has current LTS releases now.

This change ports qcam to Qt 6.2 and drops some of the baggage related
to Qt 5 that is no longer applicable.

Signed-off-by: Neal Gompa <neal@gompa.dev>
Reviewed-by: Eric Curtin <ecurtin@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-24 14:25:38 +01:00
Jai Luthra
929978ee65 libcamera: pipeline: simple: Enable Soft ISP for TI CSI-RX
The j721e-csi2rx driver pipeline uses no converters, so enable the
software ISP plugin support. This is handy for boards with AM62 SoC
(like BeaglePlay) that have no HW ISP.

Tested with IMX519 on SK-AM62 running a kernel built with dmabuf heap
support.

Signed-off-by: Jai Luthra <j-luthra@ti.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Tested-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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-07-22 03:22:22 +03:00
Hans de Goede
4661a7eedf libcamera: v4l2_videodevice: Use bufferType_ in [get|try|set]Format()
V4L2VideoDevice is using the caps to determine which kind of buffers to
use with the video-device in 2 different cases:

1. V4L2VideoDevice::open()
2. V4L2VideoDevice::[get|try|set]Format()

And the order in which the caps are checked is different between
these 2 cases. This is a problem for /dev/video# nodes which support
both video-capture and metadata buffers. open() sets bufferType_ to
V4L2_BUF_TYPE_VIDEO_CAPTURE[_MPLANE] in this case, where as
[get|try|set]Format() will call [get|set]FormatMeta() which does not
work with V4L2_BUF_TYPE_VIDEO_CAPTURE[_MPLANE] buffers.

Switch [get|try|set]Format() to use the bufferType_ to determine on what
sort of buffers they should be operating, leaving the V4L2VideoDevice
code with only a single place where the decision is made what sort
of buffers it should operate on for a specific /dev/video# node.

This will also allow to modify open() in the future to take a bufferType
argument to allow overriding the default bufferType it selects for
/dev/video# nodes which are capable of supporting more then 1 buffer type.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-07-21 19:26:46 +03:00
Kieran Bingham
644986c2b7 qcam: viewfinder_qt: Maintain aspect ratio
Keep the image aspect ratio when displaying in the viewfinder.

When the window is adjusted to a size that differs in aspect ratio to
the image, keep the image centered in the main window.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-07-08 17:52:31 +01:00
Robert Mader
d890a7e48e ipa: rkisp1: Install all tuning files
We have all these neat tuning files. Unfortunately we forgot to install
many of them.

Signed-off-by: Robert Mader <robert.mader@collabora.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>
2024-07-06 14:01:59 +01:00
Stefan Klug
974a526c83 libtuning: agc: rkisp1: Increase y-target
With the addition of gamma out correction the relative luminance target
was set too low. As brightness is a bit subjective it is difficult to
come up with the "correct" value. With 0.5 the patch 22 on the macbeth
chart (neutral grey, 18% reflectance) ended up a bit below 50% grey,
which seems reasonable.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 22:38:20 +02:00
Stefan Klug
d5db46232e libtuning: lsc: Prevent negative values
In cases where the calibration image contains super dark areas, or when
an invalid blacklevel was supplied, the grid might get close to zero or
negative. This would have bad effects on the 1/grid later. So clamp the
values to a small positive number.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 22:38:20 +02:00
Stefan Klug
e91f6c384f libtuning: lsc: rkisp1: Do not calculate ratios to green
The current LSC algorithm for the rkisp1 just forwards the LSC tables to
the hardware, so absolute factors are needed and not ratios compared to
green. Therefore every channel needs to be calculated independently.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 22:38:20 +02:00
Stefan Klug
e0f41b7401 tuning: rkisp1: Add some static modules
Add awb, blc, cproc, filter, and gamma to the tuning file.  These don't
need any configuration.

At the moment there are no inter-module dependencies in the tuning
process. We can therefore safely sort them alphabetically. As soon as
the first dependency gets introduced (most likely lsc -> ccm) we will
see how to solve that.

The output order controls the order of processing in the IPA. It is now
also in alphabetical order which happens to be no change for the modules
that existed previously. For the others, there is no need for a specific
order.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-07-05 22:38:20 +02:00
Stefan Klug
9eb26a8716 libtuning: Add static module
Add a static module class, that can be used to add static data to the
tuning file. This is propably not the best solution, but allows us to
progress without writing lots of dummy classes for static cases.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 22:38:19 +02:00
Stefan Klug
8e411bfaef libtuning: Only warn if processing returns None
There are valid cases where a module returns None. E.g. no images were
provided for LSC calibration. We should however define proper semantics
there. Continue with a warning for now.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 22:38:19 +02:00
Stefan Klug
54a8405726 libtuning: Handle cases, where no lsc tuning images are present
Make it clear that no lsc calibration was done by returning None instead
of a incomplete configuration.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 22:38:19 +02:00
Paul Elder
721b976928 libtuning: modules: Add initial CCM module
Implement a minimal ccm calibration module. For now it doesn't take the
results from lsc into account and supports rkisp1 only.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-07-05 22:38:18 +02:00
Stefan Klug
64d4e596a4 libtuning: Remove need for Cam object from ccm
Remove the need for the Cam object, as we don't want to port
it from Raspberry Pi.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 22:38:18 +02:00
Stefan Klug
902a78416c libtuning: Use the color member of the Image class
In the Image class the variable holding the color temperature is named
color instead of col which was used by the raspberry pi scripts. Rename
accordingly.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 22:38:18 +02:00
Stefan Klug
14f6a87917 libtuning: lsc: rkisp1: Clip lsc values to valid range
Based on the input images, the lsc values could exceed the range allowed
by the rkisp1. As we are now clipping the values, we can simplify the
value mapping.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 22:38:17 +02:00
Stefan Klug
a043e55110 libtuning: Be a bit more verbose
Print a info on every image that gets processed and a warning on every
image that gets ignored.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-07-05 22:38:17 +02:00
Stefan Klug
611242b259 libtuning: Reactivate macbeth locator
Add the missing pieces and store the result inside the image object.
This solution is not very nice, and should be refactored soon. For that
we need a concept to collect temperature and/or image specific results
in a central place. For now it serves the purpose.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 22:38:16 +02:00
Stefan Klug
6672c49cbf libtuning: Implement a minimal yaml parser
At the moment this just reads the yaml file and returns it verbatim.
This needs to evolve further in the near future.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-07-05 22:38:16 +02:00
Stefan Klug
797f598502 libtuning: Improve filename parsing
In the tuning datasets, the files had names like
'imx335_1600l_3000k_1.dng'. That failed on the old filename parsing
function. As there is no need to dictate the order of the tags, split
the big regex into chunks and parse them one by one. This also makes
the code easier to digest.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-07-05 22:38:16 +02:00
Stefan Klug
22c7c1e560 libtuning: Fix visualize_macbeth_chart()
The old function uses PIL to save the image, which is not in the
requirements file. As we are already requiring opencv, use that to save
images instead of an additional dependency

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-07-05 22:38:16 +02:00
Stefan Klug
aa02706a34 libtuning: Migrate prints to python logging framework
In ctt_ccm.py the logging functionality of the Cam object was used. As
we don't want to port over that class, it needs to be replaced anyways.
While at it, also replace the eprint function as it doesn't add any
value over the logging framework and misses the ability for easy log
formatting.

For nice output formatting add the coloredlogs library.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-07-05 22:38:00 +02:00
Stefan Klug
b1f3b3f08d libtuning: Fix imports
Fix imports to match new structure in the files copied from Raspberry
Pi. Add missing imports in macbeth.py. Add missing dependencies to
requirements.txt.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-07-05 17:47:42 +02:00
Stefan Klug
388fe3bcf9 utils: tuning: Add requirements file and update readme
Add a requirements file to ease the installation and use of the tuning
scripts. Document that in the readme. No debian packages are provided as
rawpy is not packaged as deb. So pip has to be used anyways.

Also add pyyaml which was missing in the dependencies.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 12:45:10 +02:00
Stefan Klug
ad930fa74b libtuning: Copy visualize_macbeth_chart from raspberry pi
Copy visualize_macbeth_chart from raspberry pi.  It is copied verbatim
and does not work in this state.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-05 12:40:53 +02:00
Stefan Klug
9af5948cac libtuning: Copy files from raspberrypi
Copy ctt_{awb,ccm,colors,ransac} from the raspberrypi tuning scripts as
basis for the libcamera implementation. color.py was renamed to
ctt_colors.py to better express the origin.

The files were taken from commit 66479605ba ("utils: raspberrypi: ctt:
Improve the Macbeth Chart search reliability").

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Paul Elder <paul.elder@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-07-05 12:39:05 +02:00
Stefan Klug
6fb8f5cbf9 libtuning: Fix reference image
Opencv fails to load the image. The added license destroys the magic
number. Fix, by moving the licence below the magic number.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul ELder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-07-05 12:38:49 +02:00
Stefan Klug
f119d6f048 libtuning: Backport improvements in MacBeth search reliability
Port commit 66479605ba ("utils: raspberrypi: ctt: Improve the Macbeth
Chart search reliability") into libtuning.

Previously the code would brighten up images in case the Macbeth Chart
is slightly dark, and also zoom in on sections of it to look for
charts occupying less of the field of view. But it would not do both
together.

This change makes the search for smaller charts also repeat that
search for the brightened up images that it made earlier, thereby
increasing the chances of success for non-optimal tuning images.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-07-05 12:37:39 +02:00
Laurent Pinchart
131039f633 test: utils: Extend utils::hex() test to 8-bit and 16-bit values
Now that the utils::hex() function supports 8-bit and 16-bit integers,
extend the unit test to cover them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-07-04 14:03:59 +03:00
Laurent Pinchart
45bd1f20f6 libcamera: base: utils: Implement hex() for 8-bit and 16-bit values
The utils::hex() function is implemented for 32-bit and 64-bit integers,
but not for 8-bit and 16-bit. This causes a link error (possibly at
runtime for IPA modules due to lazy linking) when trying to print 8-bit
or 16-bit integers. Implement additional specializations to fix it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-07-04 14:03:40 +03:00
Laurent Pinchart
050e0d33d1 ipa: rkisp1: blc: Drop [[maybe_unused]] attribute
The context parameter of the BlackLevelCorrection::init() function is
used. Drop the [[maybe_unused]] attribute.

Fixes: 50c28e1351 ("ipa: rkisp1: blc: Query black levels from camera sensor helper")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-04 13:45:19 +03:00
Dennis Bonke
06e0d8508e libcamera: pipeline: simple: Enable intel-ipu6 with Soft ISP
Enable the simple pipeline handler with software ISP for the IPU6 now
that the IPU6 CSI2 receiver (aka the isys driver) has landed in
media_staging/master.

Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-07-04 13:45:19 +03:00
Stefan Klug
196abb8d1d ipa: rkisp1: Move ov4689 and ov5640 black levels into sensor helpers
Move black levels for tuning files that contained a BLC block into
the camera sensor helpers.

ov4689.yaml had 66@12bit while the datasheet states 64@12bit. Use the
value from the datasheet (scaled to 16bit).

ov5640.yaml had 256@12bit while the datasheet states 16@10bit. Looking
at the commit message the 256 most likely stems from the imx219 tuning
file and 16@10bit is the same as the 64@12bit from the ov4689. This
seems more likely and is therefore used.

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>
2024-07-03 16:41:41 +02:00
Stefan Klug
27e4d3fc3a ipa: rkisp1: data: Update tuning files for imx219 and imx258
The black levels for imx219 and imx258 are now contained in the camera
sensor helpers. Remove them from the tuning file for the imx219. Add a
BLC entry to the imx258 tuning file.

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>
2024-07-03 16:41:41 +02:00
Stefan Klug
afa8cbca9e ipa: rkisp1: blc: Report sensor black levels in metadata
Add sensor black levels to the metadata of the rkisp1 pipeline.

Additionally enable raw support for this algorithm and add it to
uncalibrated.yaml, so that black levels get reported when capturing
tuning images. This is a bit of a hack, because no actual black level
correction is taking place in raw mode, but it is the easiest way to get
blacklevel reported for raw streams.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-07-03 16:41:41 +02:00
Stefan Klug
50c28e1351 ipa: rkisp1: blc: Query black levels from camera sensor helper
As the camera sensor helper now has the ability to provide the black
level, use it. Black levels can still be overwritten by the tuning
file, but the direction is to remove them from the tuning files and move
them into the sensor helpers.

Additionally interpret all values based on 16bits. The conversion to the
scale required by the hardware is done in process(). It ensures all the
values inside libcamera are the same scale and is in preparation for the
i.MX8MP where black levels are based on a 20bit scale. Note that this
breaks existing tuning files. The tuning files distributed with
libcamera will be fixed in a later patch.

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>
2024-07-03 16:41:41 +02:00
Stefan Klug
3df0f0f2b8 ipa: rkisp1: Move camHelper into IPAContext
To be able to query the black levels, the black level correction
algorithm needs access to the camera sensor helper. Allow this by moving
the camHelper_ member from IPARkISP1 into IPAContext.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-03 16:41:41 +02:00
Stefan Klug
808a395d19 ipa: libipa: Add black levels to camera sensor helper
For a proper tuning process we need to know the sensor black levels. In
most cases these are fixed and not reported by the kernel driver. Store
them inside the sensor helpers for later retrieval by the algorithms.

Add black level value corresponding to the data pedestal for three
initial sensors as documented in the datasheets. More should be added,
eventually filling the gaps for all supported sensors.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-07-03 16:41:41 +02:00
Umang Jain
cc3a3c46a5 libcamera: converter: Replace usage of stream index by Stream pointer
The converter interface uses the unsigned int output stream index to map
to the output frame buffers. This is cumbersome to implement new
converters because one has to keep around additional book keeping
to track the streams with their correct indexes.

The v4l2_converter_m2m and simple pipeline handler are adapted to
use the new interface. This work roped in software ISP as well,
which also seems to use indexes (although it doesn't implement converter
interface) because of a common conversionQueue_ queue used for
converter_ and swIsp_.

The logPrefix is no longer able to generate an index from a stream, and
is updated to be more expressive by reporting the stream configuration
instead, for example, reporting "1920x1080-MJPEG" in place of
"stream0".

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Tested-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com> # sm8250 RB5
2024-07-03 10:36:55 +05:30
Umang Jain
7f85673e13 converter: converter_v4l2_m2m: Rename private Stream class
Rename the private Stream class from V4L2M2MConverter::Stream to
V4L2M2MConverter::V4L2M2MStream. This is done to improve readability
of the code when we drop the handling of stream by indexes in a
subsequent patch.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-03 10:36:55 +05:30
Umang Jain
ec2402a1ad libcamera: software_isp: Drop unnecessary sanity check
Currently the soft-isp outputs a single output stream. Hence,
drop the unnecessary check for stream indexes.

Another reason to drop is actually the stream indexes is meant to be
unique in outputs std::map<>, hence checking for unique stream indexes
is redundant.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-03 10:36:55 +05:30
Umang Jain
67b24d2c4e converter: converter_v4l2_m2m: Rectify streams sanity check
The streams sanity check tries to determine if all the stream indexes
passed in outputs std::map<> are unique. However, since the data
container is std::map<>, all its keys (stream indexes in this case),
are already unique.

Instead, rectify the sanity check to ensure all the framebuffers passed
in the outputs std::map<> are unique to each index. Hence, no two stream
indexes should have same framebuffer. Update the comment to reflect
the change.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-07-03 10:36:55 +05:30
Laurent Pinchart
e3310749f5 apps: common: dng_writer: Fix RAW10 and RAW12 packing on BE machines
The 16-bit padded raw 10 and raw 12 formats are stored in memory in
little endian order, regardless of the machine's endianness. Read pixel
data as uint8_t values and hardcode bit shifting to little endian to fix
scanline packing.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-07-01 10:53:06 +03:00
Laurent Pinchart
7735d65ce8 apps: common: dng_writer: Fix thumbnail generation on BE machines
The 16-bit padded raw 10 and raw 12 formats are stored in memory in
little endian order, regardless of the machine's endianness. Swap the
16-bit values on big-endian machines when reading pixels from memory to
generate thumbnails.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-07-01 10:28:48 +03:00
Daniel Scally
7e3a351a29 utils: libtuning: Correct GBRG Image parsing
The Image class incorrectly parses data in GBRG bayer formats as the
indices to the channels are set incorrectly - fix it.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-29 00:55:03 +03:00
Stefan Klug
e9dc398b92 apps: common: dng_writer: Support RAW10 and RAW12 format
Add support for RAW10 and RAW12 to the dng_writer. This is needed on
imx8mp to produce tuning images.  Both formats were tested on a debix
som with a imx335.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-29 00:18:34 +03:00
Stefan Klug
4513db58c0 apps: common: dng_writer: Add thumbnail scanline function for Raw
Add a thumbnail function for raw formats that are 16bit aligned.
This is needed for the upcoming RAW10 and RAW12 implemntation.

Use the new function for RAW16 as the thumbScanlineRaw_CSI2P produces
incorrect results for that format (it averages over adjacent bytes,
which works for the CSI formats).

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-29 00:18:30 +03:00
Stefan Klug
a47ab2711d apps: common: dng_writer: Rename packing functions
The old names lead to confusions. Rename to better express the intent.

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>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-29 00:16:51 +03:00
Daniel Scally
5155150bbf apps: common: dng_writer: Support RAW16 formats
Add support for RAW16 formats to the DNGWriter helpers so that we can
produce dng files from the mali-c55.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-29 00:16:42 +03:00
Stefan Klug
9411578be8 libcamera: Fix maybe-uninitialized error
The gcc used in my current buildroot (Version 12.3) errors out with
-Wmaybe-uninitialized. Fix that.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-06-28 12:53:55 +02:00
Stefan Klug
36a4f67a75 apps: common: dng_writer: Workaround for "Unknown tag 33421" error
In libtiff version 4.5.1 and later the CFA* tags were missing. This got
fixed in 49856998c3
Unfortunately the fix is not released yet, but the faulty libtiff is
contained in current buildroot. As a local fix is pretty easy and
without side effects, let's workaround that.

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>
2024-06-26 15:48:34 +02:00
Laurent Pinchart
fc3efe0723 meson: Enable warnings to flag missing declarations
A recently introduced typo resulted in a function definition not
matching its declaration. As the problem occurred in libipa, and IPA
modules are loaded dynamically and are linked with lazy symbol
resolution, the problem wasn't caught at build time.

To try and catch future similar issues, enable the
-Wmissing-declarations warning.

Suggested-by: Barnabás Pőcze <pobrn@protonmail.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-26 12:07:11 +03:00
Laurent Pinchart
6fc5f90f16 test: gstreamer: Include missing sanitizer/asan_interface.h header
The GStreamer tests define a __asan_default_options() function to
influence the behaviour of ASan. The function is declared in
sanitizer/asan_interface.h, but we don't include the header. This will
cause missing declaration warnings when we enable the
-Wmissing-declarations option.

Include the header to fix the issue. It can't be done unconditionally as
not all toolchains provide ASan, so check for its availability at
configuration time.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-26 12:07:11 +03:00
Laurent Pinchart
7817f9e0cf test: ipc: unixsocket: Define local function in anonymous namespace
A local function in the unixsocket test is defined in the global
namespace without the static keyword. This compiles fine for now, but
will cause a missing declaration warning when we enable them. To prepare
for that, enclose the function declaration in an anonymous namespace.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-26 12:07:11 +03:00
Laurent Pinchart
37d81a390b apps: Define local functions in anonymous namespace
Multiple local functions are defined in the global namespace without the
static keyword. This compiles fine for now, but will cause a missing
declaration warning when we enable them. To prepare for that, move the
function declaration to an anonymous namespace.

While at it, for consistency, include an existing static function in the
namespace and drop the static keyword.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-26 12:07:11 +03:00
Laurent Pinchart
cdb05b3712 v4l2: v4l2_compat: Selectively disable -Wmissing-declarations
_FORTIFY_SOURCE redirects the open*() calls to __open*_2() functions.
The libcamera V4L2 adaptation layer intercepts those functions to
support applications compiled with _FORTIFY_SOURCE. When _FORTIFY_SOURCE
is not enabled, the C library headers will not provide declarations for
the fortified functions, which will cause missing declaration warnings
when we unable them.

Fix this by disabling the -Wmissing-declarations warnings selectively
for the _FORTIFY_SOURCE functions. To avoid sparkling pragmas around,
move the relevant function definitions next to each other.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-26 12:07:11 +03:00
Laurent Pinchart
1907c883ca v4l2: v4l2_compat: Include missing headers
The close() and ioctl() functions are declared in the unistd.h and
sys/ioctl.h headers. Include them to provide the declarations.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-26 12:07:11 +03:00
Laurent Pinchart
a2e27f4f2b py: libcamera: Move function declarations to common header
The init_py_*() functions are called by the top-level entry point of the
libcamera Python module to initialize different parts of the bindings.
They are declared in py_main.cpp where they are called, and defined in
separate compilation units. This results in functions being defined
without a corresponding declaration, and will generate warnings when we
enable -Wmissing-declarations.

Fix this by moving the function declarations from py_main.c to
py_main.h, and including py_main.h in the various compilation units that
need it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-26 12:07:11 +03:00
Laurent Pinchart
885c48028f ipa: rpi: Define local functions in anonymous namespace
Multiple local functions are defined in the global namespace without the
static keyword. This compiles fine for now, but will cause a missing
declaration warning when we enable them. To prepare for that, move the
function declaration to an anonymous namespace.

While at it, for consistency, include an existing static function in the
namespace and drop the static keyword.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2024-06-26 12:07:06 +03:00
Laurent Pinchart
e317eaf072 ipa: ipa_interface: Declare ipaCreate() in libcamera namespace
The ipaCreate() function is the entry point to IPA modules. It is
declared in ipa_interface.h, and defined by each module. As the function
is defined with extern "C" linkage, the namespace in which it is
contained is not very relevant from a caller's point of view. For the
IPA module implementer, however, defining the function in the libcamera
namespace avoids adding an explicit libcamera:: prefix to the symbols
used by the function. This is why all IPA modules define their
ipaCreate() entry point in the libcamera namespace.

The ipa_interface.h file, however, declares the function in the global
namespace. This doesn't cause any issue at runtime, but will cause a
missing declaration warning when we enable them. To prepare for that,
move the function declaration to the libcamera namespace.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-25 10:54:17 +03:00
Laurent Pinchart
38c75f863a libcamera: base: log: Declare log categories when defining them
libcamera will enable -Wmissing-declarations to catch mismatches between
function declarations and definitions. There is one offender in log.h:
when a category is defined with LOG_DEFINE_CATEGORY(), it generates a
function with no declaration. Fix it by declaring the function using
LOG_DECLARE_CATEGORY() as the first step of the category definition.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-25 10:54:16 +03:00
Barnabás Pőcze
4d0834ea0a v4l2: v4l2_compat: Move open*() flag check into function
This commit moves the check that determines whether the mode argument of
`open*()` exists into a separate function.

With that, the check is fixed because previously it failed to account
for the fact that `O_TMPFILE` is not a power of two.

Furthermore, add `assert()`s in the fortified variants that ensure that
no mode is required by the specified flags.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-25 10:22:00 +03:00
Barnabás Pőcze
bab056eb86 v4l2: v4l2_compat: Fix redirect from __open(at)64_2()
To avoid confusion, have `__open64_2()` and `__openat64_2()` delegate to
`open64()` and `openat64()`, respectively, instead of `open()` and
`openat()`.

This does not change the behaviour because
`V4L2CompatManager::instance()->openat()` calls `openat64()` internally,
and that adds the `O_LARGEFILE` flag unconditionally.

Fixes: 1023107b64 ("v4l2: v4l2_compat: Intercept open64, openat64, and mmap64")
Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-25 09:49:23 +03:00
Laurent Pinchart
2119bdac6a ipa: libipa: matrix: Fix incorrect symbol namespace
The matrixVlidateYaml() function is declared in the libcamera::ipa::
namespace, but defined in the libcamera:: namespace. This causes a
dynamic linking error at runtime. Fix it by moving the function
definition.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-24 22:14:22 +03:00
Laurent Pinchart
3d7e50fd71 libcamera: yaml_parser: Add support for float types
The YamlObject::get<T>() function template has a specialization for
double but not for float. When used in an IPA module, the issue is
caught at module load time only, when dynamic links are resolved,
causing errors such as

Failed to open IPA module shared object: /usr/lib/libcamera/ipa_rkisp1.so: undefined symbol: _ZNK9libcamera10YamlObject6GetterIfE3getERK_

Fix it by adding a float specialization. The alternative would be to use
double only in IPA modules, but the lack of enforcement at compile time
makes this dangerous.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-06-24 22:14:22 +03:00
Laurent Pinchart
a8de1f398d ipa: rkisp1: agc: Rename frame context update variable to updateMetering
The frame context agc.update variable is used to indicate if the ISP
histogram metering parameters need to be updated. Rename it to
updateMetering to make usage more explicit.

Suggested-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-24 11:08:47 +03:00
Robert Mader
437e601653 libcamera: debayer_cpu: Add 32bits/aligned output formats
In order to be more compatible with modern hardware and APIs. This
notably allows GL implementations to directly import the buffers more
often and seems to be required for Wayland.

Further more, as we already enforce a 8 byte stride, these formats work
better for clients that don't support padding - such as libwebrtc at the
time of writing.

Tested devices:
 - Librem5
 - PinePhone
 - Thinkpad X13s

Signed-off-by: Robert Mader <robert.mader@collabora.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.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>
2024-06-19 10:58:06 +01:00
Laurent Pinchart
226ce29483 ipa: libipa: pwl: Drop readYaml() function
All users of the Pwl::readYaml() function have been removed. The
function is not used, and is deprecated in favour of YamlObject::get().
Drop it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-18 00:58:12 +03:00
Laurent Pinchart
b781955c6a ipa: rpi: controller: Replace Pwl::readYaml() with YamlObject::get()
Now that deserializing a Pwl object from YAML data is possible using the
YamlObject::get() function, replace all usage of Pwl::readYaml() to
prepare for its removal.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> # On Raspberry Pi 4
2024-06-18 00:57:49 +03:00
Laurent Pinchart
13a8fbeb5c ipa: rkisp1: agc: Move AeEnable control to the AGC algorithm
The AGC algorithm implements the AeEnable control at runtime. Move the
declaration of the control from the IPA module to the algorithm.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-17 16:30:26 +03:00
Laurent Pinchart
4ce519cdc5 ipa: rkisp1: agc: Correctly clamp maximum shutter speed
The sensor's maximum shutter speed is clamped by the maximum frame
duration specified in requests. If the requested maximum frame duration
is lower than the sensor's minimum shutter speed, the Agc::process()
function will pass a minimum value higher than the maximum to the
setLimits() function, resulting in an assertion failure. Fix it by
clamping the value to both the lower and the upper bounds.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-17 16:30:23 +03:00
Laurent Pinchart
14056bceb5 ipa: rkisp1: agc: Rename maxShutterSpeed to maxFrameDuration
The AGC active state and frame context both contain a variable named
maxShutterSpeed. The variable is used to limit the maximum shutter speed
when computing the exposure time and gains, but stores the maximum frame
duration, not clamped by the sensor's maximum shutter speed. Rename it
to maxFrameDuration.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-17 16:15:24 +03:00
Laurent Pinchart
b53c6de03f ipa: rkisp1: agc: Use mode from frame context to calculate new EV
The effective exposure value for each frame is split into shutter time,
analog gain and digital gain based on the AGC constraint mode and
exposure mode. The algorithm uses the modes from the active state, which
tracks the latest queued request, instead of the frame context, which
tracks the value of the controls requested for that frame. Fix it by
using the correct modes.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-17 16:15:23 +03:00
Laurent Pinchart
ea43e056a8 ipa: rkisp1: agc: Simplify predivider calculation
The condition

	if (std::pow(std::floor(root), 2) < factor)
		predivider = static_cast<uint8_t>(std::ceil(root));
	else
		predivider = static_cast<uint8_t>(std::floor(root));

can only be false when the factor's root is an integer. In that case,
std::ceil(root) and std::floor(root) will be equal. The computation can
thus be simplified by always rounding up.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-17 16:15:10 +03:00
Laurent Pinchart
05d0f952a3 ipa: rkisp1: agc: Don't update histogram parameters unnecessarily
The ISP histogram parameters depends on the AE metering mode, but not on
the other AE algorithm controls. The exposure mode, constraints mode and
frame duration limits influence the behaviour of the algorithm, but not
the histogram computation parameters. Update the histogram parameters
only when AE metering mode changes.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-17 16:15:10 +03:00
Laurent Pinchart
de4ed4e966 ipa: rkisp1: agc: Make size argument to computeHistogramPredivider const
The Agc::computeHistogramPredivider() function doesn't need to modify
its size parameter. Make it const.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-17 16:15:10 +03:00
Laurent Pinchart
9f04e8e1ff ipa: rkisp1: Document all AGC parameters in IPAFrameContext
The IPAFrameContext AGC documentation is lagging behind the
implementation and misses many variables. Document them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-17 16:15:08 +03:00
Laurent Pinchart
c414ff9ec2 ipa: rkisp1: Document all AGC parameters in IPAActiveState
The IPAActiveState AGC documentation is lagging behind the
implementation and misses many variables. Document them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-17 16:15:05 +03:00
Laurent Pinchart
8b82a7f1e7 ipa: libipa: agc_mean_luminance: Include missing header
agc_mean_luminance.h uses utils::Duration, include the corresponding
header.

Signed-off-by: Laurent Pinchart <laurent.pinchart@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>
2024-06-17 15:04:34 +03:00
Laurent Pinchart
3faa04fe48 ipa: libipa: agc_mean_luminance: Fix enumerator names
Enumerators in libcamera start with an upper case letter. Fix the
AgcConstraint::Bound enumerators.

Signed-off-by: Laurent Pinchart <laurent.pinchart@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>
2024-06-17 15:04:02 +03:00
Laurent Pinchart
8fd673deaf ipa: rkisp1: agc: Fix initialization without metering modes
When no metering modes are specified in the tuning file, the AGC
initialzation fails with

[0:00:46.148508875] [209] ERROR RkISP1Agc agc.cpp:46 'AeMeteringMode' parameter not found in tuning file

which results in a camera initialization failure. Fix it by downgrading
the error into a warning, and continuing the AGC initialization with the
default metering mode.

Fixes: 35233938ee ("ipa: rkisp1: agc: Read histogram weights from tuning file")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-17 15:03:45 +03:00
Paul Elder
01a33fedf6 ipa: libipa: vector: Add matrix-vector multiplication
Add an operation for multiplying a matrix with a vector.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-17 12:19:01 +03:00
Paul Elder
cbfdfa42ca ipa: rkisp1: algorithms: Add crosstalk algorithm
Add an algorithm module to the rkisp1 IPA for crosstalk correction.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-17 12:18:57 +03:00
Paul Elder
f1959b9f31 ipa: libipa: Add MatrixInterpolator class
Add a class to encapsulate the functionality of fetching a matrix based
on an integer key, and interpolating if there is no exact match. This is
expected to be used by both color correction matrices / crosstalk
correction as well as lens shading correction.

A cache is included only for exact matches of the key. The caller is
expected to decide the tolererance for rounding.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-17 12:18:51 +03:00
Paul Elder
f191c10fe1 ipa: libipa: Add Matrix class
Add a class to represent a Matrix object and operations for adding
matrices, multipling a matrix by a scalar, and multiplying two matrices.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-17 12:18:41 +03:00
Laurent Pinchart
d978832d9e ipa: libipa: pwl: Specialize YamlObject getter
Implement a specialization of the YamlObject::Getter structure to
support deserializing ipa::Pwl objects from YAML data.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-16 03:28:26 +03:00
Laurent Pinchart
31c9998bf0 ipa: libipa: pwl: Add a constructor that moves a Point vector
The Pwl::Pwl(const std::vector<Point> &) constructor is inefficient as
it makes a copy of the given points vector. Add a second constructor
that takes an rvalue reference to a points vector to provide move
semantics.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-16 03:28:25 +03:00
Laurent Pinchart
0706c67711 ipa: libipa: pwl: Add a size() function
Add a size() function to the Pwl class to return the number of points in
the piecewise linear function. This is useful, for instance, to validate
that all points added with append() or prepend() have been taken into
account.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-16 03:28:25 +03:00
Laurent Pinchart
e127e63c93 ipa: libipa: pwl: Make the empty() function inline
The Pwl::empty() function is a one-liner that can be easily optimized by
the compiler given the chance. Make it inline.

While at it, move the function documentation block to match the class
declaration order.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-16 03:28:25 +03:00
Laurent Pinchart
6c735ab8e2 ipa: libipa: pwl: Suffix \param with direction
Suffix the Doxygen \param commands with the direction for all
parameters.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-16 03:28:25 +03:00
Laurent Pinchart
454bc6129f ipa: libipa: vector: Drop readYaml() function
Now that YAML deserialization of Vector instances is supported through
YamlObject::get(), remove the Vector::readYaml() function. It turns out
not to be used.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-16 03:28:25 +03:00
Laurent Pinchart
64ed07d4d0 ipa: libipa: vector: Specialize YamlObject getter
Implement a specialization of the YamlObject::Getter structure to
support deserializing ipa::Vector objects from YAML data.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-16 03:28:25 +03:00
Laurent Pinchart
922686067a libcamera: yaml_parser: Delegate YamlObject::get() to helper structure
The YamlObject::get() function is a function template that gets fully
specialized for various types. This works fine for non-template types,
but specializing it for template types (e.g. a std::vector<U>) would
require partial template specialization, which C++ allows for classes
and variables but not functions.

To work around this problem, delegate the implementation to a new
YamlObject::Getter structure template, which will support partial
specialization.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-16 03:28:25 +03:00
Laurent Pinchart
8d6f494844 libcamera: yaml_parser: Drop std::enable_if_t guards for get() function
The YamlObject::get() function template is implemented for a set of
basic types through template specializations. The function declaration
uses std::enable_if_t<> guards to signal incorrect usage at compilation
time. This however prevents the API to be extended with additional
specializations in other compilation units.

To prepare for new specializations of the function for the ipa::Vector
and ipa::Pwl classes types, implemented in their respective compilation
units, drop the std::enable_it_t<> guards. Incorrect usage will still be
reported as link errors.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-16 03:28:25 +03:00
Paul Elder
7d8a9e054e utils: tuning: rkisp1: Add skeletal AGC to the rkisp1 tuning script
Add the skeletal AGC module to the rkisp1 tuning script. For now it just
spits out hardcoded values.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-06-14 23:48:48 +09:00
Paul Elder
4eb3ff2350 utils: libtuning: modules: Add skeletal AGC module
Add a skeletal AGC module just so that we can have some AGC tuning
values that we can use to test during development of AGC in the IPAs. As
rkisp1 is the main target, we only add support for rkisp1 for now.

The parameters are mostly copied from the hardcoded values in ctt,
except for the metering modes.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-14 23:48:45 +09:00
Paul Elder
248374feca ipa: rkisp1: agc: Plumb mode-selection and frame duration controls
Plumb controls for setting metering mode, exposure mode, constraint
mode, and frame duration limits. Also report them as available controls,
as well as in metadata.

While at it, add the missing #include for tuple, as a std::tie is used.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-14 22:16:01 +09:00
Paul Elder
35233938ee ipa: rkisp1: agc: Read histogram weights from tuning file
Add support to the rkisp1 AGC to read histogram weights from the tuning
file. As controls for selecting the metering mode are not yet supported,
for now hardcode the matrix metering mode, which is the same as what the
AGC previously hardcoded.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-06-14 22:15:59 +09:00
Stefan Klug
1b91725618 ipa: rkisp1: cproc: Drop incorrect [[maybe_unused]]
A few function parameters are marked with [[maybe_unused]] but are
actually used. Drop the attribute.

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>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-13 14:02:02 +03:00
Stefan Klug
c2fad17ad0 ipa: rkisp1: cproc: Merge identical functions
convertContrast() and convertSaturation() are equal. Merge them into
one.

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>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-13 14:01:54 +03:00
Stefan Klug
9b84d75cb1 ipa: rkisp1: cproc: Use anonymous namespace to limit symbol visibility
Use a anonymous namespace instead of the static keyword to limity symbol
visibility.

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>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-13 14:01:37 +03:00
David Plowman
6960684fa1 utils: raspberrypi: ctt: Add a maximum gain parameter for LSC
A max_gain parameter is added to the config file which we pass to the
lens shading calibration. This clamps the maximum luminance gain that
gets written into the tuning files so as to prevent overflows.

It is particularly useful for lenses that cut off the light completely
from the sensor corners, and allows usable tables to be generated for
them.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Tested-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-13 11:02:39 +01:00
Naushir Patuck
b40d9dbc0b utils: raspberrypi: ctt: Add option to convert between vc4/pisp targets
This change adds functionality to the convert_tuning.py script to
convert between vc4 and pisp target tuning files. The conversion is
done on a best effort basis, and should provide functional tuning files.
However, a full tuning for the target platform is always preferred.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Tested-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-13 11:02:39 +01:00
David Plowman
e7d628942f utils: raspberrypi: ctt: Update tuning tool for HDR
The various boilerplate parts of the tuning file are extended to
include the necessary extra bits for HDR, specifically:

* rpi.denoise has different configurations for HDR modes
* rpi.agc now has extra channels for HDR
* rpi.hdr parameters are added.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Tested-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-13 11:02:38 +01:00
Ben Benson
b95032a842 utils: raspberrypi: ctt: Changed CTT handling of VC4 and PiSP
Changed how users select which platform to tune for. Now users
specify a command line argument, '-t', to specify which target
platform.

Signed-off-by: Ben Benson <ben.benson@raspberrypi.com>
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Tested-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-13 11:02:26 +01:00
Ben Benson
8bea2d5a8a utils: raspberrypi: ctt: Added CAC support to the CTT
Added the ability to tune the chromatic aberration correction
within the ctt. There are options for cac_only or to tune as part
of a larger tuning process. CTT will now recognise any files that
begin with "cac" as being chromatic aberration tuning files.

Signed-off-by: Ben Benson <ben.benson@raspberrypi.com>
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Tested-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-13 11:02:16 +01:00
David Plowman
d13542c28f utils: raspberrypi: ctt: Adapt tuning tool for both VC4 and PiSP
The old ctt.py and alsc_only.py scripts are removed.

Instead of ctt.py use ctt_vc4.py or ctt_pisp.py, depending on your
target platform.

Instead of alsc_only.py use alsc_vc4.py or alsc_pisp.py, again
according to your platform.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Tested-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-13 10:13:33 +01:00
Naushir Patuck
634bc7838f pipeline: rpi: Don't validate configuration in generateConfiguration()
generateConfiguration() called validate() as a final step, causing the
stride and frameSize fields in StreamConfiguration to be filled in based
on the pixel format and width/height.

If a user application did not clear the stride field when setting up a
custom pixel format and width/height, the pipeline handler would respect
this stride and possibly overallocate buffers with a larger stride than
needed.

Fix this by removing the call to validate() completely, leaving the
stride and frameSize fields defaulting to 0. Removal of this call is
inconsequential as we hard-code a valid configuration for Raspberry Pi
platforms in generateConfiguration().

Bug: https://github.com/raspberrypi/libcamera/issues/138
Bug: https://github.com/raspberrypi/libcamera/issues/141
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-13 09:32:59 +01:00
Barnabás Pőcze
20b8538a19 libcamera: yaml_parser: Make default value templated in get()
This way the construction of the default value of type `T`
can be delayed until it is really needed, which is useful,
for example when `T == std::string` and the default value comes
from a string literal, as the default value string would always
be constructed otherwise, even if not needed.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-13 02:13:36 +03:00
Laurent Pinchart
d9c6835e23 libcamera: libipa: camera_sensor: Define AR0521 helper functions inline
All CameraSensorHelper subclasses define their member functions inline,
except for the CameraSensorHelperAr0521 class. Inline the gainCode() and
gain() functions to match the other classes.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-13 00:18:22 +03:00
Laurent Pinchart
e76bb1f54c libcamera: controls: Add missing period at end of Gamma description
The last sentence of the Gamma control description misses the final
period. Add it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-12 12:00:36 +03:00
Laurent Pinchart
5c08b179e4 ipa: rkisp1: goc: Avoid use of auto for short type
Replace one occurrence of the auto type qualifier with the explicit type
it represents to increase readability.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-12 12:00:35 +03:00
Laurent Pinchart
1ca1d06d67 ipa: rkisp1: goc: Mark default gamma table as static constexpr
The values for the default gamma table are stored in an array that is
never modified. Mark it as static constexpr to facilitate optimizations.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-12 12:00:33 +03:00
Laurent Pinchart
1566e67f76 ipa: rkisp1: goc: Use copydoc
Use the Doygen \copydoc command instead of duplicating documentation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-12 12:00:31 +03:00
Laurent Pinchart
2a253be333 ipa: rkisp1: goc: Drop incorrect [[maybe_unused]]
A few function parameters are marked with [[maybe_unused]] but are
actually used. Drop the attribute.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-12 12:00:28 +03:00
Laurent Pinchart
6dba3f4612 ipa: rkisp1: goc: Fix typographical issues in documentation.
Fix a few assorted typographical issues:

- Sentences should end with a period.
- Paragraphs should be separated by a blank line, and there should be no
  line break within a paragraph.
- Doxygen lists need a list marker ('-' or '*', use '-' here).

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-12 12:00:25 +03:00
Paul Elder
9fcc0029ec ipa: rpi: controller: Use libipa's Pwl class
To reduce code duplication, use the Pwl class from libipa. This also
removes the Pwl class from the Raspberry Pi IPA.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Acked-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-12 16:53:00 +09:00
Paul Elder
95fa5c40ba ipa: libipa: Copy pwl from rpi, and clean it up to match libcamera
Copy the piecewise linear function code from Raspberry Pi,
and clean it up to align it more with the libcamera style.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Acked-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-12 16:52:18 +09:00
Paul Elder
93438d1aad ipa: libipa: Add Vector class
Add a vector class to libipa. The original purpose of this is to replace
the floating-point Point class that Raspberry Pi used in their Pwl, as
that implementation of Point seemed more akin to a Vector than a Point.

This is added to libipa instead of to geometry.h to avoid public API
issues, plus this is not expected to be needed by applications.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-12 16:52:14 +09:00
Stefan Klug
d2a5508d0a pipeline: rkisp1: cproc: Fix default value handling
Default control values were not applied to activeState. This had no negative
side effects in the first place, as the hardware defaults were used. The issue
became visible, when only one of the controls was set at runtime. In that case
the params for the other values were overwritten with 0 (reset value of
activeState) resulting in a black image.

While at it, only add the controls to the controls map if the algorithm is
contained in the tuning file.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-11 15:42:18 +02:00
Laurent Pinchart
f305cacc9c meson: Group libipa and libipa_includes in a dependency object
Many build targets link with libipa and need libipa_includes. Group them
in a libipa_dep dependency object to simplify the users.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-11 16:39:22 +03:00
Milan Zamazal
fceaa7f3e2 libcamera: software_isp: Fix includes ordering in simple.cpp
Let's make it conforming to the defined clang-format.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-11 16:27:07 +03:00
Milan Zamazal
fa52898efe clang-format: Make Qt includes matching case sensitive
Now that stable versions of all major distributions ship clang-format 12
or newer, we can use the CaseSensitive option for the Qt include
category. This fixes the problem that includes like

  #include <queue>

are put near the end.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-11 16:26:54 +03:00
Stefan Klug
eb41f63694 ipa: rkisp1: Add GammaOutCorrection algorithm
Add a gamma algorithm for the rkisp1. It defaults to a gamma of 2.2 which
closely resembles sRGB.  No seperate sRGB mode was implemented because the pwl
that models the gamma curve is so coarse that there is basically no difference
between srgb and gamma=2.2. The default can be overridden within the tuning
file or set at runtime using the gamma control.

The gamma algorithm is not enabled by default. This will be done in future
tuning file updates.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-11 15:11:11 +02:00
Stefan Klug
acfd602767 ipa: rkisp1: Fix algorithm controls vanish after configure
std::unordered_map::merge(source) has the side effect of actually moving items
from source to target. In this case the controls were removed from the source
maps on the first call to updateControls() and on the second call to
updateControls() they were missing in the source maps and therefore also
removed from the camera. Fix this by using insert() instead of merge(). This is
most likely cheaper than copy-contructing the source map.

Fixes: 4c5152843a ("ipa: rkisp1: Derive rkisp1::algorithms::Agc from AgcMeanLuminance")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-11 15:11:11 +02:00
Stefan Klug
294ead848c libcamera: Add gamma control id
A camera gamma of roughly 2.2 is necessary to produce correct output
images on a standard monitor. Add a control for that.

Further information is available here:
https://en.wikipedia.org/wiki/SRGB
https://www.cambridgeincolour.com/tutorials/gamma-correction.htm

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-06-11 15:11:11 +02:00
Paul Elder
f3caea0ff7 test: ipa: rkisp1: utils: Fix floating and fixed point conversion test
There was an issue where using map to store the test cases meant that
the test for ignoring unused bits was skipped because of clashing keys.
Fix this by moving the offending test out of the loop.

While at it, also change the arbitrary floating comparison precision to
be more precise.

Also fix a missing documentation brief.

Fixes: 9d152e9c66 ("ipa: rkisp1: Add a helper to convert floating-point to fixed-point")
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-10 22:05:52 +09:00
Laurent Pinchart
48cb731d72 libcamera: dma_buf_allocator: Work around lack of file seals in uClibc
uClibc doesn't provide the macros defining parameters for the file
sealing API. Define them manually as a work around.

Fixes: ea4baaacc3 ("libcamera: DmaBufAllocator: Support allocating from /dev/udmabuf")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2024-06-05 15:11:45 +03:00
Laurent Pinchart
9f0d88695e libcamera: dma_buf_allocator: Work around lack of memfd_create() in uClibc
uClibc doesn't provide a memfd_create() implementation. Fix it by using
a direct syscall when the function isn't available.

Fixes: ea4baaacc3 ("libcamera: DmaBufAllocator: Support allocating from /dev/udmabuf")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2024-06-05 15:11:21 +03:00
Laurent Pinchart
9c2ca46391 libcamera: dma_buf_allocator: Create memfd with CLOEXEC
Ensure that the memfd file descriptor won't be leaked to child processes
by creating it with MFD_CLOEXEC.

Fixes: ea4baaacc3 ("libcamera: DmaBufAllocator: Support allocating from /dev/udmabuf")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-05 12:23:52 +03:00
Naushir Patuck
98071d3109 ipa: rpi: Disable StatsOutputEnable control by default
Set the default value of controls::rpi::StatsOutputEnable to false,
disabling the functionality. This stops unnecessary copies of the
statistics output ending up in the Request metdata if not needed.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-04 17:01:11 +01:00
Hans de Goede
d284ac2d59 libcamera: software_isp: Allow using dma-buffers from /dev/udmabuf
Allow the DmaBufAllocator used by the software ISP to use memfd() +
/dev/udmabuf for the software ISP destination buffers.

This is useful on Linux distributions where normal users are not allowed
to access /dev/dma_heap/* while they are allowed to access /dev/udmabuf.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # Lenovo-x13s
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-04 16:19:33 +01:00
Hans de Goede
ea4baaacc3 libcamera: DmaBufAllocator: Support allocating from /dev/udmabuf
The dma-buf allocator currently allocates from CMA and system heaps.

Extend the dma-buf allocator to support allocating dma-buffers by creating
memfd-s and turning those into dma-buffers using /dev/udmabuf.

The buffers allocated through memfd/udmabuf are not suitable for zero-copy
buffer sharing with other devices.

Co-developed-by: Harvey Yang <chenghaoyang@chromium.org>
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # Lenovo-x13s
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-04 16:19:33 +01:00
Hans de Goede
447da4a11f libcamera: Rename DmaHeap class to DmaBufAllocator
Users of the DmaHeap class really just want some way to allocate
dma-buffers from userspace. This can also be done by using /dev/udmabuf
instead of using /dev/dma_heap/*.

Rename DmaHeap class to DmaBufAllocator in preparation of adding
/dev/udmabuf support.

And update the DmaHeap class docs to match including replacing references
to "dma-heap type" with "dma-buf provider".

This is a pure automated rename on the code ('s/DmaHeap/DmaBufAllocator/')
+ file renames + doc updates. There are no functional changes.

The DmaBufAllocator objects in vc4.cpp and software_isp.cpp are left named
dmaHeap_ to keep the changes to those 2 files to a minimum.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # Lenovo-x13s
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-04 16:19:33 +01:00
Laurent Pinchart
6cd17515ff libcamera: v4l2_subdevice: Update to the new kernel routing API
The subdev embedded data support series includes a change to the
VIDIOC_SUBDEV_G_ROUTING and VIDIOC_SUBDEV_S_ROUTING ioctls that impacts
the userspace API.

Update to the new API, while preserving backward compatibility to ease
the transition. Document the backward compatibility to only be supported
for two kernel releases. As the routing API isn't enabled in any
upstream kernel yet, users of the API need kernel patches, and are
expected to be able to upgrade quickly.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-03 12:18:25 +03:00
Hans de Goede
70d553812e include: linux: Update kernel headers to version v6.10-rc1
Updated kernel headers to v6.10-rc1 using utils/update-kernel-headers.sh
and re-instating libcamera local modifications.

This includes adding include/linux/udmabuf.h which was not part
of libcamera's include/linux headers before.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-03 12:14:33 +03:00
Hans de Goede
f6aa63acad update-kernel-headers: Add linux/udmabuf.h to headers to sync
linux/udmabuf.h will be used by upcoming DmaBufAllocator changes and it
is not available on some older kernels.

Add it to the headers to sync.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-03 12:14:33 +03:00
Laurent Pinchart
1020b6be51 test: ipa: rkisp1-utils: Fix coding style for template arguments
The coding style names template arguments using CamelCase with an
uppercase initial letter. Fix the template arguments in the rkisp1-utils
test.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-03 11:59:45 +03:00
Laurent Pinchart
f7d7a5e294 pipeline: vimc: Don't hardcode scaling factor with recent kernels
Starting in kernel v5.16, the vimc driver stopped hardcoding the scaler
factor. Use this to lift constraints on the camera configuration, and in
particular on the exotic output size alignment to a multiple of 6. As a
result, vimc-based cameras can more easily match common display
resolutions.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-06-03 11:53:12 +03:00
Laurent Pinchart
73f18f32c9 test: v4l2_videodevice: Increase timeout for vimc capture tests
On slower machines, a 10s timeout to capture frames with vimc can be too
short and cause test failures. Make the timeout proportional to the
number of frames expected to be captured, using a conservative low
estimate of the frame rate at 2fps. This does not increase the test time
if the vimc driver is fast enough to produce frames.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-06-03 11:53:10 +03:00
Laurent Pinchart
dedf9cf264 test: fence: Increase timeout for fence test
On slower machines, a 1s timeout to capture frames with vimc can be too
short and cause test failures. Make the timeout proportional to the
number of frames expected to be captured, using a conservative low
estimate of the frame rate at 2fps.

By itself, that change could increase the test time quite substantially
on fast platforms, so break from the capture loop as soon as we capture
enough frames.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-03 11:53:07 +03:00
Laurent Pinchart
13dcc7fc5f test: fence: Fix race condition
The fence test is racy, as it relies on the main loop being executed
between completion of request signalledRequestId_ and
signalledRequestId_ + 1. This usually happens, but is not guaranteed.

To fix the race condition, change the request identification logic by
replacing usage of the cookie value, which is zero-based and wraps
around at nbuffers_ - 1, with a completed request counter that is
one-based and doesn't wrap. The completedRequestId_, expiredRequestId_
and signalledRequestId_ variables now track the identifier of the last
request that has completed, the request whose fence will time out, and
the request whose fence will be signalled.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-03 11:53:04 +03:00
Laurent Pinchart
c44457957e test: fence: Turn class member variable into local variable
The fence_ class member variable is only used locally in the
FenceTest::run() function. Make it a local variable.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-06-03 11:53:02 +03:00
Laurent Pinchart
0554a55427 test: camera: Increase timeout for vimc capture tests
On slower machines, a 1s timeout to capture frames with vimc can be too
short and cause test failures. Make the timeout proportional to the
number of frames expected to be captured, using a conservative low
estimate of the frame rate at 2fps.

By itself, that change could increase the test time quite substantially
on fast platforms, so break from the capture loop as soon as we capture
enough frames. To do so, interrupt the dispatcher at every request
completion, or it will only get interrupted after the timer times out.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-06-03 11:53:01 +03:00
Milan Zamazal
a52d818e2b libcamera: software_isp: Remove TODO about internal representation
TODO #4 was recorded at a time where the IPA module computed gain values
and the ISP computed the look up tables.  The gains were higher-level
parameters.  Now that the look up tables are computed in the IPA module,
the IPA and ISP are more tightly coupled and the TODO item is less
relevant.

Let's drop the TODO item.  We may or may not need to switch to a
different representation in future but there is currently no good need
for this and the conversion of the values would be just waste of CPU
cycles.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-02 02:00:08 +03:00
Milan Zamazal
f5b7921e0a libcamera: software_isp: Remove DebayerParams::kGain10
The constant is used in a single place internally and doesn't belong to
DebayerParams anymore.  Let's use 256 directly.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-02 01:59:24 +03:00
Milan Zamazal
539c62ff8e libcamera: software_isp: Move color mappings out of debayering
Constructing the color mapping tables is related to stats rather than
debayering, where they are applied.  Let's move the corresponding code
to stats processing.

The same applies to the auxiliary gamma table.  As the gamma value is
currently fixed and used in a single place, with the temporary exception
mentioned below, there is no need to share it anywhere anymore.

It's necessary to initialize SoftwareIsp::debayerParams_ to default
values.  These initial values are used for the first two frames, before
they are changed based on determined stats.  To avoid sharing the gamma
value constant in artificial ways, we use 0.5 directly in the
initialization.  This all is not a particularly elegant thing to do,
such a code belongs conceptually to the similar code in stats
processing, but doing better is left for larger refactoring.

This is a preliminary step towards building this functionality on top of
libipa/algorithm.h, which should follow.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-02 01:54:20 +03:00
Milan Zamazal
4e13c6f55b libcamera: software_isp: Honor black level in AWB
The white balance computation didn't consider black level.  This is
wrong because then the computed ratios are off when they are computed
from the whole brightness range rather than the sensor range.

This patch adjusts white balance computation for the black level.  There
is no need to change white balance application in debayering as this is
already applied after black level correction.

Exposure computation already subtracts black level, no changes are
needed there.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-02 01:47:40 +03:00
Milan Zamazal
738bd37905 libcamera: software_isp: Use a specific integer type for black level
The documented range of values corresponds to uint8_t, so let's use that
type.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-02 01:47:24 +03:00
Laurent Pinchart
aad5837d70 utils: checkstyle.py: Show location of coding style issue within line
The issue checkers display the line number and line content of each
offending line, but don't show the location of the issue within a line.
Improve checkstyle by adding a marker that points to the exact location.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-31 20:07:12 +03:00
Laurent Pinchart
4a7c9ce467 utils: checkstyle.py: Add a check for hex values
libcamera uses lowercase hex values. Add a corresponding checker.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Milan Zamazal <mzamazal@redhat.com>
2024-05-31 20:05:25 +03:00
Laurent Pinchart
5d2c8fa11b utils: checkstyle.py: Extend IncludeChecker to cover math.h
math.h is an exception to the C compatibility header rule, as we prefer
using cmath. Extend the IncludeCheck to warn about it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-31 20:05:10 +03:00
Laurent Pinchart
b8b24c5b5e utils: checkstyle.py: Refactor IncludeChecker
The IncludeCheck warns when code uses C++ standard library headers where
corresponding C compatibility headers are preferred. We have an
exception to that rule for math.h, where cmath is prefered. In order to
prepare for extending checkstyle.py to enforce that rule, refactor the
way the IncludeChecker identifies headers. No functional change is
intended.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-31 20:04:53 +03:00
Paul Elder
9b29eba7a2 test: ipa: rkisp1-utils: Fix capitalization of hex numbers
Fix capitalization of the hexdecimal numbers in the test for conversion
between floating point and fixed point numbers.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-05-31 23:29:41 +09:00
Paul Elder
9d152e9c66 ipa: rkisp1: Add a helper to convert floating-point to fixed-point
Add helper functions for converting between floating point and fixed
point numbers. Also add tests for them.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-31 17:12:48 +09:00
Barnabás Pőcze
c79fa47aac android: camera_capabilities: Fix GCC 14 warning
GCC 14 thinks `rects` is a "possibly dangling reference to a temporary":

/libcamera/src/android/camera_capabilities.cpp: In member function ‘int CameraCapabilities::initializeStaticMetadata()’:
/libcamera/src/android/camera_capabilities.cpp:1084:46: error: possibly dangling reference to a temporary [-Werror=dangling-reference]
 1084 |                 const Span<const Rectangle>& rects =
      |                                              ^~~~~
/libcamera/src/android/camera_capabilities.cpp:1085:83: note: the temporary was destroyed at the end of the full expression ‘(& properties)->libcamera::ControlList::get<libcamera::Span<const libcamera::Rectangle> >(libcamera::properties::PixelArrayActiveAreas).std::optional<libcamera::Span<const libcamera::Rectangle> >::value_or<libcamera::Span<const libcamera::Rectangle> >(libcamera::Span<const libcamera::Rectangle>())’
 1085 |                         properties.get(properties::PixelArrayActiveAreas).value_or(Span<const Rectangle>{});
      |                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~

The return value of `value_or()` is indeed a temporary, but binding it
to a reference extends its lifetime. Avoid the warning by not using a
reference; this does not make much difference since `value_or()` does
not return a reference.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-05-27 23:53:59 +03:00
Laurent Pinchart
807119d1e0 ipa: rpi: Make monoSensor() accessor const
The ipa::RPi::IpaBase::monoSensor() function doesn't modify the class.
Make it const.

Fixes: 2031e2f290 ("ipa: rpi: Add accessor function for monoSensor_")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-05-27 14:34:38 +03:00
Barnabás Pőcze
168bb3c97c libcamera: yaml_parser: Avoid double lookup in operator[]
`YamlObject::contains()` does the same search, doing the lookup twice is
unnecessary.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-21 13:23:12 +01:00
Barnabás Pőcze
e77a275110 treewide: Query list of cameras just once
This is more efficient since only a single vector will be constructed,
and furthermore, it prevents the TOCTOU issue that might arise when
the list of cameras changes between the two queries.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-21 13:22:33 +01:00
729 changed files with 65072 additions and 8995 deletions

View file

@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# clang-format configuration file. Intended for clang-format >= 7.
# clang-format configuration file. Intended for clang-format >= 12.
#
# For more information, see:
#
@ -75,11 +75,12 @@ IncludeCategories:
Priority: 9
# Qt includes (match before C++ standard library)
- Regex: '<Q([A-Za-z0-9\-_])+>'
CaseSensitive: true
Priority: 9
# Headers in <> with an extension. (+system libraries)
- Regex: '<([A-Za-z0-9\-_])+\.h>'
Priority: 2
# System headers
# System headers
- Regex: '<sys/.*>'
Priority: 2
# C++ standard library includes (no extension)
@ -99,7 +100,7 @@ IncludeCategories:
# IPA Interfaces
- Regex: '<libcamera/ipa/.*\.h>'
Priority: 7
# libcamera Internal headers in ""
# libcamera Internal headers in ""
- Regex: '"libcamera/internal/.*\.h"'
Priority: 8
# Other libraries headers with one group per library (.h or .hpp)

29
.editorconfig Normal file
View file

@ -0,0 +1,29 @@
# SPDX-License-Identifier: CC0-1.0
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.{cpp,h}]
indent_size = 8
indent_style = tab
[*.json]
indent_size = 4
indent_style = space
[*.py]
indent_size = 4
indent_style = space
[*.yaml]
indent_size = 2
indent_style = space
[{meson.build,meson_options.txt}]
indent_size = 4
indent_style = space

1
.gitignore vendored
View file

@ -6,3 +6,4 @@
*.patch
*.pyc
__pycache__/
venv/

View file

@ -22,35 +22,17 @@ CASE_SENSE_NAMES = YES
QUIET = YES
WARN_AS_ERROR = @WARN_AS_ERROR@
INPUT = "@TOP_SRCDIR@/include/libcamera" \
"@TOP_SRCDIR@/src/ipa/ipu3" \
"@TOP_SRCDIR@/src/ipa/libipa" \
"@TOP_SRCDIR@/src/libcamera" \
"@TOP_BUILDDIR@/include/libcamera" \
"@TOP_BUILDDIR@/src/libcamera"
FILE_PATTERNS = *.c \
*.cpp \
*.dox \
*.h
RECURSIVE = YES
EXCLUDE = @TOP_SRCDIR@/include/libcamera/base/span.h \
@TOP_SRCDIR@/include/libcamera/internal/device_enumerator_sysfs.h \
@TOP_SRCDIR@/include/libcamera/internal/device_enumerator_udev.h \
@TOP_SRCDIR@/include/libcamera/internal/ipc_pipe_unixsocket.h \
@TOP_SRCDIR@/src/libcamera/device_enumerator_sysfs.cpp \
@TOP_SRCDIR@/src/libcamera/device_enumerator_udev.cpp \
@TOP_SRCDIR@/src/libcamera/ipc_pipe_unixsocket.cpp \
@TOP_SRCDIR@/src/libcamera/pipeline/ \
@TOP_SRCDIR@/src/libcamera/tracepoints.cpp \
@TOP_BUILDDIR@/include/libcamera/internal/tracepoints.h \
@TOP_BUILDDIR@/include/libcamera/ipa/soft_ipa_interface.h \
@TOP_BUILDDIR@/src/libcamera/proxy/
EXCLUDE_PATTERNS = @TOP_BUILDDIR@/include/libcamera/ipa/*_serializer.h \
@TOP_BUILDDIR@/include/libcamera/ipa/*_proxy.h \
@TOP_BUILDDIR@/include/libcamera/ipa/ipu3_*.h \
@TOP_BUILDDIR@/include/libcamera/ipa/mali-c55_*.h \
@TOP_BUILDDIR@/include/libcamera/ipa/raspberrypi_*.h \
@TOP_BUILDDIR@/include/libcamera/ipa/rkisp1_*.h \
@TOP_BUILDDIR@/include/libcamera/ipa/vimc_*.h
@ -70,14 +52,13 @@ EXCLUDE_SYMBOLS = libcamera::BoundMethodArgs \
EXCLUDE_SYMLINKS = YES
HTML_OUTPUT = api-html
GENERATE_LATEX = NO
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
INCLUDE_PATH = "@TOP_SRCDIR@/include/libcamera"
INCLUDE_PATH = "@TOP_BUILDDIR@/include" \
"@TOP_SRCDIR@/include"
INCLUDE_FILE_PATTERNS = *.h
IMAGE_PATH = "@TOP_SRCDIR@/Documentation/images"

View file

@ -0,0 +1,33 @@
# SPDX-License-Identifier: CC-BY-SA-4.0
@INCLUDE_PATH = @TOP_BUILDDIR@/Documentation
@INCLUDE = Doxyfile-common
HIDE_UNDOC_CLASSES = NO
HIDE_UNDOC_MEMBERS = NO
HTML_OUTPUT = internal-api-html
INTERNAL_DOCS = YES
ENABLED_SECTIONS = internal
INPUT = "@TOP_SRCDIR@/Documentation" \
"@TOP_SRCDIR@/include/libcamera" \
"@TOP_SRCDIR@/src/ipa/ipu3" \
"@TOP_SRCDIR@/src/ipa/libipa" \
"@TOP_SRCDIR@/src/libcamera" \
"@TOP_BUILDDIR@/include/libcamera" \
"@TOP_BUILDDIR@/src/libcamera"
EXCLUDE = @TOP_SRCDIR@/include/libcamera/base/span.h \
@TOP_SRCDIR@/include/libcamera/internal/device_enumerator_sysfs.h \
@TOP_SRCDIR@/include/libcamera/internal/device_enumerator_udev.h \
@TOP_SRCDIR@/include/libcamera/internal/ipc_pipe_unixsocket.h \
@TOP_SRCDIR@/src/libcamera/device_enumerator_sysfs.cpp \
@TOP_SRCDIR@/src/libcamera/device_enumerator_udev.cpp \
@TOP_SRCDIR@/src/libcamera/ipc_pipe_unixsocket.cpp \
@TOP_SRCDIR@/src/libcamera/pipeline/ \
@TOP_SRCDIR@/src/libcamera/sensor/camera_sensor_legacy.cpp \
@TOP_SRCDIR@/src/libcamera/sensor/camera_sensor_raw.cpp \
@TOP_SRCDIR@/src/libcamera/tracepoints.cpp \
@TOP_BUILDDIR@/include/libcamera/internal/tracepoints.h \
@TOP_BUILDDIR@/include/libcamera/ipa/soft_ipa_interface.h \
@TOP_BUILDDIR@/src/libcamera/proxy/

View file

@ -0,0 +1,20 @@
# SPDX-License-Identifier: CC-BY-SA-4.0
@INCLUDE_PATH = @TOP_BUILDDIR@/Documentation
@INCLUDE = Doxyfile-common
HIDE_UNDOC_CLASSES = YES
HIDE_UNDOC_MEMBERS = YES
HTML_OUTPUT = api-html
INTERNAL_DOCS = NO
INPUT = "@TOP_SRCDIR@/Documentation" \
${inputs}
EXCLUDE = @TOP_SRCDIR@/include/libcamera/base/class.h \
@TOP_SRCDIR@/include/libcamera/base/object.h \
@TOP_SRCDIR@/include/libcamera/base/span.h \
@TOP_SRCDIR@/src/libcamera/base/class.cpp \
@TOP_SRCDIR@/src/libcamera/base/object.cpp
PREDEFINED += __DOXYGEN_PUBLIC__

View file

@ -2,7 +2,7 @@
.. _api:
API
===
API Reference
=============
:: Placeholder for Doxygen documentation

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _camera-sensor-model:
.. todo: Move to Doxygen-generated documentation

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-4.0
.. include:: documentation-contents.rst
.. _code-of-conduct:
Contributor Covenant Code of Conduct

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _coding-style-guidelines:
Coding Style Guidelines
@ -215,7 +217,7 @@ shall be avoided when possible, but are allowed when required (for instance to
implement factories with auto-registration). They shall not depend on any other
global variable, should run a minimal amount of code in the constructor and
destructor, and code that contains dependencies should be moved to a later
point in time.
point in time.
Error Handling
~~~~~~~~~~~~~~

View file

@ -37,8 +37,11 @@ author = u'Kieran Bingham, Jacopo Mondi, Laurent Pinchart, Niklas Söderlund'
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.graphviz'
]
graphviz_output_format = 'svg'
# Add any paths that contain templates here, relative to this directory.
templates_path = []
@ -61,7 +64,12 @@ language = 'en'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
exclude_patterns = [
'_build',
'Thumbs.db',
'.DS_Store',
'documentation-contents.rst',
]
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None

331
Documentation/design/ae.rst Normal file
View file

@ -0,0 +1,331 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
Design of Exposure and Gain controls
====================================
This document explains the design and rationale of the controls related to
exposure and gain. This includes the all-encompassing auto-exposure (AE), the
manual exposure control, and the manual gain control.
Description of the problem
--------------------------
Sub controls
^^^^^^^^^^^^
There are more than one control that make up total exposure: exposure time,
gain, and aperture (though for now we will not consider aperture). We already
had individual controls for setting the values of manual exposure and manual
gain, but for switching between auto mode and manual mode we only had a
high-level boolean AeEnable control that would set *both* exposure and gain to
auto mode or manual mode; we had no way to set one to auto and the other to
manual.
So, we need to introduce two new controls to act as "levers" to indicate
individually for exposure and gain if the value would come from AEGC or if it
would come from the manual control value.
Aperture priority
^^^^^^^^^^^^^^^^^
We eventually may need to support aperture, and so whatever our solution is for
having only some controls on auto and the others on manual needs to be
extensible.
Flickering when going from auto to manual
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When a manual exposure or gain value is requested by the application, it costs
a few frames worth of time for them to take effect. This means that during a
transition from auto to manual, there would be flickering in the control values
and the transition won't be smooth.
Take for instance the following flow, where we start on auto exposure (which
for the purposes of the example increments by 1 each frame) and we want to
switch seamlessly to manual exposure, which involves copying the exposure value
computed by the auto exposure algorithm:
::
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
| N | | N+1 | | N+2 | | N+3 | | N+4 | | N+5 | | N+6 |
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
Mode requested: Auto Auto Auto Manual Manual Manual Manual
Exp requested: N/A N/A N/A 2 2 2 2
Set in Frame: N+2 N+3 N+4 N+5 N+6 N+7 N+8
Mode used: Auto Auto Auto Auto Auto Manual Manual
Exp used: 0 1 2 3 4 2 2
As we can see, after frame N+2 completes, we copy the exposure value that was
used for frame N+2 (which was computed by AE algorithm), and queue that value
into request N+3 with manual mode on. However, as it takes two frames for the
exposure to be set, the exposure still changes since it is set by AE, and we
get a flicker in the exposure during the switch from auto to manual.
A solution is to *not submit* any exposure value when manual mode is enabled,
and wait until the manual mode as been "applied" before copying the exposure
value:
::
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
| N | | N+1 | | N+2 | | N+3 | | N+4 | | N+5 | | N+6 |
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
Mode requested: Auto Auto Auto Manual Manual Manual Manual
Exp requested: N/A N/A N/A None None None 5
Set in Frame: N+2 N+3 N+4 N+5 N+6 N+7 N+8
Mode used: Auto Auto Auto Auto Auto Manual Manual
Exp used: 0 1 2 3 4 5 5
In practice, this works. However, libcamera has a policy where once a control
is submitted, its value is saved and does not need to be resubmitted. If the
manual exposure value was set while auto mode was on, in theory the value would
be saved, so when manual mode is enabled, the exposure value that was
previously set would immediately be used. Clearly this solution isn't correct,
but it can serve as the basis for a proper solution, with some more rigorous
rules.
Existing solutions
------------------
Raspberry Pi
^^^^^^^^^^^^
The Raspberry Pi IPA gets around the lack of individual AeEnable controls for
exposure and gain by using magic values. When AeEnable is false, if one of the
manual control values was set to 0 then the value computed by AEGC would be
used for just that control. This solution isn't desirable, as it prevents
that magic value from being used as a valid value.
To get around the flickering issue, when AeEnable is false, the Raspberry Pi
AEGC simply stops updating the values to be set, without restoring the
previously set manual exposure time and gain. This works, but is not a proper
solution.
Android
^^^^^^^
The Android HAL specification requires that exposure and gain (sensitivity)
must both be manual or both be auto. It cannot be that one is manual while the
other is auto, so they simply don't support sub controls.
For the flickering issue, the Android HAL has an AeLock control. To transition
from auto to manual, the application would keep AE on auto, and turn on the
lock. Once the lock has propagated through, then the value can be copied from
the result into the request and the lock disabled and the mode set to manual.
The problem with this solution is, besides the extra complexity, that it is
ambiguous what happens if there is a state transition from manual to locked
(even though it's a state transition that doesn't make sense). If locked is
defined to "use the last automatically computed values" then it could use the
values from the last time it AE was set to auto, or it would be undefined if AE
was never auto (eg. it started out as manual), or if AE is implemented to run
in the background it could just use the current values that are computed. If
locked is defined to "use the last value that was set" there would be less
ambiguity. Still, it's better if we can make it impossible to execute this
nonsensical state transition, and if we can reduce the complexity of having
this extra control or extra setting on a lever.
Summary of goals
----------------
- We need a lock of some sort, to instruct the AEGC to not update output
results
- We need manual modes, to override the values computed by the AEGC
- We need to support seamless transitions from auto to manual, and do so
without flickering
- We need custom minimum values for the manual controls; that is, no magic
values for enabling/disabling auto
- All of these need to be done with AE sub-controls (exposure time, analogue
gain) and be extensible to aperture in the future
Our solution
------------
A diagram of our solution:
::
+----------------------------+-------------+------------------+-----------------+
| INPUT | ALGORITHM | RESULT | OUTPUT |
+----------------------------+-------------+------------------+-----------------+
ExposureTimeMode ExposureTimeMode
---------------------+----------------------------------------+----------------->
0: Auto | |
1: Manual | V
| |\
| | \
| /----------------------------------> | 1| ExposureTime
| | +-------------+ exposure time | | -------------->
\--)--> | | --------------> | 0|
ExposureTime | | | | /
------------------------+--> | | |/
| | AeState
| AEGC | ----------------------------------->
AnalogueGain | |
------------------------+--> | | |\
| | | | \
/--)--> | | --------------> | 0| AnalogueGain
| | +-------------+ analogue gain | | -------------->
| \----------------------------------> | 1|
| | /
| |/
| ^
AnalogueGainMode | | AnalogueGainMode
---------------------+----------------------------------------+----------------->
0: Auto
1: Manual
AeEnable
- True -> ExposureTimeMode:Auto + AnalogueGainMode:Auto
- False -> ExposureTimeMode:Manual + AnalogueGainMode:Manual
The diagram is divided in four sections horizontally:
- Input: The values received from the request controls
- Algorithm: The algorithm itself
- Result: The values calculated by the algorithm
- Output: The values reported in result metadata and applied to the device
The four input controls are divided between manual values (ExposureTime and
AnalogueGain), and operation modes (ExposureTimeMode and AnalogueGainMode). The
former are the manual values, the latter control how they're applied. The two
modes are independent from each other, and each can take one of two values:
- Auto (0): The AGC computes the value normally. The AGC result is applied
to the output. The manual value is ignored *and is not retained*.
- Manual (1): The AGC uses the manual value internally. The corresponding
manual control from the request is applied to the output. The AGC result
is ignored.
The AeState control reports the state of the unified AEGC block. If both
ExposureTimeMode and AnalogueGainMode are set to manual then it will report
Idle. If at least one of the two is set to auto, then AeState will report
if the AEGC has Converged or not (Searching). This control replaces the old
AeLocked control, as it was insufficient for reporting the AE state.
There is a caveat to manual mode: the manual control value is not retained if
it is set during auto mode. This means that if manual mode is entered without
also setting the manual value, then it will enter a state similar to "locked",
where the last automatically computed value while the mode was auto will be
used. Once the manual value is set, then that will be used and retained as
usual.
This simulates an auto -> locked -> manual or auto -> manual state transition,
and makes it impossible to do the nonsensical manual -> locked state
transition.
AeEnable still exists to allow applications to set the mode of all the
sub-controls at once. Besides being for convenience, this will also be useful
when we eventually implement an aperture control. This is because applications
that will be made before aperture will have been available would still be able
to set aperture mode to auto or manual, as opposed to having the aperture stuck
at auto while the application really wanted manual. Although the aperture would
still be stuck at an uncontrollable value, at least it would be at a static
usable value as opposed to varying via the AEGC algorithm.
With this solution, the earlier example would become:
::
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
| N+2 | | N+3 | | N+4 | | N+5 | | N+6 | | N+7 | | N+8 | | N+9 | | N+10|
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
Mode requested: Auto Manual Manual Manual Manual Manual Manual Manual Manual
Exp requested: N/A None None None None 10 None 10 10
Set in Frame: N+4 N+5 N+6 N+7 N+8 N+9 N+10 N+11 N+12
Mode used: Auto Auto Auto Manual Manual Manual Manual Manual Manual
Exp used: 2 3 4 5 5 5 5 10 10
This example is extended by a few frames to exhibit the simulated "locked"
state. At frame N+5 the application has confirmed that the manual mode has been
entered, but does not provide a manual value until request N+7. Thus, the value
that is used in requests N+5 and N+6 (where the mode is disabled), comes from
the last value that was used when the mode was auto, which comes from frame
N+4.
Then, in N+7, a manual value of 10 is supplied. It takes until frame N+9 for
the exposure to be applied. N+8 does not supply a manual value, but the last
supplied value is retained, so a manual value of 10 is still used and set in
frame N+10.
Although this behavior is the same as what we had with waiting for the manual
mode to propagate (in the section "Description of the problem"), this time it
is correct as we have defined specifically that if a manual value was specified
while the mode was auto, it will not be retained.
Description of the controls
---------------------------
As described above, libcamera offers the following controls related to exposure
and gain:
- AnalogueGain
- AnalogueGainMode
- ExposureTime
- ExposureTimeMode
- AeState
- AeEnable
Auto-exposure and auto-gain can be enabled and disabled separately using the
ExposureTimeMode and AnalogueGainMode controls respectively. The AeEnable
control can also be used, as it sets both of the modes simultaneously. The
AeEnable control is not returned in metadata.
When the respective mode is set to auto, the respective value that is computed
by the AEGC algorithm is applied to the image sensor. Any value that is
supplied in the manual ExposureTime/AnalogueGain control is ignored and not
retained. Another way to understand this is that when the mode transitions from
auto to manual, the internally stored control value is overwritten with the
last value computed by the auto algorithm.
This means that when we transition from auto to manual without supplying a
manual control value, the last value that was set by the AEGC algorithm will
keep be used. This can be used to do a flickerless transition from auto to
manual as described earlier. If the camera started out in manual mode and no
corresponding value has been supplied yet, then a best-effort default value
shall be set.
The manual control value can be set in the same request as setting the mode to
auto if the desired manual control value is already known.
Transitioning from manual to auto shall be implicitly flickerless, as the AEGC
algorithms are expected to start running from the last manual value.
The AeState metadata reports the state of the AE algorithm. As AE cannot
compute exposure and gain separately, the state of the AE component is
unified. There are three states: Idle, Searching, and Converged.
The state shall be Idle if both ExposureTimeMode and AnalogueGainMode
are set to Manual. If the camera only supports one of the two controls,
then the state shall be Idle if that one control is set to Manual. If
the camera does not support Manual for at least one of the two controls,
then the state will never be Idle, as AE will always be running.
The state shall be Searching if at least one of exposure or gain calculated
by the AE algorithm is used (that is, at least one of the two modes is Auto),
*and* the value(s) have not converged yet.
The state shall be Converged if at least one of exposure or gain calculated
by the AE algorithm is used (that is, at least one of the two modes is Auto),
*and* the value(s) have converged.

View file

@ -1,400 +0,0 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. contents::
:local:
*************
Documentation
*************
.. toctree::
:hidden:
API <api-html/index>
API
===
The libcamera API is extensively documented using Doxygen. The :ref:`API
nightly build <api>` contains the most up-to-date API documentation, built from
the latest master branch.
Feature Requirements
====================
Device enumeration
------------------
The library shall support enumerating all camera devices available in the
system, including both fixed cameras and hotpluggable cameras. It shall
support cameras plugged and unplugged after the initialization of the
library, and shall offer a mechanism to notify applications of camera plug
and unplug.
The following types of cameras shall be supported:
* Internal cameras designed for point-and-shoot still image and video
capture usage, either controlled directly by the CPU, or exposed through
an internal USB bus as a UVC device.
* External UVC cameras designed for video conferencing usage.
Other types of camera, including analog cameras, depth cameras, thermal
cameras, external digital picture or movie cameras, are out of scope for
this project.
A hardware device that includes independent camera sensors, such as front
and back sensors in a phone, shall be considered as multiple camera devices
for the purpose of this library.
Independent Camera Devices
--------------------------
When multiple cameras are present in the system and are able to operate
independently from each other, the library shall expose them as multiple
camera devices and support parallel operation without any additional usage
restriction apart from the limitations inherent to the hardware (such as
memory bandwidth, CPU usage or number of CSI-2 receivers for instance).
Independent processes shall be able to use independent cameras devices
without interfering with each other. A single camera device shall be
usable by a single process at a time.
Multiple streams support
------------------------
The library shall support multiple video streams running in parallel
for each camera device, within the limits imposed by the system.
Per frame controls
------------------
The library shall support controlling capture parameters for each stream
on a per-frame basis, on a best effort basis based on the capabilities of the
hardware and underlying software stack (including kernel drivers and
firmware). It shall apply capture parameters to the frame they target, and
report the value of the parameters that have effectively been used for each
captured frame.
When a camera device supports multiple streams, the library shall allow both
control of each stream independently, and control of multiple streams
together. Streams that are controlled together shall be synchronized. No
synchronization is required for streams controlled independently.
Capability Enumeration
----------------------
The library shall expose capabilities of each camera device in a way that
allows applications to discover those capabilities dynamically. Applications
shall be allowed to cache capabilities for as long as they are using the
library. If capabilities can change at runtime, the library shall offer a
mechanism to notify applications of such changes. Applications shall not
cache capabilities in long term storage between runs.
Capabilities shall be discovered dynamically at runtime from the device when
possible, and may come, in part or in full, from platform configuration
data.
Device Profiles
---------------
The library may define different camera device profiles, each with a minimum
set of required capabilities. Applications may use those profiles to quickly
determine the level of features exposed by a device without parsing the full
list of capabilities. Camera devices may implement additional capabilities
on top of the minimum required set for the profile they expose.
3A and Image Enhancement Algorithms
-----------------------------------
The camera devices shall implement auto exposure, auto gain and auto white
balance. Camera devices that include a focus lens shall implement auto
focus. Additional image enhancement algorithms, such as noise reduction or
video stabilization, may be implemented.
All algorithms may be implemented in hardware or firmware outside of the
library, or in software in the library. They shall all be controllable by
applications.
The library shall be architectured to isolate the 3A and image enhancement
algorithms in a component with a documented API, respectively called the 3A
component and the 3A API. The 3A API shall be stable, and shall allow both
open-source and closed-source implementations of the 3A component.
The library may include statically-linked open-source 3A components, and
shall support dynamically-linked open-source and closed-source 3A
components.
Closed-source 3A Component Sandboxing
-------------------------------------
For security purposes, it may be desired to run closed-source 3A components
in a separate process. The 3A API would in such a case be transported over
IPC. The 3A API shall make it possible to use any IPC mechanism that
supports passing file descriptors.
The library may implement an IPC mechanism, and shall support third-party
platform-specific IPC mechanisms through the implementation of a
platform-specific 3A API wrapper. No modification to the library shall be
needed to use such third-party IPC mechanisms.
The 3A component shall not directly access any device node on the system.
Such accesses shall instead be performed through the 3A API. The library
shall validate all accesses and restrict them to what is absolutely required
by 3A components.
V4L2 Compatibility Layer
------------------------
The project shall support traditional V4L2 application through an additional
libcamera wrapper library. The wrapper library shall trap all accesses to
camera devices through `LD_PRELOAD`, and route them through libcamera to
emulate a high-level V4L2 camera device. It shall expose camera device
features on a best-effort basis, and aim for the level of features
traditionally available from a UVC camera designed for video conferencing.
Android Camera HAL v3 Compatibility
-----------------------------------
The library API shall expose all the features required to implement an
Android Camera HAL v3 on top of libcamera. Some features of the HAL may be
omitted as long as they can be implemented separately in the HAL, such as
JPEG encoding, or YUV reprocessing.
Camera Stack
============
::
a c / +-------------+ +-------------+ +-------------+ +-------------+
p a | | Native | | Framework | | Native | | Android |
p t | | V4L2 | | Application | | libcamera | | Camera |
l i | | Application | | (gstreamer) | | Application | | Framework |
i o \ +-------------+ +-------------+ +-------------+ +-------------+
n ^ ^ ^ ^
| | | |
l a | | | |
i d v v | v
b a / +-------------+ +-------------+ | +-------------+
c p | | V4L2 | | Camera | | | Android |
a t | | Compat. | | Framework | | | Camera |
m a | | | | (gstreamer) | | | HAL |
e t \ +-------------+ +-------------+ | +-------------+
r i ^ ^ | ^
a o | | | |
n | | | |
/ | ,................................................
| | ! : Language : !
l f | | ! : Bindings : !
i r | | ! : (optional) : !
b a | | \...............................................'
c m | | | | |
a e | | | | |
m w | v v v v
e o | +----------------------------------------------------------------+
r r | | |
a k | | libcamera |
| | |
\ +----------------------------------------------------------------+
^ ^ ^
Userspace | | |
------------------------ | ---------------- | ---------------- | ---------------
Kernel | | |
v v v
+-----------+ +-----------+ +-----------+
| Media | <--> | Video | <--> | V4L2 |
| Device | | Device | | Subdev |
+-----------+ +-----------+ +-----------+
The camera stack comprises four software layers. From bottom to top:
* The kernel drivers control the camera hardware and expose a
low-level interface to userspace through the Linux kernel V4L2
family of APIs (Media Controller API, V4L2 Video Device API and
V4L2 Subdev API).
* The libcamera framework is the core part of the stack. It
handles all control of the camera devices in its core component,
libcamera, and exposes a native C++ API to upper layers. Optional
language bindings allow interfacing to libcamera from other
programming languages.
Those components live in the same source code repository and
all together constitute the libcamera framework.
* The libcamera adaptation is an umbrella term designating the
components that interface to libcamera in other frameworks.
Notable examples are a V4L2 compatibility layer, a gstreamer
libcamera element, and an Android camera HAL implementation based
on libcamera.
Those components can live in the libcamera project source code
in separate repositories, or move to their respective project's
repository (for instance the gstreamer libcamera element).
* The applications and upper level frameworks are based on the
libcamera framework or libcamera adaptation, and are outside of
the scope of the libcamera project.
libcamera Architecture
======================
::
---------------------------< libcamera Public API >---------------------------
^ ^
| |
v v
+-------------+ +-------------------------------------------------+
| Camera | | Camera Device |
| Devices | | +---------------------------------------------+ |
| Manager | | | Device-Agnostic | |
+-------------+ | | | |
^ | | +------------------------+ |
| | | | ~~~~~~~~~~~~~~~~~~~~~ |
| | | | { +---------------+ } |
| | | | } | ////Image//// | { |
| | | | <-> | /Processing// | } |
| | | | } | /Algorithms// | { |
| | | | { +---------------+ } |
| | | | ~~~~~~~~~~~~~~~~~~~~~ |
| | | | ======================== |
| | | | +---------------+ |
| | | | | //Pipeline/// | |
| | | | <-> | ///Handler/// | |
| | | | | ///////////// | |
| | +--------------------+ +---------------+ |
| | Device-Specific |
| +-------------------------------------------------+
| ^ ^
| | |
v v v
+--------------------------------------------------------------------+
| Helpers and Support Classes |
| +-------------+ +-------------+ +-------------+ +-------------+ |
| | MC & V4L2 | | Buffers | | Sandboxing | | Plugins | |
| | Support | | Allocator | | IPC | | Manager | |
| +-------------+ +-------------+ +-------------+ +-------------+ |
| +-------------+ +-------------+ |
| | Pipeline | | ... | |
| | Runner | | | |
| +-------------+ +-------------+ |
+--------------------------------------------------------------------+
/// Device-Specific Components
~~~ Sandboxing
While offering a unified API towards upper layers, and presenting
itself as a single library, libcamera isn't monolithic. It exposes
multiple components through its public API, is built around a set of
separate helpers internally, uses device-specific components and can
load dynamic plugins.
Camera Devices Manager
The Camera Devices Manager provides a view of available cameras
in the system. It performs cold enumeration and runtime camera
management, and supports a hotplug notification mechanism in its
public API.
To avoid the cost associated with cold enumeration of all devices
at application start, and to arbitrate concurrent access to camera
devices, the Camera Devices Manager could later be split to a
separate service, possibly with integration in platform-specific
device management.
Camera Device
The Camera Device represents a camera device to upper layers. It
exposes full control of the device through the public API, and is
thus the highest level object exposed by libcamera.
Camera Device instances are created by the Camera Devices
Manager. An optional function to create new instances could be exposed
through the public API to speed up initialization when the upper
layer knows how to directly address camera devices present in the
system.
Pipeline Handler
The Pipeline Handler manages complex pipelines exposed by the kernel drivers
through the Media Controller and V4L2 APIs. It abstracts pipeline handling to
hide device-specific details to the rest of the library, and implements both
pipeline configuration based on stream configuration, and pipeline runtime
execution and scheduling when needed by the device.
This component is device-specific and is part of the libcamera code base. As
such it is covered by the same free software license as the rest of libcamera
and needs to be contributed upstream by device vendors. The Pipeline Handler
lives in the same process as the rest of the library, and has access to all
helpers and kernel camera-related devices.
Image Processing Algorithms
Together with the hardware image processing and hardware statistics
collection, the Image Processing Algorithms implement 3A (Auto-Exposure,
Auto-White Balance and Auto-Focus) and other algorithms. They run on the CPU
and interact with the kernel camera devices to control hardware image
processing based on the parameters supplied by upper layers, closing the
control loop of the ISP.
This component is device-specific and is loaded as an external plugin. It can
be part of the libcamera code base, in which case it is covered by the same
license, or provided externally as an open-source or closed-source component.
The component is sandboxed and can only interact with libcamera through
internal APIs specifically marked as such. In particular it will have no
direct access to kernel camera devices, and all its accesses to image and
metadata will be mediated by dmabuf instances explicitly passed to the
component. The component must be prepared to run in a process separate from
the main libcamera process, and to have a very restricted view of the system,
including no access to networking APIs and limited access to file systems.
The sandboxing mechanism isn't defined by libcamera. One example
implementation will be provided as part of the project, and platforms vendors
will be able to provide their own sandboxing mechanism as a plugin.
libcamera should provide a basic implementation of Image Processing
Algorithms, to serve as a reference for the internal API. Device vendors are
expected to provide a full-fledged implementation compatible with their
Pipeline Handler. One goal of the libcamera project is to create an
environment in which the community will be able to compete with the
closed-source vendor binaries and develop a high quality open source
implementation.
Helpers and Support Classes
While Pipeline Handlers are device-specific, implementations are expected to
share code due to usage of identical APIs towards the kernel camera drivers
and the Image Processing Algorithms. This includes without limitation handling
of the MC and V4L2 APIs, buffer management through dmabuf, and pipeline
discovery, configuration and scheduling. Such code will be factored out to
helpers when applicable.
Other parts of libcamera will also benefit from factoring code out to
self-contained support classes, even if such code is present only once in the
code base, in order to keep the source code clean and easy to read. This
should be the case for instance for plugin management.
V4L2 Compatibility Layer
------------------------
V4L2 compatibility is achieved through a shared library that traps all
accesses to camera devices and routes them to libcamera to emulate high-level
V4L2 camera devices. It is injected in a process address space through
`LD_PRELOAD` and is completely transparent for applications.
The compatibility layer exposes camera device features on a best-effort basis,
and aims for the level of features traditionally available from a UVC camera
designed for video conferencing.
Android Camera HAL
------------------
Camera support for Android is achieved through a generic Android
camera HAL implementation on top of libcamera. The HAL will implement internally
features required by Android and missing from libcamera, such as JPEG encoding
support.
The Android camera HAL implementation will initially target the
LIMITED hardware level, with support for the FULL level then being gradually
implemented.

View file

@ -0,0 +1,35 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. container:: documentation-nav
* **Documentation for Users**
* :doc:`Introduction </introduction>`
* :doc:`/feature_requirements`
* :doc:`/guides/application-developer`
* :doc:`/python-bindings`
* :doc:`/environment_variables`
* :doc:`/api-html/index`
* :doc:`/code-of-conduct`
* |
* **Documentation for Developers**
* :doc:`/libcamera_architecture`
* :doc:`/guides/pipeline-handler`
* :doc:`/guides/ipa`
* :doc:`/camera-sensor-model`
* :doc:`/guides/tracing`
* :doc:`/software-isp-benchmarking`
* :doc:`/coding-style`
* :doc:`/internal-api-html/index`
* |
* **Documentation for System Integrators**
* :doc:`/lens_driver_requirements`
* :doc:`/sensor_driver_requirements`
..
The following directive adds the "documentation" class to all of the pages
generated by sphinx. This is not relevant in libcamera nor addressed in the
theme's CSS, since all of the pages here are documentation. It **is** used
to properly format the documentation pages on libcamera.org and so should not
be removed.
.. rst-class:: documentation

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
Environment variables
=====================
@ -37,6 +39,11 @@ LIBCAMERA_IPA_MODULE_PATH
Example value: ``${HOME}/.libcamera/lib:/opt/libcamera/vendor/lib``
LIBCAMERA_IPA_PROXY_PATH
Define custom full path for a proxy worker for a given executable name.
Example value: ``${HOME}/.libcamera/proxy/worker:/opt/libcamera/vendor/proxy/worker``
LIBCAMERA_PIPELINES_MATCH_LIST
Define an ordered list of pipeline names to be used to match the media
devices in the system. The pipeline handler names used to populate the
@ -50,6 +57,11 @@ LIBCAMERA_RPI_CONFIG_FILE
Example value: ``/usr/local/share/libcamera/pipeline/rpi/vc4/minimal_mem.yaml``
LIBCAMERA_<NAME>_TUNING_FILE
Define a custom IPA tuning file to use with the pipeline handler `NAME`.
Example value: ``/usr/local/share/libcamera/ipa/rpi/vc4/custom_sensor.json``
Further details
---------------

View file

@ -0,0 +1,150 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
Feature Requirements
====================
Device enumeration
------------------
The library shall support enumerating all camera devices available in the
system, including both fixed cameras and hotpluggable cameras. It shall
support cameras plugged and unplugged after the initialization of the
library, and shall offer a mechanism to notify applications of camera plug
and unplug.
The following types of cameras shall be supported:
* Internal cameras designed for point-and-shoot still image and video
capture usage, either controlled directly by the CPU, or exposed through
an internal USB bus as a UVC device.
* External UVC cameras designed for video conferencing usage.
Other types of camera, including analog cameras, depth cameras, thermal
cameras, external digital picture or movie cameras, are out of scope for
this project.
A hardware device that includes independent camera sensors, such as front
and back sensors in a phone, shall be considered as multiple camera devices
for the purpose of this library.
Independent Camera Devices
--------------------------
When multiple cameras are present in the system and are able to operate
independently from each other, the library shall expose them as multiple
camera devices and support parallel operation without any additional usage
restriction apart from the limitations inherent to the hardware (such as
memory bandwidth, CPU usage or number of CSI-2 receivers for instance).
Independent processes shall be able to use independent cameras devices
without interfering with each other. A single camera device shall be
usable by a single process at a time.
Multiple streams support
------------------------
The library shall support multiple video streams running in parallel
for each camera device, within the limits imposed by the system.
Per frame controls
------------------
The library shall support controlling capture parameters for each stream
on a per-frame basis, on a best effort basis based on the capabilities of the
hardware and underlying software stack (including kernel drivers and
firmware). It shall apply capture parameters to the frame they target, and
report the value of the parameters that have effectively been used for each
captured frame.
When a camera device supports multiple streams, the library shall allow both
control of each stream independently, and control of multiple streams
together. Streams that are controlled together shall be synchronized. No
synchronization is required for streams controlled independently.
Capability Enumeration
----------------------
The library shall expose capabilities of each camera device in a way that
allows applications to discover those capabilities dynamically. Applications
shall be allowed to cache capabilities for as long as they are using the
library. If capabilities can change at runtime, the library shall offer a
mechanism to notify applications of such changes. Applications shall not
cache capabilities in long term storage between runs.
Capabilities shall be discovered dynamically at runtime from the device when
possible, and may come, in part or in full, from platform configuration
data.
Device Profiles
---------------
The library may define different camera device profiles, each with a minimum
set of required capabilities. Applications may use those profiles to quickly
determine the level of features exposed by a device without parsing the full
list of capabilities. Camera devices may implement additional capabilities
on top of the minimum required set for the profile they expose.
3A and Image Enhancement Algorithms
-----------------------------------
The library shall provide a basic implementation of Image Processing Algorithms
to serve as a reference for the internal API. This shall including auto exposure
and gain and auto white balance. Camera devices that include a focus lens shall
implement auto focus. Additional image enhancement algorithms, such as noise
reduction or video stabilization, may be implemented. Device vendors are
expected to provide a fully-fledged implementation compatible with their
Pipeline Handler. One goal of the libcamera project is to create an environment
in which the community will be able to compete with the closed-source vendor
biaries and develop a high quality open source implementation.
All algorithms may be implemented in hardware or firmware outside of the
library, or in software in the library. They shall all be controllable by
applications.
The library shall be architectured to isolate the 3A and image enhancement
algorithms in a component with a documented API, respectively called the 3A
component and the 3A API. The 3A API shall be stable, and shall allow both
open-source and closed-source implementations of the 3A component.
The library may include statically-linked open-source 3A components, and
shall support dynamically-linked open-source and closed-source 3A
components.
Closed-source 3A Component Sandboxing
-------------------------------------
For security purposes, it may be desired to run closed-source 3A components
in a separate process. The 3A API would in such a case be transported over
IPC. The 3A API shall make it possible to use any IPC mechanism that
supports passing file descriptors.
The library may implement an IPC mechanism, and shall support third-party
platform-specific IPC mechanisms through the implementation of a
platform-specific 3A API wrapper. No modification to the library shall be
needed to use such third-party IPC mechanisms.
The 3A component shall not directly access any device node on the system.
Such accesses shall instead be performed through the 3A API. The library
shall validate all accesses and restrict them to what is absolutely required
by 3A components.
V4L2 Compatibility Layer
------------------------
The project shall support traditional V4L2 application through an additional
libcamera wrapper library. The wrapper library shall trap all accesses to
camera devices through `LD_PRELOAD`, and route them through libcamera to
emulate a high-level V4L2 camera device. It shall expose camera device
features on a best-effort basis, and aim for the level of features
traditionally available from a UVC camera designed for video conferencing.
Android Camera HAL v3 Compatibility
-----------------------------------
The library API shall expose all the features required to implement an
Android Camera HAL v3 on top of libcamera. Some features of the HAL may be
omitted as long as they can be implemented separately in the HAL, such as
JPEG encoding, or YUV reprocessing.

46
Documentation/gen-doxyfile.py Executable file
View file

@ -0,0 +1,46 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2024, Google Inc.
#
# Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
#
# Generate Doxyfile from a template
import argparse
import os
import string
import sys
def fill_template(template, data):
template = open(template, 'rb').read()
template = template.decode('utf-8')
template = string.Template(template)
return template.substitute(data)
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument('-o', dest='output', metavar='file',
type=argparse.FileType('w', encoding='utf-8'),
default=sys.stdout,
help='Output file name (default: standard output)')
parser.add_argument('template', metavar='doxyfile.tmpl', type=str,
help='Doxyfile template')
parser.add_argument('inputs', type=str, nargs='*',
help='Input files')
args = parser.parse_args(argv[1:])
inputs = [f'"{os.path.realpath(input)}"' for input in args.inputs]
data = fill_template(args.template, {'inputs': (' \\\n' + ' ' * 25).join(inputs)})
args.output.write(data)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))

View file

@ -1,4 +1,5 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. Getting started information is defined in the project README file.
.. include:: ../README.rst
:start-after: .. section-begin-getting-started

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: ../documentation-contents.rst
Using libcamera in a C++ application
====================================
@ -116,19 +118,21 @@ available.
.. code:: cpp
if (cm->cameras().empty()) {
auto cameras = cm->cameras();
if (cameras.empty()) {
std::cout << "No cameras were identified on the system."
<< std::endl;
cm->stop();
return EXIT_FAILURE;
}
std::string cameraId = cm->cameras()[0]->id();
camera = cm->get(cameraId);
std::string cameraId = cameras[0]->id();
camera = cm->get(cameraId);
/*
* Note that is equivalent to:
* camera = cm->cameras()[0];
* Note that `camera` may not compare equal to `cameras[0]`.
* In fact, it might simply be a `nullptr`, as the particular
* device might have disappeared (and reappeared) in the meantime.
*/
Once a camera has been selected an application needs to acquire an exclusive
@ -479,7 +483,7 @@ instance. An example of how to write image data to disk is available in the
`FileSink class`_ which is a part of the ``cam`` utility application in the
libcamera repository.
.. _FileSink class: https://git.libcamera.org/libcamera/libcamera.git/tree/src/cam/file_sink.cpp
.. _FileSink class: https://git.libcamera.org/libcamera/libcamera.git/tree/src/apps/cam/file_sink.cpp
With the handling of this request completed, it is possible to re-use the
request and the associated buffers and re-queue it to the camera
@ -614,7 +618,7 @@ accordingly. In this example, the application file has been named
simple_cam = executable('simple-cam',
'simple-cam.cpp',
dependencies: dependency('libcamera', required : true))
dependencies: dependency('libcamera'))
The ``dependencies`` line instructs meson to ask ``pkgconfig`` (or ``cmake``) to
locate the ``libcamera`` library, which the test application will be

View file

@ -1,319 +0,0 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
Developers guide to libcamera
=============================
The Linux kernel handles multimedia devices through the 'Linux media' subsystem
and provides a set of APIs (application programming interfaces) known
collectively as V4L2 (`Video for Linux 2`_) and the `Media Controller`_ API
which provide an interface to interact and control media devices.
Included in this subsystem are drivers for camera sensors, CSI2 (Camera
Serial Interface) receivers, and ISPs (Image Signal Processors)
The usage of these drivers to provide a functioning camera stack is a
responsibility that lies in userspace which is commonly implemented separately
by vendors without a common architecture or API for application developers.
libcamera provides a complete camera stack for Linux based systems to abstract
functionality desired by camera application developers and process the
configuration of hardware and image control algorithms required to obtain
desirable results from the camera.
.. _Video for Linux 2: https://www.linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/v4l/v4l2.html
.. _Media Controller: https://www.linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/mediactl/media-controller.html
In this developers guide, we will explore the `Camera Stack`_ and how it is
can be visualised at a high level, and explore the internal `Architecture`_ of
the libcamera library with its components. The current `Platform Support`_ is
detailed, as well as an overview of the `Licensing`_ requirements of the
project.
This introduction is followed by a walkthrough tutorial to newcomers wishing to
support a new platform with the `Pipeline Handler Writers Guide`_ and for those
looking to make use of the libcamera native API an `Application Writers Guide`_
provides a tutorial of the key APIs exposed by libcamera.
.. _Pipeline Handler Writers Guide: pipeline-handler.html
.. _Application Writers Guide: application-developer.html
.. TODO: Correctly link to the other articles of the guide
Camera Stack
------------
The libcamera library is implemented in userspace, and makes use of underlying
kernel drivers that directly interact with hardware.
Applications can make use of libcamera through the native `libcamera API`_'s or
through an adaptation layer integrating libcamera into a larger framework.
.. _libcamera API: https://www.libcamera.org/api-html/index.html
::
Application Layer
/ +--------------+ +--------------+ +--------------+ +--------------+
| | Native | | Framework | | Native | | Android |
| | V4L2 | | Application | | libcamera | | Camera |
| | Application | | (gstreamer) | | Application | | Framework |
\ +--------------+ +--------------+ +--------------+ +--------------+
^ ^ ^ ^
| | | |
| | | |
v v | v
Adaptation Layer |
/ +--------------+ +--------------+ | +--------------+
| | V4L2 | | gstreamer | | | Android |
| | Compatibility| | element | | | Camera |
| | (preload) | |(libcamerasrc)| | | HAL |
\ +--------------+ +--------------+ | +--------------+
|
^ ^ | ^
| | | |
| | | |
v v v v
libcamera Framework
/ +--------------------------------------------------------------------+
| | |
| | libcamera |
| | |
\ +--------------------------------------------------------------------+
^ ^ ^
Userspace | | |
--------------------- | ---------------- | ---------------- | ---------------
Kernel | | |
v v v
+-----------+ +-----------+ +-----------+
| Media | <--> | Video | <--> | V4L2 |
| Device | | Device | | Subdev |
+-----------+ +-----------+ +-----------+
The camera stack comprises of four software layers. From bottom to top:
* The kernel drivers control the camera hardware and expose a low-level
interface to userspace through the Linux kernel V4L2 family of APIs
(Media Controller API, V4L2 Video Device API and V4L2 Subdev API).
* The libcamera framework is the core part of the stack. It handles all control
of the camera devices in its core component, libcamera, and exposes a native
C++ API to upper layers.
* The libcamera adaptation layer is an umbrella term designating the components
that interface to libcamera in other frameworks. Notable examples are the V4L2
compatibility layer, the gstreamer libcamera element, and the Android camera
HAL implementation based on libcamera which are provided as a part of the
libcamera project.
* The applications and upper level frameworks are based on the libcamera
framework or libcamera adaptation, and are outside of the scope of the
libcamera project, however example native applications (cam, qcam) are
provided for testing.
V4L2 Compatibility Layer
V4L2 compatibility is achieved through a shared library that traps all
accesses to camera devices and routes them to libcamera to emulate high-level
V4L2 camera devices. It is injected in a process address space through
``LD_PRELOAD`` and is completely transparent for applications.
The compatibility layer exposes camera device features on a best-effort basis,
and aims for the level of features traditionally available from a UVC camera
designed for video conferencing.
Android Camera HAL
Camera support for Android is achieved through a generic Android camera HAL
implementation on top of libcamera. The HAL implements features required by
Android and out of scope from libcamera, such as JPEG encoding support.
This component is used to provide support for ChromeOS platforms
GStreamer element (gstlibcamerasrc)
A `GStreamer element`_ is provided to allow capture from libcamera supported
devices through GStreamer pipelines, and connect to other elements for further
processing.
Development of this element is ongoing and is limited to a single stream.
Native libcamera API
Applications can make use of the libcamera API directly using the C++
API. An example application and walkthrough using the libcamera API can be
followed in the `Application Writers Guide`_
.. _GStreamer element: https://gstreamer.freedesktop.org/documentation/application-development/basics/elements.html
Architecture
------------
While offering a unified API towards upper layers, and presenting itself as a
single library, libcamera isn't monolithic. It exposes multiple components
through its public API and is built around a set of separate helpers internally.
Hardware abstractions are handled through the use of device-specific components
where required and dynamically loadable plugins are used to separate image
processing algorithms from the core libcamera codebase.
::
--------------------------< libcamera Public API >---------------------------
^ ^
| |
v v
+-------------+ +---------------------------------------------------+
| Camera | | Camera Device |
| Manager | | +-----------------------------------------------+ |
+-------------+ | | Device-Agnostic | |
^ | | | |
| | | +--------------------------+ |
| | | | ~~~~~~~~~~~~~~~~~~~~~~~ |
| | | | { +-----------------+ } |
| | | | } | //// Image //// | { |
| | | | <-> | / Processing // | } |
| | | | } | / Algorithms // | { |
| | | | { +-----------------+ } |
| | | | ~~~~~~~~~~~~~~~~~~~~~~~ |
| | | | ========================== |
| | | | +-----------------+ |
| | | | | // Pipeline /// | |
| | | | <-> | /// Handler /// | |
| | | | | /////////////// | |
| | +--------------------+ +-----------------+ |
| | Device-Specific |
| +---------------------------------------------------+
| ^ ^
| | |
v v v
+--------------------------------------------------------------------+
| Helpers and Support Classes |
| +-------------+ +-------------+ +-------------+ +-------------+ |
| | MC & V4L2 | | Buffers | | Sandboxing | | Plugins | |
| | Support | | Allocator | | IPC | | Manager | |
| +-------------+ +-------------+ +-------------+ +-------------+ |
| +-------------+ +-------------+ |
| | Pipeline | | ... | |
| | Runner | | | |
| +-------------+ +-------------+ |
+--------------------------------------------------------------------+
/// Device-Specific Components
~~~ Sandboxing
Camera Manager
The Camera Manager enumerates cameras and instantiates Pipeline Handlers to
manage each Camera that libcamera supports. The Camera Manager supports
hotplug detection and notification events when supported by the underlying
kernel devices.
There is only ever one instance of the Camera Manager running per application.
Each application's instance of the Camera Manager ensures that only a single
application can take control of a camera device at once.
Read the `Camera Manager API`_ documentation for more details.
.. _Camera Manager API: https://libcamera.org/api-html/classlibcamera_1_1CameraManager.html
Camera Device
The Camera class represents a single item of camera hardware that is capable
of producing one or more image streams, and provides the API to interact with
the underlying device.
If a system has multiple instances of the same hardware attached, each has its
own instance of the camera class.
The API exposes full control of the device to upper layers of libcamera through
the public API, making it the highest level object libcamera exposes, and the
object that all other API operations interact with from configuration to
capture.
Read the `Camera API`_ documentation for more details.
.. _Camera API: https://libcamera.org/api-html/classlibcamera_1_1Camera.html
Pipeline Handler
The Pipeline Handler manages the complex pipelines exposed by the kernel
drivers through the Media Controller and V4L2 APIs. It abstracts pipeline
handling to hide device-specific details from the rest of the library, and
implements both pipeline configuration based on stream configuration, and
pipeline runtime execution and scheduling when needed by the device.
The Pipeline Handler lives in the same process as the rest of the library, and
has access to all helpers and kernel camera-related devices.
Hardware abstraction is handled by device specific Pipeline Handlers which are
derived from the Pipeline Handler base class allowing commonality to be shared
among the implementations.
Derived pipeline handlers create Camera device instances based on the devices
they detect and support on the running system, and are responsible for
managing the interactions with a camera device.
More details can be found in the `PipelineHandler API`_ documentation, and the
`Pipeline Handler Writers Guide`_.
.. _PipelineHandler API: https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html
Image Processing Algorithms
An image processing algorithm (IPA) component is a loadable plugin that
implements 3A (Auto-Exposure, Auto-White Balance, and Auto-Focus) and other
algorithms.
The algorithms run on the CPU and interact with the camera devices through the
Pipeline Handler to control hardware image processing based on the parameters
supplied by upper layers, maintaining state and closing the control loop
of the ISP.
The component is sandboxed and can only interact with libcamera through the
API provided by the Pipeline Handler and an IPA has no direct access to kernel
camera devices.
Open source IPA modules built with libcamera can be run in the same process
space as libcamera, however external IPA modules are run in a separate process
from the main libcamera process. IPA modules have a restricted view of the
system, including no access to networking APIs and limited access to file
systems.
IPA modules are only required for platforms and devices with an ISP controlled
by the host CPU. Camera sensors which have an integrated ISP are not
controlled through the IPA module.
Platform Support
----------------
The library currently supports the following hardware platforms specifically
with dedicated pipeline handlers:
- Intel IPU3 (ipu3)
- Rockchip RK3399 (rkisp1)
- RaspberryPi 3 and 4 (rpi/vc4)
Furthermore, generic platform support is provided for the following:
- USB video device class cameras (uvcvideo)
- iMX7, Allwinner Sun6i (simple)
- Virtual media controller driver for test use cases (vimc)
Licensing
---------
The libcamera core, is covered by the `LGPL-2.1-or-later`_ license. Pipeline
Handlers are a part of the libcamera code base and need to be contributed
upstream by device vendors. IPA modules included in libcamera are covered by a
free software license, however third-parties may develop IPA modules outside of
libcamera and distribute them under a closed-source license, provided they do
not include source code from the libcamera project.
The libcamera project itself contains multiple libraries, applications and
utilities. Licenses are expressed through SPDX tags in text-based files that
support comments, and through the .reuse/dep5 file otherwise. A copy of all
licenses are stored in the LICENSES directory, and a full summary of the
licensing used throughout the project can be found in the COPYING.rst document.
Applications which link dynamically against libcamera and use only the public
API are an independent work of the authors and have no license restrictions
imposed upon them from libcamera.
.. _LGPL-2.1-or-later: https://spdx.org/licenses/LGPL-2.1-or-later.html

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: ../documentation-contents.rst
IPA Writer's Guide
==================

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: ../documentation-contents.rst
Pipeline Handler Writers Guide
==============================
@ -151,13 +153,14 @@ integrates with the libcamera build system, and a *vivid.cpp* file that matches
the name of the pipeline.
In the *meson.build* file, add the *vivid.cpp* file as a build source for
libcamera by adding it to the global meson ``libcamera_sources`` variable:
libcamera by adding it to the global meson ``libcamera_internal_sources``
variable:
.. code-block:: none
# SPDX-License-Identifier: CC0-1.0
libcamera_sources += files([
libcamera_internal_sources += files([
'vivid.cpp',
])
@ -183,7 +186,7 @@ to the libcamera build options in the top level ``meson_options.txt``.
option('pipelines',
type : 'array',
choices : ['ipu3', 'rkisp1', 'rpi/vc4', 'simple', 'uvcvideo', 'vimc', 'vivid'],
choices : ['ipu3', 'rkisp1', 'rpi/pisp', 'rpi/vc4', 'simple', 'uvcvideo', 'vimc', 'vivid'],
description : 'Select which pipeline handlers to include')
@ -210,7 +213,7 @@ implementations for the overridden class members.
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start(Camera *camera, const ControlList *controls) override;
void stop(Camera *camera) override;
void stopDevice(Camera *camera) override;
int queueRequestDevice(Camera *camera, Request *request) override;
@ -244,7 +247,7 @@ implementations for the overridden class members.
return -1;
}
void PipelineHandlerVivid::stop(Camera *camera)
void PipelineHandlerVivid::stopDevice(Camera *camera)
{
}
@ -518,14 +521,14 @@ handler and camera manager using `registerCamera`_.
Finally with a successful construction, we return 'true' indicating that the
PipelineHandler successfully matched and constructed a device.
.. _Camera::create: https://libcamera.org/api-html/classlibcamera_1_1Camera.html#a453740e0d2a2f495048ae307a85a2574
.. _Camera::create: https://libcamera.org/internal-api-html/classlibcamera_1_1Camera.html#adf5e6c22411f953bfaa1ae21155d6c31
.. _registerCamera: https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html#adf02a7f1bbd87aca73c0e8d8e0e6c98b
.. code-block:: cpp
std::set<Stream *> streams{ &data->stream_ };
std::shared_ptr<Camera> camera = Camera::create(this, data->video_->deviceName(), streams);
registerCamera(std::move(camera), std::move(data));
std::shared_ptr<Camera> camera = Camera::create(std::move(data), data->video_->deviceName(), streams);
registerCamera(std::move(camera));
return true;
@ -551,8 +554,7 @@ Our match function should now look like the following:
/* Create and register the camera. */
std::set<Stream *> streams{ &data->stream_ };
const std::string &id = data->video_->deviceName();
std::shared_ptr<Camera> camera = Camera::create(data.release(), id, streams);
std::shared_ptr<Camera> camera = Camera::create(std::move(data), data->video_->deviceName(), streams);
registerCamera(std::move(camera));
return true;
@ -590,11 +592,11 @@ immutable properties of the ``Camera`` device.
The libcamera controls and properties are defined in YAML form which is
processed to automatically generate documentation and interfaces. Controls are
defined by the src/libcamera/`control_ids_core.yaml`_ file and camera properties
are defined by src/libcamera/`properties_ids_core.yaml`_.
are defined by src/libcamera/`property_ids_core.yaml`_.
.. _controls framework: https://libcamera.org/api-html/controls_8h.html
.. _control_ids_core.yaml: https://libcamera.org/api-html/control__ids_8h.html
.. _properties_ids_core.yaml: https://libcamera.org/api-html/property__ids_8h.html
.. _property_ids_core.yaml: https://libcamera.org/api-html/property__ids_8h.html
Pipeline handlers can optionally register the list of controls an application
can set as well as a list of immutable camera properties. Being both
@ -797,8 +799,7 @@ derived class, and assign it to a base class pointer.
.. code-block:: cpp
VividCameraData *data = cameraData(camera);
CameraConfiguration *config = new VividCameraConfiguration();
auto config = std::make_unique<VividCameraConfiguration>();
A ``CameraConfiguration`` is specific to each pipeline, so you can only create
it from the pipeline handler code path. Applications can also generate an empty
@ -826,9 +827,7 @@ To generate a ``StreamConfiguration``, you need a list of pixel formats and
frame sizes which are supported as outputs of the stream. You can fetch a map of
the ``V4LPixelFormat`` and ``SizeRange`` supported by the underlying output
device, but the pipeline handler needs to convert this to a
``libcamera::PixelFormat`` type to pass to applications. We do this here using
``std::transform`` to convert the formats and populate a new ``PixelFormat`` map
as shown below.
``libcamera::PixelFormat`` type to pass to applications.
Continue adding the following code example to our ``generateConfiguration``
implementation.
@ -838,14 +837,12 @@ implementation.
std::map<V4L2PixelFormat, std::vector<SizeRange>> v4l2Formats =
data->video_->formats();
std::map<PixelFormat, std::vector<SizeRange>> deviceFormats;
std::transform(v4l2Formats.begin(), v4l2Formats.end(),
std::inserter(deviceFormats, deviceFormats.begin()),
[&](const decltype(v4l2Formats)::value_type &format) {
return decltype(deviceFormats)::value_type{
format.first.toPixelFormat(),
format.second
};
});
for (auto &[v4l2PixelFormat, sizes] : v4l2Formats) {
PixelFormat pixelFormat = v4l2PixelFormat.toPixelFormat();
if (pixelFormat.isValid())
deviceFormats.try_emplace(pixelFormat, std::move(sizes));
}
The `StreamFormats`_ class holds information about the pixel formats and frame
sizes that a stream can support. The class groups size information by the pixel
@ -935,9 +932,9 @@ Add the following function implementation to your file:
StreamConfiguration &cfg = config_[0];
const std::vector<libcamera::PixelFormat> formats = cfg.formats().pixelformats();
const std::vector<libcamera::PixelFormat> &formats = cfg.formats().pixelformats();
if (std::find(formats.begin(), formats.end(), cfg.pixelFormat) == formats.end()) {
cfg.pixelFormat = cfg.formats().pixelformats()[0];
cfg.pixelFormat = formats[0];
LOG(VIVID, Debug) << "Adjusting format to " << cfg.pixelFormat.toString();
status = Adjusted;
}
@ -1155,7 +1152,7 @@ available to the devices which have to be started and ready to produce
images. At the end of a capture session the ``Camera`` device needs to be
stopped, to gracefully clean up any allocated memory and stop the hardware
devices. Pipeline handlers implement two functions for these purposes, the
``start()`` and ``stop()`` functions.
``start()`` and ``stopDevice()`` functions.
The memory initialization phase that happens at ``start()`` time serves to
configure video devices to be able to use memory buffers exported as dma-buf
@ -1258,8 +1255,8 @@ algorithms, or other devices you should also stop them.
.. _releaseBuffers: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#a191619c152f764e03bc461611f3fcd35
Of course we also need to handle the corresponding actions to stop streaming on
a device, Add the following to the ``stop`` function, to stop the stream with
the `streamOff`_ function and release all buffers.
a device, Add the following to the ``stopDevice()`` function, to stop the
stream with the `streamOff`_ function and release all buffers.
.. _streamOff: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#a61998710615bdf7aa25a046c8565ed66
@ -1347,7 +1344,7 @@ before being set.
continue;
}
int32_t value = lroundf(it.second.get<float>() * 128 + offset);
int32_t value = std::lround(it.second.get<float>() * 128 + offset);
controls.set(cid, std::clamp(value, 0, 255));
}
@ -1411,7 +1408,7 @@ value translation operations:
.. code-block:: cpp
#include <math.h>
#include <cmath>
Frame completion and event handling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: ../documentation-contents.rst
Tracing Guide
=============

View file

@ -1,27 +1,31 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. Front page matter is defined in the project README file.
.. include:: ../README.rst
:start-after: .. section-begin-libcamera
:end-before: .. section-end-libcamera
.. include:: introduction.rst
.. toctree::
:maxdepth: 1
:caption: Contents:
Home <self>
Docs <docs>
Contribute <contributing>
Getting Started <getting-started>
Developer Guide <guides/introduction>
Application Writer's Guide <guides/application-developer>
Pipeline Handler Writer's Guide <guides/pipeline-handler>
IPA Writer's guide <guides/ipa>
Tracing guide <guides/tracing>
Environment variables <environment_variables>
Sensor driver requirements <sensor_driver_requirements>
Lens driver requirements <lens_driver_requirements>
Python Bindings <python-bindings>
Camera Sensor Model <camera-sensor-model>
Environment variables <environment_variables>
Feature Requirements <feature_requirements>
IPA Writer's guide <guides/ipa>
Lens driver requirements <lens_driver_requirements>
libcamera Architecture <libcamera_architecture>
Pipeline Handler Writer's Guide <guides/pipeline-handler>
Python Bindings <python-bindings>
Sensor driver requirements <sensor_driver_requirements>
SoftwareISP Benchmarking <software-isp-benchmarking>
Tracing guide <guides/tracing>
Design document: AE <design/ae>
.. toctree::
:hidden:
introduction

View file

@ -0,0 +1,8 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. _internal-api:
Internal API Reference
======================
:: Placeholder for Doxygen documentation

View file

@ -0,0 +1,224 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
************
Introduction
************
.. toctree::
:hidden:
API <api-html/index>
Internal API <internal-api-html/index>
What is libcamera?
==================
libcamera is an open source complex camera support library for Linux, Android
and ChromeOS. The library interfaces with Linux kernel device drivers and
provides an intuitive API to developers in order to simplify the complexity
involved in capturing images from complex cameras on Linux systems.
What is a "complex camera"?
===========================
A modern "camera" tends to infact be several different pieces of hardware which
must all be controlled together in order to produce and capture images of
appropriate quality. A hardware pipeline typically consists of a camera sensor
that captures raw frames and transmits them on a bus, a receiver that decodes
the bus signals, and an image signal processor that processes raw frames to
produce usable images in a standard format. The Linux kernel handles these
multimedia devices through the 'Linux media' subsystem and provides a set of
application programming interfaces known collectively as the
V4L2 (`Video for Linux 2`_) and the `Media Controller`_ APIs, which provide an
interface to interact and control media devices.
.. _Video for Linux 2: https://www.linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/v4l/v4l2.html
.. _Media Controller: https://www.linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/mediactl/media-controller.html
Included in this subsystem are drivers for camera sensors, CSI2 (Camera
Serial Interface) receivers, and ISPs (Image Signal Processors).
The usage of these drivers to provide a functioning camera stack is a
responsibility that lies in userspace, and is commonly implemented separately
by vendors without a common architecture or API for application developers. This
adds a lot of complexity to the task, particularly when considering that the
differences in hardware pipelines and their representation in the kernel's APIs
often necessitate bespoke handling.
What is libcamera for?
======================
libcamera provides a complete camera stack for Linux-based systems to abstract
the configuration of hardware and image control algorithms required to obtain
desirable results from the camera through the kernel's APIs, reducing those
operations to a simple and consistent method for developers. In short instead of
having to deal with this:
.. graphviz:: mali-c55.dot
you can instead simply deal with:
.. code-block:: python
>>> import libcamera as lc
>>> camera_manager = lc.CameraManager.singleton()
[0:15:59.582029920] [504] INFO Camera camera_manager.cpp:313 libcamera v0.3.0+182-01e57380
>>> for camera in camera_manager.cameras:
... print(f' - {camera.id}')
...
- mali-c55 tpg
- imx415 1-001a
The library handles the rest for you. These documentary pages give more
information on the internal workings of libcamera (and the kernel camera stack
that lies behind it) as well as guidance on using libcamera in an application or
extending the library with support for your hardware (through the pipeline
handler and IPA module writer's guides).
How should I use it?
====================
There are a few ways you might want to use libcamera, depending on your
application. It's always possible to use the library directly, and you can find
detailed information on how to do so in the
:doc:`application writer's guide <guides/application-developer>`.
It is often more appropriate to use one of the frameworks with libcamera
support. For example an application powering an embedded media device
incorporating capture, encoding and streaming of both video and audio would
benefit from using `GStreamer`_, for which libcamera provides a plugin.
Similarly an application for user-facing devices like a laptop would likely
benefit accessing cameras through the XDG camera portal and `pipewire`_, which
brings the advantages of resource sharing (multiple applications accessing the
stream at the same time) and access control.
.. _GStreamer: https://gstreamer.freedesktop.org/
.. _pipewire: https://pipewire.org/
Camera Stack
============
::
a c / +-------------+ +-------------+ +-------------+ +-------------+
p a | | Native | | Framework | | Native | | Android |
p t | | V4L2 | | Application | | libcamera | | Camera |
l i | | Application | | (gstreamer) | | Application | | Framework |
i o \ +-------------+ +-------------+ +-------------+ +-------------+
n ^ ^ ^ ^
| | | |
l a | | | |
i d v v | v
b a / +-------------+ +-------------+ | +-------------+
c p | | V4L2 | | Camera | | | Android |
a t | | Compat. | | Framework | | | Camera |
m a | | | | (gstreamer) | | | HAL |
e t \ +-------------+ +-------------+ | +-------------+
r i ^ ^ | ^
a o | | | |
n | | | |
/ | ,................................................
| | ! : Language : !
l f | | ! : Bindings : !
i r | | ! : (optional) : !
b a | | \...............................................'
c m | | | | |
a e | | | | |
m w | v v v v
e o | +----------------------------------------------------------------+
r r | | |
a k | | libcamera |
| | |
\ +----------------------------------------------------------------+
^ ^ ^
Userspace | | |
------------------------ | ---------------- | ---------------- | ---------------
Kernel | | |
v v v
+-----------+ +-----------+ +-----------+
| Media | <--> | Video | <--> | V4L2 |
| Device | | Device | | Subdev |
+-----------+ +-----------+ +-----------+
The camera stack comprises four software layers. From bottom to top:
* The kernel drivers control the camera hardware and expose a
low-level interface to userspace through the Linux kernel V4L2
family of APIs (Media Controller API, V4L2 Video Device API and
V4L2 Subdev API).
* The libcamera framework is the core part of the stack. It
handles all control of the camera devices in its core component,
libcamera, and exposes a native C++ API to upper layers. Optional
language bindings allow interfacing to libcamera from other
programming languages.
Those components live in the same source code repository and
all together constitute the libcamera framework.
* The libcamera adaptation is an umbrella term designating the
components that interface to libcamera in other frameworks.
Notable examples are a V4L2 compatibility layer, a gstreamer
libcamera element, and an Android camera HAL implementation based
on libcamera.
Those components can live in the libcamera project source code
in separate repositories, or move to their respective project's
repository (for instance the gstreamer libcamera element).
* The applications and upper level frameworks are based on the
libcamera framework or libcamera adaptation, and are outside of
the scope of the libcamera project.
V4L2 Compatibility Layer
V4L2 compatibility is achieved through a shared library that traps all
accesses to camera devices and routes them to libcamera to emulate high-level
V4L2 camera devices. It is injected in a process address space through
``LD_PRELOAD`` and is completely transparent for applications.
The compatibility layer exposes camera device features on a best-effort basis,
and aims for the level of features traditionally available from a UVC camera
designed for video conferencing.
Android Camera HAL
Camera support for Android is achieved through a generic Android camera HAL
implementation on top of libcamera. The HAL implements features required by
Android and out of scope from libcamera, such as JPEG encoding support.
This component is used to provide support for ChromeOS platforms.
GStreamer element (gstlibcamerasrc)
A `GStreamer element`_ is provided to allow capture from libcamera supported
devices through GStreamer pipelines, and connect to other elements for further
processing.
Native libcamera API
Applications can make use of the libcamera API directly using the C++
API. An example application and walkthrough using the libcamera API can be
followed in the :doc:`Application writer's guide </guides/application-developer>`
.. _GStreamer element: https://gstreamer.freedesktop.org/documentation/application-development/basics/elements.html
Licensing
=========
The libcamera core is covered by the `LGPL-2.1-or-later`_ license. Pipeline
Handlers are a part of the libcamera code base and need to be contributed
upstream by device vendors. IPA modules included in libcamera are covered by a
free software license, however third-parties may develop IPA modules outside of
libcamera and distribute them under a closed-source license, provided they do
not include source code from the libcamera project.
The libcamera project itself contains multiple libraries, applications and
utilities. Licenses are expressed through SPDX tags in text-based files that
support comments, and through the .reuse/dep5 file otherwise. A copy of all
licenses are stored in the LICENSES directory, and a full summary of the
licensing used throughout the project can be found in the COPYING.rst document.
Applications which link dynamically against libcamera and use only the public
API are an independent work of the authors and have no license restrictions
imposed upon them from libcamera.
.. _LGPL-2.1-or-later: https://spdx.org/licenses/LGPL-2.1-or-later.html

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _lens-driver-requirements:
Lens Driver Requirements

View file

@ -0,0 +1,168 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
libcamera Architecture
======================
While offering a unified API towards upper layers, and presenting itself as a
single library, libcamera isn't monolithic. It exposes multiple components
through its public API and is built around a set of separate helpers internally.
Hardware abstractions are handled through the use of device-specific components
where required and dynamically loadable plugins are used to separate image
processing algorithms from the core libcamera codebase.
::
--------------------------< libcamera Public API >---------------------------
^ ^
| |
v v
+-------------+ +---------------------------------------------------+
| Camera | | Camera Device |
| Manager | | +-----------------------------------------------+ |
+-------------+ | | Device-Agnostic | |
^ | | | |
| | | +--------------------------+ |
| | | | ~~~~~~~~~~~~~~~~~~~~~~~ |
| | | | { +-----------------+ } |
| | | | } | //// Image //// | { |
| | | | <-> | / Processing // | } |
| | | | } | / Algorithms // | { |
| | | | { +-----------------+ } |
| | | | ~~~~~~~~~~~~~~~~~~~~~~~ |
| | | | ========================== |
| | | | +-----------------+ |
| | | | | // Pipeline /// | |
| | | | <-> | /// Handler /// | |
| | | | | /////////////// | |
| | +--------------------+ +-----------------+ |
| | Device-Specific |
| +---------------------------------------------------+
| ^ ^
| | |
v v v
+--------------------------------------------------------------------+
| Helpers and Support Classes |
| +-------------+ +-------------+ +-------------+ +-------------+ |
| | MC & V4L2 | | Buffers | | Sandboxing | | Plugins | |
| | Support | | Allocator | | IPC | | Manager | |
| +-------------+ +-------------+ +-------------+ +-------------+ |
| +-------------+ +-------------+ |
| | Pipeline | | ... | |
| | Runner | | | |
| +-------------+ +-------------+ |
+--------------------------------------------------------------------+
/// Device-Specific Components
~~~ Sandboxing
Camera Manager
The Camera Manager enumerates cameras and instantiates Pipeline Handlers to
manage each Camera that libcamera supports. The Camera Manager supports
hotplug detection and notification events when supported by the underlying
kernel devices.
There is only ever one instance of the Camera Manager running per application.
Each application's instance of the Camera Manager ensures that only a single
application can take control of a camera device at once.
Read the `Camera Manager API`_ documentation for more details.
.. _Camera Manager API: https://libcamera.org/api-html/classlibcamera_1_1CameraManager.html
Camera Device
The Camera class represents a single item of camera hardware that is capable
of producing one or more image streams, and provides the API to interact with
the underlying device.
If a system has multiple instances of the same hardware attached, each has its
own instance of the camera class.
The API exposes full control of the device to upper layers of libcamera through
the public API, making it the highest level object libcamera exposes, and the
object that all other API operations interact with from configuration to
capture.
Read the `Camera API`_ documentation for more details.
.. _Camera API: https://libcamera.org/api-html/classlibcamera_1_1Camera.html
Pipeline Handler
The Pipeline Handler manages the complex pipelines exposed by the kernel
drivers through the Media Controller and V4L2 APIs. It abstracts pipeline
handling to hide device-specific details from the rest of the library, and
implements both pipeline configuration based on stream configuration, and
pipeline runtime execution and scheduling when needed by the device.
The Pipeline Handler lives in the same process as the rest of the library, and
has access to all helpers and kernel camera-related devices.
Hardware abstraction is handled by device specific Pipeline Handlers which are
derived from the Pipeline Handler base class allowing commonality to be shared
among the implementations.
Derived pipeline handlers create Camera device instances based on the devices
they detect and support on the running system, and are responsible for
managing the interactions with a camera device.
More details can be found in the `PipelineHandler API`_ documentation, and the
:doc:`Pipeline Handler Writers Guide <guides/pipeline-handler>`.
.. _PipelineHandler API: https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html
Image Processing Algorithms
Together with the hardware image processing and hardware statistics
collection, the Image Processing Algorithms (IPA) implement 3A (Auto-Exposure,
Auto-White Balance and Auto-Focus) and other algorithms. They run on the CPU
and control hardware image processing based on the parameters supplied by
upper layers, closing the control loop of the ISP.
IPAs are loaded as external plugins named IPA Modules. IPA Modules can be part
of the libcamera code base or provided externally by camera vendors as
open-source or closed-source components.
Open source IPA Modules built with libcamera are run in the same process space
as libcamera. External IPA Modules are run in a separate sandboxed process. In
either case, they can only interact with libcamera through the API provided by
the Pipeline Handler. They have a restricted view of the system, with no direct
access to kernel camera devices, no access to networking APIs, and limited
access to file systems. All their accesses to image and metadata are mediated
by dmabuf instances explicitly passed by the Pipeline Handler to the IPA
Module.
IPA Modules are only required for platforms and devices with an ISP controlled
by the host CPU. Camera sensors which have an integrated ISP are not
controlled through the IPA Module.
Helpers and Support Classes
While Pipeline Handlers are device-specific, implementations are expected to
share code due to usage of identical APIs towards the kernel camera drivers
and the Image Processing Algorithms. This includes without limitation handling
of the MC and V4L2 APIs, buffer management through dmabuf, and pipeline
discovery, configuration and scheduling. Such code will be factored out to
helpers when applicable.
Other parts of libcamera will also benefit from factoring code out to
self-contained support classes, even if such code is present only once in the
code base, in order to keep the source code clean and easy to read. This
should be the case for instance for plugin management.
Platform Support
----------------
The library currently supports the following hardware platforms specifically
with dedicated pipeline handlers:
- Arm Mali-C55
- Intel IPU3 (ipu3)
- NXP i.MX8MP (imx8-isi and rkisp1)
- RaspberryPi 3, 4 and zero (rpi/vc4)
- Rockchip RK3399 (rkisp1)
Furthermore, generic platform support is provided for the following:
- USB video device class cameras (uvcvideo)
- iMX7, IPU6, Allwinner Sun6i (simple)
- Virtual media controller driver for test use cases (vimc)

View file

@ -0,0 +1,33 @@
/**
\mainpage libcamera API reference
Welcome to the API reference for <a href="https://libcamera.org/">libcamera</a>,
a complex camera support library for Linux, Android and ChromeOS. These pages
are automatically generated from the libcamera source code and describe the API
in detail - if this is your first interaction with libcamera then you may find
it useful to visit the [documentation](../introduction.html) in
the first instance, which can provide a more generic introduction to the
library's concepts.
\if internal
As a follow-on to the developer's guide, to assist you in adding support for
your platform the [pipeline handler writer's guide](../guides/pipeline-handler.html)
and the [ipa module writer's guide](../guides/ipa.html) should be helpful.
The full libcamera API is documented here. If you wish to see only the public
part of the API you can use [these pages](../api-html/index.html) instead.
\else
As a follow-on to the developer's guide, to assist you in using libcamera within
your project the [application developer's guide](../guides/application-developer.html)
gives an overview on how to achieve that.
Only the public part of the libcamera API is documented here; if you are a
developer seeking to add support for your hardware to the library or make other
improvements, you should switch to the internal API
[reference pages](../internal-api-html/index.html) instead.
\endif
*/

View file

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: CC-BY-SA-4.0 */
digraph board {
rankdir=TB
n00000001 [label="{{} | mali-c55 tpg\n/dev/v4l-subdev0 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
n00000001:port0 -> n00000003:port0 [style=dashed]
n00000003 [label="{{<port0> 0 | <port4> 4} | mali-c55 isp\n/dev/v4l-subdev1 | {<port1> 1 | <port2> 2 | <port3> 3}}", shape=Mrecord, style=filled, fillcolor=green]
n00000003:port1 -> n00000009:port0 [style=bold]
n00000003:port2 -> n00000009:port2 [style=bold]
n00000003:port1 -> n0000000d:port0 [style=bold]
n00000003:port3 -> n0000001c
n00000009 [label="{{<port0> 0 | <port2> 2} | mali-c55 resizer fr\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
n00000009:port1 -> n00000010
n0000000d [label="{{<port0> 0} | mali-c55 resizer ds\n/dev/v4l-subdev3 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
n0000000d:port1 -> n00000014
n00000010 [label="mali-c55 fr\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
n00000014 [label="mali-c55 ds\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
n00000018 [label="mali-c55 3a params\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
n00000018 -> n00000003:port4
n0000001c [label="mali-c55 3a stats\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
n00000030 [label="{{<port0> 0} | lte-csi2-rx\n/dev/v4l-subdev4 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
n00000030:port1 -> n00000003:port0
n00000035 [label="{{} | imx415 1-001a\n/dev/v4l-subdev5 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
n00000035:port0 -> n00000030:port0 [style=bold]
}

View file

@ -24,44 +24,100 @@ if doxygen.found() and dot.found()
cdata.set('PREDEFINED', ' \\\n\t\t\t '.join(doxygen_predefined))
doxyfile = configure_file(input : 'Doxyfile.in',
output : 'Doxyfile',
configuration : cdata)
doxyfile_common = configure_file(input : 'Doxyfile-common.in',
output : 'Doxyfile-common',
configuration : cdata)
doxygen_input = [
doxyfile,
libcamera_base_headers,
libcamera_base_sources,
doxygen_public_input = [
libcamera_base_public_headers,
libcamera_base_public_sources,
libcamera_public_headers,
libcamera_public_sources,
]
doxygen_internal_input = [
libcamera_base_private_headers,
libcamera_base_internal_sources,
libcamera_internal_headers,
libcamera_internal_sources,
libcamera_ipa_headers,
libcamera_ipa_interfaces,
libcamera_public_headers,
libcamera_sources,
libipa_headers,
libipa_sources,
]
if is_variable('ipu3_ipa_sources')
doxygen_input += [ipu3_ipa_sources]
doxygen_internal_input += [ipu3_ipa_sources]
endif
custom_target('doxygen',
input : doxygen_input,
# We run doxygen twice - the first run excludes internal API objects as it
# is intended to document the public API only. A second run covers all of
# the library's objects for libcamera developers. Common configuration is
# set in an initially generated Doxyfile, which is then included by the two
# final Doxyfiles.
# This is the "public" run of doxygen generating an abridged version of the
# API's documentation.
doxyfile_tmpl = configure_file(input : 'Doxyfile-public.in',
output : 'Doxyfile-public.tmpl',
configuration : cdata)
# The set of public input files stored in the doxygen_public_input array
# needs to be set in Doxyfile public. We can't pass them through cdata
# cdata, as some of the array members are custom_tgt instances, which
# configuration_data.set() doesn't support. Using a separate script invoked
# through custom_target(), which supports custom_tgt instances as inputs.
doxyfile = custom_target('doxyfile-public',
input : [
doxygen_public_input,
],
output : 'Doxyfile-public',
command : [
'gen-doxyfile.py',
'-o', '@OUTPUT@',
doxyfile_tmpl,
'@INPUT@',
])
custom_target('doxygen-public',
input : [
doxyfile,
doxyfile_common,
],
output : 'api-html',
command : [doxygen, doxyfile],
install : true,
install_dir : doc_install_dir,
install_tag : 'doc')
# This is the internal documentation, which hard-codes a list of directories
# to parse in its doxyfile.
doxyfile = configure_file(input : 'Doxyfile-internal.in',
output : 'Doxyfile-internal',
configuration : cdata)
custom_target('doxygen-internal',
input : [
doxyfile,
doxyfile_common,
doxygen_internal_input,
],
output : 'internal-api-html',
command : [doxygen, doxyfile],
install : true,
install_dir : doc_install_dir,
install_tag : 'doc-internal')
endif
#
# Sphinx
#
sphinx = find_program('sphinx-build-3', required : false)
if not sphinx.found()
sphinx = find_program('sphinx-build', required : get_option('documentation'))
endif
sphinx = find_program('sphinx-build-3', 'sphinx-build',
required : get_option('documentation'))
if sphinx.found()
docs_sources = [
@ -70,15 +126,19 @@ if sphinx.found()
'coding-style.rst',
'conf.py',
'contributing.rst',
'docs.rst',
'design/ae.rst',
'documentation-contents.rst',
'environment_variables.rst',
'feature_requirements.rst',
'guides/application-developer.rst',
'guides/introduction.rst',
'guides/ipa.rst',
'guides/pipeline-handler.rst',
'guides/tracing.rst',
'index.rst',
'introduction.rst',
'lens_driver_requirements.rst',
'libcamera_architecture.rst',
'mali-c55.dot',
'python-bindings.rst',
'sensor_driver_requirements.rst',
'software-isp-benchmarking.rst',

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _python-bindings:
Python Bindings for libcamera

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _sensor-driver-requirements:
Sensor Driver Requirements

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _software-isp-benchmarking:
Software ISP benchmarking

View file

@ -283,9 +283,13 @@ div#signature {
font-size: 12px;
}
#libcamera div.toctree-wrapper {
#licensing div.toctree-wrapper {
height: 0px;
margin: 0px;
padding: 0px;
visibility: hidden;
}
.documentation-nav {
display: none;
}

View file

@ -0,0 +1,44 @@
/**
* \page thread-safety Reentrancy and Thread-Safety
*
* Through the documentation, several terms are used to define how classes and
* their member functions can be used from multiple threads.
*
* - A **reentrant** function may be called simultaneously from multiple
* threads if and only if each invocation uses a different instance of the
* class. This is the default for all member functions not explictly marked
* otherwise.
*
* - \anchor thread-safe A **thread-safe** function may be called
* simultaneously from multiple threads on the same instance of a class. A
* thread-safe function is thus reentrant. Thread-safe functions may also be
* called simultaneously with any other reentrant function of the same class
* on the same instance.
*
* \internal
* - \anchor thread-bound A **thread-bound** function may be called only from
* the thread that the class instances lives in (see section \ref
* thread-objects). For instances of classes that do not derive from the
* Object class, this is the thread in which the instance was created. A
* thread-bound function is not thread-safe, and may or may not be reentrant.
* \endinternal
*
* Neither reentrancy nor thread-safety, in this context, mean that a function
* may be called simultaneously from the same thread, for instance from a
* callback invoked by the function. This may deadlock and isn't allowed unless
* separately documented.
*
* \if internal
* A class is defined as reentrant, thread-safe or thread-bound if all its
* member functions are reentrant, thread-safe or thread-bound respectively.
* \else
* A class is defined as reentrant or thread-safe if all its member functions
* are reentrant or thread-safe respectively.
* \endif
* Some member functions may additionally be documented as having additional
* thread-related attributes.
*
* Most classes are reentrant but not thread-safe, as making them fully
* thread-safe would incur locking costs considered prohibitive for the
* expected use cases.
*/

View file

@ -1,7 +1,5 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. section-begin-libcamera
===========
libcamera
===========
@ -22,7 +20,6 @@ open-source-friendly while still protecting vendor core IP. libcamera was born
out of that collaboration and will offer modern camera support to Linux-based
systems, including traditional Linux distributions, ChromeOS and Android.
.. section-end-libcamera
.. section-begin-getting-started
Getting Started
@ -47,7 +44,7 @@ A C++ toolchain: [required]
Either {g++, clang}
Meson Build system: [required]
meson (>= 0.60) ninja-build pkg-config
meson (>= 0.63) ninja-build pkg-config
for the libcamera core: [required]
libyaml-dev python3-yaml python3-ply python3-jinja2
@ -86,9 +83,10 @@ for cam: [optional]
- libdrm-dev: Enables the KMS sink
- libjpeg-dev: Enables MJPEG on the SDL sink
- libsdl2-dev: Enables the SDL sink
- libtiff-dev: Enables writing DNG
for qcam: [optional]
libtiff-dev qtbase5-dev qttools5-dev-tools
libtiff-dev qt6-base-dev
for tracing with lttng: [optional]
liblttng-ust-dev python3-jinja2 lttng-tools
@ -96,9 +94,6 @@ for tracing with lttng: [optional]
for android: [optional]
libexif-dev libjpeg-dev
for Python bindings: [optional]
pybind11-dev
for lc-compliance: [optional]
libevent-dev libgtest-dev
@ -178,6 +173,22 @@ Which can be received on another device over the network with:
gst-launch-1.0 tcpclientsrc host=$DEVICE_IP port=5000 ! \
multipartdemux ! jpegdec ! autovideosink
The GStreamer element also supports multiple streams. This is achieved by
requesting additional source pads. Downstream caps filters can be used
to choose specific parameters like resolution and pixel format. The pad
property ``stream-role`` can be used to select a role.
The following example displays a 640x480 view finder while streaming JPEG
encoded 800x600 video. You can use the receiver pipeline above to view the
remote stream from another device.
.. code::
gst-launch-1.0 libcamerasrc name=cs src::stream-role=view-finder src_0::stream-role=video-recording \
cs.src ! queue ! video/x-raw,width=640,height=480 ! videoconvert ! autovideosink \
cs.src_0 ! queue ! video/x-raw,width=800,height=600 ! videoconvert ! \
jpegenc ! multipartmux ! tcpserversink host=0.0.0.0 port=5000
.. section-end-getting-started
Troubleshooting

View file

@ -98,21 +98,15 @@ public:
using PackType = BoundMethodPack<R, Args...>;
private:
template<std::size_t... I, typename T = R>
std::enable_if_t<!std::is_void<T>::value, void>
invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>)
template<std::size_t... I>
void invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>)
{
PackType *args = static_cast<PackType *>(pack);
args->ret_ = invoke(std::get<I>(args->args_)...);
}
[[maybe_unused]] auto *args = static_cast<PackType *>(pack);
template<std::size_t... I, typename T = R>
std::enable_if_t<std::is_void<T>::value, void>
invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>)
{
/* args is effectively unused when the sequence I is empty. */
PackType *args [[gnu::unused]] = static_cast<PackType *>(pack);
invoke(std::get<I>(args->args_)...);
if constexpr (!std::is_void_v<R>)
args->ret_ = invoke(std::get<I>(args->args_)...);
else
invoke(std::get<I>(args->args_)...);
}
public:

View file

@ -1,14 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2021, Google Inc.
*
* Compiler support
*/
#pragma once
#if __cplusplus >= 201703L
#define __nodiscard [[nodiscard]]
#else
#define __nodiscard
#endif

View file

@ -7,8 +7,6 @@
#pragma once
#include <vector>
#include <libcamera/base/private.h>
namespace libcamera {

View file

@ -7,10 +7,10 @@
#pragma once
#include <sys/types.h>
#include <map>
#include <stdint.h>
#include <string>
#include <sys/types.h>
#include <libcamera/base/private.h>

View file

@ -7,8 +7,9 @@
#pragma once
#include <chrono>
#include <atomic>
#include <sstream>
#include <string_view>
#include <libcamera/base/private.h>
@ -29,25 +30,29 @@ enum LogSeverity {
class LogCategory
{
public:
static LogCategory *create(const char *name);
static LogCategory *create(std::string_view name);
const std::string &name() const { return name_; }
LogSeverity severity() const { return severity_; }
void setSeverity(LogSeverity severity);
LogSeverity severity() const { return severity_.load(std::memory_order_relaxed); }
void setSeverity(LogSeverity severity) { severity_.store(severity, std::memory_order_relaxed); }
static const LogCategory &defaultCategory();
private:
explicit LogCategory(const char *name);
friend class Logger;
explicit LogCategory(std::string_view name);
const std::string name_;
LogSeverity severity_;
std::atomic<LogSeverity> severity_;
static_assert(decltype(severity_)::is_always_lock_free);
};
#define LOG_DECLARE_CATEGORY(name) \
extern const LogCategory &_LOG_CATEGORY(name)();
#define LOG_DEFINE_CATEGORY(name) \
LOG_DECLARE_CATEGORY(name) \
const LogCategory &_LOG_CATEGORY(name)() \
{ \
/* The instance will be deleted by the Logger destructor. */ \
@ -60,9 +65,7 @@ class LogMessage
public:
LogMessage(const char *fileName, unsigned int line,
const LogCategory &category, LogSeverity severity,
const std::string &prefix = std::string());
LogMessage(LogMessage &&);
std::string prefix = {});
~LogMessage();
std::ostream &stream() { return msgStream_; }
@ -75,9 +78,7 @@ public:
const std::string msg() const { return msgStream_.str(); }
private:
LIBCAMERA_DISABLE_COPY(LogMessage)
void init(const char *fileName, unsigned int line);
LIBCAMERA_DISABLE_COPY_AND_MOVE(LogMessage)
std::ostringstream msgStream_;
const LogCategory &category_;

View file

@ -0,0 +1,32 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2024, Ideas on Board Oy
*
* Anonymous file creation
*/
#pragma once
#include <libcamera/base/flags.h>
#include <libcamera/base/unique_fd.h>
namespace libcamera {
class MemFd
{
public:
enum class Seal {
None = 0,
Shrink = (1 << 0),
Grow = (1 << 1),
};
using Seals = Flags<Seal>;
static UniqueFD create(const char *name, std::size_t size,
Seals seals = Seal::None);
};
LIBCAMERA_FLAGS_ENABLE_OPERATORS(MemFd::Seal)
} /* namespace libcamera */

View file

@ -5,7 +5,6 @@ libcamera_base_include_dir = libcamera_include_dir / 'base'
libcamera_base_public_headers = files([
'bound_method.h',
'class.h',
'compiler.h',
'flags.h',
'object.h',
'shared_fd.h',
@ -21,6 +20,7 @@ libcamera_base_private_headers = files([
'event_notifier.h',
'file.h',
'log.h',
'memfd.h',
'message.h',
'mutex.h',
'private.h',

View file

@ -23,10 +23,6 @@ namespace libcamera {
class LIBCAMERA_TSA_CAPABILITY("mutex") Mutex final
{
public:
constexpr Mutex()
{
}
void lock() LIBCAMERA_TSA_ACQUIRE()
{
mutex_.lock();
@ -84,10 +80,6 @@ private:
class ConditionVariable final
{
public:
ConditionVariable()
{
}
void notify_one() noexcept
{
cv_.notify_one();

View file

@ -9,9 +9,11 @@
#include <list>
#include <memory>
#include <utility>
#include <vector>
#include <libcamera/base/bound_method.h>
#include <libcamera/base/class.h>
namespace libcamera {
@ -38,7 +40,7 @@ public:
{
T *obj = static_cast<T *>(this);
auto *method = new BoundMethodMember<T, R, FuncArgs...>(obj, this, func, type);
return method->activate(args..., true);
return method->activate(std::forward<Args>(args)..., true);
}
Thread *thread() const { return thread_; }
@ -52,6 +54,8 @@ protected:
bool assertThreadBound(const char *message);
private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(Object)
friend class SignalBase;
friend class Thread;

View file

@ -10,7 +10,6 @@
#include <functional>
#include <list>
#include <type_traits>
#include <vector>
#include <libcamera/base/bound_method.h>
@ -64,11 +63,8 @@ public:
#ifndef __DOXYGEN__
template<typename T, typename Func,
std::enable_if_t<std::is_base_of<Object, T>::value
#if __cplusplus >= 201703L
&& std::is_invocable_v<Func, Args...>
#endif
> * = nullptr>
std::enable_if_t<std::is_base_of<Object, T>::value &&
std::is_invocable_v<Func, Args...>> * = nullptr>
void connect(T *obj, Func func, ConnectionType type = ConnectionTypeAuto)
{
Object *object = static_cast<Object *>(obj);
@ -76,11 +72,8 @@ public:
}
template<typename T, typename Func,
std::enable_if_t<!std::is_base_of<Object, T>::value
#if __cplusplus >= 201703L
&& std::is_invocable_v<Func, Args...>
#endif
> * = nullptr>
std::enable_if_t<!std::is_base_of<Object, T>::value &&
std::is_invocable_v<Func, Args...>> * = nullptr>
#else
template<typename T, typename Func>
#endif

View file

@ -10,7 +10,6 @@
#include <array>
#include <iterator>
#include <limits>
#include <stddef.h>
#include <type_traits>
namespace libcamera {
@ -347,13 +346,7 @@ public:
}
constexpr Span(const Span &other) noexcept = default;
constexpr Span &operator=(const Span &other) noexcept
{
data_ = other.data_;
size_ = other.size_;
return *this;
}
constexpr Span &operator=(const Span &other) noexcept = default;
constexpr iterator begin() const { return data(); }
constexpr const_iterator cbegin() const { return begin(); }

View file

@ -13,8 +13,10 @@
#include <libcamera/base/private.h>
#include <libcamera/base/class.h>
#include <libcamera/base/message.h>
#include <libcamera/base/signal.h>
#include <libcamera/base/span.h>
#include <libcamera/base/utils.h>
namespace libcamera {
@ -35,6 +37,8 @@ public:
void exit(int code = 0);
bool wait(utils::duration duration = utils::duration::max());
int setThreadAffinity(const Span<const unsigned int> &cpus);
bool isRunning();
Signal<> finished;
@ -44,16 +48,21 @@ public:
EventDispatcher *eventDispatcher();
void dispatchMessages(Message::Type type = Message::Type::None);
void dispatchMessages(Message::Type type = Message::Type::None,
Object *receiver = nullptr);
protected:
int exec();
virtual void run();
private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(Thread)
void startThread();
void finishThread();
void setThreadAffinityInternal();
void postMessage(std::unique_ptr<Message> msg, Object *receiver);
void removeMessages(Object *receiver);

View file

@ -8,7 +8,6 @@
#pragma once
#include <chrono>
#include <stdint.h>
#include <libcamera/base/private.h>

View file

@ -10,7 +10,6 @@
#include <utility>
#include <libcamera/base/class.h>
#include <libcamera/base/compiler.h>
namespace libcamera {
@ -43,7 +42,7 @@ public:
return *this;
}
__nodiscard int release()
[[nodiscard]] int release()
{
int fd = fd_;
fd_ = -1;

View file

@ -9,12 +9,13 @@
#include <algorithm>
#include <chrono>
#include <functional>
#include <iterator>
#include <memory>
#include <ostream>
#include <sstream>
#include <string>
#include <stdint.h>
#include <string.h>
#include <string>
#include <sys/time.h>
#include <type_traits>
#include <utility>
@ -90,6 +91,30 @@ template<typename T,
_hex hex(T value, unsigned int width = 0);
#ifndef __DOXYGEN__
template<>
inline _hex hex<int8_t>(int8_t value, unsigned int width)
{
return { static_cast<uint64_t>(value), width ? width : 2 };
}
template<>
inline _hex hex<uint8_t>(uint8_t value, unsigned int width)
{
return { static_cast<uint64_t>(value), width ? width : 2 };
}
template<>
inline _hex hex<int16_t>(int16_t value, unsigned int width)
{
return { static_cast<uint64_t>(value), width ? width : 4 };
}
template<>
inline _hex hex<uint16_t>(uint16_t value, unsigned int width)
{
return { static_cast<uint64_t>(value), width ? width : 4 };
}
template<>
inline _hex hex<int32_t>(int32_t value, unsigned int width)
{
@ -180,7 +205,16 @@ public:
iterator &operator++();
std::string operator*() const;
bool operator!=(const iterator &other) const;
bool operator==(const iterator &other) const
{
return pos_ == other.pos_;
}
bool operator!=(const iterator &other) const
{
return !(*this == other);
}
private:
const StringSplitter *ss_;
@ -188,8 +222,15 @@ public:
std::string::size_type next_;
};
iterator begin() const;
iterator end() const;
iterator begin() const
{
return { this, 0 };
}
iterator end() const
{
return { this, std::string::npos };
}
private:
std::string str_;
@ -375,6 +416,18 @@ constexpr std::underlying_type_t<Enum> to_underlying(Enum e) noexcept
return static_cast<std::underlying_type_t<Enum>>(e);
}
class ScopeExitActions
{
public:
~ScopeExitActions();
void operator+=(std::function<void()> &&action);
void release();
private:
std::vector<std::function<void()>> actions_;
};
} /* namespace utils */
#ifndef __DOXYGEN__

View file

@ -9,6 +9,7 @@
#include <memory>
#include <string>
#include <string_view>
#include <sys/types.h>
#include <vector>
@ -31,7 +32,7 @@ public:
void stop();
std::vector<std::shared_ptr<Camera>> cameras() const;
std::shared_ptr<Camera> get(const std::string &id);
std::shared_ptr<Camera> get(std::string_view id);
static const std::string &version() { return version_; }

View file

@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Google Inc.
*
* Control ID list
* {{mode|capitalize}} ID list
*
* This file is auto-generated. Do not edit.
*/
@ -18,18 +18,44 @@
namespace libcamera {
namespace controls {
namespace {{mode}} {
extern const ControlIdMap {{mode}};
{%- for vendor, ctrls in controls -%}
{% if vendor != 'libcamera' %}
namespace {{vendor}} {
#define LIBCAMERA_HAS_{{vendor|upper}}_VENDOR_{{mode|upper}}
{%- endif %}
{% if ctrls %}
enum {
${ids}
{%- for ctrl in ctrls %}
{{ctrl.name|snake_case|upper}} = {{ctrl.id}},
{%- endfor %}
};
{% endif %}
${controls}
{% for ctrl in ctrls -%}
{% if ctrl.is_enum -%}
enum {{ctrl.name}}Enum {
{%- for enum in ctrl.enum_values %}
{{enum.name}} = {{enum.value}},
{%- endfor %}
};
extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.name}}Values;
extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap;
{% endif -%}
extern const Control<{{ctrl.type}}> {{ctrl.name}};
{% endfor -%}
extern const ControlIdMap controls;
{% if vendor != 'libcamera' %}
} /* namespace {{vendor}} */
{% endif -%}
${vendor_controls}
} /* namespace controls */
{% endfor %}
} /* namespace {{mode}} */
} /* namespace libcamera */

View file

@ -8,6 +8,7 @@
#pragma once
#include <assert.h>
#include <map>
#include <optional>
#include <set>
#include <stdint.h>
@ -16,6 +17,7 @@
#include <vector>
#include <libcamera/base/class.h>
#include <libcamera/base/flags.h>
#include <libcamera/base/span.h>
#include <libcamera/geometry.h>
@ -28,67 +30,102 @@ enum ControlType {
ControlTypeNone,
ControlTypeBool,
ControlTypeByte,
ControlTypeUnsigned16,
ControlTypeUnsigned32,
ControlTypeInteger32,
ControlTypeInteger64,
ControlTypeFloat,
ControlTypeString,
ControlTypeRectangle,
ControlTypeSize,
ControlTypePoint,
};
namespace details {
template<typename T>
template<typename T, typename = std::void_t<>>
struct control_type {
};
template<>
struct control_type<void> {
static constexpr ControlType value = ControlTypeNone;
static constexpr std::size_t size = 0;
};
template<>
struct control_type<bool> {
static constexpr ControlType value = ControlTypeBool;
static constexpr std::size_t size = 0;
};
template<>
struct control_type<uint8_t> {
static constexpr ControlType value = ControlTypeByte;
static constexpr std::size_t size = 0;
};
template<>
struct control_type<uint16_t> {
static constexpr ControlType value = ControlTypeUnsigned16;
static constexpr std::size_t size = 0;
};
template<>
struct control_type<uint32_t> {
static constexpr ControlType value = ControlTypeUnsigned32;
static constexpr std::size_t size = 0;
};
template<>
struct control_type<int32_t> {
static constexpr ControlType value = ControlTypeInteger32;
static constexpr std::size_t size = 0;
};
template<>
struct control_type<int64_t> {
static constexpr ControlType value = ControlTypeInteger64;
static constexpr std::size_t size = 0;
};
template<>
struct control_type<float> {
static constexpr ControlType value = ControlTypeFloat;
static constexpr std::size_t size = 0;
};
template<>
struct control_type<std::string> {
static constexpr ControlType value = ControlTypeString;
static constexpr std::size_t size = 0;
};
template<>
struct control_type<Rectangle> {
static constexpr ControlType value = ControlTypeRectangle;
static constexpr std::size_t size = 0;
};
template<>
struct control_type<Size> {
static constexpr ControlType value = ControlTypeSize;
static constexpr std::size_t size = 0;
};
template<>
struct control_type<Point> {
static constexpr ControlType value = ControlTypePoint;
static constexpr std::size_t size = 0;
};
template<typename T, std::size_t N>
struct control_type<Span<T, N>> : public control_type<std::remove_cv_t<T>> {
struct control_type<Span<T, N>, std::enable_if_t<control_type<std::remove_cv_t<T>>::size == 0>> : public control_type<std::remove_cv_t<T>> {
static constexpr std::size_t size = N;
};
template<typename T>
struct control_type<T, std::enable_if_t<std::is_enum_v<T> && sizeof(T) == sizeof(int32_t)>> : public control_type<int32_t> {
};
} /* namespace details */
@ -213,23 +250,44 @@ private:
class ControlId
{
public:
ControlId(unsigned int id, const std::string &name, ControlType type)
: id_(id), name_(name), type_(type)
{
}
enum class Direction {
In = (1 << 0),
Out = (1 << 1),
};
using DirectionFlags = Flags<Direction>;
ControlId(unsigned int id, const std::string &name, const std::string &vendor,
ControlType type, DirectionFlags direction,
std::size_t size = 0,
const std::map<std::string, int32_t> &enumStrMap = {});
unsigned int id() const { return id_; }
const std::string &name() const { return name_; }
const std::string &vendor() const { return vendor_; }
ControlType type() const { return type_; }
DirectionFlags direction() const { return direction_; }
bool isInput() const { return !!(direction_ & Direction::In); }
bool isOutput() const { return !!(direction_ & Direction::Out); }
bool isArray() const { return size_ > 0; }
std::size_t size() const { return size_; }
const std::map<int32_t, std::string> &enumerators() const { return reverseMap_; }
private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(ControlId)
unsigned int id_;
std::string name_;
std::string vendor_;
ControlType type_;
DirectionFlags direction_;
std::size_t size_;
std::map<std::string, int32_t> enumStrMap_;
std::map<int32_t, std::string> reverseMap_;
};
LIBCAMERA_FLAGS_ENABLE_OPERATORS(ControlId::Direction)
static inline bool operator==(unsigned int lhs, const ControlId &rhs)
{
return lhs == rhs.id();
@ -256,8 +314,11 @@ class Control : public ControlId
public:
using type = T;
Control(unsigned int id, const char *name)
: ControlId(id, name, details::control_type<std::remove_cv_t<T>>::value)
Control(unsigned int id, const char *name, const char *vendor,
ControlId::DirectionFlags direction,
const std::map<std::string, int32_t> &enumStrMap = {})
: ControlId(id, name, vendor, details::control_type<std::remove_cv_t<T>>::value,
direction, details::control_type<std::remove_cv_t<T>>::size, enumStrMap)
{
}

View file

@ -7,7 +7,6 @@
#pragma once
#include <assert.h>
#include <limits>
#include <memory>
#include <stdint.h>
@ -27,6 +26,7 @@ struct FrameMetadata {
FrameSuccess,
FrameError,
FrameCancelled,
FrameStartup,
};
struct Plane {

View file

@ -11,8 +11,6 @@
#include <ostream>
#include <string>
#include <libcamera/base/compiler.h>
namespace libcamera {
class Rectangle;
@ -110,8 +108,8 @@ public:
return *this;
}
__nodiscard constexpr Size alignedDownTo(unsigned int hAlignment,
unsigned int vAlignment) const
[[nodiscard]] constexpr Size alignedDownTo(unsigned int hAlignment,
unsigned int vAlignment) const
{
return {
width / hAlignment * hAlignment,
@ -119,8 +117,8 @@ public:
};
}
__nodiscard constexpr Size alignedUpTo(unsigned int hAlignment,
unsigned int vAlignment) const
[[nodiscard]] constexpr Size alignedUpTo(unsigned int hAlignment,
unsigned int vAlignment) const
{
return {
(width + hAlignment - 1) / hAlignment * hAlignment,
@ -128,7 +126,7 @@ public:
};
}
__nodiscard constexpr Size boundedTo(const Size &bound) const
[[nodiscard]] constexpr Size boundedTo(const Size &bound) const
{
return {
std::min(width, bound.width),
@ -136,7 +134,7 @@ public:
};
}
__nodiscard constexpr Size expandedTo(const Size &expand) const
[[nodiscard]] constexpr Size expandedTo(const Size &expand) const
{
return {
std::max(width, expand.width),
@ -144,7 +142,7 @@ public:
};
}
__nodiscard constexpr Size grownBy(const Size &margins) const
[[nodiscard]] constexpr Size grownBy(const Size &margins) const
{
return {
width + margins.width,
@ -152,7 +150,7 @@ public:
};
}
__nodiscard constexpr Size shrunkBy(const Size &margins) const
[[nodiscard]] constexpr Size shrunkBy(const Size &margins) const
{
return {
width > margins.width ? width - margins.width : 0,
@ -160,10 +158,10 @@ public:
};
}
__nodiscard Size boundedToAspectRatio(const Size &ratio) const;
__nodiscard Size expandedToAspectRatio(const Size &ratio) const;
[[nodiscard]] Size boundedToAspectRatio(const Size &ratio) const;
[[nodiscard]] Size expandedToAspectRatio(const Size &ratio) const;
__nodiscard Rectangle centeredTo(const Point &center) const;
[[nodiscard]] Rectangle centeredTo(const Point &center) const;
Size operator*(float factor) const;
Size operator/(float factor) const;
@ -262,6 +260,15 @@ public:
{
}
constexpr Rectangle(const Point &point1, const Point &point2)
: Rectangle(std::min(point1.x, point2.x), std::min(point1.y, point2.y),
static_cast<unsigned int>(std::max(point1.x, point2.x)) -
static_cast<unsigned int>(std::min(point1.x, point2.x)),
static_cast<unsigned int>(std::max(point1.y, point2.y)) -
static_cast<unsigned int>(std::min(point1.y, point2.y)))
{
}
int x;
int y;
unsigned int width;
@ -285,11 +292,14 @@ public:
Rectangle &scaleBy(const Size &numerator, const Size &denominator);
Rectangle &translateBy(const Point &point);
__nodiscard Rectangle boundedTo(const Rectangle &bound) const;
__nodiscard Rectangle enclosedIn(const Rectangle &boundary) const;
__nodiscard Rectangle scaledBy(const Size &numerator,
const Size &denominator) const;
__nodiscard Rectangle translatedBy(const Point &point) const;
[[nodiscard]] Rectangle boundedTo(const Rectangle &bound) const;
[[nodiscard]] Rectangle enclosedIn(const Rectangle &boundary) const;
[[nodiscard]] Rectangle scaledBy(const Size &numerator,
const Size &denominator) const;
[[nodiscard]] Rectangle translatedBy(const Point &point) const;
Rectangle transformedBetween(const Rectangle &source,
const Rectangle &target) const;
};
bool operator==(const Rectangle &lhs, const Rectangle &rhs);

View file

@ -11,6 +11,7 @@
#include <list>
#include <memory>
#include <set>
#include <stdint.h>
#include <string>
#include <libcamera/base/class.h>
@ -32,6 +33,7 @@ public:
~Private();
PipelineHandler *pipe() { return pipe_.get(); }
const PipelineHandler *pipe() const { return pipe_.get(); }
std::list<Request *> queuedRequests_;
ControlInfoMap controlInfo_;

View file

@ -7,6 +7,7 @@
#pragma once
#include <memory>
#include <stdint.h>
#include <string>
#include <libcamera/base/class.h>

View file

@ -9,7 +9,6 @@
#include <libcamera/camera_manager.h>
#include <map>
#include <memory>
#include <sys/types.h>
#include <vector>
@ -19,13 +18,14 @@
#include <libcamera/base/thread.h>
#include <libcamera/base/thread_annotations.h>
#include "libcamera/internal/ipa_manager.h"
#include "libcamera/internal/process.h"
namespace libcamera {
class Camera;
class DeviceEnumerator;
class IPAManager;
class PipelineHandlerFactoryBase;
class CameraManager::Private : public Extensible::Private, public Thread
{
@ -38,6 +38,8 @@ public:
void addCamera(std::shared_ptr<Camera> camera) LIBCAMERA_TSA_EXCLUDES(mutex_);
void removeCamera(std::shared_ptr<Camera> camera) LIBCAMERA_TSA_EXCLUDES(mutex_);
IPAManager *ipaManager() const { return ipaManager_.get(); }
protected:
void run() override;
@ -62,7 +64,7 @@ private:
std::unique_ptr<DeviceEnumerator> enumerator_;
IPAManager ipaManager_;
std::unique_ptr<IPAManager> ipaManager_;
ProcessManager processManager_;
};

View file

@ -8,11 +8,12 @@
#pragma once
#include <memory>
#include <stdint.h>
#include <string>
#include <variant>
#include <vector>
#include <libcamera/base/class.h>
#include <libcamera/base/log.h>
#include <libcamera/control_ids.h>
#include <libcamera/controls.h>
@ -20,10 +21,8 @@
#include <libcamera/orientation.h>
#include <libcamera/transform.h>
#include <libcamera/ipa/core_ipa_interface.h>
#include "libcamera/internal/bayer_format.h"
#include "libcamera/internal/formats.h"
#include "libcamera/internal/camera_sensor_properties.h"
#include "libcamera/internal/v4l2_subdevice.h"
namespace libcamera {
@ -32,95 +31,101 @@ class CameraLens;
class MediaEntity;
class SensorConfiguration;
struct CameraSensorProperties;
enum class Orientation;
class CameraSensor : protected Loggable
struct IPACameraSensorInfo;
class CameraSensor
{
public:
explicit CameraSensor(const MediaEntity *entity);
~CameraSensor();
virtual ~CameraSensor();
int init();
virtual const std::string &model() const = 0;
virtual const std::string &id() const = 0;
const std::string &model() const { return model_; }
const std::string &id() const { return id_; }
virtual const MediaEntity *entity() const = 0;
virtual V4L2Subdevice *device() = 0;
const MediaEntity *entity() const { return entity_; }
V4L2Subdevice *device() { return subdev_.get(); }
virtual CameraLens *focusLens() = 0;
CameraLens *focusLens() { return focusLens_.get(); }
virtual const std::vector<unsigned int> &mbusCodes() const = 0;
virtual std::vector<Size> sizes(unsigned int mbusCode) const = 0;
virtual Size resolution() const = 0;
const std::vector<unsigned int> &mbusCodes() const { return mbusCodes_; }
std::vector<Size> sizes(unsigned int mbusCode) const;
Size resolution() const;
virtual V4L2SubdeviceFormat
getFormat(const std::vector<unsigned int> &mbusCodes,
const Size &size, const Size maxSize = Size()) const = 0;
virtual int setFormat(V4L2SubdeviceFormat *format,
Transform transform = Transform::Identity) = 0;
virtual int tryFormat(V4L2SubdeviceFormat *format) const = 0;
V4L2SubdeviceFormat getFormat(const std::vector<unsigned int> &mbusCodes,
const Size &size) const;
int setFormat(V4L2SubdeviceFormat *format,
Transform transform = Transform::Identity);
int tryFormat(V4L2SubdeviceFormat *format) const;
virtual int applyConfiguration(const SensorConfiguration &config,
Transform transform = Transform::Identity,
V4L2SubdeviceFormat *sensorFormat = nullptr) = 0;
int applyConfiguration(const SensorConfiguration &config,
Transform transform = Transform::Identity,
V4L2SubdeviceFormat *sensorFormat = nullptr);
virtual V4L2Subdevice::Stream imageStream() const;
virtual std::optional<V4L2Subdevice::Stream> embeddedDataStream() const;
virtual V4L2SubdeviceFormat embeddedDataFormat() const;
virtual int setEmbeddedDataEnabled(bool enable);
const ControlList &properties() const { return properties_; }
int sensorInfo(IPACameraSensorInfo *info) const;
Transform computeTransform(Orientation *orientation) const;
BayerFormat::Order bayerOrder(Transform t) const;
virtual const ControlList &properties() const = 0;
virtual int sensorInfo(IPACameraSensorInfo *info) const = 0;
virtual Transform computeTransform(Orientation *orientation) const = 0;
virtual BayerFormat::Order bayerOrder(Transform t) const = 0;
const ControlInfoMap &controls() const;
ControlList getControls(const std::vector<uint32_t> &ids);
int setControls(ControlList *ctrls);
virtual const ControlInfoMap &controls() const = 0;
virtual ControlList getControls(const std::vector<uint32_t> &ids) = 0;
virtual int setControls(ControlList *ctrls) = 0;
const std::vector<controls::draft::TestPatternModeEnum> &testPatternModes() const
{
return testPatternModes_;
}
int setTestPatternMode(controls::draft::TestPatternModeEnum mode);
protected:
std::string logPrefix() const override;
private:
LIBCAMERA_DISABLE_COPY(CameraSensor)
int generateId();
int validateSensorDriver();
void initVimcDefaultProperties();
void initStaticProperties();
void initTestPatternModes();
int initProperties();
int discoverAncillaryDevices();
int applyTestPatternMode(controls::draft::TestPatternModeEnum mode);
const MediaEntity *entity_;
std::unique_ptr<V4L2Subdevice> subdev_;
unsigned int pad_;
const CameraSensorProperties *staticProps_;
std::string model_;
std::string id_;
V4L2Subdevice::Formats formats_;
std::vector<unsigned int> mbusCodes_;
std::vector<Size> sizes_;
std::vector<controls::draft::TestPatternModeEnum> testPatternModes_;
controls::draft::TestPatternModeEnum testPatternMode_;
Size pixelArraySize_;
Rectangle activeArea_;
const BayerFormat *bayerFormat_;
bool supportFlips_;
bool flipsAlterBayerOrder_;
Orientation mountingOrientation_;
ControlList properties_;
std::unique_ptr<CameraLens> focusLens_;
virtual const std::vector<controls::draft::TestPatternModeEnum> &
testPatternModes() const = 0;
virtual int setTestPatternMode(controls::draft::TestPatternModeEnum mode) = 0;
virtual const CameraSensorProperties::SensorDelays &sensorDelays() = 0;
};
class CameraSensorFactoryBase
{
public:
CameraSensorFactoryBase(const char *name, int priority);
virtual ~CameraSensorFactoryBase() = default;
static std::unique_ptr<CameraSensor> create(MediaEntity *entity);
const std::string &name() const { return name_; }
int priority() const { return priority_; }
private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(CameraSensorFactoryBase)
static std::vector<CameraSensorFactoryBase *> &factories();
static void registerFactory(CameraSensorFactoryBase *factory);
virtual std::variant<std::unique_ptr<CameraSensor>, int>
match(MediaEntity *entity) const = 0;
std::string name_;
int priority_;
};
template<typename _CameraSensor>
class CameraSensorFactory final : public CameraSensorFactoryBase
{
public:
CameraSensorFactory(const char *name, int priority)
: CameraSensorFactoryBase(name, priority)
{
}
private:
std::variant<std::unique_ptr<CameraSensor>, int>
match(MediaEntity *entity) const override
{
return _CameraSensor::match(entity);
}
};
#define REGISTER_CAMERA_SENSOR(sensor, priority) \
static CameraSensorFactory<sensor> global_##sensor##Factory{ #sensor, priority };
} /* namespace libcamera */

View file

@ -8,6 +8,7 @@
#pragma once
#include <map>
#include <stdint.h>
#include <string>
#include <libcamera/control_ids.h>
@ -16,10 +17,18 @@
namespace libcamera {
struct CameraSensorProperties {
struct SensorDelays {
uint8_t exposureDelay;
uint8_t gainDelay;
uint8_t vblankDelay;
uint8_t hblankDelay;
};
static const CameraSensorProperties *get(const std::string &sensor);
Size unitCellSize;
std::map<controls::draft::TestPatternModeEnum, int32_t> testPatternModes;
SensorDelays sensorDelays;
};
} /* namespace libcamera */

View file

@ -0,0 +1,68 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2024, Raspberry Pi Ltd
*
* Camera recovery algorithm
*/
#pragma once
#include <stdint.h>
namespace libcamera {
class ClockRecovery
{
public:
ClockRecovery();
void configure(unsigned int numSamples = 100, unsigned int maxJitter = 2000,
unsigned int minSamples = 10, unsigned int errorThreshold = 50000);
void reset();
void addSample();
void addSample(uint64_t input, uint64_t output);
uint64_t getOutput(uint64_t input);
private:
/* Approximate number of samples over which the model state persists. */
unsigned int numSamples_;
/* Remove any output jitter larger than this immediately. */
unsigned int maxJitter_;
/* Number of samples required before we start to use model estimates. */
unsigned int minSamples_;
/* Threshold above which we assume the wallclock has been reset. */
unsigned int errorThreshold_;
/* How many samples seen (up to numSamples_). */
unsigned int count_;
/* This gets subtracted from all input values, just to make the numbers easier. */
uint64_t inputBase_;
/* As above, for the output. */
uint64_t outputBase_;
/* The previous input sample. */
uint64_t lastInput_;
/* The previous output sample. */
uint64_t lastOutput_;
/* Average x value seen so far. */
double xAve_;
/* Average y value seen so far */
double yAve_;
/* Average x^2 value seen so far. */
double x2Ave_;
/* Average x*y value seen so far. */
double xyAve_;
/*
* The latest estimate of linear parameters to derive the output clock
* from the input.
*/
double slope_;
double offset_;
/* Use this cumulative error to monitor for spontaneous clock updates. */
double error_;
};
} /* namespace libcamera */

View file

@ -14,9 +14,11 @@
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include <libcamera/base/class.h>
#include <libcamera/base/flags.h>
#include <libcamera/base/signal.h>
#include <libcamera/geometry.h>
@ -26,12 +28,25 @@ namespace libcamera {
class FrameBuffer;
class MediaDevice;
class PixelFormat;
class Stream;
struct StreamConfiguration;
class Converter
{
public:
Converter(MediaDevice *media);
enum class Feature {
None = 0,
InputCrop = (1 << 0),
};
using Features = Flags<Feature>;
enum class Alignment {
Down = 0,
Up,
};
Converter(MediaDevice *media, Features features = Feature::None);
virtual ~Converter();
virtual int loadConfiguration(const std::string &filename) = 0;
@ -41,25 +56,45 @@ public:
virtual std::vector<PixelFormat> formats(PixelFormat input) = 0;
virtual SizeRange sizes(const Size &input) = 0;
virtual Size adjustInputSize(const PixelFormat &pixFmt,
const Size &size,
Alignment align = Alignment::Down) = 0;
virtual Size adjustOutputSize(const PixelFormat &pixFmt,
const Size &size,
Alignment align = Alignment::Down) = 0;
virtual std::tuple<unsigned int, unsigned int>
strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size) = 0;
virtual int validateOutput(StreamConfiguration *cfg, bool *adjusted,
Alignment align = Alignment::Down) = 0;
virtual int configure(const StreamConfiguration &inputCfg,
const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs) = 0;
virtual int exportBuffers(unsigned int output, unsigned int count,
virtual bool isConfigured(const Stream *stream) const = 0;
virtual int exportBuffers(const Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;
virtual int start() = 0;
virtual void stop() = 0;
virtual int queueBuffers(FrameBuffer *input,
const std::map<unsigned int, FrameBuffer *> &outputs) = 0;
const std::map<const Stream *, FrameBuffer *> &outputs) = 0;
virtual int setInputCrop(const Stream *stream, Rectangle *rect) = 0;
virtual std::pair<Rectangle, Rectangle> inputCropBounds() = 0;
virtual std::pair<Rectangle, Rectangle> inputCropBounds(const Stream *stream) = 0;
Signal<FrameBuffer *> inputBufferReady;
Signal<FrameBuffer *> outputBufferReady;
const std::string &deviceNode() const { return deviceNode_; }
Features features() const { return features_; }
protected:
Features features_;
private:
std::string deviceNode_;
};

View file

@ -28,7 +28,9 @@ class FrameBuffer;
class MediaDevice;
class Size;
class SizeRange;
class Stream;
struct StreamConfiguration;
class Rectangle;
class V4L2M2MDevice;
class V4L2M2MConverter : public Converter
@ -36,31 +38,45 @@ class V4L2M2MConverter : public Converter
public:
V4L2M2MConverter(MediaDevice *media);
int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; }
bool isValid() const { return m2m_ != nullptr; }
int loadConfiguration([[maybe_unused]] const std::string &filename) override { return 0; }
bool isValid() const override { return m2m_ != nullptr; }
std::vector<PixelFormat> formats(PixelFormat input);
SizeRange sizes(const Size &input);
std::vector<PixelFormat> formats(PixelFormat input) override;
SizeRange sizes(const Size &input) override;
std::tuple<unsigned int, unsigned int>
strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size);
strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size) override;
Size adjustInputSize(const PixelFormat &pixFmt,
const Size &size, Alignment align = Alignment::Down) override;
Size adjustOutputSize(const PixelFormat &pixFmt,
const Size &size, Alignment align = Alignment::Down) override;
int configure(const StreamConfiguration &inputCfg,
const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfg);
int exportBuffers(unsigned int output, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers);
const std::vector<std::reference_wrapper<StreamConfiguration>>
&outputCfg) override;
bool isConfigured(const Stream *stream) const override;
int exportBuffers(const Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start();
void stop();
int start() override;
void stop() override;
int validateOutput(StreamConfiguration *cfg, bool *adjusted,
Alignment align = Alignment::Down) override;
int queueBuffers(FrameBuffer *input,
const std::map<unsigned int, FrameBuffer *> &outputs);
const std::map<const Stream *, FrameBuffer *> &outputs) override;
int setInputCrop(const Stream *stream, Rectangle *rect) override;
std::pair<Rectangle, Rectangle> inputCropBounds() override { return inputCropBounds_; }
std::pair<Rectangle, Rectangle> inputCropBounds(const Stream *stream) override;
private:
class Stream : protected Loggable
class V4L2M2MStream : protected Loggable
{
public:
Stream(V4L2M2MConverter *converter, unsigned int index);
V4L2M2MStream(V4L2M2MConverter *converter, const Stream *stream);
bool isValid() const { return m2m_ != nullptr; }
@ -74,6 +90,11 @@ private:
int queueBuffers(FrameBuffer *input, FrameBuffer *output);
int setInputSelection(unsigned int target, Rectangle *rect);
int getInputSelection(unsigned int target, Rectangle *rect);
std::pair<Rectangle, Rectangle> inputCropBounds();
protected:
std::string logPrefix() const override;
@ -82,17 +103,23 @@ private:
void outputBufferReady(FrameBuffer *buffer);
V4L2M2MConverter *converter_;
unsigned int index_;
const Stream *stream_;
std::unique_ptr<V4L2M2MDevice> m2m_;
unsigned int inputBufferCount_;
unsigned int outputBufferCount_;
std::pair<Rectangle, Rectangle> inputCropBounds_;
};
Size adjustSizes(const Size &size, const std::vector<SizeRange> &ranges,
Alignment align);
std::unique_ptr<V4L2M2MDevice> m2m_;
std::vector<Stream> streams_;
std::map<const Stream *, std::unique_ptr<V4L2M2MStream>> streams_;
std::map<FrameBuffer *, unsigned int> queue_;
std::pair<Rectangle, Rectangle> inputCropBounds_;
};
} /* namespace libcamera */

View file

@ -0,0 +1,46 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2024, Google Inc.
*
* Debug metadata helpers
*/
#pragma once
#include <libcamera/control_ids.h>
namespace libcamera {
class DebugMetadata
{
public:
DebugMetadata() = default;
void enableByControl(const ControlList &controls);
void enable(bool enable = true);
void setParent(DebugMetadata *parent);
void moveEntries(ControlList &list);
template<typename T, typename V>
void set(const Control<T> &ctrl, const V &value)
{
if (parent_) {
parent_->set(ctrl, value);
return;
}
if (!enabled_)
return;
cache_.set(ctrl, value);
}
void set(unsigned int id, const ControlValue &value);
private:
bool enabled_ = false;
DebugMetadata *parent_ = nullptr;
ControlList cache_;
};
} /* namespace libcamera */

View file

@ -10,13 +10,15 @@
#include <stdint.h>
#include <unordered_map>
#include <libcamera/base/object.h>
#include <libcamera/controls.h>
namespace libcamera {
class V4L2Device;
class DelayedControls
class DelayedControls : public Object
{
public:
struct ControlParams {

View file

@ -7,7 +7,6 @@
#pragma once
#include <memory>
#include <string>
#include "libcamera/internal/device_enumerator.h"

View file

@ -0,0 +1,80 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2020, Raspberry Pi Ltd
*
* Helper class for dma-buf allocations.
*/
#pragma once
#include <memory>
#include <stdint.h>
#include <string>
#include <vector>
#include <libcamera/base/flags.h>
#include <libcamera/base/shared_fd.h>
#include <libcamera/base/unique_fd.h>
namespace libcamera {
class FrameBuffer;
class DmaBufAllocator
{
public:
enum class DmaBufAllocatorFlag {
CmaHeap = 1 << 0,
SystemHeap = 1 << 1,
UDmaBuf = 1 << 2,
};
using DmaBufAllocatorFlags = Flags<DmaBufAllocatorFlag>;
DmaBufAllocator(DmaBufAllocatorFlags flags = DmaBufAllocatorFlag::CmaHeap);
~DmaBufAllocator();
bool isValid() const { return providerHandle_.isValid(); }
UniqueFD alloc(const char *name, std::size_t size);
int exportBuffers(unsigned int count,
const std::vector<unsigned int> &planeSizes,
std::vector<std::unique_ptr<FrameBuffer>> *buffers);
private:
std::unique_ptr<FrameBuffer> createBuffer(
std::string name, const std::vector<unsigned int> &planeSizes);
UniqueFD allocFromHeap(const char *name, std::size_t size);
UniqueFD allocFromUDmaBuf(const char *name, std::size_t size);
UniqueFD providerHandle_;
DmaBufAllocatorFlag type_;
};
class DmaSyncer final
{
public:
enum class SyncType {
Read = 0,
Write,
ReadWrite,
};
explicit DmaSyncer(SharedFD fd, SyncType type = SyncType::ReadWrite);
DmaSyncer(DmaSyncer &&other) = default;
DmaSyncer &operator=(DmaSyncer &&other) = default;
~DmaSyncer();
private:
LIBCAMERA_DISABLE_COPY(DmaSyncer)
void sync(uint64_t step);
SharedFD fd_;
uint64_t flags_ = 0;
};
LIBCAMERA_FLAGS_ENABLE_OPERATORS(DmaBufAllocator::DmaBufAllocatorFlag)
} /* namespace libcamera */

View file

@ -1,38 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2020, Raspberry Pi Ltd
*
* Helper class for dma-heap allocations.
*/
#pragma once
#include <stddef.h>
#include <libcamera/base/flags.h>
#include <libcamera/base/unique_fd.h>
namespace libcamera {
class DmaHeap
{
public:
enum class DmaHeapFlag {
Cma = 1 << 0,
System = 1 << 1,
};
using DmaHeapFlags = Flags<DmaHeapFlag>;
DmaHeap(DmaHeapFlags flags = DmaHeapFlag::Cma);
~DmaHeap();
bool isValid() const { return dmaHeapHandle_.isValid(); }
UniqueFD alloc(const char *name, std::size_t size);
private:
UniqueFD dmaHeapHandle_;
};
LIBCAMERA_FLAGS_ENABLE_OPERATORS(DmaHeap::DmaHeapFlag)
} /* namespace libcamera */

View file

@ -8,7 +8,6 @@
#pragma once
#include <array>
#include <map>
#include <vector>
#include <libcamera/geometry.h>

View file

@ -8,6 +8,7 @@
#pragma once
#include <memory>
#include <stdint.h>
#include <utility>
#include <libcamera/base/class.h>

View file

@ -7,8 +7,7 @@
#pragma once
#include <deque>
#include <iostream>
#include <stdint.h>
#include <string.h>
#include <tuple>
#include <type_traits>
@ -20,10 +19,9 @@
#include <libcamera/control_ids.h>
#include <libcamera/framebuffer.h>
#include <libcamera/geometry.h>
#include <libcamera/ipa/ipa_interface.h>
#include "libcamera/internal/byte_stream_buffer.h"
#include "libcamera/internal/camera_sensor.h"
#include "libcamera/internal/control_serializer.h"
namespace libcamera {
@ -165,7 +163,7 @@ public:
std::vector<SharedFD>::const_iterator fdIter = fdsBegin;
for (uint32_t i = 0; i < vecLen; i++) {
uint32_t sizeofData = readPOD<uint32_t>(dataIter, 0, dataEnd);
uint32_t sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
uint32_t sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
dataIter += 8;
ret[i] = IPADataSerializer<V>::deserialize(dataIter,
@ -272,7 +270,7 @@ public:
std::vector<SharedFD>::const_iterator fdIter = fdsBegin;
for (uint32_t i = 0; i < mapLen; i++) {
uint32_t sizeofData = readPOD<uint32_t>(dataIter, 0, dataEnd);
uint32_t sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
uint32_t sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
dataIter += 8;
K key = IPADataSerializer<K>::deserialize(dataIter,
@ -284,7 +282,7 @@ public:
dataIter += sizeofData;
fdIter += sizeofFds;
sizeofData = readPOD<uint32_t>(dataIter, 0, dataEnd);
sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
sizeofFds = readPOD<uint32_t>(dataIter, 4, dataEnd);
dataIter += 8;
const V value = IPADataSerializer<V>::deserialize(dataIter,
@ -311,7 +309,6 @@ public:
serialize(const Flags<E> &data, [[maybe_unused]] ControlSerializer *cs = nullptr)
{
std::vector<uint8_t> dataVec;
dataVec.reserve(sizeof(Flags<E>));
appendPOD<uint32_t>(dataVec, static_cast<typename Flags<E>::Type>(data));
return { dataVec, {} };

View file

@ -7,6 +7,7 @@
#pragma once
#include <memory>
#include <stdint.h>
#include <vector>
@ -15,6 +16,7 @@
#include <libcamera/ipa/ipa_interface.h>
#include <libcamera/ipa/ipa_module_info.h>
#include "libcamera/internal/camera_manager.h"
#include "libcamera/internal/ipa_module.h"
#include "libcamera/internal/pipeline_handler.h"
#include "libcamera/internal/pub_key.h"
@ -34,11 +36,13 @@ public:
uint32_t minVersion,
uint32_t maxVersion)
{
IPAModule *m = self_->module(pipe, minVersion, maxVersion);
CameraManager *cm = pipe->cameraManager();
IPAManager *self = cm->_d()->ipaManager();
IPAModule *m = self->module(pipe, minVersion, maxVersion);
if (!m)
return nullptr;
std::unique_ptr<T> proxy = std::make_unique<T>(m, !self_->isSignatureValid(m));
std::unique_ptr<T> proxy = std::make_unique<T>(m, !self->isSignatureValid(m));
if (!proxy->isValid()) {
LOG(IPAManager, Error) << "Failed to load proxy";
return nullptr;
@ -55,8 +59,6 @@ public:
#endif
private:
static IPAManager *self_;
void parseDir(const char *libDir, unsigned int maxDepth,
std::vector<std::string> &files);
unsigned int addDir(const char *libDir, unsigned int maxDepth = 0);
@ -66,7 +68,7 @@ private:
bool isSignatureValid(IPAModule *ipa) const;
std::vector<IPAModule *> modules_;
std::vector<std::unique_ptr<IPAModule>> modules_;
#if HAVE_IPA_PUBKEY
static const uint8_t publicKeyData_[];

View file

@ -29,7 +29,7 @@ public:
bool isValid() const;
const struct IPAModuleInfo &info() const;
const std::vector<uint8_t> signature() const;
const std::vector<uint8_t> &signature() const;
const std::string &path() const;
bool load();

View file

@ -7,9 +7,7 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <libcamera/ipa/ipa_interface.h>
@ -31,7 +29,8 @@ public:
bool isValid() const { return valid_; }
std::string configurationFile(const std::string &file) const;
std::string configurationFile(const std::string &name,
const std::string &fallbackName = std::string()) const;
protected:
std::string resolvePath(const std::string &file) const;

View file

@ -7,6 +7,7 @@
#pragma once
#include <stdint.h>
#include <vector>
#include <libcamera/base/shared_fd.h>

View file

@ -9,7 +9,7 @@
#include <map>
#include <memory>
#include <vector>
#include <stdint.h>
#include "libcamera/internal/ipc_pipe.h"
#include "libcamera/internal/ipc_unixsocket.h"

View file

@ -0,0 +1,226 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2024, Paul Elder <paul.elder@ideasonboard.com>
*
* Matrix and related operations
*/
#pragma once
#include <algorithm>
#include <sstream>
#include <type_traits>
#include <vector>
#include <libcamera/base/log.h>
#include <libcamera/base/span.h>
#include "libcamera/internal/yaml_parser.h"
namespace libcamera {
LOG_DECLARE_CATEGORY(Matrix)
#ifndef __DOXYGEN__
template<typename T>
bool matrixInvert(Span<const T> dataIn, Span<T> dataOut, unsigned int dim,
Span<T> scratchBuffer, Span<unsigned int> swapBuffer);
#endif /* __DOXYGEN__ */
template<typename T, unsigned int Rows, unsigned int Cols>
class Matrix
{
static_assert(std::is_arithmetic_v<T>, "Matrix type must be arithmetic");
public:
constexpr Matrix()
{
}
Matrix(const std::array<T, Rows * Cols> &data)
{
std::copy(data.begin(), data.end(), data_.begin());
}
Matrix(const Span<const T, Rows * Cols> data)
{
std::copy(data.begin(), data.end(), data_.begin());
}
static constexpr Matrix identity()
{
Matrix ret;
for (size_t i = 0; i < std::min(Rows, Cols); i++)
ret[i][i] = static_cast<T>(1);
return ret;
}
~Matrix() = default;
const std::string toString() const
{
std::stringstream out;
out << "Matrix { ";
for (unsigned int i = 0; i < Rows; i++) {
out << "[ ";
for (unsigned int j = 0; j < Cols; j++) {
out << (*this)[i][j];
out << ((j + 1 < Cols) ? ", " : " ");
}
out << ((i + 1 < Rows) ? "], " : "]");
}
out << " }";
return out.str();
}
constexpr Span<const T, Rows * Cols> data() const { return data_; }
constexpr Span<const T, Cols> operator[](size_t i) const
{
return Span<const T, Cols>{ &data_.data()[i * Cols], Cols };
}
constexpr Span<T, Cols> operator[](size_t i)
{
return Span<T, Cols>{ &data_.data()[i * Cols], Cols };
}
#ifndef __DOXYGEN__
template<typename U, std::enable_if_t<std::is_arithmetic_v<U>>>
#else
template<typename U>
#endif /* __DOXYGEN__ */
Matrix<T, Rows, Cols> &operator*=(U d)
{
for (unsigned int i = 0; i < Rows * Cols; i++)
data_[i] *= d;
return *this;
}
Matrix<T, Rows, Cols> inverse(bool *ok = nullptr) const
{
static_assert(Rows == Cols, "Matrix must be square");
Matrix<T, Rows, Cols> inverse;
std::array<T, Rows * Cols * 2> scratchBuffer;
std::array<unsigned int, Rows> swapBuffer;
bool res = matrixInvert(Span<const T>(data_),
Span<T>(inverse.data_),
Rows,
Span<T>(scratchBuffer),
Span<unsigned int>(swapBuffer));
if (ok)
*ok = res;
return inverse;
}
private:
/*
* \todo The initializer is only necessary for the constructor to be
* constexpr in C++17. Remove the initializer as soon as we are on
* C++20.
*/
std::array<T, Rows * Cols> data_ = {};
};
#ifndef __DOXYGEN__
template<typename T, typename U, unsigned int Rows, unsigned int Cols,
std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
#else
template<typename T, typename U, unsigned int Rows, unsigned int Cols>
#endif /* __DOXYGEN__ */
Matrix<U, Rows, Cols> operator*(T d, const Matrix<U, Rows, Cols> &m)
{
Matrix<U, Rows, Cols> result;
for (unsigned int i = 0; i < Rows; i++) {
for (unsigned int j = 0; j < Cols; j++)
result[i][j] = d * m[i][j];
}
return result;
}
#ifndef __DOXYGEN__
template<typename T, typename U, unsigned int Rows, unsigned int Cols,
std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
#else
template<typename T, typename U, unsigned int Rows, unsigned int Cols>
#endif /* __DOXYGEN__ */
Matrix<U, Rows, Cols> operator*(const Matrix<U, Rows, Cols> &m, T d)
{
return d * m;
}
template<typename T1, unsigned int R1, unsigned int C1, typename T2, unsigned int R2, unsigned int C2>
constexpr Matrix<std::common_type_t<T1, T2>, R1, C2> operator*(const Matrix<T1, R1, C1> &m1,
const Matrix<T2, R2, C2> &m2)
{
static_assert(C1 == R2, "Matrix dimensions must match for multiplication");
Matrix<std::common_type_t<T1, T2>, R1, C2> result;
for (unsigned int i = 0; i < R1; i++) {
for (unsigned int j = 0; j < C2; j++) {
std::common_type_t<T1, T2> sum = 0;
for (unsigned int k = 0; k < C1; k++)
sum += m1[i][k] * m2[k][j];
result[i][j] = sum;
}
}
return result;
}
template<typename T, unsigned int Rows, unsigned int Cols>
constexpr Matrix<T, Rows, Cols> operator+(const Matrix<T, Rows, Cols> &m1, const Matrix<T, Rows, Cols> &m2)
{
Matrix<T, Rows, Cols> result;
for (unsigned int i = 0; i < Rows; i++) {
for (unsigned int j = 0; j < Cols; j++)
result[i][j] = m1[i][j] + m2[i][j];
}
return result;
}
#ifndef __DOXYGEN__
bool matrixValidateYaml(const YamlObject &obj, unsigned int size);
#endif /* __DOXYGEN__ */
#ifndef __DOXYGEN__
template<typename T, unsigned int Rows, unsigned int Cols>
std::ostream &operator<<(std::ostream &out, const Matrix<T, Rows, Cols> &m)
{
out << m.toString();
return out;
}
template<typename T, unsigned int Rows, unsigned int Cols>
struct YamlObject::Getter<Matrix<T, Rows, Cols>> {
std::optional<Matrix<T, Rows, Cols>> get(const YamlObject &obj) const
{
if (!matrixValidateYaml(obj, Rows * Cols))
return std::nullopt;
Matrix<T, Rows, Cols> matrix;
T *data = &matrix[0][0];
unsigned int i = 0;
for (const YamlObject &entry : obj.asList()) {
const auto value = entry.get<T>();
if (!value)
return std::nullopt;
data[i++] = *value;
}
return matrix;
}
};
#endif /* __DOXYGEN__ */
} /* namespace libcamera */

View file

@ -8,7 +8,6 @@
#pragma once
#include <map>
#include <sstream>
#include <string>
#include <vector>
@ -56,6 +55,8 @@ public:
Signal<> disconnected;
std::vector<MediaEntity *> locateEntities(unsigned int function);
protected:
std::string logPrefix() const override;

View file

@ -48,6 +48,8 @@ public:
unsigned int flags() const { return flags_; }
int setEnabled(bool enable);
std::string toString() const;
private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(MediaLink)
@ -61,6 +63,8 @@ private:
unsigned int flags_;
};
std::ostream &operator<<(std::ostream &out, const MediaLink &link);
class MediaPad : public MediaObject
{
public:
@ -71,6 +75,8 @@ public:
void addLink(MediaLink *link);
std::string toString() const;
private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(MediaPad)
@ -85,6 +91,8 @@ private:
std::vector<MediaLink *> links_;
};
std::ostream &operator<<(std::ostream &out, const MediaPad &pad);
class MediaEntity : public MediaObject
{
public:
@ -104,7 +112,7 @@ public:
unsigned int deviceMinor() const { return minor_; }
const std::vector<MediaPad *> &pads() const { return pads_; }
const std::vector<MediaEntity *> ancillaryEntities() const { return ancillaryEntities_; }
const std::vector<MediaEntity *> &ancillaryEntities() const { return ancillaryEntities_; }
const MediaPad *getPadByIndex(unsigned int index) const;
const MediaPad *getPadById(unsigned int id) const;

View file

@ -0,0 +1,59 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2024, Ideas on Board Oy
*
* Media pipeline support
*/
#pragma once
#include <list>
#include <string>
#include <libcamera/base/log.h>
namespace libcamera {
class CameraSensor;
class MediaEntity;
class MediaLink;
class MediaPad;
struct V4L2SubdeviceFormat;
class MediaPipeline
{
public:
int init(MediaEntity *source, std::string_view sink);
int initLinks();
int configure(CameraSensor *sensor, V4L2SubdeviceFormat *);
private:
struct Entity {
/* The media entity, always valid. */
MediaEntity *entity;
/*
* Whether or not the entity is a subdev that supports the
* routing API.
*/
bool supportsRouting;
/*
* The local sink pad connected to the upstream entity, null for
* the camera sensor at the beginning of the pipeline.
*/
const MediaPad *sink;
/*
* The local source pad connected to the downstream entity, null
* for the video node at the end of the pipeline.
*/
const MediaPad *source;
/*
* The link on the source pad, to the downstream entity, null
* for the video node at the end of the pipeline.
*/
MediaLink *sourceLink;
};
std::list<Entity> entities_;
};
} /* namespace libcamera */

View file

@ -2,13 +2,6 @@
subdir('tracepoints')
libcamera_tracepoint_header = custom_target(
'tp_header',
input : ['tracepoints.h.in', tracepoint_files],
output : 'tracepoints.h',
command : [gen_tracepoints_header, include_build_dir, '@OUTPUT@', '@INPUT@'],
)
libcamera_internal_headers = files([
'bayer_format.h',
'byte_stream_buffer.h',
@ -18,23 +11,29 @@ libcamera_internal_headers = files([
'camera_manager.h',
'camera_sensor.h',
'camera_sensor_properties.h',
'clock_recovery.h',
'control_serializer.h',
'control_validator.h',
'converter.h',
'debug_controls.h',
'delayed_controls.h',
'device_enumerator.h',
'device_enumerator_sysfs.h',
'device_enumerator_udev.h',
'dma_heaps.h',
'dma_buf_allocator.h',
'formats.h',
'framebuffer.h',
'ipa_data_serializer.h',
'ipa_manager.h',
'ipa_module.h',
'ipa_proxy.h',
'ipc_pipe.h',
'ipc_unixsocket.h',
'mapped_framebuffer.h',
'matrix.h',
'media_device.h',
'media_object.h',
'media_pipeline.h',
'pipeline_handler.h',
'process.h',
'pub_key.h',
@ -46,8 +45,18 @@ libcamera_internal_headers = files([
'v4l2_pixelformat.h',
'v4l2_subdevice.h',
'v4l2_videodevice.h',
'vector.h',
'yaml_parser.h',
])
tracepoints_h = custom_target(
'tp_header',
input : ['tracepoints.h.in', tracepoint_files],
output : 'tracepoints.h',
command : [gen_tracepoints, include_build_dir, '@OUTPUT@', '@INPUT@'],
)
libcamera_internal_headers += tracepoints_h
subdir('converter')
subdir('software_isp')

View file

@ -9,19 +9,15 @@
#include <memory>
#include <queue>
#include <set>
#include <string>
#include <sys/types.h>
#include <vector>
#include <libcamera/base/mutex.h>
#include <libcamera/base/object.h>
#include <libcamera/controls.h>
#include <libcamera/stream.h>
#include "libcamera/internal/ipa_proxy.h"
namespace libcamera {
class Camera;
@ -45,7 +41,7 @@ public:
MediaDevice *acquireMediaDevice(DeviceEnumerator *enumerator,
const DeviceMatch &dm);
bool acquire();
bool acquire(Camera *camera);
void release(Camera *camera);
virtual std::unique_ptr<CameraConfiguration> generateConfiguration(Camera *camera,
@ -64,12 +60,16 @@ public:
bool completeBuffer(Request *request, FrameBuffer *buffer);
void completeRequest(Request *request);
void cancelRequest(Request *request);
std::string configurationFile(const std::string &subdir,
const std::string &name) const;
const std::string &name,
bool silent = false) const;
const char *name() const { return name_; }
CameraManager *cameraManager() const { return manager_; }
protected:
void registerCamera(std::shared_ptr<Camera> camera);
void hotplugMediaDevice(MediaDevice *media);
@ -77,6 +77,7 @@ protected:
virtual int queueRequestDevice(Camera *camera, Request *request) = 0;
virtual void stopDevice(Camera *camera) = 0;
virtual bool acquireDevice(Camera *camera);
virtual void releaseDevice(Camera *camera);
CameraManager *manager_;
@ -96,9 +97,7 @@ private:
std::queue<Request *> waitingRequests_;
const char *name_;
Mutex lock_;
unsigned int useCount_ LIBCAMERA_TSA_GUARDED_BY(lock_);
unsigned int useCount_;
friend class PipelineHandlerFactoryBase;
};

View file

@ -11,6 +11,7 @@
#include <string>
#include <vector>
#include <libcamera/base/class.h>
#include <libcamera/base/signal.h>
#include <libcamera/base/unique_fd.h>
@ -42,6 +43,8 @@ public:
Signal<enum ExitStatus, int> finished;
private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(Process)
void closeAllFdsExcept(const std::vector<int> &fds);
int isolate();
void died(int wstatus);

View file

@ -10,6 +10,8 @@
#include <chrono>
#include <map>
#include <memory>
#include <stdint.h>
#include <unordered_set>
#include <libcamera/base/event_notifier.h>
#include <libcamera/base/timer.h>

View file

@ -8,7 +8,6 @@
*/
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <sys/mman.h>

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2023, Red Hat Inc.
* Copyright (C) 2023-2025 Red Hat Inc.
*
* Authors:
* Hans de Goede <hdegoede@redhat.com>
@ -10,20 +10,45 @@
#pragma once
#include <array>
#include <stdint.h>
namespace libcamera {
struct DebayerParams {
static constexpr unsigned int kGain10 = 256;
static constexpr unsigned int kRGBLookupSize = 256;
unsigned int gainR;
unsigned int gainG;
unsigned int gainB;
struct CcmColumn {
int16_t r;
int16_t g;
int16_t b;
};
float gamma;
/**
* \brief Level of the black point, 0..255, 0 is no correction.
using LookupTable = std::array<uint8_t, kRGBLookupSize>;
using CcmLookupTable = std::array<CcmColumn, kRGBLookupSize>;
/*
* Color lookup tables when CCM is not used.
*
* Each color of a debayered pixel is amended by the corresponding
* value in the given table.
*/
unsigned int blackLevel;
LookupTable red;
LookupTable green;
LookupTable blue;
/*
* Color and gamma lookup tables when CCM is used.
*
* Each of the CcmLookupTable's corresponds to a CCM column; together they
* make a complete 3x3 CCM lookup table. The CCM is applied on debayered
* pixels and then the gamma lookup table is used to set the resulting
* values of all the three colors.
*/
CcmLookupTable redCcm;
CcmLookupTable greenCcm;
CcmLookupTable blueCcm;
LookupTable gammaLut;
};
} /* namespace libcamera */

View file

@ -7,16 +7,19 @@
#pragma once
#include <deque>
#include <functional>
#include <initializer_list>
#include <map>
#include <memory>
#include <stdint.h>
#include <string>
#include <tuple>
#include <vector>
#include <libcamera/base/class.h>
#include <libcamera/base/log.h>
#include <libcamera/base/object.h>
#include <libcamera/base/signal.h>
#include <libcamera/base/thread.h>
@ -27,7 +30,7 @@
#include <libcamera/ipa/soft_ipa_proxy.h>
#include "libcamera/internal/camera_sensor.h"
#include "libcamera/internal/dma_heaps.h"
#include "libcamera/internal/dma_buf_allocator.h"
#include "libcamera/internal/pipeline_handler.h"
#include "libcamera/internal/shared_mem_object.h"
#include "libcamera/internal/software_isp/debayer_params.h"
@ -37,14 +40,16 @@ namespace libcamera {
class DebayerCpu;
class FrameBuffer;
class PixelFormat;
class Stream;
struct StreamConfiguration;
LOG_DECLARE_CATEGORY(SoftwareIsp)
class SoftwareIsp
class SoftwareIsp : public Object
{
public:
SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor);
SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
ControlInfoMap *ipaControls);
~SoftwareIsp();
int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; }
@ -60,30 +65,33 @@ public:
int configure(const StreamConfiguration &inputCfg,
const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs,
const ControlInfoMap &sensorControls);
const ipa::soft::IPAConfigInfo &configInfo);
int exportBuffers(unsigned int output, unsigned int count,
int exportBuffers(const Stream *stream, unsigned int count,
std::vector<std::unique_ptr<FrameBuffer>> *buffers);
void processStats(const ControlList &sensorControls);
void processStats(const uint32_t frame, const uint32_t bufferId,
const ControlList &sensorControls);
int start();
void stop();
int queueBuffers(FrameBuffer *input,
const std::map<unsigned int, FrameBuffer *> &outputs);
void queueRequest(const uint32_t frame, const ControlList &controls);
int queueBuffers(uint32_t frame, FrameBuffer *input,
const std::map<const Stream *, FrameBuffer *> &outputs);
void process(FrameBuffer *input, FrameBuffer *output);
void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output);
Signal<FrameBuffer *> inputBufferReady;
Signal<FrameBuffer *> outputBufferReady;
Signal<> ispStatsReady;
Signal<uint32_t, uint32_t> ispStatsReady;
Signal<uint32_t, const ControlList &> metadataReady;
Signal<const ControlList &> setSensorControls;
private:
void saveIspParams();
void setSensorCtrls(const ControlList &sensorControls);
void statsReady();
void statsReady(uint32_t frame, uint32_t bufferId);
void inputReady(FrameBuffer *input);
void outputReady(FrameBuffer *output);
@ -91,9 +99,12 @@ private:
Thread ispWorkerThread_;
SharedMemObject<DebayerParams> sharedParams_;
DebayerParams debayerParams_;
DmaHeap dmaHeap_;
DmaBufAllocator dmaHeap_;
bool ccmEnabled_;
std::unique_ptr<ipa::soft::IPAProxySoft> ipa_;
std::deque<FrameBuffer *> queuedInputBuffers_;
std::deque<FrameBuffer *> queuedOutputBuffers_;
};
} /* namespace libcamera */

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) {{year}}, Google Inc.
* Copyright (C) 2020, Google Inc.
*
* Tracepoints with lttng
*

View file

@ -5,6 +5,8 @@
* request.tp - Tracepoints for the request object
*/
#include <stdint.h>
#include <libcamera/framebuffer.h>
#include "libcamera/internal/request.h"

View file

@ -10,6 +10,7 @@
#include <map>
#include <memory>
#include <optional>
#include <stdint.h>
#include <vector>
#include <linux/videodev2.h>
@ -44,6 +45,7 @@ public:
const std::string &deviceNode() const { return deviceNode_; }
std::string devicePath() const;
bool supportsFrameStartEvent();
int setFrameStartEnabled(bool enable);
Signal<uint32_t> frameStart;

View file

@ -49,6 +49,8 @@ public:
static const std::vector<V4L2PixelFormat> &
fromPixelFormat(const PixelFormat &pixelFormat);
bool isGenericLineBasedMetadata() const;
private:
uint32_t fourcc_;
};

View file

@ -10,6 +10,7 @@
#include <memory>
#include <optional>
#include <ostream>
#include <stdint.h>
#include <string>
#include <vector>
@ -176,6 +177,9 @@ private:
std::vector<SizeRange> enumPadSizes(const Stream &stream,
unsigned int code);
int getRoutingLegacy(Routing *routing, Whence whence);
int setRoutingLegacy(Routing *routing, Whence whence);
const MediaEntity *entity_;
std::string model_;

View file

@ -8,7 +8,6 @@
#pragma once
#include <array>
#include <atomic>
#include <memory>
#include <optional>
#include <ostream>
@ -158,7 +157,7 @@ private:
std::vector<Plane> planes_;
};
std::atomic<uint64_t> lastUsedCounter_;
uint64_t lastUsedCounter_;
std::vector<Entry> cache_;
/* \todo Expose the miss counter through an instrumentation API. */
unsigned int missCounter_;
@ -208,6 +207,7 @@ public:
int setFormat(V4L2DeviceFormat *format);
Formats formats(uint32_t code = 0);
int getSelection(unsigned int target, Rectangle *rect);
int setSelection(unsigned int target, Rectangle *rect);
int allocateBuffers(unsigned int count,

View file

@ -0,0 +1,371 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2024, Paul Elder <paul.elder@ideasonboard.com>
*
* Vector and related operations
*/
#pragma once
#include <algorithm>
#include <array>
#include <cmath>
#include <functional>
#include <numeric>
#include <optional>
#include <ostream>
#include <type_traits>
#include <libcamera/base/log.h>
#include <libcamera/base/span.h>
#include "libcamera/internal/matrix.h"
#include "libcamera/internal/yaml_parser.h"
namespace libcamera {
LOG_DECLARE_CATEGORY(Vector)
#ifndef __DOXYGEN__
template<typename T, unsigned int Rows,
std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
#else
template<typename T, unsigned int Rows>
#endif /* __DOXYGEN__ */
class Vector
{
public:
constexpr Vector() = default;
constexpr explicit Vector(T scalar)
{
data_.fill(scalar);
}
constexpr Vector(const std::array<T, Rows> &data)
{
std::copy(data.begin(), data.end(), data_.begin());
}
constexpr Vector(const Span<const T, Rows> data)
{
std::copy(data.begin(), data.end(), data_.begin());
}
const T &operator[](size_t i) const
{
ASSERT(i < data_.size());
return data_[i];
}
T &operator[](size_t i)
{
ASSERT(i < data_.size());
return data_[i];
}
constexpr Vector<T, Rows> operator-() const
{
Vector<T, Rows> ret;
for (unsigned int i = 0; i < Rows; i++)
ret[i] = -data_[i];
return ret;
}
constexpr Vector operator+(const Vector &other) const
{
return apply(*this, other, std::plus<>{});
}
constexpr Vector operator+(T scalar) const
{
return apply(*this, scalar, std::plus<>{});
}
constexpr Vector operator-(const Vector &other) const
{
return apply(*this, other, std::minus<>{});
}
constexpr Vector operator-(T scalar) const
{
return apply(*this, scalar, std::minus<>{});
}
constexpr Vector operator*(const Vector &other) const
{
return apply(*this, other, std::multiplies<>{});
}
constexpr Vector operator*(T scalar) const
{
return apply(*this, scalar, std::multiplies<>{});
}
constexpr Vector operator/(const Vector &other) const
{
return apply(*this, other, std::divides<>{});
}
constexpr Vector operator/(T scalar) const
{
return apply(*this, scalar, std::divides<>{});
}
Vector &operator+=(const Vector &other)
{
return apply(other, [](T a, T b) { return a + b; });
}
Vector &operator+=(T scalar)
{
return apply(scalar, [](T a, T b) { return a + b; });
}
Vector &operator-=(const Vector &other)
{
return apply(other, [](T a, T b) { return a - b; });
}
Vector &operator-=(T scalar)
{
return apply(scalar, [](T a, T b) { return a - b; });
}
Vector &operator*=(const Vector &other)
{
return apply(other, [](T a, T b) { return a * b; });
}
Vector &operator*=(T scalar)
{
return apply(scalar, [](T a, T b) { return a * b; });
}
Vector &operator/=(const Vector &other)
{
return apply(other, [](T a, T b) { return a / b; });
}
Vector &operator/=(T scalar)
{
return apply(scalar, [](T a, T b) { return a / b; });
}
constexpr Vector min(const Vector &other) const
{
return apply(*this, other, [](T a, T b) { return std::min(a, b); });
}
constexpr Vector min(T scalar) const
{
return apply(*this, scalar, [](T a, T b) { return std::min(a, b); });
}
constexpr Vector max(const Vector &other) const
{
return apply(*this, other, [](T a, T b) { return std::max(a, b); });
}
constexpr Vector max(T scalar) const
{
return apply(*this, scalar, [](T a, T b) -> T { return std::max(a, b); });
}
constexpr T dot(const Vector<T, Rows> &other) const
{
T ret = 0;
for (unsigned int i = 0; i < Rows; i++)
ret += data_[i] * other[i];
return ret;
}
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
#endif /* __DOXYGEN__ */
constexpr const T &x() const { return data_[0]; }
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
#endif /* __DOXYGEN__ */
constexpr const T &y() const { return data_[1]; }
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
#endif /* __DOXYGEN__ */
constexpr const T &z() const { return data_[2]; }
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
#endif /* __DOXYGEN__ */
constexpr T &x() { return data_[0]; }
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
#endif /* __DOXYGEN__ */
constexpr T &y() { return data_[1]; }
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
#endif /* __DOXYGEN__ */
constexpr T &z() { return data_[2]; }
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
#endif /* __DOXYGEN__ */
constexpr const T &r() const { return data_[0]; }
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
#endif /* __DOXYGEN__ */
constexpr const T &g() const { return data_[1]; }
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
#endif /* __DOXYGEN__ */
constexpr const T &b() const { return data_[2]; }
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
#endif /* __DOXYGEN__ */
constexpr T &r() { return data_[0]; }
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
#endif /* __DOXYGEN__ */
constexpr T &g() { return data_[1]; }
#ifndef __DOXYGEN__
template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
#endif /* __DOXYGEN__ */
constexpr T &b() { return data_[2]; }
constexpr double length2() const
{
double ret = 0;
for (unsigned int i = 0; i < Rows; i++)
ret += data_[i] * data_[i];
return ret;
}
constexpr double length() const
{
return std::sqrt(length2());
}
template<typename R = T>
constexpr R sum() const
{
return std::accumulate(data_.begin(), data_.end(), R{});
}
private:
template<class BinaryOp>
static constexpr Vector apply(const Vector &lhs, const Vector &rhs, BinaryOp op)
{
Vector result;
std::transform(lhs.data_.begin(), lhs.data_.end(),
rhs.data_.begin(), result.data_.begin(),
op);
return result;
}
template<class BinaryOp>
static constexpr Vector apply(const Vector &lhs, T rhs, BinaryOp op)
{
Vector result;
std::transform(lhs.data_.begin(), lhs.data_.end(),
result.data_.begin(),
[&op, rhs](T v) { return op(v, rhs); });
return result;
}
template<class BinaryOp>
Vector &apply(const Vector &other, BinaryOp op)
{
auto itOther = other.data_.begin();
std::for_each(data_.begin(), data_.end(),
[&op, &itOther](T &v) { v = op(v, *itOther++); });
return *this;
}
template<class BinaryOp>
Vector &apply(T scalar, BinaryOp op)
{
std::for_each(data_.begin(), data_.end(),
[&op, scalar](T &v) { v = op(v, scalar); });
return *this;
}
std::array<T, Rows> data_;
};
template<typename T>
using RGB = Vector<T, 3>;
template<typename T, typename U, unsigned int Rows, unsigned int Cols>
Vector<std::common_type_t<T, U>, Rows> operator*(const Matrix<T, Rows, Cols> &m, const Vector<U, Cols> &v)
{
Vector<std::common_type_t<T, U>, Rows> result;
for (unsigned int i = 0; i < Rows; i++) {
std::common_type_t<T, U> sum = 0;
for (unsigned int j = 0; j < Cols; j++)
sum += m[i][j] * v[j];
result[i] = sum;
}
return result;
}
template<typename T, unsigned int Rows>
bool operator==(const Vector<T, Rows> &lhs, const Vector<T, Rows> &rhs)
{
for (unsigned int i = 0; i < Rows; i++) {
if (lhs[i] != rhs[i])
return false;
}
return true;
}
template<typename T, unsigned int Rows>
bool operator!=(const Vector<T, Rows> &lhs, const Vector<T, Rows> &rhs)
{
return !(lhs == rhs);
}
#ifndef __DOXYGEN__
bool vectorValidateYaml(const YamlObject &obj, unsigned int size);
#endif /* __DOXYGEN__ */
#ifndef __DOXYGEN__
template<typename T, unsigned int Rows>
std::ostream &operator<<(std::ostream &out, const Vector<T, Rows> &v)
{
out << "Vector { ";
for (unsigned int i = 0; i < Rows; i++) {
out << v[i];
out << ((i + 1 < Rows) ? ", " : " ");
}
out << " }";
return out;
}
template<typename T, unsigned int Rows>
struct YamlObject::Getter<Vector<T, Rows>> {
std::optional<Vector<T, Rows>> get(const YamlObject &obj) const
{
if (!vectorValidateYaml(obj, Rows))
return std::nullopt;
Vector<T, Rows> vector;
unsigned int i = 0;
for (const YamlObject &entry : obj.asList()) {
const auto value = entry.get<T>();
if (!value)
return std::nullopt;
vector[i++] = *value;
}
return vector;
}
};
#endif /* __DOXYGEN__ */
} /* namespace libcamera */

View file

@ -10,7 +10,9 @@
#include <iterator>
#include <map>
#include <optional>
#include <stdint.h>
#include <string>
#include <string_view>
#include <vector>
#include <libcamera/base/class.h>
@ -158,37 +160,34 @@ public:
{
return type_ == Type::Dictionary;
}
bool isEmpty() const
{
return type_ == Type::Empty;
}
explicit operator bool() const
{
return type_ != Type::Empty;
}
std::size_t size() const;
#ifndef __DOXYGEN__
template<typename T,
std::enable_if_t<
std::is_same_v<bool, T> ||
std::is_same_v<double, T> ||
std::is_same_v<int8_t, T> ||
std::is_same_v<uint8_t, T> ||
std::is_same_v<int16_t, T> ||
std::is_same_v<uint16_t, T> ||
std::is_same_v<int32_t, T> ||
std::is_same_v<uint32_t, T> ||
std::is_same_v<std::string, T> ||
std::is_same_v<Size, T>> * = nullptr>
#else
template<typename T>
#endif
std::optional<T> get() const;
template<typename T>
T get(const T &defaultValue) const
std::optional<T> get() const
{
return get<T>().value_or(defaultValue);
return Getter<T>{}.get(*this);
}
template<typename T, typename U>
T get(U &&defaultValue) const
{
return get<T>().value_or(std::forward<U>(defaultValue));
}
#ifndef __DOXYGEN__
template<typename T,
std::enable_if_t<
std::is_same_v<bool, T> ||
std::is_same_v<float, T> ||
std::is_same_v<double, T> ||
std::is_same_v<int8_t, T> ||
std::is_same_v<uint8_t, T> ||
@ -208,25 +207,33 @@ public:
const YamlObject &operator[](std::size_t index) const;
bool contains(const std::string &key) const;
const YamlObject &operator[](const std::string &key) const;
bool contains(std::string_view key) const;
const YamlObject &operator[](std::string_view key) const;
private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(YamlObject)
template<typename T>
friend struct Getter;
friend class YamlParserContext;
enum class Type {
Dictionary,
List,
Value,
Empty,
};
template<typename T, typename Enable = void>
struct Getter {
std::optional<T> get(const YamlObject &obj) const;
};
Type type_;
std::string value_;
Container list_;
std::map<std::string, YamlObject *> dictionary_;
std::map<std::string, YamlObject *, std::less<>> dictionary_;
};
class YamlParser final

View file

@ -46,7 +46,8 @@ struct ipa_control_info_entry {
uint32_t id;
uint32_t type;
uint32_t offset;
uint32_t padding[1];
uint8_t direction;
uint8_t padding[3];
};
#ifdef __cplusplus

View file

@ -7,19 +7,6 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <vector>
#include <libcamera/base/flags.h>
#include <libcamera/base/signal.h>
#include <libcamera/controls.h>
#include <libcamera/framebuffer.h>
#include <libcamera/geometry.h>
namespace libcamera {
/*
@ -33,8 +20,8 @@ public:
virtual ~IPAInterface() = default;
};
} /* namespace libcamera */
extern "C" {
libcamera::IPAInterface *ipaCreate();
}
} /* namespace libcamera */

View file

@ -31,14 +31,14 @@ interface IPAIPU3Interface {
unmapBuffers(array<uint32> ids);
[async] queueRequest(uint32 frame, libcamera.ControlList controls);
[async] fillParamsBuffer(uint32 frame, uint32 bufferId);
[async] processStatsBuffer(uint32 frame, int64 frameTimestamp,
uint32 bufferId, libcamera.ControlList sensorControls);
[async] computeParams(uint32 frame, uint32 bufferId);
[async] processStats(uint32 frame, int64 frameTimestamp,
uint32 bufferId, libcamera.ControlList sensorControls);
};
interface IPAIPU3EventInterface {
setSensorControls(uint32 frame, libcamera.ControlList sensorControls,
libcamera.ControlList lensControls);
paramsBufferReady(uint32 frame);
paramsComputed(uint32 frame);
metadataReady(uint32 frame, libcamera.ControlList metadata);
};

Some files were not shown because too many files have changed in this diff Show more