Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ] a2dp: Add codec prioritization
@ 2026-06-08 11:16 Simon Mikuda
  2026-06-08 12:21 ` [BlueZ] " bluez.test.bot
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Simon Mikuda @ 2026-06-08 11:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Simon Mikuda

This change will select best codec when connecting to A2DP:
LDAC > AptX HD > AptX > AAC > SBC
---
 profiles/audio/avdtp.c | 51 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index d475a545e..a8733a7e1 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -42,6 +42,8 @@
 #include "sink.h"
 #include "source.h"
 
+#include "a2dp-codecs.h"
+
 #define AVDTP_PSM 25
 
 #define MAX_SEID 0x3E
@@ -1293,10 +1295,49 @@ static struct avdtp_stream *find_stream_by_lseid(struct avdtp *session,
 	return find_stream_by_lsep(session, sep);
 }
 
+static unsigned int get_codec_priority(
+				struct avdtp_media_codec_capability *codec_cap)
+{
+	unsigned int priority = codec_cap->media_codec_type;
+
+	if (codec_cap->media_codec_type == A2DP_CODEC_VENDOR) {
+		a2dp_vendor_codec_t *vendor_codec = (void *) codec_cap->data;
+
+		switch (A2DP_GET_VENDOR_ID(*vendor_codec)) {
+		case APTX_VENDOR_ID:
+			return priority + 100;
+		case APTX_HD_VENDOR_ID:
+			return priority + 200;
+		case LDAC_VENDOR_ID:
+			return priority + 300;
+		}
+	}
+
+	return priority;
+}
+
+static int sep_codec_cmp(gconstpointer a, gconstpointer b)
+{
+	const struct avdtp_remote_sep *sep1 = a;
+	struct avdtp_service_capability *cap1 = sep1->codec;
+	unsigned int priority1 = get_codec_priority((void *) cap1->data);
+
+	const struct avdtp_remote_sep *sep2 = b;
+	struct avdtp_service_capability *cap2 = sep2->codec;
+	unsigned int priority2 = get_codec_priority((void *) cap2->data);
+
+	if (priority1 < priority2)
+		return 1;
+	if (priority1 > priority2)
+		return -1;
+	return 0;
+}
+
 struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
 						struct avdtp_local_sep *lsep)
 {
 	GSList *l;
+	GSList *sorted = NULL;
 
 	for (l = session->seps; l != NULL; l = g_slist_next(l)) {
 		struct avdtp_remote_sep *sep = l->data;
@@ -1325,7 +1366,15 @@ struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
 				continue;
 
 		if (sep->stream == NULL)
-			return sep;
+			sorted = g_slist_insert_sorted(sorted, sep,
+							sep_codec_cmp);
+	}
+
+	if (sorted) {
+		struct avdtp_remote_sep *sep = sorted->data;
+
+		g_slist_free(sorted);
+		return sep;
 	}
 
 	return NULL;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* RE: [BlueZ] a2dp: Add codec prioritization
  2026-06-08 11:16 [PATCH BlueZ] a2dp: Add codec prioritization Simon Mikuda
@ 2026-06-08 12:21 ` bluez.test.bot
  2026-06-08 13:48 ` [PATCH BlueZ] " Luiz Augusto von Dentz
  2026-06-08 15:58 ` Pauli Virtanen
  2 siblings, 0 replies; 4+ messages in thread
From: bluez.test.bot @ 2026-06-08 12:21 UTC (permalink / raw)
  To: linux-bluetooth, simon.mikuda

