* [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