[v9,0/8] Bluetooth A2DP codecs

Submitted by Luiz Augusto von Dentz on April 25, 2019, 4:43 p.m.

Details

Message ID CABBYNZJft8X1Y5EraQrCqmPVoj5WtVkyc88m=3nNWvnu8CnhCw@mail.gmail.com
State Not Applicable
Headers show
Series "New API for Bluetooth A2DP codecs" ( rev: 60 ) in PulseAudio

Not browsing as part of any series.

Commit Message

Luiz Augusto von Dentz April 25, 2019, 4:43 p.m.
Hi Pali,

On Thu, Apr 25, 2019 at 2:42 PM Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
>
> Hi Pali,
>
> On Thu, Apr 25, 2019 at 2:35 PM Pali Rohár <pali.rohar@gmail.com> wrote:
> >
> > On Thursday 25 April 2019 13:28:16 Pali Rohár wrote:
> > > On Thursday 25 April 2019 14:19:15 Luiz Augusto von Dentz wrote:
> > > > These seems to work great, I can even switch on the fly the profiles
> > > > and after a short delay it switches without a problem, there is one
> > > > issue related to reconnecting though:
> > > >
> > > > https://gist.github.com/Vudentz/40f10e85fb860083958edae67093f016
> > > >
> > > > With BlueZ remembering the last used endpoint (aptX) it seems the
> > > > policy ignores that and reverts to highest priority (SBC UHQ),
> >
> > Relevant lines:
> >
> > D: [lt-pulseaudio] bluez5-util.c: Transport /org/bluez/hci0/dev_94_20_53_2E_08_CE/sep5/fd26 available for profile a2dp_sink_aptx
> > ...
> > D: [lt-pulseaudio] card.c: a2dp_sink_aptx availability unknown
> > ...
> > D: [lt-pulseaudio] card.c: off availability yes
> > I: [lt-pulseaudio] card.c: bluez_card.94_20_53_2E_08_CE: active_profile: a2dp_sink_sbc_uhq2
> > D: [lt-pulseaudio] module-bluetooth-policy.c: Looking for A2DP profile activated by bluez for card bluez_card.94_20_53_2E_08_CE
> > I: [lt-pulseaudio] card.c: Created 5 "bluez_card.94_20_53_2E_08_CE"
> >
> > We got information that sep5 is activated with fd26 and it corespondent
> > to profile a2dp_sink_aptx. And on next lines we see that profile has
> > unknown availability -- which means that it is possible to switch to
> > that codec/profile, but it is not activated yet. On next lines we see
> > that module-bluetooth-policy is trying to find "a2dp_*" which has
> > availability "on", but there is no one. So initial profile stay
> > a2dp_sink_sbc_uhq2 which was chosen as default by card.c.
> >
> > So problem is why a2dp_sink_aptx profile has unknown availability even
> > it is activated? It should have "on" availability. And then policy
> > choose it as initial.
>
> Right, looks like the state is not correct since it has a fd already
> it should have been marked available.

Problem seems to be that we need to set the transport state to playing
since we introduce the following code:

    if (cp->available == PA_AVAILABLE_NO &&
u->support_a2dp_codec_switch && pa_bluetooth_profile_is_a2dp(profile))
        cp->available = PA_AVAILABLE_UNKNOWN;

That means every A2DP profile will be set to unknown including even if
they have no transport yet, so now we have to set the initial
transport to playing which hopefully it is just a matter doing the
following changes (not tested):

pa_bluetooth_profile_to_string(t->profile));

Patch hide | download patch | download mbox

