Commit graph

635 commits

Author SHA1 Message Date
Pauli Virtanen
c0e8b397f6 bluez5: avoid (harmless) integer overflow
If no packets have been received and spa_bt_decode_buffer_process is
called, this->packet_size.max == INT32_MIN, which can give overflows.

Guard against this condition, although it should be harmless.
2022-08-24 16:59:21 +00:00
Frédéric Danis
6b3390387d bluez5: Test transport pointer before using it
If this->transport is NULL the debug log will crash.
2022-08-18 12:57:04 +02:00
Pauli Virtanen
b9baeeb587 bluez5: opus: react faster to too long packet queue
React immediately to "bad" buffer level. Use smaller bitrate
increments/decrements.  Fix ABR timer increment for fragmented packets.
Handle actual bitrate being smaller than target during silence.
2022-08-13 15:58:08 +03:00
Pauli Virtanen
c1acb5168d bluez5: bump Opus max bitrates
Limit bitrates to 2-2.5x Opus recommended "good quality", instead of
1.5x, which is safer quality-wise for CVBR.
2022-08-13 15:12:35 +03:00
Pauli Virtanen
8f0478a2ce bluez5: sco-source: deal with incomplete CVSD frames
Rarely BT adapter may send CVSD packets with incomplete frames.  Ignore
such packets, as it's not clear if they contain valid data at all.
2022-08-05 13:12:24 +00:00
Frédéric Danis
e7f17e1523 bluez5: use lower case for UUIDs
BlueZ uses lower case version for the UUIDs in its DBus interface.
This will simplify future UUID tests.
2022-08-03 06:15:54 +00:00
Frédéric Danis
76adcfaabe bluez5: Add AAC decoder 2022-08-02 11:12:25 +02:00
Isa Mert Gurbuz
f32017c874 bluez5: Disable hw-volume for Soundcore Motion B 2022-08-01 19:34:39 +00:00
Pauli Virtanen
3579857a64 bluez5: opus: tweak ABR
Count retry from last non-good interval.  Minimum retry interval 5sec.
2022-08-01 19:23:07 +00:00
Pauli Virtanen
5724d405d6 bluez5: opus: better default bitrates
Use smaller bitrate caps, as it's not necessary to use all bandwidth
available.
2022-08-01 19:23:07 +00:00
Huang-Huang Bao
c5bce24f01
bluez5: correct type of arguments to a dbus function
The 3rd "value" arguments to dbus_message_iter_append_basic() should be the address of a basic-typed value.

Fixes #2591
2022-07-23 16:35:01 +08:00
Frédéric Danis
343ae88bbf bluez5: Simplify DBus append_basic_* helpers
String key is used in all calls to append_basic_variant_dict_entry() and
append_basic_array_variant_dict_entry().
2022-07-22 19:10:26 +00:00
Frédéric Danis
e560468800 bluez5: Removed unused variables in meson.build 2022-07-22 18:46:35 +02:00
Pauli Virtanen
67c41336db bluez5: fix minor issues / warnings
Make static analysis happier.
2022-07-21 07:12:22 +00:00
Pauli Virtanen
434cc6a90b bluez5: add Opus as a (Pipewire-specific) A2DP vendor codec
Support Opus as A2DP vendor codec.

The specification for vendor A2DP codec is our Pipewire-specific one, so
it is compatible only with devices running Pipewire.
2022-07-19 13:44:56 +00:00
Pauli Virtanen
bf52b2acff bluez5: add opus-a2dp-0.5 caps 2022-07-19 13:44:56 +00:00
Pauli Virtanen
b6d237fa43 bluez5: add OPUS-A2DP specification 2022-07-19 13:44:56 +00:00
Pauli Virtanen
0dc8255057 bluez5: handle sink vs. source correctly in get_supported_codecs
Make a distinction between sink and source endpoints when determining
supported codecs.
2022-07-19 13:44:56 +00:00
Pauli Virtanen
889d507e9c bluez5: enable logging for codecs
Add codec->set_log for setting the logging object for each codec.

Bump codec API.
2022-07-19 13:44:56 +00:00
Pauli Virtanen
d29aafd857 bluez5: enable A2DP duplex volume boost only if codec asks for it
Make A2DP volume boost conditional on a flag the codec sets.

