Commit graph

4249 commits

Author SHA1 Message Date
Wim Taymans
0be61add02 Revert "spa: alsa: Try to get driver rate before setting up matching"
This reverts commit 019b53ace8.

This is a result of a different problem, that the rates are compared
when they are unset.
2025-07-15 14:52:31 +02:00
Demi Marie Obenour
b04da87e38 pod: check that choices are not empty
Before using the contents of a choice, check that it is not empty to
avoid reading out of bounds.
2025-07-15 10:13:18 +02:00
Demi Marie Obenour
fb315b9050 *: Missing bounds checks in POD handling
There were missing bounds checks for ill-formed POD all over the place.
2025-07-15 10:13:17 +02:00
Demi Marie Obenour
5bfc3e6b03 spa: v4l2: avoid integer wraparound to out of bounds read
I'm not sure if untrusted input can reach this point.
2025-07-15 10:13:17 +02:00
Barnabás Pőcze
2c2808fab1 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`.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
db3d91ebeb spa: libcamera: use nullptr instead of NULL 2025-07-15 08:12:54 +00:00
Barnabás Pőcze
4fa11619a2 spa: libcamera: use C++ style casts 2025-07-15 08:12:54 +00:00
Barnabás Pőcze
bb8223bff1 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.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
cb71071d93 spa: libcamera: device: remove empty line 2025-07-15 08:12:54 +00:00
Barnabás Pőcze
e19a8bb5cd 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()`.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
561a9d6ebb 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.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
0022fc90b7 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.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
f94f4de6ff spa: libcamera: source: simplify control mapping
Remove the `impl` parameter as it is not used, and use C++ range
based for loops.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
311b3cc37f 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.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
489cc49937 spa: libcamera: source: simplify format lookup
Use range based for loops instead of indices.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
0ea7dc9f19 spa: libcamera: source: use enum types
Use the appropriate enum types instead of bare `uint32_t`,
this provides better type safety in C++.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
f53ac8d57c spa: libcamera: source: handle camera acquire failure
Check the return value of `Camera::acquire()` and return the error
if that fails.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
1a1cf55efb 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).
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
5a9cdd724f spa: libcamera: clean up includes
Remove some unnecessarily includes.
2025-07-15 08:12:54 +00:00
Barnabás Pőcze
5f4f4b5dd3 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.
2025-07-15 08:12:54 +00:00
Pauli Virtanen
cee0c39b00 bluez5: fix decode-buffer buffering threshold
The minimum is the number of requested samples, not duration, which can
be different when resampling.
2025-07-12 19:59:33 +00:00
Pauli Virtanen
ff81fc9f7b bluez5: fix ISO sequence numbering
Pass zero-length packets to the codec. BAP/ISO may use these to indicate
missing data.

Fix A2DP codecs to not parse input with spa_return_val_if_fail, that's
meant for assertions. Just return -EINVAL directly, it's normal that
input data may contain garbage.
2025-07-12 19:59:33 +00:00
Pauli Virtanen
02d5d9bc1f bluez5: sco-io: remove unnecessary variable 2025-07-12 19:59:33 +00:00
Pauli Virtanen
87843366ce bluez5: add PLC for MSBC using spandsp
Use spandsp as optional dependency for MSBC codec, for providing PLC.
2025-07-12 19:59:33 +00:00
Pauli Virtanen
90a1b35017 bluez5: media-source: support codec-provided packet loss concealment
If packet sequence number jumps ahead, or we would underflow, use
codec-provided packet loss concealment to produce some audio data.

When we produce it during underflow, skip the corresponding number of
sequence numbers of future packets.

If codec doesn't have PLC, keep the previous behavior (pad with zeros,
buffering pauses to wait for data).
2025-07-12 19:59:33 +00:00
Pauli Virtanen
d0680a2b3d bluez5: support packet loss concealment in codecs
LC3 and Opus have built-in support for packet loss concealment.