diff --git a/src/modules/bluetooth/bluez5-util.c
b/src/modules/bluetooth/bluez5-util.c
index 4e4ab0cb8..429914328 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -1837,6 +1837,7 @@  static DBusMessage
*endpoint_set_configuration(DBusConnection *conn, DBusMessage
     t->acquire = bluez5_transport_acquire_cb;
     t->release = bluez5_transport_release_cb;
     pa_bluetooth_transport_put(t);
+    pa_bluetooth_transport_set_state(t, PA_BLUETOOTH_TRANSPORT_STATE_PLAYING);

     pa_log_debug("Transport %s available for profile %s", t->path,

Comments




Hi Pali,

On Thu, Apr 25, 2019 at 8:03 PM Pali Rohár <pali.rohar@gmail.com> wrote:
>
> On Thursday 25 April 2019 18:54:05 Pali Rohár wrote:
> > On Thursday 25 April 2019 18:51:49 Pali Rohár wrote:
> > > On Thursday 25 April 2019 19:43:28 Luiz Augusto von Dentz wrote:
> > > > Hi Pali,
> > > >
> > > > On Thu, Apr 25, 2019 at 2:42 PM Luiz Augusto von Dentz
> > > > <luiz.dentz@gmail.com> wrote:
> > > > >
> > > > > Hi Pali,
> > > > >
> > > > > On Thu, Apr 25, 2019 at 2:35 PM Pali Rohár <pali.rohar@gmail.com> wrote:
> > > > > >
> > > > > > On Thursday 25 April 2019 13:28:16 Pali Rohár wrote:
> > > > > > > On Thursday 25 April 2019 14:19:15 Luiz Augusto von Dentz wrote:
> > > > > > > > These seems to work great, I can even switch on the fly the profiles
> > > > > > > > and after a short delay it switches without a problem, there is one
> > > > > > > > issue related to reconnecting though:
> > > > > > > >
> > > > > > > > https://gist.github.com/Vudentz/40f10e85fb860083958edae67093f016
> > > > > > > >
> > > > > > > > With BlueZ remembering the last used endpoint (aptX) it seems the
> > > > > > > > policy ignores that and reverts to highest priority (SBC UHQ),
> > > > > >
> > > > > > Relevant lines:
> > > > > >
> > > > > > D: [lt-pulseaudio] bluez5-util.c: Transport /org/bluez/hci0/dev_94_20_53_2E_08_CE/sep5/fd26 available for profile a2dp_sink_aptx
> > > > > > ...
> > > > > > D: [lt-pulseaudio] card.c: a2dp_sink_aptx availability unknown
> > > > > > ...
> > > > > > D: [lt-pulseaudio] card.c: off availability yes
> > > > > > I: [lt-pulseaudio] card.c: bluez_card.94_20_53_2E_08_CE: active_profile: a2dp_sink_sbc_uhq2
> > > > > > D: [lt-pulseaudio] module-bluetooth-policy.c: Looking for A2DP profile activated by bluez for card bluez_card.94_20_53_2E_08_CE
> > > > > > I: [lt-pulseaudio] card.c: Created 5 "bluez_card.94_20_53_2E_08_CE"
> > > > > >
> > > > > > We got information that sep5 is activated with fd26 and it corespondent
> > > > > > to profile a2dp_sink_aptx. And on next lines we see that profile has
> > > > > > unknown availability -- which means that it is possible to switch to
> > > > > > that codec/profile, but it is not activated yet. On next lines we see
> > > > > > that module-bluetooth-policy is trying to find "a2dp_*" which has
> > > > > > availability "on", but there is no one. So initial profile stay
> > > > > > a2dp_sink_sbc_uhq2 which was chosen as default by card.c.
> > > > > >
> > > > > > So problem is why a2dp_sink_aptx profile has unknown availability even
> > > > > > it is activated? It should have "on" availability. And then policy
> > > > > > choose it as initial.
> > > > >
> > > > > Right, looks like the state is not correct since it has a fd already
> > > > > it should have been marked available.
> > > >
> > > > Problem seems to be that we need to set the transport state to playing
> > > > since we introduce the following code:
> > > >
> > > >     if (cp->available == PA_AVAILABLE_NO &&
> > > > u->support_a2dp_codec_switch && pa_bluetooth_profile_is_a2dp(profile))
> > > >         cp->available = PA_AVAILABLE_UNKNOWN;
> > > >
> > > > That means every A2DP profile will be set to unknown including even if
> > > > they have no transport yet
> > >
> > > That is truth. But if there is a transport then availability is YES.
> > >
> > > Availability NO is used when it is not possible to activate transport
> > > because it is unsupported (e.g. A2DP not connected or when bluez does
> > > not support profile switching).
> > >
> > > > so now we have to set the initial transport to playing
> > >
> > > How it should help? I do not see reason now...
> > >
> > > Anyway, I was not able to reproduce your problem, basically I always had
> > > availability for activated profile set to YES.
> >
> > Now I see it. PA_AVAILABLE_YES is returned only for
> > PA_BLUETOOTH_TRANSPORT_STATE_PLAYING.
> >
> > So for PA_BLUETOOTH_TRANSPORT_STATE_IDLE we also get
> > PA_AVAILABLE_UNKNOWN and therefore module-bluetooth-policy does not know
> > which transport is activated.
> >
> > Cannot we get transport state in module-bluetooth-policy? Seems that
> > this is the right direction.
>
> Currently we have following mapping:
>
> PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED --> PA_AVAILABLE_NO
> PA_BLUETOOTH_TRANSPORT_STATE_PLAYING --> PA_AVAILABLE_YES
> PA_BLUETOOTH_TRANSPORT_STATE_IDLE --> PA_AVAILABLE_UNKNOWN
>
> Plus PA_AVAILABLE_NO is changed to PA_AVAILABLE_UNKNOWN when pulseaudio
> can activate that transport via bluez codec switch API as described
> above.
>
> PA_PORT_AVAILABLE_YES is defined as:
> This port is available, likely because the jack is plugged in.
>
> PA_PORT_AVAILABLE_NO as:
> This port is not available, likely because the jack is not plugged in.
>
> And PA_PORT_AVAILABLE_UNKNOWN as:
> This port does not support jack detection
>
> Seems that PA code and applications skips profiles with PA_AVAILABLE_NO
> and do not allow to use it. So above change to PA_AVAILABLE_UNKNOWN
> seems like a good idea.
>
> But why idle/suspended transports have PA_AVAILABLE_UNKNOWN? Should not
> it be PA_AVAILABLE_YES? Because transport is activated and can be used.
> It is known that connection is working.

That has different meaning in HFP, for A2DP when we got a transport it
really means that it can be connected so I guess setting it to playing
state is the correct thing to do.

> > > > which hopefully it is just a matter doing the
> > > > following changes (not tested):
> > > >
> > > > diff --git a/src/modules/bluetooth/bluez5-util.c
> > > > b/src/modules/bluetooth/bluez5-util.c
> > > > index 4e4ab0cb8..429914328 100644
> > > > --- a/src/modules/bluetooth/bluez5-util.c
> > > > +++ b/src/modules/bluetooth/bluez5-util.c
> > > > @@ -1837,6 +1837,7 @@ static DBusMessage
> > > > *endpoint_set_configuration(DBusConnection *conn, DBusMessage
> > > >      t->acquire = bluez5_transport_acquire_cb;
> > > >      t->release = bluez5_transport_release_cb;
> > > >      pa_bluetooth_transport_put(t);
> > > > +    pa_bluetooth_transport_set_state(t, PA_BLUETOOTH_TRANSPORT_STATE_PLAYING);
> > > >
> > > >      pa_log_debug("Transport %s available for profile %s", t->path,
> > > > pa_bluetooth_profile_to_string(t->profile));

I testes this change it seems to work properly, though I have an
assert when I use a different headset which does support apt-X HD:

https://gist.github.com/Vudentz/0d6b6f2ad08524db69a3e223e26bc80d
On Friday 26 April 2019 11:20:26 Luiz Augusto von Dentz wrote:
> I have an assert when I use a different headset which does support apt-X HD:
> 
> https://gist.github.com/Vudentz/0d6b6f2ad08524db69a3e223e26bc80d

I have not tested aptX HD, nor aptX Low Latency. I tested only (classic)
aptX. I looked at code and there is incorrect calculation of buffer
block size for aptX HD. Try following:

static void get_buffer_size_hd(void *codec_info, size_t link_mtu, size_t *decoded_buffer_size, size_t *encoded_buffer_size) {
    /* aptX HD compression ratio is 4:1 and we need to process one aptX HD sample (6 bytes) at once */
    *encoded_buffer_size = (link_mtu/6) * 6;
    *decoded_buffer_size = *encoded_buffer_size * 4;
}
On Thu, 2019-04-25 at 18:54 +0200, Pali Rohár wrote:
> On Thursday 25 April 2019 18:51:49 Pali Rohár wrote:
> > On Thursday 25 April 2019 19:43:28 Luiz Augusto von Dentz wrote:
> > > Hi Pali,
> > > 
> > > On Thu, Apr 25, 2019 at 2:42 PM Luiz Augusto von Dentz
> > > <luiz.dentz@gmail.com> wrote:
> > > > Hi Pali,
> > > > 
> > > > On Thu, Apr 25, 2019 at 2:35 PM Pali Rohár <pali.rohar@gmail.com> wrote:
> > > > > On Thursday 25 April 2019 13:28:16 Pali Rohár wrote:
> > > > > > On Thursday 25 April 2019 14:19:15 Luiz Augusto von Dentz wrote:
> > > > > > > These seems to work great, I can even switch on the fly the profiles
> > > > > > > and after a short delay it switches without a problem, there is one
> > > > > > > issue related to reconnecting though:
> > > > > > > 
> > > > > > > https://gist.github.com/Vudentz/40f10e85fb860083958edae67093f016
> > > > > > > 
> > > > > > > With BlueZ remembering the last used endpoint (aptX) it seems the
> > > > > > > policy ignores that and reverts to highest priority (SBC UHQ),
> > > > > 
> > > > > Relevant lines:
> > > > > 
> > > > > D: [lt-pulseaudio] bluez5-util.c: Transport /org/bluez/hci0/dev_94_20_53_2E_08_CE/sep5/fd26 available for profile a2dp_sink_aptx
> > > > > ...
> > > > > D: [lt-pulseaudio] card.c: a2dp_sink_aptx availability unknown
> > > > > ...
> > > > > D: [lt-pulseaudio] card.c: off availability yes
> > > > > I: [lt-pulseaudio] card.c: bluez_card.94_20_53_2E_08_CE: active_profile: a2dp_sink_sbc_uhq2
> > > > > D: [lt-pulseaudio] module-bluetooth-policy.c: Looking for A2DP profile activated by bluez for card bluez_card.94_20_53_2E_08_CE
> > > > > I: [lt-pulseaudio] card.c: Created 5 "bluez_card.94_20_53_2E_08_CE"
> > > > > 
> > > > > We got information that sep5 is activated with fd26 and it corespondent
> > > > > to profile a2dp_sink_aptx. And on next lines we see that profile has
> > > > > unknown availability -- which means that it is possible to switch to
> > > > > that codec/profile, but it is not activated yet. On next lines we see
> > > > > that module-bluetooth-policy is trying to find "a2dp_*" which has
> > > > > availability "on", but there is no one. So initial profile stay
> > > > > a2dp_sink_sbc_uhq2 which was chosen as default by card.c.
> > > > > 
> > > > > So problem is why a2dp_sink_aptx profile has unknown availability even
> > > > > it is activated? It should have "on" availability. And then policy
> > > > > choose it as initial.
> > > > 
> > > > Right, looks like the state is not correct since it has a fd already
> > > > it should have been marked available.
> > > 
> > > Problem seems to be that we need to set the transport state to playing
> > > since we introduce the following code:
> > > 
> > >     if (cp->available == PA_AVAILABLE_NO &&
> > > u->support_a2dp_codec_switch && pa_bluetooth_profile_is_a2dp(profile))
> > >         cp->available = PA_AVAILABLE_UNKNOWN;
> > > 
> > > That means every A2DP profile will be set to unknown including even if
> > > they have no transport yet
> > 
> > That is truth. But if there is a transport then availability is YES.
> > 
> > Availability NO is used when it is not possible to activate transport
> > because it is unsupported (e.g. A2DP not connected or when bluez does
> > not support profile switching).
> > 
> > > so now we have to set the initial transport to playing
> > 
> > How it should help? I do not see reason now...
> > 
> > Anyway, I was not able to reproduce your problem, basically I always had
> > availability for activated profile set to YES.
> 
> Now I see it. PA_AVAILABLE_YES is returned only for
> PA_BLUETOOTH_TRANSPORT_STATE_PLAYING.
> 
> So for PA_BLUETOOTH_TRANSPORT_STATE_IDLE we also get
> PA_AVAILABLE_UNKNOWN and therefore module-bluetooth-policy does not know
> which transport is activated.
> 
> Cannot we get transport state in module-bluetooth-policy? Seems that
> this is the right direction.

Yes, I think module-bluetooth-policy should look at the transport
states directly, if that provides better information than the profile
availability.
On Thu, 2019-04-25 at 19:03 +0200, Pali Rohár wrote:
> On Thursday 25 April 2019 18:54:05 Pali Rohár wrote:
> > On Thursday 25 April 2019 18:51:49 Pali Rohár wrote:
> > > On Thursday 25 April 2019 19:43:28 Luiz Augusto von Dentz wrote:
> > > > Hi Pali,
> > > > 
> > > > On Thu, Apr 25, 2019 at 2:42 PM Luiz Augusto von Dentz
> > > > <luiz.dentz@gmail.com> wrote:
> > > > > Hi Pali,
> > > > > 
> > > > > On Thu, Apr 25, 2019 at 2:35 PM Pali Rohár <pali.rohar@gmail.com> wrote:
> > > > > > On Thursday 25 April 2019 13:28:16 Pali Rohár wrote:
> > > > > > > On Thursday 25 April 2019 14:19:15 Luiz Augusto von Dentz wrote:
> > > > > > > > These seems to work great, I can even switch on the fly the profiles
> > > > > > > > and after a short delay it switches without a problem, there is one
> > > > > > > > issue related to reconnecting though:
> > > > > > > > 
> > > > > > > > https://gist.github.com/Vudentz/40f10e85fb860083958edae67093f016
> > > > > > > > 
> > > > > > > > With BlueZ remembering the last used endpoint (aptX) it seems the
> > > > > > > > policy ignores that and reverts to highest priority (SBC UHQ),
> > > > > > 
> > > > > > Relevant lines:
> > > > > > 
> > > > > > D: [lt-pulseaudio] bluez5-util.c: Transport /org/bluez/hci0/dev_94_20_53_2E_08_CE/sep5/fd26 available for profile a2dp_sink_aptx
> > > > > > ...
> > > > > > D: [lt-pulseaudio] card.c: a2dp_sink_aptx availability unknown
> > > > > > ...
> > > > > > D: [lt-pulseaudio] card.c: off availability yes
> > > > > > I: [lt-pulseaudio] card.c: bluez_card.94_20_53_2E_08_CE: active_profile: a2dp_sink_sbc_uhq2
> > > > > > D: [lt-pulseaudio] module-bluetooth-policy.c: Looking for A2DP profile activated by bluez for card bluez_card.94_20_53_2E_08_CE
> > > > > > I: [lt-pulseaudio] card.c: Created 5 "bluez_card.94_20_53_2E_08_CE"
> > > > > > 
> > > > > > We got information that sep5 is activated with fd26 and it corespondent
> > > > > > to profile a2dp_sink_aptx. And on next lines we see that profile has
> > > > > > unknown availability -- which means that it is possible to switch to
> > > > > > that codec/profile, but it is not activated yet. On next lines we see
> > > > > > that module-bluetooth-policy is trying to find "a2dp_*" which has
> > > > > > availability "on", but there is no one. So initial profile stay
> > > > > > a2dp_sink_sbc_uhq2 which was chosen as default by card.c.
> > > > > > 
> > > > > > So problem is why a2dp_sink_aptx profile has unknown availability even
> > > > > > it is activated? It should have "on" availability. And then policy
> > > > > > choose it as initial.
> > > > > 
> > > > > Right, looks like the state is not correct since it has a fd already
> > > > > it should have been marked available.
> > > > 
> > > > Problem seems to be that we need to set the transport state to playing
> > > > since we introduce the following code:
> > > > 
> > > >     if (cp->available == PA_AVAILABLE_NO &&
> > > > u->support_a2dp_codec_switch && pa_bluetooth_profile_is_a2dp(profile))
> > > >         cp->available = PA_AVAILABLE_UNKNOWN;
> > > > 
> > > > That means every A2DP profile will be set to unknown including even if
> > > > they have no transport yet
> > > 
> > > That is truth. But if there is a transport then availability is YES.
> > > 
> > > Availability NO is used when it is not possible to activate transport
> > > because it is unsupported (e.g. A2DP not connected or when bluez does
> > > not support profile switching).
> > > 
> > > > so now we have to set the initial transport to playing
> > > 
> > > How it should help? I do not see reason now...
> > > 
> > > Anyway, I was not able to reproduce your problem, basically I always had
> > > availability for activated profile set to YES.
> > 
> > Now I see it. PA_AVAILABLE_YES is returned only for
> > PA_BLUETOOTH_TRANSPORT_STATE_PLAYING.
> > 
> > So for PA_BLUETOOTH_TRANSPORT_STATE_IDLE we also get
> > PA_AVAILABLE_UNKNOWN and therefore module-bluetooth-policy does not know
> > which transport is activated.
> > 
> > Cannot we get transport state in module-bluetooth-policy? Seems that
> > this is the right direction.
> 
> Currently we have following mapping:
> 
> PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED --> PA_AVAILABLE_NO
> PA_BLUETOOTH_TRANSPORT_STATE_PLAYING --> PA_AVAILABLE_YES
> PA_BLUETOOTH_TRANSPORT_STATE_IDLE --> PA_AVAILABLE_UNKNOWN
> 
> Plus PA_AVAILABLE_NO is changed to PA_AVAILABLE_UNKNOWN when pulseaudio
> can activate that transport via bluez codec switch API as described
> above.
> 
> PA_PORT_AVAILABLE_YES is defined as:
> This port is available, likely because the jack is plugged in.
> 
> PA_PORT_AVAILABLE_NO as:
> This port is not available, likely because the jack is not plugged in.
> 
> And PA_PORT_AVAILABLE_UNKNOWN as:
> This port does not support jack detection
> 
> Seems that PA code and applications skips profiles with PA_AVAILABLE_NO
> and do not allow to use it. So above change to PA_AVAILABLE_UNKNOWN
> seems like a good idea.
> 
> But why idle/suspended transports have PA_AVAILABLE_UNKNOWN? Should not
> it be PA_AVAILABLE_YES? Because transport is activated and can be used.
> It is known that connection is working.

If I recall correctly, that's because opening the audio link may fail
even if the profile is connected. I think a device can have connections
established with multiple other devices simultaneously, but it might
not be able to stream audio with more than one device at a time.
Hi Pali,

On Fri, Apr 26, 2019 at 11:34 AM Pali Rohár <pali.rohar@gmail.com> wrote:
>
> On Friday 26 April 2019 11:20:26 Luiz Augusto von Dentz wrote:
> > I have an assert when I use a different headset which does support apt-X HD:
> >
> > https://gist.github.com/Vudentz/0d6b6f2ad08524db69a3e223e26bc80d
>
> I have not tested aptX HD, nor aptX Low Latency. I tested only (classic)
> aptX. I looked at code and there is incorrect calculation of buffer
> block size for aptX HD. Try following:
>
> static void get_buffer_size_hd(void *codec_info, size_t link_mtu, size_t *decoded_buffer_size, size_t *encoded_buffer_size) {
>     /* aptX HD compression ratio is 4:1 and we need to process one aptX HD sample (6 bytes) at once */
>     *encoded_buffer_size = (link_mtu/6) * 6;
>     *decoded_buffer_size = *encoded_buffer_size * 4;
> }

Will try, btw if I disable aptX HD it attempts to pick up UHQ2 but it
asserts as well:

https://gist.github.com/Vudentz/0e91f3ba260211cab38822bcf04edd1f

It seems that fill_preferred_configuration and can_accept_capabilities
are not agreeing with one another, so we got a transport but no
profile.
On Friday 26 April 2019 13:09:00 Luiz Augusto von Dentz wrote:
> Hi Pali,
> 
> On Fri, Apr 26, 2019 at 11:34 AM Pali Rohár <pali.rohar@gmail.com> wrote:
> >
> > On Friday 26 April 2019 11:20:26 Luiz Augusto von Dentz wrote:
> > > I have an assert when I use a different headset which does support apt-X HD:
> > >
> > > https://gist.github.com/Vudentz/0d6b6f2ad08524db69a3e223e26bc80d
> >
> > I have not tested aptX HD, nor aptX Low Latency. I tested only (classic)
> > aptX. I looked at code and there is incorrect calculation of buffer
> > block size for aptX HD. Try following:
> >
> > static void get_buffer_size_hd(void *codec_info, size_t link_mtu, size_t *decoded_buffer_size, size_t *encoded_buffer_size) {
> >     /* aptX HD compression ratio is 4:1 and we need to process one aptX HD sample (6 bytes) at once */
> >     *encoded_buffer_size = (link_mtu/6) * 6;
> >     *decoded_buffer_size = *encoded_buffer_size * 4;
> > }
> 
> Will try, btw if I disable aptX HD it attempts to pick up UHQ2 but it
> asserts as well:
> 
> https://gist.github.com/Vudentz/0e91f3ba260211cab38822bcf04edd1f
> 
> It seems that fill_preferred_configuration and can_accept_capabilities
> are not agreeing with one another

When fill_preferred_configuration or can_accept_capabilities fails it
prints debug message about it. But I do not see any of them in your
output. So I think problem can be somewhere else.

I have not got this assert for uhq2, so this looks like some race
condition.

> so we got a transport but no profile.

In your log is:
bluez activated sbc_uhq2, then module-bluez5-device started to be
loading, card.c chose a2dp_sink_aptx as initial profile and due to bug
in module-bluetooth-policy.c aptx was not changed to sbc_uhq2. Next
sbc_uhq2 was released and prepared for switching to initial profile
aptx. And then assertion failed.

My guess is: because card.c was not fully initialized yet (it called
hook for choosing initial profile), which called code for switching
profile, then u->card->profiles was not fully initialized and crashed.
Profile switching should be probably allowed only after full card
initialization to prevent such race conditions...
Hi Pali,

On Fri, Apr 26, 2019 at 1:55 PM Pali Rohár <pali.rohar@gmail.com> wrote:
>
> On Friday 26 April 2019 13:09:00 Luiz Augusto von Dentz wrote:
> > Hi Pali,
> >
> > On Fri, Apr 26, 2019 at 11:34 AM Pali Rohár <pali.rohar@gmail.com> wrote:
> > >
> > > On Friday 26 April 2019 11:20:26 Luiz Augusto von Dentz wrote:
> > > > I have an assert when I use a different headset which does support apt-X HD:
> > > >
> > > > https://gist.github.com/Vudentz/0d6b6f2ad08524db69a3e223e26bc80d
> > >
> > > I have not tested aptX HD, nor aptX Low Latency. I tested only (classic)
> > > aptX. I looked at code and there is incorrect calculation of buffer
> > > block size for aptX HD. Try following:
> > >
> > > static void get_buffer_size_hd(void *codec_info, size_t link_mtu, size_t *decoded_buffer_size, size_t *encoded_buffer_size) {
> > >     /* aptX HD compression ratio is 4:1 and we need to process one aptX HD sample (6 bytes) at once */
> > >     *encoded_buffer_size = (link_mtu/6) * 6;
> > >     *decoded_buffer_size = *encoded_buffer_size * 4;
> > > }
> >
> > Will try, btw if I disable aptX HD it attempts to pick up UHQ2 but it
> > asserts as well:
> >
> > https://gist.github.com/Vudentz/0e91f3ba260211cab38822bcf04edd1f
> >
> > It seems that fill_preferred_configuration and can_accept_capabilities
> > are not agreeing with one another
>
> When fill_preferred_configuration or can_accept_capabilities fails it
> prints debug message about it. But I do not see any of them in your
> output. So I think problem can be somewhere else.
>
> I have not got this assert for uhq2, so this looks like some race
> condition.
>
> > so we got a transport but no profile.
>
> In your log is:
> bluez activated sbc_uhq2, then module-bluez5-device started to be
> loading, card.c chose a2dp_sink_aptx as initial profile and due to bug
> in module-bluetooth-policy.c aptx was not changed to sbc_uhq2. Next
> sbc_uhq2 was released and prepared for switching to initial profile
> aptx. And then assertion failed.
>
> My guess is: because card.c was not fully initialized yet (it called
> hook for choosing initial profile), which called code for switching
> profile, then u->card->profiles was not fully initialized and crashed.
> Profile switching should be probably allowed only after full card
> initialization to prevent such race conditions...

Managed to find the problem, it was in choose_remote_endpoint_table:


     for (i = 0; i < PA_ELEMENTSOF(freq_table); i++) {
         if (freq_table[i].rate == default_sample_spec->rate) {
-            frequency = freq_table[i].rate;
+            frequency = freq_table[i].cap;
             break;
         }

I have not idea how this worked with the bose, maybe that has more
frequencies enabled since I end up with 0x44 which did not match any
frequencies supported in case of sony.

Hi Pali,

On Fri, Apr 26, 2019 at 6:47 PM Pali Rohár <pali.rohar@gmail.com> wrote:
>
> On Friday 26 April 2019 16:44:03 Luiz Augusto von Dentz wrote:
> > Hi Pali,
> >
> > On Fri, Apr 26, 2019 at 1:55 PM Pali Rohár <pali.rohar@gmail.com> wrote:
> > >
> > > On Friday 26 April 2019 13:09:00 Luiz Augusto von Dentz wrote:
> > > > Hi Pali,
> > > >
> > > > On Fri, Apr 26, 2019 at 11:34 AM Pali Rohár <pali.rohar@gmail.com> wrote:
> > > > >
> > > > > On Friday 26 April 2019 11:20:26 Luiz Augusto von Dentz wrote:
> > > > > > I have an assert when I use a different headset which does support apt-X HD:
> > > > > >
> > > > > > https://gist.github.com/Vudentz/0d6b6f2ad08524db69a3e223e26bc80d
> > > > >
> > > > > I have not tested aptX HD, nor aptX Low Latency. I tested only (classic)
> > > > > aptX. I looked at code and there is incorrect calculation of buffer
> > > > > block size for aptX HD. Try following:
> > > > >
> > > > > static void get_buffer_size_hd(void *codec_info, size_t link_mtu, size_t *decoded_buffer_size, size_t *encoded_buffer_size) {
> > > > >     /* aptX HD compression ratio is 4:1 and we need to process one aptX HD sample (6 bytes) at once */
> > > > >     *encoded_buffer_size = (link_mtu/6) * 6;
> > > > >     *decoded_buffer_size = *encoded_buffer_size * 4;
> > > > > }
> > > >
> > > > Will try, btw if I disable aptX HD it attempts to pick up UHQ2 but it
> > > > asserts as well:
> > > >
> > > > https://gist.github.com/Vudentz/0e91f3ba260211cab38822bcf04edd1f
> > > >
> > > > It seems that fill_preferred_configuration and can_accept_capabilities
> > > > are not agreeing with one another
> > >
> > > When fill_preferred_configuration or can_accept_capabilities fails it
> > > prints debug message about it. But I do not see any of them in your
> > > output. So I think problem can be somewhere else.
> > >
> > > I have not got this assert for uhq2, so this looks like some race
> > > condition.
> > >
> > > > so we got a transport but no profile.
> > >
> > > In your log is:
> > > bluez activated sbc_uhq2, then module-bluez5-device started to be
> > > loading, card.c chose a2dp_sink_aptx as initial profile and due to bug
> > > in module-bluetooth-policy.c aptx was not changed to sbc_uhq2. Next
> > > sbc_uhq2 was released and prepared for switching to initial profile
> > > aptx. And then assertion failed.
> > >
> > > My guess is: because card.c was not fully initialized yet (it called
> > > hook for choosing initial profile), which called code for switching
> > > profile, then u->card->profiles was not fully initialized and crashed.
> > > Profile switching should be probably allowed only after full card
> > > initialization to prevent such race conditions...
> >
> > Managed to find the problem, it was in choose_remote_endpoint_table:
> >
> >
> >      for (i = 0; i < PA_ELEMENTSOF(freq_table); i++) {
> >          if (freq_table[i].rate == default_sample_spec->rate) {
> > -            frequency = freq_table[i].rate;
> > +            frequency = freq_table[i].cap;
> >              break;
> >          }
>
> Nice catch, thank you!
>
> > I have not idea how this worked with the bose, maybe that has more
> > frequencies enabled since I end up with 0x44 which did not match any
> > frequencies supported in case of sony.
>
> It worked also for me, so seems that more enabled frequencies was the
> reason.

Btw, if you are to send a v10 also include the following:

@@ -1838,6 +1847,9 @@ static DBusMessage
*endpoint_set_configuration(DBusConnection *conn, DBusMessage
     t->release = bluez5_transport_release_cb;
     pa_bluetooth_transport_put(t);

+    if (!d->change_a2dp_profile_in_progress)
+        pa_bluetooth_transport_set_state(t,
PA_BLUETOOTH_TRANSPORT_STATE_PLAYING);
+
     pa_log_debug("Transport %s available for profile %s", t->path,
pa_bluetooth_profile_to_string(t->profile));

     return NULL;

Otherwise last used logic don't work as intended.

Btw, have you tried these patches with a phone? It seems to work but
we got some problems:

1. At least Android seems to prefer aptX-HD but that doesn't seems to
produce any audio, in fact it crashed a few times so either have to
find out why aptX-HD is not working or don't include it.
2. Codec switching with Android always seems to timeout.
3. There seem to be some regression with loopback module, there seems
it always produces some glitch when resuming (during the playback it
seems alright):

I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 17414 usec of
audio from queue
I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 20317 usec of
audio from queue
I: [alsa-sink-ALC293 Analog] module-loopback.c: Adding 30657 usec of
silence to queue
I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 105170 usec
of audio from queue


>
> --
> Pali Rohár
> pali.rohar@gmail.com
Hi Pali,

On Tue, Apr 30, 2019 at 12:42 PM Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
>
> Hi Pali,
>
> On Fri, Apr 26, 2019 at 6:47 PM Pali Rohár <pali.rohar@gmail.com> wrote:
> >
> > On Friday 26 April 2019 16:44:03 Luiz Augusto von Dentz wrote:
> > > Hi Pali,
> > >
> > > On Fri, Apr 26, 2019 at 1:55 PM Pali Rohár <pali.rohar@gmail.com> wrote:
> > > >
> > > > On Friday 26 April 2019 13:09:00 Luiz Augusto von Dentz wrote:
> > > > > Hi Pali,
> > > > >
> > > > > On Fri, Apr 26, 2019 at 11:34 AM Pali Rohár <pali.rohar@gmail.com> wrote:
> > > > > >
> > > > > > On Friday 26 April 2019 11:20:26 Luiz Augusto von Dentz wrote:
> > > > > > > I have an assert when I use a different headset which does support apt-X HD:
> > > > > > >
> > > > > > > https://gist.github.com/Vudentz/0d6b6f2ad08524db69a3e223e26bc80d
> > > > > >
> > > > > > I have not tested aptX HD, nor aptX Low Latency. I tested only (classic)
> > > > > > aptX. I looked at code and there is incorrect calculation of buffer
> > > > > > block size for aptX HD. Try following:
> > > > > >
> > > > > > static void get_buffer_size_hd(void *codec_info, size_t link_mtu, size_t *decoded_buffer_size, size_t *encoded_buffer_size) {
> > > > > >     /* aptX HD compression ratio is 4:1 and we need to process one aptX HD sample (6 bytes) at once */
> > > > > >     *encoded_buffer_size = (link_mtu/6) * 6;
> > > > > >     *decoded_buffer_size = *encoded_buffer_size * 4;
> > > > > > }
> > > > >
> > > > > Will try, btw if I disable aptX HD it attempts to pick up UHQ2 but it
> > > > > asserts as well:
> > > > >
> > > > > https://gist.github.com/Vudentz/0e91f3ba260211cab38822bcf04edd1f
> > > > >
> > > > > It seems that fill_preferred_configuration and can_accept_capabilities
> > > > > are not agreeing with one another
> > > >
> > > > When fill_preferred_configuration or can_accept_capabilities fails it
> > > > prints debug message about it. But I do not see any of them in your
> > > > output. So I think problem can be somewhere else.
> > > >
> > > > I have not got this assert for uhq2, so this looks like some race
> > > > condition.
> > > >
> > > > > so we got a transport but no profile.
> > > >
> > > > In your log is:
> > > > bluez activated sbc_uhq2, then module-bluez5-device started to be
> > > > loading, card.c chose a2dp_sink_aptx as initial profile and due to bug
> > > > in module-bluetooth-policy.c aptx was not changed to sbc_uhq2. Next
> > > > sbc_uhq2 was released and prepared for switching to initial profile
> > > > aptx. And then assertion failed.
> > > >
> > > > My guess is: because card.c was not fully initialized yet (it called
> > > > hook for choosing initial profile), which called code for switching
> > > > profile, then u->card->profiles was not fully initialized and crashed.
> > > > Profile switching should be probably allowed only after full card
> > > > initialization to prevent such race conditions...
> > >
> > > Managed to find the problem, it was in choose_remote_endpoint_table:
> > >
> > >
> > >      for (i = 0; i < PA_ELEMENTSOF(freq_table); i++) {
> > >          if (freq_table[i].rate == default_sample_spec->rate) {
> > > -            frequency = freq_table[i].rate;
> > > +            frequency = freq_table[i].cap;
> > >              break;
> > >          }
> >
> > Nice catch, thank you!
> >
> > > I have not idea how this worked with the bose, maybe that has more
> > > frequencies enabled since I end up with 0x44 which did not match any
> > > frequencies supported in case of sony.
> >
> > It worked also for me, so seems that more enabled frequencies was the
> > reason.
>
> Btw, if you are to send a v10 also include the following:
>
> @@ -1838,6 +1847,9 @@ static DBusMessage
> *endpoint_set_configuration(DBusConnection *conn, DBusMessage
>      t->release = bluez5_transport_release_cb;
>      pa_bluetooth_transport_put(t);
>
> +    if (!d->change_a2dp_profile_in_progress)
> +        pa_bluetooth_transport_set_state(t,
> PA_BLUETOOTH_TRANSPORT_STATE_PLAYING);
> +
>      pa_log_debug("Transport %s available for profile %s", t->path,
> pa_bluetooth_profile_to_string(t->profile));
>
>      return NULL;
>
> Otherwise last used logic don't work as intended.
>
> Btw, have you tried these patches with a phone? It seems to work but
> we got some problems:
>
> 1. At least Android seems to prefer aptX-HD but that doesn't seems to
> produce any audio, in fact it crashed a few times so either have to
> find out why aptX-HD is not working or don't include it.
> 2. Codec switching with Android always seems to timeout.
> 3. There seem to be some regression with loopback module, there seems
> it always produces some glitch when resuming (during the playback it
> seems alright):
>
> I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 17414 usec of
> audio from queue
> I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 20317 usec of
> audio from queue
> I: [alsa-sink-ALC293 Analog] module-loopback.c: Adding 30657 usec of
> silence to queue
> I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 105170 usec
> of audio from queue

Ive also got this crash:

E: [lt-pulseaudio] core-util.c: The per-process limit on the number of
open file descriptors has been reached.
E: [lt-pulseaudio] module-loopback.c: pa_asyncmsgq_new() failed.
I: [lt-pulseaudio] source-output.c: Freeing output 129 "(null)"
I: [lt-pulseaudio] sink-input.c: Freeing input 124 "(null)"
E: [lt-pulseaudio] module.c: Failed to load module "module-loopback"
(argument: "source="bluez_source.B4_CD_27_F0_8D_0A.headset_audio_gateway"
source_dont_move="true" sink_input_properties="media.role=phone""):
initialization failed.
D: [lt-pulseaudio] module-suspend-on-idle.c: Source
bluez_source.B4_CD_27_F0_8D_0A.headset_audio_gateway becomes idle,
timeout in 5 seconds.
D: [lt-pulseaudio] backend-native.c: RFCOMM >> AT+VGS=15
D: [lt-pulseaudio] card.c: bluez_card.B4_CD_27_F0_8D_0A:
active_profile: off -> headset_audio_gateway
D: [lt-pulseaudio] core-subscribe.c: Dropped redundant event due to
change event.
Segmentation fault (core dumped)

On 01.05.19 11:09, Pali Rohár wrote:
> On Tuesday 30 April 2019 12:42:28 Luiz Augusto von Dentz wrote:
>> 1. At least Android seems to prefer aptX-HD but that doesn't seems to
>> produce any audio, in fact it crashed a few times so either have to
>> find out why aptX-HD is not working or don't include it.
>> 2. Codec switching with Android always seems to timeout.
>> 3. There seem to be some regression with loopback module, there seems
>> it always produces some glitch when resuming (during the playback it
>> seems alright):
>>
>> I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 17414 usec of
>> audio from queue
>> I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 20317 usec of
>> audio from queue
>> I: [alsa-sink-ALC293 Analog] module-loopback.c: Adding 30657 usec of
>> silence to queue
>> I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 105170 usec
>> of audio from queue
> Can you send btmon/wireshark dump? I can inspect aptx HD packets if
> decoder can correctly decode them.
>
Those messages from module-loopback are normal and expected.
They just show that module-loopback is adjusting the initial latency
to what is requested. If the source or sink is not ready when the
loopback starts processing data, it means that either the latency
will grow (if the sink is not yet accepting data) or shrink (if the
source is not yet providing data). Module-loopback tries to
compensate by dropping samples or inserting silence.
On 30.04.19 14:23, Luiz Augusto von Dentz wrote:
>
> Ive also got this crash:
>
> E: [lt-pulseaudio] core-util.c: The per-process limit on the number of
> open file descriptors has been reached.
> E: [lt-pulseaudio] module-loopback.c: pa_asyncmsgq_new() failed.
> I: [lt-pulseaudio] source-output.c: Freeing output 129 "(null)"
> I: [lt-pulseaudio] sink-input.c: Freeing input 124 "(null)"
> E: [lt-pulseaudio] module.c: Failed to load module "module-loopback"
> (argument: "source="bluez_source.B4_CD_27_F0_8D_0A.headset_audio_gateway"
> source_dont_move="true" sink_input_properties="media.role=phone""):
> initialization failed.
> D: [lt-pulseaudio] module-suspend-on-idle.c: Source
> bluez_source.B4_CD_27_F0_8D_0A.headset_audio_gateway becomes idle,
> timeout in 5 seconds.
> D: [lt-pulseaudio] backend-native.c: RFCOMM >> AT+VGS=15
> D: [lt-pulseaudio] card.c: bluez_card.B4_CD_27_F0_8D_0A:
> active_profile: off -> headset_audio_gateway
> D: [lt-pulseaudio] core-subscribe.c: Dropped redundant event due to
> change event.
> Segmentation fault (core dumped)
>
>
This is also not related to module-loopback. The crash happens
after the failure to load the module and the failure is caused by
the number of open file descriptors being exceeded.
So I think the crash is a consequence of the first error and it
needs to be figured out why there are so many open file descriptors.
Hi Pali,

On Wed, May 1, 2019 at 12:09 PM Pali Rohár <pali.rohar@gmail.com> wrote:
>
> On Tuesday 30 April 2019 12:42:28 Luiz Augusto von Dentz wrote:
> > 1. At least Android seems to prefer aptX-HD but that doesn't seems to
> > produce any audio, in fact it crashed a few times so either have to
> > find out why aptX-HD is not working or don't include it.
> > 2. Codec switching with Android always seems to timeout.
> > 3. There seem to be some regression with loopback module, there seems
> > it always produces some glitch when resuming (during the playback it
> > seems alright):
> >
> > I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 17414 usec of
> > audio from queue
> > I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 20317 usec of
> > audio from queue
> > I: [alsa-sink-ALC293 Analog] module-loopback.c: Adding 30657 usec of
> > silence to queue
> > I: [alsa-sink-ALC293 Analog] module-loopback.c: Dropping 105170 usec
> > of audio from queue
>
> Can you send btmon/wireshark dump? I can inspect aptx HD packets if
> decoder can correctly decode them.

You can probably reproduce this faster with a phone, I suspect it also
doesn't work with iOS either.






Hi Pali,

On Wed, May 8, 2019 at 1:42 PM Pali Rohár <pali.rohar@gmail.com> wrote:
>
> On Tuesday 30 April 2019 12:42:28 Luiz Augusto von Dentz wrote:
> > Btw, have you tried these patches with a phone? It seems to work but
> > we got some problems:
> >
> > 1. At least Android seems to prefer aptX-HD but that doesn't seems to
> > produce any audio, in fact it crashed a few times so either have to
> > find out why aptX-HD is not working or don't include it.
>
> Can you test V10 series with aptX-HD again? Now codec expects aptx-HD
> packets to be encapsulated in RTP packets.

Will try this out today.

> > 2. Codec switching with Android always seems to timeout.
>
> I tested V10 series with Android and switching between SBC and aptX is
> working fine.

Interesting, this must be something specific to my phone then :/,
Android is so fragmented in this part with manufacturers putting their
on extensions.
Hi Pali,

On Fri, May 10, 2019 at 11:21 AM Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
>
> Hi Pali,
>
> On Wed, May 8, 2019 at 1:42 PM Pali Rohár <pali.rohar@gmail.com> wrote:
> >
> > On Tuesday 30 April 2019 12:42:28 Luiz Augusto von Dentz wrote:
> > > Btw, have you tried these patches with a phone? It seems to work but
> > > we got some problems:
> > >
> > > 1. At least Android seems to prefer aptX-HD but that doesn't seems to
> > > produce any audio, in fact it crashed a few times so either have to
> > > find out why aptX-HD is not working or don't include it.
> >
> > Can you test V10 series with aptX-HD again? Now codec expects aptx-HD
> > packets to be encapsulated in RTP packets.
>
> Will try this out today.

Works great with my phone.

> > > 2. Codec switching with Android always seems to timeout.
> >
> > I tested V10 series with Android and switching between SBC and aptX is
> > working fine.
>
> Interesting, this must be something specific to my phone then :/,
> Android is so fragmented in this part with manufacturers putting their
> on extensions.
>
> --
> Luiz Augusto von Dentz