Bump codec API version.
2022-07-19 13:44:56 +00:00
Pauli Virtanen
92b2b44954 bluez5: pass global setting dict to codec select_config / preference_cmp
The device is not know at SelectConfiguration time, so the settings
argument in select_config is currently unused. Pass on a global settings
dict instead, so that codec parameters can be configured.

Also add settings argument to caps_preference_cmp.

Bump codec API version.
2022-07-19 13:44:56 +00:00
Pauli Virtanen
a8eb146d39 bluez5: tell the codec whether endpoint is sink or source
Add a flag A2DP_CODEC_FLAG_SINK to incidate a sink endpoint.

Also enum_config and caps_preference_cmp may need to know whether the
codec is being configured for SRC or SNK. Also add the flags argument to
init_props.

Bump codec API version.
2022-07-19 13:44:56 +00:00
Pauli Virtanen
8d66b2b2f7 bluez5: a2dp-source: more duplex codec workarounds
a2dp-sink writing duplex data to the BT socket breaks a2dp-source source
polling, also in A2DP source role. Hence, use the timer-based polling
workaround always in duplex mode.
2022-07-19 13:44:56 +00:00
Pauli Virtanen
f593a44069 bluez5: a2dp-sink: support duplex codec
Allow running a2dp-sink using the duplex codec, when the local endpoint
is the A2DP sink.
2022-07-19 13:44:56 +00:00
Pauli Virtanen
d6a7db8020 bluez5: mark HFP/HSP streams with media.role=Communication 2022-07-12 14:04:31 +00:00
Pauli Virtanen
6e37110efd bluez5: adjust source rate control
Use different filter function than spa_dll for the rate control.
Also use a longer window for spike determination.
2022-07-12 13:55:54 +00:00
Pauli Virtanen
fe7c6bcef9 bluez5: volume changes from headset should be saved
User changing volume via headset buttons should be treated on the same
level as changing from desktop UI.  Also initial headset volume should
be considered saved (even though session managers currently ignore the
initial route values on route restore).

Mark route as saved on volume events.
2022-07-09 18:19:45 +00:00
Pauli Virtanen
77959a2c1c bluez5: get initial node volume from transport
When emitting node, get initial volumes from transport hardware volume,
if available.

The session manager usually overrides these immediately with saved
values, but it's better to show the HW volume when the node first
appears.
2022-07-09 18:19:45 +00:00
Pauli Virtanen
d82b3d6479 bluez5: backend-native: set HFP/HSP volume when connecting
The HFP/HSP HW volume on the device is not necessarily what we think it
is.

Sync the device volume to our value at connect time.
2022-07-09 18:19:45 +00:00
Pauli Virtanen
276c4bc554 bluez5: use separate routes for HFP and A2DP
The A2DP and HFP profiles may have different volume curves, so trying to
convert volumes between the two can produce undesirable volume spikes.
For example, when one of them is using hardware volume and the other
software.

Fix by separating HFP and A2DP routes.
2022-07-09 18:19:45 +00:00
Pauli Virtanen
783fbc507b bluez5: fix minor error handling/warning issues 2022-07-06 14:36:22 +00:00
Pauli Virtanen
e1cb7c6fb2 bluez5: sco-source: implement sco-source the same way as a2dp-source 2022-07-05 14:21:04 +00:00
Pauli Virtanen
51356ea3d0 bluez5: a2dp-source: separate clock from recv + handle buffering
a2dp-source as driver does not produce regularly spaced graph cycles,
because A2DP is not isochronous. This causes e.g. crackling for alsa
etc. that expect regular timings. It also does not rate match.

Change a2dp-source to trigger graph on regular intervals. Change recv to
only accumulate data to a buffer, and put data to buffers in process().

Rate match with DLL, keeping average buffer level constant.  Keep track
of jitter to determine a safe target value.
2022-07-05 14:21:04 +00:00
Pauli Virtanen
459a1114f1 bluez5: sco-io: we should always read from socket
Not reading from the socket appears to cause messages to pile up to some
limit, which causes problems if we start the source after some point.
2022-07-05 14:21:04 +00:00
Pauli Virtanen
02bdfcb115 bluez5: ad2p-sink: adjust debug log message
timeout -> timer, since "timeout" looks like error to users
2022-07-05 14:21:04 +00:00
Frédéric Danis
8bd1d4c7c9 bluez5: Fix LC3plus plugin build
LC3PLus plugin should not depend on LDAC C args to build
2022-06-10 18:16:49 +02:00
Pauli Virtanen
5b429607a8 bluez5: disable dummy avrcp player by default
It causes some headsets behave strangely. See pipewire#2391,
pipewire#1853.

