Commit graph

13601 commits

Author SHA1 Message Date
Barnabás Pőcze
c3fec9769c spa: libcamera: manager: fix id allocation
There is an issue in the id allocation mechanism which can result
in the different devices having the same id. Specifically, consider
the scenario where there are only two cameras, which have just been
added. In this case `impl::devices` looks like this:

   (0, camA) | (1, camB) | (?, nullptr) | ...

Now assume that `camA` is removed, after which the array appears
as follows:

  (1, camB) | (1, nullptr) | (?, nullptr) | ...

Then assume that a new camera appears. When `get_free_id()` runs,
when `i == 1`, it will observe that `devices[i].camera == nullptr`,
so it selects `1` as the id. Leading to the following:

  (1, camB) | (1, camC) | (?, nullptr) | ...

This is of course incorrect. The set of ids must be unique. When
wireplumber is faced with this situation it destroys the device
object for `camB` when `camC` is emitted.

Fix this by simply not moving elements in the `devices` array,
leaving everything where it is. In which case the array looks
like this:

  (nullptr) | (camB) | (nullptr) | ... // after `camA` removal
  (camC) | (camB) | (nullptr) | ... // after `camC` appearance

Note that `device::id` is removed, and the id is now derived from
the position in `impl::devices`.

(cherry picked from commit 2c2808fab1)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
0749851cfe spa: libcamera: use nullptr instead of NULL
(cherry picked from commit db3d91ebeb)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
a5ba04a8ba spa: libcamera: use C++ style casts
(cherry picked from commit 4fa11619a2)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
ea67bf1662 spa: libcamera: use anon ns instead of static
Move most things into anonymous namespaces for internal linkage
instead of using `static`. This shortes declarations and makes it
hard to forget.

(cherry picked from commit bb8223bff1)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
843dfe48b0 spa: libcamera: device: remove empty line
(cherry picked from commit cb71071d93)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
c22d9127e1 spa: libcamera: source: inline mmap_init()
The function has a single caller is essentially just a wrapper only
calling `mmap_init()`. So inline it into `spa_libcamera_alloc_buffers()`.

(cherry picked from commit e19a8bb5cd)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
5f77c729c2 spa: libcamera: source: set "corrupted" flag if applicable
If the libcamera `FrameMetadata` reports anything other than `FrameSuccess`,
then set `SPA_META_HEADER_FLAG_CORRUPTED`, notifying the application that
the frame may be unusable.

(cherry picked from commit 561a9d6ebb)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
7414d948ad spa: libcamera: source: use union for transferring control value
Use a union since only one member is active at a time, and use the
proper `libcamera::ControlType` enum to store the type instead of a
bare number. Also remove an unnecessary cast.

(cherry picked from commit 0022fc90b7)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
8181e2e051 spa: libcamera: source: simplify control mapping
Remove the `impl` parameter as it is not used, and use C++ range
based for loops.

(cherry picked from commit f94f4de6ff)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
bf1c57928b spa: libcamera: source: do not make expensive queries multiple times
`StreamFormats::pixelformats()` and `StreamFormats::sizes()` both
return newly created `std::vector`s, so do not call them multiple
times.

(cherry picked from commit 311b3cc37f)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
bdf904ebad spa: libcamera: source: simplify format lookup
Use range based for loops instead of indices.

(cherry picked from commit 489cc49937)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
d1eb5f6d20 spa: libcamera: source: use enum types
Use the appropriate enum types instead of bare `uint32_t`,
this provides better type safety in C++.

(cherry picked from commit 0ea7dc9f19)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
3dd413e131 spa: libcamera: source: handle camera acquire failure
Check the return value of `Camera::acquire()` and return the error
if that fails.

(cherry picked from commit f53ac8d57c)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
a233905f75 spa: libcamera: inline libcamera-utils.cpp
The file is not useful without `libcamera-source.cpp` because it
uses symbols only defined there. And being a non-self-contained
source file, it also breaks clangd. So move its contents directly
to `libcamera-source.cpp`. This makes the file about 2200 lines long,
but I feel that is still manageable (and it is by far not the longest).