Add codec interface for that, and implement for LC3.

Extend media_codec interface so that packets not aligned with socket
reads can be handled, as in HFP. This is required for correct sequence
number counting, and for being able to run codec PLC *before* decoding
the next correctly received packet.
2025-07-12 19:59:33 +00:00
Pauli Virtanen
a2ede93479 bluez5: report ISO latency correctly and refresh when transport starts 2025-07-12 19:57:22 +00:00
Pauli Virtanen
5e79d0fb01 bluez5: fix compilation and warnings 2025-07-12 19:57:22 +00:00
Pauli Virtanen
d10249d0ce bluez5: allow faster rate matching
Bump up DLL maximum rate difference and reduce averaging time.
2025-07-12 19:57:22 +00:00
Pauli Virtanen
2c70c13cc3 bluez5: rate match ISO only from process()
Update rate matching only once per process(). This ensures all nodes in
the group update their rate matching in the same way.

Also account for audio data in ISO output buffer in the reference time.
2025-07-12 19:57:22 +00:00
Pauli Virtanen
ad90a2d0ac bluez5: take clock rate difference into account in get_reference_time()
The calculations is in system clock domain, so when converting from
samples/duration to time rate difference should be accounted.

This does not have much effect in practice.
2025-07-12 19:57:22 +00:00
Pauli Virtanen
30047f232b bluez5: account for driver clock rate difference in rate matching
The rate matching calculations are done in the system clock domain.  If
the driver ticks at a different rate, the correction factor needs to be
adjusted by the rate_diff.

This fixes ISO streams getting out of sync with each other when target
delay changes. This happens because typically one of them is the driver
and the other follower. Driver adjust clock rate, and follower does its
own adjustment *on top of that* so it rate matches more or less at
double speed.  (The DLL of the follower to some degree corrects for
this, but can't do that when hitting RATE_CTL_DIFF_MAX and moreover it
acts with a delay.)
2025-07-12 19:57:22 +00:00
Pauli Virtanen
ddc023b883 bluez5: media-sink: make ISO target latency scale with quantum
The ISO target latency should scale with graph quantum, as jitter in the
graph processing time probably is proportional to the quantum.
2025-07-12 19:57:22 +00:00
Barnabás Pőcze
ca47d0ef15 spa: vulkan: map VK_INCOMPLETE to ENOSPC
`VK_INCOMPLETE` means "A return array was too small for the result",
so map it to `ENOSPC` since that describes it better than `EBUSY`.
2025-07-12 19:54:14 +00:00
Frédéric Danis
067e29543a bluez5: backend-native: Fix call held hangup
Currently it's not possible to hangup a call place on hold, and
request user to swap calls before been able to hangup.
2025-07-11 10:42:03 +02:00
Wim Taymans
74e576c31a filter-graph: don't pass NULL label around
lv2 does not have a label, make sure we pass "" around like befor
because code does not expect this to be NULL.
2025-07-10 18:10:51 +02:00
Pauli Virtanen
ae7a893ce9 bluez5: aac: fix for A2DP v1.4 using rfa bits for more channels
A2DP v1.4 uses the rfa bits for adding 5.1 and 7.1 configurations.
Clear those bits properly when sending configuration, in case remote
device sets them.
2025-07-10 14:12:15 +00:00
Robert Mader
7e202a3844 spa: libcamera: add colorimetry support
Libcamera equivalent to 41b831d0f ("spa: v4l2: add colorimetry support")
2025-07-10 14:11:41 +00:00
Demi Marie Obenour
b3bf5be1f6 *: Avoid macros that use casts where possible
Use direct field access when the type is known, instead of a macro that
includes a cast.

These were missed in e4fcbef89a.
2025-07-10 14:02:55 +00:00
Wim Taymans
b4f97c62c6 filter-graph: support more complicated labels
If we see a container as the label, copy the whole container and use
that as the label.