[-- Attachment #1: Type: text/plain, Size: 988 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1107778

---Test result---

Test Summary:
CheckPatch                    PASS      0.47 seconds
GitLint                       PASS      0.28 seconds
BuildEll                      PASS      17.69 seconds
BluezMake                     PASS      603.58 seconds
MakeCheck                     PASS      3.19 seconds
MakeDistcheck                 PASS      222.11 seconds
CheckValgrind                 PASS      212.63 seconds
CheckSmatch                   PASS      310.71 seconds
bluezmakeextell               PASS      165.91 seconds
IncrementalBuild              PASS      587.03 seconds
ScanBuild                     PASS      920.58 seconds



https://github.com/bluez/bluez/pull/2189

---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH BlueZ] a2dp: Add codec prioritization
  2026-06-08 11:16 [PATCH BlueZ] a2dp: Add codec prioritization Simon Mikuda
  2026-06-08 12:21 ` [BlueZ] " bluez.test.bot
@ 2026-06-08 13:48 ` Luiz Augusto von Dentz
  2026-06-08 15:58 ` Pauli Virtanen
  2 siblings, 0 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2026-06-08 13:48 UTC (permalink / raw)
  To: Simon Mikuda; +Cc: linux-bluetooth

Hi Simon,

On Mon, Jun 8, 2026 at 7:19 AM Simon Mikuda
<simon.mikuda@streamunlimited.com> wrote:
>
> This change will select best codec when connecting to A2DP:
> LDAC > AptX HD > AptX > AAC > SBC
> ---
>  profiles/audio/avdtp.c | 51 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 50 insertions(+), 1 deletion(-)
>
> diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
> index d475a545e..a8733a7e1 100644
> --- a/profiles/audio/avdtp.c
> +++ b/profiles/audio/avdtp.c
> @@ -42,6 +42,8 @@
>  #include "sink.h"
>  #include "source.h"
>
> +#include "a2dp-codecs.h"
> +
>  #define AVDTP_PSM 25
>
>  #define MAX_SEID 0x3E
> @@ -1293,10 +1295,49 @@ static struct avdtp_stream *find_stream_by_lseid(struct avdtp *session,
>         return find_stream_by_lsep(session, sep);
>  }
>
> +static unsigned int get_codec_priority(
> +                               struct avdtp_media_codec_capability *codec_cap)
> +{
> +       unsigned int priority = codec_cap->media_codec_type;
> +
> +       if (codec_cap->media_codec_type == A2DP_CODEC_VENDOR) {
> +               a2dp_vendor_codec_t *vendor_codec = (void *) codec_cap->data;
> +
> +               switch (A2DP_GET_VENDOR_ID(*vendor_codec)) {
> +               case APTX_VENDOR_ID:
> +                       return priority + 100;
> +               case APTX_HD_VENDOR_ID:
> +                       return priority + 200;
> +               case LDAC_VENDOR_ID:
> +                       return priority + 300;
> +               }
> +       }

Nak, not going to accept fixed, made up, ranking, the ranking should
be per endpoint source by ordering from higher to lower priority.

> +       return priority;
> +}
> +
> +static int sep_codec_cmp(gconstpointer a, gconstpointer b)
> +{
> +       const struct avdtp_remote_sep *sep1 = a;
> +       struct avdtp_service_capability *cap1 = sep1->codec;
> +       unsigned int priority1 = get_codec_priority((void *) cap1->data);
> +
> +       const struct avdtp_remote_sep *sep2 = b;
> +       struct avdtp_service_capability *cap2 = sep2->codec;
> +       unsigned int priority2 = get_codec_priority((void *) cap2->data);
> +
> +       if (priority1 < priority2)
> +               return 1;
> +       if (priority1 > priority2)
> +               return -1;
> +       return 0;
> +}
> +
>  struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
>                                                 struct avdtp_local_sep *lsep)
>  {
>         GSList *l;
> +       GSList *sorted = NULL;
>
>         for (l = session->seps; l != NULL; l = g_slist_next(l)) {
>                 struct avdtp_remote_sep *sep = l->data;
> @@ -1325,7 +1366,15 @@ struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
>                                 continue;
>
>                 if (sep->stream == NULL)
> -                       return sep;
> +                       sorted = g_slist_insert_sorted(sorted, sep,
> +                                                       sep_codec_cmp);
> +       }
> +
> +       if (sorted) {
> +               struct avdtp_remote_sep *sep = sorted->data;
> +
> +               g_slist_free(sorted);
> +               return sep;
>         }
>
>         return NULL;
> --
> 2.43.0
>
>


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH BlueZ] a2dp: Add codec prioritization
  2026-06-08 11:16 [PATCH BlueZ] a2dp: Add codec prioritization Simon Mikuda
  2026-06-08 12:21 ` [BlueZ] " bluez.test.bot
  2026-06-08 13:48 ` [PATCH BlueZ] " Luiz Augusto von Dentz
@ 2026-06-08 15:58 ` Pauli Virtanen
  2 siblings, 0 replies; 4+ messages in thread
