[RFC,2/2] bluetooth: Add SBC get/set config message support

Submitted by Frédéric Danis on May 17, 2019, 1:45 p.m.

Details

Message ID 20190517134512.13399-3-frederic.danis@collabora.com
State New
Headers show
Series "Add dynamic configuration of SBC bitpool" ( rev: 1 ) in PulseAudio

Not browsing as part of any series.

Commit Message

Frédéric Danis May 17, 2019, 1:45 p.m.
Capability to dynamically change the bitpool used during runtime allows to
adjust the bitrate of the stream. In a crowded environment this can allow
to manage the bandwidth used and limit interference between source and
headphones.

get-a2dp-config message returns SBC bitpool configuration:
{{current bitpool} {min bitpool} {max bitpool}}

set-a2dp-config message gets new bitpool to use as parameter:
{new bitpool}
---
 src/modules/bluetooth/a2dp-codec-sbc.c | 47 ++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

--
2.18.0

Patch hide | download patch | download mbox

diff --git a/src/modules/bluetooth/a2dp-codec-sbc.c b/src/modules/bluetooth/a2dp-codec-sbc.c
index cdc20d7f0..93aeb6241 100644
--- a/src/modules/bluetooth/a2dp-codec-sbc.c
+++ b/src/modules/bluetooth/a2dp-codec-sbc.c
@@ -27,6 +27,7 @@ 
 #include <pulsecore/once.h>
 #include <pulse/sample.h>
 #include <pulse/xmalloc.h>
+#include <pulse/message-params.h>

 #include <arpa/inet.h>

@@ -51,6 +52,7 @@  struct sbc_info {
     uint8_t initial_bitpool;
     uint8_t min_bitpool;
     uint8_t max_bitpool;
+    uint8_t next_bitpool;
 };

 static bool can_accept_capabilities(const uint8_t *capabilities_buffer, uint8_t capabilities_size, bool for_encoding) {
@@ -502,6 +504,48 @@  static size_t reduce_encoder_bitrate(void *codec_info, size_t write_link_mtu) {
     return get_block_size(codec_info, write_link_mtu);
 }

+static char* get_encoder_config(void *codec_info) {
+    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
+    pa_message_params *param;
+
+    param = pa_message_params_new();
+    pa_message_params_begin_list(param);
+    pa_message_params_write_int64(param, sbc_info->sbc.bitpool);
+    pa_message_params_write_int64(param, sbc_info->min_bitpool);
+    pa_message_params_write_int64(param, sbc_info->max_bitpool);
+    pa_message_params_end_list(param);
+
+    return pa_message_params_to_string_free(param);
+}
+
+static int set_encoder_config(void *codec_info, char *new_config) {
+    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
+    void *state = NULL;
+    int64_t value;
+
+    if (pa_message_params_read_int64(new_config, &value, &state) != PA_PARAMS_OK)
+        return -PA_ERR_INVALID;
+
+    pa_log_info("Requested SBC Bitpool: %ld", value);
+    if (value < sbc_info->min_bitpool || value > sbc_info->max_bitpool)
+        return -PA_ERR_INVALID;
+    sbc_info->next_bitpool = (uint8_t)value;
+
+    return PA_OK;
+}
+
+static size_t apply_encoder_config(void *codec_info, size_t write_link_mtu) {
+    struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
+
+    if (!sbc_info->next_bitpool)
+        return 0;
+
+    set_bitpool(sbc_info, sbc_info->next_bitpool);
+    sbc_info->next_bitpool = 0;
+
+    return get_block_size(codec_info, write_link_mtu);
+}
+
 static size_t encode_buffer(void *codec_info, uint32_t timestamp, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {
     struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
     struct rtp_header *header;
@@ -644,4 +688,7 @@  const pa_a2dp_codec pa_a2dp_codec_sbc = {
     .reduce_encoder_bitrate = reduce_encoder_bitrate,
     .encode_buffer = encode_buffer,
     .decode_buffer = decode_buffer,
+    .get_encoder_config = get_encoder_config,
+    .set_encoder_config = set_encoder_config,
+    .apply_encoder_config = apply_encoder_config,
 };