2024-02-05 17:03:37

by Pauli Virtanen

[permalink] [raw]
Subject: [PATCH BlueZ v2 1/2] monitor: parse Google's Opus A2DP vendor codec capabilities

Support parsing Opus (Google) A2DP vendor codec capabilities.
AOSP & Google Pixel Buds Pro has this implemented.

> ACL Data RX: Handle 256 flags 0x02 dlen 21 #419 [hci0] 26.905032
Channel: 65 len 17 [PSM 25 mode Basic (0x00)] {chan 4}
AVDTP: Get All Capabilities (0x0c) Response Accept (0x02) type 0x00 label 3 nosp 0
Service Category: Media Transport (0x01)
Service Category: Media Codec (0x07)
Media Type: Audio (0x00)
Media Codec: Non-A2DP (0xff)
Vendor ID: Google (0x000000e0)
Vendor Specific Codec ID: Opus (Google) (0x0001)
Frequency: 0x80
48000
Frame Duration: 0x18
10 ms
20 ms
Channel Mode: 0x07
Mono
Stereo
Dual Mono
Reserved: 0x60
Service Category: Delay Reporting (0x08)
---

Notes:
As far as I know, Opus is in no Bluetooth standard, only vendor codec.

monitor/a2dp.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)

diff --git a/monitor/a2dp.c b/monitor/a2dp.c
index f6e99ab26..ae88f565e 100644
--- a/monitor/a2dp.c
+++ b/monitor/a2dp.c
@@ -47,6 +47,8 @@
#define APTX_HD_CODEC_ID 0x0024
#define LDAC_VENDOR_ID 0x0000012d
#define LDAC_CODEC_ID 0x00aa
+#define OPUS_G_VENDOR_ID 0x000000e0
+#define OPUS_G_CODEC_ID 0x0001

