[pulseaudio-discuss] Bluetooth - HSP / HFP - source based timing & hard-coded MTU causes SCO packets to be badly delayed

Attila Tőkés attitokes at gmail.com
Tue May 22 18:52:57 UTC 2018

Hi Georg,

Sorry for the late answer. Your message ended up in the spam folder

On Sun, May 20, 2018 at 9:33 PM, Georg Chini <georg at chini.tk> wrote:
> On 19.05.2018 22:34, Attila Tőkés wrote:
>> Hi,
>> Apparently, the source based timing logic (when using the
>> headset_head_unit profile there is a sink and a source) from:
>> https://github.com/pulseaudio/pulseaudio/blob/master/src/modules/bluetooth/module-bluez5-device.c#L1581
>> combined with the hard-coded MTU of 48 bytes / packet can cause SCO
>> packets to be badly delayed with some devices.
>> For example, the following happens with the CYW43438 chip used in the
>> Raspberry Pi 3:
>> PulseAudio (hard-coded) MTU - 48 bytes / packet
>> Real MTU - 64 bytes / packet
>> Packet Size negotiated at the eSCO connect - 60 bytes / packet
>> The CYW43438 uses the negotiated packet size of 60 bytes / packet, so it
>> sends bigger, 60 bytes SCO packets less often.
>> Based on the above logic from module-bluez5-device.c, PulseAudio sends SCO
>> packets (one at a time) only when SCO packet are received from CYW43438.
>> Because of the packet size of 60 bytes, these packets are sent less often
>> than PulseAudio would need to send its 48 byte packets.
>> The result is that the playback (paplay) is way to slow: 12.16 seconds,
>> instead of 9.72 seconds (+25%).
>> HCI (+SCO) log:
>> https://www.dropbox.com/s/yy7a1sltmzbsakk/bt-log-bcm.txt?dl=0
>> ---
>> Using autodetect_mtu=yes resolves the delay, but the problem does not
>> seems to be the MTU.
> What problem remains after setting autodetect_mtu=yes?

It works as workaround for the CYW43438, but breaks other controllers
and does not seems to be correct for eSCO.

When using eSCO the connection parameters, including the RX / TX
packet length, are negotiated with the Bluetooth device on the other
end (ex. head set). I think, we should use this packet length instead
of the MTU. For the above example the negotiated packet length is 60
bytes, while the MTU is 64 bytes.

This may be related to why the autodetect_mtu=yes does not works for
some devices.

>> ---
>> The issue, I think is the same as in:
>> [pulseaudio-discuss] [PATCH] Fix: Distorted audio during Bluetooth SCO
>> HFP/HSP playback
>> https://lists.freedesktop.org/archives/pulseaudio-discuss/2017-January/027448.html
>> ---
> The link you reference describes exactly the MTU issue. We had to revert
> setting
> autodetect_mtu=yes by default because there seem to be more head sets where
> it does not work with autodetect_mtu = yes than those which require it.
>> I tried to change module-bluez5-device.c to always use system clock based
>> timing (as for A2DP) and this seems to fix the problem.
>> What is the reason to use this source based timing, instead of using
>> system clock based timing as for A2DP ? It's just optimization? Or it is
>> some requirement of the Bluetooth spec? Using the system clock would be more
>> reliable, I think.cuss
> The SCO protocol requires that for each packet sent by the head set one has
> to be sent
> back from the system to the head set. So the timing is controlled by the
> head set and
> it is not guaranteed that this timing matches the system clock. Therefore
> you cannot
> use system clock and you would probably see a delay between recording and
> playback
> after some time. A2DP playback is different because the head set has no
> active part
> in the timing of events.

Can you please explain this in more details?

I'm just reading the Bluetooth specs and from what I understood so
far, SCO / eSCO logical transports uses reserved time slots to
transmit the data. The slots are reserved at connection time. The
master sends first, the slave sends immediately after the master after
which there is a delay (the eSCO window). But all this is done in the
Bluetooth controller.

On the host side, I think we need just to ensure that we feed the
Bluetooth controller with SCO packets in the right rate. For this the
current implementation based on the received SCO packets may work, but
for this requires the packets size to be precise. Also, it would be
worth checking how dropped/not-received SCO packets and asymmetric
(one-way) SCO connections are handled.

Attila Tőkés

More information about the pulseaudio-discuss mailing list