diff --git a/spa/plugins/bluez5/bap-codec-lc3.c b/spa/plugins/bluez5/bap-codec-lc3.c index b1b12cb78..881af4e14 100644 --- a/spa/plugins/bluez5/bap-codec-lc3.c +++ b/spa/plugins/bluez5/bap-codec-lc3.c @@ -1503,6 +1503,10 @@ static int codec_get_bis_config(const struct media_codec *codec, uint8_t *caps, struct ltv_writer writer = LTV_WRITER(caps, *caps_size); const struct bap_qos *preset = NULL; + uint32_t retransmissions = 0; + uint8_t rtn_manual_set = 0; + uint32_t max_transport_latency = 0; + uint32_t presentation_delay = 0; *caps_size = 0; if (settings) { @@ -1511,6 +1515,14 @@ static int codec_get_bis_config(const struct media_codec *codec, uint8_t *caps, sscanf(settings->items[i].value, "%"PRIu32, &channel_allocation); if (spa_streq(settings->items[i].key, "preset")) preset_name = settings->items[i].value; + if (spa_streq(settings->items[i].key, "max_transport_latency")) + spa_atou32(settings->items[i].value, &max_transport_latency, 0); + if (spa_streq(settings->items[i].key, "presentation_delay")) + spa_atou32(settings->items[i].value, &presentation_delay, 0); + if (spa_streq(settings->items[i].key, "retransmissions")) { + spa_atou32(settings->items[i].value, &retransmissions, 0); + rtn_manual_set = 1; + } } } @@ -1537,9 +1549,9 @@ static int codec_get_bis_config(const struct media_codec *codec, uint8_t *caps, else qos->framing = 0; qos->sdu = preset->framelen * get_channel_count(channel_allocation); - qos->retransmission = preset->retransmission; - qos->latency = preset->latency; - qos->delay = preset->delay; + qos->retransmission = rtn_manual_set ? retransmissions : preset->retransmission; + qos->latency = max_transport_latency ? max_transport_latency : preset->latency; + qos->delay = presentation_delay ? presentation_delay : preset->delay; qos->phy = 2; qos->interval = (preset->frame_duration == LC3_CONFIG_DURATION_7_5 ? 7500 : 10000); diff --git a/spa/plugins/bluez5/bluez5-dbus.c b/spa/plugins/bluez5/bluez5-dbus.c index f4b384547..22d971c37 100644 --- a/spa/plugins/bluez5/bluez5-dbus.c +++ b/spa/plugins/bluez5/bluez5-dbus.c @@ -188,9 +188,16 @@ struct spa_bt_metadata { uint8_t value[METADATA_MAX_LEN - 1]; }; +#define RTN_MAX 0x1E +#define MAX_TRANSPORT_LATENCY_MIN 0x5 +#define MAX_TRANSPORT_LATENCY_MAX 0x0FA0 + struct spa_bt_bis { struct spa_list link; char qos_preset[255]; + int retransmissions; + int rtn_manual_set; + int max_transport_latency; int channel_allocation; struct spa_list metadata_list; }; @@ -6192,8 +6199,11 @@ static void configure_bis(struct spa_bt_monitor *monitor, struct bap_codec_qos qos; struct spa_bt_metadata *metadata_entry; struct spa_dict settings; - struct spa_dict_item setting_items[2]; + struct spa_dict_item setting_items[4]; + uint32_t n_items = 0; char channel_allocation[64] = {0}; + char retransmissions[3] = {0}; + char max_transport_latency[5] = {0}; int mse = 0; int options = 0; @@ -6218,12 +6228,27 @@ static void configure_bis(struct spa_bt_monitor *monitor, metadata_size += metadata_entry->length - 1; } + spa_log_debug(monitor->log, "bis->channel_allocation %d", bis->channel_allocation); - if (bis->channel_allocation) + if (bis->channel_allocation) { spa_scnprintf(channel_allocation, sizeof(channel_allocation), "%"PRIu32, bis->channel_allocation); - setting_items[0] = SPA_DICT_ITEM_INIT("channel_allocation", channel_allocation); - setting_items[1] = SPA_DICT_ITEM_INIT("preset", bis->qos_preset); - settings = SPA_DICT_INIT(setting_items, 2); + } + spa_log_debug(monitor->log, "bis->rtn_manual_set %d", bis->rtn_manual_set); + spa_log_debug(monitor->log, "bis->retransmissions %d", bis->retransmissions); + if (bis->rtn_manual_set) { + spa_scnprintf(retransmissions, sizeof(retransmissions), "%"PRIu8, bis->retransmissions); + setting_items[n_items++] = SPA_DICT_ITEM_INIT("retransmissions", retransmissions); + } + spa_log_debug(monitor->log, "bis->max_transport_latency %d", bis->max_transport_latency); + if (bis->max_transport_latency) { + spa_scnprintf(max_transport_latency, sizeof(max_transport_latency), "%"PRIu32, bis->max_transport_latency); + setting_items[n_items++] = SPA_DICT_ITEM_INIT("max_transport_latency", max_transport_latency); + } + + setting_items[n_items++] = SPA_DICT_ITEM_INIT("preset", bis->qos_preset); + setting_items[n_items++] = SPA_DICT_ITEM_INIT("channel_allocation", channel_allocation); + + settings = SPA_DICT_INIT(setting_items, n_items); caps_size = sizeof(caps); ret = codec->get_bis_config(codec, caps, &caps_size, &settings, &qos); @@ -7126,6 +7151,20 @@ static void parse_broadcast_source_config(struct spa_bt_monitor *monitor, const if (spa_json_get_string(&it[1], bis_entry->qos_preset, sizeof(bis_entry->qos_preset)) <= 0) goto parse_failed; spa_log_debug(monitor->log, "bis_entry->qos_preset %s", bis_entry->qos_preset); + } else if (spa_streq(bis_key, "retransmissions")) { + if (spa_json_get_int(&it[2], &bis_entry->retransmissions) <= 0) + goto parse_failed; + if (bis_entry->retransmissions > RTN_MAX) + goto parse_failed; + bis_entry->rtn_manual_set = 1; + spa_log_debug(monitor->log, "bis_entry->retransmissions %d", bis_entry->retransmissions); + } else if (spa_streq(bis_key, "max_transport_latency")) { + if (spa_json_get_int(&it[2], &bis_entry->max_transport_latency) <= 0) + goto parse_failed; + if (bis_entry->max_transport_latency < MAX_TRANSPORT_LATENCY_MIN && + bis_entry->max_transport_latency > MAX_TRANSPORT_LATENCY_MAX) + goto parse_failed; + spa_log_debug(monitor->log, "bis_entry->max_transport_latency %d", bis_entry->max_transport_latency); } else if (spa_streq(bis_key, "audio_channel_allocation")) { if (spa_json_get_int(&it[1], &bis_entry->channel_allocation) <= 0) goto parse_failed;