struct bit_desc {
uint8_t bit_num;
@@ -201,6 +203,24 @@ static const struct bit_desc faststream_source_frequency_table[] = {
{ }
};

+static const struct bit_desc opus_g_frequency_table[] = {
+ { 7, "48000" },
+ { }
+};
+
+static const struct bit_desc opus_g_duration_table[] = {
+ { 3, "10 ms" },
+ { 4, "20 ms" },
+ { }
+};
+
+static const struct bit_desc opus_g_channels_table[] = {
+ { 0, "Mono" },
+ { 1, "Stereo" },
+ { 2, "Dual Mono" },
+ { }
+};
+
static void print_value_bits(uint8_t indent, uint32_t value,
const struct bit_desc *table)
{
@@ -244,6 +264,7 @@ static bool codec_vendor_aptx_ll_cfg(uint8_t losc, struct l2cap_frame *frame);
static bool codec_vendor_aptx_hd_cap(uint8_t losc, struct l2cap_frame *frame);
static bool codec_vendor_aptx_hd_cfg(uint8_t losc, struct l2cap_frame *frame);
static bool codec_vendor_ldac(uint8_t losc, struct l2cap_frame *frame);
+static bool codec_vendor_opus_g(uint8_t losc, struct l2cap_frame *frame);

static const struct vndcodec vndcodecs[] = {
{ APTX_VENDOR_ID, APTX_CODEC_ID, "aptX",
@@ -256,6 +277,8 @@ static const struct vndcodec vndcodecs[] = {
codec_vendor_aptx_hd_cap, codec_vendor_aptx_hd_cfg },
{ LDAC_VENDOR_ID, LDAC_CODEC_ID, "LDAC",
codec_vendor_ldac, codec_vendor_ldac },
+ { OPUS_G_VENDOR_ID, OPUS_G_CODEC_ID, "Opus (Google)",
+ codec_vendor_opus_g, codec_vendor_opus_g },
{ }
};

@@ -685,6 +708,31 @@ static bool codec_vendor_ldac(uint8_t losc, struct l2cap_frame *frame)
return true;
}

+static bool codec_vendor_opus_g(uint8_t losc, struct l2cap_frame *frame)
+{
+ uint8_t cap = 0;
+
+ if (losc != 1)
+ return false;
+
+ l2cap_frame_get_u8(frame, &cap);
+
+ print_field("%*cFrequency: 0x%02x", BASE_INDENT + 2, ' ', cap & 0x80);
+ print_value_bits(BASE_INDENT + 2, cap, opus_g_frequency_table);
+
+ print_field("%*cFrame Duration: 0x%02x", BASE_INDENT + 2, ' ',
+ cap & 0x18);
+ print_value_bits(BASE_INDENT + 2, cap, opus_g_duration_table);
+
+ print_field("%*cChannel Mode: 0x%02x", BASE_INDENT + 2, ' ',
+ cap & 0x07);
+ print_value_bits(BASE_INDENT + 2, cap, opus_g_channels_table);
+
+ print_field("%*cReserved: 0x%02x", BASE_INDENT + 2, ' ', cap & 0x60);
+
+ return true;
+}
+
static bool codec_vendor_cap(uint8_t losc, struct l2cap_frame *frame)
{
uint32_t vendor_id = 0;
--
2.43.0



2024-02-05 17:03:40

by Pauli Virtanen

[permalink] [raw]
Subject: [PATCH BlueZ v2 2/2] client/player: parse Google's Opus A2DP vendor codec capabilities

Support parsing Opus (Google) A2DP vendor codec capabilities.

Transport /org/bluez/hci0/dev_B8_7B_D4_32_44_15/sep3/fd2
UUID: 0000110a-0000-1000-8000-00805f9b34fb
Codec: 0xff (255)
Media Codec: Vendor Specific A2DP Codec
Vendor ID 0x000000e0
Vendor Specific Codec ID 0x0001
Vendor Specific Data: 0x92
Vendor Specific Value (Opus [Google])
Frequencies: 48kHz
Channel modes: Stereo
Frame durations: 20 ms
Device: /org/bluez/hci0/dev_B8_7B_D4_32_44_15
State: idle
Delay: 0x0898 (2200)
Volume: 0x001e (30)
Endpoint: /org/bluez/hci0/dev_B8_7B_D4_32_44_15/sep3
---
client/player.c | 32 ++++++++++++++++++++++++++++++++
profiles/audio/a2dp-codecs.h | 17 +++++++++++++++++
2 files changed, 49 insertions(+)

diff --git a/client/player.c b/client/player.c
index b43b4b867..a40bf66e3 100644
--- a/client/player.c
+++ b/client/player.c
@@ -2471,6 +2471,36 @@ static void print_ldac(a2dp_ldac_t *ldac, uint8_t size)
bt_shell_printf("\n");
}

+static void print_opus_g(a2dp_opus_g_t *opus, uint8_t size)
+{
+ bt_shell_printf("\t\tVendor Specific Value (Opus [Google])");
+
+ if (size < sizeof(*opus)) {
+ bt_shell_printf(" (broken)\n");
+ return;
+ }
+
+ bt_shell_printf("\n\t\tFrequencies: ");
+ if (opus->data & OPUS_G_FREQUENCY_48000)
+ bt_shell_printf("48kHz ");
+
+ bt_shell_printf("\n\t\tChannel modes: ");
+ if (opus->data & OPUS_G_CHANNELS_MONO)
+ bt_shell_printf("Mono ");
+ if (opus->data & OPUS_G_CHANNELS_STEREO)
+ bt_shell_printf("Stereo ");
+ if (opus->data & OPUS_G_CHANNELS_DUAL)
+ bt_shell_printf("Dual Mono ");
+
+ bt_shell_printf("\n\t\tFrame durations: ");
+ if (opus->data & OPUS_G_DURATION_100)
+ bt_shell_printf("10 ms ");
+ if (opus->data & OPUS_G_DURATION_200)
+ bt_shell_printf("20 ms ");
+
+ bt_shell_printf("\n");
+}
+
static void print_vendor(a2dp_vendor_codec_t *vendor, uint8_t size)
{
uint32_t vendor_id;
@@ -2508,6 +2538,8 @@ static void print_vendor(a2dp_vendor_codec_t *vendor, uint8_t size)
print_aptx_hd((void *) vendor, size);
else if (vendor_id == LDAC_VENDOR_ID && codec_id == LDAC_CODEC_ID)
print_ldac((void *) vendor, size);
+ else if (vendor_id == OPUS_G_VENDOR_ID && codec_id == OPUS_G_CODEC_ID)
+ print_opus_g((void *) vendor, size);
}

static void print_mpeg24(a2dp_aac_t *aac, uint8_t size)
diff --git a/profiles/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
index 6f5670947..38b9038f8 100644
--- a/profiles/audio/a2dp-codecs.h
+++ b/profiles/audio/a2dp-codecs.h
@@ -250,6 +250,18 @@
#define LDAC_CHANNEL_MODE_DUAL 0x02
#define LDAC_CHANNEL_MODE_STEREO 0x01

+#define OPUS_G_VENDOR_ID 0x000000e0
+#define OPUS_G_CODEC_ID 0x0001
+
+#define OPUS_G_FREQUENCY_48000 0x80
+
+#define OPUS_G_DURATION_100 0x08
+#define OPUS_G_DURATION_200 0x10
+
+#define OPUS_G_CHANNELS_MONO 0x01
+#define OPUS_G_CHANNELS_STEREO 0x02
+#define OPUS_G_CHANNELS_DUAL 0x04
+
typedef struct {
uint8_t vendor_id4;
uint8_t vendor_id3;
@@ -420,3 +432,8 @@ typedef struct {
uint8_t reserved2;
uint8_t reserved3;
} __attribute__ ((packed)) a2dp_aptx_hd_t;
+
+typedef struct {
+ a2dp_vendor_codec_t info;
+ uint8_t data;
+} __attribute__ ((packed)) a2dp_opus_g_t;
--
2.43.0


2024-02-05 18:17:57

by bluez.test.bot

[permalink] [raw]
Subject: RE: [BlueZ,v2,1/2] monitor: parse Google's Opus A2DP vendor codec capabilities

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=823244

---Test result---

Test Summary:
CheckPatch FAIL 1.18 seconds
GitLint FAIL 0.81 seconds
BuildEll PASS 23.99 seconds
BluezMake PASS 729.02 seconds
MakeCheck PASS 12.14 seconds
MakeDistcheck PASS 162.98 seconds
CheckValgrind PASS 225.59 seconds
CheckSmatch PASS 327.30 seconds
bluezmakeextell PASS 107.84 seconds
IncrementalBuild PASS 1360.33 seconds
ScanBuild PASS 927.70 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,v2,1/2] monitor: parse Google's Opus A2DP vendor codec capabilities
WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#94:
AVDTP: Get All Capabilities (0x0c) Response Accept (0x02) type 0x00 label 3 nosp 0

/github/workspace/src/src/13545880.patch total: 0 errors, 1 warnings, 78 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/src/13545880.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.


[BlueZ,v2,2/2] client/player: parse Google's Opus A2DP vendor codec capabilities
WARNING:NEW_TYPEDEFS: do not add new typedefs
#197: FILE: profiles/audio/a2dp-codecs.h:436:
+typedef struct {

WARNING:PREFER_DEFINED_ATTRIBUTE_MACRO: Prefer __packed over __attribute__((packed))
#200: FILE: profiles/audio/a2dp-codecs.h:439:
+} __attribute__ ((packed)) a2dp_opus_g_t;

/github/workspace/src/src/13545881.patch total: 0 errors, 2 warnings, 70 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/src/13545881.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.


##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,v2,1/2] monitor: parse Google's Opus A2DP vendor codec capabilities

WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search
8: B1 Line exceeds max length (88>80): " AVDTP: Get All Capabilities (0x0c) Response Accept (0x02) type 0x00 label 3 nosp 0"


---
Regards,
Linux Bluetooth

2024-02-06 22:30:43

by patchwork-bot+bluetooth

[permalink] [raw]
Subject: Re: [PATCH BlueZ v2 1/2] monitor: parse Google's Opus A2DP vendor codec capabilities

Hello:

This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <[email protected]>:

On Mon, 5 Feb 2024 19:03:16 +0200 you wrote:
> Support parsing Opus (Google) A2DP vendor codec capabilities.
> AOSP & Google Pixel Buds Pro has this implemented.
>
> > ACL Data RX: Handle 256 flags 0x02 dlen 21 #419 [hci0] 26.905032
> Channel: 65 len 17 [PSM 25 mode Basic (0x00)] {chan 4}
> AVDTP: Get All Capabilities (0x0c) Response Accept (0x02) type 0x00 label 3 nosp 0
> Service Category: Media Transport (0x01)
> Service Category: Media Codec (0x07)
> Media Type: Audio (0x00)
> Media Codec: Non-A2DP (0xff)
> Vendor ID: Google (0x000000e0)
> Vendor Specific Codec ID: Opus (Google) (0x0001)
> Frequency: 0x80
> 48000
> Frame Duration: 0x18
> 10 ms
> 20 ms
> Channel Mode: 0x07
> Mono
> Stereo
> Dual Mono
> Reserved: 0x60
> Service Category: Delay Reporting (0x08)
>
> [...]

Here is the summary with links:
- [BlueZ,v2,1/2] monitor: parse Google's Opus A2DP vendor codec capabilities
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=c3613b8a933d
- [BlueZ,v2,2/2] client/player: parse Google's Opus A2DP vendor codec capabilities
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=1c60eb02e6c3

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html