From: Pauli Virtanen @ 2026-06-08 15:58 UTC (permalink / raw)
  To: Simon Mikuda, linux-bluetooth; +Cc: Luiz Augusto von Dentz

Hi,

ma, 2026-06-08 kello 13:16 +0200, Simon Mikuda kirjoitti:
> This change will select best codec when connecting to A2DP:
> LDAC > AptX HD > AptX > AAC > SBC

Currently it's media server's job to decide what A2DP codec to use.

What they do for this sort of static ordering, is to register endpoints
in the wanted priority order, so I think another mechanism for fixed
ordering is not really needed.

What could be useful is something that allows per-device priority
selection, e.g. DBus callback that BlueZ uses to query which endpoint
to configure, before starting SelectConfiguration.

I'm not sure this is highly needed though, as iirc BlueZ remembers what
configuration was used on previous connects, and if BlueZ gets it wrong
the sound server can just reconfigure as needed at the cost of some
extra delay when connecting.

> ---
>  profiles/audio/avdtp.c | 51 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 50 insertions(+), 1 deletion(-)
> 
> diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
> index d475a545e..a8733a7e1 100644
> --- a/profiles/audio/avdtp.c
> +++ b/profiles/audio/avdtp.c
> @@ -42,6 +42,8 @@
>  #include "sink.h"
>  #include "source.h"
>  
> +#include "a2dp-codecs.h"
> +
>  #define AVDTP_PSM 25
>  
>  #define MAX_SEID 0x3E
> @@ -1293,10 +1295,49 @@ static struct avdtp_stream *find_stream_by_lseid(struct avdtp *session,
>  	return find_stream_by_lsep(session, sep);
>  }
>  
> +static unsigned int get_codec_priority(
> +				struct avdtp_media_codec_capability *codec_cap)
> +{
> +	unsigned int priority = codec_cap->media_codec_type;
> +
> +	if (codec_cap->media_codec_type == A2DP_CODEC_VENDOR) {
> +		a2dp_vendor_codec_t *vendor_codec = (void *) codec_cap->data;
> +
> +		switch (A2DP_GET_VENDOR_ID(*vendor_codec)) {
> +		case APTX_VENDOR_ID:
> +			return priority + 100;
> +		case APTX_HD_VENDOR_ID:
> +			return priority + 200;
> +		case LDAC_VENDOR_ID:
> +			return priority + 300;
> +		}
> +	}
> +
> +	return priority;
> +}
> +
> +static int sep_codec_cmp(gconstpointer a, gconstpointer b)
> +{
> +	const struct avdtp_remote_sep *sep1 = a;
> +	struct avdtp_service_capability *cap1 = sep1->codec;
> +	unsigned int priority1 = get_codec_priority((void *) cap1->data);
> +
> +	const struct avdtp_remote_sep *sep2 = b;
> +	struct avdtp_service_capability *cap2 = sep2->codec;
> +	unsigned int priority2 = get_codec_priority((void *) cap2->data);
> +
> +	if (priority1 < priority2)
> +		return 1;
> +	if (priority1 > priority2)
> +		return -1;
> +	return 0;
> +}
> +
>  struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
>  						struct avdtp_local_sep *lsep)
>  {
>  	GSList *l;
> +	GSList *sorted = NULL;
>  
>  	for (l = session->seps; l != NULL; l = g_slist_next(l)) {
>  		struct avdtp_remote_sep *sep = l->data;
> @@ -1325,7 +1366,15 @@ struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
>  				continue;
>  
>  		if (sep->stream == NULL)
> -			return sep;
> +			sorted = g_slist_insert_sorted(sorted, sep,
> +							sep_codec_cmp);
> +	}
> +
> +	if (sorted) {
> +		struct avdtp_remote_sep *sep = sorted->data;
> +
> +		g_slist_free(sorted);
> +		return sep;
>  	}
>  
>  	return NULL;

-- 
Pauli Virtanen

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-06-08 15:58 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-08 11:16 [PATCH BlueZ] a2dp: Add codec prioritization Simon Mikuda
2026-06-08 12:21 ` [BlueZ] " bluez.test.bot
2026-06-08 13:48 ` [PATCH BlueZ] " Luiz Augusto von Dentz
2026-06-08 15:58 ` Pauli Virtanen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox