Compare commits

...

1255 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
Kieran Bingham
aee16c0691 libcamera v0.3.0
abi-compliance checker reports 99.7% binary compatibility and 99.9% source
compatibility between v0.2.0 and v0.3.0. The SONAME has been updated
accordingly and applications must be relinked against this version of
libcamera.

 Total binary compatibility problems: 2, warnings: 0
 Total source compatibility problems: 2, warnings: 0

Specifically, the symbol
  - ControlList::merge(struct ControlList const& source )
 has been replaced with the new symbol:
  - ControlList::merge ( struct ControlList const& source, enum ControlList::MergePolicy policy )

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

 - utils: ipc: extract-docs: Fix escape characters in regex
   - Reported-by: Nicolas Dufresne <nicolas@ndufresne.ca>
 - libcamera: Remove empty formats.c
   - Fixes: e0a51061bc ("libcamera: formats: Add 14-bits Bayer RAW formats")
 - libcamera: bayer_format: Add Y12 to bayerToFormat
   - Fixes: ec63095716 ("libcamera: bayer_format: Add unpacked mono 12-bit format to the conversion table")
 - apps: common: dng_writer: Add a default case for switch-case on a modulo
   - Bug: https://bugs.libcamera.org/show_bug.cgi?id=207
 - utils: mojom: Fix build error caused by the mojom tool update
   - Fixes: d17de86904 ("utils: ipc: Update mojo")
 - libcamera: formats: Fix planes bounds check
   - Fixes: e83727a194 ("libcamera: PixelFormatInfo: Add functions stride and frameSize")
 - utils: ipu3: Fix return value check on file output
   - Fixes: 23ac77dc4a ("utils: ipu3: Add IPU3 raw capture unpack utility")
 - ipa: libipa: histogram: Fix documentation of constructor
   - Fixes: 1dc01bc9e6 ("ipa: libipa: histogram: Add transform parameter to constructor")
 - gstreamer: Fix string memory leak
   - Fixes: fc9783acc6 ("gstreamer: Provide colorimetry <> ColorSpace mappings")
 - gstreamer: Use copied camera name
   - Fixes: 58feb69f85 ("gst: libcamerasrc: Implement selection and acquisition")

core:
 - include: linux: Update kernel headers to version v6.7
 - libcamera: v4l2_subdevice: Enable streams API when supported
 - libcamera: base: signal: Update Qt documentation link to Qt 6
 - Documentation: Update Qt documentation links to Qt 6
 - test: gstreamer: Use env instead of registry edit
 - libcamera: Remove empty formats.c
 - libcamera: formats: Add 16-bit mono format
 - libcamera: formats: Fix sort ordering of R10_CSI2P
 - libcamera: bayer_format: Add Y12 to bayerToFormat
 - libcamera: v4l2_subdevice: Explain sort order of formatInfoMap
 - libcamera: object: Fix thread-bound reference in documentation
 - libcamera: signal: Replace object.h inclusion with forward declatation
 - test: object-delete: Test deferred delete just before thread stops
 - libcamera: thread: Ensure deferred deletion of all objects before stopping
 - test: event-thread: Destroy Object from correct thread context
 - test: message: Remove incorrect slow receiver test
 - test: message: Destroy Object from correct thread context
 - test: signal-threads: Destroy Object from correct thread context
 - test: timer-thread: Move timer start from wrong thread to separate test
 - test: timer-thread: Destroy Object from correct thread context
 - libcamera: object: Document and ensure Object deletion constraints
 - libcamera: object: Add and use thread-bound assertion
 - utils: mojom: Fix build error caused by the mojom tool update
 - include: linux: Add RKISP1_V_IMX8MP version
 - libcamera: utils: Add to_underlying() helper function
 - libcamera: Use utils::to_underlying()
 - libcamera: formats: Fix typos in PixelFormatInfo documentation
 - utils: checkstyle.py: Don't presume python3 location
 - utils: checkstyle.py: Update LogCategoryChecker regexp
 - utils: rkisp1: gen-csc-table.py: Don't presume python3 location
 - libcamera: formats: Fix planes bounds check
 - utils: ipu3: Fix return value check on file output
 - README.rst: Report py dependencies
 - meson_options: Autodetect pycamera support
 - libcamera: controls: Fix typo on thermal
 - guides: pipeline-handler: Fix controlInfo_ initialization
 - libcamera: v4l2_subdevice: Add 14-bit Bayer formats
 - utils: checkstyle.py: Add Co-developed-by to known_trailers
 - utils: checkstyle.py: Fix known_trailers sort order
 - libcamera: framebuffer_allocator: Move from argument in constructor
 - libcamera: framebuffer_allocator: Use default destructor
 - libcamera: framebuffer_allocator: Remove entry if allocation fails
 - libcamera: controls: Add policy parameter to ControlList::merge()
 - libcamera: v4l2_subdevice: Rename V4L2SubdeviceFormatInfo
 - libcamera: v4l2_subdevice: Add code member to MediaBusFormatInfo
 - libcamera: v4l2_subdevice: Expose media bus format info as internal API
 - libcamera: v4l2_subdevice: Extend MediaBusFormatInfo with metadata formats
 - libcamera: v4l2_subdevice: Drop V4L2SubdeviceFormat::bitsPerPixel()
 - libcamera: v4l2_subdevice: Rename V4L2SubdeviceFormat::mbus_code to code
 - libcamera: v4l2_subdevice: Add stream support to get/set functions
 - libcamera: v4l2_subdevice: Replace Routing::toString() with operator<<()
 - libcamera: v4l2_subdevice: Add V4L2Subdevice::Route structure
 - libcamera: camera_sensor: Move related classes to subdirectory
 - libcamera: camera_sensor: Drop updateControlInfo() function
 - libcamera: camera_sensor: Reorder functions
 - libcamera: camera_sensor: Test for read-only HBLANK with READ_ONLY flag
 - libcamera: camera_sensor: Expose the Bayer order
 - checkstyle: Work around bug in difflib
 - utils: tuning: readme: Improve names of dependency packages
 - libcamera: internal: Move dma_heaps.[h, cpp] to common directories
 - libcamera: dma_heaps: extend DmaHeap class to support system heap
 - libcamera: internal: Move SharedMemObject class to a common directory
 - libcamera: shared_mem_object: Rename SIZE constant to `size'
 - libcamera: shared_mem_object: Reorganize the code and document the SharedMemObject class
 - libcamera: software_isp: Add SwStatsCpu class
 - libcamera: software_isp: Add Debayer base class
 - libcamera: software_isp: Add DebayerCpu class
 - libcamera: Introduce SoftwareIsp
 - libcamera: swstats_cpu: Add support for 8, 10 and 12 bpp unpacked bayer input
 - libcamera: debayer_cpu: Add support for 8, 10 and 12 bpp unpacked bayer input
 - libcamera: debayer_cpu: Add BGR888 output support
 - libcamera: Add "Software ISP benchmarking" documentation
 - libcamera: software_isp: Apply black level compensation
 - Documentation: coding-style: Clean up header guard style
 - utils: checkstyle.py: Use r'' strings for regular expressions
 - utils: checkstyle.py: Drop period at end of Doxygen one liners
 - libcamera: device_enumerator: Fix spell error
 - libcamera: Fix output spelling error
 - libcamera: utils: Avoid infinite recursion with strtod()
 - libcamera: shared_mem_object: Fix compilation with uClibc
 - meson: Deprecate bitwise operations between different enumeration type
 - Revert "meson: Deprecate bitwise operations between different enumeration type"
 - test: Don't add current build directory to include path
 - libcamera: controls: Generate enum value-name maps
 - libcamera: Drop file name from header comment blocks
 - libcamera: Drop file name from header comment blocks in templates
 - libcamera: Drop remaining file name from header comment blocks
 - test: gstreamer: Simplify single stream test
 - Documentation: Add option to treat Doxygen warnings as errors
 - libcamera: camera_manager: Add environment variable to order pipelines match
 - include: linux: Add RGB48 formats
 - libcamera: formats: Add RGB48 formats
 - include: linux: Add PiSP specific image and config buffer formats
 - libcamera: formats: Add PiSP specific image and config buffer formats
 - libcamera: v4l2_subdevice: Add missing MEDIA_BUS_FMT_xxxx16_1X16 info

pipeline:
 - pipeline: rpi: Always initialize the embedded buffer in tryRunPipeline
 - pipeline: rpi: vc4: Use an unpacked format if no packed one is available
 - pipeline: simple: Add support for MediaTek MT8365 platforms
 - libcamera: pipeline: Add Mali-C55 ISP pipeline
 - libcamera: pipeline: simple: fix size adjustment in validate()
 - libcamera: pipeline: simple: Rename converterBuffers_ and related vars
 - libcamera: pipeline: simple: Enable use of Soft ISP and Soft IPA
 - ipu3: Use posix basename
 - pipeline: rpi: Avoid duplicating size range for the same pixel format
 - libcamera: pipeline: Rename pipelines to a shorter name
 - libcamera: pipeline: Add a get factory by name helper

ipa:
 - libipa: camera_sensor_helper: Mark createInstance() with override
 - utils: ipc: extract-docs: Fix escape characters in regex
 - ipa: rkisp1: agc: Wrap variable length C arrays in spans
 - ipa: rkisp1: Store hardware parameters in IPA context
 - ipa: rkisp1: Fix histogram weights configuration
 - ipa: rkisp1: Support the i.MX8MP ISP version
 - ipa: rpi: cam_helper: Extend embedded data parsing to RAW14 modes
 - utils: ipc: Fix event functions with no parameters
 - utils: ipc: Fix async main interface functions with no parameters
 - libcamera: ipa: Add Soft IPA
 - libcamera: libipa: camera_sensor: Add Sony IMX283 sensor properties
 - libcamera: libipa: camera_sensor: Add Sony IMX335 sensor properties
 - libcamera: libipa: camera_sensor: Add Sony IMX415 sensor properties
 - ipa: libipa: Allow creation of empty Histogram
 - ipa: libipa: Add ExposureModeHelper
 - ipa: libipa: Add AgcMeanLuminance base class
 - ipa: ipu3: Derive ipu3::algorithms::Agc from AgcMeanLuminance
 - ipa: ipu3: Remove bespoke AGC functions from IPU3
 - ipa: rkisp1: Derive rkisp1::algorithms::Agc from AgcMeanLuminance
 - ipa: rkisp1: Remove bespoke Agc functions
 - ipa: libipa: histogram: Add transform parameter to constructor
 - ipa: rpi: Fix for incorrectly reported max shutter speed
 - ipa: rkisp1: agc: Fix histogram construction
 - ipa: libipa: histogram: Fix documentation of constructor
 - ipa: rpi: Add HDR support
 - ipa: rpi: Add accessor function for monoSensor_

apps:
 - gstreamer: Add meson devenv support
 - apps: common: dng_writer: Add a default case for switch-case on a modulo
 - doc: gstreamer: Add missing queues
 - gstreamer: Map R8/R16 pixel format
 - gstreamer: Map 10/12/14/16 bayer formats supports
 - cam: capture_script: Make parseRectangles work for non-array
 - apps: lc-compliance: Check that requests complete successfully
 - apps: lc-compliance: Fix typo in comment
 - apps: lc-compliance: Re-organize source directory
 - android: camera_device: Save capture settings unconditionally
 - v4l2: Unset _TIME_BITS in addition to _FILE_OFFSET_BITS
 - v4l2: meson: Keep defines sorted alphabetically
 - apps: cam: Add support for PPM output format
 - android: camera_device: Always clear descriptors_ in stop()
 - apps: cam: Fix C++20 deprecation warning
 - apps: qcam: Use standard key sequence for quit action
 - gstreamer: Fix string memory leak
 - gstreamer: Use copied camera name

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-19 16:54:11 +01:00
Naushir Patuck
2031e2f290 ipa: rpi: Add accessor function for monoSensor_
The monoSensor_ member variable will be used by the derived IPAs in an
upcoming commit, so add an accessor function for it.

Signed-off-by: Naushir Patuck <naush@raspberrypi.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-05-16 16:11:06 +01:00
Naushir Patuck
706578ecc8 ipa: rpi: Add HDR support
Add support for the following HDR modes in the Raspberry Pi IPA:
- Night mode
- Single exposure mode
- Multi-exposure (merged and unmerged)

The algorithm is updated to expect the HDR short channel to meter
explicitly for highlights. This means that it will not in general
under-expose the short channel more than is actually necessary.

When images don't have much saturation, it's good to detect this so
that some of the boost we want to apply to the dark areas can be
implemented as regular gain. This means we can then adjust the tone
curve less, leading to less flat looking images.

The impact on the HDR algorithm is then that this determines how we
build tonemaps dynamically. The highlights are more-or-less correct
now, so we have to build a power-type curve that gives us the
appropriately configured targets in the lower part of the histogram.

We allow the tuning file to supply the maximum spatial gain value,
rather than the whole curve (though it can supply this if it
wants). Some parameter defaults are tweaked to be generally better
across the range of our cameras.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-16 16:11:06 +01:00
Naushir Patuck
84ed4456fc libcamera: v4l2_subdevice: Add missing MEDIA_BUS_FMT_xxxx16_1X16 info
Add the missing 16-bit MEDIA_BUS_FMT_xxxx16_1X16 definitions to the
mediaBusFormatInfo table.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@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>
2024-05-16 16:11:06 +01:00
Naushir Patuck
8c93055043 libcamera: formats: Add PiSP specific image and config buffer formats
Add the Raspberry Pi 5 PiSP specific compressed Bayer format types 1/2:
- V4L2_PIX_FMT_PISP_COMP1_xxx
- V4L2_PIX_FMT_PISP_COMP2_xxx

Add the Raspberry Pi 5 PiSP Frontend and Backend config formats:
- V4L2_META_FMT_RPI_FE_CFG
- V4L2_META_FMT_RPI_BE_CFG

Add the Raspberry Pi 5 PiSP Frontend statistics format:
- V4L2_META_FMT_RPI_FE_STATS

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>
2024-05-16 16:11:06 +01:00
Naushir Patuck
b14f061150 include: linux: Add PiSP specific image and config buffer formats
Add the Raspberry Pi 5 PiSP specific compressed Bayer format types 1/2:
- V4L2_PIX_FMT_PISP_COMP1_xxx
- V4L2_PIX_FMT_PISP_COMP2_xxx

Add the Raspberry Pi 5 PiSP Frontend and Backend config formats:
- V4L2_META_FMT_RPI_FE_CFG
- V4L2_META_FMT_RPI_BE_CFG

Add the Raspberry Pi 5 PiSP Frontend statistics format:
- V4L2_META_FMT_RPI_FE_STATS

The corresponding changes submitted to the linux-media mailing list can
be found at:
(series "media: raspberrypi: Add support for PiSP Back End")
https://lore.kernel.org/linux-media/20240502110503.38412-4-jacopo.mondi@ideasonboard.com/
https://lore.kernel.org/linux-media/20240502110503.38412-5-jacopo.mondi@ideasonboard.com/

and for the DRM mailing at:
(patch "[RFC] drm/fourcc: Add RPI modifiers")
https://lore.kernel.org/dri-devel/20240226153854.99471-1-jacopo.mondi@ideasonboard.com/

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>
2024-05-16 16:11:06 +01:00
Naushir Patuck
1659e68cdc libcamera: formats: Add RGB48 formats
Add support for 16-bps (48-bpp) RGB output formats to libcamera. These
new formats are defined for the RGB and BGR ordering.

Signed-off-by: Naushir Patuck <naush@raspberrypi.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-16 16:11:06 +01:00
Naushir Patuck
223a1d3755 include: linux: Add RGB48 formats
Add support for 16-bps (48-bpp) RGB output formats in the uapi headers.
These new formats are defined for the RGB and BGR ordering.

The corresponding change submitted to the linux-media and DRM mailing
lists can be found at:

https://lore.kernel.org/linux-media/20240502110503.38412-3-jacopo.mondi@ideasonboard.com/
and
https://lore.kernel.org/dri-devel/20240226132544.82817-1-jacopo.mondi@ideasonboard.com/

respectively.

Signed-off-by: Naushir Patuck <naush@raspberrypi.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-16 16:11:06 +01:00
Julien Vuillaumier
d258025da7 libcamera: camera_manager: Add environment variable to order pipelines match
To match the enumerated media devices, each registered pipeline handler
is used in no specific order. It is a limitation when several pipelines
can match the devices, and user has to select a specific pipeline.

For this purpose, environment variable LIBCAMERA_PIPELINES_MATCH_LIST is
created to give the option to define an ordered list of pipelines to
match on.

LIBCAMERA_PIPELINES_MATCH_LIST="<name1>[,<name2>[,<name3>...]]]"

Example:
LIBCAMERA_PIPELINES_MATCH_LIST="rkisp1,simple"

Signed-off-by: Julien Vuillaumier <julien.vuillaumier@nxp.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-14 23:22:55 +01:00
Julien Vuillaumier
353ccef143 libcamera: pipeline: Add a get factory by name helper
Add a static helper to the PipelineHandlerFactoryBase class to
allow retrieving a pipeline by name.

Signed-off-by: Julien Vuillaumier <julien.vuillaumier@nxp.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-14 23:22:55 +01:00
Julien Vuillaumier
5ed35fca68 libcamera: pipeline: Rename pipelines to a shorter name
The PipelineHandlerFactoryBase class has a name that is propagated to
the PipelineHandler instance it creates.

In present implementation, this name comes from the
REGISTER_PIPELINE_HANDLER registration macro. It corresponds to the
stringified name of the PipelineHandler derived class. Therefore,
PipelineHandler factories and instances names can be quite long such as
"PipelineHandlerRkISP1".

A libcamera user may have to explicitly refer to a PipelineHandler name
for configuration purpose: one usage of the name can be to define a
pipeline handlers match list and their priorities. It is desired, for
user convenience, to use a short name to designate a pipeline handler.
Reusing the short pipeline names already defined in the meson option
files is an existing and consistent way of naming pipelines.

This change adds an explicit name parameter to the
REGISTER_PIPELINE_HANDLER registration macro. That parameter is used to
define the name of a pipeline handler factory, instead of the current
pipeline handler class name.

Each pipeline registration is updated accordingly. The short name
assigned corresponds to the pipeline directory name in the source tree.
It is consistent with pipelines names used in meson.

Changing the pipeline name has an impact on the IPA modules: each module
defines a IPAModuleInfo structure. This structure has a pipelineName
member defining the pipeline handler name it shall match with.
Therefore, each internal IPA module definition has to be changed to have
its IPAModuleInfo pipelineName name updated with the short pipeline
handler name.

In addition to this pipelineName member, the IPAModuleInfo structure
also has a name member, associated to the IPA module name. Having
renamed the pipelines to a short name, the pipeline name and the IPA
module names of the IPAModuleInfo structure are the same: for in-tree
IPA, they correspond to the respective pipeline and IPA subdirectories
in the source tree.  However the IPA name could be different, for
instance with a close source IPA implementation built out-of-tree. Thus,
it makes sense to keep the IPA name in that structure, as the 2
definitions may not always be redundant.

Signed-off-by: Julien Vuillaumier <julien.vuillaumier@nxp.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
[Kieran: Adjust for clang-format style fix, reformat commitmsg]
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-14 23:20:29 +01:00
Barnabás Pőcze
e43d2a35fa gstreamer: Use copied camera name
The camera name is copied in gst_libcamera_src_open() as we can't hold
the lock protecting the name while calling GST_ELEMENT_ERROR(). The
GST_ELEMENT_ERROR() macro sends a message on the bus, taking more locks
and possibly causing issues.

However, the current code makes the copy, but does not actually use it.
So fix that.

Fixes: 58feb69f85 ("gst: libcamerasrc: Implement selection and acquisition")
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>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-05-14 23:51:57 +03:00
Barnabás Pőcze
f113464b34 gstreamer: Fix string memory leak
The string returned by `gst_video_colorimetry_to_string()`
has to be freed, this was missing.

Fixes: fc9783acc6 ("gstreamer: Provide colorimetry <> ColorSpace mappings")
Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-05-14 23:45:19 +03:00
Laurent Pinchart
899087fe42 Documentation: Add option to treat Doxygen warnings as errors
A new Doxygen warning introduced in a recent commit went unnoticed, both
in manual tests and in CI. Unlike C/C++ warnings that are treated as
errors, we don't fail the build with Doxygen warnings. This is due to
the fact that the libcamera documentation compiles cleanly only with quite
recent versions of Doxygen. Enabling the WARN_AS_ERROR Doxygen option
unconditionally could bother many users.

To improve the situation, add a meson option to treat Doxygen warnings
as errors. The option is disabled by default, preserving the current
behaviour, and will be enabled in CI builds.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-14 14:52:55 +03:00
Nicolas Dufresne
a2a61121eb test: gstreamer: Simplify single stream test
The single stream test for the GStreamer component has a simple pipeline
construction using only a fakesink.

The implementation currently supports connecting to a more complex
stream construction defined by the streamDescription, but this is over
engineered for the simple need to start a stream to capture and discard
the frames.

Convert the use of gst_parse_bin_from_description_full() which uses only
a single element 'fakesink' to construct the fakesink directly and link
it to the libcamerasrc.

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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-05-13 16:33:43 +03:00
Laurent Pinchart
467bd6268d ipa: libipa: histogram: Fix documentation of constructor
Commit 1dc01bc9e6 ("ipa: libipa: histogram: Add transform parameter to
constructor") added a new constructor for the Histogram class. The
implementation is inline in the header file, and the documentation was
added in the corresponding .cpp file, but it missed the \fn directive.
This causes Doxygen to complain:

src/ipa/libipa/histogram.h:31: warning: Member Histogram(Span< const uint32_t > data, Transform transform) (function) of class libcamera::ipa::Histogram is not documented.
src/ipa/libipa/histogram.cpp:59: warning: libcamera::ipa::Histogram::bins has @param documentation sections but no arguments

Fix it.

Fixes: 1dc01bc9e6 ("ipa: libipa: histogram: Add transform parameter to constructor")
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-05-13 16:33:43 +03:00
Laurent Pinchart
3cb20bc230 libcamera: Drop remaining file name from header comment blocks
Source files in libcamera start by a comment block header, which
includes the file name and a one-line description of the file contents.
While the latter is useful to get a quick overview of the file contents
at a glance, the former is mostly a source of inconvenience. The name in
the comments can easily get out of sync with the file name when files
are renamed, and copy & paste during development have often lead to
incorrect names being used to start with.

Readers of the source code are expected to know which file they're
looking it. Drop the file name from the header comment blocks in all
remaining locations that were not caught by the automated script as they
are out of sync with the file name.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-05-09 23:31:15 +03:00
Laurent Pinchart
829acb3ab0 libcamera: Drop file name from header comment blocks in templates
Source files in libcamera start by a comment block header, which
includes the file name and a one-line description of the file contents.
While the latter is useful to get a quick overview of the file contents
at a glance, the former is mostly a source of inconvenience. The name in
the comments can easily get out of sync with the file name when files
are renamed, and copy & paste during development have often lead to
incorrect names being used to start with.

Readers of the source code are expected to know which file they're
looking it. Drop the file name from the header comment blocks in
template files and templates embedded in generator scripts.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-05-09 23:31:14 +03:00
Paul Elder
f1522e94df ipa: rkisp1: agc: Fix histogram construction
This histogram reported by the rkisp1 hardware is 20 bits, where the
upper 16 bits are meaningful integer data and the lower 4 bits are
fractional and meant to be discarded. Remove these 4 bits when
construction the histogram.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-05-09 21:08:21 +09:00
Naushir Patuck
299e5278bd ipa: rpi: Fix for incorrectly reported max shutter speed
The maximum shutter speed calculation in the cam-helper relied on
the frame duration limits being correctly set in the cam-helper's mode
structure. This was not the case on first startup, so the maximum
shutter speed reported back via the ControlInfo was incorrect.

Fix this by setting up the camera mode in the cam-helper before querying
for the max shutter value.

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>
2024-05-09 12:49:35 +01:00
David Plowman
5e85157bcf pipeline: rpi: Avoid duplicating size range for the same pixel format
Some V4L2 formats translate to the same pixel format, e.g. YU12 and
YM12 both produce YUV420. In this case our ISP driver advertises the
same size range for both, but we must not record the same thing twice
for the same pixel format (which will cause a failure later on).

Instead, ignore the V4l2 format if the pixel format has already been
seen.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-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: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-09 12:37:50 +01:00
Paul Elder
1dc01bc9e6 ipa: libipa: histogram: Add transform parameter to constructor
Add a parameter to the histogram constructor that takes a transformation
function to apply to all the bins upon construction.

This is necessary notably for the rkisp1, as the values reported from
the hardware are 20 bits where the upper 16-bits are meaningful integer
values and the lower 4 bits are fractional and meant to be discarded. As
adding a right-shift parameter is probably too specialized, a generic
function is added as a parameter instead.

While at it, optimize the existing constructor to avoid push_back() into
a vector with a known final size.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-05-09 20:31:06 +09:00
Laurent Pinchart
626172a16b libcamera: Drop file name from header comment blocks
Source files in libcamera start by a comment block header, which
includes the file name and a one-line description of the file contents.
While the latter is useful to get a quick overview of the file contents
at a glance, the former is mostly a source of inconvenience. The name in
the comments can easily get out of sync with the file name when files
are renamed, and copy & paste during development have often lead to
incorrect names being used to start with.

Readers of the source code are expected to know which file they're
looking it. Drop the file name from the header comment block.

The change was generated with the following script:

----------------------------------------

dirs="include/libcamera src test utils"

declare -rA patterns=(
	['c']=' \* '
	['cpp']=' \* '
	['h']=' \* '
	['py']='# '
	['sh']='# '
)

for ext in ${!patterns[@]} ; do
	files=$(for dir in $dirs ; do find $dir -name "*.${ext}" ; done)
	pattern=${patterns[${ext}]}

	for file in $files ; do
		name=$(basename ${file})
		sed -i "s/^\(${pattern}\)${name} - /\1/" "$file"
	done
done
----------------------------------------

This misses several files that are out of sync with the comment block
header. Those will be addressed separately and manually.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-05-08 22:39:50 +03:00
Daniel Scally
fdcd5d04ec ipa: rkisp1: Remove bespoke Agc functions
Now that the rkisp1 Agc algorithm is a derivation of MeanLuminanceAgc
we can remove the bespoke functions from the IPA's class.

Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-08 12:54:57 +01:00
Daniel Scally
4c5152843a ipa: rkisp1: Derive rkisp1::algorithms::Agc from AgcMeanLuminance
Now that we have a AgcMeanLuminance class that centralises our AEGC
algorithm, derive the RkISP1's Agc class from it and plumb in the
necessary framework to enable it to be used. For simplicities sake
this commit switches the algorithm to use the derived class, but
does not remove the bespoke functions at this time.

Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-08 12:54:56 +01:00
Daniel Scally
9b9a7b3f32 ipa: ipu3: Remove bespoke AGC functions from IPU3
Now that the IPU3's Agc is derived from MeanLuminanceAgc we can
delete all the unecessary bespoke functions.

Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-08 12:54:56 +01:00
Daniel Scally
87353f2bba ipa: ipu3: Derive ipu3::algorithms::Agc from AgcMeanLuminance
In preparation for switching to a derivation of AgcMeanLuminance, add
a function to parse and store the statistics for easy retrieval in an
overriding estimateLuminance() function.

Now that we have a MeanLuminanceAgc class that centralises our AEGC
algorithm, derive the IPU3's Agc class from it and plumb in the
necessary framework to enable it to be used. For simplicity's sake
this commit switches the algorithm to use the derived class, but
does not remove the bespoke functions at this time.

Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-08 12:54:56 +01:00
Daniel Scally
24247a12c7 ipa: libipa: Add AgcMeanLuminance base class
The Agc algorithms for the RkIsp1 and IPU3 IPAs do the same thing in
very large part; following the Rpi IPA's algorithm in spirit with a
few tunable values in that IPA being hardcoded in the libipa ones.
Add a new base class for AgcMeanLuminance which implements the same
algorithm and additionally parses yaml tuning files to inform an IPA
module's Agc algorithm about valid constraint and exposure modes and
their associated bounds.

Reviewed-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: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-08 12:54:56 +01:00
Paul Elder
34c9ab6282 ipa: libipa: Add ExposureModeHelper
Add a helper for managing exposure modes and splitting exposure times
into shutter and gain values.

Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-08 09:47:07 +01:00
Daniel Scally
6728160b11 libcamera: controls: Generate enum value-name maps
Generate maps for each control enum which associate strings that
represent the enum values with the values themselves. This change
will allow us to refer to enumerated control values using the
string. For example if we want to pass variables to an algorithm
for use when a control has a particular value we can embed within
tuning files a dictionary that uses the control values as keys.

Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-08 09:47:07 +01:00
Daniel Scally
76e2db61ee ipa: libipa: Allow creation of empty Histogram
For convenience's sake allow the creation of empty Histograms so
they can be embedded within other Classes and filled out with
data at some later point in time.

Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-08 09:47:07 +01:00
Laurent Pinchart
ea1e9eba74 Revert "meson: Deprecate bitwise operations between different enumeration type"
Enabling -Wdeprecated-enum-enum-conversion by default turned out to be a
too hasty decision. It causes compilation failures with Qt headers prior
to Qt v5.15.8. As the previous LTS versions of Debian and Ubuntu ship
older Qt versions, those errors cause real inconvenience to users.

This reverts commit bf4695266b.

The original goal of avoiding C++20 compilation regressions is still
handled through a test in CI.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-05-07 23:01:34 +03:00
Laurent Pinchart
6cd8491258 test: Don't add current build directory to include path
Meson adds the current source and build directory to the include path by
default. This causes a namespace clash in tests when using C++20, as the
Span class test is compiled into a binary named 'span', which then gets
included by source code through indirect '#include <span>' directives.
Unsurprisingly, the compiler doesn't react happily when fed binary data.

We could work around the problem by renaming the test executable, but
disabling the implicit inclusion of the local directory is a more
generic solution that will avoid similar issues in the future.

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-07 19:35:43 +03:00
Laurent Pinchart
bf4695266b meson: Deprecate bitwise operations between different enumeration type
C++20 deprecates bitwise operations between different enumeration types.
This is a bad practice even in C++17, so enable the deprecation warning.
Doing so ensures no such operations will be added.

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-05-03 17:58:44 +03:00
Laurent Pinchart
4885f2d70d apps: qcam: Use standard key sequence for quit action
Replace the manual CTRL+Q key sequence with QKeySequence::Quit. This
automatically maps to the native shortcut for the quit action,
regardless of the platform. Even though we don't expect qcam to run on
non-Linux platform, using a QKeySequence is still a good practice when
one exists.

This doesn't change qcam's behaviour, as the native quit key sequence is
CTRL+Q on Linux systems.

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-05-03 17:58:44 +03:00
Laurent Pinchart
acf61456cc libcamera: shared_mem_object: Fix compilation with uClibc
uClibc doesn't provide a memfd_create() implementation. Fix it by using
a direct syscall when the function isn't available.

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-05-03 17:58:44 +03:00
Laurent Pinchart
e0318c4776 libcamera: utils: Avoid infinite recursion with strtod()
When the C library doesn't provide local object support, the
utils::strtod() function simply calls strtod() from the C library. The
current implementation does so incorrectly, and calls utils::strtod()
instead, resulting in infinite recursion. Fix it with a proper namespace
qualifier.

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-05-03 17:58:43 +03:00
Alexander Stein
7235248d38 libcamera: libipa: camera_sensor: Add Sony IMX415 sensor properties
Provide the Sony IMX415 camera sensor properties and registration
with libipa for the gain code helpers.

The test patterns exposed by the IMX415 do not map well to the current
set of test pattern controls supplied by libcamera. These are left
intentionally unimplemented.

Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.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-05-03 17:58:41 +03:00
Barnabás Pőcze
77269a2869 apps: cam: Fix C++20 deprecation warning
C++20 deprecated implicit capture of `this` via `[=]`.
Fix that by explicitly capturing the necessary variables.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.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-05-03 17:57:45 +03:00
Kieran Bingham
6b1b2bd7ea libcamera: libipa: camera_sensor: Add Sony IMX335 sensor properties
Provide the Sony IMX335 camera sensor properties and registration
with libipa for the gain code helpers.

The test patterns exposed by the IMX335 do not map well to the current
set of test pattern controls supplied by libcamera. These are left
intentionally unimplemented.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-05-03 14:50:45 +05:30
Kieran Bingham
2ac544cfd6 libcamera: libipa: camera_sensor: Add Sony IMX283 sensor properties
Provide the IMX283 camera sensor properties and registration
with libipa for the gain code helpers.

The test patterns exposed by the IMX283 do not map well to the current
set of test pattern controls supplied by libcamera. These are left
intentionally unimplemented.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-05-03 14:50:43 +05:30
Anle Pan
fb74bb7df6 android: camera_device: Always clear descriptors_ in stop()
When flush() is called and then a new stream configuration is set, the
descriptors_ queue might have a chance to be not cleared in stop(), as
the Camera is already in Stopped state.

This will prevent further requests from being completed in
sendCaptureResults() as the descriptors_ queue is not empty.

To fix the issue, clear the descriptors_ even if the Camera State is
Stopped. As a drawback the libcamera::Camera::stop() function might be
called twice, but this is allowed by the Camera state machine, and the
second call is guaranteed to be a nop.

Signed-off-by: Anle Pan <anle.pan@nxp.com>
Signed-off-by: Fang Hui <hui.fang@nxp.com>
Tested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-20 01:37:25 +01:00
Umang Jain
503c3a838a libcamera: Fix output spelling error
There are two places where "output" is spelled as "ouput".
Fix it.

Signed-off-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: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-20 01:18:07 +01:00
Umang Jain
ae0752ba04 libcamera: device_enumerator: Fix spell error
In the description of DeviceMatch, the word 'appropriate' is
spelled incorrectly as 'appropriare'. Fix it.

Signed-off-by: Umang Jain <umang.jain@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-04-20 01:16:57 +01:00
Laurent Pinchart
7d79e9425e utils: checkstyle.py: Drop period at end of Doxygen one liners
The libcamera documentation style calls for no period at the end of the
Doxygen one-liner commands (\brief, \param and \return). Extend the
DoxygenFormatter class to drop the period.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-19 12:35:03 +03:00
Laurent Pinchart
fef732d4dc utils: checkstyle.py: Use r'' strings for regular expressions
It's a good practice to use r'' strings for regular expressions in
Python, to avoid unexpected interaction with string escape sequences.
Use them globally. This allows simplifying escaping in one of the
regular expression strings.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-19 12:34:57 +03:00
Kieran Bingham
dbd13a6f77 Documentation: coding-style: Clean up header guard style
Header guards were replaced by pragma once calls with commits
0a64cf8b76 ("libcamera: Convert to pragma once") through to
796210ecea ("v4l2: Convert to pragma once")

Update the coding style to reflect the updated header guard style.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-04-17 17:11:54 +01:00
Khem Raj
f4d416db91 ipu3: Use posix basename
musl does not implement GNU basename extention and with latest musl
the prototype from string.h is also removed [1] which now results in
compile errors e.g.

../git/utils/ipu3/ipu3-pack.c:21:47: error: call to undeclared function 'basename'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]

These utilities are using this function in usage() which is used just
before program exit. Always use the basename APIs from libgen.h which is
posix implementation

[1] https://git.musl-libc.org/cgit/musl/commit/?id=725e17ed6dff4d0cd22487bb64470881e86a92e7

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-17 10:56:03 +01:00
Milan Zamazal
b2ef255295 libcamera: software_isp: Apply black level compensation
Black may not be represented as 0 pixel value for given hardware, it may
be higher.  If this is not compensated then various problems may occur
such as low contrast or suboptimal exposure.

The black pixel value can be either retrieved from a tuning file for the
given hardware, or automatically on the fly.  The former is the right
and correct method, while the latter can be used when a tuning file is
not available for the given hardware.  Since there is currently no
support for tuning files in software ISP, the automatic, hardware
independent way, is always used.  Support for tuning files should be
added in future but it will require more work than this patch.

The patch looks at the image histogram and assumes that black starts
when pixel values start occurring on the left.  A certain amount of the
darkest pixels is ignored; it doesn't matter whether they represent
various kinds of noise or are real, they are better to omit in any case
to make the image looking better.  It also doesn't matter whether the
darkest pixels occur around the supposed black level or are spread
between 0 and the black level, the difference is not important.

An arbitrary threshold of 2% darkest pixels is applied; there is no
magic about that value.

The patch assumes that the black values for different colors are the
same and doesn't attempt any other non-primitive enhancements.  It
cannot completely replace tuning files and simplicity, while providing
visible benefit, is its goal.  Anything more sophisticated is left for
future patches.

A possible cheap enhancement, if needed, could be setting exposure +
gain to minimum values temporarily, before setting the black level.  In
theory, the black level should be fixed but it may not be reached in all
images.  For this reason, the patch updates black level only if the
observed value is lower than the current one; it should be never
increased.

The purpose of the patch is to compensate for hardware properties.
General image contrast enhancements are out of scope of this patch.

Stats are still gathered as an uncorrected histogram, to avoid any
confusion and to represent the raw image data.  Exposure must be
determined after the black level correction -- it has no influence on
the sub-black area and must be correct after applying the black level
correction.  The granularity of the histogram is increased from 16 to 64
to provide a better precision (there is no theory behind either of those
numbers).

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Hans de Goede
d9b2619e2e libcamera: Add "Software ISP benchmarking" documentation
Add a "Software ISP benchmarking" documentation section which describes the
performance/power consumption measurements used during the Software ISP's
development.

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
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-04-16 13:00:21 +01:00
Hans de Goede
09fb65486e libcamera: debayer_cpu: Add BGR888 output support
BGR888 is RGB888 with the red and blue pixels swapped, adjust
the debayering to swap the red and blue pixels in the bayer pattern
to add support for writing formats::BGR888.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Hans de Goede
17c58df4b4 libcamera: debayer_cpu: Add support for 8, 10 and 12 bpp unpacked bayer input
Add support for 8, 10 and 12 bpp unpacked bayer input for all 4 standard
bayer orders.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Hans de Goede
e19adc453f libcamera: swstats_cpu: Add support for 8, 10 and 12 bpp unpacked bayer input
Add support for 8, 10 and 12 bpp unpacked bayer input for all 4 standard
bayer orders.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Andrey Konovalov
c50065c9eb libcamera: pipeline: simple: Enable use of Soft ISP and Soft IPA
To enable the Simple Soft ISP and Soft IPA for simple pipeline handler
configure the build with:
  -Dpipelines=simple -Dipas=simple

Also using the Soft ISP for the particular hardware platform must
be enabled in the supportedDevices[] table.  It is currently enabled
for and only for qcom-camss.

If the pipeline uses Converter, Soft ISP and Soft IPA aren't
available.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Andrey Konovalov
4095a8184b libcamera: pipeline: simple: Rename converterBuffers_ and related vars
The converterBuffers_ and the converterQueue_ are not that specific
to the Converter, and could be used by another entity doing the format
conversion.

Rename converterBuffers_, converterQueue_, and useConverter_ to
conversionBuffers_, conversionQueue_ and useConversion_ to
disassociate them from the Converter.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Andrey Konovalov
6362bd46ca libcamera: Introduce SoftwareIsp
Doxygen documentation by Dennis Bonke.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Co-developed-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Andrey Konovalov
c987946e43 libcamera: ipa: Add Soft IPA
Define the Soft IPA main and event interfaces, add the Soft IPA
implementation.

The current src/ipa/meson.build assumes the IPA name to match the
pipeline name. For this reason "-Dipas=simple" is used for the
Soft IPA module.

Auto exposure/gain and AWB implementation by Dennis, Toon and Martti.

Auto exposure/gain targets a Mean Sample Value of 2.5 following
the MSV calculation algorithm from:
https://www.araa.asn.au/acra/acra2007/papers/paper84final.pdf

Use CameraSensorHelper to convert the analogue gain code read from the
camera sensor into real analogue gain value. In the future this makes
it possible to use faster AE/AGC algorithm. Right now the CameraSensorHelper
lets us use the full range of analogue gain values.

If there is no CameraSensorHelper for the camera sensor in use, a
warning log message is printed.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Co-developed-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
Co-developed-by: Marttico <g.martti@gmail.com>
Signed-off-by: Marttico <g.martti@gmail.com>
Co-developed-by: Toon Langendam <t.langendam@gmail.com>
Signed-off-by: Toon Langendam <t.langendam@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Hans de Goede
3755d96648 libcamera: software_isp: Add DebayerCpu class
Add CPU based debayering implementation. This initial implementation
only supports debayering packed 10 bits per pixel bayer data in
the 4 standard bayer orders.

Doxygen documentation by Dennis Bonke.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Co-developed-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
Co-developed-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Co-developed-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Hans de Goede
783f92c018 libcamera: software_isp: Add Debayer base class
Add a base class for debayer implementations. This is intended to be
suitable for both GPU (or otherwise) accelerated debayer implementations
as well as CPU based debayering.

Doxygen documentation by Dennis Bonke.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Co-developed-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
Co-developed-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Hans de Goede
c683e81947 libcamera: software_isp: Add SwStatsCpu class
Add a CPU based SwStats implementation for SoftwareISP / SoftIPA use.

This implementation offers a configure function + functions to gather
statistics on a line by line basis. This allows CPU based software
debayering to call into interleave debayering and statistics gathering
on a line by line basis while the input data is still hot in the cache.

This implementation also allows specifying a window over which to gather
statistics instead of processing the whole frame.

Doxygen documentation by Dennis Bonke.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Co-developed-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Co-developed-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Pavel Machek <pavel@ucw.cz>
Co-developed-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
Co-developed-by: Marttico <g.martti@gmail.com>
Signed-off-by: Marttico <g.martti@gmail.com>
Co-developed-by: Toon Langendam <t.langendam@gmail.com>
Signed-off-by: Toon Langendam <t.langendam@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Andrei Konovalov
9a2d7d3b6a libcamera: shared_mem_object: Reorganize the code and document the SharedMemObject class
The SharedMemObject class template contains a fair amount of inline code
that does not depend on the template types T. To avoid duplicating it in
every template specialization, split that code to a separate base
SharedMem class.

We don't define copy semantics for the classes (we don't need one at the
moment) and we make them non-copyable since the default copy constructor
would lead to use-after-unmap.

Doxygen documentation by Dennis Bonke and Andrei Konovalov.

Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Co-developed-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Dennis Bonke <admin@dennisbonke.com>
Signed-off-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Milan Zamazal
ce3c8a5082 libcamera: shared_mem_object: Rename SIZE constant to `size'
The SharedMemObject has been imported directly into the libcamera
internal components. Adapt the SIZE constant of the class to match the
libcamera coding style.

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>
2024-04-16 13:00:21 +01:00
Andrey Konovalov
bd801907bf libcamera: internal: Move SharedMemObject class to a common directory
Move SharedMemObject class out of RPi namespace and put it into
include/libcamera/internal so that everyone could use it.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Andrey Konovalov
87ee158ec8 libcamera: dma_heaps: extend DmaHeap class to support system heap
Add an argument to the constructor to specify dma heaps type(s)
to use. Can be DmaHeapFlag::Cma and/or DmaHeapFlag::System.
By default DmaHeapFlag::Cma is used. If both DmaHeapFlag::Cma and
DmaHeapFlag::System are set, CMA heap is tried first.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Andrey Konovalov
6062ada2f5 libcamera: internal: Move dma_heaps.[h, cpp] to common directories
DmaHeap class is useful outside the RPi pipeline handler too.

Move dma_heaps.h and dma_heaps.cpp to common directories. Update
the build files and RPi vc4 pipeline handler accordingly.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Andrey Konovalov
d89b15a612 libcamera: pipeline: simple: fix size adjustment in validate()
SimpleCameraConfiguration::validate() adjusts the configuration of its
streams (if the size is not in the outputSizes) to the captureSize. But
the captureSize itself can be not in the outputSizes, and then the
adjusted configuration won't be valid resulting in camera configuration
failure.

Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # sc8280xp Lenovo x13s
Tested-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-16 13:00:21 +01:00
Paul Elder
1c5830a9a4 utils: ipc: Fix async main interface functions with no parameters
If an async main interface function is defined with no parameters, there
would be a compilation error complaining about an extra comma. Fix this.

Signed-off-by: Paul Elder <paul.elder@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>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-04-13 19:25:01 +03:00
Paul Elder
9dc601cf7a utils: ipc: Fix event functions with no parameters
If an event function is defined with no parameters, there would be a
compilation error complaining about unused parameters in the generated
code for the data and dataSize parameters that would normally correspond
to serialized data. Fix this by simply marking the parameters as
maybe_unused.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-04-10 16:40:34 +09:00
Milan Zamazal
666f17affc apps: cam: Add support for PPM output format
When file output is requested from cam app, it simply dumps the
processed data and it must be converted to a readable image format
manually. Let's add support for PPM output file format to make files
produced by cam directly readable by image display and processing
software.

For now, only BGR888 output format, which is the simplest one to use, is
supported but nothing prevents adding support for other output formats
if needed. Nevertheless, they would typically need byte reordering or
other conversions for PPM file format. It may be better to find a way to
dump the image data in other output formats directly using some of the
already existing file formats or raw file format converters.

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-03-28 03:11:59 +02:00
Laurent Pinchart
48f3a25d7c v4l2: meson: Keep defines sorted alphabetically
Due to my mistake, commit 705601781b ("v4l2: Unset _TIME_BITS in
addition to _FILE_OFFSET_BITS") got merged with incorrect sorting of
defines. Fix it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-03-27 23:20:52 +02:00
Steve Langasek
705601781b v4l2: Unset _TIME_BITS in addition to _FILE_OFFSET_BITS
libcamera fails to build from source in Debian/Ubuntu on 32-bit
architectures under 64-bit time_t (to avoid the 'year 2038
problem'), because its v4l2 module legitimately un-sets
_FILE_OFFSET_BITS for building but this is not allowed without
also unsetting _TIME_BITS.

Having verified that nothing in this module is sensitive to 64-bit
time_t (none of the functions it intercepts handle time), we also
unset _TIME_BITS to allow this to build as before.

Signed-off-by: Steve Langasek <steve.langasek@canonical.com>
Reviewed-by: Dylan Aïssi <dylan.aissi@collabora.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-03-27 01:27:44 +02:00
Jacopo Mondi
0fbc801a1d libcamera: pipeline: Add Mali-C55 ISP pipeline
Add a pipeline handler for the Mali-C55 ISP.

The pipeline doesn't currently support an IPA and does not run
any 3a algorithm but only handles the media graph topology and
formats/sizes configuration

Co-developed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Acked-by: Nayden Kanchev <nayden.kanchev@arm.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-03-26 12:50:02 +01:00
Fang Hui
edef303bbe android: camera_device: Save capture settings unconditionally
As the Android framework sends to the camera device settings
incrementally (only the ones that change are updated), the CameraDevice
class in the Android camera HAL keeps a copy of the last received
settings to be able to apply controls to the libcamera Camera and to
populate metadata correctly.

When a valid 'camera3Request->settings' is provided, it gets saved to
'lastSettings_' but 'descriptor->settings_' is not initialized until
the next frame (assuming it does not contain more settings).

Fix this by assigning to 'descriptor->settings_' the last saved
settings unconditionally.

Signed-off-by: Fang Hui <hui.fang@nxp.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-03-22 11:05:49 +01:00
Jacopo Mondi
ed632bf37e apps: lc-compliance: Re-organize source directory
Before adding more tests and more helper classes to lc-compliance,
reorganize the source tree to split test and helpers in two separate
directories.

While at it, rename the 'SimpleCapture' class and its derived classes to
just 'Capture'. Rename the source files accordingly.

Re-sort headers inclusions to please checkstyle.py too.

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>
Tested-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-03-20 11:12:01 +01:00
Jacopo Mondi
b20e1e1c5a apps: lc-compliance: Fix typo in comment
Fix a small typo in a comment.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-03-20 11:12:01 +01:00
Nícolas F. R. A. Prado
3e93337996 apps: lc-compliance: Check that requests complete successfully
When a request fails to queue it is completed but with its status set to
RequestCancelled. Add a check in the requestComplete callback to make
sure that the request was completed successfully.

For the SimpleCaptureUnbalanced test we need to do this check only if
the capture isn't over yet, otherwise the few extra requests that get
cancelled at the end, which is the normal behavior, will make the test
fail.

Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-03-20 11:11:57 +01:00
Paul Elder
8106b6671f utils: tuning: readme: Improve names of dependency packages
Change the names of python packages in the list of dependencies to the
exact names that should be used in the pip install command.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-03-19 19:57:29 +09:00
Stefan Klug
62c31a352c checkstyle: Work around bug in difflib
If a file misses the newline at the end it gets detected by checkstyle,
but the resulting patch is incorrect and does not apply. It took me a
while to understand that it wasn't me using checkstyle incorrectly, but
that the patch was faulty. The bug itself is in difflib and dates back to
2008.

To reproduce:
- Remove trailing newline from a file
- git add the file
- run ./utils/checkstyle.py -s | patch -p0

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-03-15 14:14:59 +01:00
Laurent Pinchart
284919ef2e libcamera: camera_sensor: Expose the Bayer order
Pipeline handlers may need to know the Bayer order produced by the
sensor when a Transform is applied (horizontal or vertical flip). This
is currently implemented manually in the Raspberry Pi pipeline handler.
Move the implementation to the CameraSensor class to make it usable in
other pipeline handlers.

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-03-15 13:00:58 +02:00
Laurent Pinchart
58bcddbdeb libcamera: camera_sensor: Test for read-only HBLANK with READ_ONLY flag
The CameraSensor class tests if the sensor HBLANK control is read-only
by comparing the minimum and maximum values, and documents this as being
a workaround for the lack of a read-only control flag in V4L2. This is
incorrect, as the V4L2 API provides such a flag. Use it to replace the
workaround.

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-03-15 13:00:58 +02:00
Laurent Pinchart
2a6d432457 libcamera: camera_sensor: Reorder functions
The CameraSensor class has grown a lot since its creation, with many
functions added for different types of purposes. They are not grouped by
categories in the class definition, generating confusion when reading
the header file. Improve readability by sorting functions by category:

- Getters for static data (model, entity, focus lens, ...)
- Format and sensor configuration accessors
- Properties and controls (including test pattern mode)

Update the .cpp file accordingly.

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-03-15 13:00:58 +02:00
Laurent Pinchart
9b1a2a8c8b libcamera: camera_sensor: Drop updateControlInfo() function
The CameraSensor::updateControlInfo() function is a wrapper around the
same function of the V4L2Subdevice class. It was meant to be called by
pipeline handlers that modify the sensor configuration directly,
bypassing the CameraSensor::setFormat() function. This never happened,
and the function is called once only, internally to the CameraSensor
class. No external users are foreseen, drop the function and call
V4L2Subdevice::updateControlInfo() directly.

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-03-15 13:00:58 +02:00
Laurent Pinchart
2a0baf47eb libcamera: camera_sensor: Move related classes to subdirectory
In preparation for adding alternative implementations of the
CameraSensor class, move the code to a subdirectory to avoid cluttering
the main src/libcamera/ directory.

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-03-15 13:00:58 +02:00
Laurent Pinchart
c5a8152af2 libcamera: v4l2_subdevice: Add V4L2Subdevice::Route structure
The V4L2Subdevice class deals with streams in two places:

- In routing tables, streams as expressed as a pad number and a stream
  number in a v4l2_subdev_route instance.
- In the format and selection get and set functions, streams as
  expressed using the Stream structure, which binds the pad number and
  stream number.

Expressing streams in different ways requires pipeline handlers and
other helpers to convert between the two representations. This isn't
much of an issue yet as libcamera has little stream-aware code, but it
is expected to increasingly become a burden.

To simplify the API, introduce a V4L2Subdevice::Route structure that
mimicks the kernel v4l2_subdev_route structure but represents streams as
V4L2Subdevice::Stream instances. This will improve seamless integration
of routes, formats and selection rectangles.

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-03-15 13:00:49 +02:00
Laurent Pinchart
e8f01b37e8 libcamera: v4l2_subdevice: Replace Routing::toString() with operator<<()
The main (and only at the moment) use case for the Routing::toString()
function is to print a representation of the routing table in a log
message. The function is implemented using an std::stringstream, and the
returned std::string is then inserted into an std::ostream. This is
inefficient. Replace the function with a specialization of the
operator<<() and use it in the caller.

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-03-15 12:55:09 +02:00
Laurent Pinchart
0d2ad0cd84 libcamera: v4l2_subdevice: Add stream support to get/set functions
Extend the V4L2Subdevice API with stream support for the functions that
get and set formats and selection rectangles. Add a Stream structure to
identify a subdev pad and stream, and use it to extend the V4L2Subdevice
functions that get and set formats and selection rectangles with stream
support.

To preserve the existing pad-based API, implement overloaded functions
that wrap the new stream-based API. This allows callers that are not
stream-aware to use a simpler pad-based API, instead of having to
explicitly set the stream number to 0 in all API calls.

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-03-15 12:55:05 +02:00
Laurent Pinchart
d41e0585e9 libcamera: v4l2_subdevice: Rename V4L2SubdeviceFormat::mbus_code to code
The V4L2SubdeviceFormat::mbus_code member doesn't follow the libcamera
coding style as it should use camelCase. Fix it by renaming it to just
'code', to shorten lines in addition to fixing the coding style.

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-03-15 12:55:03 +02:00
Laurent Pinchart
4c82481fc4 libcamera: v4l2_subdevice: Drop V4L2SubdeviceFormat::bitsPerPixel()
The V4L2SubdeviceFormat::bitsPerPixel() function is just a wrapper
around a MediaBusFormatInfo lookup. It made sense when the
MediaBusFormatInfo class was not exposed outside of the compilation
unit, but is now redundant. Drop it and use MediaBusFormatInfo in the
only caller.

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-03-15 12:55:00 +02:00
Laurent Pinchart
7941903d62 libcamera: v4l2_subdevice: Extend MediaBusFormatInfo with metadata formats
Not all media bus formats describe image formats. Extend the
MediaBusFormatInfo class with a type member to indicate if the format
corresponds to image data or metadata, and add the (only) metatdata
format supported by the kernel to the known mediaBusFormatInfo.

The kernel doesn't (yet) have any metadata format specific to sensor
embedded data. This is being addressed in the V4L2 API. In preparation
for embedded data support, already introduce the EmbeddedData type here.
Corresponding formats will be added when available.

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-03-15 12:54:58 +02:00
Laurent Pinchart
d60fb23258 libcamera: v4l2_subdevice: Expose media bus format info as internal API
The V4L2SubdeviceFormatInfo structure, internal to the
v4l2_subdevice.cpp compilation unit, contains information about media
bus formats that will be useful in other parts of libcamera. To prepare
for this, expose the structure in the v4l2_subdevice.h header and turn
it into a class with a similar design as PixelFormatInfo.

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-03-15 12:54:56 +02:00
Laurent Pinchart
1a1cf4a2c1 libcamera: v4l2_subdevice: Add code member to MediaBusFormatInfo
To prepare for exposing the MediaBusFormatInfo structure as an internal
API, add a code member to the structure to store the media bus code.
This makes MediaBusFormatInfo usable standalone, without having to
externally associate the code related to the info.

The entries in the mediaBusFormatInfo map are becoming too long, so
split them on multiple lines.

While at it, swap the order of the members to match the PixelFormatInfo
class for consistency.

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-03-15 12:54:47 +02:00
Laurent Pinchart
3777d80acc libcamera: v4l2_subdevice: Rename V4L2SubdeviceFormatInfo
The V4L2SubdeviceFormatInfo structure contains information about a media
bus format, not a V4L2 subdevice format. Rename it to MediaBusFormatInfo
to clarify its purpose. Rename the formatInfoMap map accordingly.

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-03-15 12:54:44 +02:00
Stefan Klug
d54abd32af libcamera: controls: Add policy parameter to ControlList::merge()
This is useful in many cases although not included in the stl.

Note: This is an ABI incompatible change.

Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-03-12 17:04:28 +01:00
Barnabás Pőcze
2e2ba223f3 libcamera: framebuffer_allocator: Remove entry if allocation fails
Remove the entry from the `buffers_` mapping if
`Camera::exportFrameBuffers()` fails, otherwise
there would be a stale entry in the map.

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>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-03-12 10:09:56 +00:00
Barnabás Pőcze
ab5816a540 libcamera: framebuffer_allocator: Use default destructor
The compiler generated destructor works fine, so use that.

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>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-03-12 10:09:56 +00:00
Barnabás Pőcze
443734023c libcamera: framebuffer_allocator: Move from argument in constructor
The single argument, of type `std::shared_ptr<Camera>`,
is passed by value, so it can simply be moved from in order to
avoid calling the copy constructor.

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>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-03-12 10:09:56 +00:00
Paul Elder
01935edbba cam: capture_script: Make parseRectangles work for non-array
parseRectangles currently always parses Rectangle controls as an array
of Rectangles. This causes non-array Rectangle controls to not be parsed
correctly, as when the ControlValue is get()ed, the non-array assertion
will fail.

Set the ControlValue with a single Rectangle in case a single Rectangle
has been specified in the yaml capture script to fix that.

Signed-off-by: Paul Elder <paul.elder@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>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-03-11 14:50:14 +00:00
Hans de Goede
cdb07a0217 utils: checkstyle.py: Fix known_trailers sort order
An unruly libcamera maintainer merged the wrong patch adding the
Co-developed-by: tag to the known_trailers.

Fix the sort order alphabetically to match the version which should have
been merged.

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-03-11 14:24:14 +00:00
Hans de Goede
60f6e71cc4 utils: checkstyle.py: Add Co-developed-by to known_trailers
Add Co-developed-by to known_trailers to silence false positive
"Invalid commit trailer key 'Co-developed-by'" warnings.

Signed-off-by: Hans de Goede <hdegoede@redhat.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-03-11 13:04:01 +00:00
Nick Hollinghurst
caed5a551b ipa: rpi: cam_helper: Extend embedded data parsing to RAW14 modes
Fix embedded data byte-skipping for 14-bit modes (4 out of 7 bytes
carry register data), and allow 14-bit modes in IMX708 PDAF parsing.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-03-06 12:52:14 +00:00
Nick Hollinghurst
a63af956ac libcamera: v4l2_subdevice: Add 14-bit Bayer formats
Add MEDIA_BUS_FMT_SBGGR14_1X14 etc to formatInfoMap.
Not adding any Y14 for now.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-03-06 12:52:14 +00:00
Jacopo Mondi
1bf2d707e4 guides: pipeline-handler: Fix controlInfo_ initialization
Since commit b48db3c489 ("libcamera: controls: Create ControlInfoMap
with ControlIdMap"), instances of the ControlInfoMap class need to be
created with an instance of an unordered_map of ControlId to ControlInfo
and with a ControlIdMap instance.

The pipeline handler developer guide was never updated to reflect the
change. Fix it.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-03-05 10:09:41 +01:00
Kieran Bingham
be21f2747a libcamera: controls: Fix typo on thermal
The documentation for the SensorTemperature control has a spelling
mistake for thermal.

Fix it.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-03-01 23:16:09 +00:00
Suhrid Subramaniam
c64446c226 pipeline: simple: Add support for MediaTek MT8365 platforms
The camera pipeline for MediaTek MT8365 consists of the following:
Raw sensor (+ external ISP) --> SENINF --> CAMSV30 --> DRAM

SENINF (SENsor INterFace) is a CSI-2 receiver.
CAMSV30 (Camera Simple Version) is a DMA Engine which bypasses
ISP3.0 and writes directly to DRAM.
Both SENINF and CAMSV30 are supported by V4L2 drivers.

MT8365 platform consists of a hardware converter called MDP which
supports up to three streams.

Signed-off-by: Suhrid Subramaniam <suhrid.subramaniam@mediatek.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-02-28 16:57:35 +00:00
Kieran Bingham
4d122bfbb7 meson_options: Autodetect pycamera support
The pycamera was defaulted to be disabled due to a requirement
on a specialised branch of the pybind dependency.

This requirement on a subproject has been removed and we can
now build the pycamera component provided that the distribution
packages pybind directly which is common.

Enable the pycamera build option to be selected automatically
when both Python and pybind are detected on the system.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-02-28 11:43:38 +00:00
Kieran Bingham
36753f5cbb README.rst: Report py dependencies
The Python bindings were supported by a subproject when they were first
contributed to be able to directly make use of the smart pointers
branch.

This requirement has now been removed to prefer using released versions
of pybind11 directly, however the README.rst was not updated to
reference and reflect this.

Update the README.rst to report the pybind11 package which needs to be
installed to make use of the optional Python bindings component.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-02-28 11:43:34 +00:00
Kieran Bingham
bdd85fa01c utils: ipu3: Fix return value check on file output
The data parsed by ipu3-unpack is written out using the write() c
library call, but the error code is incorrectly checked which misses the
single erroroneous return value returned by the function.

Fix it to explicitly check against the error code.

Fixes: 23ac77dc4a ("utils: ipu3: Add IPU3 raw capture unpack utility")
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-02-28 11:09:11 +00:00
Kieran Bingham
25a8d8b8a9 libcamera: formats: Fix planes bounds check
The plane validation in the stride helper incorrectly accepts the number
of planes as a plane index. Fix the off by one issue.

Fixes: e83727a194 ("libcamera: PixelFormatInfo: Add functions stride and frameSize")
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-02-28 11:09:02 +00:00
Laurent Pinchart
26d9e36d3e utils: rkisp1: gen-csc-table.py: Don't presume python3 location
The python3 binary may be present in a location other than /usr/bin/.
Use /usr/bin/env to locate it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-02-27 15:53:46 +02:00
Milan Zamazal
51054cef60 utils: checkstyle.py: Update LogCategoryChecker regexp
The regexp uses obsolete form, update it to mute the warning emitted by Python
3.12:

  SyntaxWarning: invalid escape sequence '\('

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-02-27 15:39:33 +02:00
Milan Zamazal
08556380b8 utils: checkstyle.py: Don't presume python3 location
python3 binary may be present in a location other than /usr/bin/.

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-02-27 15:39:33 +02:00
Laurent Pinchart
f26e75fd0f libcamera: formats: Fix typos in PixelFormatInfo documentation
The PixelFormatInfo documentation has typo. Fix two of them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-02-27 15:39:28 +02:00
Laurent Pinchart
dae4a44067 libcamera: Use utils::to_underlying()
Replace manual implementations of the utils::to_underlying() helper with
calls to the function.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2024-02-27 11:48:44 +02:00
Laurent Pinchart
6a50c960be libcamera: utils: Add to_underlying() helper function
C++23 has a std::to_underlying() helper function that converts an
enumeration value to its underlying type. Add a compatible
implementation to the libcamera::utils namespace.

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>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2024-02-27 11:47:48 +02:00
Paul Elder
059bbcdc34 ipa: rkisp1: Support the i.MX8MP ISP version
Handle the RKISP1_V_IMX8MP version in the rkisp1 IPA. This enables basic
support of the i.MX8MP, excluding the processing blocks specific to the
new ISP version. Those will be supported later.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-02-23 15:18:34 +02:00
Paul Elder
d2436c57d7 include: linux: Add RKISP1_V_IMX8MP version
Patches have been posted to the linux-media@vger.kernel.org mailing list
to add i.MX8MP support to the rkisp1 driver ([1]). As no changes are
expected to the userspace API in future versions of the series, add the
RKISP1_V_IMX8MP version manually to the rkisp1-config.h header already.
Once the patches get merged in the kernel, the changes will trickle down
to libcamera with the next kernel headers update.

[1] https://lore.kernel.org/linux-media/20240216095458.2919694-1-paul.elder@ideasonboard.com/

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-02-23 15:18:26 +02:00
Laurent Pinchart
a5e6b7f0db ipa: rkisp1: Fix histogram weights configuration
The histogram weights are initialized to hardcoded 1's for each
histogram grid cell. The code uses the wrong variable for the grid size,
resulting in some weights having a 0 value. Fix it.

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-02-23 15:12:42 +02:00
Laurent Pinchart
528dc21b09 ipa: rkisp1: Store hardware parameters in IPA context
Versions of the ISP differ in the processing blocks they include, as
well as in the implementation of some of those blocks. In particular,
they have different numbers of histogram bins oe AE statistics cells.
The algorithms take these differences into account by checking the ISP
version reported by the driver.

These checks are currently scattered in multiple places. Centralize them
in the IPARkISP1::init() function, and store the version-dependent
hardware parameters in the IPA context, accessible by all algorithms.

While at it, drop the IPASessionConfiguration::hw member that stores the
revision number, unused by the algorithms. It can be added back laer to
the IPAHwSettings structure if needed.

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-02-23 15:12:33 +02:00
Laurent Pinchart
971c4904ff ipa: rkisp1: agc: Wrap variable length C arrays in spans
The RkISP1 statistics structure contains multiple arrays whose length
varies depending on the hardware revision. Accessing those arrays is
error-prone, wrap them in spans at the top level to reduce risks of
out-of-bound accesses.

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-02-23 15:12:15 +02:00
David Plowman
366077c4db pipeline: rpi: vc4: Use an unpacked format if no packed one is available
When validating a stream, and no valid packed pixel format can be
found, see if an unpacked format can be used instead.

This is particularly helpful for 8 (and 16) bit raw formats, where
asking for a packed format would previously have failed. Now the
configuration will be adjusted to give you a format (in fact, the only
format) that will work.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-02-23 15:12:15 +02:00
Naushir Patuck
5e4dc46a0c utils: mojom: Fix build error caused by the mojom tool update
The update to the mojom tool in commit d17de86904 causes build errors
with gcc 12.2 release builds. One such error is:

In file included from src/libcamera/proxy/worker/raspberrypi_ipa_proxy_worker.cpp:18:
In static member function ‘static libcamera::ipa::RPi::ProcessParams libcamera::IPADataSerializer<libcamera::ipa::RPi::ProcessParams>::deserialize(std::vector<unsigned char>::const_iterator, std::vector<unsigned char>::const_iterator, libcamera::ControlSerializer*)’,
    inlined from ‘void IPAProxyRPiWorker::readyRead()’ at src/libcamera/proxy/worker/raspberrypi_ipa_proxy_worker.cpp:302:70:
include/libcamera/ipa/raspberrypi_ipa_serializer.h:1172:32: error: ‘*(uint32_t*)((char*)&ret + offsetof(libcamera::ipa::RPi::ProcessParams, libcamera::ipa::RPi::ProcessParams::buffers.libcamera::ipa::RPi::BufferIds::bayer))’ may be used uninitialized [-Werror=maybe-uninitialized]
 1172 |                         return ret;

The failure is caused by the new auto-generated IPA interface not
initialising POD types to a default value. This is because the updated
mojom library uses a new mojom.ValueKind class to represent POD types,
whereas the interface generator script uses the mojom.Kind class, which
is correct for the older mojom library.

Fix this breakage by switching the interface generator script to use
mojom.ValueKind to test for POD types.

Fixes: d17de86904 ("utils: ipc: Update mojo")
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-02-15 11:38:25 +00:00
Nicolas Dufresne
38d28cc5fc gstreamer: Map 10/12/14/16 bayer formats supports
These formats are now defined in upstream GStreamer main branch, so it
is now safe to use their names. Note that libcamera only supports little
endian variants of these formats.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-02-02 11:33:13 +02:00
Nicolas Dufresne
05894d2652 gstreamer: Map R8/R16 pixel format
This enables monochrome support in libcamerasrc.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-02-02 11:33:09 +02:00
Nicolas Dufresne
1dd3bd9d7d doc: gstreamer: Add missing queues
As libcamerasrc reports some latency, a queue is needed in order to store the
data in case the buffers has been produced slightly ahead of our reported
latency.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-02-02 11:26:24 +02:00
Laurent Pinchart
6f1bd9cf55 libcamera: object: Add and use thread-bound assertion
Several functions in libcamera classes are marked as thread-bound,
restricting the contexts in which those functions can be called. There
is no infrastructure to enforce these restrictions, causing difficult to
debug race conditions when they are not met by callers.

As a first step to solve this, add an assertThreadBound() protected
function to the Object class to test if the calling thread context is
valid, and use it in member functions of Object subclasses marked as
thread-bound. This replaces manual tests in a few locations.

The thread-bound member functions of classes that do not inherit from
Object are not checked, and neither are the functions of classes marked
as thread-bound at the class level. These issue should be addressed in
the future.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:39:22 +02:00
Laurent Pinchart
56f817892c libcamera: object: Document and ensure Object deletion constraints
Object instances are meant to be deleted from the thread they are bound
to, and this requirement is documented. There are however exceptions to
the rule, as threads may be stopped and restarted, with objects bound to
them not being deleted and recreated for every stop/restart cycle. Bound
objects may therefore need to be deleted after the thread has stopped,
making it impossible to use Object::deleteLater().

Document the lifetime requirements more precisely, and enforce them with
an assertion.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:39:21 +02:00
Laurent Pinchart
fdcea5ad79 test: timer-thread: Destroy Object from correct thread context
The TimeoutHandler used in the test is destroyed from the main thread,
which is invalid for a thread-bound object bound to a different thread.
Fix it by destroying it with deleteLater().

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:39:20 +02:00
Laurent Pinchart
4f76beae86 test: timer-thread: Move timer start from wrong thread to separate test
Starting a timer from the wrong thread is expected to fail, and we test
this in the timer-thread unit test. This is however not something that a
caller is allowed to do, and libcamera will get assertion failures to
catch this invalid usage. The unit test will then fail.

To prepare for this, split the unit test in two, with a test that is
expected by meson to succeed, and one that is expected to fail. The
assertion will then cause an expected failure, making the test suite
succeed.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:39:15 +02:00
Laurent Pinchart
dfe81fd702 test: signal-threads: Destroy Object from correct thread context
The SignalReceiver used in the test is destroyed from the main thread,
which is invalid for a thread-bound object bound to a different thread.
Fix it by destroying it with deleteLater().

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:39:14 +02:00
Laurent Pinchart
edbcdebba7 test: message: Destroy Object from correct thread context
The MessageReceiver and RecursiveMessageReceiver used in the test are
destroyed from the main thread, which is invalid for a thread-bound
object bound to a different thread. Fix it by destroying them with
deleteLater().

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:39:12 +02:00
Laurent Pinchart
652b47249a test: message: Remove incorrect slow receiver test
The slow receiver test verifies there's no race condition between
concurrent message delivery and object deletion. This is not a valid use
case in the first place, as objects are not allowed to be deleted from a
different thread than the one they are bound to. Remove the incorrect
test.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:39:10 +02:00
Laurent Pinchart
1f5d485bfb test: event-thread: Destroy Object from correct thread context
The EventHandler used in the test is destroyed from the main thread,
which is invalid for a thread-bound object bound to a different thread.
Fix it by destroying it with deleteLater().

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:39:08 +02:00
Laurent Pinchart
f422624d9c libcamera: thread: Ensure deferred deletion of all objects before stopping
Objects can be scheduled for deletion with Object::deleteLater(), which
queues a deferred deletion to the thread's event loop. As the
deleteLater() function is meant to be called from a different thread,
this may race with thread termination, and deferred deletions queued
just before calling Thread::exit() may not be processed by the event
loop. Make sure they get processed when finishing the thread, before
stopping.

This eliminates the race condition that occurs when calling
Object::deleteLater() followed by Thread::exit() from the same thread.
Calling deleteLater() from neither the thread the object is bound to or
the thread calling Thread::exit() is still inherently racy.

The change fixes a failure in the object-delete unit test.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:39:05 +02:00
Laurent Pinchart
d47fa37c2e test: object-delete: Test deferred delete just before thread stops
The Object::deleteLater() function is expected to not race with stopping
the thread the object is bound to. Add a test for this.

The test currently fails, demonstrating a bug in libcamera.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:39:02 +02:00
Laurent Pinchart
d5c9b726bd libcamera: signal: Replace object.h inclusion with forward declatation
The signal.h header doesn't need to include object.h. Replace it with a
forward declaration, and instead include object.h in source files that
require it. It can speed up compilation a little bit, but more
importantly avoids unintended dependencies from the Signal class to the
Object class to be added later as the compiler will catch them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:38:59 +02:00
Laurent Pinchart
fc4ded714d libcamera: object: Fix thread-bound reference in documentation
The Object::message() function is documented as thread-bound without
using the correct \threadbound reference. Fix it to ensure it gets
included in the thread safety context list.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-01-25 02:38:58 +02:00
Paul Elder
64502c8d4a apps: common: dng_writer: Add a default case for switch-case on a modulo
Clearly all cases in the switch are already satisfied, but some
compilers fail to realize this and spit out an error:

Compiler version: gcc 11.2.0 "aarch64-buildroot-linux-gnu-gcc.br_real (Buildroot 2021.11) 11.2.0"

../../src/apps/common/dng_writer.cpp: In function ‘void thumbScanlineIPU3(const FormatInfo&, void*, const void*, unsigned int, unsigned int)’:
../../src/apps/common/dng_writer.cpp:277:55: error: ‘val4’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  277 |                 uint8_t value = (val1 + val2 + val3 + val4) >> 10;
      |                                                       ^~~~
../../src/apps/common/dng_writer.cpp:277:48: error: ‘val3’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  277 |                 uint8_t value = (val1 + val2 + val3 + val4) >> 10;
      |                                                ^~~~
../../src/apps/common/dng_writer.cpp:277:41: error: ‘val2’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  277 |                 uint8_t value = (val1 + val2 + val3 + val4) >> 10;
      |                                         ^~~~
../../src/apps/common/dng_writer.cpp:277:34: error: ‘val1’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  277 |                 uint8_t value = (val1 + val2 + val3 + val4) >> 10;
      |                                  ^~~~

Add a default case for the switch-case on a modulo to silence this.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=207
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-01-24 17:29:24 +02:00
Kieran Bingham
4d9eac1a68 libcamera: v4l2_subdevice: Explain sort order of formatInfoMap
The sort order used in the table isn't obvious. Reference the source of
linux/media-bus-format.h at the top of the table for reference for
future updates.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-23 17:17:09 +00:00
Kieran Bingham
d11c6359b5 libcamera: bayer_format: Add Y12 to bayerToFormat
Support for Mono 12-bit formats were added to the mbusCodeToBayer table
without supplying the corresponding entry for converting the other way.

Add the relevant entry to the bayerToFormat table.

Fixes: ec63095716 ("libcamera: bayer_format: Add unpacked mono 12-bit format to the conversion table")
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-23 17:17:09 +00:00
Kieran Bingham
f87e4c3908 libcamera: formats: Fix sort ordering of R10_CSI2P
Move formats::R10_CSI2P to be grouped with the formats::R10 counterpart
and keep the section of format declarations sorted in increasing bit
depth.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-23 17:17:09 +00:00
Naushir Patuck
2ab8b8d48a libcamera: formats: Add 16-bit mono format
Add the relevant definitions for a 16-bit mono pixel and media-bus
format.

Signed-off-by: Naushir Patuck <naush@raspberrypi.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-01-23 17:17:09 +00:00
Laurent Pinchart
6fb55e1e70 libcamera: Remove empty formats.c
Commit e0a51061bc ("libcamera: formats: Add 14-bits Bayer RAW
formats") added an empty formats.c file by mistake (and we failed to
catch it during review). Delete it.

Fixes: e0a51061bc ("libcamera: formats: Add 14-bits Bayer RAW formats")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-23 02:21:39 +02:00
Elias Naur
0dc737d3e3 pipeline: rpi: Always initialize the embedded buffer in tryRunPipeline
Vc4CameraData::findMatchBuffers() may return successfully with a null
embedded buffer, in which case the embedded buffer id would be left
uninitialized.

Without this change, libcamera v0.2.0 usually crashes for me with an
assertion error:

 ipa_base.cpp:397 assertion "it != buffers_.end()" failed in prepareIsp()

Signed-off-by: Elias Naur <mail@eliasnaur.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-01-23 02:21:39 +02:00
Nicolas Dufresne
484c86ac65 test: gstreamer: Use env instead of registry edit
Instead of editing the registry, use gst_env variable provided by the plugin and
already used as part of the devenv shell. This reduces the complexity of the
C++ test code.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-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-01-23 02:21:39 +02:00
Nicolas Dufresne
ebc396fc7a gstreamer: Add meson devenv support
This change to the build system will prepend the plugin build directory
to GST_PLUGIN_PATH environment. This makes the built plugin visible to
GStreamer inside meson devenv enabling uninstalled testing. In order to
avoid polluting the user registry, the GST_REGISTRY environment is also
set.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-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-01-23 02:21:39 +02:00
Paul Elder
81791d2cac utils: ipc: extract-docs: Fix escape characters in regex
Newer versions of python now generate a SyntaxWarning (SyntaxError in
the future [1]) for invalid escape sequences. Fix this, as there were
invalid escape sequences in the regexes:

"libcamera/utils/ipc/./extract-docs.py:13: SyntaxWarning: invalid escape
sequence '\/'"

[1] https://docs.python.org/3.12/library/re.html

Reported-by: Nicolas Dufresne <nicolas@ndufresne.ca>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-01-23 02:21:30 +02:00
Neal Gompa
e683297374 Documentation: Update Qt documentation links to Qt 6
The documentation is effectively the same, but we should be pointing
to the actively supported and used Qt version.

Signed-off-by: Neal Gompa <neal@gompa.dev>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-01-22 09:44:03 +02:00
Neal Gompa
fdd479dd63 libcamera: base: signal: Update Qt documentation link to Qt 6
The documentation is effectively the same, but we should be pointing
to the actively supported and used Qt version.

Signed-off-by: Neal Gompa <neal@gompa.dev>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-01-22 09:43:59 +02:00
Laurent Pinchart
0d99f2de13 libcamera: v4l2_subdevice: Enable streams API when supported
The streams API needs to be enabled explictly by setting a subdev client
capability. Do so unconditionally for subdevs that expose streams
support. We don't need any kernel version check to use the
VIDIOC_SUBDEV_S_CLIENT_CAP ioctl, as it is guaranteed to be supported by
kernels that support streams.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-17 19:36:59 +02:00
Laurent Pinchart
df770d4b0a include: linux: Update kernel headers to version v6.7
Update kernel headers to v6.7 using utils/update-kernel-headers.sh
and re-instating libcamera local modifications.

The V4L2_SUBDEV_CAP_MPLEXED flag has been renamed to
V4L2_SUBDEV_CAP_STREAMS in the upstream streams API. Adapt the code base
accordingly. The flag's numerical value hasn't changed, there is no ABI
breakage introduced by the API update.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-17 19:36:47 +02:00
Laurent Pinchart
439cfe7fbd libipa: camera_sensor_helper: Mark createInstance() with override
The CameraSensorHelperFactory::createInstance() function overrides a
virtual function from CameraSensorHelperFactoryBase. The function
declaration doesn't mark it with the override keyword. This could cause
issues in the future if the base class' function changes, as the
compiler will not issue any warning in that case. Fix it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-12 12:49:20 +02:00
Kieran Bingham
89227a428a libcamera v0.2.0
ABI Compliance:

abi-compliance-checker reports  94.6% binary compatibilty and 97.6% source
compatibility between 0.1.0 and 0.2.0. The SONAME has been updated accordingly
and applications must be relinked against this version of libcamera.

 - Binary compatibility: 94.6%
 - Source compatibility: 97.6%
 - Total binary compatibility problems: 5, warnings: 2
 - Total source compatibility problems: 3, warnings: 3

The key ABI/API differences here are:

 - AeFlicker

   The control "SceneFlicker" has been removed and replaced by
   AeFlickerMode, AeFlickerDetected and AeFlickerPeriod.

 - struct CameraConfiguration

   Field transform has been removed from the middle position of this structural type.
   Field orientation has been added at the middle position of this structural type.
   Field sensorConfig has been added at the middle position of this structural type.
   Size of this type has been changed from 40 bytes to 96 bytes.

Bugs:

The following bugs are resolved with this release:

 https://bugs.libcamera.org:
 - Bug 91 - libcamerasrc is missing EOS handling
 - Bug 199 - Install error on Ubuntu for Orange Pi 5
 - Bug 205 - ipa_proxy_worker.cpp fails to compile if an interface function has
             two arguments of SharedFD type
 - Bug 206 - Fails to build with Python 3.12

 https://github.com/raspberrypi/libcamera/issues:
 - Assertion '!this->empty()' failed in libcamera::utils::Duration - libcamera-tools 0.0.5-1 #64

Integration overview:

core:
 - utils: checkstyle.py: Treat Malformed trailers as a CommitIssue
 - utils: checkstyle.py: Initialise staged trailers
 - utils: checkstyle.py: Derive Amendment from Commit
 - utils: checkstyle.py: Check trailers for Amendment commits
 - libcamera: controls: Add controls for AEC/AGC flicker avoidance
 - libcamera: yaml: Increase the YAML parser limit
 - utils: checkstyle.py: Extract title and trailers with one command
 - meson: Correctly locate libc++
 - Documentation: theme: Fix compilation with Sphinx >= 7.0.0
 - libcamera: Remove duplicated SortIncludes in `.clang-format`
 - libcamera: stream: Document stride will be 0 for compressed formats
 - README.rst: Drop recommendation to install meson using pip3
 - meson: Don't set _FORTIFY_SOURCE for ChromeOS
 - meson: Simplify check for _FORTIFY_SOURCE
 - libcamera: formats: Fix typo in YV444 V4L2PixelFormat listing
 - Documentation: Introduce Camera Sensor Model
 - libcamera: camera: Introduce SensorConfiguration
 - libcamera: camera_sensor: Support SensorConfiguration
 - libcamera: converter: A few fixes to ConverterFactoryBase documentation
 - libcamera: converter: drop unnecessary #include directive
 - utils: update-kernel-headers: Support git worktrees
 - libcamera: camera_sensor: Cache rotationTransform_
 - libcamera: camera: Introduce Orientation
 - Documentation: Add figures to document Orientation
 - libcamera: properties: Make 'Rotation' the mounting rotation
 - libcamera: transform: Add functions to convert Orientation
 - libcamera: transform: Invert operator*() operands
 - libcamera: transform: Add operations with Orientation
 - test: Add unit test for Transform and Orientation
 - libcamera: Use CameraConfiguration::orientation
 - libcamera: camera_sensor: Cache mounting orientation instead of transform
 - libcamera: transform: Fold transformToOrientation() in its only caller
 - libcamera: transform: Make the transformFromOrientation() function static
 - libcamera: controls: Add controls for HDR
 - libcamera: camera_sensor: Only access V4L_CID_HBLANK if existing
 - Documentation: Add code of conduct
 - Documentation: code-of-conduct: Convert to reStructuredText
 - Documentation: code-of-conduct: Add license information
 - Documentation: code-of-conduct: Add contact information
 - Documentation: contributing: Integrate the code of conduct
 - README.rst: Use code directive for all code examples
 - Documentation: Fix list indentation
 - controls: Add vendor control/property support to generation scripts
 - controls: Update argument handling for controls generation scripts
 - build: controls: Rework how controls and properties are generated
 - libcamera: control: Add vendor control id range reservation
 - libcamera: controls: Use vendor tags for draft controls and properties
 - documentation: Document vendor specific controls and properties handling
 - README.rst: Drop indirect dependencies on Qt5 packages
 - README.rst: Document dependencies for the Python bindings
 - meson_options: Sort options alphabetically
 - meson: Tag all installed files
 - test: log: log_process: Log an error when failing due to incorrect message
 - test: log: log_process: Fix uninitialized variable on process exit failure
 - test: log: log_process: Improve debugging on process exit failures
 - test: log: log_process: Increase process exit timeout
 - test: ipc: unixsocket: Increase process exit timeout
 - test: gstreamer: Remove videoconvert element from pipeline
 - README.rst: Add missing libgtest-dev dependency for lc-compliance
 - meson: Replace hack with usage of '@BASENAME@'
 - libcamera: camera: Fix unused variable compiler warning
 - Documentation: camera-sensor-model: Support Sphinx < 2.0
 - libcamera: camera_sensor: Add OV64A40 sensor properties
 - utils: ipc: Fix deserialization of multiple fd parameters
 - libcamera: device_enumerator: ensure deviceNode is not empty
 - utils: ipc: mojom_libcamera_generator.py: Fix Python warning
 - libcamera: framebuffer_allocator: Remove unnecessary `clear()`
 - hooks: pre-push: Disable interpretation of escape sequences
 - libcamera: geometry: Correct doxygen reference to classes
 - utils: update-mojo.sh: Properly remove old sources
 - utils: update-mojo.sh: Exit immediately on error
 - utils: update-mojo.sh: Change to the libcamera source directory
 - utils: update-mojo.sh: Reject a dirty libcamera tree
 - utils: update-mojo.sh: Commit the mojo update
 - utils: ipc: generate.py: Add bindings directory to Python path
 - utils: ipc: generate.py: Disable attributes checker
 - utils: ipc: Update mojo

pipeline:
 - libcamera: rpi: pipeline_base: Remove populateSensorFormats()
 - libcamera: rpi: pipeline_base: Move findBestFormat to CameraData
 - libcamera: rpi: pipeline_base: Cache sensor format
 - pipeline: rpi: Don't call toV4L2DeviceFormat() from validate()
 - pipeline: rpi: Increase buffer import count to 32
 - pipeline: rpi: Remove additional external dma buf handling logic
 - pipeline: rpi: Rename RPi::Stream::setExternalBuffer()
 - pipeline: rpi: Simplify buffer id generation
 - pipeline: rpi: Reset the frame lengths queue during configure
 - libcamera: rpi: Handle SensorConfiguration
 - libcamera: rpi: Allow platformValidate() to adjust format strides
 - libcamera: rpi: Fix wrong comment indentation
 - libcamera: rpi: Make isRaw/isYuv/isRgb static functions
 - libcamera: rpi: Cache rawStreams and outStreams
 - libcamera: rpi: Add some helpers to PipelineHandlerBase
 - libcamera: rpi: Simplify validate() and configure() for RAW streams
 - libcamera: rpi: Change default stream formats
 - libcamera: rpi: Simplify validate() and configure() for YUV/RGB streams
 - pipeline: rpi: Add RequiresMmap flag to RPi::Stream
 - pipeline: rpi: Add Recurrent and Needs32bitConv flags to RPi::Stream
 - pipeline: rpi: Add SharedMemObject class
 - pipeline: rpi: Add SW downscale status to RPi::Stream
 - pipeline: rpi: Move flip handling validation code
 - pipeline: rpi: Make color space members in RPiCameraConfiguration public
 - pipeline: rpi: vc4: Allocate more embedded data buffers
 - pipeline: rpi: Remove unused variable
 - pipeline: rpi: vc4: Fix drop frame bug when no ISP streams are configured
 - pipeline: rpi: Add some useful logging messages
 - libcamera: pipeline: Fix c++20 compile warning
 - pipeline: rpi: Respect provided stride

ipa:
 - ipa: rpi: common: Handle AEC/AGC flicker controls
 - utils: raspberrypi: ctt: Improved color matrix fitting
 - ipa: rpi: vc4: data: Updated color matrices for RPi Cameras
 - utils: raspberrypi: ctt: Code tidying
 - ipa: rpi: Fix the reporting of Focus FoMs
 - ipa: rpi: imx290: Hide one frame on startup
 - ipa: rpi: agc: Fetch AWB status in process method, not prepare
 - ipa: rpi: agc: Filter exposures before dealing with digital gain
 - ipa: rpi: agc: Split AgcStatus into AgcStatus and AgcPrepareStatus
 - ipa: rpi: vc4: Make the StatisticsPtr construction clearer
 - ipa: rpi: histogram: Add interBinMean()
 - ipa: rpi: agc: Reorganise code for multi-channel AGC
 - ipa: rpi: agc: Implementation of multi-channel AGC
 - ipa: rpi: agc: Add AgcChannelConstraint class
 - ipa: rpi: agc: Use channel constraints in the AGC algorithm
 - ipa: rpi: Fix segfault when parsing invalid json file
 - ipa: rpi: Fix frame count logic when running algorithms
 - ipa: rpi: Avoid skipping IPAs on the first frame after the drop frames
 - ipa: rpi: Add IpaBase::platformStart() member function
 - mojom: pipeline: ipa: rpi: Add fields for PiSP objects
 - ipa: rpi: Add try_lock() to RPiController::Metadata
 - ipa: rpi: Add statsInline to the Controller hardware description
 - ipa: rpi: Add PiSP definitions to the Controller hardware description
 - ipa: rpi: Prepare ALSC for PiSP support
 - ipa: rpi: Prepare AWB for PiSP support
 - ipa: rpi: Add new algorithms for PiSP
 - build: ipa: Fix bug in building multiple IPA interfaces with the same mojom file
 - ipa: rpi: agc: Add an AGC stable region
 - ipa: rpi: contrast: Allow adaptive contrast enhancement to be disabled
 - ipa: rpi: denoise: Support different denoise configurations
 - ipa: rpi: agc: Avoid overwriting caller's statistics pointer
 - ipa: rpi: agc: When AGC channels are changed, start with the 1st channel
 - ipa: rpi: hdr: Add the ability to alter the LSC table
 - ipa: rpi: alsc: Do not re-read the alsc.status metadata
 - ipa: rpi: agc: Allow AGC channels to avoid using "fast desaturation"
 - ipa: rpi: vc4: Move denoise control handling into the VC4 derived IPA
 - ipa: rpi: agc: Fetch AWB status in the prepare method
 - ipa: rpi: agc: Make AGC controls affect all channels
 - ipa: rpi: alsc: Do not allow zero colour ratio statistics
 - ipa: rpi: agc: Fix bug where AeLocked was never getting set
 - ipa: rpi: cac: Minor code improvements and tidying
 - ipa: rpi: Add hardware line rate constraints
 - ipa: rpi: Allow the mean of an empty histogram interval
 - ipa: rpi: black_level: Add an initialValues method
 - ipa: rpi: awb: Add an initialValues method
 - utils: raspberrypi: ctt: Improve the Macbeth Chart search reliability
 - build: controls: Add Raspberry Pi vendor specific controls
 - ipa: vc4: Implement the StatsOutputEnable vendor control
 - ipa: rpi: Provide a Camera Helper for the OV64A40
 - libipa: camera_sensor_helper: Add OV64A40 helper
 - ipa: rpi: vc4: Add OV64A40 tuning files
 - ipa: rpi: Implement HDR control
 - ipa: rpi: vc4: data: Update tuning files for HDR

apps:
 - android: camera_device: Fix requestedStream handling
 - py: Add the SensorConfiguration class
 - py: gen-py-controls: Remove SceneFlicker workaround
 - apps: qcam: Add support for RGB565
 - py: libcamera: Define and use Orientation
 - apps: cam: Add option to set stream orientation
 - py: cam: Add option to set stream orientation
 - gstreamer: Implement element EOS handling
 - gstreamer: Fix unused variable error
 - test: gstreamer: Fix indentation in comments
 - gstreamer: Move negotiation logic to separate function
 - gstreamer: Add GstLibcameraSrcState::clearRequests method
 - gstreamer: Implement renegotiation
 - lc-compliance: Set minimum version for gtest dependency
 - gstreamer: Support for pre-1.16 GstEvent
 - apps: lc-compliance: Fix source file ordering in meson.build

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 17:21:06 +00:00
Laurent Pinchart
d17de86904 utils: ipc: Update mojo
Update mojo from commit

9be4263648d7d1a04bb78be75df53f56449a5e3a "Updating trunk VERSION from 6225.0 to 6226.0"

from the Chromium repository.

The update-mojo.sh script was used for this update.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=206
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:05 +00:00
Laurent Pinchart
8ac367fe0c utils: ipc: generate.py: Disable attributes checker
The attributes checker ensures that .mojom files don't contain unknown
attributes. These check fail with the custom 'skipSerdes' and 'async'
libcamera attributes. Ideally the list of supported attributes should be
extended, but that can't easily be done without modifying the mojo
sources that we try to keep identical to the upstream version to make
updates easier. Disable the attributes checker completely for now to fix
this issue.

While at it, fix an indentation issue reported by checkstyle.py.

Signed-off-by: Laurent Pinchart <laurent.pinchart@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-01-09 15:39:05 +00:00
Laurent Pinchart
3e4a211ff4 utils: ipc: generate.py: Add bindings directory to Python path
Newer mojo versions import a 'checks' module located in the bindings
directory. In preparation for a mojo update, add the directory to the
Python path make the import work.

Signed-off-by: Laurent Pinchart <laurent.pinchart@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-01-09 15:39:05 +00:00
Laurent Pinchart
3a74a36316 utils: update-mojo.sh: Commit the mojo update
Commit the mojo update with a standardized commit message. As mojo is
imported as-is without local modifications, this simplifies usage of the
update script.

Signed-off-by: Laurent Pinchart <laurent.pinchart@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-01-09 15:39:05 +00:00
Laurent Pinchart
a9adb798e1 utils: update-mojo.sh: Reject a dirty libcamera tree
If the libcamera tree is dirty committing the result of the mojo update
will be messy. Bail out in that case.

Signed-off-by: Laurent Pinchart <laurent.pinchart@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-01-09 15:39:04 +00:00
Laurent Pinchart
0e9585ff5b utils: update-mojo.sh: Change to the libcamera source directory
Instead of prefixing all paths to IPC files with ${ipc_dir}, change to
the libcamera sources root directory and use relative file paths. This
simplifies the update script.

Signed-off-by: Laurent Pinchart <laurent.pinchart@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-01-09 15:39:04 +00:00
Laurent Pinchart
09af551b93 utils: update-mojo.sh: Exit immediately on error
If an error occurs there's no point in ignoring it silently and
continuing. Exit immediately.

Signed-off-by: Laurent Pinchart <laurent.pinchart@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-01-09 15:39:04 +00:00
Laurent Pinchart
cb69c6e843 utils: update-mojo.sh: Properly remove old sources
The update-mojo.sh script starts by removing all sources before copying
the new files from chromium. A bug in the 'rm' command makes the removal
a no-op: the glob pattern is quoted, which attempts to remove a file
name '*' in the tools directory, not all files in the directory. Fix it
by removing the whole utils/ipc/mojo/ directory.

While at it, also remove the utils/ipc/tools/ directory that contains
imported sources.

Signed-off-by: Laurent Pinchart <laurent.pinchart@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-01-09 15:39:04 +00:00
Daniel Scally
effb8f5d7c libcamera: geometry: Correct doxygen reference to classes
The classes Rectangle, Size and SizeRange are referenced with \struct in
the doxygen comments in geometry.cpp. Correct the reference to \class
to better reflect their definition.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:04 +00:00
Kieran Bingham
ffcd1b2804 hooks: pre-push: Disable interpretation of escape sequences
The pre-push hook validates the commit messages utilising 'echo' to send
the captured data from the git commit through grep.

Commit messages may occasionally contain strings that could appear to be
escape sequences such as doxygen style references to \struct.

The '\' 'c' escape sequence can be interpreted to supress all further
output [0] which then breaks the processing and string matching.

Unfortunatley for us, doxygen's class reference constructed in the same
form as \struct can be interpreted as the escape sequence to supress
further output.

[0] https://www.gnu.org/software/bash/manual/bash.html#Bash-Builtins

Update the pre-push hook to explicitly disable escape sequence
interpretation using the '-E' flag. This is not available on the
posix-compliant shell 'dash', so also switch to bash explicitly to
prevent potential failures.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:04 +00:00
David Plowman
d8a17149cb ipa: rpi: vc4: data: Update tuning files for HDR
All the Raspberry Pi official camera tuning files are updated for
HDR. As stated previously, there is no mechanism in the hardware for
combining images so all this does is enable multi-channel AGC to
produce short and long exposure frames. It will be up to the
application to deal with them.

The changes are identical in every tuning file.

1. The existing AGC tuning is duplicated twice so that we have 3 AGC
channels.

2. The first is left alone (the default AGC channel), the second is
tweaked to under-expose significantly (ev -3) and the final one is
tweaked to over-exposure slightly (ev +0.5)

3. Control parameters are provided to the "rpi.hdr" algorithm to
associate these AGC channels correctly with the HDR modes.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:04 +00:00
David Plowman
7ba0053ede ipa: rpi: Implement HDR control
Sufficient plumbing is added so that the HDR mode control can be used
to engage HDR modes on platforms that support them. On the vc4
platform, this allows multi-channel AGC to run, though there is no
image merging.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:04 +00:00
Barnabás Pőcze
b1b798ef68 libcamera: framebuffer_allocator: Remove unnecessary clear()
The vector in question is destroyed when the item in the `buffers_` map
is destroyed as a result of the `erase()` call. A vector's destructor
already does all the things that `clear()` does,
so calling it earlier is not needed.

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: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:04 +00:00
Milan Zamazal
3d45b9ad9a utils: ipc: mojom_libcamera_generator.py: Fix Python warning
Python 3.12 starts emitting the following warning when building libcamera:

  .../utils/ipc/generators/mojom_libcamera_generator.py:372:
  SyntaxWarning: invalid escape sequence '\.'
    if not re.match('^ipa\.[0-9A-Za-z_]+', namespace):

`r' prefix is now required before the regexp.

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-01-09 15:39:04 +00:00
Benjamin Bara
90fa9a0f2b libcamera: device_enumerator: ensure deviceNode is not empty
When activating both ISP nodes on the i.MX8MP, but only connecting one
camera sensor, libcamera aborts because it couldn't find the chosen
entity's device node:

[37:54:40.779902250] [3631] DEBUG DeviceEnumerator device_enumerator.cpp:252 Added device /dev/media1: rkisp1
[37:54:40.780196750] [3631] DEBUG DeviceEnumerator device_enumerator_udev.cpp:322 All dependencies for media device /dev/media0 found
[37:54:40.780237875] [3631] DEBUG DeviceEnumerator device_enumerator.cpp:252 Added device /dev/media0: rkisp1
[37:54:40.780505125] [3631] DEBUG Camera camera_manager.cpp:152 Found registered pipeline handler 'PipelineHandlerRkISP1'
[37:54:40.780599875] [3631] DEBUG DeviceEnumerator device_enumerator.cpp:312 Successful match for media device "rkisp1"
[37:54:40.780731375] [3631] ERROR V4L2 v4l2_device.cpp:93 'rkisp1_isp': Failed to open V4L2 device '': No such file or directory

Fix this by skipping empty device nodes:

[37:49:05.172672000] [3603] DEBUG DeviceEnumerator device_enumerator_udev.cpp:322 All dependencies for media device /dev/media1 found
[37:49:05.172720625] [3603] DEBUG DeviceEnumerator device_enumerator.cpp:256 Added device /dev/media1: rkisp1
[37:49:05.172973875] [3603] DEBUG DeviceEnumerator device_enumerator_udev.cpp:322 All dependencies for media device /dev/media0 found
[37:49:05.173012125] [3603] DEBUG DeviceEnumerator device_enumerator.cpp:256 Added device /dev/media0: rkisp1
[37:49:05.173281625] [3603] DEBUG Camera camera_manager.cpp:152 Found registered pipeline handler 'PipelineHandlerRkISP1'
[37:49:05.173376875] [3603] DEBUG DeviceEnumerator device_enumerator.cpp:107 Skip rkisp1_isp: no device node
[37:49:05.173414375] [3603] DEBUG DeviceEnumerator device_enumerator.cpp:316 Successful match for media device "rkisp1"
[37:49:05.173671250] [3603] DEBUG V4L2 v4l2_videodevice.cpp:632 /dev/video1[15:cap]: Opened device platform:rkisp1: rkisp1: rkisp1_stats
[37:49:05.173775125] [3603] DEBUG V4L2 v4l2_videodevice.cpp:632 /dev/video2[16:out]: Opened device platform:rkisp1: rkisp1: rkisp1_params
[37:49:05.173880500] [3603] DEBUG V4L2 v4l2_videodevice.cpp:632 /dev/video0[18:cap]: Opened device platform:rkisp1: rkisp1: rkisp1

Signed-off-by: Benjamin Bara <benjamin.bara@skidata.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-01-09 15:39:04 +00:00
Paul Elder
1d0d2cf67c utils: ipc: Fix deserialization of multiple fd parameters
The IPADataSerializer::deserializer attempts to optimise code paths and
remove potentially unused code where multiple File Descriptors were not
expected to be utilised.

The addition of multiple SharedFD entries in the IPC highlights this as
a bug.

Clean up the conditionals to ensure that all File Descriptors are
correctly deserialized.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=205
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Tested-by: Andrey Konovalov <andrey.konovalov@linaro.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>
2024-01-09 15:39:04 +00:00
Nícolas F. R. A. Prado
0857348887 apps: lc-compliance: Fix source file ordering in meson.build
The capture_test.cpp file was added in the source list of meson in the
wrong place. Fix it so the list is alphabetically sorted.

Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:04 +00:00
Lee Jackson
ad248036d3 ipa: rpi: vc4: Add OV64A40 tuning files
Provide the OV64A40 tuning files for the Arducam Omnivision camera
module to operate on the VC4 ISP architecture on Raspberry Pi 4 and
below.

Signed-off-by: Lee Jackson <lee.jackson@arducam.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:04 +00:00
Jacopo Mondi
aa5066b413 libipa: camera_sensor_helper: Add OV64A40 helper
Add a CameraSensorHelper for the OV64A40 camera sensor.

Signed-off-by: Jacopo Mondi <jacopo.mondi@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-01-09 15:39:03 +00:00
Jacopo Mondi
6d93836e1a ipa: rpi: Provide a Camera Helper for the OV64A40
Support the OV64A40 sensor with a camera helper to manage the gain
model, light sensitivity, and control delays.

Signed-off-by: Lee Jackson <lee.jackson@arducam.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.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-01-09 15:39:03 +00:00
Kieran Bingham
44409005ab libcamera: camera_sensor: Add OV64A40 sensor properties
Add an entry for the Omnivision OV64A40 Sensor which has a square pixel
size of 1.008µ.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:03 +00:00
Naushir Patuck
0110d9915e ipa: vc4: Implement the StatsOutputEnable vendor control
Implement the StatsOutputEnable control for the VC4 IPA. When set,
this outputs the ISP statistics as a uint8_t span through the Bcm2835StatsOutput
metadata control.

To get this working, IpaBase::libcameraMetadata_ is moved from a private
to a protected member variable. This makes it accessable to the VC4
derived IPA class.

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-01-09 15:39:03 +00:00
Naushir Patuck
12ffe28e1c build: controls: Add Raspberry Pi vendor specific controls
Add a new control_ids_rpi.yaml file to hold the Raspberry Pi specific
vendor controls.

Define a control StatsOutputEnable to allow the ISP hardware statistics
to be output through metadata via the Bcm2835StatsOutput control. The
implementation of these controls will follow in a subsequent patch.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:03 +00:00
David Plowman
66479605ba utils: raspberrypi: ctt: Improve the Macbeth Chart search reliability
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.

There are also a couple of very small drive-by typo fixes.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.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>
2024-01-09 15:39:02 +00:00
David Plowman
cfb4bee74b ipa: rpi: awb: Add an initialValues method
This allows the IPA to get reasonable default colour gains before AWB
has run. This is particularly important on the PiSP platform where
these numbers are helpful in programming the Front End statistics
block in advance.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:02 +00:00
David Plowman
8892d937c5 ipa: rpi: black_level: Add an initialValues method
This allows the IPA to discover the correct black level values even
before any frames have been processed. This is important on the PiSP
platform where the front end black level blocks must be programmed in
advance.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:02 +00:00
Nick Hollinghurst
e71d63ce1b ipa: rpi: Allow the mean of an empty histogram interval
Don't assert when taking the weighted mean of a zero-width or
zero-weight interval; return its upper bound. That is certainly
correct in the zero-width case, and plausible otherwise.

Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:39:02 +00:00
Laurent Pinchart
12fb8ed5cb Documentation: camera-sensor-model: Support Sphinx < 2.0
The language argument to the code-block directive was mandatory in
Sphinx before 2.0. Fix the few instances where no language is specified
to support older versions of Sphinx.

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>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:35:06 +00:00
Laurent Pinchart
0e0043053f gstreamer: Support for pre-1.16 GstEvent
The gst_clear_event() function used by libcamerasrc has been introduced
in GStreamer 1.16, while libcamera claims to need 1.14 or newer. This
causes a compilation error. Fix it by copying the gst_clear_event()
implementation to gstlibcamera-utils.h when compiling with older
GStreamer version.

The version check makes it clear that the workaround is needed with
older versions only, flagging it for removal when the minimum GStreamer
version requirement will be bumped.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-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-01-09 15:34:03 +00:00
Laurent Pinchart
4a362ddeaa lc-compliance: Set minimum version for gtest dependency
lc-compliance depends on support for skipping tests in gtest (commit
00938b2b228f upstream, merged in v1.10.0). Set the corresponding minimum
version for the gtest dependency.

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>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-01-09 15:33:38 +00:00
Naushir Patuck
271598618d ipa: rpi: Add hardware line rate constraints
Advertise hardware constraints on the pixel processing rate through the
Controller::HardwareConfig structure. When calculating the minimum line
length during a configure() operation, ensure that we don't exceed this
constraint.

If we do exceed the hardware constraints, increase the modes's minimum
line length so the pixel processing rate falls below the hardware limit.
If this is not possible, throw a loud error message in the logs.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-01-05 00:40:28 +02:00
William Vinnicombe
577e0c6b76 pipeline: rpi: Respect provided stride
When converting from StreamConfiguration to V4L2DeviceFormat, the stride
was being dropped with the result that users could not request a custom
stride.

Set the stride in the V4L2DeviceFormat to prevent this happening.

Signed-off-by: William Vinnicombe <william.vinnicombe@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-12-21 18:28:24 +02:00
Laurent Pinchart
4843f72b13 libcamera: camera: Fix unused variable compiler warning
When compiling with gcc 8.4.0, the compiler was reported to throw an
unused variable warning:

../src/libcamera/camera.cpp: In member function ‘libcamera::CameraConfiguration::Status libcamera::CameraConfiguration::validateColorSpaces(libcamera::CameraConfiguration::ColorSpaceFlags)’:
../src/libcamera/camera.cpp:497:19: error: unused variable ‘i’ [-Werror=unused-variable]
  for (auto [i, cfg] : utils::enumerate(config_)) {
                   ^

The build environment may have been incorrect as the problem couldn't be
reproduced with gcc 8.3.0 and 8.5.0. Nonetheless, the 'i' variable is
indeed unused. It turns out that the code can be simplified, as the
commit that removed usage of the variable kept the now unneeded
utils::enumerate() call.

Simplify the code and fix the warning in one go.

Fixes: 13986d6ce3 ("libcamera: camera: Fix validateColorSpaces to choose "main" colour space")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-12-21 17:24:28 +02:00
Laurent Pinchart
41d6e6e5c1 meson: Replace hack with usage of '@BASENAME@'
Starting with meson 0.59, the custom_target() function substitutes
'@BASENAME@' in the output parameter with the input file name, with the
extension removed. This is exactly what we implement manually when
generating the IPA interface .cpp files.

Furthermore, starting with meson 0.60, the 'name' positional parameter
to the custom_target() function is optional, and defaults to the
basename of the output file (including the extension). This is exactly
the name we compute manually and pass to the function.

As libcamera requires meson 0.60 or newer, we can depend on those two
features and drop manual computation of the base name. This fixes a
warning with recent meson versions that complain that passing a file
object to the format() function is a broken feature:

WARNING: Broken features used:
 * 1.3.0: {'str.format: Value other than strings, integers, bools, options, dictionaries and lists thereof.'}

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-12-08 00:25:00 +02:00
Laurent Pinchart
1c56d2a2cd README.rst: Add missing libgtest-dev dependency for lc-compliance
lc-compliance requires gtest. When not available on the system, we
install it using a meson wrap, but it is still better to install the
system package. Add it as a dependency in README.rst.

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>
2023-12-07 19:37:50 +02:00
Laurent Pinchart
17d8b89deb test: gstreamer: Remove videoconvert element from pipeline
The GStreamer single stream test uses the following pipeline:

	libcamerasrc ! videoconvert ! fakesink

The videoconvert element isn't useful as the data is thrown away by the
fakesink anyway. We can shorten the pipeline to

	libcamerasrc ! fakesink

to save CPU time and to avoid depending on the gstreamer1.0-plugins-base
package to run the unit tests.

The test could be further simplified by replacing
gst_parse_bin_from_description_full() with gst_element_factory_make(),
now that we only add one element to the bin. The extra cost incurred by
the bin only impacts initialization time, and using a bin will make it
easier to add other elements in the future if needed. Keep the bin, and
only drop the videoconvert element.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-12-07 18:59:42 +02:00
Laurent Pinchart
efcda47985 test: ipc: unixsocket: Increase process exit timeout
When running tests on slower devices, 200ms is too low to wait for the
process to exit. Increase the timeout to 2s.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-12-07 18:59:42 +02:00
Laurent Pinchart
9dc2642d2c test: log: log_process: Increase process exit timeout
When running tests on slower devices, 200ms is too low to wait for the
process to exit. Increase the timeout to 2s.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-12-07 18:59:42 +02:00
Laurent Pinchart
2d12e6088e test: log: log_process: Improve debugging on process exit failures
When the process fails to run and exit normally, the test prints an
error message that provides little information:

	process did not exit normally

Expand the error message to print the exit status to make debugging
easier.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-12-07 18:59:42 +02:00
Laurent Pinchart
db31477433 test: log: log_process: Fix uninitialized variable on process exit failure
If the process fails to exit before the timeout, the
LogProcessTest::exitStatus_ variable gets used uninitialized. Fix it by
initializating to Process::NotExited.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-12-07 18:59:42 +02:00
Laurent Pinchart
030fe617ef test: log: log_process: Log an error when failing due to incorrect message
One of the error paths in the test returns without logging a message,
which makes failures difficult to debug. Fix it by adding an error
message.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-12-07 18:59:42 +02:00
Laurent Pinchart
9ba0c3fef8 meson: Tag all installed files
Meson uses tags to sort installed files in categories, and makes it
possible to install a subset of the files using the '--tags' argument to
'meson install'. This is typically used by distributions to split the
runtime, development and documentation files into separate packages.

By default, meson tries to guess the correct tag for installed files,
but can't always do so properly. Mark the install targets that meson
can't guess with the correct install_tag.

As the feature has been introduced in meson 0.60, bump the minimum meson
version. The latest LTS release of all major distributions that
libcamera currently targets ship a recent enough meson version.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-12-07 01:43:17 +02:00
Jaslo Ziska
b06ebdedba gstreamer: Implement renegotiation
This commit implements renegotiation of the camera configuration and
source pad caps. A renegotiation can happen when a downstream element
decides to change caps or the pipeline is dynamically changed.

To handle a renegotiation the GST_FLOW_NOT_NEGOTIATED return value has
to be handled in GstLibcameraSrcState::processRequest(). Otherwise the
default would be to print an error and stop streaming.

To archive this in a clean way the if statement is altered into a switch
statement which now also has a case for GST_FLOW_NOT_NEGOTIATED. In the
case of GST_FLOW_NOT_NEGOTIATED every source pad is checked for the
reconfiguration flag with gst_pad_needs_reconfigure() which does not
clear this flag. If at least one pad requested a reconfiguration the
function returns without an error and the renegotiation will happen
later in the running task. If no pad requested a reconfiguration then
the function will return with an error.

In gst_libcamera_src_task_run() the source pads are checked for the
reconfigure flag by calling gst_pad_check_reconfigure() and if one pad
returns true and the caps are not sufficient anymore then the
negotiation is triggered. It is fine to trigger the negotiation after
only a single pad returns true for gst_pad_check_reconfigure() because
the reconfigure flags are cleared in the gst_libcamera_src_negotiate()
function.

If any pad requested a reconfiguration the following will happen:
1. The camera is stopped because changing the configuration may not
   happen while running.
2. The completedRequests queue will be cleared by calling
   GstLibcameraSrcState::clearRequests() because the completed buffers
   have the wrong configuration.
3. The new caps are negotiated by calling gst_libcamera_src_negotiate().
   When the negotiation fails streaming will stop.
4. The camera is started again.

Signed-off-by: Jaslo Ziska <jaslo@ziska.de>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-12-07 01:39:41 +02:00
Jaslo Ziska
bf231ead1c gstreamer: Add GstLibcameraSrcState::clearRequests method
Add a clearRequests() function to GstLibcameraSrcState which clears the
GstLibcameraSrcState::completedRequests_ queue.

Use this new function in gst_libcamera_src_task_leave() instead of doing
it manually.

Signed-off-by: Jaslo Ziska <jaslo@ziska.de>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-12-07 01:26:46 +02:00
Jaslo Ziska
9d4da0ca98 gstreamer: Move negotiation logic to separate function
Move the code which negotiates all the source pad caps into a separate
function called gst_libcamera_src_negotiate(). When the negotiation
fails this function will return false and true otherwise.

Use this function instead of doing the negotiation manually in
gst_libcamera_src_task_enter() and remove the now redundant error
handling code accordingly.

Signed-off-by: Jaslo Ziska <jaslo@ziska.de>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-12-07 01:26:36 +02:00
Laurent Pinchart
d61104fa7b test: gstreamer: Fix indentation in comments
A couple of comments are mis-indented in the gstreamer unit test. Fix
them, and reflow the text while at it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-12-06 02:51:35 +02:00
Laurent Pinchart
4eba2dc73c meson_options: Sort options alphabetically
The pycamera option was added at the end of the file, breaking
alphabetical order. Restore it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
2023-12-06 02:06:18 +02:00
Laurent Pinchart
9d08a134c4 README.rst: Document dependencies for the Python bindings
The Python bindings require the libpython3-dev and pybind11-dev
packages. Document it along the other dependencies in README.rst.

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>
2023-12-04 22:57:44 +02:00
Laurent Pinchart
197009f06e README.rst: Drop indirect dependencies on Qt5 packages
The libqt5core5a, libqt5gui5 and libqt5widgets packages are dependencies
of the qtbase5-dev package. There's no need to list them explicitly.

While at it, sort the qcam dependencies alphabetically.

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>
2023-12-04 16:40:58 +02:00
David Plowman
8e215127c1 ipa: rpi: cac: Minor code improvements and tidying
We make a few small improvements to the code:

* The arrayToSet method is prevented from overwriting the end of the
  array if there are too many values in the input table. If you supply
  a table, it will force you to put the correct number of elements in
  it.

* The arrayToSet and setStrength member functions are turned into
  static functions. (There may be a different public setStrength
  member function in future.)

* When no tables at all are given, the configuration is flagged as
  being disabled, so that we can avoid copying tables full of zeroes
  around. As a consequence, the pipeline handler too will disable this
  hardware block rather than run it needlessly. (Note that the tuning
  tool will put in a completely empty "rpi.cac" block if no CAC tuning
  images are supplied, benefiting from this behaviour.)

* The initialise member function is removed as it does nothing.

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>
2023-11-30 15:44:58 +00:00
David Plowman
2905eabad9 ipa: rpi: agc: Fix bug where AeLocked was never getting set
The recent change where time-filtering is done before sorting out the
digital gain means that the target exposure without digital gain is no
longer set, breaking the 'AeLocked' calculation.

We can use the regular (full) target exposure instead.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Fixes: 84b6327789 ("ipa: rpi: agc: Filter exposures before dealing with digital gain")
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-30 15:44:58 +00:00
Naushir Patuck
cbfbab48a7 documentation: Document vendor specific controls and properties handling
Add some documentation to the pipeline handler file describing how to
implement and handle vendor specific controls and properties with a
small example.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-30 13:59:28 +00:00
Naushir Patuck
e18a007b9d libcamera: controls: Use vendor tags for draft controls and properties
Label draft controls and properties through the "draft" vendor tag
and deprecate the existing "draft: true" mechanism. This uses the new
vendor tags mechanism to place draft controls in the same
libcamera::controls::draft namespace and provide a defined control id
range for these controls. This requires moving all draft controls from
control_ids.yaml to control_ids_draft.yaml.

One breaking change in this commit is that draft control ids also move
to the libcamera::controls::draft namespace from the existing
libcamera::controls namespace. This is desirable to avoid API breakages
when adding new libcamera controls. So, for example, the use of
controls::NOISE_REDUCTION_MODE will need to be replaced with
controls::draft::NOISE_REDUCTION_MODE.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-30 13:59:27 +00:00
Naushir Patuck
d3365b358f libcamera: control: Add vendor control id range reservation
Add a new control_ranges.yaml file that is used to reserve control id
ranges/offsets for libcamera and vendor specific controls. This file is
used by the gen-controls.py script to generate control id values for
each control.

Draft controls now have a separate range from core libcamera controls,
breaking the existing numbering behaviour.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-11-29 09:05:39 +00:00
Naushir Patuck
0455bbbf51 build: controls: Rework how controls and properties are generated
Add support for using separate YAML files for controls and properties
generation. The mapping of vendor/pipeline handler to control file is
done through the controls_map variable in include/libcamera/meson.build.

This simplifies management of vendor control definitions and avoids
possible merge conflicts when changing the control_ids.yaml file for
core and draft controls. With this change, libcamera and draft controls
and properties files are designated the 'libcamera' vendor tag.

In this change, we also rename control_ids.yaml -> control_ids_core.yaml
and property_ids.yaml -> property_ids_core.yaml to designate these as
core libcamera controls.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-29 09:05:38 +00:00
Naushir Patuck
bba4ec63c4 controls: Update argument handling for controls generation scripts
The template file to the gen-controls.py and gen-py-controls.py is now
passed in through the '-t' or '--template' command line argument instead
of being a positional argument.  This will allow multiple input files to
be provided to the scripts in a future commit.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-29 09:05:38 +00:00
Naushir Patuck
bd6658943a controls: Add vendor control/property support to generation scripts
Add support for vendor-specific controls and properties to libcamera.
The controls/properties are defined by a "vendor" tag in the YAML
control description file, for example:

vendor: rpi
controls:
  - MyExampleControl:
      type: string
      description: |
        Test for libcamera vendor-specific controls.

This will now generate a control id in the libcamera::controls::rpi
namespace, ensuring no id conflict between different vendors, core or
draft libcamera controls. Similarly, a ControlIdMap control is generated
in the libcamera::controls::rpi namespace.

A #define LIBCAMERA_HAS_RPI_VENDOR_CONTROLS is also generated to allow
applications to conditionally compile code if the specific vendor
controls are present. For the python bindings, the control is available
with libcamera.controls.rpi.MyExampleControl. The above controls
example applies similarly to properties.

Existing libcamera controls defined in control_ids.yaml are given the
"libcamera" vendor tag.

A new --mode flag is added to gen-controls.py to specify the mode of
operation, either 'controls' or 'properties' to allow the code generator
to correctly set the #define string.

As a drive-by, sort and redefine the output command line argument in
gen-controls.py and gen-py-controls.py to ('--output', '-o') for
consistency.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-29 09:05:37 +00:00
Brett Brotherton
61f6b37242 libcamera: pipeline: Fix c++20 compile warning
Fix -Wdeprecated-this-capture error when building with c++20 by
explicity naming this in the capture.

Signed-off-by: Brett Brotherton <bbrotherton@google.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-11-29 02:50:40 +02:00
Laurent Pinchart
64be677b11 Documentation: Fix list indentation
reStructuredText requires list items to be indented. Fix the few
offenders in the documentation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-28 14:08:13 +02:00
Laurent Pinchart
74c5db6fd4 README.rst: Use code directive for all code examples
Most of the code examples in README.rst use the code directive, but some
use literal blocks or just quoted paragraphs. Use the code directive for
all code for consistency.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-28 14:08:04 +02:00
Laurent Pinchart
e25003e78b Documentation: contributing: Integrate the code of conduct
Now that libcamera has an official code of conduct, mention it in the
'contributing' document with a clear indication that all community
members are expected to follow the code of conduct.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-25 19:01:07 +02:00
Laurent Pinchart
cfb7a260e9 Documentation: code-of-conduct: Add contact information
Replace the boilerplate "[INSERT EMAIL ADDRESS]" contact information
with conduct@libcamera.org, and indicate that the people behind that
e-mail address can also be contacted directly if needed. The direct
contact information aims at offering more confidence to reporters than
an anonymous mail alias in case they wish to report an issue with one of
the core project members.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-25 18:56:32 +02:00
Laurent Pinchart
f285ce9c54 Documentation: code-of-conduct: Add license information
The Contributor Covenant is covered by the CC-BY-4.0 license. Indicate
this in the file.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-25 18:56:20 +02:00
Laurent Pinchart
62956b34eb Documentation: code-of-conduct: Convert to reStructuredText
All documentation in libcamera is in reStructuredText format. Convert
the code of conduct from Markdown. No change in the contents is
intended.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-25 18:55:57 +02:00
Laurent Pinchart
0fae5d8c86 Documentation: Add code of conduct
Communities have standards regarding behaviours they consider acceptable
or not acceptable, and expect community members to follow those
standards. libcamera is no different, even if it has never clearly
expressed those standards in a formal code of conduct document.

Like software licenses, codes of conduct can be written in a myriad of
ways. And like software licenses, using a widely adopted code of conduct
instead of writing our own can help bringing clarity. One such standard
code of conduct is the Contributor Covenant, stewarded by the
Organization for Ethical Source.

The Contributor Covenant has been adopted by the freedesktop.org
organization, which hosts a large number of projects historically
related to graphics, and more recently to multimedia in general.
freedesktop.org offers services such as git hosting with CI, which
libcamera could benefit from. There is therefore a clear incentive to
choose the same code of conduct as freedesktop.org, and no known
drawback.

As a first step towards this, and to keep the libcamera code of conduct
history clear in git, copy the original Contributor Covenant v1.4 from
https://github.com/EthicalSource/contributor_covenant/. "v1.4" is
ambiguous as the document initially published as v1.4 has received small
(but sometimes significant) modifications over time. The version
imported here ([1]) is the most recent "v1.4", from tags/2.1 (commit
8a3be1350b07 "Merge pull request #979 from JustArchi/patch-2").

[1] https://github.com/EthicalSource/contributor_covenant/blob/2.1/content/version/1/4/code-of-conduct.md

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-25 16:12:30 +02:00
Jaslo Ziska
62e5289819 gstreamer: Fix unused variable error
Commit fd84180d7a ("gstreamer: Implement element EOS handling") has
introduced a compilation warning with clang:

../../src/gstreamer/gstlibcamerasrc.cpp:768:23: error: unused variable 'oldEvent' [-Werror,-Wunused-variable]
                g_autoptr(GstEvent) oldEvent = self->pending_eos.exchange(event);
                                    ^

This seems to be a false positive, but nonetheless breaks the build. Fix
it.

Fixes: fd84180d7a ("gstreamer: Implement element EOS handling")
Signed-off-by: Jaslo Ziska <jaslo@ziska.de>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2023-11-23 10:10:04 +02:00
David Plowman
2fae9603e6 ipa: rpi: alsc: Do not allow zero colour ratio statistics
The algorithm computes R/G and B/G colour ratio statistics which we
should not allow to go to zero because there is clearly no gain you
could apply to R or B to equalise them. Instead flag such regions as
having "insufficient data" in the normal manner.

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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-11-22 18:33:17 +02:00
Jaslo Ziska
fd84180d7a gstreamer: Implement element EOS handling
This commit implements EOS handling for events sent to the libcamerasrc
element by the send_event method (which can happen when pressing
Ctrl-C while running gst-launch-1.0 -e, see below). EOS events from
downstream elements returning GST_FLOW_EOS are not considered here.

To archive this add a function for the send_event method which handles
the GST_EVENT_EOS event. This function will set an atomic to the
received event and push this EOS event to all source pads in the running
task.

Also set the GST_ELEMENT_FLAG_SOURCE flag to identify libcamerasrc as a
source element which enables it to receive EOS events sent to the
(pipeline) bin containing it. This in turn enables libcamerasrc
to receive EOS events, for example, from gst-launch-1.0 with
the -e (--eos-on-shutdown) flag applied.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=91
Signed-off-by: Jaslo Ziska <jaslo@ziska.de>
Acked-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
2023-11-22 01:18:19 +05:30
Naushir Patuck
091591b52e pipeline: rpi: Add some useful logging messages
Add a bunch of logging messages that have come in handy debugging
various issues with the pipeline handler code.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-11-21 11:48:22 +02:00
Alain Volmat
882d04d740 libcamera: camera_sensor: Only access V4L_CID_HBLANK if existing
Correct a crash in CameraSensor::init() when trying to set the
V4L2_CID_HBLANK control on sensor not implementing this control. The
HBLANK sensor not being mandatory for non-RAW sensors, it can happen
that the sensor does not expose this control. Perform check against
availability of the control prior to usage in order to avoid the crash.

Signed-off-by: Alain Volmat <alain.volmat@foss.st.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>
2023-11-21 11:46:03 +02:00
Naushir Patuck
34b248c88f pipeline: rpi: vc4: Fix drop frame bug when no ISP streams are configured
If no ISP output streams are configured, the ISP output count is skipped
for the the low res stream, and causes the drop frame logic to fail
because of a count mismatch. This in-turn stops any requests from
completing correctly.

Fix this by ensuring the low res output is counted correctly when no ISP
output streams are configured.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-06 11:48:46 +00:00
Naushir Patuck
226a1dacb1 pipeline: rpi: Remove unused variable
The entityControls variable is unused, remove it.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-11-06 11:44:41 +00:00
David Plowman
73c7eeb3e4 libcamera: controls: Add controls for HDR
We add an HdrMode control (to enable and disable HDR processing)
and an HdrChannel, which indicates what kind of HDR frame (short, long
or medium) has just arrived.

Currently the HdrMode supports the following values:

* Off - no HDR processing at all.
* MultiExposureUnmerged - frames at multiple different exposures are
  produced, but not merged together. They are returned "as is".
* MultiExposure - frames at multiple different exposures are merged
  to create HDR images.
* SingleExposure - multiple frames all at the same exposure are
  merged to create HDR images.
* Night - multiple frames will be combined to create "night mode"
  images.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-11-06 11:31:37 +02:00
David Plowman
02eea043f2 ipa: rpi: agc: Make AGC controls affect all channels
We need to be able to do things like enable/disable AGC for all the
channels, so most of the AGC controls are updated to be applied to all
channels. There are a couple of exceptions, such as setting explicit
shutter/gain values, which apply only to channel 0.

Signed-off-by: David Plowman <david.plowman@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>
2023-10-24 14:11:33 +01:00
David Plowman
78a2d00c79 ipa: rpi: agc: Fetch AWB status in the prepare method
AWB writes this out during prepare, so we may as well read it in AGC
prepare as well. Reading it in process is wrong on the PiSP platform
because process runs before prepare, so the AWB status won't be there
(on vc4 it made no difference).

Signed-off-by: David Plowman <david.plowman@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>
2023-10-24 14:11:33 +01:00
Naushir Patuck
4e7c26b197 ipa: rpi: vc4: Move denoise control handling into the VC4 derived IPA
Since noise control handling differs between the VC4 and PiSP IPAs,
move the current denoise control handler from ipa base into the vc4 IPA
derived class.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-10-24 14:11:28 +01:00
David Plowman
edb48a1337 ipa: rpi: agc: Allow AGC channels to avoid using "fast desaturation"
"Fast desaturation" is a technique that can help the AGC algorithm to
desaturate images more quickly when they are very
over-exposed. However, it uses digital gain to do this which can
confuse our HDR techniques. Therefore make it optional.

Signed-off-by: David Plowman <david.plowman@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>
2023-10-24 14:11:16 +01:00
David Plowman
0923d50b15 ipa: rpi: alsc: Do not re-read the alsc.status metadata
This was being re-read in order to determine what LSC gains had been
applied. We can just retrieve these numbers from the prevAsyncResults_
instead.

This will also enable other future algorithms to manipulate the LSC
tables in the alsc.status, without it breaking the core ALSC algorithm
here.

Signed-off-by: David Plowman <david.plowman@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>
2023-10-24 14:11:16 +01:00
David Plowman
5f2ef63e7a ipa: rpi: hdr: Add the ability to alter the LSC table
We can perform some of the local contrast adjustment using global
gains in the LSC table. We can vary the amount of gain according to
the measured brightness of that image region.

Signed-off-by: David Plowman <david.plowman@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>
2023-10-24 14:11:16 +01:00
Laurent Pinchart
fd98779d78 libcamera: transform: Make the transformFromOrientation() function static
Now that the transformFromOrientation() function isn't used outside of
transform.cpp, make it static to remove it from the public API.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-10-23 16:06:22 +03:00
Laurent Pinchart
53b4419986 libcamera: transform: Fold transformToOrientation() in its only caller
The transformToOrientation() function is called from

Orientation operator*(const Orientation &o, const Transform &t);

only. Fold the code in the caller and drop the transformToOrientation()
function to drop what can be considered as an ill-defined operation from
the API.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-10-23 16:06:19 +03:00
Laurent Pinchart
7a5d4b83e5 libcamera: camera_sensor: Cache mounting orientation instead of transform
The cached rotationTransform_ value is used in computeTransform() only,
to compute the mounting orientation. Cache the mounting orientation
instead, removing the need for the intermediate conversion of the
rotation to a transform.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-10-23 16:06:18 +03:00
Jacopo Mondi
4814d8f1b5 py: cam: Add option to set stream orientation
Add a '--orientation|-o' option to the Python version of the cam test
application to set an orientation to the image stream.

Supported values are:
- rot0: no rotation
- rot180: rotate 180 degrees
- flip: vertical flip
- mirror: horizontal flip

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:06:14 +03:00
Jacopo Mondi
7e5f1e1ced apps: cam: Add option to set stream orientation
Add a '--orientation|-o' option to the cam test application to set
an orientation to the image stream.

Supported values are the ones obtained by applying flips to the camera
sensor:
- rot0: no rotation
- rot180: rotate 180 degrees
- flip: vertical flip
- mirror: horizontal flip

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:06:12 +03:00
Jacopo Mondi
c65e40b848 libcamera: Use CameraConfiguration::orientation
Replace the usage of CameraConfiguration::transform with the newly
introduced CameraConfiguration::orientation.

Rework and rename the CameraSensor::validateTransform(transform) to
CameraSensor::computeTransform(orientation), that given the desired
image orientation computes the Transform that pipeline handlers should
apply to the sensor to obtain it.

Port all pipeline handlers to use the newly introduced function.

This commit breaks existing applications as it removes the public
CameraConfiguration::transform in favour of
CameraConfiguration::orientation.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:06:09 +03:00
Jacopo Mondi
a28f871836 py: libcamera: Define and use Orientation
Define an enumeration type for Orientation and expose the
CameraConfiguration::orientation property in place of
CameraConfiguration::transform.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:06:07 +03:00
Jacopo Mondi
69b2dc16a0 test: Add unit test for Transform and Orientation
Add a unit test for Transform and Orientation to validate the
implementation of the operations between the two types.

In particular, test that:

	o1 / o2 = t
	o2 * t = o1

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:06:05 +03:00
Jacopo Mondi
8bb0f472c3 libcamera: transform: Add operations with Orientation
Add two operations that allows to combine Transform with Orientation.

- Transform operator/(const Orientation &o1, const Orientation &o2)
  allows to easily get back the Transform that needs to be applied to
  Orientation2 to get Orientation1

- Orientation operator*(const Orientation &o, const Transform &t)
  allows to apply a Transform to an Orientation and obtain the
  combination of the two

These two operations allow applications to use Transforms to
manipulate the Orientation inside the CameraConfiguration, if they
wish.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:06:02 +03:00
Jacopo Mondi
b54c935dd7 libcamera: transform: Invert operator*() operands
The current definition of operator*(Transform t1, Transform t0) follows
the function composition notion, where t0 is applied first then t1 is
applied last.

In order to introduce operator*(Orientation, Transform) where a
Transform is applied on top of an Orientation, invert the operand order
of operator*(Transform, Transform) so that usage of operator* with both
Orientation and Transform can be made associative.

For example:

Orientation o;
Transform t = t1 * t2
Orientation o1 = o * t
	       = o * (t1 * t2) = (o * t1) * t2 = o * t1 * t2

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:05:59 +03:00
Jacopo Mondi
250577878b libcamera: transform: Add functions to convert Orientation
Add two helper functions to the transform.cpp file that allows to
convert to and from an Orientation.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:05:58 +03:00
Jacopo Mondi
568569b081 libcamera: properties: Make 'Rotation' the mounting rotation
Specify in the documentation that properties::Rotation specifies the
mounting rotation of the camera module. This avoids confusion with the
image orientation which is instead expressed by
CameraConfiguration::orientation.

For this reason, do not compensate the Rotation property when
initializing the CameraSensor class but report the value of
V4L2_CID_CAMERA_SENSOR_ROTATION or 0 if the control is not available.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:05:57 +03:00
Jacopo Mondi
891720ae8c Documentation: Add figures to document Orientation
Add figures in Documentation/rotation/ to document the plane
transformations defined by the Orientation enumeration.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:05:54 +03:00
Jacopo Mondi
cc65629b68 libcamera: camera: Introduce Orientation
Introduce the Orientation enumeration which describes the possible 2D
transformations that can be applied to an image using two basic plane
transformations.

Add to the CameraConfiguration class a new member 'orientation' which is
used to specify the image orientation in the memory buffers delivered to
applications.

The enumeration values follow the ones defined by the EXIF specification at
revision 2.32, Tag 274 'orientation'.

The newly introduced field is meant to replace
CameraConfiguration::transform which is not removed yet not to break
compilation.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:05:50 +03:00
Jacopo Mondi
042649f044 libcamera: camera_sensor: Cache rotationTransform_
The rotationTransform_ depends on a V4L2 control whose value does not
change for the whole lifetime of the camera.

Instead of re-calculating it everytime the camera is configured, cache
it at properties initialization time.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-23 16:05:46 +03:00
Daniel Scally
b5f5a89bc3 apps: qcam: Add support for RGB565
Qt supports RGB565 natively; add support for the format by mapping
the libcamera format to Qt's representation of it.

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>
2023-10-23 13:50:18 +03:00
William Vinnicombe
d477ee97bc pipeline: rpi: vc4: Allocate more embedded data buffers
If the pipeline runs out of embedded data buffers, then it will pass
the frame to the IPA without the metadata. The IPA then has to use the
delayed controls as inputs to the algorithms. This can cause problems
with the subsequent algorithms if the sensor did not action the
controls, especially with the autofocus as that doesn't have controls
which can be passed in lieu of the metadata.

Reduce the likelihood of this by increasing the number of embedded data
buffers, as they are small so a generous number can be allocated.

Signed-off-by: William Vinnicombe <william.vinnicombe@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>
2023-10-18 14:23:23 +01:00
Laurent Pinchart
d2094a0185 utils: update-kernel-headers: Support git worktrees
When operating on a git worktree, the Linux kernel directory contains a
.git file, not a .git directory. Relax the git tree check to support
both.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-10-18 16:17:18 +03:00
Naushir Patuck
d848d2a21c ipa: rpi: agc: When AGC channels are changed, start with the 1st channel
Whenever the AGC active channels are changed, start with the first
channel listed. This allows applications to rely on a particular channel
being generated first. For example, multi-exposure HDR always wants the
short channel first.

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>
2023-10-18 11:01:23 +01:00
David Plowman
daeaf681c9 ipa: rpi: agc: Avoid overwriting caller's statistics pointer
The code was inadvertently overwriting the caller's StatisticsPtr,
meaning that subsequent algorithms would get the wrong image
statistics when AGC channels changed.

This could be fix using std::ref, though I find the C-style pointer
fix easier to understand!

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-10-18 11:01:23 +01:00
David Plowman
ac232470fb ipa: rpi: denoise: Support different denoise configurations
Some use cases may require stronger, or different, denosie settings to
others. For example, the way frames are accumulated during single
exposure HDR means that we may want stronger denoise.

This commit adds such support for different configurations that can be
defined in the tuning file.

Older tuning files, or files where there is only a single
configuration, load only the "normal" denoise configuration.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-10-18 11:01:23 +01:00
David Plowman
0ff20bf8c1 ipa: rpi: contrast: Allow adaptive contrast enhancement to be disabled
The enableCe() function enables or disables adaptive contrast
enhancement and the restoreCe() function sets it back to its normal
state (which is what was read from the tuning file).

In future, algorithms like HDR might want to take over tonemapping
functions, so any dynamic behaviour here would upset them.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-10-18 11:01:23 +01:00
David Plowman
9c90e56733 ipa: rpi: agc: Add an AGC stable region
Add a small "stable region" parameter (defaulting to 2%) within which
the AGC will not adjust the exposure it requests. It allows
applications to configure the AGC to avoid continual micro-adjustments
of exposure values if they are somehow sensitive to it.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-10-18 11:01:23 +01:00
Naushir Patuck
a04fe76a45 pipeline: rpi: Make color space members in RPiCameraConfiguration public
This allows them to be accessed by the pipeline handlers when needed.

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>
2023-10-18 11:01:23 +01:00
Naushir Patuck
0d4342bf22 pipeline: rpi: Move flip handling validation code
Move the handling of Bayer order changes due to flips to run before
platformValidate(). This removes the need for this code to be split
between platformValidate() and validate() as it is right now.

Also add some validation to ensure the vc4 pipeline handler only
supports CSI2 packing or no packing.

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>
2023-10-18 11:01:23 +01:00
Naushir Patuck
2ec7f2fede build: ipa: Fix bug in building multiple IPA interfaces with the same mojom file
In the existing meson scripts, an IPA mojom interface file may not be
built if:

- There are duplicate entries for the mojom file shared by different
  pipeline handlers in pipeline_ipa_mojom_mapping, and
- The IPA is not listed first in pipeline_ipa_mojom_mapping, and
- The first listed IPA for the given mojom file is not selected in the
  build.

Fix this by using a separate list of already built mojom files
(mojoms_built) instead of overloading use of the existing
ipa_mojom_files list.  Now, ipa_mojom_files gets filled in outside of
the IPA list enumeration loop, this also guarantees the IPA
documentation gets built even if the pipeline is not selected.

Fixes: 312e9910ba ("meson: ipa: Add mapping for pipeline handler to mojom interface 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>
2023-10-18 11:01:23 +01:00
Naushir Patuck
9535f2c745 pipeline: rpi: Add SW downscale status to RPi::Stream
Record if additional software downscaling is needed for a particular
stream in the RPi::Stream class. Additional software downscaling may be
needed if the user required downscale factor is greater than what the
ISP hardware is capable of.

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>
2023-10-18 11:01:23 +01:00
Naushir Patuck
ded9004e91 ipa: rpi: Add new algorithms for PiSP
Add new CAC, HDR, Saturation and Tonemapping algorithms.

Add a new Denoise algorithm that handles spatial/temporal/colour denoise
through one interface. With this change, the old SDN algorithm is now
considered deprecated and a warning message will be displayed if it is
enabled.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-10-18 11:01:22 +01:00
Naushir Patuck
c9fb1d44d8 ipa: rpi: Prepare AWB for PiSP support
Prepare the AWB algorithm to support the PiSP hardware. The key change
is to factor in the LS correction in the AWB zone statistics. This is
different from VC4 where the LS correction happens before statistics
gathering.

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>
2023-10-18 11:01:22 +01:00
Naushir Patuck
0be32012ef ipa: rpi: Prepare ALSC for PiSP support
Prepare the ALSC algorithm to support the PiSP hardware. The key change
is to avoid factoring out the WB correction in the AWB zone statistics.

Add the ALSC correction to the global metadata so that AWB can use it to
factor the gains back in for the AWB calculations.

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>
2023-10-18 11:01:22 +01:00
Naushir Patuck
56ca5091de ipa: rpi: Add PiSP definitions to the Controller hardware description
Add an entry to Controller::HardwareConfig describing the PiSP hardware
for the IPA and controller algorithms to use.

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>
2023-10-18 11:01:22 +01:00
Naushir Patuck
11c939a200 ipa: rpi: Add statsInline to the Controller hardware description
Add a new boolean field (statsInline) to Controller::HardwareConfigMap.
This field indicates where the statistics are generated in the hardware
ISP pipeline. For statsInline == true, statistics are generated before
the frame is processed (e.g. the PiSP case), and statsInline == false
indicates statistics are generated after the frame is processed (e.g.
the VC4 case).

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>
2023-10-18 11:01:22 +01:00
Naushir Patuck
0548079581 ipa: rpi: Add try_lock() to RPiController::Metadata
Add the missing try_lock() member function to RPiController::Metadata.
This will allow RPiController::Metadata to be used as a template
parameter in std::scoped_lock.

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>
2023-10-18 11:01:22 +01:00
Naushir Patuck
6f44b9f969 mojom: pipeline: ipa: rpi: Add fields for PiSP objects
Add the PiSP Frontend and Backend SharedMemObject file descriptors to
the ipa::init() call. This will allow the pipeline handler to pass these
objects to the IPA after construction.

Add a flag to indicate if buffer swaps are needed when starting the
ISP for the stitch block.

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>
2023-10-18 11:01:22 +01:00
Naushir Patuck
71bb5b345f ipa: rpi: Add IpaBase::platformStart() member function
Add a virtual IpaBase::platformStart() member function that is called
at the end of IpaBase::start(). For the IpaVc4 derived class, this
function does nothing, but will be used in the PiSP derived class to
reset internal state on startup.

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>
2023-10-18 11:01:22 +01:00
Naushir Patuck
92a74cf454 pipeline: rpi: Add SharedMemObject class
Add new SharedMemObject class that wraps a memfd memory allocation and
constructs a templated object in the memory. With appropriate locking,
this object can then be shared across different processes using the
associated allocation file handle.

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>
2023-10-18 11:01:22 +01:00
Naushir Patuck
cc71d12a18 pipeline: rpi: Add Recurrent and Needs32bitConv flags to RPi::Stream
Add a new "Recurrent" stream flag. This flag indicates the stream buffer
handling/management happend from the pipeline handler exclusively. This
is used for TDN/Stitch and Config streams.

Add a new Needs32bitConv stream flag to indicate that this stream needs
a software postprocessing conversion run on it before returning out to
the application.

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>
2023-10-18 11:01:22 +01:00
Naushir Patuck
f4839fb3a3 pipeline: rpi: Add RequiresMmap flag to RPi::Stream
Add a new RequiresMmap flag to the RPi::Stream class indicating that
buffers handled by the stream must be mmapped after allocation and
cached internally.

Add a new member function getBuffer(id) which can be used to obtain the
mapped buffers for a given buffer id.

Add a new member function acquireBuffer() which can be used to obtain
any mapped buffer that has not already been acquired by the caller.

As a drive-by, add the <algorithm> header to rpi_stream.cpp as it is
needed for the std::find_if() function.

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>
2023-10-18 11:01:21 +01:00
Kieran Bingham
c258302863 py: gen-py-controls: Remove SceneFlicker workaround
The python bindings layer has to parse the libcamera controls to ensure
that they are converted to suitable names for the python layer.

Part of this strips out common prefixes from control names, however the
SceneFlicker control would end up using an illegal name if processed in
the same way as the other controls.

The SceneFlicker control has now been removed as part of the
introduction of the AeFlickerMode and AeFlickerPeriod controls.

Remove the workaround in the python layer.

Fixes: 6fdbf3f38c ("libcamera: controls: Add controls for AEC/AGC flicker avoidance")
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.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>
2023-10-16 16:38:08 +01:00
David Plowman
d05009d34c py: Add the SensorConfiguration class
We provide access to the various fields of the new SensorConfiguration
class. The class also needs a constructor so that Python applications
can make one and put it into the CameraConfiguration.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-10-16 16:21:04 +01:00
Andrey Konovalov
161be650a8 libcamera: converter: drop unnecessary #include directive
libcamera/internal/media_device.h includes linux/media.h already.

Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Suggested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-06 02:39:05 +03:00
Andrey Konovalov
b2b5129d0c libcamera: converter: A few fixes to ConverterFactoryBase documentation
The description of ConverterFactoryBase::registerType() referred to
a converter factory as "converter class" and "converter". Fix that.

Also make the descriptions of ConverterFactoryBase::compatibles() and
ConverterFactoryBase::create() a bit more specific.

Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-10-06 02:39:05 +03:00
David Plowman
ff41de7ba1 ipa: rpi: Avoid skipping IPAs on the first frame after the drop frames
We avoid skipping the IPAs while frameCount_ is less than
dropFrameCount_, indicating that these frames will not be sent to the
application. This means that when these numbers are equal then this is
the first frame the application will get, so again, we must avoid
skipping the IPAs. Consequently the test here must avoid the case of
equality.

Fixes: 51533fecae ("ipa: rpi: Fix frame count logic when running algorithms")
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>
2023-10-05 17:04:06 +01:00
Naushir Patuck
eaf82088b1 libcamera: rpi: Simplify validate() and configure() for YUV/RGB streams
This commit simplifies the validate() and configure() calls in the
pipeline handler in a number of ways:

- Determine the V4L2DeviceFormat structure fields for all streams
  in validate(), cache them and reuse in configure() instead of
  re-generating this structure multiple times.

- Remove setting a default pixel format in validate(), this code patch
  will not be used.

- Use the recently added updateStreamConfig() and toV4L2DeviceFormat()
  helpers to populate fields in the V4L2DeviceFormat and StreamConfiguration
  structures to reduce code duplication.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-09-27 14:44:39 +03:00
Naushir Patuck
b60a5c34fb libcamera: rpi: Change default stream formats
Switch to XRGB8888 as a default Viewfinder role output format, this is a
more correct description of the ISP hardware output, and what is
accepted by the Raspberry Pi hardware.

Switch to YUV420 as a default output format for everything else, as this
format is best supported by encoding (e.g. H.264, JPEG) sinks on the
Raspberry Pi platform.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-09-27 14:43:38 +03:00
Naushir Patuck
723c0abb40 libcamera: rpi: Simplify validate() and configure() for RAW streams
This commit simplifies the validate() and configure() calls in the
pipeline handler in a number of ways:

- Only pass the RPiCameraConfiguration structure into platformValidate()
  and platformConfigure().

- Determine the V4L2DeviceFormat structure fields for all streams in
  validate(), cache them and reuse in configure() instead of
  re-generating this structure multiple times.

- Use the recently added updateStreamConfig() and toV4L2DeviceFormat()
  helpers to populate fields in the V4L2DeviceFormat and
  StreamConfiguration structures to reduce code duplication.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-09-27 14:42:36 +03:00
Naushir Patuck
71bbf10a2f libcamera: rpi: Add some helpers to PipelineHandlerBase
Add a helper updateStreamConfig() that updates the format related fields
in a StreamConfiguration from a given V4L2DeviceFormat structure.

Add and override to the toV4L2DeviceFormat() helper that returns a
V4L2DeviceFormat structure populated from the format related fields in
a StreamConfiguration.

Both these helper functions will be used in a future commit to simplify
the Raspberry Pi pipeline handler configuration/validation code.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-09-27 14:42:23 +03:00
Naushir Patuck
0602cbc596 libcamera: rpi: Cache rawStreams and outStreams
Currently, the stream configuration is stored in two vectors, rawStreams
and outStreams for convenience. However, these vectors are constructed
in both platformValidate() and platformConfigure().

This change caches these vectors in the RPiCameraConfiguration class to
construct them only once in platformValidate().

Pass a pointer to the current configuration to platformValidate() and
platformConfigure() so that they can access the streams vectors.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-09-27 14:42:12 +03:00
Naushir Patuck
2a5120f674 libcamera: rpi: Make isRaw/isYuv/isRgb static functions
Move the existing isRaw()/isYuv()/isRgb()into a static function of
PipelineHandlerBase. This will allow them to be shared with the
pipeline handler derived class.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.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>
2023-09-27 14:41:57 +03:00
Jacopo Mondi
792511a3df libcamera: rpi: Fix wrong comment indentation
The closing line of a comment block was aligned with spaces and not
tabs. Fix it.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-09-27 14:41:44 +03:00
Naushir Patuck
3caaafafa8 libcamera: rpi: Allow platformValidate() to adjust format strides
Propagate any changes to the format stride done by platformValidate().
The stride value may be adjusted for performace reasons.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-09-27 14:41:31 +03:00
Jacopo Mondi
40d50263f5 libcamera: rpi: Handle SensorConfiguration
Handle the SensorConfiguration provided by the application in the
pipeline validate() and configure() call chains.

During validation, first make sure SensorConfiguration is valid, then
handle it to compute the sensor format.

For the VC4 platform where the RAW stream follows the sensor's
configuration adjust the RAW stream configuration to match the sensor
configuration.

Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-09-27 14:41:29 +03:00
Jacopo Mondi
f446c23842 libcamera: camera_sensor: Support SensorConfiguration
Add a class function to the CameraSensor class to apply a full
configuration to the sensor.

The configuration shall be fully populated and shall apply without
modifications to the sensor.

Signed-off-by: Jacopo Mondi <jacopo.mondi@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>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-09-27 14:39:22 +03:00
Jacopo Mondi
1602043e62 libcamera: camera: Introduce SensorConfiguration
Introduce SensorConfiguration in the libcamera API.

The SensorConfiguration is part of the CameraConfiguration class
and allows applications to control the sensor settings.

Signed-off-by: Jacopo Mondi <jacopo.mondi@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>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-09-27 14:35:42 +03:00
Jacopo Mondi
9780f46f64 Documentation: Introduce Camera Sensor Model
Introduce a documentation page about the 'camera sensor model'
implemented by libcamera.

The camera sensor model serves to provide to applications a reference
description of the processing steps that take place in a camera sensor
in order to precisely control the sensor configuration through the
forthcoming SensorConfiguration class.

Signed-off-by: Jacopo Mondi <jacopo.mondi@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>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-09-27 14:35:33 +03:00
Naushir Patuck
e991a2887e pipeline: rpi: Reset the frame lengths queue during configure
The IPA stores a list of the last 10 frame lengths applied to the
sensor for determining the timeout to use. This list gets reset on
start(), but there is a path through the code that accesses this list
in configure() which happens earlier, causing a logical error.

Fix this by constructing the list with 10 initial values of 0s.

Bug: https://github.com/raspberrypi/libcamera/issues/64
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>
2023-09-25 16:08:35 +01:00
Naushir Patuck
51533fecae ipa: rpi: Fix frame count logic when running algorithms
The frame counter test to determine if we run the IPA algorithms has a
logic bug where it treats dropFrameCount_ and mistrustCount_ as frame
numbers, not counts of frames (which it is). The implication is that
startup convergence and initial settings take one extra frame to apply.
Fix this.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Tested-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-09-25 16:01:21 +01:00
Naushir Patuck
870943f80a libcamera: formats: Fix typo in YV444 V4L2PixelFormat listing
This format was defined with the V4L2_PIX_FMT_YUV444M fourcc instead of
the correct V4L2_PIX_FMT_YVU444M fourcc.

Fixes: 3b9fe4ae99 ("libcamera: formats: Add YUV444 and YVU444 pixel formats")
Signed-off-by: Naushir Patuck <naush@raspberrypi.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>
2023-09-25 16:01:21 +01:00
Laurent Pinchart
1d61614142 meson: Simplify check for _FORTIFY_SOURCE
Use the compiler.get_define() function to get the value of
_FORTIFY_SOURCE instead of iterating over the cpp_args. This simplies
the code, but also guarantees to return the actual value of
_FORTIFY_SOURCE, even if defined through other means than through the
meson cpp_args.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: George Burgess IV <gbiv@google.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-09-21 15:24:37 +02:00
Harvey Yang
dbe4e0e945 android: camera_device: Fix requestedStream handling
The Android CameraDevice class adds a sourceStream for each Mapped
stream requested by the framework.

When mapping multiple framework streams to the same sourceStream, the
implementation of CameraDevice::processCaptureRequest wrongly erases the
just added sourceStream from the list of streams to request to
libcamera.

Fix this by adding the stream instead of erasing it.

Fixes: 7ea83eba0d ("android: camera_device: Postpone mapped streams handling")
Signed-off-by: Harvey Yang <chenghaoyang@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-09-21 12:44:09 +02:00
George Burgess IV
9c5eb9237c meson: Don't set _FORTIFY_SOURCE for ChromeOS
ChromeOS is moving to a platform default of `_FORTIFY_SOURCE=3`, and
this definition conflicts with that:

<command line>:4:9: error: '_FORTIFY_SOURCE' macro redefined
[-Werror,-Wmacro-redefined]

Rather than adding logic to keep up with their local configuration, it
seems best to leave setting _FORTIFY_SOURCE on ChromeOS up to ChromeOS.

Signed-off-by: George Burgess IV <gbiv@google.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>
2023-09-19 11:25:08 +03:00
Naushir Patuck
90e0fea6c6 ipa: rpi: Fix segfault when parsing invalid json file
If the json file parsing failed due to a malformed file, the root
pointer would be null. This was not tested and caused a segfault when
trying to use the pointer to retrieve the version key.

Fix this by bailing out early if the parser returns a null pointer.

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: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-09-16 17:33:44 +02:00
David Plowman
7127954aaa ipa: rpi: agc: Use channel constraints in the AGC algorithm
Whenever we run Agc::process(), we store the most recent total
exposure requested for each channel.

With these values we can apply the channel constraints after
time-filtering the requested total exposure, but before working out
how much digital gain is needed.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-09-16 17:33:44 +02:00
David Plowman
7927c44735 ipa: rpi: agc: Add AgcChannelConstraint class
A channel constraint is somewhat similar to the upper/lower bound
constraints that we use elsewhere, but these constraints apply between
multiple AGC channels. For example, it lets you say things like "don't
let the channel 1 total exposure be more than 8x that of channel 0",
and so on. By using both an upper and lower bound constraint, you
could fix one AGC channel always to be a fixed ratio of another.

Also read a vector of them (if present) when loading the tuning file.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-09-16 17:33:44 +02:00
David Plowman
beab3a229f ipa: rpi: agc: Implementation of multi-channel AGC
The switchMode, prepare and process methods are updated to implement
multi-channel AGC correctly:

* switchMode now invokes switchMode on all the channels (whether
  active or not).

* prepare must find what channel the current frame is, and run on
  behalf of that channel.

* process updates the most recent DeviceStatus and statistics for the
  channel of the frame that has just arrived, but generates updated
  values working through the active channels in round-robin fashion.

One minor detail in process is that we don't want to change the
DeviceStatus metadata of the current frame, so we now pass this to the
AgcChannel's process method, rather than letting it find the
DeviceStatus in the metadata.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-09-16 17:33:44 +02:00
David Plowman
b2cb498a1a ipa: rpi: agc: Reorganise code for multi-channel AGC
This commit does the basic reorganisation of the code in order to
implement multi-channel AGC. The main changes are:

* The previous Agc class (in agc.cpp) has become the AgcChannel class
  in (agc_channel.cpp).

* A new Agc class is introduced which is a wrapper round a number of
  AgcChannels.

* The basic plumbing from ipa_base.cpp to Agc is updated to include a
  channel number. All the existing controls are hardwired to talk
  directly to channel 0.

There are a couple of limitations which we expect to apply to
multi-channel AGC. We're not allowing different frame durations to be
applied to the channels, nor are we allowing separate metering
modes. To be fair, supporting these things is not impossible, but
there are reasons why it may be tricky so they remain "TBD" for now.

This patch only includes the basic reorganisation and plumbing. It
does not yet update the important methods (switchMode, prepare and
process) to implement multi-channel AGC properly. This will appear in
a subsequent commit. For now, these functions are hard-coded just to
use channel 0, thereby preserving the existing behaviour.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-09-16 17:33:44 +02:00
Naushir Patuck
cd940f7fd3 ipa: rpi: histogram: Add interBinMean()
Add a new helper function Histogram::interBinMean() that essentially
replaces the existing Histogram::interQuantileMean() logic but working on
bins instead.

Rework the interQuantileMean() to call into interBinMean() with the
appropriate convertion from quatiles to bins.

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: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-09-16 17:33:44 +02:00
Laurent Pinchart
e5f0846695 README.rst: Drop recommendation to install meson using pip3
Usage of pip3 to install meson may result in a different meson version
available for the local user and for root. This causes issues when
running `meson install` (directly or through `ninja install`):
Installing to a system location will request elevated privileges and use
the system meson version to install files, which may fail to unpickle
data pickled with the meson version for the local user.

As all major distributions now provide a recent-enough version of meson,
usage of pip3 is not longer needed in most cases, and shouldn't be
recommended. Drop it.

While at it, update the version of meson listed in the documentation to
match the required version.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=199
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
2023-09-15 10:52:16 +03:00
David Plowman
58e501c71c ipa: rpi: vc4: Make the StatisticsPtr construction clearer
StatisticsPtr is a shared pointer, so the use of std::make_unique to
create it was a bit confusing. Use std::make_shared instead.

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>
2023-09-04 18:01:17 +01:00
David Plowman
250565b5e8 ipa: rpi: agc: Split AgcStatus into AgcStatus and AgcPrepareStatus
The Agc::process() function returns an AgcStatus object in the
metadata as before, but Agc::prepare() is changed to return the values
it computes in a separate AgcPrepareStatus object (under the new tag
"agc.prepare_status").

The "digitalGain" and "locked" fields are moved from AgcStatus to
AgcPrepareStatus.

This will be useful going forward as we can be more flexible about the
order in which prepare() and process() are called, without them
trampling on each other's results.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-09-04 17:47:35 +01:00
David Plowman
84b6327789 ipa: rpi: agc: Filter exposures before dealing with digital gain
We now time-filter the exposure before sorting out how much digital
gain is required. This is actually a little more natural and
simplifies the code.  It also prepares us for some future work where
this arrangement will be helpful.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrpyi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-09-04 17:47:35 +01:00
David Plowman
2ea57d0b77 ipa: rpi: agc: Fetch AWB status in process method, not prepare
prepare() doesn't use the AWB status, so fetching it in process() is
probably better. This change is preparatory to other changes, where we
may find ourselves calling process() without having called prepare()
previously.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-09-04 17:47:35 +01:00
Naushir Patuck
ad64716ce9 pipeline: rpi: Simplify buffer id generation
Replace the buffer id generation in RPi::Stream with a simple integer
counter since ids don't get recycled any more.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-09-04 11:13:27 +01:00
Naushir Patuck
74af791304 pipeline: rpi: Rename RPi::Stream::setExternalBuffer()
Since we don't distinguish between externally and internally allocated
dma bufs, rename this function to setExportedBuffer() to clearer on its
function.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-09-04 10:45:22 +01:00
Naushir Patuck
e8582ee42e pipeline: rpi: Remove additional external dma buf handling logic
There is no need to distinguish between dma bufs allocated outside of
libcamera and internally allocated buffers. As such, remove all the
special case handling of such buffers.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-09-04 10:45:22 +01:00
Naushir Patuck
1107999f71 pipeline: rpi: Increase buffer import count to 32
Hardcode the maximum number of buffers imported to the V4L2 video device
to 32. This only has a minor disadvantage of over-allocating cache slots
and V4L2 buffer indexes, but does allow more headroom for using dma
buffers allocated from outside of libcamera.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-09-04 10:45:10 +01:00
Umang Jain
ae9bcb2155 libcamera: stream: Document stride will be 0 for compressed formats
For compressed formats, v4l2_pix_format.bytesperline value will be zero
and is documented similarly in the kernel. Since we set the stride to
v4l2_pix_format.bytesperline, document the case where it is expected
to be zero (i.e. if the format is compressed).

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
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>
2023-08-29 10:40:25 +03:00
Naushir Patuck
26ac1a8e3f ipa: rpi: imx290: Hide one frame on startup
The imx290 produces a single unusable frame on startup and mode switch.
This is signalled to the IPA in the mode switch case, but not the
startup case. Fix this.

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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-08-29 10:39:13 +03:00
Harvey Yang
960d0c1e19 libcamera: Remove duplicated SortIncludes in .clang-format
`SortIncludes: true` was added in both commit ae05b9f9d0
("clang-format: Enable sorted includes") and commit 0e1ff86e78
("clang-format: Regroup sort orders"), which caused issues to run
clang-format.

Fixes: 0e1ff86e78 ("clang-format: Regroup sort orders")
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: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2023-08-02 00:50:31 +03:00
Laurent Pinchart
6cb92b523b Documentation: theme: Fix compilation with Sphinx >= 7.0.0
Sphinx 7.0.0 has dropped support for the deprecated 'style' variable
(https://github.com/sphinx-doc/sphinx/pull/11381). This breaks
compilation of the documentation:

  /usr/bin/sphinx-build -D release=v0.1.0+16-eed6a079 -q -W -b html Documentation Documentation/html

  Theme error:
  An error happened in rendering the page api-html/index.
  Reason: UndefinedError("'style' is undefined")

The recommended replacement is 'styles[-1]'. However, this resolves to
'_static/css/theme.css', which is part of the 'css_styles' variable, and
results in the stylesheet being included twice. To avoid that and fix
the compilation error, simply drop the first reference.

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>
2023-07-31 22:58:58 +03:00
Naushir Patuck
fe73f05475 pipeline: rpi: Don't call toV4L2DeviceFormat() from validate()
Don't make an unnecessary call to toV4L2DeviceFormat() from validate()
to get a V4L2DeviceFormat. Instead, the conversion can happen directly
from the RAW stream PixelFormat.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2023-07-31 12:09:41 +02:00
Laurent Pinchart
eed6a079d2 meson: Correctly locate libc++
The meson find_library() function takes a library name without the "lib"
prefix. Its usage to find lic++ is thus not correct, and meson warns
about it:

WARNING: find_library('libc++') starting in "lib" only works by accident and is not portable

Fix it by dropping the "lib" prefix.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-07-28 19:45:04 +03:00
Laurent Pinchart
4694e441c3 utils: checkstyle.py: Extract title and trailers with one command
The Amendment class calls `git show` twice, once to extract the commit
title, and a second time to extract the trailers. This can be combined
in a single command, which is more efficient. Do so.

While at it, centralize initialization of self._trailers in the
Commit.__init__() function.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-07-28 19:11:56 +03:00
Naushir Patuck
5322b7ba61 libcamera: yaml: Increase the YAML parser limit
Increase the maximum list size to 2000 elements. This allows, for
example, larger lens shading config structures to be parsed correctly
without throwing any errors.

Signed-off-by: Naushir Patuck <naush@raspberrypi.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>
2023-07-28 18:34:02 +03:00
David Plowman
baab00721c ipa: rpi: Fix the reporting of Focus FoMs
The FocusFom metadata was no longer being reported back because the
"focus.status" metadata was never being created.

Additionally, the scaling of the focus FoMs was over-zealous, rounding
just about everything down to zero.

Fixes: ac7511dc4c ("ipa: raspberrypi: Generalise the focus reporting code")
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.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>
2023-07-28 18:34:02 +03:00
Ben Benson
09dd65442b utils: raspberrypi: ctt: Code tidying
Altered the way that some lines are laid out, made functions
more attractive to look at, and tidied up messy areas.

Signed-off-by: Ben Benson <ben.benson@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
2023-07-28 08:32:40 +01:00
Ben Benson
6213ecb859 ipa: rpi: vc4: data: Updated color matrices for RPi Cameras
Altered the color matrices for the tuning files for various
cameras in order to make them more color accurate.

Signed-off-by: Ben Benson <ben.benson@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
2023-07-28 08:32:23 +01:00
Ben Benson
f8dd17a8f4 utils: raspberrypi: ctt: Improved color matrix fitting
Added code which optimises the color matrices based off
delta E values for the calibration images. Working in LAB
color space.

Signed-off-by: Ben Benson <ben.benson@raspberrypi.com>
Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
2023-07-28 08:31:38 +01:00
David Plowman
a2eadc40a7 ipa: rpi: common: Handle AEC/AGC flicker controls
We handle the flicker modes by passing the correct period to the
AEC/AGC algorithm which already contains the necessary code.

The "Auto" mode, as well as reporting the detected flicker period via
the "AeFlickerDetected" metadata, are unsupported for now.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
2023-07-25 10:21:11 +01:00
David Plowman
6fdbf3f38c libcamera: controls: Add controls for AEC/AGC flicker avoidance
Flicker is the term used to describe brightness banding or oscillation
of images caused typically by artificial lighting driven by a 50 or
60Hz mains supply. We add three controls intended to be used by
AEC/AGC algorithms:

AeFlickerMode to enable flicker avoidance.

AeFlickerPeriod to set the flicker period "manually".

AeFlickerDetected to report any flicker that is currently detected.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
2023-07-25 10:21:01 +01:00
Jacopo Mondi
cd7d917a04 libcamera: rpi: pipeline_base: Cache sensor format
The format to be applied on the sensor is selected by two criteria: the
desired output size and the bit depth. As the selection depends on the
presence of a RAW stream and the streams configuration is handled in
validate() there is no need to re-compute the format in configure().

Centralize the computation of the sensor format in validate() and remove
it from configure().

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2023-07-24 11:38:15 +02:00
Jacopo Mondi
4edc162e3d libcamera: rpi: pipeline_base: Move findBestFormat to CameraData
The findBestFormat() helper operates on the list of sensor formats,
which is owned by the CameraData class. Move the function to that class
as well to:

1) Avoid passing the list of formats to the function
2) Remove a static helper in favour of a class function
3) Allow subclasses with access to CameraData to call the function

Move to the CameraData class the scoreFormat helper as well.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2023-07-24 11:32:10 +02:00
Jacopo Mondi
81fa10d87f libcamera: rpi: pipeline_base: Remove populateSensorFormats()
populateSensorFormats() is a static helper that is called from a single
place and performs a simple loop over the sensor camera formats.

Remove it and in-line it in the caller to remove one static helper from
the pipeline_base.cpp file.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-07-24 11:21:00 +02:00
Kieran Bingham
baaad1bf9e utils: checkstyle.py: Check trailers for Amendment commits
The commit trailers are checked as part of processing the commit message
with the newly introduced TrailersChecker.

This relies on the trailers property being correctly exposed by the
Commit object, and is implemented for the base Commit but not processed
for Amendment commits.

Refactor the trailer property handling to a helper function in the base
Commit class and make use of it with a newly added call to obtain the
existing Trailers from the most recent commit when using Amendment.

Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-07-18 09:26:31 +01:00
Kieran Bingham
e2f0ad27b1 utils: checkstyle.py: Derive Amendment from Commit
The Amendment commit class is derived from the StagedChanges class
(which in turn derives from the Commit base class), however there is no
code sharing between Amendment and StagedChanges other than the call to
initalise through the base Commit class.

Refactor the inheritance to make an Amendment derive directly from
Commit.

Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-07-18 09:26:24 +01:00
Kieran Bingham
37106ba02a utils: checkstyle.py: Initialise staged trailers
There are no possible Trailers for staged changes as the commit message
has not yet been written.

Initialise the empty trailers when the commit object is initialised.

Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-07-18 09:26:12 +01:00
Kieran Bingham
b14d2cab12 utils: checkstyle.py: Treat Malformed trailers as a CommitIssue
If a Malformed trailer is identified the checkstyle script triggers a
RuntimeError and stops processing the rest of the commit.

A malformed trailer can be regarded as an issue in the commit and
reported as such using the same method as other faults identified by the
tool.

Convert the RuntimeError into a CommitIssue and continue processing
other trailers.

Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Tested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-07-18 09:25:13 +01:00
1047 changed files with 100573 additions and 14235 deletions

View file

@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only # 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: # For more information, see:
# #
@ -66,7 +66,6 @@ ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true FixNamespaceComments: true
ForEachMacros: ForEachMacros:
- 'udev_list_entry_foreach' - 'udev_list_entry_foreach'
SortIncludes: true
IncludeBlocks: Regroup IncludeBlocks: Regroup
IncludeCategories: IncludeCategories:
# Headers matching the name of the component are matched automatically. # Headers matching the name of the component are matched automatically.
@ -76,6 +75,7 @@ IncludeCategories:
Priority: 9 Priority: 9
# Qt includes (match before C++ standard library) # Qt includes (match before C++ standard library)
- Regex: '<Q([A-Za-z0-9\-_])+>' - Regex: '<Q([A-Za-z0-9\-_])+>'
CaseSensitive: true
Priority: 9 Priority: 9
# Headers in <> with an extension. (+system libraries) # Headers in <> with an extension. (+system libraries)
- Regex: '<([A-Za-z0-9\-_])+\.h>' - Regex: '<([A-Za-z0-9\-_])+\.h>'

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 *.patch
*.pyc *.pyc
__pycache__/ __pycache__/
venv/

View file

@ -3,6 +3,12 @@ Upstream-Name: libcamera
Upstream-Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Upstream-Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Source: https://git.libcamera.org/libcamera/libcamera.git/ Source: https://git.libcamera.org/libcamera/libcamera.git/
Files: Documentation/binning.svg
Documentation/camera-sensor-model.rst
Documentation/sensor_model.svg
Copyright: Copyright 2023 Ideas On Board Oy
License: CC-BY-SA-4.0
Files: Documentation/theme/static/search.png Files: Documentation/theme/static/search.png
Copyright: 2022 Fonticons, Inc. Copyright: 2022 Fonticons, Inc.
License: CC-BY-4.0 License: CC-BY-4.0

View file

@ -20,35 +20,19 @@ TOC_INCLUDE_HEADINGS = 0
CASE_SENSE_NAMES = YES CASE_SENSE_NAMES = YES
QUIET = 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 \ FILE_PATTERNS = *.c \
*.cpp \ *.cpp \
*.dox \
*.h *.h
RECURSIVE = YES 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@/src/libcamera/proxy/
EXCLUDE_PATTERNS = @TOP_BUILDDIR@/include/libcamera/ipa/*_serializer.h \ EXCLUDE_PATTERNS = @TOP_BUILDDIR@/include/libcamera/ipa/*_serializer.h \
@TOP_BUILDDIR@/include/libcamera/ipa/*_proxy.h \ @TOP_BUILDDIR@/include/libcamera/ipa/*_proxy.h \
@TOP_BUILDDIR@/include/libcamera/ipa/ipu3_*.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/raspberrypi_*.h \
@TOP_BUILDDIR@/include/libcamera/ipa/rkisp1_*.h \ @TOP_BUILDDIR@/include/libcamera/ipa/rkisp1_*.h \
@TOP_BUILDDIR@/include/libcamera/ipa/vimc_*.h @TOP_BUILDDIR@/include/libcamera/ipa/vimc_*.h
@ -68,16 +52,17 @@ EXCLUDE_SYMBOLS = libcamera::BoundMethodArgs \
EXCLUDE_SYMLINKS = YES EXCLUDE_SYMLINKS = YES
HTML_OUTPUT = api-html
GENERATE_LATEX = NO GENERATE_LATEX = NO
MACRO_EXPANSION = YES MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES EXPAND_ONLY_PREDEF = YES
INCLUDE_PATH = "@TOP_SRCDIR@/include/libcamera" INCLUDE_PATH = "@TOP_BUILDDIR@/include" \
"@TOP_SRCDIR@/include"
INCLUDE_FILE_PATTERNS = *.h INCLUDE_FILE_PATTERNS = *.h
IMAGE_PATH = "@TOP_SRCDIR@/Documentation/images"
PREDEFINED = __DOXYGEN__ \ PREDEFINED = __DOXYGEN__ \
__cplusplus \ __cplusplus \
__attribute__(x)= \ __attribute__(x)= \

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 API Reference
=== =============
:: Placeholder for Doxygen documentation :: Placeholder for Doxygen documentation

5053
Documentation/binning.svg Normal file

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 194 KiB

View file

@ -0,0 +1,175 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _camera-sensor-model:
.. todo: Move to Doxygen-generated documentation
The libcamera camera sensor model
=================================
libcamera defines an abstract camera sensor model in order to provide
a description of each of the processing steps that result in image data being
sent on the media bus and that form the image stream delivered to applications.
Applications should use the abstract camera sensor model defined here to
precisely control the operations of the camera sensor.
The libcamera camera sensor model targets image sensors producing frames in
RAW format, delivered through a MIPI CSI-2 compliant bus implementation.
The abstract sensor model maps libcamera components to the characteristics and
operations of an image sensor, and serves as a reference to model the libcamera
CameraSensor class and SensorConfiguration classes and operations.
In order to control the configuration of the camera sensor through the
SensorConfiguration class, applications should understand this model and map it
to the combination of image sensor and kernel driver in use.
The camera sensor model defined here is based on the *MIPI CCS specification*,
particularly on *Section 8.2 - Image readout* of *Chapter 8 - Video Timings*.
Glossary
--------
.. glossary::
Pixel array
The full grid of pixels, active and inactive ones
Pixel array active area
The portion(s) of the pixel array that contains valid and readable pixels;
corresponds to the libcamera properties::PixelArrayActiveAreas
Analog crop rectangle
The portion of the *pixel array active area* which is read out and passed
to further processing stages
Subsampling
Pixel processing techniques that reduce the image size by binning or by
skipping adjacent pixels
Digital crop
Crop of the sub-sampled image data before scaling
Frame output
The frame (image) as output on the media bus by the camera sensor
Camera sensor model
-------------------
The abstract sensor model is described in the following diagram.
.. figure:: sensor_model.svg
1. The sensor reads pixels from the *pixel array*. The pixels being read out are
selected by the *analog crop rectangle*.
2. The pixels can be subsampled to reduce the image size without affecting the
field of view. Two subsampling techniques can be used:
- Binning: combines adjacent pixels of the same colour by averaging or
summing their values, in the analog domain and/or the digital domain.
.. figure:: binning.svg
- Skipping: skips the read out of a number of adjacent pixels.
.. figure:: skipping.svg
3. The output of the optional sub-sampling stage is then cropped after the
conversion of the analogue pixel values in the digital domain.
4. The resulting output frame is sent on the media bus by the sensor.
Camera Sensor configuration parameters
--------------------------------------
The libcamera camera sensor model defines parameters that allow users to
control:
1. The image format bit depth
2. The size and position of the *Analog crop rectangle*
3. The subsampling factors used to downscale the pixel array readout data to a
smaller frame size without reducing the image *field of view*. Two
configuration parameters are made available to control the downscaling
factor:
- binning
A vertical and horizontal binning factor can be specified, the image
will be downscaled in its vertical and horizontal sizes by the specified
factor.
.. code-block:: c
:caption: Definition: The horizontal and vertical binning factors
horizontal_binning = xBin;
vertical_binning = yBin;
- skipping
Skipping reduces the image resolution by skipping the read-out of a number
of adjacent pixels. The skipping factor is specified by the 'increment'
number (number of pixels to 'skip') in the vertical and horizontal
directions and for even and odd rows and columns.
.. code-block:: c
:caption: Definition: The horizontal and vertical skipping factors
horizontal_skipping = (xOddInc + xEvenInc) / 2;
vertical_skipping = (yOddInc + yEvenInc) / 2;
Different sensors perform the binning and skipping stages in different
orders. For the sake of computing the final output image size the order of
execution is not relevant. The overall down-scaling factor is obtained by
combining the binning and skipping factors.
.. code-block:: c
:caption: Definition: The total scaling factor (binning + sub-sampling)
total_horizontal_downscale = horizontal_binning + horizontal_skipping;
total_vertical_downscale = vertical_binning + vertical_skipping;
4. The output size is used to specify any additional cropping on the sub-sampled
frame.
5. The total line length and frame height (*visibile* pixels + *blankings*) as
sent on the MIPI CSI-2 bus.
6. The pixel transmission rate on the MIPI CSI-2 bus.
The above parameters are combined to obtain the following high-level
configurations:
- **frame output size**
Obtained by applying a crop to the physical pixel array size in the analog
domain, followed by optional binning and sub-sampling (in any order),
followed by an optional crop step in the output digital domain.
- **frame rate**
The combination of the *total frame size*, the image format *bit depth* and
the *pixel rate* of the data sent on the MIPI CSI-2 bus allows to compute the
image stream frame rate. The equation is the well known:
.. code-block:: c
frame_duration = total_frame_size / pixel_rate;
frame_rate = 1 / frame_duration;
where the *pixel_rate* parameter is the result of the sensor's configuration
of the MIPI CSI-2 bus *(the following formula applies to MIPI CSI-2 when
used on MIPI D-PHY physical protocol layer only)*
.. code-block:: c
pixel_rate = csi_2_link_freq * 2 * nr_of_lanes / bits_per_sample;

View file

@ -0,0 +1,96 @@
.. SPDX-License-Identifier: CC-BY-4.0
.. include:: documentation-contents.rst
.. _code-of-conduct:
Contributor Covenant Code of Conduct
====================================
Our Pledge
----------
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
Our Standards
-------------
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
Our Responsibilities
--------------------
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
Scope
-----
This Code of Conduct applies within all project spaces, and it also applies when
an individual is representing the project or its community in public spaces.
Examples of representing a project or community include using an official
project e-mail address, posting via an official social media account, or acting
as an appointed representative at an online or offline event. Representation of
a project may be further defined and clarified by project maintainers.
Enforcement
-----------
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at conduct@libcamera.org, or directly to
any member of the code of conduct team:
* Kieran Bingham <kieran.bingham@ideasonboard.com>
* Laurent Pinchart <laurent.pinchart@ideasonboard.com>
All complaints will be reviewed and investigated and will result in a response
that is deemed necessary and appropriate to the circumstances. The project team
is obligated to maintain confidentiality with regard to the reporter of an
incident. Further details of specific enforcement policies may be posted
separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
Attribution
-----------
This Code of Conduct is adapted from the `Contributor Covenant`_, version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
.. _Contributor Covenant: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _coding-style-guidelines: .. _coding-style-guidelines:
Coding Style Guidelines Coding Style Guidelines
@ -59,7 +61,7 @@ document:
underscores in between underscores in between
* All formatting rules specified in the selected sections of the Linux kernel * All formatting rules specified in the selected sections of the Linux kernel
Code Style for indentation, braces, spacing, etc Code Style for indentation, braces, spacing, etc
* Header guards are formatted as '__LIBCAMERA_FILE_NAME_H__' * Headers are guarded by the use of '#pragma once'
Order of Includes Order of Includes
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

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 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones. # ones.
extensions = [ extensions = [
'sphinx.ext.graphviz'
] ]
graphviz_output_format = 'svg'
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = [] templates_path = []
@ -61,7 +64,12 @@ language = 'en'
# List of patterns, relative to source directory, that match files and # List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files. # directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path. # 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. # The name of the Pygments (syntax highlighting) style to use.
pygments_style = None pygments_style = None

View file

@ -8,6 +8,10 @@ Whether you would like to help with coding, documentation, testing, proposing
new features, or just discussing the project with the community, you can join new features, or just discussing the project with the community, you can join
our official public communication channels, or simply check out the code. our official public communication channels, or simply check out the code.
The project adheres to a :ref:`code of conduct <code-of-conduct>` that
maintainers, contributors and community members are expected to follow in all
online and offline communication.
Mailing List Mailing List
------------ ------------
@ -134,4 +138,5 @@ By making a contribution to this project, I certify that:
.. toctree:: .. toctree::
:hidden: :hidden:
Code of Conduct <code-of-conduct>
Coding Style <coding-style> Coding Style <coding-style>

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 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
Environment variables Environment variables
===================== =====================
@ -37,11 +39,29 @@ LIBCAMERA_IPA_MODULE_PATH
Example value: ``${HOME}/.libcamera/lib:/opt/libcamera/vendor/lib`` 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
variable are the ones passed to the REGISTER_PIPELINE_HANDLER() macro in the
source code.
Example value: ``rkisp1,simple``
LIBCAMERA_RPI_CONFIG_FILE LIBCAMERA_RPI_CONFIG_FILE
Define a custom configuration file to use in the Raspberry Pi pipeline handler. Define a custom configuration file to use in the Raspberry Pi pipeline handler.
Example value: ``/usr/local/share/libcamera/pipeline/rpi/vc4/minimal_mem.yaml`` 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 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 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. Getting started information is defined in the project README file. .. Getting started information is defined in the project README file.
.. include:: ../README.rst .. include:: ../README.rst
:start-after: .. section-begin-getting-started :start-after: .. section-begin-getting-started

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: ../documentation-contents.rst
Using libcamera in a C++ application Using libcamera in a C++ application
==================================== ====================================
@ -116,19 +118,21 @@ available.
.. code:: cpp .. code:: cpp
if (cm->cameras().empty()) { auto cameras = cm->cameras();
if (cameras.empty()) {
std::cout << "No cameras were identified on the system." std::cout << "No cameras were identified on the system."
<< std::endl; << std::endl;
cm->stop(); cm->stop();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
std::string cameraId = cm->cameras()[0]->id(); std::string cameraId = cameras[0]->id();
camera = cm->get(cameraId);
camera = cm->get(cameraId);
/* /*
* Note that is equivalent to: * Note that `camera` may not compare equal to `cameras[0]`.
* camera = cm->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 Once a camera has been selected an application needs to acquire an exclusive
@ -348,7 +352,7 @@ The libcamera library uses the concept of `signals and slots` (similar to `Qt
Signals and Slots`_) to connect events with callbacks to handle them. Signals and Slots`_) to connect events with callbacks to handle them.
.. _signals and slots: https://libcamera.org/api-html/classlibcamera_1_1Signal.html#details .. _signals and slots: https://libcamera.org/api-html/classlibcamera_1_1Signal.html#details
.. _Qt Signals and Slots: https://doc.qt.io/qt-5/signalsandslots.html .. _Qt Signals and Slots: https://doc.qt.io/qt-6/signalsandslots.html
The ``Camera`` device emits two signals that applications can connect to in The ``Camera`` device emits two signals that applications can connect to in
order to execute callbacks on frame completion events. order to execute callbacks on frame completion events.
@ -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 `FileSink class`_ which is a part of the ``cam`` utility application in the
libcamera repository. 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 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 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 = executable('simple-cam',
'simple-cam.cpp', 'simple-cam.cpp',
dependencies: dependency('libcamera', required : true)) dependencies: dependency('libcamera'))
The ``dependencies`` line instructs meson to ask ``pkgconfig`` (or ``cmake``) to The ``dependencies`` line instructs meson to ask ``pkgconfig`` (or ``cmake``) to
locate the ``libcamera`` library, which the test application will be 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 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: ../documentation-contents.rst
IPA Writer's Guide IPA Writer's Guide
================== ==================

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: ../documentation-contents.rst
Pipeline Handler Writers Guide 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. the name of the pipeline.
In the *meson.build* file, add the *vivid.cpp* file as a build source for 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 .. code-block:: none
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
libcamera_sources += files([ libcamera_internal_sources += files([
'vivid.cpp', 'vivid.cpp',
]) ])
@ -183,7 +186,7 @@ to the libcamera build options in the top level ``meson_options.txt``.
option('pipelines', option('pipelines',
type : 'array', 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') 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; std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;
int start(Camera *camera, const ControlList *controls) 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; int queueRequestDevice(Camera *camera, Request *request) override;
@ -244,7 +247,7 @@ implementations for the overridden class members.
return -1; return -1;
} }
void PipelineHandlerVivid::stop(Camera *camera) void PipelineHandlerVivid::stopDevice(Camera *camera)
{ {
} }
@ -258,7 +261,7 @@ implementations for the overridden class members.
return false; return false;
} }
REGISTER_PIPELINE_HANDLER(PipelineHandlerVivid) REGISTER_PIPELINE_HANDLER(PipelineHandlerVivid, "vivid")
} /* namespace libcamera */ } /* namespace libcamera */
@ -266,6 +269,8 @@ Note that you must register the ``PipelineHandler`` subclass with the pipeline
handler factory using the `REGISTER_PIPELINE_HANDLER`_ macro which handler factory using the `REGISTER_PIPELINE_HANDLER`_ macro which
registers it and creates a global symbol to reference the class and make it registers it and creates a global symbol to reference the class and make it
available to try and match devices. available to try and match devices.
String "vivid" is the name assigned to the pipeline, matching the pipeline
subdirectory name in the source tree.
.. _REGISTER_PIPELINE_HANDLER: https://libcamera.org/api-html/pipeline__handler_8h.html .. _REGISTER_PIPELINE_HANDLER: https://libcamera.org/api-html/pipeline__handler_8h.html
@ -516,14 +521,14 @@ handler and camera manager using `registerCamera`_.
Finally with a successful construction, we return 'true' indicating that the Finally with a successful construction, we return 'true' indicating that the
PipelineHandler successfully matched and constructed a device. 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 .. _registerCamera: https://libcamera.org/api-html/classlibcamera_1_1PipelineHandler.html#adf02a7f1bbd87aca73c0e8d8e0e6c98b
.. code-block:: cpp .. code-block:: cpp
std::set<Stream *> streams{ &data->stream_ }; std::set<Stream *> streams{ &data->stream_ };
std::shared_ptr<Camera> camera = Camera::create(this, data->video_->deviceName(), streams); std::shared_ptr<Camera> camera = Camera::create(std::move(data), data->video_->deviceName(), streams);
registerCamera(std::move(camera), std::move(data)); registerCamera(std::move(camera));
return true; return true;
@ -549,8 +554,7 @@ Our match function should now look like the following:
/* Create and register the camera. */ /* Create and register the camera. */
std::set<Stream *> streams{ &data->stream_ }; std::set<Stream *> streams{ &data->stream_ };
const std::string &id = data->video_->deviceName(); std::shared_ptr<Camera> camera = Camera::create(std::move(data), data->video_->deviceName(), streams);
std::shared_ptr<Camera> camera = Camera::create(data.release(), id, streams);
registerCamera(std::move(camera)); registerCamera(std::move(camera));
return true; return true;
@ -587,12 +591,12 @@ immutable properties of the ``Camera`` device.
The libcamera controls and properties are defined in YAML form which is The libcamera controls and properties are defined in YAML form which is
processed to automatically generate documentation and interfaces. Controls are processed to automatically generate documentation and interfaces. Controls are
defined by the src/libcamera/`control_ids.yaml`_ file and camera properties defined by the src/libcamera/`control_ids_core.yaml`_ file and camera properties
are defined by src/libcamera/`properties_ids.yaml`_. are defined by src/libcamera/`property_ids_core.yaml`_.
.. _controls framework: https://libcamera.org/api-html/controls_8h.html .. _controls framework: https://libcamera.org/api-html/controls_8h.html
.. _control_ids.yaml: https://libcamera.org/api-html/control__ids_8h.html .. _control_ids_core.yaml: https://libcamera.org/api-html/control__ids_8h.html
.. _properties_ids.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 Pipeline handlers can optionally register the list of controls an application
can set as well as a list of immutable camera properties. Being both can set as well as a list of immutable camera properties. Being both
@ -651,7 +655,7 @@ inline in our VividCameraData init:
ctrls.emplace(id, info); ctrls.emplace(id, info);
} }
controlInfo_ = std::move(ctrls); controlInfo_ = ControlInfoMap(std::move(ctrls), controls::controls);
The ``properties_`` field is a list of ``ControlId`` instances The ``properties_`` field is a list of ``ControlId`` instances
associated with immutable values, which represent static characteristics that can associated with immutable values, which represent static characteristics that can
@ -672,6 +676,58 @@ handling controls:
#include <libcamera/controls.h> #include <libcamera/controls.h>
#include <libcamera/control_ids.h> #include <libcamera/control_ids.h>
Vendor-specific controls and properties
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Vendor-specific controls and properties must be defined in a separate YAML file
and included in the build by defining the pipeline handler to file mapping in
include/libcamera/meson.build. These YAML files live in the src/libcamera
directory.
For example, adding a Raspberry Pi vendor control file for the PiSP pipeline
handler is done with the following mapping:
.. code-block:: meson
controls_map = {
'controls': {
'draft': 'control_ids_draft.yaml',
'libcamera': 'control_ids_core.yaml',
'rpi/pisp': 'control_ids_rpi.yaml',
},
'properties': {
'draft': 'property_ids_draft.yaml',
'libcamera': 'property_ids_core.yaml',
}
}
The pipeline handler named above must match the pipeline handler option string
specified in the meson build configuration.
Vendor-specific controls and properties must contain a `vendor: <vendor_string>`
tag in the YAML file. Every unique vendor tag must define a unique and
non-overlapping range of reserved control IDs in src/libcamera/control_ranges.yaml.
For example, the following block defines a vendor-specific control with the
`rpi` vendor tag:
.. code-block:: yaml
vendor: rpi
controls:
- PispConfigDumpFile:
type: string
description: |
Triggers the Raspberry Pi PiSP pipeline handler to generate a JSON
formatted dump of the Backend configuration to the filename given by the
value of the control.
The controls will be generated in the vendor-specific namespace
`libcamera::controls::rpi`. Additionally a `#define
LIBCAMERA_HAS_RPI_VENDOR_CONTROLS` will be available to allow applications to
test for the availability of these controls.
Generating a default configuration Generating a default configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -743,8 +799,7 @@ derived class, and assign it to a base class pointer.
.. code-block:: cpp .. code-block:: cpp
VividCameraData *data = cameraData(camera); auto config = std::make_unique<VividCameraConfiguration>();
CameraConfiguration *config = new VividCameraConfiguration();
A ``CameraConfiguration`` is specific to each pipeline, so you can only create 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 it from the pipeline handler code path. Applications can also generate an empty
@ -772,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 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 the ``V4LPixelFormat`` and ``SizeRange`` supported by the underlying output
device, but the pipeline handler needs to convert this to a device, but the pipeline handler needs to convert this to a
``libcamera::PixelFormat`` type to pass to applications. We do this here using ``libcamera::PixelFormat`` type to pass to applications.
``std::transform`` to convert the formats and populate a new ``PixelFormat`` map
as shown below.
Continue adding the following code example to our ``generateConfiguration`` Continue adding the following code example to our ``generateConfiguration``
implementation. implementation.
@ -784,14 +837,12 @@ implementation.
std::map<V4L2PixelFormat, std::vector<SizeRange>> v4l2Formats = std::map<V4L2PixelFormat, std::vector<SizeRange>> v4l2Formats =
data->video_->formats(); data->video_->formats();
std::map<PixelFormat, std::vector<SizeRange>> deviceFormats; std::map<PixelFormat, std::vector<SizeRange>> deviceFormats;
std::transform(v4l2Formats.begin(), v4l2Formats.end(),
std::inserter(deviceFormats, deviceFormats.begin()), for (auto &[v4l2PixelFormat, sizes] : v4l2Formats) {
[&](const decltype(v4l2Formats)::value_type &format) { PixelFormat pixelFormat = v4l2PixelFormat.toPixelFormat();
return decltype(deviceFormats)::value_type{ if (pixelFormat.isValid())
format.first.toPixelFormat(), deviceFormats.try_emplace(pixelFormat, std::move(sizes));
format.second }
};
});
The `StreamFormats`_ class holds information about the pixel formats and frame 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 sizes that a stream can support. The class groups size information by the pixel
@ -881,9 +932,9 @@ Add the following function implementation to your file:
StreamConfiguration &cfg = config_[0]; 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()) { 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(); LOG(VIVID, Debug) << "Adjusting format to " << cfg.pixelFormat.toString();
status = Adjusted; status = Adjusted;
} }
@ -1101,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 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 stopped, to gracefully clean up any allocated memory and stop the hardware
devices. Pipeline handlers implement two functions for these purposes, the 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 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 configure video devices to be able to use memory buffers exported as dma-buf
@ -1204,8 +1255,8 @@ algorithms, or other devices you should also stop them.
.. _releaseBuffers: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#a191619c152f764e03bc461611f3fcd35 .. _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 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 a device, Add the following to the ``stopDevice()`` function, to stop the
the `streamOff`_ function and release all buffers. stream with the `streamOff`_ function and release all buffers.
.. _streamOff: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#a61998710615bdf7aa25a046c8565ed66 .. _streamOff: https://libcamera.org/api-html/classlibcamera_1_1V4L2VideoDevice.html#a61998710615bdf7aa25a046c8565ed66
@ -1293,7 +1344,7 @@ before being set.
continue; 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)); controls.set(cid, std::clamp(value, 0, 255));
} }
@ -1357,7 +1408,7 @@ value translation operations:
.. code-block:: cpp .. code-block:: cpp
#include <math.h> #include <cmath>
Frame completion and event handling Frame completion and event handling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -1370,7 +1421,7 @@ emitted triggers the execution of the connected slots. A detailed description
of the libcamera implementation is available in the `libcamera Signal and Slot`_ of the libcamera implementation is available in the `libcamera Signal and Slot`_
classes documentation. classes documentation.
.. _Qt Signals and Slots: https://doc.qt.io/qt-5/signalsandslots.html .. _Qt Signals and Slots: https://doc.qt.io/qt-6/signalsandslots.html
.. _libcamera Signal and Slot: https://libcamera.org/api-html/classlibcamera_1_1Signal.html#details .. _libcamera Signal and Slot: https://libcamera.org/api-html/classlibcamera_1_1Signal.html#details
In order to notify applications about the availability of new frames and data, In order to notify applications about the availability of new frames and data,

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: ../documentation-contents.rst
Tracing Guide Tracing Guide
============= =============