(cherry picked from commit 1a1cf55efb)
2025-09-26 09:58:10 +02:00
Barnabás Pőcze
60d95e447a spa: libcamera: clean up includes
Remove some unnecessarily includes.

(cherry picked from commit 5a9cdd724f)
2025-09-19 05:35:47 +02:00
Barnabás Pőcze
de97a682f2 spa: libcamera: use lock when acquiring CameraManager
Make `libcamera_manager_acquire()` thread safe by locking a mutex
when the `CameraManager` instance is created and started.

(cherry picked from commit 5f4f4b5dd3)
2025-09-19 05:35:39 +02:00
Robert Mader
74bd520224 spa: libcamera: add colorimetry support
Libcamera equivalent to 41b831d0f ("spa: v4l2: add colorimetry support")

(cherry picked from commit 7e202a3844)
2025-09-19 05:35:23 +02:00
David Turner
8094cdf846 libcamera: Default to auto-focus & auto-exposure
libcamera says that cameras should default to manual focus mode.  This
means that unless pipewire clients specifically change this control,
users with an autofocus-capable camera are left with an out-of-focus
image.  This patch sets the autofocus mode to continuous and enables
auto-exposure (as the default for this is unspecified).

Testing with an imx708 on Raspberry Pi OS on a Raspberry Pi 4, before
this patch the image was generally out of focus in Firefox/webrtc, after
this patch autofocus works correctly.

(cherry picked from commit 3a0ffe21e6)
2025-09-19 05:34:37 +02:00
Wim Taymans
8f35e18d18 systemd: remove RestrictNamespaces from service file
Wireplumber loads the libcamera nodes into the pipewire server.
We need to remove the RestrictNamespaces option from the service file
to allow libcamera to load sandboxed IPA modules.
2025-09-17 10:29:35 +02:00
Wim Taymans
5212649ee1 control: fix event compare function
We can only compare UMP when both types are 2 or 4, so it must be
different from 2 *and* 4 to be rejected.

Fixes #4899
2025-09-17 10:29:15 +02:00
Wim Taymans
24ab601201 impl-node: only do unprepare once
There is not reason to do the unprepare logic twice and it might
actually interfere with the actions of the client.

See #4840
Fixes #4893
2025-09-15 10:33:14 +02:00
Wim Taymans
3e574b314a Revert "impl-node: improve the node unprepare function"
This reverts commit 839383d0dd.
2025-09-15 10:32:56 +02:00
Wim Taymans
8b43ed5c91 1.4.8 2025-09-11 10:12:34 +02:00
Wim Taymans
67a541eac5 meta: add SPA_META_SYNC_TIMELINE_UNSCHEDULED_RELEASE
This flag is set by the producer and should be cleared by the consumer
when it promises to signal the release point.

When a consumer dequeues a buffer with the flag set, it should assume
the client is not going to signal the release point and so it should
reuse the buffer right away. This can only happen when the client
didn't dequeue the buffer at all (killed, timeout, error, ...) or when
it dequeued and queued the buffer without clearing the flag.

See #4885
2025-09-11 09:48:21 +02:00
Wim Taymans
839383d0dd impl-node: improve the node unprepare function
do_node_unprepare runs in both the server and the client when a node is
stopped. On the server size, set the status to FINISHED and trigger any
targets. This ensures the node will not be scheduled in this cycle
anymore. We have to do this because we can't know if the node is still
alive or not.

When the client receives the stop message, it will unprepare and set the
status to INACTIVE. This ensures the driver will no longer trigger the
node. If the server didn't already trigger the targets, do this in the
remote node then.

This avoid a race where both the client and the server are setting the
status and if the INACTIVE state is set by the server, it might stall
processing of the client.