The label is used to construct a plugin description.
2025-07-10 13:47:29 +02:00
Arun Raghavan
eec1ac20b7 spa: aec: webrtc: Expose echo canceller mobile_mode
Significantly better CPU performance in lieu of canceller quality. Not
implemented for 0.x series, as there's a lot more to enable there (such
as routing modes), and I am hoping to drop support for those versions
before too long.
2025-07-09 13:02:18 -04:00
Arun Raghavan
477674740e spa: aec: webrtc: Drop outdated comment
The Intelligibility enhancer was removed, so the FIXMEs are irrelevant.
2025-07-09 12:48:24 -04:00
Arun Raghavan
a328e0ae28 spa: audioconvert: Avoid reading past filter-graph param name end
Ensure we have at least a `.` after `audioconvert.filter-graph`, so we
don't try to read past the end if it does not exist.

Also document in the param name that an index is expected.
2025-07-09 15:20:09 +00:00
Arun Raghavan
8f429ac04b spa: aec: webrtc: Actually enable echo cancellation for 2.0 2025-07-09 08:54:36 -04:00
Wim Taymans
0efd0258a7 filter-graph: rename the plugin files
Move the plugin prefix to the front like everywhere else and this also
makes it easier to spot the plugins when listing the directory.
2025-07-08 16:18:13 +02:00
Frédéric Danis
80d44e8f39 bluez5: backend-native: Fix incorrect dial number management
When dialing an incorrect phone number some phones (e.g. iOS 18.5)
replies with OK but never send +CIEV updates, so there's no way to
know that the dial is not in progress and the call object should be
removed.

This change waits for +CIEV event to create the call object.
2025-07-08 11:37:45 +00:00
Julien Massot
8aa836d588 alsa-pcm: add support for api.alsa.dll-bandwidth-max
In USB Audio Class 2 (UAC2) setups, pitch control is handled by
feedback endpoints. The host adjusts its data rate accordingly.

When pitch control is active (pitch_elem), applying the default
delay-locked loop (DLL) bandwidth can lead to instability and
oscillations around the target rate.

This patch adds a new parameter, api.alsa.dll-bandwidth-max, to
configure the maximum DLL bandwidth. It introduces a new field
in the ALSA state to store this value.

By default, it uses SPA_DLL_BW_MAX, but when pitch control is in
use, setting it to a lower value (e.g. 0.02) helps ensure better
stability, based on empirical testing.
2025-07-07 10:40:11 +00:00
Arun Raghavan
019b53ace8 spa: alsa: Try to get driver rate before setting up matching
In some cases, it is possible that the follower shares a clock with the
driver, but the driver rate is not known when the follower is assigned
to the driver. If this happens, then state->driver_rate is 0, and when
setting the format, we might think that we need to resample (because
follower rate != driver rate). This can cause us to incorrectly halve
the period size for the node.

This was introduced in commit 0b67c10a9c,
which forces reevaluation of matching status on driver change.

To avoid this, let us also probe for the driver rate when updating the
matching status, so we can make the update more accurate.
2025-07-03 19:02:02 +00:00
Wim Taymans
ef5d9ff028 filter-graph: add a simple noise gate 2025-07-03 20:58:00 +02:00
Arun Raghavan
70aaec0ac4 spa: v4l2: Drop unused variable
Fixes warning:

[186/359] Compiling C object spa/plugins/v4l2/libspa-v4l2.so.p/v4l2-source.c.o
In file included from ../spa/plugins/v4l2/v4l2-source.c:164:
../spa/plugins/v4l2/v4l2-utils.c: In function ‘spa_v4l2_enum_format’:
../spa/plugins/v4l2/v4l2-utils.c:1103:22: warning: unused variable ‘drop_next’ [-Wunused-variable]
 1103 |                 bool drop_next = false;
      |                      ^~~~~~~~~
2025-07-03 10:07:54 -04:00