View file

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="297mm"
height="210mm"
viewBox="0 0 297 210"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="rotate0.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="true"
showguides="false"
inkscape:zoom="1.4854147"
inkscape:cx="666.48052"
inkscape:cy="448.35962"
inkscape:window-width="1916"
inkscape:window-height="1040"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="0.26458334"
spacingy="0.26458333"
empcolor="#0000ff"
empopacity="0.25098039"
color="#0000ff"
opacity="0.1254902"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;paint-order:markers stroke fill;stroke-dasharray:none"
id="rect1"
width="152.88184"
height="119.41136"
x="77.237244"
y="81.982094" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;paint-order:markers stroke fill;stroke-dasharray:none"
id="rect2"
width="49.755535"
height="36.468258"
x="92.612343"
y="98.912964" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2-5"
width="49.755535"
height="36.468258"
x="167.25099"
y="98.912964" />
<g
id="g4"
transform="translate(-0.98582077)"
style="stroke-width:1.5875;stroke-dasharray:none">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect3"
width="40.994682"
height="43.605846"
x="134.16664"
y="157.24184" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="path3"
cx="140.15703"
cy="176.44627"
rx="1.889045"
ry="1.925626" />
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 244.95942,81.765726 62.444825,81.97209 154.25639,28.65633 Z"
id="path4"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="m 199.76751,33.368887 0.0285,21.581353"
id="path5" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="m 215.59016,33.189206 0.0959,31.330304"
id="path6" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 194.42835,33.189356 25.2821,-0.220612"
id="path7" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
d="m 195.19248,33.096339 -0.0701,-5.375793 23.77787,-0.05613 0.0553,5.315811"
id="path8" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 194.20874,25.616264 25.25485,-0.02536"
id="path7-5"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 195.03436,26.298566 -0.0455,-5.426692 23.77787,-0.05613 0.0553,5.315811"
id="path8-9"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="297mm"
height="210mm"
viewBox="0 0 297 210"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="rotate0Mirror.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="true"
showguides="false"
inkscape:zoom="0.82900578"
inkscape:cx="599.51331"
inkscape:cy="579.00682"
inkscape:window-width="1916"
inkscape:window-height="1040"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="0.26458334"
spacingy="0.26458333"
empcolor="#0000ff"
empopacity="0.25098039"
color="#0000ff"
opacity="0.1254902"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect1"
width="152.88184"
height="119.41136"
x="-230.13463"
y="81.982094"
transform="scale(-1,1)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2"
width="49.755535"
height="36.468258"
x="-214.75954"
y="98.912964"
transform="scale(-1,1)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2-5"
width="49.755535"
height="36.468258"
x="-140.12088"
y="98.912964"
transform="scale(-1,1)" />
<g
id="g4"
transform="matrix(-1,0,0,1,308.35769,0)"
style="stroke-width:1.5875;stroke-dasharray:none">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect3"
width="40.994682"
height="43.605846"
x="134.16664"
y="157.24184" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="path3"
cx="140.15703"
cy="176.44627"
rx="1.889045"
ry="1.925626" />
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 62.412454,81.765726 244.92705,81.97209 153.11548,28.65633 Z"
id="path4"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 107.60436,33.368887 -0.0285,21.581353"
id="path5" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 91.781714,33.189206 -0.0959,31.330304"
id="path6" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 112.94352,33.189356 87.661424,32.968744"
id="path7" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 112.17939,33.096339 0.0701,-5.375793 -23.777866,-0.05613 -0.0553,5.315811"
id="path8" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 113.16313,25.616264 87.908284,25.590904"
id="path7-5"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 112.33751,26.298566 0.0455,-5.426692 -23.777866,-0.05613 -0.0553,5.315811"
id="path8-9"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="297mm"
height="210mm"
viewBox="0 0 297 210"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="rotate180.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="true"
showguides="false"
inkscape:zoom="0.94272086"
inkscape:cx="467.79489"
inkscape:cy="423.24299"
inkscape:window-width="1916"
inkscape:window-height="1040"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="0.26458334"
spacingy="0.26458333"
empcolor="#0000ff"
empopacity="0.25098039"
color="#0000ff"
opacity="0.1254902"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect1"
width="152.88184"
height="119.41136"
x="-230.13461"
y="-140.22527"
transform="scale(-1)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2"
width="49.755535"
height="36.468258"
x="-214.75951"
y="-123.2944"
transform="scale(-1)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2-5"
width="49.755535"
height="36.468258"
x="-140.12086"
y="-123.2944"
transform="scale(-1)" />
<g
id="g4"
transform="rotate(180,154.17884,111.10368)"
style="stroke-width:1.5875;stroke-dasharray:none">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect3"
width="40.994682"
height="43.605846"
x="134.16664"
y="157.24184" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="path3"
cx="140.15703"
cy="176.44627"
rx="1.889045"
ry="1.925626" />
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 62.412437,140.44163 182.514593,-0.20636 -91.81156,53.31576 z"
id="path4"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 107.60435,188.83847 -0.0285,-21.58135"
id="path5" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 91.781697,189.01815 -0.0959,-31.3303"
id="path6" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 112.94351,189.018 -25.282103,0.22061"
id="path7" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 112.17938,189.11102 0.0701,5.37579 -23.777873,0.0561 -0.0553,-5.31581"
id="path8" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 113.16312,196.59109 -25.254853,0.0254"
id="path7-5"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 112.3375,195.90879 0.0455,5.42669 -23.777873,0.0561 -0.0553,-5.31581"
id="path8-9"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="297mm"
height="210mm"
viewBox="0 0 297 210"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="rotate180Mirror.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="true"
showguides="false"
inkscape:zoom="0.94272086"
inkscape:cx="467.79489"
inkscape:cy="423.24299"
inkscape:window-width="1916"
inkscape:window-height="1040"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="0.26458334"
spacingy="0.26458333"
empcolor="#0000ff"
empopacity="0.25098039"
color="#0000ff"
opacity="0.1254902"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect1"
width="152.88184"
height="119.41136"
x="77.237228"
y="-140.22527"
transform="scale(1,-1)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2"
width="49.755535"
height="36.468258"
x="92.612335"
y="-123.2944"
transform="scale(1,-1)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2-5"
width="49.755535"
height="36.468258"
x="167.25098"
y="-123.2944"
transform="scale(1,-1)" />
<g
id="g4"
transform="matrix(1,0,0,-1,-0.98584226,222.20736)"
style="stroke-width:1.5875;stroke-dasharray:none">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect3"
width="40.994682"
height="43.605846"
x="134.16664"
y="157.24184" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="path3"
cx="140.15703"
cy="176.44627"
rx="1.889045"
ry="1.925626" />
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 244.9594,140.44163 62.444808,140.23527 154.25637,193.55103 Z"
id="path4"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 199.76749,188.83847 0.0285,-21.58135"
id="path5" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 215.59014,189.01815 0.0959,-31.3303"
id="path6" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 194.42833,189.018 25.2821,0.22061"
id="path7" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 195.19246,189.11102 -0.0701,5.37579 23.77787,0.0561 0.0553,-5.31581"
id="path8" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 194.20872,196.59109 25.25485,0.0254"
id="path7-5"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 195.03434,195.90879 -0.0455,5.42669 23.77787,0.0561 0.0553,-5.31581"
id="path8-9"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="297mm"
height="210mm"
viewBox="0 0 297 210"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="rotate270.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="true"
showguides="false"
inkscape:zoom="0.94272086"
inkscape:cx="467.26451"
inkscape:cy="423.24299"
inkscape:window-width="1916"
inkscape:window-height="1040"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="0.26458334"
spacingy="0.26458333"
empcolor="#0000ff"
empopacity="0.25098039"
color="#0000ff"
opacity="0.1254902"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect1"
width="152.88184"
height="119.41136"
x="-187.55237"
y="124.56432"
transform="rotate(-90)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2"
width="49.755535"
height="36.468258"
x="-172.17726"
y="141.49518"
transform="rotate(-90)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2-5"
width="49.755535"
height="36.468258"
x="-97.538612"
y="141.49518"
transform="rotate(-90)" />
<g
id="g4"
transform="rotate(-90,154.17883,111.5966)"
style="stroke-width:1.5875;stroke-dasharray:none">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect3"
width="40.994682"
height="43.605846"
x="134.16664"
y="157.24184" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="path3"
cx="140.15703"
cy="176.44627"
rx="1.889045"
ry="1.925626" />
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 124.34796,19.830188 124.55432,202.34478 71.238559,110.53322 Z"
id="path4"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 75.951119,65.022101 21.58135,-0.0285"
id="path5" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 75.771439,49.199448 31.330301,-0.0959"
id="path6" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 75.771589,70.361261 75.550979,45.079158"
id="path7" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 75.678569,69.597131 -5.37579,0.0701 -0.0561,-23.777873 5.31581,-0.0553"
id="path8" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 68.198499,70.580871 -0.0254,-25.254853"
id="path7-5"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 68.880799,69.755251 -5.42669,0.0455 -0.0561,-23.777873 5.31581,-0.0553"
id="path8-9"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="297mm"
height="210mm"
viewBox="0 0 297 210"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="rotate270Mirror.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="true"
showguides="false"
inkscape:zoom="0.94272086"
inkscape:cx="467.79489"
inkscape:cy="423.24299"
inkscape:window-width="1916"
inkscape:window-height="1040"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="0.26458334"
spacingy="0.26458333"
empcolor="#0000ff"
empopacity="0.25098039"
color="#0000ff"
opacity="0.1254902"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect1"
width="152.88184"
height="119.41136"
x="-187.55237"
y="-182.80751"
transform="matrix(0,-1,-1,0,0,0)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2"
width="49.755535"
height="36.468258"
x="-172.17726"
y="-165.87666"
transform="matrix(0,-1,-1,0,0,0)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2-5"
width="49.755535"
height="36.468258"
x="-97.538612"
y="-165.87666"
transform="matrix(0,-1,-1,0,0,0)" />
<g
id="g4"
transform="matrix(0,-1,-1,0,264.78961,265.77543)"
style="stroke-width:1.5875;stroke-dasharray:none">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect3"
width="40.994682"
height="43.605846"
x="134.16664"
y="157.24184" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="path3"
cx="140.15703"
cy="176.44627"
rx="1.889045"
ry="1.925626" />
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 183.02388,19.830188 -0.20636,182.514592 53.31576,-91.81156 z"
id="path4"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 231.42072,65.022101 -21.58135,-0.0285"
id="path5" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 231.6004,49.199448 -31.3303,-0.0959"
id="path6" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 231.60025,70.361261 0.22061,-25.282103"
id="path7" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 231.69327,69.597131 5.37579,0.0701 0.0561,-23.777873 -5.31581,-0.0553"
id="path8" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 239.17334,70.580871 0.0254,-25.254853"
id="path7-5"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 238.49104,69.755251 5.42669,0.0455 0.0561,-23.777873 -5.31581,-0.0553"
id="path8-9"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="297mm"
height="210mm"
viewBox="0 0 297 210"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="rotate90.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="true"
showguides="false"
inkscape:zoom="0.94272086"
inkscape:cx="467.26451"
inkscape:cy="423.24299"
inkscape:window-width="1916"
inkscape:window-height="1040"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="0.26458334"
spacingy="0.26458333"
empcolor="#0000ff"
empopacity="0.25098039"
color="#0000ff"
opacity="0.1254902"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect1"
width="152.88184"
height="119.41136"
x="34.65498"
y="-182.80751"
transform="rotate(90)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2"
width="49.755535"
height="36.468258"
x="50.030079"
y="-165.87665"
transform="rotate(90)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2-5"
width="49.755535"
height="36.468258"
x="124.66872"
y="-165.87665"
transform="rotate(90)" />
<g
id="g4"
transform="rotate(90,154.17885,110.61076)"
style="stroke-width:1.5875;stroke-dasharray:none">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect3"
width="40.994682"
height="43.605846"
x="134.16664"
y="157.24184" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="path3"
cx="140.15703"
cy="176.44627"
rx="1.889045"
ry="1.925626" />
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 183.02388,202.37715 -0.20636,-182.51459 53.31576,91.81156 z"
id="path4"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 231.42072,157.18524 -21.58135,0.0285"
id="path5" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 231.6004,173.00789 -31.3303,0.0959"
id="path6" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 231.60025,151.84608 0.22061,25.2821"
id="path7" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 231.69327,152.61021 5.37579,-0.0701 0.0561,23.77787 -5.31581,0.0553"
id="path8" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 239.17334,151.62647 0.0254,25.25485"
id="path7-5"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 238.49104,152.45209 5.42669,-0.0455 0.0561,23.77787 -5.31581,0.0553"
id="path8-9"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="297mm"
height="210mm"
viewBox="0 0 297 210"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="rotate90Mirror.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="true"
showguides="false"
inkscape:zoom="0.94272086"
inkscape:cx="467.79489"
inkscape:cy="423.24299"
inkscape:window-width="1916"
inkscape:window-height="1040"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="layer1">
<inkscape:grid
id="grid1"
units="px"
originx="0"
originy="0"
spacingx="0.26458334"
spacingy="0.26458333"
empcolor="#0000ff"
empopacity="0.25098039"
color="#0000ff"
opacity="0.1254902"
empspacing="5"
dotted="false"
gridanglex="30"
gridanglez="30"
visible="true" />
</sodipodi:namedview>
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect1"
width="152.88184"
height="119.41136"
x="34.65498"
y="124.56432"
transform="matrix(0,1,1,0,0,0)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2"
width="49.755535"
height="36.468258"
x="50.030079"
y="141.49519"
transform="matrix(0,1,1,0,0,0)" />
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect2-5"
width="49.755535"
height="36.468258"
x="124.66872"
y="141.49519"
transform="matrix(0,1,1,0,0,0)" />
<g
id="g4"
transform="matrix(0,1,1,0,42.582224,-43.56809)"
style="stroke-width:1.5875;stroke-dasharray:none">
<rect
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="rect3"
width="40.994682"
height="43.605846"
x="134.16664"
y="157.24184" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:1.5875;stroke-dasharray:none;paint-order:markers stroke fill"
id="path3"
cx="140.15703"
cy="176.44627"
rx="1.889045"
ry="1.925626" />
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 124.34795,202.37715 124.55431,19.86256 71.238554,111.67412 Z"
id="path4"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 75.951114,157.18524 21.58135,0.0285"
id="path5" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 75.771434,173.00789 31.330296,0.0959"
id="path6" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 75.771584,151.84608 -0.22061,25.2821"
id="path7" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 75.678564,152.61021 -5.37579,-0.0701 -0.0561,23.77787 5.31581,0.0553"
id="path8" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 68.198494,151.62647 -0.0254,25.25485"
id="path7-5"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.5875;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 68.880794,152.45209 -5.42669,-0.0455 -0.0561,23.77787 5.31581,0.0553"
id="path8-9"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -1,25 +1,31 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. Front page matter is defined in the project README file. .. include:: introduction.rst
.. include:: ../README.rst
:start-after: .. section-begin-libcamera
:end-before: .. section-end-libcamera
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
:caption: Contents: :caption: Contents:
Home <self> Home <self>
Docs <docs>
Contribute <contributing> Contribute <contributing>
Getting Started <getting-started> Getting Started <getting-started>
Developer Guide <guides/introduction>
Application Writer's Guide <guides/application-developer> Application Writer's Guide <guides/application-developer>
Pipeline Handler Writer's Guide <guides/pipeline-handler> Camera Sensor Model <camera-sensor-model>
IPA Writer's guide <guides/ipa>
Tracing guide <guides/tracing>
Environment variables <environment_variables> Environment variables <environment_variables>
Sensor driver requirements <sensor_driver_requirements> Feature Requirements <feature_requirements>
IPA Writer's guide <guides/ipa>
Lens driver requirements <lens_driver_requirements> Lens driver requirements <lens_driver_requirements>
libcamera Architecture <libcamera_architecture>
Pipeline Handler Writer's Guide <guides/pipeline-handler>
Python Bindings <python-bindings> 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 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _lens-driver-requirements: .. _lens-driver-requirements:
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

