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`.
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.
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.
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).
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.
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).
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.
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.
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.
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.)
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.
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.
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.
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.
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.
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.
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;
| ^~~~~~~~~