Fixes #4840
2025-09-10 10:30:30 +02:00
Barnabás Pőcze
08dcd3a83a pipewire: mem: pw_memblock_map(): fix pointer when reusing mapping
Previously the pointer was determined as follows:

  mm->this.ptr = SPA_PTROFF(m->ptr, range.start, void);

however, when `pw_map_range` is calculated, `pw_map_range::start` is the offset
from the beginning of the first page, starting at `pw_map_range::offset`.

This works correctly if `memblock_map()` runs because that will map the file
with expected offset, so using `range.start` is correct.

However, when a mapping is reused (i.e. `memblock_find_mapping()`) finds something,
then `range.start` is not necessarily correct. Consider the following example:

  * page size is 10
  * one memblock with size 20 (2 pages)
  * the applications wants to mappings:
    * (offset=5,size=10)
    * (offset=15,size=5)

After the first request from the application, a `mapping` object is created
that covers the first two pages of the memblock: offset=0 and size=20. During
the second request, the calculated `pw_map_range` is as follows:

  { start = 5, offset = 10, size = 10 }

and the only previously created mapping is reused since (0 <= 5) and (10 <= 20). When
the pointer of the mapping is adjusted afterwards it will be incorrect since `m->ptr`
points to byte 0 on page 0 (instead of byte 0 on page 1 -- that is assumed). Thereforce
the two will unexpectedly overlap.

Fix that by using `offset - m->offset` when adjusting the mapping's pointer. Also move
the `range` variable into a smaller scope because it only makes sense there. And add
a test that check the above previously incorrect case.

Fixes: 2caf81c97c ("mem: improve memory handling")
Fixes #4884
2025-09-10 10:29:53 +02:00
Barnabás Pőcze
31151dbb97 pipewire: mem: log page size on creation 2025-09-10 10:29:46 +02:00
Barnabás Pőcze
7eceaf360e pipewire: mem: forward declare spa_hook
This type is used in function arguments, so forward declare it.
2025-09-10 10:29:34 +02:00
Barnabás Pőcze
f5da303c9f pipewire-v4l2: support choice sizes
Add support for `SPA_CHOICE_{None,Enum,Step,Range}`. They can all
be naturally mapped to `v4l2_frmsizeenum`.
2025-09-10 10:29:27 +02:00
Pauli Virtanen
16b3c8a6f6 audioconvert: add log topic for resampler 2025-09-10 10:28:57 +02:00
Pauli Virtanen
e8d739fdd7 alsa: report extra latency for FireWire drivers
Based on testing, ALSA FireWire drivers introduce additional latency
determined by the buffer size.

Report that latency.

Pass device.bus to the node, so it can recognize firewire.
2025-09-10 10:28:42 +02:00
Pauli Virtanen
3cb2c93c48 alsa: force IRQ scheduling for firewire in pro-audio profile
FireWire ALSA driver latency is determined by the buffer size and not the
period. Timer-based scheduling is then not really useful on these devices as
the latency is fixed.

In pro-audio profile, enable IRQ scheduling unconditionally for these
devices, so that controlling the latency works properly.

See #4785
2025-09-10 10:28:34 +02:00
Pauli Virtanen
8077dabd3a alsa: set minimum period count before automatic period size
Some devices (FireWire) fail to produce audio if period count is < 3,
and also have small buffer size. When quantum is too large, we might
then get too few periods and broken sound.

Set minimum for the period count in ALSA, to determine the maximum
period size we can use. If smaller than what we were going to use, round
down to power-of-2.