@ -15,6 +15,7 @@ if doxygen.found() and dot.found()
cdata.set('TOP_SRCDIR', meson.project_source_root()) cdata.set('TOP_SRCDIR', meson.project_source_root())
cdata.set('TOP_BUILDDIR', meson.project_build_root()) cdata.set('TOP_BUILDDIR', meson.project_build_root())
cdata.set('OUTPUT_DIR', meson.current_build_dir()) cdata.set('OUTPUT_DIR', meson.current_build_dir())
cdata.set('WARN_AS_ERROR', get_option('doc_werror') ? 'YES' : 'NO')
doxygen_predefined = [] doxygen_predefined = []
foreach key : config_h.keys() foreach key : config_h.keys()
@ -23,60 +24,124 @@ if doxygen.found() and dot.found()
cdata.set('PREDEFINED', ' \\\n\t\t\t '.join(doxygen_predefined)) cdata.set('PREDEFINED', ' \\\n\t\t\t '.join(doxygen_predefined))
doxyfile = configure_file(input : 'Doxyfile.in', doxyfile_common = configure_file(input : 'Doxyfile-common.in',
output : 'Doxyfile', output : 'Doxyfile-common',
configuration : cdata) configuration : cdata)
doxygen_input = [ doxygen_public_input = [
doxyfile, libcamera_base_public_headers,
libcamera_base_headers, libcamera_base_public_sources,
libcamera_base_sources, libcamera_public_headers,
libcamera_public_sources,
]
doxygen_internal_input = [
libcamera_base_private_headers,
libcamera_base_internal_sources,
libcamera_internal_headers, libcamera_internal_headers,
libcamera_internal_sources,
libcamera_ipa_headers, libcamera_ipa_headers,
libcamera_ipa_interfaces, libcamera_ipa_interfaces,
libcamera_public_headers,
libcamera_sources,
libipa_headers, libipa_headers,
libipa_sources, libipa_sources,
] ]
if is_variable('ipu3_ipa_sources') if is_variable('ipu3_ipa_sources')
doxygen_input += [ipu3_ipa_sources] doxygen_internal_input += [ipu3_ipa_sources]
endif endif
custom_target('doxygen', # We run doxygen twice - the first run excludes internal API objects as it
input : doxygen_input, # 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', output : 'api-html',
command : [doxygen, doxyfile], command : [doxygen, doxyfile],
install : true, install : true,
install_dir : doc_install_dir) 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 endif
# #
# Sphinx # Sphinx
# #
sphinx = find_program('sphinx-build-3', required : false) sphinx = find_program('sphinx-build-3', 'sphinx-build',
if not sphinx.found() required : get_option('documentation'))
sphinx = find_program('sphinx-build', required : get_option('documentation'))
endif
if sphinx.found() if sphinx.found()
docs_sources = [ docs_sources = [
'camera-sensor-model.rst',
'code-of-conduct.rst',
'coding-style.rst', 'coding-style.rst',
'conf.py', 'conf.py',
'contributing.rst', 'contributing.rst',
'docs.rst', 'design/ae.rst',
'documentation-contents.rst',
'environment_variables.rst', 'environment_variables.rst',
'feature_requirements.rst',
'guides/application-developer.rst', 'guides/application-developer.rst',
'guides/introduction.rst',
'guides/ipa.rst', 'guides/ipa.rst',
'guides/pipeline-handler.rst', 'guides/pipeline-handler.rst',
'guides/tracing.rst', 'guides/tracing.rst',
'index.rst', 'index.rst',
'introduction.rst',
'lens_driver_requirements.rst', 'lens_driver_requirements.rst',
'libcamera_architecture.rst',
'mali-c55.dot',
'python-bindings.rst', 'python-bindings.rst',
'sensor_driver_requirements.rst', 'sensor_driver_requirements.rst',
'software-isp-benchmarking.rst',
'../README.rst', '../README.rst',
] ]
@ -89,7 +154,8 @@ if sphinx.found()
output : 'html', output : 'html',
build_by_default : true, build_by_default : true,
install : true, install : true,
install_dir : doc_install_dir) install_dir : doc_install_dir,
install_tag : 'doc')
custom_target('documentation-linkcheck', custom_target('documentation-linkcheck',
command : [sphinx, '-W', '-b', 'linkcheck', meson.current_source_dir(), '@OUTPUT@'], command : [sphinx, '-W', '-b', 'linkcheck', meson.current_source_dir(), '@OUTPUT@'],

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _python-bindings: .. _python-bindings:
Python Bindings for libcamera Python Bindings for libcamera
@ -17,13 +19,13 @@ chapter lists the differences.
Mostly these differences fall under two categories: Mostly these differences fall under two categories:
1. Differences caused by the inherent differences between C++ and Python. 1. Differences caused by the inherent differences between C++ and Python.
These differences are usually caused by the use of threads or differences in These differences are usually caused by the use of threads or differences in
C++ vs Python memory management. C++ vs Python memory management.
2. Differences caused by the code being work-in-progress. It's not always 2. Differences caused by the code being work-in-progress. It's not always
trivial to create a binding in a satisfying way, and the current bindings trivial to create a binding in a satisfying way, and the current bindings
contain simplified versions of the C++ API just to get forward. These contain simplified versions of the C++ API just to get forward. These
differences are expected to eventually go away. differences are expected to eventually go away.
Coding Style Coding Style
------------ ------------

View file

@ -1,5 +1,7 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _sensor-driver-requirements: .. _sensor-driver-requirements:
Sensor Driver Requirements Sensor Driver Requirements

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 171 KiB

1720
Documentation/skipping.svg Normal file

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 80 KiB

View file

@ -0,0 +1,79 @@
.. SPDX-License-Identifier: CC-BY-SA-4.0
.. include:: documentation-contents.rst
.. _software-isp-benchmarking:
Software ISP benchmarking
=========================
The Software ISP is particularly sensitive to performance regressions therefore
it is a good idea to always benchmark the Software ISP before and after making
changes to it and ensure that there are no performance regressions.
DebayerCpu class builtin benchmark
----------------------------------
The DebayerCpu class has a builtin benchmark. This benchmark measures the time
spent on processing (collecting statistics and debayering) only, it does not
measure the time spent on capturing or outputting the frames.
The builtin benchmark always runs. So this can be used by simply running "cam"
or "qcam" with a pipeline using the Software ISP.
When it runs it will skip measuring the first 30 frames to allow the caches and
the CPU temperature (turbo-ing) to warm-up and then it measures 30 fps and shows
the total and per frame processing time using an info level log message:
.. code-block:: text
INFO Debayer debayer_cpu.cpp:907 Processed 30 frames in 244317us, 8143 us/frame
To get stable measurements it is advised to disable any other processes which
may cause significant CPU usage (e.g. disable wifi, bluetooth and browsers).
When possible it is also advisable to disable CPU turbo-ing and
frequency-scaling.
For example when benchmarking on a Lenovo ThinkPad X1 Yoga Gen 8, with the
charger plugged in, the CPU can be fixed to run at 2 GHz using:
.. code-block:: shell
sudo x86_energy_perf_policy --turbo-enable 0
sudo cpupower frequency-set -d 2GHz -u 2GHz
with these settings the builtin bench reports a processing time of ~7.8ms/frame
on this laptop for FHD SGRBG10 (unpacked) bayer data.
Measuring power consumption
---------------------------
Since the Software ISP is often used on mobile devices it is also important to
measure power consumption and ensure that that does not regress.
For example to measure power consumption on a Lenovo ThinkPad X1 Yoga Gen 8 it
needs to be running on battery and it should be configured with its
platform-profile (/sys/firmware/acpi/platform_profile) set to balanced and with
its default turbo and frequency-scaling behavior to match real world usage.
Then start qcam to capture a FHD picture at 30 fps and position the qcam window
so that it is fully visible. After this run the following command to monitor the
power consumption:
.. code-block:: shell
watch -n 10 cat /sys/class/power_supply/BAT0/power_now /sys/class/hwmon/hwmon6/fan?_input
Note this not only measures the power consumption in µW it also monitors the
speed of this laptop's 2 fans. This is important because depending on the
ambient temperature the 2 fans may spin up while testing and this will cause an
additional power consumption of approx. 0.5 W messing up the measurement.
After starting qcam + the watch command let the laptop sit without using it for
2 minutes for the readings to stabilize. Then check that the fans have not
turned on and manually take a couple of consecutive power readings and average
these.
On the example Lenovo ThinkPad X1 Yoga Gen 8 laptop this results in a measured
power consumption of approx. 13 W while running qcam versus approx. 4-5 W while
setting idle with its OLED panel on.

View file

@ -33,11 +33,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0
{% endif %} {% endif %}
{# RTD hosts this file, so just load on non RTD builds #}
{% if not READTHEDOCS %}
<link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
{% endif %}
{% for cssfile in css_files %} {% for cssfile in css_files %}
<link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" /> <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
{% endfor %} {% endfor %}

View file

@ -283,9 +283,13 @@ div#signature {
font-size: 12px; font-size: 12px;
} }
#libcamera div.toctree-wrapper { #licensing div.toctree-wrapper {
height: 0px; height: 0px;
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
visibility: hidden; 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 .. SPDX-License-Identifier: CC-BY-SA-4.0
.. section-begin-libcamera
=========== ===========
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 out of that collaboration and will offer modern camera support to Linux-based
systems, including traditional Linux distributions, ChromeOS and Android. systems, including traditional Linux distributions, ChromeOS and Android.
.. section-end-libcamera
.. section-begin-getting-started .. section-begin-getting-started
Getting Started Getting Started
@ -30,7 +27,7 @@ Getting Started
To fetch the sources, build and install: To fetch the sources, build and install:
:: .. code::
git clone https://git.libcamera.org/libcamera/libcamera.git git clone https://git.libcamera.org/libcamera/libcamera.git
cd libcamera cd libcamera
@ -47,15 +44,7 @@ A C++ toolchain: [required]
Either {g++, clang} Either {g++, clang}
Meson Build system: [required] Meson Build system: [required]
meson (>= 0.56) ninja-build pkg-config meson (>= 0.63) ninja-build pkg-config
If your distribution doesn't provide a recent enough version of meson,
you can install or upgrade it using pip3.
.. code::
pip3 install --user meson
pip3 install --user --upgrade meson
for the libcamera core: [required] for the libcamera core: [required]
libyaml-dev python3-yaml python3-ply python3-jinja2 libyaml-dev python3-yaml python3-ply python3-jinja2
@ -83,6 +72,9 @@ for documentation: [optional]
for gstreamer: [optional] for gstreamer: [optional]
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
for Python bindings: [optional]
libpython3-dev pybind11-dev
for cam: [optional] for cam: [optional]
libevent-dev is required to support cam, however the following libevent-dev is required to support cam, however the following
optional dependencies bring more functionality to the cam test optional dependencies bring more functionality to the cam test
@ -91,9 +83,10 @@ for cam: [optional]
- libdrm-dev: Enables the KMS sink - libdrm-dev: Enables the KMS sink
- libjpeg-dev: Enables MJPEG on the SDL sink - libjpeg-dev: Enables MJPEG on the SDL sink
- libsdl2-dev: Enables the SDL sink - libsdl2-dev: Enables the SDL sink
- libtiff-dev: Enables writing DNG
for qcam: [optional] for qcam: [optional]
qtbase5-dev libqt5core5a libqt5gui5 libqt5widgets5 qttools5-dev-tools libtiff-dev libtiff-dev qt6-base-dev
for tracing with lttng: [optional] for tracing with lttng: [optional]
liblttng-ust-dev python3-jinja2 lttng-tools liblttng-ust-dev python3-jinja2 lttng-tools
@ -102,7 +95,7 @@ for android: [optional]
libexif-dev libjpeg-dev libexif-dev libjpeg-dev
for lc-compliance: [optional] for lc-compliance: [optional]
libevent-dev libevent-dev libgtest-dev
for abi-compat.sh: [optional] for abi-compat.sh: [optional]
abi-compliance-checker abi-compliance-checker
@ -125,10 +118,13 @@ setting the ``LIBCAMERA_LOG_LEVELS`` environment variable:
Using GStreamer plugin Using GStreamer plugin
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
To use GStreamer plugin from source tree, set the following environment so that To use the GStreamer plugin from the source tree, use the meson ``devenv``
GStreamer can find it. This isn't necessary when libcamera is installed. command. This will create a new shell instance with the ``GST_PLUGIN_PATH``
environment set accordingly.
export GST_PLUGIN_PATH=$(pwd)/build/src/gstreamer .. code::
meson devenv -C build
The debugging tool ``gst-launch-1.0`` can be used to construct a pipeline and The debugging tool ``gst-launch-1.0`` can be used to construct a pipeline and
test it. The following pipeline will stream from the camera named "Camera 1" test it. The following pipeline will stream from the camera named "Camera 1"
@ -136,7 +132,7 @@ onto the OpenGL accelerated display element on your system.
.. code:: .. code::
gst-launch-1.0 libcamerasrc camera-name="Camera 1" ! glimagesink gst-launch-1.0 libcamerasrc camera-name="Camera 1" ! queue ! glimagesink
To show the first camera found you can omit the camera-name property, or you To show the first camera found you can omit the camera-name property, or you
can list the cameras and their capabilities using: can list the cameras and their capabilities using:
@ -151,7 +147,7 @@ if desired with a pipeline such as:
.. code:: .. code::
gst-launch-1.0 libcamerasrc ! 'video/x-raw,width=1280,height=720' ! \ gst-launch-1.0 libcamerasrc ! 'video/x-raw,width=1280,height=720' ! \
glimagesink queue ! glimagesink
The libcamerasrc element has two log categories, named libcamera-provider (for The libcamerasrc element has two log categories, named libcamera-provider (for
the video device provider) and libcamerasrc (for the operation of the camera). the video device provider) and libcamerasrc (for the operation of the camera).
@ -167,7 +163,7 @@ the following example could be used as a starting point:
gst-launch-1.0 libcamerasrc ! \ gst-launch-1.0 libcamerasrc ! \
video/x-raw,colorimetry=bt709,format=NV12,width=1280,height=720,framerate=30/1 ! \ video/x-raw,colorimetry=bt709,format=NV12,width=1280,height=720,framerate=30/1 ! \
jpegenc ! multipartmux ! \ queue ! jpegenc ! multipartmux ! \
tcpserversink host=0.0.0.0 port=5000 tcpserversink host=0.0.0.0 port=5000
Which can be received on another device over the network with: Which can be received on another device over the network with:
@ -177,6 +173,22 @@ Which can be received on another device over the network with:
gst-launch-1.0 tcpclientsrc host=$DEVICE_IP port=5000 ! \ gst-launch-1.0 tcpclientsrc host=$DEVICE_IP port=5000 ! \
multipartdemux ! jpegdec ! autovideosink 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 .. section-end-getting-started
Troubleshooting Troubleshooting
@ -194,8 +206,8 @@ the build.ninja module. This is a snippet of the error message.
This can be solved in two ways: This can be solved in two ways:
1) Don't install meson again if it is already installed system-wide. 1. Don't install meson again if it is already installed system-wide.
2) If a version of meson which is different from the system-wide version is 2. If a version of meson which is different from the system-wide version is
already installed, uninstall that meson using pip3, and install again without already installed, uninstall that meson using pip3, and install again without
the --user argument. the --user argument.

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2021, Ideas on Board Oy * Copyright (C) 2021, Ideas on Board Oy
* *
* backtrace.h - Call stack backtraces * Call stack backtraces
*/ */
#pragma once #pragma once

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* bound_method.h - Method bind and invocation * Method bind and invocation
*/ */
#pragma once #pragma once
@ -98,21 +98,15 @@ public:
using PackType = BoundMethodPack<R, Args...>; using PackType = BoundMethodPack<R, Args...>;
private: private:
template<std::size_t... I, typename T = R> template<std::size_t... I>
std::enable_if_t<!std::is_void<T>::value, void> void invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>)
invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>)
{ {
PackType *args = static_cast<PackType *>(pack); [[maybe_unused]] auto *args = static_cast<PackType *>(pack);
args->ret_ = invoke(std::get<I>(args->args_)...);
}
template<std::size_t... I, typename T = R> if constexpr (!std::is_void_v<R>)
std::enable_if_t<std::is_void<T>::value, void> args->ret_ = invoke(std::get<I>(args->args_)...);
invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>) else
{ invoke(std::get<I>(args->args_)...);
/* args is effectively unused when the sequence I is empty. */
PackType *args [[gnu::unused]] = static_cast<PackType *>(pack);
invoke(std::get<I>(args->args_)...);
} }
public: public:

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2020, Google Inc. * Copyright (C) 2020, Google Inc.
* *
* class.h - Utilities and helpers for classes * Utilities and helpers for classes
*/ */
#pragma once #pragma once

