diff --git a/spa/plugins/bluez5/bap-codec-lc3.c b/spa/plugins/bluez5/bap-codec-lc3.c index f2b9d5928..39c8a4cd1 100644 --- a/spa/plugins/bluez5/bap-codec-lc3.c +++ b/spa/plugins/bluez5/bap-codec-lc3.c @@ -475,6 +475,40 @@ static int codec_validate_config(const struct media_codec *codec, uint32_t flags return 0; } +static void codec_get_qos(const struct media_codec *codec, + const void *config, size_t config_size, + struct codec_qos *qos) +{ + bap_lc3_t conf; + + memset(qos, 0, sizeof(*qos)); + + if (!parse_conf(&conf, config, config_size)) + return; + + qos->framing = false; + qos->phy = "2M"; + qos->retransmission = 2; /* default */ + qos->sdu = conf.framelen * conf.n_blks; + qos->latency = 20; /* default */ + qos->delay = 40000U; + qos->interval = (conf.frame_duration == LC3_CONFIG_DURATION_7_5 ? 7500 : 10000); + + switch (conf.rate) { + case LC3_CONFIG_FREQ_8KHZ: + case LC3_CONFIG_FREQ_16KHZ: + case LC3_CONFIG_FREQ_24KHZ: + case LC3_CONFIG_FREQ_32KHZ: + qos->retransmission = 2; + qos->latency = (conf.frame_duration == LC3_CONFIG_DURATION_7_5 ? 8 : 10); + break; + case LC3_CONFIG_FREQ_48KHZ: + qos->retransmission = 5; + qos->latency = (conf.frame_duration == LC3_CONFIG_DURATION_7_5 ? 15 : 20); + break; + } +} + static void *codec_init(const struct media_codec *codec, uint32_t flags, void *config, size_t config_len, const struct spa_audio_info *info, void *props, size_t mtu) @@ -688,6 +722,7 @@ const struct media_codec bap_codec_lc3 = { .select_config = codec_select_config, .enum_config = codec_enum_config, .validate_config = codec_validate_config, + .get_qos = codec_get_qos, .caps_preference_cmp = codec_caps_preference_cmp, .init = codec_init, .deinit = codec_deinit, diff --git a/spa/plugins/bluez5/bluez5-dbus.c b/spa/plugins/bluez5/bluez5-dbus.c index 68d403607..026cb1acb 100644 --- a/spa/plugins/bluez5/bluez5-dbus.c +++ b/spa/plugins/bluez5/bluez5-dbus.c @@ -664,31 +664,21 @@ static DBusHandlerResult endpoint_select_properties(DBusConnection *conn, DBusMe &dict); append_basic_array_variant_dict_entry(&dict, "Capabilities", "ay", "y", DBUS_TYPE_BYTE, &config, size); + if (codec->get_qos) { - /*TBD: QoS Params are not coming from BlueZ now. Hard code it - * for now - */ - uint32_t interval = 10000U; - dbus_bool_t framing = FALSE; - char *phy = "2M"; - uint16_t sdu = 120; - uint8_t retransmissions; - uint16_t latency = 20; - uint32_t delay = 40000U; - spa_log_debug(monitor->log, "packing interval"); - append_basic_variant_dict_entry(&dict, "Interval", DBUS_TYPE_UINT32, "u", &interval); - spa_log_debug(monitor->log, "packing framing"); + struct codec_qos qos; + dbus_bool_t framing; + + codec->get_qos(codec, config, size, &qos); + + append_basic_variant_dict_entry(&dict, "Interval", DBUS_TYPE_UINT32, "u", &qos.interval); + framing = (qos.framing ? TRUE : FALSE); append_basic_variant_dict_entry(&dict, "Framing", DBUS_TYPE_BOOLEAN, "b", &framing); - spa_log_debug(monitor->log, "packing PHY"); - append_basic_variant_dict_entry(&dict, "PHY", DBUS_TYPE_STRING, "s", &phy); - spa_log_debug(monitor->log, "packing SDU"); - append_basic_variant_dict_entry(&dict, "SDU", DBUS_TYPE_UINT16, "q", &sdu); - spa_log_debug(monitor->log, "packing RTN"); - append_basic_variant_dict_entry(&dict, "Retransmissions", DBUS_TYPE_BYTE, "y", &retransmissions); - spa_log_debug(monitor->log, "packing Lat"); - append_basic_variant_dict_entry(&dict, "Latency", DBUS_TYPE_UINT16, "q", &latency); - spa_log_debug(monitor->log, "packing Delay"); - append_basic_variant_dict_entry(&dict, "Delay", DBUS_TYPE_UINT32, "u", &delay); + append_basic_variant_dict_entry(&dict, "PHY", DBUS_TYPE_STRING, "s", &qos.phy); + append_basic_variant_dict_entry(&dict, "SDU", DBUS_TYPE_UINT16, "q", &qos.sdu); + append_basic_variant_dict_entry(&dict, "Retransmissions", DBUS_TYPE_BYTE, "y", &qos.retransmission); + append_basic_variant_dict_entry(&dict, "Latency", DBUS_TYPE_UINT16, "q", &qos.latency); + append_basic_variant_dict_entry(&dict, "Delay", DBUS_TYPE_UINT32, "u", &qos.delay); } dbus_message_iter_close_container(&iter, &dict); diff --git a/spa/plugins/bluez5/media-codecs.h b/spa/plugins/bluez5/media-codecs.h index 89247f516..0bdf914d7 100644 --- a/spa/plugins/bluez5/media-codecs.h +++ b/spa/plugins/bluez5/media-codecs.h @@ -79,6 +79,16 @@ struct media_codec_audio_info { uint32_t channels; }; +struct codec_qos { + uint32_t interval; + bool framing; + char *phy; + uint16_t sdu; + uint8_t retransmission; + uint16_t latency; + uint32_t delay; +}; + struct media_codec { enum spa_bluetooth_audio_codec id; uint8_t codec_id; @@ -109,6 +119,9 @@ struct media_codec { int (*validate_config) (const struct media_codec *codec, uint32_t flags, const void *caps, size_t caps_size, struct spa_audio_info *info); + void (*get_qos)(const struct media_codec *codec, + const void *config, size_t config_size, + struct codec_qos *qos); /** qsort comparison sorting caps in order of preference for the codec. * Used in codec switching to select best remote endpoints.