The BlueZ issue of AVRCP volume sometimes missing that this worked
around was fixed in recent versions. The issue of some headsets not
sending volume without AVRCP player remains, but it appears this breaks
more headsets than fixes.
2022-06-07 18:13:06 +03:00
Pauli Virtanen
8898a6a8f0 bluez5: don't consider profiles the adapter doesn't have
Don't try to reconnect or wait for profiles, which cannot be connected
because the adapter doesn't have the counterpart sink/source profile.

E.g. we should not reconnect/wait for HFP HF on remote device, if
we don't have the corresponding HFP AG.
2022-06-05 18:15:42 +00:00
Pauli Virtanen
8383ee8552 bluez5: a2dp-sink: address A2DP transport acquire failure mode
If A2DP remote does not acquire its pending transport within a timeout,
we won't get a write error in a2dp-sink, but instead the transport
becomes idle.  Currently, we continue writing to the socket as if
everything was fine, even though the data won't be processed at the
remote end.

Handle this by stopping the node and emitting a node error event.
Pipewire may then restart the node to retry.
2022-06-05 18:10:01 +00:00
Pauli Virtanen
8949d45c69 bluez5: check decode/encode capability also at registering
Endpoints without decode/encode capability are skipped in the object
manager, but we should also skip them in the registration calls (even
though in practice this doesn't appear to matter).
2022-06-05 18:03:24 +00:00
Wim Taymans
a58d815024 bluez5: implement freewheel in sink
We need to skip all samples.
2022-05-30 09:54:22 +02:00
Wim Taymans
0cdcd04f77 bluez5: use position clock time
Use the position clock time and fall back to the monotonic time.
2022-05-30 09:53:37 +02:00
Pauli Virtanen
ebccd89ae1 bluez5: a2dp-sink: update follower current time
Update follower current time in process, since it is otherwise not
updated. Fixes bitpool control as follower.
2022-05-30 07:40:52 +00:00
Pauli Virtanen
ca18b8b733 bluez5: endpoint can be used only by one device at a time
AVDTP (v1.3 Sec 5.3) has a limitation that a local SEP (on the same
adapter) can be connected to at most one remote SEP. Trying to do have
it connected to multiple remotes either fails or causes misbehavior
later on.

Skip SetConfigure the same local endpoint for multiple remote ones in
codec switch. BlueZ observes this restriction in SelectConfiguration,
so also it won't try to do invalid configurations.

In BlueZ 5.64, the SetConfiguration calls succeed, but subsequent
transport acquires will fail. (Likely already the SetConfiguration DBus
call should fail.)

This all has the consequence, with the current approach to the
codec=endpoint correspondence, that if multiple devices are connected to
the same adapter, they currently have to use different codecs.
2022-05-30 07:35:54 +00:00
Fabrice Fontaine
85ca67b927 fix detection of reallocarray
Fix detection of reallocarray (e.g. on glibc) raised since commit
0708a39b43

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2022-05-30 09:33:27 +02:00
Barnabás Pőcze
f24250da66 spa: bluez: ignore unsupported indicators
Do not emit a warning when a known, but
otherwise unsupported indicator is received.

Fixes wireplumber#253
2022-05-10 12:09:18 +02:00
Pauli Virtanen
6ccb939267 bluez5: use lc3plus.h instead of lc3.h
The file name "lc3.h" in the ETSI LC3plus package may conflict with the
actual LC3 codec, so try to find a file "lc3plus.h" instead.  Also try
to find a pkg-config dependency for it first (in which case use lc3.h,
assuming it's in different directory).  This can be fine tuned, if
something starts to package that library.
2022-05-03 00:29:47 +03:00
Pauli Virtanen
7f67dedac6 bluez5: fix lc3plus initial bitrate 2022-05-02 23:14:45 +03:00
Pauli Virtanen
9e59a56894 bluez5: add LC3plus A2DP vendor codec
Implement codec plugin for the LC3plus codec, supporting the LC3plus
encoder/decoder from Fraunhofer.
2022-05-01 15:09:00 +03:00
Pauli Virtanen
d28394173a bluez5: add LC3plus A2DP vendor codec caps
From the specification
https://www.iis.fraunhofer.de/en/ff/amm/communication/lc3.html
2022-05-01 00:27:05 +03:00