View file

@ -1,14 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2021, Google Inc.
*
* compiler.h - Compiler support
*/
#pragma once
#if __cplusplus >= 201703L
#define __nodiscard [[nodiscard]]
#else
#define __nodiscard
#endif

View file

@ -2,13 +2,11 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* event_dispatcher.h - Event dispatcher * Event dispatcher
*/ */
#pragma once #pragma once
#include <vector>
#include <libcamera/base/private.h> #include <libcamera/base/private.h>
namespace libcamera { namespace libcamera {

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* event_dispatcher_poll.h - Poll-based event dispatcher * Poll-based event dispatcher
*/ */
#pragma once #pragma once

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* event_notifier.h - File descriptor event notifier * File descriptor event notifier
*/ */
#pragma once #pragma once

View file

@ -2,15 +2,15 @@
/* /*
* Copyright (C) 2020, Google Inc. * Copyright (C) 2020, Google Inc.
* *
* file.h - File I/O operations * File I/O operations
*/ */
#pragma once #pragma once
#include <sys/types.h>
#include <map> #include <map>
#include <stdint.h>
#include <string> #include <string>
#include <sys/types.h>
#include <libcamera/base/private.h> #include <libcamera/base/private.h>

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2020, Google Inc. * Copyright (C) 2020, Google Inc.
* *
* flags.h - Type-safe enum-based bitfields * Type-safe enum-based bitfields
*/ */
#pragma once #pragma once

View file

@ -2,13 +2,14 @@
/* /*
* Copyright (C) 2018, Google Inc. * Copyright (C) 2018, Google Inc.
* *
* log.h - Logging infrastructure * Logging infrastructure
*/ */
#pragma once #pragma once
#include <chrono> #include <atomic>
#include <sstream> #include <sstream>
#include <string_view>
#include <libcamera/base/private.h> #include <libcamera/base/private.h>
@ -29,25 +30,29 @@ enum LogSeverity {
class LogCategory class LogCategory
{ {
public: public:
static LogCategory *create(const char *name); static LogCategory *create(std::string_view name);
const std::string &name() const { return name_; } const std::string &name() const { return name_; }
LogSeverity severity() const { return severity_; } LogSeverity severity() const { return severity_.load(std::memory_order_relaxed); }
void setSeverity(LogSeverity severity); void setSeverity(LogSeverity severity) { severity_.store(severity, std::memory_order_relaxed); }
static const LogCategory &defaultCategory(); static const LogCategory &defaultCategory();
private: private:
explicit LogCategory(const char *name); friend class Logger;
explicit LogCategory(std::string_view name);
const std::string name_; const std::string name_;
LogSeverity severity_;
std::atomic<LogSeverity> severity_;
static_assert(decltype(severity_)::is_always_lock_free);
}; };
#define LOG_DECLARE_CATEGORY(name) \ #define LOG_DECLARE_CATEGORY(name) \
extern const LogCategory &_LOG_CATEGORY(name)(); extern const LogCategory &_LOG_CATEGORY(name)();
#define LOG_DEFINE_CATEGORY(name) \ #define LOG_DEFINE_CATEGORY(name) \
LOG_DECLARE_CATEGORY(name) \
const LogCategory &_LOG_CATEGORY(name)() \ const LogCategory &_LOG_CATEGORY(name)() \
{ \ { \
/* The instance will be deleted by the Logger destructor. */ \ /* The instance will be deleted by the Logger destructor. */ \
@ -60,9 +65,7 @@ class LogMessage
public: public:
LogMessage(const char *fileName, unsigned int line, LogMessage(const char *fileName, unsigned int line,
const LogCategory &category, LogSeverity severity, const LogCategory &category, LogSeverity severity,
const std::string &prefix = std::string()); std::string prefix = {});
LogMessage(LogMessage &&);
~LogMessage(); ~LogMessage();
std::ostream &stream() { return msgStream_; } std::ostream &stream() { return msgStream_; }
@ -75,9 +78,7 @@ public:
const std::string msg() const { return msgStream_.str(); } const std::string msg() const { return msgStream_.str(); }
private: private:
LIBCAMERA_DISABLE_COPY(LogMessage) LIBCAMERA_DISABLE_COPY_AND_MOVE(LogMessage)
void init(const char *fileName, unsigned int line);
std::ostringstream msgStream_; std::ostringstream msgStream_;
const LogCategory &category_; 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([ libcamera_base_public_headers = files([
'bound_method.h', 'bound_method.h',
'class.h', 'class.h',
'compiler.h',
'flags.h', 'flags.h',
'object.h', 'object.h',
'shared_fd.h', 'shared_fd.h',
@ -21,6 +20,7 @@ libcamera_base_private_headers = files([
'event_notifier.h', 'event_notifier.h',
'file.h', 'file.h',
'log.h', 'log.h',
'memfd.h',
'message.h', 'message.h',
'mutex.h', 'mutex.h',
'private.h', 'private.h',

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* message.h - Message queue support * Message queue support
*/ */
#pragma once #pragma once

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2021, Google Inc. * Copyright (C) 2021, Google Inc.
* *
* mutex.h - Mutex classes with clang thread safety annotation * Mutex classes with clang thread safety annotation
*/ */
#pragma once #pragma once
@ -23,10 +23,6 @@ namespace libcamera {
class LIBCAMERA_TSA_CAPABILITY("mutex") Mutex final class LIBCAMERA_TSA_CAPABILITY("mutex") Mutex final
{ {
public: public:
constexpr Mutex()
{
}
void lock() LIBCAMERA_TSA_ACQUIRE() void lock() LIBCAMERA_TSA_ACQUIRE()
{ {
mutex_.lock(); mutex_.lock();
@ -84,10 +80,6 @@ private:
class ConditionVariable final class ConditionVariable final
{ {
public: public:
ConditionVariable()
{
}
void notify_one() noexcept void notify_one() noexcept
{ {
cv_.notify_one(); cv_.notify_one();

View file

@ -2,16 +2,18 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* object.h - Base object * Base object
*/ */
#pragma once #pragma once
#include <list> #include <list>
#include <memory> #include <memory>
#include <utility>
#include <vector> #include <vector>
#include <libcamera/base/bound_method.h> #include <libcamera/base/bound_method.h>
#include <libcamera/base/class.h>
namespace libcamera { namespace libcamera {
@ -38,7 +40,7 @@ public:
{ {
T *obj = static_cast<T *>(this); T *obj = static_cast<T *>(this);
auto *method = new BoundMethodMember<T, R, FuncArgs...>(obj, this, func, type); 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_; } Thread *thread() const { return thread_; }
@ -49,7 +51,11 @@ public:
protected: protected:
virtual void message(Message *msg); virtual void message(Message *msg);
bool assertThreadBound(const char *message);
private: private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(Object)
friend class SignalBase; friend class SignalBase;
friend class Thread; friend class Thread;

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2021, Google Inc. * Copyright (C) 2021, Google Inc.
* *
* private.h - Private Header Validation * Private Header Validation
* *
* A selection of internal libcamera headers are installed as part * A selection of internal libcamera headers are installed as part
* of the libcamera package to allow sharing of a select subset of * of the libcamera package to allow sharing of a select subset of

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* semaphore.h - General-purpose counting semaphore * General-purpose counting semaphore
*/ */
#pragma once #pragma once

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* shared_fd.h - File descriptor wrapper with shared ownership * File descriptor wrapper with shared ownership
*/ */
#pragma once #pragma once

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* signal.h - Signal & slot implementation * Signal & slot implementation
*/ */
#pragma once #pragma once
@ -10,13 +10,13 @@
#include <functional> #include <functional>
#include <list> #include <list>
#include <type_traits> #include <type_traits>
#include <vector>
#include <libcamera/base/bound_method.h> #include <libcamera/base/bound_method.h>
#include <libcamera/base/object.h>
namespace libcamera { namespace libcamera {
class Object;
class SignalBase class SignalBase
{ {
public: public:
@ -63,11 +63,8 @@ public:
#ifndef __DOXYGEN__ #ifndef __DOXYGEN__
template<typename T, typename Func, template<typename T, typename Func,
std::enable_if_t<std::is_base_of<Object, T>::value std::enable_if_t<std::is_base_of<Object, T>::value &&
#if __cplusplus >= 201703L std::is_invocable_v<Func, Args...>> * = nullptr>
&& std::is_invocable_v<Func, Args...>
#endif
> * = nullptr>
void connect(T *obj, Func func, ConnectionType type = ConnectionTypeAuto) void connect(T *obj, Func func, ConnectionType type = ConnectionTypeAuto)
{ {
Object *object = static_cast<Object *>(obj); Object *object = static_cast<Object *>(obj);
@ -75,11 +72,8 @@ public:
} }
template<typename T, typename Func, template<typename T, typename Func,
std::enable_if_t<!std::is_base_of<Object, T>::value std::enable_if_t<!std::is_base_of<Object, T>::value &&
#if __cplusplus >= 201703L std::is_invocable_v<Func, Args...>> * = nullptr>
&& std::is_invocable_v<Func, Args...>
#endif
> * = nullptr>
#else #else
template<typename T, typename Func> template<typename T, typename Func>
#endif #endif

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2020, Google Inc. * Copyright (C) 2020, Google Inc.
* *
* span.h - C++20 std::span<> implementation for C++11 * C++20 std::span<> implementation for C++11
*/ */
#pragma once #pragma once
@ -10,7 +10,6 @@
#include <array> #include <array>
#include <iterator> #include <iterator>
#include <limits> #include <limits>
#include <stddef.h>
#include <type_traits> #include <type_traits>
namespace libcamera { namespace libcamera {
@ -347,13 +346,7 @@ public:
} }
constexpr Span(const Span &other) noexcept = default; constexpr Span(const Span &other) noexcept = default;
constexpr Span &operator=(const Span &other) noexcept = default;
constexpr Span &operator=(const Span &other) noexcept
{
data_ = other.data_;
size_ = other.size_;
return *this;
}
constexpr iterator begin() const { return data(); } constexpr iterator begin() const { return data(); }
constexpr const_iterator cbegin() const { return begin(); } constexpr const_iterator cbegin() const { return begin(); }

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* thread.h - Thread support * Thread support
*/ */
#pragma once #pragma once
@ -13,8 +13,10 @@
#include <libcamera/base/private.h> #include <libcamera/base/private.h>
#include <libcamera/base/class.h>
#include <libcamera/base/message.h> #include <libcamera/base/message.h>
#include <libcamera/base/signal.h> #include <libcamera/base/signal.h>
#include <libcamera/base/span.h>
#include <libcamera/base/utils.h> #include <libcamera/base/utils.h>
namespace libcamera { namespace libcamera {
@ -35,6 +37,8 @@ public:
void exit(int code = 0); void exit(int code = 0);
bool wait(utils::duration duration = utils::duration::max()); bool wait(utils::duration duration = utils::duration::max());
int setThreadAffinity(const Span<const unsigned int> &cpus);
bool isRunning(); bool isRunning();
Signal<> finished; Signal<> finished;
@ -44,16 +48,21 @@ public:
EventDispatcher *eventDispatcher(); EventDispatcher *eventDispatcher();
void dispatchMessages(Message::Type type = Message::Type::None); void dispatchMessages(Message::Type type = Message::Type::None,
Object *receiver = nullptr);
protected: protected:
int exec(); int exec();
virtual void run(); virtual void run();
private: private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(Thread)
void startThread(); void startThread();
void finishThread(); void finishThread();
void setThreadAffinityInternal();
void postMessage(std::unique_ptr<Message> msg, Object *receiver); void postMessage(std::unique_ptr<Message> msg, Object *receiver);
void removeMessages(Object *receiver); void removeMessages(Object *receiver);

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2021, Google Inc. * Copyright (C) 2021, Google Inc.
* *
* thread_annotation.h - Macro of Clang thread safety analysis * Macro of Clang thread safety analysis
*/ */
#pragma once #pragma once

View file

@ -2,13 +2,12 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* timer.h - Generic timer * Generic timer
*/ */
#pragma once #pragma once
#include <chrono> #include <chrono>
#include <stdint.h>
#include <libcamera/base/private.h> #include <libcamera/base/private.h>

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2021, Google Inc. * Copyright (C) 2021, Google Inc.
* *
* unique_fd.h - File descriptor wrapper that owns a file descriptor. * File descriptor wrapper that owns a file descriptor.
*/ */
#pragma once #pragma once
@ -10,7 +10,6 @@
#include <utility> #include <utility>
#include <libcamera/base/class.h> #include <libcamera/base/class.h>
#include <libcamera/base/compiler.h>
namespace libcamera { namespace libcamera {
@ -43,7 +42,7 @@ public:
return *this; return *this;
} }
__nodiscard int release() [[nodiscard]] int release()
{ {
int fd = fd_; int fd = fd_;
fd_ = -1; fd_ = -1;

View file

@ -2,19 +2,20 @@
/* /*
* Copyright (C) 2018, Google Inc. * Copyright (C) 2018, Google Inc.
* *
* utils.h - Miscellaneous utility functions * Miscellaneous utility functions
*/ */
#pragma once #pragma once
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
#include <functional>
#include <iterator> #include <iterator>
#include <memory>
#include <ostream> #include <ostream>
#include <sstream> #include <sstream>
#include <string> #include <stdint.h>
#include <string.h> #include <string.h>
#include <string>
#include <sys/time.h> #include <sys/time.h>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
@ -90,6 +91,30 @@ template<typename T,
_hex hex(T value, unsigned int width = 0); _hex hex(T value, unsigned int width = 0);
#ifndef __DOXYGEN__ #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<> template<>
inline _hex hex<int32_t>(int32_t value, unsigned int width) inline _hex hex<int32_t>(int32_t value, unsigned int width)
{ {
@ -180,7 +205,16 @@ public:
iterator &operator++(); iterator &operator++();
std::string operator*() const; 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: private:
const StringSplitter *ss_; const StringSplitter *ss_;
@ -188,8 +222,15 @@ public:
std::string::size_type next_; std::string::size_type next_;
}; };
iterator begin() const; iterator begin() const
iterator end() const; {
return { this, 0 };
}
iterator end() const
{
return { this, std::string::npos };
}
private: private:
std::string str_; std::string str_;
@ -369,6 +410,24 @@ decltype(auto) abs_diff(const T &a, const T &b)
double strtod(const char *__restrict nptr, char **__restrict endptr); double strtod(const char *__restrict nptr, char **__restrict endptr);
template<class Enum>
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 */ } /* namespace utils */
#ifndef __DOXYGEN__ #ifndef __DOXYGEN__

View file

@ -2,13 +2,14 @@
/* /*
* Copyright (C) 2018, Google Inc. * Copyright (C) 2018, Google Inc.
* *
* camera.h - Camera object interface * Camera object interface
*/ */
#pragma once #pragma once
#include <initializer_list> #include <initializer_list>
#include <memory> #include <memory>
#include <optional>
#include <set> #include <set>
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
@ -19,9 +20,10 @@
#include <libcamera/base/signal.h> #include <libcamera/base/signal.h>
#include <libcamera/controls.h> #include <libcamera/controls.h>
#include <libcamera/geometry.h>
#include <libcamera/orientation.h>
#include <libcamera/request.h> #include <libcamera/request.h>
#include <libcamera/stream.h> #include <libcamera/stream.h>
#include <libcamera/transform.h>
namespace libcamera { namespace libcamera {
@ -30,6 +32,30 @@ class FrameBufferAllocator;
class PipelineHandler; class PipelineHandler;
class Request; class Request;
class SensorConfiguration
{
public:
unsigned int bitDepth = 0;
Rectangle analogCrop;
struct {
unsigned int binX = 1;
unsigned int binY = 1;
} binning;
struct {
unsigned int xOddInc = 1;
unsigned int xEvenInc = 1;
unsigned int yOddInc = 1;
unsigned int yEvenInc = 1;
} skipping;
Size outputSize;
bool isValid() const;
};
class CameraConfiguration class CameraConfiguration
{ {
public: public:
@ -66,7 +92,8 @@ public:
bool empty() const; bool empty() const;
std::size_t size() const; std::size_t size() const;
Transform transform; std::optional<SensorConfiguration> sensorConfig;
Orientation orientation;
protected: protected:
CameraConfiguration(); CameraConfiguration();

View file

@ -2,13 +2,14 @@
/* /*
* Copyright (C) 2018, Google Inc. * Copyright (C) 2018, Google Inc.
* *
* camera_manager.h - Camera management * Camera management
*/ */
#pragma once #pragma once
#include <memory> #include <memory>
#include <string> #include <string>
#include <string_view>
#include <sys/types.h> #include <sys/types.h>
#include <vector> #include <vector>
@ -31,7 +32,7 @@ public:
void stop(); void stop();
std::vector<std::shared_ptr<Camera>> cameras() const; 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_; } static const std::string &version() { return version_; }

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2021, Raspberry Pi Ltd * Copyright (C) 2021, Raspberry Pi Ltd
* *
* color_space.h - color space definitions * color space definitions
*/ */
#pragma once #pragma once

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* control_ids.h - Control ID list * {{mode|capitalize}} ID list
* *
* This file is auto-generated. Do not edit. * This file is auto-generated. Do not edit.
*/ */
@ -10,28 +10,52 @@
#pragma once #pragma once
#include <array> #include <array>
#include <map>
#include <stdint.h> #include <stdint.h>
#include <string>
#include <libcamera/controls.h> #include <libcamera/controls.h>
namespace libcamera { 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 { 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 -%}
namespace draft { {% endfor %}
} /* namespace {{mode}} */
${draft_controls}
} /* namespace draft */
} /* namespace controls */
} /* namespace libcamera */ } /* namespace libcamera */

View file

@ -2,12 +2,13 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* controls.h - Control handling * Control handling
*/ */
#pragma once #pragma once
#include <assert.h> #include <assert.h>
#include <map>
#include <optional> #include <optional>
#include <set> #include <set>
#include <stdint.h> #include <stdint.h>
@ -16,6 +17,7 @@
#include <vector> #include <vector>
#include <libcamera/base/class.h> #include <libcamera/base/class.h>
#include <libcamera/base/flags.h>
#include <libcamera/base/span.h> #include <libcamera/base/span.h>
#include <libcamera/geometry.h> #include <libcamera/geometry.h>
@ -28,67 +30,102 @@ enum ControlType {
ControlTypeNone, ControlTypeNone,
ControlTypeBool, ControlTypeBool,
ControlTypeByte, ControlTypeByte,
ControlTypeUnsigned16,
ControlTypeUnsigned32,
ControlTypeInteger32, ControlTypeInteger32,
ControlTypeInteger64, ControlTypeInteger64,
ControlTypeFloat, ControlTypeFloat,
ControlTypeString, ControlTypeString,
ControlTypeRectangle, ControlTypeRectangle,
ControlTypeSize, ControlTypeSize,
ControlTypePoint,
}; };
namespace details { namespace details {
template<typename T> template<typename T, typename = std::void_t<>>
struct control_type { struct control_type {
}; };
template<> template<>
struct control_type<void> { struct control_type<void> {
static constexpr ControlType value = ControlTypeNone; static constexpr ControlType value = ControlTypeNone;
static constexpr std::size_t size = 0;
}; };
template<> template<>
struct control_type<bool> { struct control_type<bool> {
static constexpr ControlType value = ControlTypeBool; static constexpr ControlType value = ControlTypeBool;
static constexpr std::size_t size = 0;
}; };
template<> template<>
struct control_type<uint8_t> { struct control_type<uint8_t> {
static constexpr ControlType value = ControlTypeByte; 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<> template<>
struct control_type<int32_t> { struct control_type<int32_t> {
static constexpr ControlType value = ControlTypeInteger32; static constexpr ControlType value = ControlTypeInteger32;
static constexpr std::size_t size = 0;
}; };
template<> template<>
struct control_type<int64_t> { struct control_type<int64_t> {
static constexpr ControlType value = ControlTypeInteger64; static constexpr ControlType value = ControlTypeInteger64;
static constexpr std::size_t size = 0;
}; };
template<> template<>
struct control_type<float> { struct control_type<float> {
static constexpr ControlType value = ControlTypeFloat; static constexpr ControlType value = ControlTypeFloat;
static constexpr std::size_t size = 0;
}; };
template<> template<>
struct control_type<std::string> { struct control_type<std::string> {
static constexpr ControlType value = ControlTypeString; static constexpr ControlType value = ControlTypeString;
static constexpr std::size_t size = 0;
}; };
template<> template<>
struct control_type<Rectangle> { struct control_type<Rectangle> {
static constexpr ControlType value = ControlTypeRectangle; static constexpr ControlType value = ControlTypeRectangle;
static constexpr std::size_t size = 0;
}; };
template<> template<>
struct control_type<Size> { struct control_type<Size> {
static constexpr ControlType value = ControlTypeSize; 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> 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 */ } /* namespace details */
@ -213,23 +250,44 @@ private:
class ControlId class ControlId
{ {
public: public:
ControlId(unsigned int id, const std::string &name, ControlType type) enum class Direction {
: id_(id), name_(name), type_(type) 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_; } unsigned int id() const { return id_; }
const std::string &name() const { return name_; } const std::string &name() const { return name_; }
const std::string &vendor() const { return vendor_; }
ControlType type() const { return type_; } 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: private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(ControlId) LIBCAMERA_DISABLE_COPY_AND_MOVE(ControlId)
unsigned int id_; unsigned int id_;
std::string name_; std::string name_;
std::string vendor_;
ControlType type_; 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) static inline bool operator==(unsigned int lhs, const ControlId &rhs)
{ {
return lhs == rhs.id(); return lhs == rhs.id();
@ -256,8 +314,11 @@ class Control : public ControlId
public: public:
using type = T; using type = T;
Control(unsigned int id, const char *name) Control(unsigned int id, const char *name, const char *vendor,
: ControlId(id, name, details::control_type<std::remove_cv_t<T>>::value) 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)
{ {
} }
@ -352,6 +413,11 @@ private:
using ControlListMap = std::unordered_map<unsigned int, ControlValue>; using ControlListMap = std::unordered_map<unsigned int, ControlValue>;
public: public:
enum class MergePolicy {
KeepExisting = 0,
OverwriteExisting,
};
ControlList(); ControlList();
ControlList(const ControlIdMap &idmap, const ControlValidator *validator = nullptr); ControlList(const ControlIdMap &idmap, const ControlValidator *validator = nullptr);
ControlList(const ControlInfoMap &infoMap, const ControlValidator *validator = nullptr); ControlList(const ControlInfoMap &infoMap, const ControlValidator *validator = nullptr);
@ -368,7 +434,7 @@ public:
std::size_t size() const { return controls_.size(); } std::size_t size() const { return controls_.size(); }
void clear() { controls_.clear(); } void clear() { controls_.clear(); }
void merge(const ControlList &source); void merge(const ControlList &source, MergePolicy policy = MergePolicy::KeepExisting);
bool contains(unsigned int id) const; bool contains(unsigned int id) const;

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2021, Google Inc. * Copyright (C) 2021, Google Inc.
* *
* internal/fence.h - Synchronization fence * Synchronization fence
*/ */
#pragma once #pragma once

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2020, Google Inc. * Copyright (C) 2020, Google Inc.
* *
* formats.h - Formats * Formats
* *
* This file is auto-generated. Do not edit. * This file is auto-generated. Do not edit.
*/ */

View file

@ -2,12 +2,11 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* framebuffer.h - Frame buffer handling * Frame buffer handling
*/ */
#pragma once #pragma once
#include <assert.h>
#include <limits> #include <limits>
#include <memory> #include <memory>
#include <stdint.h> #include <stdint.h>
@ -27,6 +26,7 @@ struct FrameMetadata {
FrameSuccess, FrameSuccess,
FrameError, FrameError,
FrameCancelled, FrameCancelled,
FrameStartup,
}; };
struct Plane { struct Plane {

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* framebuffer_allocator.h - FrameBuffer allocator * FrameBuffer allocator
*/ */
#pragma once #pragma once

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* geometry.h - Geometry-related classes * Geometry-related classes
*/ */
#pragma once #pragma once
@ -11,8 +11,6 @@
#include <ostream> #include <ostream>
#include <string> #include <string>
#include <libcamera/base/compiler.h>
namespace libcamera { namespace libcamera {
class Rectangle; class Rectangle;
@ -110,8 +108,8 @@ public:
return *this; return *this;
} }
__nodiscard constexpr Size alignedDownTo(unsigned int hAlignment, [[nodiscard]] constexpr Size alignedDownTo(unsigned int hAlignment,
unsigned int vAlignment) const unsigned int vAlignment) const
{ {
return { return {
width / hAlignment * hAlignment, width / hAlignment * hAlignment,
@ -119,8 +117,8 @@ public:
}; };
} }
__nodiscard constexpr Size alignedUpTo(unsigned int hAlignment, [[nodiscard]] constexpr Size alignedUpTo(unsigned int hAlignment,
unsigned int vAlignment) const unsigned int vAlignment) const
{ {
return { return {
(width + hAlignment - 1) / hAlignment * hAlignment, (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 { return {
std::min(width, bound.width), 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 { return {
std::max(width, expand.width), 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 { return {
width + margins.width, 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 { return {
width > margins.width ? width - margins.width : 0, width > margins.width ? width - margins.width : 0,
@ -160,10 +158,10 @@ public:
}; };
} }
__nodiscard Size boundedToAspectRatio(const Size &ratio) const; [[nodiscard]] Size boundedToAspectRatio(const Size &ratio) const;
__nodiscard Size expandedToAspectRatio(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;
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 x;
int y; int y;
unsigned int width; unsigned int width;
@ -285,11 +292,14 @@ public:
Rectangle &scaleBy(const Size &numerator, const Size &denominator); Rectangle &scaleBy(const Size &numerator, const Size &denominator);
Rectangle &translateBy(const Point &point); Rectangle &translateBy(const Point &point);
__nodiscard Rectangle boundedTo(const Rectangle &bound) const; [[nodiscard]] Rectangle boundedTo(const Rectangle &bound) const;
__nodiscard Rectangle enclosedIn(const Rectangle &boundary) const; [[nodiscard]] Rectangle enclosedIn(const Rectangle &boundary) const;
__nodiscard Rectangle scaledBy(const Size &numerator, [[nodiscard]] Rectangle scaledBy(const Size &numerator,
const Size &denominator) const; const Size &denominator) const;
__nodiscard Rectangle translatedBy(const Point &point) 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); bool operator==(const Rectangle &lhs, const Rectangle &rhs);

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2020, Raspberry Pi Ltd * Copyright (C) 2020, Raspberry Pi Ltd
* *
* bayer_format.h - Bayer Pixel Format * Bayer Pixel Format
*/ */
#pragma once #pragma once
@ -34,6 +34,8 @@ public:
None = 0, None = 0,
CSI2 = 1, CSI2 = 1,
IPU3 = 2, IPU3 = 2,
PISP1 = 3,
PISP2 = 4,
}; };
constexpr BayerFormat() constexpr BayerFormat()

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* byte_stream_buffer.h - Byte stream buffer * Byte stream buffer
*/ */
#pragma once #pragma once

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2021, Google Inc. * Copyright (C) 2021, Google Inc.
* *
* camera.h - Camera private data * Camera private data
*/ */
#pragma once #pragma once
@ -11,6 +11,7 @@
#include <list> #include <list>
#include <memory> #include <memory>
#include <set> #include <set>
#include <stdint.h>
#include <string> #include <string>
#include <libcamera/base/class.h> #include <libcamera/base/class.h>
@ -32,6 +33,7 @@ public:
~Private(); ~Private();
PipelineHandler *pipe() { return pipe_.get(); } PipelineHandler *pipe() { return pipe_.get(); }
const PipelineHandler *pipe() const { return pipe_.get(); }
std::list<Request *> queuedRequests_; std::list<Request *> queuedRequests_;
ControlInfoMap controlInfo_; ControlInfoMap controlInfo_;

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* camera_controls.h - Camera controls * Camera controls
*/ */
#pragma once #pragma once

View file

@ -2,11 +2,12 @@
/* /*
* Copyright (C) 2021, Google Inc. * Copyright (C) 2021, Google Inc.
* *
* camera_lens.h - A camera lens controller * A camera lens controller
*/ */
#pragma once #pragma once
#include <memory> #include <memory>
#include <stdint.h>
#include <string> #include <string>
#include <libcamera/base/class.h> #include <libcamera/base/class.h>

View file

@ -2,14 +2,13 @@
/* /*
* Copyright (C) 2023, Ideas on Board Oy. * Copyright (C) 2023, Ideas on Board Oy.
* *
* camera_manager.h - Camera manager private data * Camera manager private data
*/ */
#pragma once #pragma once
#include <libcamera/camera_manager.h> #include <libcamera/camera_manager.h>
#include <map>
#include <memory> #include <memory>
#include <sys/types.h> #include <sys/types.h>
#include <vector> #include <vector>
@ -19,13 +18,14 @@
#include <libcamera/base/thread.h> #include <libcamera/base/thread.h>
#include <libcamera/base/thread_annotations.h> #include <libcamera/base/thread_annotations.h>
#include "libcamera/internal/ipa_manager.h"
#include "libcamera/internal/process.h" #include "libcamera/internal/process.h"
namespace libcamera { namespace libcamera {
class Camera; class Camera;
class DeviceEnumerator; class DeviceEnumerator;
class IPAManager;
class PipelineHandlerFactoryBase;
class CameraManager::Private : public Extensible::Private, public Thread class CameraManager::Private : public Extensible::Private, public Thread
{ {
@ -38,12 +38,15 @@ public:
void addCamera(std::shared_ptr<Camera> camera) LIBCAMERA_TSA_EXCLUDES(mutex_); void addCamera(std::shared_ptr<Camera> camera) LIBCAMERA_TSA_EXCLUDES(mutex_);
void removeCamera(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: protected:
void run() override; void run() override;
private: private:
int init(); int init();
void createPipelineHandlers(); void createPipelineHandlers();
void pipelineFactoryMatch(const PipelineHandlerFactoryBase *factory);
void cleanup() LIBCAMERA_TSA_EXCLUDES(mutex_); void cleanup() LIBCAMERA_TSA_EXCLUDES(mutex_);
/* /*
@ -61,7 +64,7 @@ private:
std::unique_ptr<DeviceEnumerator> enumerator_; std::unique_ptr<DeviceEnumerator> enumerator_;
IPAManager ipaManager_; std::unique_ptr<IPAManager> ipaManager_;
ProcessManager processManager_; ProcessManager processManager_;
}; };

View file

@ -2,115 +2,130 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* camera_sensor.h - A camera sensor * A camera sensor
*/ */
#pragma once #pragma once
#include <memory> #include <memory>
#include <stdint.h>
#include <string> #include <string>
#include <variant>
#include <vector> #include <vector>
#include <libcamera/base/class.h> #include <libcamera/base/class.h>
#include <libcamera/base/log.h>
#include <libcamera/control_ids.h> #include <libcamera/control_ids.h>
#include <libcamera/controls.h> #include <libcamera/controls.h>
#include <libcamera/geometry.h> #include <libcamera/geometry.h>
#include <libcamera/orientation.h>
#include <libcamera/transform.h> #include <libcamera/transform.h>
#include <libcamera/ipa/core_ipa_interface.h> #include "libcamera/internal/bayer_format.h"
#include "libcamera/internal/camera_sensor_properties.h"
#include "libcamera/internal/formats.h"
#include "libcamera/internal/v4l2_subdevice.h" #include "libcamera/internal/v4l2_subdevice.h"
namespace libcamera { namespace libcamera {
class BayerFormat;
class CameraLens; class CameraLens;
class MediaEntity; class MediaEntity;
class SensorConfiguration;
struct CameraSensorProperties; enum class Orientation;
class CameraSensor : protected Loggable struct IPACameraSensorInfo;
class CameraSensor
{ {
public: public:
explicit CameraSensor(const MediaEntity *entity); virtual ~CameraSensor();
~CameraSensor();
int init(); virtual const std::string &model() const = 0;
virtual const std::string &id() const = 0;
const std::string &model() const { return model_; } virtual const MediaEntity *entity() const = 0;
const std::string &id() const { return id_; } virtual V4L2Subdevice *device() = 0;
const MediaEntity *entity() const { return entity_; }
const std::vector<unsigned int> &mbusCodes() const { return mbusCodes_; }
std::vector<Size> sizes(unsigned int mbusCode) const;
Size resolution() const;
const std::vector<controls::draft::TestPatternModeEnum> &testPatternModes() const
{
return testPatternModes_;
}
int setTestPatternMode(controls::draft::TestPatternModeEnum mode);
V4L2SubdeviceFormat getFormat(const std::vector<unsigned int> &mbusCodes, virtual CameraLens *focusLens() = 0;
const Size &size) const;
int setFormat(V4L2SubdeviceFormat *format,
Transform transform = Transform::Identity);
int tryFormat(V4L2SubdeviceFormat *format) const;
const ControlInfoMap &controls() const; virtual const std::vector<unsigned int> &mbusCodes() const = 0;
ControlList getControls(const std::vector<uint32_t> &ids); virtual std::vector<Size> sizes(unsigned int mbusCode) const = 0;
int setControls(ControlList *ctrls); virtual Size resolution() const = 0;
V4L2Subdevice *device() { return subdev_.get(); } 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;
const ControlList &properties() const { return properties_; } virtual int applyConfiguration(const SensorConfiguration &config,
int sensorInfo(IPACameraSensorInfo *info) const; Transform transform = Transform::Identity,
V4L2SubdeviceFormat *sensorFormat = nullptr) = 0;
void updateControlInfo(); virtual V4L2Subdevice::Stream imageStream() const;
virtual std::optional<V4L2Subdevice::Stream> embeddedDataStream() const;
virtual V4L2SubdeviceFormat embeddedDataFormat() const;
virtual int setEmbeddedDataEnabled(bool enable);
CameraLens *focusLens() { return focusLens_.get(); } 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;
Transform validateTransform(Transform *transform) const; virtual const ControlInfoMap &controls() const = 0;
virtual ControlList getControls(const std::vector<uint32_t> &ids) = 0;
virtual int setControls(ControlList *ctrls) = 0;
protected: virtual const std::vector<controls::draft::TestPatternModeEnum> &
std::string logPrefix() const override; testPatternModes() const = 0;
virtual int setTestPatternMode(controls::draft::TestPatternModeEnum mode) = 0;
private: virtual const CameraSensorProperties::SensorDelays &sensorDelays() = 0;
LIBCAMERA_DISABLE_COPY(CameraSensor)
int generateId();
int validateSensorDriver();
void initVimcDefaultProperties();
void initStaticProperties();
void initTestPatternModes();
int initProperties();
int applyTestPatternMode(controls::draft::TestPatternModeEnum mode);
int discoverAncillaryDevices();
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_;
ControlList properties_;
std::unique_ptr<CameraLens> focusLens_;
}; };
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 */ } /* namespace libcamera */

View file

@ -2,12 +2,13 @@
/* /*
* Copyright (C) 2021, Google Inc. * Copyright (C) 2021, Google Inc.
* *
* camera_sensor_properties.h - Database of camera sensor properties * Database of camera sensor properties
*/ */
#pragma once #pragma once
#include <map> #include <map>
#include <stdint.h>
#include <string> #include <string>
#include <libcamera/control_ids.h> #include <libcamera/control_ids.h>
@ -16,10 +17,18 @@
namespace libcamera { namespace libcamera {
struct CameraSensorProperties { struct CameraSensorProperties {
struct SensorDelays {
uint8_t exposureDelay;
uint8_t gainDelay;
uint8_t vblankDelay;
uint8_t hblankDelay;
};
static const CameraSensorProperties *get(const std::string &sensor); static const CameraSensorProperties *get(const std::string &sensor);
Size unitCellSize; Size unitCellSize;
std::map<controls::draft::TestPatternModeEnum, int32_t> testPatternModes; std::map<controls::draft::TestPatternModeEnum, int32_t> testPatternModes;
SensorDelays sensorDelays;
}; };
} /* namespace libcamera */ } /* 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

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* control_serializer.h - Control (de)serializer * Control (de)serializer
*/ */
#pragma once #pragma once

View file

@ -2,7 +2,7 @@
/* /*
* Copyright (C) 2019, Google Inc. * Copyright (C) 2019, Google Inc.
* *
* control_validator.h - Control validator * Control validator
*/ */
#pragma once #pragma once

View file

@ -3,7 +3,7 @@
* Copyright (C) 2020, Laurent Pinchart * Copyright (C) 2020, Laurent Pinchart
* Copyright 2022 NXP * Copyright 2022 NXP
* *
* converter.h - Generic format converter interface * Generic format converter interface
*/ */
#pragma once #pragma once
@ -14,9 +14,11 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <utility>
#include <vector> #include <vector>
#include <libcamera/base/class.h> #include <libcamera/base/class.h>
#include <libcamera/base/flags.h>
#include <libcamera/base/signal.h> #include <libcamera/base/signal.h>
#include <libcamera/geometry.h> #include <libcamera/geometry.h>
@ -26,12 +28,25 @@ namespace libcamera {
class FrameBuffer; class FrameBuffer;
class MediaDevice; class MediaDevice;
class PixelFormat; class PixelFormat;
class Stream;
struct StreamConfiguration; struct StreamConfiguration;
class Converter class Converter
{ {
public: 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 ~Converter();
virtual int loadConfiguration(const std::string &filename) = 0; virtual int loadConfiguration(const std::string &filename) = 0;
@ -41,25 +56,45 @@ public:
virtual std::vector<PixelFormat> formats(PixelFormat input) = 0; virtual std::vector<PixelFormat> formats(PixelFormat input) = 0;
virtual SizeRange sizes(const Size &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> virtual std::tuple<unsigned int, unsigned int>
strideAndFrameSize(const PixelFormat &pixelFormat, const Size &size) = 0; 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, virtual int configure(const StreamConfiguration &inputCfg,
const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs) = 0; 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; std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;
virtual int start() = 0; virtual int start() = 0;
virtual void stop() = 0; virtual void stop() = 0;
virtual int queueBuffers(FrameBuffer *input, 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 *> inputBufferReady;
Signal<FrameBuffer *> outputBufferReady; Signal<FrameBuffer *> outputBufferReady;
const std::string &deviceNode() const { return deviceNode_; } const std::string &deviceNode() const { return deviceNode_; }
Features features() const { return features_; }
protected:
Features features_;
private: private:
std::string deviceNode_; std::string deviceNode_;
}; };

View file

@ -3,7 +3,7 @@
* Copyright (C) 2020, Laurent Pinchart * Copyright (C) 2020, Laurent Pinchart
* Copyright 2022 NXP * Copyright 2022 NXP
* *
* converter_v4l2_m2m.h - V4l2 M2M Format converter interface * V4l2 M2M Format converter interface
*/ */
#pragma once #pragma once
@ -28,7 +28,9 @@ class FrameBuffer;
class MediaDevice; class MediaDevice;
class Size; class Size;
class SizeRange; class SizeRange;
class Stream;
struct StreamConfiguration; struct StreamConfiguration;
class Rectangle;
class V4L2M2MDevice; class V4L2M2MDevice;
class V4L2M2MConverter : public Converter class V4L2M2MConverter : public Converter
@ -36,31 +38,45 @@ class V4L2M2MConverter : public Converter
public: public:
V4L2M2MConverter(MediaDevice *media); V4L2M2MConverter(MediaDevice *media);
int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; } int loadConfiguration([[maybe_unused]] const std::string &filename) override { return 0; }
bool isValid() const { return m2m_ != nullptr; } bool isValid() const override { return m2m_ != nullptr; }
std::vector<PixelFormat> formats(PixelFormat input); std::vector<PixelFormat> formats(PixelFormat input) override;
SizeRange sizes(const Size &input); SizeRange sizes(const Size &input) override;
std::tuple<unsigned int, unsigned int> 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, int configure(const StreamConfiguration &inputCfg,
const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfg); const std::vector<std::reference_wrapper<StreamConfiguration>>
int exportBuffers(unsigned int ouput, unsigned int count, &outputCfg) override;
std::vector<std::unique_ptr<FrameBuffer>> *buffers); 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(); int start() override;
void stop(); void stop() override;
int validateOutput(StreamConfiguration *cfg, bool *adjusted,
Alignment align = Alignment::Down) override;
int queueBuffers(FrameBuffer *input, 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: private:
class Stream : protected Loggable class V4L2M2MStream : protected Loggable
{ {
public: public:
Stream(V4L2M2MConverter *converter, unsigned int index); V4L2M2MStream(V4L2M2MConverter *converter, const Stream *stream);
bool isValid() const { return m2m_ != nullptr; } bool isValid() const { return m2m_ != nullptr; }
@ -74,6 +90,11 @@ private:
int queueBuffers(FrameBuffer *input, FrameBuffer *output); 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: protected:
std::string logPrefix() const override; std::string logPrefix() const override;
@ -82,17 +103,23 @@ private:
void outputBufferReady(FrameBuffer *buffer); void outputBufferReady(FrameBuffer *buffer);
V4L2M2MConverter *converter_; V4L2M2MConverter *converter_;
unsigned int index_; const Stream *stream_;
std::unique_ptr<V4L2M2MDevice> m2m_; std::unique_ptr<V4L2M2MDevice> m2m_;
unsigned int inputBufferCount_; unsigned int inputBufferCount_;
unsigned int outputBufferCount_; 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::unique_ptr<V4L2M2MDevice> m2m_;
std::vector<Stream> streams_; std::map<const Stream *, std::unique_ptr<V4L2M2MStream>> streams_;
std::map<FrameBuffer *, unsigned int> queue_; std::map<FrameBuffer *, unsigned int> queue_;
std::pair<Rectangle, Rectangle> inputCropBounds_;
}; };
} /* namespace libcamera */ } /* 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 */

Some files were not shown because too many files have changed in this diff Show more