Do transport release synchronously for simplicity. BlueZ handles
releasing while acquire is pending, but acquire while release is pending
would fail the acquire.
Otherwise we need to maintain an operation chain to handle trying to
acquire/release while the other operation is pending. This makes things
complex with little gained, as releases generally don't block for a long
time.
Drivers should only read the target_ values in the timeout, update the
timeout with the new duration and then update the position.
For the position we simply need to add the previous duration to the
position and then set the new duration + rate.
Otherwise, everything else should read the duration/rate and not use
the target_ values.
Make BAP nodes align the first sample of their packets at multiples of
the ISO interval, counted in the shared graph sample position. This
skips a few samples (< 10ms) at the start of playback to ensure the
alignment.
Since the sinks align their flush timing to the graph time, this also
results to them sending packets corresponding to the same graph time at
the same real time instants.
Due to packet queues in kernel/controller, the playback may still be off
by multiples of packets. Kernel changes are needed to address that part.
This works towards making BAP left and right channels to be
synchronized in TWS headsets, where the two earpieces currently appear
as different devices.
If transport goes into error state too often, fail instead of trying to
acquire it again.
This avoids getting into a tight acquire->fail->reacquire loop.
We need to acquire and release all transports in the same CIG at the
same time.
Due to current kernel ISO socket limitations, this cannot be done one by
one.
Now that sinks/sources can do transport acquire asynchronously, remove
the workaround that made it synchronous. Do release still synchronously
however.
Change A2DP/BAP transport acquire and release to be async.
Since BlueZ acquiring ISO sockets blocks until all sockets in same CIG
are acquired, BAP transports must be acquired asynchronously.
Allow asynchronous changes in transport state in the sinks/sources.
Also allow transport acquire to be actually synchronous, in this case it
must set transport state during acquire call.
Separate driver start/stop from transport start/stop.
Emit any remove node events before resetting initial profile. It
indicates to the session manager that nodes if any went away before
device disconnected.
Usually the profile is removed first which removes the nodes. This
depends on ordering of events from bluez, which apparently can be
different depending on how remote device disconnects.
Add some guards against doing processing when there has been an error or
the node is not started. Set error status to IO. Continue driving on IO
errors.
In media-sink, there's no need to set RCVBUF.
In media-source, we don't need to set NONBLOCK, as reads are done with
DONTWAIT. Don't set SNDBUF as it's not needed there. Don't set RCVBUF,
but use the (big) kernel default value: decode-buffer will handle any
overruns. Small values of RCVBUF might cause problems if kernel is
sending packets in a burst faster than we wake up.
On underflow in sources, pad with explicit silence. This avoids the
audioadapter from getting off sync from the cycle. That causes problems
as driver when we want to produce a buffer only a the start of the
cycle.
In some cases, it's also possible that the io already has buffer at the
start of the cycle when rate matching as driver. Currently, we don't
produce buffer in this case, but we should. Fix that by doing things in
the exact same way as ALSA sources do.
Delay output by one packet, so that we never need to wait for
node_process to supply more data when a packet is due out, and can write
audio packets at exactly equal intervals (up to timer/io accuracy).
In principle, this should not be necessary. However, enable it for now,
in case this improves the various stutter/etc. bug reports.
After flushing a packet, encode the next one immediately if we already
have the data. This makes the flush timing more accurate (std ~4x
smaller) as we don't need to wait for the encode.
The maximum receive buffer target of 6 packets may be too small when
there's huge jitter in reception. Increase it so that we may use all
buffer available if needed (2*quantum_limit = 370 ms @ 44100).
For SCO, explicitly set maximum buffer to 40 ms, so that latency cannot
grow too large there. For A2DP duplex, set it to 80 ms for same reason.
These are close to the old 6*packet limit.
For BAP server audio sink, set buffering target so that we try to match
the target presentation delay. Also adjust requested node latency to be
smaller than the delay.
Also fix BAP transport presentation delay value parsing, and parse also
the other BAP transport properties. Of these, transport latency value
needs to be taken into account in the total sink latency.
Codec switching does not currently work properly for source/duplex.
With BAP it's also possible only when we're BAP client.
When we can't codec switch, emit the "codecless" BAP profile.
BAP Clients do not have endpoints associated with them, and we only know
that codecs on currently configured transports are supported.
Handle this case in spa_bt_device_supports_media_codec
BlueZ fails registering object managers containing A2DP endpoints if
controller is in LE-only mode.
Make the A2DP and BAP object managers separate, so that failure to
register one does not prevent registering the other.
Also rename some functions to indicate which ones deal with the legacy
BlueZ API.
Strip initial \n from commands: some devices (Sennheiser HD 350BT) send
them.
Only reply OK to empty command with terminated command line;
non-terminated lines are invalid.
Add some debug in case the RFCOMM reply contains non-printable
characters.
The Bluetooth Low Energy MIDI code added a few legacy function declarations
that fail when building with -Werror=strict-prototypes. The fix is same as
before: add a void to the empty function argument list.
Signed-off-by: Niklāvs Koļesņikovs <89q1r14hd@relay.firefox.com>