See #4785
2025-09-10 10:28:27 +02:00
Barnabás Pőcze
2735baa4ce treewide: map SPA_PROP_exposure to V4L2_CID_EXPOSURE_ABSOLUTE
Currently the v4l2 and libcamera plugins map `SPA_PROP_exposure` in incompatible
ways. So change the v4l2 mapping to `V4L2_CID_EXPOSURE_ABSOLUTE` because at least
that is in units of time (a step closer to addressing #4697), and because that
is more relevant for UVC cameras.

Also change the pipewire-v4l2 translation layer.
2025-09-10 10:28:08 +02:00
Wim Taymans
f0629fa8be spa: fix typo in raw-types for LLFE
Spotted by Nikolai

Fixes #4881
2025-09-10 10:21:10 +02:00
Wim Taymans
35dbea3c6c audiomixer: set change mask correctly 2025-09-10 10:20:34 +02:00
Wim Taymans
42eb28c0d2 audiomixer: format is Id 2025-09-10 10:20:18 +02:00
Wim Taymans
881d0e44d0 alsa: don't add MAX_LATENCY when using IRQ scheduling
The Max latency property only works for timer based scheduling so that
we don't select a quantum larger than we can handle in our buffer.

With IRQ based scheduling this does not make sense because we will
reconfigure the buffer completely when we change quantums and so the
currently selected buffer size does not limit the latency in any way.

Fixes #4877
2025-09-10 10:20:07 +02:00
Wim Taymans
ec1f3437e5 alsa: use 3 periods in IRQ mode by default
3 seems to work better as a default for Firewire. It does not actually
add latency because we only keep 1 period filled with data at all times.
2025-09-10 10:19:51 +02:00
Wim Taymans
6dbef07e72 filter: removed QUEUED flag and add DEQUEUED flag
Remove the QUEUED flags to check if a buffer is in some queue.

Add a new flag to check if a buffer was dequeued by the application.
Check if the application only queues buffers with the DEQUEUED flag set.
2025-09-10 10:19:35 +02:00
Wim Taymans
d48c012715 stream: remove QUEUED buffer flag
The flag was used to see if a buffer was in a queue or not but that
doesn't really matter much and with the DEQUEUED flag we can only move
buffers from dequeued to queued.
2025-09-10 10:19:29 +02:00
Jonas Ådahl
4ec9994bf0 pipewire/stream: Don't queue back cleared buffers
When renegotiating stream parameters (e.g. size), the buffers
are cleared should no longer be queued back. Add a flag to detect this,
while logging a warning and erroring out when the user tries to queue
such a buffer.
2025-09-10 10:19:20 +02:00
Wim Taymans
124aa40f64 alsa: use 2 (or 3 for batch) periods in IRQ mode
Some drivers (Firewire) have a latency depending on the ALSA buffer size
instead of the period size.

In IRQ mode, we can safely use 2 (or 3 for batch devices) periods
because we always need to reconfigure the hardware when we want to
change the period and so we don't need to keep some headroom like we do
for timer based scheduling.

See #4785
2025-09-10 10:18:55 +02:00
Wim Taymans
fabfdb1b01 v4l2: delay pipewire init until first openat call
Initialization of PipeWire could happen too early and deadlock in some
cases. Instead, initialize pipewire right before we're going to actually
use it for the first time.

Fixes #4859
2025-09-10 10:18:27 +02:00
Wim Taymans
0da4afca76 audiommixer: only clear mix_ops when initialized
It's possible that the mix_ops was not initialized and then the free
pointer is NULL, so check this instead of segfaulting.
2025-09-10 10:17:29 +02:00
Robert Mader
52852f66cb systemd: Allow mincore syscal for Mesa/EGL
This is required in order to allow plugins to use GL as mincore
is used in Mesas `_eglPointerIsDereferenceable()`.

One example for a client wanting to do so is the in-development
libcamera GPUISP, see https://patchwork.libcamera.org/cover/24183/
2025-09-10 10:16:24 +02:00
Wim Taymans
1efd76455f ump: make sure we set the group correctly 2025-09-10 10:15:44 +02:00
Wim Taymans
6a44b2e10f raop: write ALAC end tag
Fixes #4853
2025-09-10 10:14:57 +02:00
alexdlm
ee0809ead9 Map Razer BlackShark v3 ACP 2025-09-10 10:12:37 +02:00
Wim Taymans
f0cfe9449d tools: dump sndfile loginfo on error when verbose 2025-09-10 10:12:00 +02:00